feat(agenttool): share parent session id with in-process sub-agents#153
Open
alenkacz wants to merge 3 commits into
Open
feat(agenttool): share parent session id with in-process sub-agents#153alenkacz wants to merge 3 commits into
alenkacz wants to merge 3 commits into
Conversation
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>
|
Found 6 test failures on Blacksmith runners: Failures
|
Contributor
|
Codex finished review in 6m26s · The changes compile and the relevant/full test suites pass. I did not identify any introduced correctness issues that warrant an inline finding.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
In-process sub-agents (
agenttool) minted a freshagent-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 viactxpropagation.This makes an
agenttoolsub-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: newContextWithInvocation/InvocationFromContext— the missing channel that lets a tool see its parent invocation.llmagent.executeToolsinjects the invocation intoctxbefore executing tools (additive; tools that don't read it are unaffected).agenttool: when a parent invocation is inctx, 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: canonicalMetadata*linkage key constants (single source of truth).plugins/otel: emitsredpanda.agent.parent_invocation_id/redpanda.agent.pathspan attributes on the invocation span.Isolation & safety
Messagesare still built fresh in memory and never loaded, so it cannot observe the parent's history — sharing the id only affects grouping, not context.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)
session.IDsessionIdInvocationIDagentIdparent_invocation_idparentUuid/toolUseId(An earlier
is_sidechainboolean was dropped — it was Claude-internal jargon and redundant withparent_invocation_id, whose presence is itself the sub-agent signal.)Tests
agent/context_test.goandtool/agenttool/shared_session_test.gocover: round-trip ctx helpers, shared id, context isolation despite shared id, no-parent fallback, and nil-session fallback. Existingagent/llmagent/otel/runnersuites pass;go vet,golangci-lint,gofmtclean.🤖 Generated with Claude Code