Browse documentation

Record context assembly

Record metadata-only evidence for the sources, compactions, and cache outcomes behind an agent model call.

Context assembly evidence answers three questions about a model step: which sources were considered and included, whether the context overflowed or was compacted, and whether a provider cache reused input tokens. It travels as span events on the model-call span, keeping the model step itself a model step.

What is recorded

  • An ordered source list containing kind, stable ID, optional version/digest/owner, sensitivity, token count, position, visibility, and an optional reason code.
  • The input budget, reserved output budget, assembled token count, overflow outcome, and an assembly SHA-256 digest.
  • Compaction trigger and strategy, before/after counts and digests, summarizer identity, retained overlap, and IDs removed.
  • Cache provider, outcome, optional cache/config digests, and optional measured savings.

Source IDs form the lineage. Use a document ID, memory item key, tool call ID, or other stable identifier—not text. A source with kind = memory must use its memory_item_key, which lets Anectico connect the model input back to memory provenance.

What is never recorded

These events do not accept prompt text, retrieved document bodies, memory content, generated summaries, or tool-result bytes. They are metadata-only even when the project’s content policy would permit content. Prompt/completion and tool content remain separate, opt-in capture paths.

Record from an SDK

Start an agent run, make a model-category span current, and call the run handle’s assembly, compaction, or cache method inside that span. The SDK refuses a call when no recording model span is active and validates the whole event before recording any part of it.

  • Go: run.RecordContextAssembly(modelCtx, value), RecordContextCompaction, and RecordContextCache. Go takes modelCtx explicitly because its OpenTelemetry API has no ambient current-span accessor.
  • JavaScript: run.recordContextAssembly(value), recordContextCompaction, and recordContextCache inside context.with(modelContext, ...).
  • Python: run.record_context_assembly(value), record_context_compaction, and record_context_cache inside the current model span’s context manager.

See the Go SDK, JavaScript SDK, and Python SDK for examples and Agent span and event attributes for every bound.

The OpenAI and Anthropic auto-instrumentation wrappers record cache evidence without an explicit cache call when their response includes the provider cache field. Reused tokens greater than zero produce hit; a reported zero produces miss; absence produces no cache event. Providers do not report the ordered source list or compaction decision, so those two events remain explicit.

Read context evidence

All read surfaces return the same metadata-only fields; none resolves a digest or source ID into content.

  • REST: GET /api/v1/agent-runs/{runId}/graph includes context on every model step. Use GET /api/v1/agent-events?run_id={runId}&category=context for the individual assembly, compaction, and cache rows. Add context_source_id={stable-id} to keep assembly events whose ordered source list contains that lineage ID.
  • MCP: get_agent_run_graph includes the same step summary. The gatewayed list_context_events read takes run_id and optional context_source_id; it requires mcp:read plus agents:read and returns bounded identifiers, hashes, counts, and outcomes only.
  • CLI: anectico agent-runs context <run-id> -o json prints the model-step summaries and all three context event kinds. Use -o table for a deterministic path/value view.

context.instrumented is the instrumentation answer. It is true only when at least one valid context event was accepted for that model step. A model step from an older producer, or one whose only context event was rejected, returns a summary with instrumented: false; its empty counters do not mean a measured zero. Conversely, instrumented: true with assembled_tokens: 0 is a real measured zero. Never infer instrumentation from a number or from provenance.normalizer_version.

The storage schema preserves that step/event presence bit, but not a separate presence bit for each optional numeric member inside an accepted event. Consequently an accepted event can return numeric zero for a member the producer omitted. Treat those member-level zeroes as the V1 stored projection; only instrumented distinguishes an uninstrumented step from an instrumented one.

How to verify

Choose a run whose model span recorded assembly, compaction, and cache events. The following three reads must name the same model span and the same three accepted events:

curl -sS -H "Authorization: Bearer $ANECTICO_TOKEN" \
  "$ANECTICO_URL/api/v1/agent-events?project_id=$ANECTICO_PROJECT&run_id=$RUN_ID&category=context"

curl -sS -H "Authorization: Bearer $ANECTICO_TOKEN" \
  "$ANECTICO_URL/api/v1/agent-runs/$RUN_ID/graph?project_id=$ANECTICO_PROJECT"

anectico agent-runs context "$RUN_ID" --project "$ANECTICO_PROJECT" -o json

For MCP, call the read gateway twice: execute_read_action with action list_context_events and arguments {"run_id":"<run-id>"}, then with action get_agent_run_graph and the same run ID. The MCP credential needs mcp:read and agents:read.

Verify exact values rather than presence alone:

  • assembly.sources has the expected IDs, positions, token counts, visibilities, and reason codes; assembly_sha256 is the lowercase SHA-256 of each source ordered by position as position<TAB>id<TAB>visibility<NEWLINE>.
  • A truncated assembly has overflow: "truncated", at least one source with visibility: "truncated", and a bounded reason such as budget. Its assembled count is below budget_tokens - reserved_output_tokens.
  • A compaction’s ratio equals after_tokens / before_tokens; the producer should omit the ratio because Anectico derives it. Its removed source IDs and before/after hashes must match the producer’s decision.
  • A cache hit’s reused_tokens equals the model step’s model.usage.cache_read_tokens; a reported miss is a separate outcome and may carry a measured zero.
  • steps[].context.instrumented is true, and its assembled-token, overflow, compaction-count, and cache-outcome summary agrees with the event rows. The CLI JSON is the REST graph projected onto those context fields, without renaming or recomputing them.

To verify one lineage link, add context_source_id=<stable-id> to the REST event request or to the MCP list_context_events arguments. For a memory source, use the exact 64-character memory_item_key, then read:

curl -sS -H "Authorization: Bearer $ANECTICO_TOKEN" \
  "$ANECTICO_URL/api/v1/memory-items/$MEMORY_ITEM_KEY/propagation?project_id=$ANECTICO_PROJECT"

The context source ID must equal memory_item_key, and the propagation point at the model run’s instant must carry the trust label then in force. Source IDs containing whitespace or more than 128 bytes are refused as a whole event; they never appear as partially accepted lineage.