Help us shape the future of Go! Take the 2026 Go Developer Survey

rctx

package
v0.4.45 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package rctx holds the runtime-context protocol: readers and writers for every value carried on context.Context during execution (session, envelope, route, metadata, workspace key, outbound emit), plus inbound MessageEvent route helpers (WithInboundRoute, WithDeliveryRoute, WithDeliverySession) and outbound payload encoding. SessionContext is the history snapshot; execution.Identity identifies a single invocation. This package depends on root/cap contracts, never lifecycle or backend implementations. All runtime layers may depend on it; scope lifecycle lives in runtime/execution.

Index

Constants

View Source
const (
	MetadataSessionScope   = "sessionScope"
	MetadataConversationID = "conversationId"
	MetadataTurnCount      = "turnCount"
)
View Source
const DefaultCLISessionID = agentkit.SessionID("cli:default")

DefaultCLISessionID is the stable CLI session id used when no /new happened.

Variables

This section is empty.

Functions

func ActiveEntryKey

func ActiveEntryKey(route agentkit.RouteRef, policy RoutePolicy, userID string) agentkit.SessionID

ActiveEntryKey returns the stable key for /new active-session mapping.

func ActiveEntryKeyFromContext

func ActiveEntryKeyFromContext(ctx context.Context) agentkit.SessionID

ActiveEntryKeyFromContext derives the stable /new active-session mapping key from the turn route. Conversation may already be resolved to a child session.

func ActiveSessionEntryKey

func ActiveSessionEntryKey(platform string, delivery agentkit.SessionID, scope agentkit.SessionScope, userID string) agentkit.SessionID

ActiveSessionEntryKey returns the stable session-store key used for /new active-session mapping.

func AgentIDFromContext

func AgentIDFromContext(ctx context.Context) agentkit.AgentID

AgentIDFromContext reports the agent executing the current turn.

func ApplyEnvelopeToContext

func ApplyEnvelopeToContext(ctx context.Context, env agentkit.TurnEnvelope) context.Context

ApplyEnvelopeToContext stores the turn envelope on ctx.

func ApplyScope

func ApplyScope(delivery agentkit.SessionID, scope agentkit.SessionScope, userID string) agentkit.SessionID

ApplyScope derives the effective session id used for Loop locking, history, and permission pending.

func BuildDeliverySessionID

func BuildDeliverySessionID(platform, channel, thread, user string) agentkit.SessionID

BuildDeliverySessionID is the canonical finest-grain id platforms should emit.

func BuildSessionRoute

func BuildSessionRoute(in agentkit.SessionRouteInput) agentkit.RouteRef

BuildSessionRoute builds a session-kind RouteRef from structured fields.

func ChannelEntryKey added in v0.4.35

func ChannelEntryKey(route agentkit.RouteRef, policy RoutePolicy, userID string) agentkit.SessionID

ChannelEntryKey returns the stable session-store key for channel-scoped bindings (/agent -c). Its granularity is always the channel, regardless of the configured conversation scope: a channel-level default must not fragment per thread or per user, otherwise the same chat resolves a different default in each thread and a bind set in one thread stays invisible from another. Contrast ActiveEntryKey, whose granularity follows the turn policy and drives /new active-session mapping. Opaque-delivery platforms (ActiveEntryDelivery, e.g. chat-api) keep their raw delivery id.

Thin wrapper over BindKeysForRoute so every binding level shares one key computation.

func ChannelEntryKeyFromContext added in v0.4.35

func ChannelEntryKeyFromContext(ctx context.Context) agentkit.SessionID

ChannelEntryKeyFromContext derives the channel-scoped binding key from the turn route, honouring per-platform policy for opaque-delivery platforms.

func ChannelKeyMatches

func ChannelKeyMatches(jobChannelKey, contextChannelKey string) bool

ChannelKeyMatches reports whether a job belongs to the given channel key.

func ChildConversationID

func ChildConversationID(parentConversation, agentName string, seq int64) string

ChildConversationID returns a subagent conversation id under a parent.

func ContextWithDeliveryRoute

func ContextWithDeliveryRoute(ctx context.Context, platform string, delivery agentkit.SessionID) context.Context

ContextWithDeliveryRoute attaches a minimal session-kind delivery route to ctx.

func ContextWithOutboundEmit

func ContextWithOutboundEmit(ctx context.Context, emit agentkit.OutboundEmit) context.Context

ContextWithOutboundEmit attaches the per-turn outbound hook to ctx.

func ConversationFromContext

func ConversationFromContext(ctx context.Context) string

ConversationFromContext reports the history/lock key for the current turn.

func ConversationFromEvent

func ConversationFromEvent(event agentkit.MessageEvent) agentkit.SessionID

ConversationFromEvent returns the conversation key for Loop locking and history.

func ConversationFromLoopRequest

func ConversationFromLoopRequest(req agentkit.LoopRequest) agentkit.SessionID

ConversationFromLoopRequest returns the conversation key for a queued turn.

func DecodeSessionRoute

func DecodeSessionRoute(route agentkit.RouteRef) (agentkit.SessionRouteTarget, bool)

DecodeSessionRoute decodes a session-kind RouteRef into SessionRouteTarget. Any structured component missing from the payload is derived from the delivery id (mirroring BuildSessionRoute's backfill), so the returned target always carries channel / thread / user on every path — including bare-string and legacy flat-JSON targets persisted before structured fields existed. Callers therefore never re-parse the delivery id.

func DeliveryFromEnvelope

func DeliveryFromEnvelope(env agentkit.TurnEnvelope) agentkit.SessionID

DeliveryFromEnvelope returns the outbound delivery id from a turn envelope.

func DeliveryRouteFromContext

func DeliveryRouteFromContext(ctx context.Context) agentkit.SessionID

DeliveryRouteFromContext returns the platform delivery target from the turn envelope.

func DeliveryWithUser

func DeliveryWithUser(delivery agentkit.SessionID, userID string) agentkit.SessionID

DeliveryWithUser returns a delivery SessionID with the :u: segment set or replaced.

func EnvelopeFromContext

func EnvelopeFromContext(ctx context.Context) agentkit.TurnEnvelope

EnvelopeFromContext returns the current turn envelope, or zero when unset.

func ExecutionIdentityFromContext added in v0.4.39

func ExecutionIdentityFromContext(ctx context.Context) capexecution.Identity

func InboundDeliveryID

func InboundDeliveryID(event agentkit.MessageEvent) agentkit.SessionID

InboundDeliveryID returns the platform delivery target from an inbound message.

func InheritedWorkingDirectory added in v0.4.38

func InheritedWorkingDirectory(ctx context.Context) string

func MarshalOutboundData

func MarshalOutboundData(v any) json.RawMessage

MarshalOutboundData JSON-encodes an outbound event payload.

func MergeEnvelopeMetadata

func MergeEnvelopeMetadata(env agentkit.TurnEnvelope, extra map[string]any) agentkit.TurnEnvelope

MergeEnvelopeMetadata copies extra metadata onto env.

func MetadataFromContext

func MetadataFromContext(ctx context.Context) map[string]any

MetadataFromContext returns platform metadata for the current turn.

func MetadataString

func MetadataString(env agentkit.TurnEnvelope, key string) string

MetadataString returns a trimmed metadata string when present.

func NewCLISessionID

func NewCLISessionID() agentkit.SessionID

NewCLISessionID returns a fresh opaque CLI session id.

func NewConversationID

func NewConversationID(current string) string

NewConversationID returns a fresh conversation id for /new.

func NewSessionID

func NewSessionID(base agentkit.SessionID) agentkit.SessionID

NewSessionID returns a fresh logical session id derived from the current stable session key. CLI keeps its historic cli:<timestamp> format.

func NormalizeSessionID added in v0.4.24

func NormalizeSessionID(ctx context.Context, raw string) agentkit.SessionID

NormalizeSessionID maps slash-style targets to delivery session ids. Bare ids without ":" are qualified with the inbox platform from context.

func OutboundEmitFromContext

func OutboundEmitFromContext(ctx context.Context) agentkit.OutboundEmit

OutboundEmitFromContext returns the per-turn outbound hook, if any.

func OutboundFromEnvelope

func OutboundFromEnvelope(env agentkit.TurnEnvelope, typ agentkit.EventType, data []byte) agentkit.OutboundEvent

OutboundFromEnvelope builds an outbound event from envelope routing context.

func OutboundRoute added in v0.4.24

func OutboundRoute(platform string, deliveryID agentkit.SessionID) agentkit.RouteRef

OutboundRoute builds a session-kind route for proactive delivery.

func OutboundRouteID

func OutboundRouteID(event agentkit.OutboundEvent) agentkit.SessionID

OutboundRouteID returns the platform routing target for an outbound event.

func ParseScope

func ParseScope(raw string) agentkit.SessionScope

ParseScope normalizes runner config. Unknown values fall back to channel scope.

func PlatformFromContext

func PlatformFromContext(ctx context.Context) string

PlatformFromContext reports the platform id for the current turn.

func RegisterPlatformPolicy

func RegisterPlatformPolicy(platform string, policy PlatformSessionPolicy)

RegisterPlatformPolicy registers or overrides routing policy for a platform id.

func ResolveEnvelope

func ResolveEnvelope(event agentkit.MessageEvent, policy RoutePolicy) agentkit.TurnEnvelope

ResolveEnvelope builds a TurnEnvelope from an inbound MessageEvent and policy.

func ResolveRoute added in v0.4.24

func ResolveRoute(ctx context.Context, input delivery.RouteInput) (agentkit.RouteRef, error)

ResolveRoute resolves a user-facing destination selector to its stable RouteRef.

func RouteForPlatform added in v0.4.35

func RouteForPlatform(route agentkit.RouteRef, protocol string) (agentkit.RouteRef, error)

RouteForPlatform resolves an instance selector into the selected leaf's protocol. Transport delivery IDs keep protocol prefixes; Instance retains adapter identity.

func RouteRefFromContext

func RouteRefFromContext(ctx context.Context) agentkit.RouteRef

RouteRefFromContext returns the outbound route from the turn envelope.

func RouteReplyTo

func RouteReplyTo(route agentkit.RouteRef) string

RouteReplyTo returns the ephemeral reply anchor for this turn, if any.

func RouteSessionID

func RouteSessionID(route agentkit.RouteRef) (agentkit.SessionID, bool)

RouteSessionID decodes a session-kind RouteRef into a delivery SessionID.

func SanitizeDirSegment

func SanitizeDirSegment(key string) string

SanitizeDirSegment maps an arbitrary string to a single safe path segment.

func SessionFromContext

func SessionFromContext(ctx context.Context) (agentkit.Session, bool)

SessionFromContext returns the open session when the agent set it for tools.

func SessionIDFromContext

func SessionIDFromContext(ctx context.Context) agentkit.SessionID

SessionIDFromContext reports the history/lock key for the current turn.

func SessionIndexGlobalFromContext added in v0.4.16

func SessionIndexGlobalFromContext(ctx context.Context) bool

SessionIndexGlobalFromContext reports whether global index scope was requested.

func SessionRoute

func SessionRoute(platform, deliveryID string) agentkit.RouteRef

SessionRoute builds a minimal session-kind route from a delivery id string.

func SessionRouteFromDelivery

func SessionRouteFromDelivery(platform string, delivery agentkit.SessionID, replyTo string) agentkit.RouteRef

SessionRouteFromDelivery builds a session route from a delivery SessionID.

func SessionScopeFromContext

func SessionScopeFromContext(ctx context.Context) agentkit.SessionScope

SessionScopeFromContext reads the runner/platform session scope from envelope metadata.

func UserIDFromContext

func UserIDFromContext(ctx context.Context) string

UserIDFromContext reports the end-user id for the current turn.

func WithAgentID

func WithAgentID(ctx context.Context, agentID agentkit.AgentID) context.Context

WithAgentID returns ctx with an updated envelope agent id.

func WithContextMetadata

func WithContextMetadata(ctx context.Context, extra map[string]any) context.Context

WithContextMetadata merges metadata onto the turn envelope.

func WithConversation

func WithConversation(ctx context.Context, conversation string) context.Context

WithConversation returns ctx with an updated envelope conversation.

func WithDeliveryRoute added in v0.3.33

func WithDeliveryRoute(event agentkit.MessageEvent, route agentkit.RouteRef) agentkit.MessageEvent

WithDeliveryRoute attaches the platform return address to an inbound event. Runner resolves conversation and workspace before dispatch.

func WithDeliverySession added in v0.3.33

func WithDeliverySession(event agentkit.MessageEvent, platformID string, delivery agentkit.SessionID) agentkit.MessageEvent

WithDeliverySession builds a session-kind route from platform and delivery ids. Prefer WithInboundRoute when channel, thread, or ReplyTo are known.

func WithExecution added in v0.4.38

func WithExecution(ctx context.Context, execution Execution) context.Context

WithExecution preserves the legacy session-context writer.

func WithExecutionIdentity added in v0.4.39

func WithExecutionIdentity(ctx context.Context, identity capexecution.Identity) context.Context

func WithInboundRoute added in v0.3.33

WithInboundRoute attaches a structured session route to an inbound event.

func WithInheritedWorkingDirectory added in v0.4.38

func WithInheritedWorkingDirectory(ctx context.Context, cwd string) context.Context

WithInheritedWorkingDirectory captures a parent's turn directory as the child's default. It survives clearing an execution snapshot and never copies the parent's history epoch into the child session.

func WithMetadataScope

func WithMetadataScope(env agentkit.TurnEnvelope, scope agentkit.SessionScope) agentkit.TurnEnvelope

WithMetadataScope stamps session scope onto envelope metadata for /new entry-key resolution.

func WithRoute

func WithRoute(ctx context.Context, route agentkit.RouteRef) context.Context

WithRoute returns ctx with an updated envelope route.

func WithSession

func WithSession(ctx context.Context, s agentkit.Session) context.Context

WithSession attaches the turn's open session for tool handlers (e.g. delegate).

func WithSessionContext added in v0.4.39

func WithSessionContext(ctx context.Context, execution SessionContext) context.Context

func WithSessionIndexGlobal added in v0.4.16

func WithSessionIndexGlobal(ctx context.Context) context.Context

WithSessionIndexGlobal opts session-index queries out of channel (workspace) scoping: they span every tenant sharing the backing store. Only stores with a global view (session/sql-index) honor it; file-based indexes are physically per-workspace and ignore the flag.

func WithState added in v0.3.53

func WithState(ctx context.Context, s *State) context.Context

WithState attaches a state bag to ctx, typically once at turn start.

func WithSubagentModelScope added in v0.3.59

func WithSubagentModelScope(ctx context.Context, scope SubagentModelScope) context.Context

WithSubagentModelScope attaches the parent model scope to a child context.

func WithWorkspace

func WithWorkspace(ctx context.Context, workspace string) context.Context

WithWorkspace returns ctx with an updated envelope workspace.

func WithWorkspaceService

func WithWorkspaceService(ctx context.Context, ws workspace.Service) context.Context

WithWorkspaceService attaches the workspace resolver used for session spill files.

func WithoutExecution added in v0.4.38

func WithoutExecution(ctx context.Context) context.Context

WithoutExecution preserves the legacy session-context reset.

func WithoutSessionContext added in v0.4.39

func WithoutSessionContext(ctx context.Context) context.Context

WithoutSessionContext clears a previous turn snapshot while retaining route and workspace identity. The next turn resolves pending bindings again.

func WorkspaceDirName

func WorkspaceDirName(key string) string

WorkspaceDirName maps a workspace key to a single safe path segment.

func WorkspaceFromContext

func WorkspaceFromContext(ctx context.Context) string

WorkspaceFromContext reports the tenant workspace key for the current turn. Runner should set TurnEnvelope.Workspace explicitly; fallback derivation logs a warning.

func WorkspaceKey

func WorkspaceKey(sessionID string) string

WorkspaceKey derives the workspace isolation key from an opaque SessionID. Routable IM-style ids collapse to platform:channel; non-routable ids keep platform plus the first segment after the platform prefix.

func WorkspaceKeyFromLocalDir

func WorkspaceKeyFromLocalDir(dirName string, omitPlatform bool) string

WorkspaceKeyFromLocalDir maps a tenant directory name under localBase back to a workspace key. This mirrors WorkspaceLocalDirName for the common platform_channel layout.

func WorkspaceLocalDirName

func WorkspaceLocalDirName(key string, omitPlatform bool) string

WorkspaceLocalDirName maps a workspace key to a single safe path segment under localBase. When omitPlatform is true, only the first routing segment is used.

func WorkspaceServiceFromContext

func WorkspaceServiceFromContext(ctx context.Context) workspace.Service

WorkspaceServiceFromContext returns the workspace service for spill I/O, if set.

Types

type ActiveEntryMode

type ActiveEntryMode string

ActiveEntryMode selects which key active-session mapping uses.

const (
	ActiveEntryEffective ActiveEntryMode = "effective"
	ActiveEntryDelivery  ActiveEntryMode = "delivery"
)

type AsyncEmitter

type AsyncEmitter struct {
	// contains filtered or unexported fields
}

AsyncEmitter wraps an OutboundEmit so calls return immediately while events are delivered in arrival order by a single goroutine. This keeps async subagent outbound (e.g. ACP SessionUpdate) from blocking the child agent runtime on platform I/O, while preserving event order for progress cards. Close must be called when the emitter is no longer needed to retire the goroutine; events still queued are best-effort drained.

func NewAsyncEmitter

func NewAsyncEmitter(inner agentkit.OutboundEmit) *AsyncEmitter

NewAsyncEmitter returns an emitter that serializes events through a single goroutine. Returns nil when inner is nil so callers can assign directly.

func (*AsyncEmitter) Close

func (e *AsyncEmitter) Close()

Close drains the queue and retires the goroutine. Safe to call once.

func (*AsyncEmitter) CloseWithTimeout

func (e *AsyncEmitter) CloseWithTimeout(d time.Duration) bool

CloseWithTimeout drains the queue like Close but gives up waiting after d. It returns true if the loop retired within d, false if it is still draining (the loop goroutine keeps running best-effort and retires once the queue is empty). Use this on paths where blocking forever on platform I/O would stall a more important step (e.g. async subagent follow-up delivery): the progress card is best-effort UI and must not block the follow-up turn.

func (*AsyncEmitter) Emit

Emit is the OutboundEmit entry point. It never blocks on platform I/O; when the queue is full the event is dropped with a warning rather than stalling the caller or growing without bound.

type BindKeys added in v0.4.35

type BindKeys struct {
	Channel agentkit.SessionID
	Thread  agentkit.SessionID
	User    agentkit.SessionID
	Session agentkit.SessionID
}

BindKeys holds a turn's resolution keys for every dynamic-binding level, computed in one place so no caller hand-rolls a delivery id. The global level is workspace-scoped and needs no key, so it is not a field here.

Granularity, coarse to fine: Channel < Thread|User < Session. Thread and User are mutually exclusive siblings (a delivery id carries :t: or :u:, not both). A level is empty when the route carries no such segment. Session is the resolved conversation history key, which may already point at a /new child.

func BindKeysForRoute added in v0.4.35

func BindKeysForRoute(route agentkit.RouteRef, policy RoutePolicy, userID string, session agentkit.SessionID) BindKeys

BindKeysForRoute derives every route-scoped key under policy from the route's structured target (ChannelID / ThreadID / ScopeUserID), which BuildSessionRoute now fills for every construction path. session is the already-resolved conversation key (inbound: the turn conversation; slash: SessionIDFromContext, optionally upgraded to a /new child with ResolveSessionKey).

Levels reuse the same granularity as ApplyScope, so a bind key equals the session id the runner would lock on for that scope. userID is the actor id (rctx.UserIDFromContext) used when neither the delivery nor the target carries a :u: segment. Opaque-delivery platforms (ActiveEntryDelivery, e.g. chat-api) have no sub-scoping: the raw delivery id is the channel key and the finer levels are empty.

func BindKeysFromContext added in v0.4.35

func BindKeysFromContext(ctx context.Context) BindKeys

BindKeysFromContext derives keys from the turn envelope and route. Channel granularity is always the channel, independent of the configured conversation scope, so a channel-level default never fragments per thread. The user id is read from the envelope actor (UserIDFromContext), the same source the runner uses for route resolution, so the user level is populated even for a delivery that omitted the :u: segment.

type DeliveryParts

type DeliveryParts struct {
	Platform string
	Channel  string
	Thread   string
	User     string
	Routable bool
}

DeliveryParts holds parsed segments of a platform delivery SessionID.

func ParseDelivery

func ParseDelivery(id agentkit.SessionID, fallbackUser string) DeliveryParts

ParseDelivery splits a delivery SessionID into routing segments.

type Execution added in v0.4.38

type Execution struct {
	SessionID agentkit.SessionID
	Cwd       string
	Epoch     string
}

Execution is the immutable history/cwd snapshot prepared for one turn. Its defined type name is retained for runtime/reflection compatibility. Epoch is a durable context version, not an invocation ID.

func ExecutionFromContext added in v0.4.38

func ExecutionFromContext(ctx context.Context) (Execution, bool)

ExecutionFromContext preserves the legacy session-context reader.

type PlatformSessionPolicy

type PlatformSessionPolicy struct {
	ActiveEntryMode ActiveEntryMode
}

PlatformSessionPolicy holds per-platform routing overrides applied on top of runner defaults.

func PlatformSessionPolicyFor

func PlatformSessionPolicyFor(platform string) PlatformSessionPolicy

PlatformSessionPolicyFor returns overrides for a platform, or zero when unset.

type RoutePolicy

type RoutePolicy struct {
	ConversationScope agentkit.SessionScope
	ActiveEntryMode   ActiveEntryMode
}

RoutePolicy configures how inbound routes map to conversation and workspace.

func DefaultRoutePolicy

func DefaultRoutePolicy(conversationScope agentkit.SessionScope) RoutePolicy

DefaultRoutePolicy is runner's default: channel conversation and workspace.

func RoutePolicyForPlatform

func RoutePolicyForPlatform(platform string, base RoutePolicy) RoutePolicy

RoutePolicyForPlatform merges runner defaults with platform-specific overrides.

type RouteTarget

type RouteTarget struct {
	DeliveryID  agentkit.SessionID
	ChannelID   string
	ThreadID    string
	ReplyTo     string
	ScopeUserID string
}

RouteTarget is the decoded delivery target for a session-kind route.

func RouteTargetFromRoute

func RouteTargetFromRoute(route agentkit.RouteRef) (RouteTarget, bool)

RouteTargetFromRoute decodes structured delivery fields from a session route. DecodeSessionRoute already backfills missing components from the delivery id, so the result carries channel/thread/user on every path.

type SessionContext added in v0.4.39

type SessionContext = Execution

SessionContext names the history snapshot separately from invocation identity. It aliases the original defined Execution type, preserving its runtime name.

func SessionContextFromContext added in v0.4.39

func SessionContextFromContext(ctx context.Context) (SessionContext, bool)

type State added in v0.3.53

type State struct {
	// contains filtered or unexported fields
}

State is a mutable per-turn bag injected by the runner at turn start. Hooks, tools, and policies share it for optimization-grade state (caches, reveal sets, markers); it is destroyed with the turn.

Keys use the "namespace.key" convention, namespace = plugin kind (e.g. "tools/deferred.revealed"). State must never affect correctness: plugins degrade to stateless behavior when StateFrom returns nil.

func NewState added in v0.3.53

func NewState() *State

NewState returns an empty turn state bag.

func StateFrom added in v0.3.53

func StateFrom(ctx context.Context) *State

StateFrom returns the turn state bag, or nil when none was injected.

func (*State) Delete added in v0.3.53

func (s *State) Delete(key string)

Delete removes key.

func (*State) Get added in v0.3.53

func (s *State) Get(key string) (any, bool)

Get returns the value for key, or (nil, false) when absent.

func (*State) Set added in v0.3.53

func (s *State) Set(key string, v any)

Set stores v under key, replacing any previous value.

type SubagentModelScope added in v0.3.59

type SubagentModelScope struct {
	ParentAgentID agentkit.AgentID
}

SubagentModelScope carries the parent turn's agent id into a delegated child context. In-process subagent models resolve from explicit config only — the definition model, then global binds keyed by the child agent, then by the parent agent — never from conversation session state.

func SubagentModelScopeFrom added in v0.3.59

func SubagentModelScopeFrom(ctx context.Context) (SubagentModelScope, bool)

SubagentModelScopeFrom returns the parent model scope, or false when the context is not running inside an in-process subagent delegation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL