diff --git a/agent/assistant/agent.go b/agent/assistant/agent.go index 9c448c0b..5d9f070d 100644 --- a/agent/assistant/agent.go +++ b/agent/assistant/agent.go @@ -55,6 +55,9 @@ func (ast *Assistant) Stream(ctx *context.Context, inputMessages []context.Messa opts = &context.Options{} } + // Merge caller-provided metadata into ctx so sub-agent hooks can read it via ctx.metadata + ctx.MergeMetadata(opts.Metadata) + // Initialize stack and auto-handle completion/failure/restore _, _, done := context.EnterStack(ctx, ast.ID, opts) defer done() diff --git a/agent/context/context.go b/agent/context/context.go index 75f27c0b..b419cf49 100644 --- a/agent/context/context.go +++ b/agent/context/context.go @@ -541,3 +541,19 @@ func (ctx *Context) IsA2ACall() bool { func (ctx *Context) IsForkedA2ACall() bool { return ctx.Referer == RefererAgentFork } + +// MergeMetadata merges the given metadata into ctx.Metadata. +// Existing keys are overwritten by incoming values. +// This enables A2A callers to pass custom metadata (e.g. oneshot, async) +// to sub-agent hooks via ctx.metadata in JavaScript. +func (ctx *Context) MergeMetadata(metadata map[string]interface{}) { + if len(metadata) == 0 { + return + } + if ctx.Metadata == nil { + ctx.Metadata = make(map[string]interface{}, len(metadata)) + } + for k, v := range metadata { + ctx.Metadata[k] = v + } +}