Problem
Every runtime from #363 (Claude Code, Codex, Copilot CLI, Cursor, OpenCode, Antigravity CLI, Grok Build) writes the same graph shape through the Event Protocol. That shared shape is intended, but it leaves providers hard to tell apart or compare.
1. Provider identity is buried in a JSON string. source_sdk exists only inside each (:Session)/(:Action) node's metadata property, which is a serialized JSON string. Filtering by provider means string matching with no index:
MATCH (s:Session)-[:HAS_ACTION]->(a:Action)
WHERE a.metadata CONTAINS '"source_sdk": "grok"'
This was needed to verify the six live sessions in #363. A Session created by a non-start event also lacks source_sdk on the Session node itself.
2. Tool names are provider-native, with no normalization. The same capability has a different name in each runtime, as seen in the #363 live runs:
| Capability |
Claude Code |
Codex |
Copilot |
OpenCode |
Antigravity |
Grok |
| shell |
Bash |
Bash |
bash |
shell |
run_command |
run_terminal_command |
| read file |
Read |
(via Bash) |
view |
read |
view_file |
read_file |
A cross-provider question ("which files did agents read?", "how many shell commands per session?") needs a hand-written mapping in every query.
3. Provider-specific extras are unqueryable. Adapter metadata_keys land in the same JSON string: Grok's durationMs/permissionMode, Codex's turn_id, Antigravity's stepIdx/terminationReason, Copilot's timestamp.
Proposed direction
- Promote
source_sdk to a first-class, indexed property on Session and Action, set on MERGE/CREATE regardless of which event creates the node.
- Add a normalized
tool_kind (e.g. shell, read, edit, write, search, web, agent, mcp, other) beside the native tool_name, mapped per adapter in its RuntimeSpec (a tool-name → kind table), and carried on ToolStartEvent/ToolEndEvent.
- Decide which provider extras deserve first-class properties (e.g.
duration_ms, which several runtimes report) versus staying in metadata.
- Real-Memgraph test: one query per capability returns the same answer across all runtimes' captured payloads.
Context
Also affects the capture-completeness differences documented in agent-context-graph/docs/command-hooks.md. Antigravity has no tool results and Copilot no assistant replies, so provider-aware queries should be able to tell "not captured" apart from "didn't happen".
Problem
Every runtime from #363 (Claude Code, Codex, Copilot CLI, Cursor, OpenCode, Antigravity CLI, Grok Build) writes the same graph shape through the Event Protocol. That shared shape is intended, but it leaves providers hard to tell apart or compare.
1. Provider identity is buried in a JSON string.
source_sdkexists only inside each(:Session)/(:Action)node'smetadataproperty, which is a serialized JSON string. Filtering by provider means string matching with no index:This was needed to verify the six live sessions in #363. A Session created by a non-start event also lacks
source_sdkon the Session node itself.2. Tool names are provider-native, with no normalization. The same capability has a different name in each runtime, as seen in the #363 live runs:
BashBashbashshellrun_commandrun_terminal_commandReadBash)viewreadview_fileread_fileA cross-provider question ("which files did agents read?", "how many shell commands per session?") needs a hand-written mapping in every query.
3. Provider-specific extras are unqueryable. Adapter
metadata_keysland in the same JSON string: Grok'sdurationMs/permissionMode, Codex'sturn_id, Antigravity'sstepIdx/terminationReason, Copilot'stimestamp.Proposed direction
source_sdkto a first-class, indexed property onSessionandAction, set on MERGE/CREATE regardless of which event creates the node.tool_kind(e.g.shell,read,edit,write,search,web,agent,mcp,other) beside the nativetool_name, mapped per adapter in itsRuntimeSpec(a tool-name → kind table), and carried onToolStartEvent/ToolEndEvent.duration_ms, which several runtimes report) versus staying in metadata.Context
Also affects the capture-completeness differences documented in
agent-context-graph/docs/command-hooks.md. Antigravity has no tool results and Copilot no assistant replies, so provider-aware queries should be able to tell "not captured" apart from "didn't happen".