package loop import "context" // loopSessionIDKey is the context key for the session id the current Run is // driving. It is seeded at the top of Run and read where the loop emits a // session-scoped UI event (capacity_awaken), so the event carries the right // session rather than being treated as global. type loopSessionIDKey struct{} // withLoopSession returns a context carrying the Run's session id. func withLoopSession(ctx context.Context, sessionID string) context.Context { return context.WithValue(ctx, loopSessionIDKey{}, sessionID) } // loopSession returns the session id on ctx, or "" when none was seeded (a // defensive fallback for a caller that drives the loop outside Run). func loopSession(ctx context.Context) string { s, _ := ctx.Value(loopSessionIDKey{}).(string) return s } // SessionFromContext returns the session id the enclosing Run is driving, or "" // when none was attached. It is exported so a tool executing inside the loop can // attribute the work it starts (a spawned sub-agent, a background task) to the // conversation that launched it — never inferred from model output. func SessionFromContext(ctx context.Context) string { return loopSession(ctx) } // loopTurnIDKey is the context key for the assistant turn the current Run is // producing. The gateway attaches it (WithTurnID) before starting a turn so the // streaming events the loop emits can be correlated to that turn by the client. type loopTurnIDKey struct{} // WithTurnID attaches turnID to ctx so the streaming events the loop emits carry // the turn they belong to. It is exported because the gateway calls it once per // turn, before Run; a caller that attaches none leaves the events' TurnID empty, // which keeps the correlation fields backward compatible. func WithTurnID(ctx context.Context, turnID string) context.Context { return context.WithValue(ctx, loopTurnIDKey{}, turnID) } // loopTurn returns the turn id on ctx, or "" when none was attached. func loopTurn(ctx context.Context) string { s, _ := ctx.Value(loopTurnIDKey{}).(string) return s }