Skip to content

feat(agenttool): share parent session id with in-process sub-agents#153

Open
alenkacz wants to merge 3 commits into
mainfrom
av/shared-session-id-subagents
Open

feat(agenttool): share parent session id with in-process sub-agents#153
alenkacz wants to merge 3 commits into
mainfrom
av/shared-session-id-subagents

Conversation

@alenkacz

Copy link
Copy Markdown
Contributor

What

In-process sub-agents (agenttool) minted a fresh agent-tool-<name>-<nano> session id per call, so the OTel conversation id differed from the parent and the two appeared as separate conversations in session-oriented observability (e.g. Langfuse) — even though the trace tree is already connected via ctx propagation.

This makes an agenttool sub-agent share its parent's session id when invoked as part of a parent agent's turn, so the two group into one conversation for tracing/reconstruction. Context stays fully isolated.

How

  • agent: new ContextWithInvocation / InvocationFromContext — the missing channel that lets a tool see its parent invocation. llmagent.executeTools injects the invocation into ctx before executing tools (additive; tools that don't read it are unaffected).
  • agenttool: when a parent invocation is in ctx, the sub-agent shares the parent's session id and stamps linkage (parent_invocation_id, agent_path) into session metadata. Falls back to the previous minted id when there is no parent invocation.
  • store/session: canonical Metadata* linkage key constants (single source of truth).
  • plugins/otel: emits redpanda.agent.parent_invocation_id / redpanda.agent.path span attributes on the invocation span.

Isolation & safety

  • Isolation is preserved: the sub-agent's Messages are still built fresh in memory and never loaded, so it cannot observe the parent's history — sharing the id only affects grouping, not context.
  • The sub-agent path never persists (no Runner, no store on llmagent), so the shared id is safe as a non-storage-key. A code comment records the guard: if persistence is ever added on this path, key on the unique invocation id / agent_path, not the shared session id.

Linkage surface (maps to Claude's model)

Concern Field Claude analog
Grouping shared session.ID sessionId
Per-sub-agent identity child InvocationID agentId
Parent back-reference parent_invocation_id parentUuid / toolUseId

(An earlier is_sidechain boolean was dropped — it was Claude-internal jargon and redundant with parent_invocation_id, whose presence is itself the sub-agent signal.)

Tests

agent/context_test.go and tool/agenttool/shared_session_test.go cover: round-trip ctx helpers, shared id, context isolation despite shared id, no-parent fallback, and nil-session fallback. Existing agent/llmagent/otel/runner suites pass; go vet, golangci-lint, gofmt clean.

🤖 Generated with Claude Code

alenkacz and others added 3 commits June 16, 2026 16:47
In-process sub-agents (agenttool) minted a fresh `agent-tool-<name>-<nano>`
session id per call, so the OTel conversation id differed from the parent and
the two showed up as separate conversations in session-oriented observability
(e.g. Langfuse), even though the trace tree is already connected via ctx.

When a parent invocation is present in context, the sub-agent now shares the
parent's session id so the two group into one conversation, and stamps linkage
(is_sidechain / parent_invocation_id / agent_path) for reconstruction. Context
stays isolated: the sub-agent's Messages are still built fresh and never loaded,
so it cannot observe the parent's history. Falls back to the minted id when no
parent invocation is in context.

- agent: ContextWithInvocation / InvocationFromContext; llmagent injects the
  invocation into ctx before executing tools
- store/session: canonical Metadata* linkage key constants
- plugins/otel: emit redpanda.agent.* linkage span attributes on the invocation

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ent_invocation_id

"sidechain" was borrowed from Claude Code's internal transcript field and reads
as jargon outside that context. The boolean was also redundant: parent_invocation_id
is only set on sub-agent runs, so its presence already signals a sub-agent. Drop
the flag and rely on the linkage fields (parent_invocation_id + agent_path).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…isted

Preserve the intent of the removed "unique id prevents store collisions" comment:
the id may now be shared with the parent, which is safe only because the sub-agent
session is never loaded or persisted. If a store is ever added on this path, it must
key on the unique invocation id / agent_path, not the shared session id.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@blacksmith-sh

blacksmith-sh Bot commented Jun 17, 2026

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
github.com/redpanda-data/ai-sdk-go/providers/anthropic/
TestAnthropicConformance_Integration
View Logs
github.com/redpanda-data/ai-sdk-go/runner/TestOpenAICompatProviders/Anthropic View Logs
github.com/redpanda-data/ai-sdk-go/tool/builtin/plot/TestOpenAICompatProviders View Logs
github.com/redpanda-data/ai-sdk-go/tool/mcp/TestAnthropicConformance_Integration/
TestAllSupportedModels
View Logs
github.com/redpanda-data/ai-sdk-go/tool/mcp/TestAnthropicConformance_Integration/
TestAllSupportedModels/basic_generation_works_for_all_supported_models
View Logs
github.com/redpanda-data/ai-sdk-go/tool/mcp/TestAnthropicConformance_Integration/
TestAllSupportedModels/basic_generation_works_for_all_supported_models/
model_claude-fable-5
View Logs

Fix in Cursor

@birdayz

birdayz commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Codex finished review in 6m26s · 63d26aac


The changes compile and the relevant/full test suites pass. I did not identify any introduced correctness issues that warrant an inline finding.


29 tool-calls · Generated by Codex 0.139.0 on gpt-5.5 (xhigh) and codex-review

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants