Skip to content

Deep call-path queries (e.g. "trace HTTP insert → nativelog write") return no result — sparse C++ call graph + agent doesn't use path_between #17

Description

@gangtao

Symptom

Asking the chat agent a call-path question like "Trace the call path from HTTP insert to nativelog write" (one of the empty-state suggested questions) returns "I could not find a documented call-path…" even though the endpoint entities exist. The agent runs ~9 search_entities keyword calls and gives up.

Root cause (two compounding factors)

1. The agent treats it as keyword search, not graph traversal.
The trace shows 9 search_entities calls and zero path_between / neighbors. "Trace the call path from A to B" is inherently a path_between(A, B) question — find the two endpoint nodes, walk the calls edges. The agent never attempts a traversal, so it never reconstructs a path.

2. Even with the right tool, the path isn't in the graph.
Measured on proton-enterprise@v3.3.1:

  • Call graph is sparse: only ~38% of function/method nodes (22,715 / 60,467) have any outgoing calls edge.
  • InterpreterInsertQuery (the INSERT entry point) has 0 outgoing calls edges — a leaf in the extracted graph, so nothing to trace from it.
  • proton is ingested code-only (AST). C++ AST call extraction misses virtual dispatch, templates, and callbacks — exactly how ClickHouse/proton dispatches between layers via abstract interfaces (IStorage/IInterpreter, indirect_call is only 851 edges vs 46k direct calls).
  • The real path (HTTP handler → parser → interpreter → storage → WAL/nativelog) is many layers deep, beyond path_between's MAX_PATH_DEPTH = 6 cap (src/tpk/tools.py:52).

The individual entities are findable (InterpreterInsertQuery, NativeLog ×92, HTTPHandler ×22) — browsable in Explorer — but the end-to-end chain connecting them can't be reconstructed from the current data.

Options

A. Small — nudge the agent to use path_between/neighbors for trace questions.
Improve the agent system prompt / tool descriptions so "trace"/"call path"/"how does X reach Y"/"what calls X" questions drive neighbors (single-hop: what calls X / what X calls) and path_between (endpoint-to-endpoint). Makes single/few-hop call questions work reliably. Does not fix deep cross-layer traces — the agent can't invent edges that aren't extracted. Low effort, real value for the common "what calls X?" case.

B. Large — richer call-graph extraction.
Either a semantic (LLM) extraction pass on proton (currently code-only), or a proper C++ call-graph analyzer (e.g. clang-based) that resolves virtual dispatch/templates. This is the real fix for deep-path questions, but a substantial effort. Possibly also raise/parameterize MAX_PATH_DEPTH for deep codebases.

Suggested near-term action

Do A (small agent-prompt improvement) and set expectations in the UI: consider replacing the "Trace the call path from HTTP insert to nativelog write" suggested question with one the current graph can answer well (e.g. "What calls CheckpointCoordinator::trigger?"), keeping deep-trace as a target for B.

Context

Found while debugging chat answers. Related fixes already merged this cycle: stale bare-name node keys re-ingested; repo-filter now accepts bare name or name@ref (#14). This issue is specifically about call-path reconstruction depth/coverage and agent tool selection, which those did not address.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions