Documentation
¶
Index ¶
- Constants
- Variables
- func ContextWithOutboundEmit(ctx context.Context, emit OutboundEmit) context.Context
- func FormatToolResult(out any) (string, error)
- func IsAdmin(ctx context.Context) bool
- func MarshalOutboundData(v any) json.RawMessage
- type ACPCommandCapable
- type ACPCommandCatalog
- type ACPCommandInfo
- type ACPConfigOptionInfo
- type ACPConfigOptionValue
- type ActiveSessionStore
- type ActorRef
- type AfterToolHook
- type Agent
- type AgentBindStore
- type AgentCatalogEntry
- type AgentID
- type AppInitializer
- type Approval
- type ApprovalDecision
- type ApprovalRequest
- type AssistantMessageEvent
- type AssistantMessageEventType
- type BeforeStep
- type BeforeStepHook
- type BeforeToolHook
- type BudgetState
- type Command
- type CommandCollector
- type CommandProvider
- type Commands
- type ContentPart
- type Decision
- type DecisionKind
- type EventID
- type EventSeq
- type EventType
- type FollowUpMode
- type Hook
- type HookProvider
- type HookRuntime
- type JSONSchema
- type LLMEvent
- type LLMProvider
- type LLMRequest
- type LLMStream
- type Loop
- type LoopRequest
- type MessageEndPayload
- type MessageEvent
- type MessageStartPayload
- type MessageUpdatePayload
- type ModelMessage
- type OutboundEmit
- type OutboundEvent
- type Platform
- type PlatformIdentifier
- type Policy
- type PolicyInput
- type PromptAssembler
- type PromptRequest
- type PromptSection
- type RouteKind
- type RouteRef
- type Runner
- type Section
- type SectionProvider
- type Session
- type SessionEvent
- type SessionID
- type SessionRouteTarget
- type SessionStore
- type SlashAdminContext
- type Tool
- type ToolBuilder
- type ToolCall
- type ToolCallID
- type ToolPack
- type ToolProvider
- type ToolResult
- type ToolRuntime
- type ToolSpec
- type TurnEnvelope
- func (e TurnEnvelope) WithAgentID(agentID AgentID) TurnEnvelope
- func (e TurnEnvelope) WithConversation(conversation string) TurnEnvelope
- func (e TurnEnvelope) WithMetadata(metadata map[string]any) TurnEnvelope
- func (e TurnEnvelope) WithRoute(route RouteRef) TurnEnvelope
- func (e TurnEnvelope) WithWorkspace(workspace string) TurnEnvelope
- type TurnInput
- type TurnStopReason
- type TurnStopping
- type TurnStoppingHook
- type Usage
- type UserTimezoneProvider
Constants ¶
const ( // KeyTurnID is the context key for the current turn, when one is active. KeyTurnID contextKey = "agentkit.turn_id" // KeyToolCallID is the context key for the current tool call, when one is active. KeyToolCallID contextKey = "agentkit.tool_call_id" // KeySessionControl is the context key for per-session steer/follow-up state. // Loop sets it before Agent.RunTurn; the value is a runtime/loop.Control that // also implements permission.Broker. KeySessionControl contextKey = "agentkit.session_control" // KeyOutboundEmit is the per-turn outbound hook. Loop sets it before // Agent.RunTurn so tools and permission waits can emit outbound events // through the same channel as assistant streaming. KeyOutboundEmit contextKey = "agentkit.outbound_emit" // KeyInSubagent marks a context running inside a delegated child agent. KeyInSubagent contextKey = "agentkit.subagent.active" // KeyProactiveSendUsed is set when tool/send delivers through the turn emit // channel during the current turn. KeyProactiveSendUsed contextKey = "agentkit.proactive_send_used" // KeyScheduleFireTurn marks a turn started by schedule runtime. Turn-end // assistant text may be suppressed when send already delivered the message. KeyScheduleFireTurn contextKey = "agentkit.schedule_fire_turn" // KeyScheduleStateless marks a schedule-fired turn that must not inherit the // delivery conversation's active session history (similar to KeyInSubagent). KeyScheduleStateless contextKey = "agentkit.schedule_stateless" // KeyTurnEnvelope carries the normalized Route / Conversation / Workspace // context for the current turn. Runner sets it before Loop.Dispatch. KeyTurnEnvelope contextKey = "agentkit.turn_envelope" )
const InboundMetaTag = "meta"
InboundMetaTag is the bracket tag for runner inject prefixes on user messages. Example: [meta sender_id=U111 sender_name="Alice" timestamp="..." timezone="UTC"]
const (
// KeyIsAdmin marks whether the current user is configured as an admin.
KeyIsAdmin contextKey = "agentkit.is_admin"
)
const MetadataSkipPromptMeta = "skipPromptMeta"
MetadataSkipPromptMeta, when true on MessageEvent.Metadata, tells runner not to prepend the optional [meta ...] inbound prefix for that turn.
Variables ¶
var ErrCommandForbidden = errors.New("command forbidden")
ErrCommandForbidden means the caller is not allowed to run the command.
var ErrCommandNotHandled = errors.New("command not handled")
ErrCommandNotHandled means the name is not a registered slash command.
var ErrOutboundPlatformRequired = errors.New("outbound event requires platformID")
ErrOutboundPlatformRequired is returned when OutboundEvent.PlatformID is empty.
Functions ¶
func ContextWithOutboundEmit ¶ added in v0.2.1
func ContextWithOutboundEmit(ctx context.Context, emit OutboundEmit) context.Context
ContextWithOutboundEmit attaches the per-turn outbound hook to ctx.
func FormatToolResult ¶ added in v0.1.2
FormatToolResult converts a typed tool handler result into model-visible text.
func IsAdmin ¶ added in v0.1.16
IsAdmin reports whether ctx carries admin privileges for the current user.
func MarshalOutboundData ¶
func MarshalOutboundData(v any) json.RawMessage
Types ¶
type ACPCommandCapable ¶ added in v0.2.0
type ACPCommandCapable interface {
Agent
ACPCommandCatalog(ctx context.Context, sessionID SessionID) (ACPCommandCatalog, error)
SetACPConfigOption(ctx context.Context, sessionID SessionID, key, value string) (string, error)
}
ACPCommandCapable is implemented by agent/acp-remote instances. It exposes ACP session config control via session/set_config_option, without going through the AgentKit LLM loop or session/prompt.
type ACPCommandCatalog ¶ added in v0.2.0
type ACPCommandCatalog struct {
AvailableCommands []ACPCommandInfo
ConfigOptions []ACPConfigOptionInfo
}
ACPCommandCatalog is the cached native command surface of an ACP remote session.
type ACPCommandInfo ¶ added in v0.2.0
ACPCommandInfo describes one native slash command advertised by an ACP agent.
type ACPConfigOptionInfo ¶ added in v0.2.0
type ACPConfigOptionInfo struct {
ID string
Name string
Category string
Type string
CurrentValue string
Description string
Options []ACPConfigOptionValue
}
ACPConfigOptionInfo is a display snapshot of a session config option from ACP.
type ACPConfigOptionValue ¶ added in v0.2.0
ACPConfigOptionValue is one selectable value for a select-type config option.
type ActiveSessionStore ¶ added in v0.1.6
type ActiveSessionStore interface {
ActiveSession(context.Context, SessionID) (SessionID, error)
SetActiveSession(context.Context, SessionID, SessionID) error
}
ActiveSessionStore maps stable platform/effective session keys to the logical session currently used for model-visible history. Missing mapping means the key itself is the logical session.
type ActorRef ¶ added in v0.2.1
type ActorRef struct {
UserID string `json:"userId,omitempty"`
Name string `json:"name,omitempty"`
Email string `json:"email,omitempty"`
}
ActorRef identifies who spoke on an inbound turn.
type AfterToolHook ¶
type AfterToolHook interface {
Hook
AfterTool(context.Context, *ToolResult) error
}
func OnAfterTool ¶
func OnAfterTool(fn func(context.Context, *ToolResult) error) AfterToolHook
OnAfterTool wraps a function as an AfterToolHook.
type Agent ¶
Agent is the execution unit below Loop. It owns prompt, model, tools, policies and hooks for a single agent identity. Conversation state lives in Session; the agent implementation resolves Session via SessionStore using SessionIDFromContext. Loop does not inject Session objects or duplicate routing fields in TurnInput.
Steer/follow-up/cancel are owned by Loop per conversation. Loop seeds ctx.Value(KeySessionControl) before RunTurn; Agent reads it to inject queued steering messages at step boundaries without interrupting in-flight steps.
Agent plugins declare SessionStore in their Deps struct (pluginkit injection).
type AgentBindStore ¶ added in v0.1.6
type AgentBindStore interface {
AgentBind(ctx context.Context, id SessionID) (AgentID, error)
SetAgentBind(ctx context.Context, id SessionID, agent AgentID) error
}
AgentBindStore reads and writes per-session agent routing beside session logs. Missing bind means Runner falls back to loop.defaultAgent.
type AgentCatalogEntry ¶ added in v0.1.5
type AgentCatalogEntry interface {
AgentCatalogEntry() string
}
AgentCatalogEntry optionally describes a built agent for /agent help output.
type AppInitializer ¶ added in v0.1.18
AppInitializer performs one-time setup before the runner serves traffic. Examples: seed workspace directories, copy bundled agents/skills, init git.
Config (bootstrap/shell):
runner.default:
deps:
init:
- bootstrap.shell.default
bootstrap.shell.default:
use: bootstrap/shell
config:
commands:
- echo "init"
deps:
workspace: workspace.default
Distinct from StartStop.Start: InitApp runs once at process start and should be idempotent; Start launches long-running background work.
type Approval ¶
type Approval interface {
Ask(context.Context, ApprovalRequest) (ApprovalDecision, error)
}
type ApprovalDecision ¶
type ApprovalRequest ¶
type AssistantMessageEvent ¶
type AssistantMessageEvent struct {
Type AssistantMessageEventType `json:"type"`
ContentIndex int `json:"contentIndex,omitempty"`
Delta string `json:"delta,omitempty"`
Content string `json:"content,omitempty"`
ID string `json:"id,omitempty"`
ToolName string `json:"toolName,omitempty"`
ToolCall *ToolCall `json:"toolCall,omitempty"`
Reason string `json:"reason,omitempty"`
ErrorMessage string `json:"errorMessage,omitempty"`
}
AssistantMessageEvent is the wire-safe Pi RPC delta payload (no cumulative partial).
type AssistantMessageEventType ¶
type AssistantMessageEventType string
AssistantMessageEventType mirrors Pi RPC assistantMessageEvent.type values.
const ( AssistantEventStart AssistantMessageEventType = "start" AssistantEventTextStart AssistantMessageEventType = "text_start" AssistantEventTextDelta AssistantMessageEventType = "text_delta" AssistantEventTextEnd AssistantMessageEventType = "text_end" AssistantEventThinkingStart AssistantMessageEventType = "thinking_start" AssistantEventThinkingDelta AssistantMessageEventType = "thinking_delta" AssistantEventThinkingEnd AssistantMessageEventType = "thinking_end" AssistantEventToolCallStart AssistantMessageEventType = "toolcall_start" AssistantEventToolCallDelta AssistantMessageEventType = "toolcall_delta" AssistantEventToolCallEnd AssistantMessageEventType = "toolcall_end" AssistantEventDone AssistantMessageEventType = "done" AssistantEventError AssistantMessageEventType = "error" )
const LLMEventMessage AssistantMessageEventType = "message"
LLMEventMessage carries a finalized (or snapshot) ModelMessage rather than a delta. It is internal to the provider/agent boundary and is never forwarded to platforms, so it has no counterpart in the Pi RPC event set.
type BeforeStep ¶
type BeforeStep struct {
Messages []ModelMessage
}
BeforeStep is invoked before a model step. Hooks read routing context from ctx.Value(KeyTurnEnvelope) / SessionIDFromContext; hooks that need durable state should depend on SessionStore via pluginkit Deps.
type BeforeStepHook ¶
type BeforeStepHook interface {
Hook
BeforeStep(context.Context, *BeforeStep) error
}
func OnBeforeStep ¶
func OnBeforeStep(fn func(context.Context, *BeforeStep) error) BeforeStepHook
OnBeforeStep wraps a function as a BeforeStepHook.
type BeforeToolHook ¶
func OnBeforeTool ¶
func OnBeforeTool(fn func(context.Context, *ToolCall) error) BeforeToolHook
OnBeforeTool wraps a function as a BeforeToolHook.
type BudgetState ¶
type BudgetState struct {
RemainingSteps int
RemainingContinuations int
RemainingSeconds int
RemainingTokens int
// SoftExhausted is true once any limited dimension crosses softRatio.
SoftExhausted bool
// Exhausted is true when a hard limit is reached; Continue is then ignored.
Exhausted bool
}
BudgetState reports what is left of the run budget. Unlimited dimensions report -1 so hooks can distinguish "no limit" from "nothing left".
type Command ¶
type Command interface {
Name() string
Alias() string
Description() string
CommandExec(ctx context.Context, args string) (string, error)
}
Command is one slash command contribution.
type CommandCollector ¶
type CommandCollector interface {
SetCommands(providers []CommandProvider) error
}
CommandCollector receives CommandProvider contributions after pluginkit build. Runner wires them with build.WireContributions during Run.
type CommandProvider ¶
type CommandProvider interface {
Commands() []Command
}
CommandProvider contributes human-facing commands from a built plugin instance. It is designed to work with pluginkit/build.WireContributions so commands can live next to the capability that owns their behavior.
type Commands ¶
type Commands interface {
Dispatch(ctx context.Context, name string, rawArgs string) (string, error)
List() []Command
}
Commands is a post-build slash command catalog for platforms.
type ContentPart ¶
type ContentPart struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
URL string `json:"url,omitempty"`
MIME string `json:"mime,omitempty"`
Detail string `json:"detail,omitempty"`
// Source is a workspace-relative attachment path (e.g. work/upload/foo.png) used
// for session persistence and vision replay; not sent to model providers.
// Persisted attachments use type attachment_ref (see runtime/media).
Source string `json:"source,omitempty"`
}
type Decision ¶
type Decision struct {
Kind DecisionKind
Reason string
// Audit is merged into ToolResult.Audit when the tool runtime denies a call.
Audit map[string]string
}
type DecisionKind ¶
type DecisionKind string
const ( DecisionAllow DecisionKind = "allow" DecisionDeny DecisionKind = "deny" DecisionAsk DecisionKind = "ask" )
type EventType ¶
type EventType string
const ( EventTurnStart EventType = "turn/start" EventTurnEnd EventType = "turn/end" EventStepStart EventType = "step/start" EventStepEnd EventType = "step/end" EventUserMessage EventType = "user/message" EventMessageStart EventType = "message/start" EventMessageUpdate EventType = "message/update" EventMessageEnd EventType = "message/end" EventAssistantMessage EventType = "assistant/message" EventToolCall EventType = "tool/call" EventToolResult EventType = "tool/result" EventCompaction EventType = "session/compaction" EventSkillLoad EventType = "skill/load" EventAutoRetryStart EventType = "retry/start" EventAutoRetryEnd EventType = "retry/end" EventSummarizationRetryStart EventType = "summarization/retry/start" EventSummarizationRetryEnd EventType = "summarization/retry/end" EventOverflowRecovery EventType = "overflow/recovery" EventTurnContinue EventType = "turn/continue" EventUsage EventType = "usage" EventTodoUpdate EventType = "todo/update" EventRunFinish EventType = "run/finish" EventSessionRecovery EventType = "session/recovery" EventSubagentStart EventType = "subagent/start" EventSubagentEnd EventType = "subagent/end" EventPermissionRequest EventType = "permission/request" EventPermissionResolved EventType = "permission/resolved" )
type FollowUpMode ¶
type FollowUpMode string
FollowUpMode controls how queued follow-up messages are drained after a turn.
const ( FollowUpOneAtATime FollowUpMode = "one-at-a-time" FollowUpAll FollowUpMode = "all" )
type Hook ¶
type Hook interface {
// contains filtered or unexported methods
}
Hook marks a value that may implement one or more hook point interfaces. Execution order follows deps.providers list order; within a provider, Hooks() slice order is preserved.
type HookProvider ¶
type HookProvider interface {
Hooks() []Hook
}
type HookRuntime ¶
type JSONSchema ¶
type JSONSchema struct {
Type string `json:"type,omitempty"`
Description string `json:"description,omitempty"`
Properties map[string]JSONSchema `json:"properties,omitempty"`
Required []string `json:"required,omitempty"`
Items *JSONSchema `json:"items,omitempty"`
Raw map[string]any `json:"-"`
}
func (JSONSchema) MarshalJSON ¶
func (s JSONSchema) MarshalJSON() ([]byte, error)
MarshalJSON emits Raw when set so MCP and other external schemas round-trip intact.
func (*JSONSchema) UnmarshalJSON ¶
func (s *JSONSchema) UnmarshalJSON(data []byte) error
UnmarshalJSON stores the full object in Raw and also fills known fields when present.
type LLMEvent ¶
type LLMEvent struct {
Type AssistantMessageEventType
Message *ModelMessage
ContentIndex int
Delta string
ToolCall *ToolCall
Usage *Usage
}
LLMEvent reuses AssistantMessageEventType so provider output and the platform-facing stream share one vocabulary. Providers emit the text_*, thinking_* and toolcall_* values plus LLMEventMessage; AssistantEventDone and AssistantEventError are wire-only and never produced here.
type LLMProvider ¶
LLMProvider streams model responses for an already assembled request. LLMRequest carries model-visible messages only; session routing is handled by the agent runtime before and after the provider boundary.
type LLMRequest ¶
type LLMRequest struct {
Model string
Messages []ModelMessage
Tools []ToolSpec
}
type Loop ¶
type Loop interface {
Dispatch(context.Context, LoopRequest) error
Steer(context.Context, ModelMessage) error
FollowUp(context.Context, ModelMessage) error
// Cancel requests the in-flight turn for the session in ctx to stop. The
// conversation key is read from TurnEnvelope, same as Steer/FollowUp.
Cancel(context.Context, string) error
// IsSessionBusy reports whether a turn is currently executing for the session.
IsSessionBusy(SessionID) bool
// TryDeliverPermission consumes a typed permission reply. It returns true
// when the message was handled and must not start a new turn.
TryDeliverPermission(MessageEvent) bool
// SupersedePendingForInbound cancels an active permission wait when a new
// user message arrives without a permission reply.
SupersedePendingForInbound(MessageEvent)
}
Loop is the turn scheduler. It routes inbound MessageEvents to agents, serializes work per Conversation, and owns per-session steer/follow-up control. Loop seeds ctx with KeyTurnEnvelope (conversation, agent, route, workspace) and KeyOutboundEmit before calling the agent. It does not resolve Session objects; that is the agent's responsibility.
type LoopRequest ¶
type LoopRequest struct {
Event MessageEvent
Emit OutboundEmit
Capability any // permission.Capability, resolved by runner from the inbound platform
}
LoopRequest wraps one inbound message. Runner resolves TurnEnvelope on Event.Envelope before Dispatch: Conversation for history/lock, Route for outbound Send.
type MessageEndPayload ¶
type MessageEndPayload struct {
Message ModelMessage `json:"message"`
}
MessageEndPayload is emitted when an assistant message is finalized.
type MessageEvent ¶
type MessageEvent struct {
// Envelope is optional on ingress; runner fills it when empty.
Envelope TurnEnvelope `json:"envelope,omitempty"`
AgentID AgentID
PlatformID string
UserID string
Message ModelMessage
// Metadata is optional platform context copied onto persisted user messages.
Metadata map[string]any `json:"metadata,omitempty"`
// Reply carries a permission answer as JSON. Decode with runtime/permission.DecodeReply.
Reply json.RawMessage `json:"reply,omitempty"`
}
MessageEvent is the inbound envelope from Platform to Loop.
Platforms should set Envelope.Route on ingress (e.g. common.WithInboundRoute). Runner normalizes into TurnEnvelope before Dispatch: Conversation for history/lock, Workspace for tenant resources, Route for outbound return path.
type MessageStartPayload ¶
type MessageStartPayload struct {
Message ModelMessage `json:"message"`
}
MessageStartPayload is emitted when assistant streaming begins.
type MessageUpdatePayload ¶
type MessageUpdatePayload struct {
Usage *Usage `json:"usage,omitempty"`
AssistantMessageEvent AssistantMessageEvent `json:"assistantMessageEvent"`
}
MessageUpdatePayload matches Pi RPC message_update events.
type ModelMessage ¶
type ModelMessage struct {
Role string
Content []ContentPart
ToolCalls []ToolCall
ToolResults []ToolResult
}
ModelMessage is model-visible content only. Session routing lives on event envelopes and context keys, not on ModelMessage.
type OutboundEmit ¶
type OutboundEmit func(context.Context, OutboundEvent) error
OutboundEmit sends platform events during a turn. When nil, streaming is suppressed.
func OutboundEmitFromContext ¶ added in v0.2.1
func OutboundEmitFromContext(ctx context.Context) OutboundEmit
OutboundEmitFromContext returns the per-turn outbound hook, if any.
type OutboundEvent ¶
type OutboundEvent struct {
Route RouteRef
AgentID AgentID
PlatformID string // required
UserID string
Type EventType
Data json.RawMessage
}
OutboundEvent is the outbound envelope from Agent/Loop to Platform. Route is the return address captured at inbound. PlatformID is required; multiplex rejects empty values.
func (OutboundEvent) RequirePlatformID ¶ added in v0.1.10
func (e OutboundEvent) RequirePlatformID() error
RequirePlatformID reports whether the event names a target platform.
type Platform ¶
type Platform interface {
Receive(context.Context) (MessageEvent, error)
Send(context.Context, OutboundEvent) error
}
Platform adapts external transports into AgentKit message events. Platforms should populate Envelope.Route on ingress (e.g. common.WithDeliveryRoute); runner normalizes TurnEnvelope before Loop.Dispatch. OutboundEvent.Route is the return address.
Concurrency contract:
- Receive is called from a single goroutine and may block.
- Send must be safe for concurrent use. Runner runs turns from different effective sessions in parallel (runner.config.maxConcurrentTurns, default 64); each turn emits from its own goroutine.
type PlatformIdentifier ¶ added in v0.1.1
type PlatformIdentifier interface {
PlatformID() string
}
PlatformIdentifier exposes the stable routing ID for a leaf platform. Multiplex and other aggregators use it to key sub-platforms without extra config; conflicts are disambiguated with an index suffix.
type Policy ¶
type Policy interface {
Evaluate(context.Context, PolicyInput) (Decision, error)
}
func PolicyFunc ¶
func PolicyFunc(fn func(context.Context, PolicyInput) Decision) Policy
PolicyFunc wraps a function as a Policy implementation.
type PolicyInput ¶
type PolicyInput struct {
ToolCall *ToolCall
}
PolicyInput carries the policy payload. Per-conversation policy should read SessionIDFromContext / AgentIDFromContext / UserIDFromContext.
type PromptAssembler ¶
type PromptAssembler interface {
Assemble(context.Context, PromptRequest) ([]ModelMessage, error)
}
PromptAssembler builds the model request prompt from registered sections.
type PromptRequest ¶
type PromptRequest struct {
Messages []ModelMessage
}
PromptRequest carries model-visible prompt inputs. Routing context is read from TurnEnvelope / SessionIDFromContext / AgentIDFromContext / UserIDFromContext, not duplicated here.
type PromptSection ¶
PromptSection is one section provider contribution before it is folded into the leading system message.
type RouteKind ¶ added in v0.2.1
type RouteKind string
RouteKind identifies the payload schema stored in RouteRef.Target.
const RouteKindSession RouteKind = "session"
RouteKindSession marks a route that returns to an IM-style delivery inbox.
type RouteRef ¶ added in v0.2.1
type RouteRef struct {
Platform string `json:"platform,omitempty"`
Kind RouteKind `json:"kind"`
Target json.RawMessage `json:"target,omitempty"`
}
RouteRef identifies where outbound events should be delivered.
Core layers (Runner / Loop / Agent / tools) treat RouteRef as opaque and only store or copy it. Platform adapters decode by Kind via runtime/session codecs.
Today only RouteKindSession is used. Future kinds (webhook, email, …) should add their own typed payload in Target; do not grow flat IM fields on RouteRef.
func SessionRoute
deprecated
added in
v0.2.1
func (RouteRef) HasTarget ¶ added in v0.2.1
HasTarget reports whether the route carries a delivery target payload.
func (RouteRef) IsZero ¶ added in v0.2.1
IsZero reports whether the route carries no platform, kind, or target.
func (RouteRef) MarshalJSON ¶ added in v0.2.1
MarshalJSON writes the stable wire form: platform, kind, target.
func (*RouteRef) UnmarshalJSON ¶ added in v0.2.1
UnmarshalJSON accepts target payloads and legacy session/data/flat encodings.
type Runner ¶
type Runner interface {
// Run starts the process. result is the build graph produced alongside this
// runner; implementations wire CommandProvider contributions to
// commands/registry and run AppInitializer hooks before serving traffic.
Run(context.Context, *build.Result) error
Stop(context.Context) error
}
Runner is the root plugin type. It owns process lifecycle and connects a Platform to a Loop.
type Section ¶
type Section struct {
Name string
Build func(context.Context, PromptRequest) (PromptSection, error)
}
type SectionProvider ¶
type SectionProvider interface {
Sections() []Section
}
type Session ¶
type Session interface {
ID() SessionID
Append(context.Context, SessionEvent) (EventSeq, error)
Read(context.Context, EventSeq) ([]SessionEvent, error)
DeriveMessages(context.Context) ([]ModelMessage, error)
}
Session is the durable source of truth for model-visible state.
type SessionEvent ¶
type SessionEvent struct {
ID EventID
Seq EventSeq
SessionID SessionID
AgentID AgentID
Type EventType
Data json.RawMessage
CreatedAt time.Time
// UserID attributes the event to an end user. It is set on user messages
// when the platform knows who spoke, and is what makes a session shared by a
// whole Slack channel legible: without it the model reads one undifferentiated
// stream of user turns. Empty for single-user transports such as the CLI, and
// for everything the agent itself produces.
UserID string
// Metadata carries optional platform fields for replay-time user-message
// templates (display name, channel label, etc.). Persisted on user messages.
Metadata map[string]any `json:"metadata,omitempty"`
}
type SessionID ¶
type SessionID string
SessionID identifies a conversation unit for Loop locking and durable history. Platforms emit a delivery route (finest grain: channel + optional :t:thread + optional :u:user). Runner resolves active-session mappings (/new) and writes the resulting conversation into TurnEnvelope before Loop.Dispatch. Outbound replies still use the delivery route.
Delivery examples:
slack:C123ABC slack:C123ABC:t:1712345678.123456:u:U456 feishu:oc_xxx:om_yyy cli:default
Only platform plugins decode delivery SessionIDs into IM routing targets.
type SessionRouteTarget ¶ added in v0.2.1
type SessionRouteTarget struct {
DeliveryID SessionID `json:"deliveryId,omitempty"`
ChannelID string `json:"channelId,omitempty"`
ThreadID string `json:"threadId,omitempty"`
ScopeUserID string `json:"scopeUserId,omitempty"`
ReplyTo string `json:"replyTo,omitempty"`
}
SessionRouteTarget is the delivery payload for RouteKindSession.
DeliveryID is the stable return path (active-session / delivery key). When empty it is derived from Platform + ChannelID + ThreadID + ScopeUserID.
ReplyTo is an ephemeral inbound message anchor for threaded replies during this turn; it is not part of the stable delivery key.
ScopeUserID is the :u: segment in delivery ids (routing scope), not the speaking user — see TurnEnvelope.Actor for actor identity.
func (SessionRouteTarget) HasTarget ¶ added in v0.2.1
func (t SessionRouteTarget) HasTarget() bool
HasTarget reports whether the payload carries a delivery id or channel.
type SessionStore ¶
SessionStore resolves durable sessions by opaque SessionID. Platform plugins generate SessionID values (cc-connect style: platform:segment:...); agent plugins depend on SessionStore and call Get with the logical history id resolved for the turn. Loop only uses SessionID for routing and per-session locking (TurnEnvelope.Conversation), never SessionStore.Get.
type SlashAdminContext ¶ added in v0.1.16
SlashAdminContext enriches slash command ctx (for example KeyIsAdmin).
type Tool ¶
type Tool interface {
Name() string
Description() string
InputSchema() JSONSchema
Call(context.Context, json.RawMessage) (string, error)
}
Tool is the model-visible consumer plugin type.
Call receives only the raw arguments and returns model-visible text. The tool runtime stamps call identity onto a ToolResult before writing to session or sending back to the model.
type ToolBuilder ¶
type ToolBuilder[In, Out any] struct { // contains filtered or unexported fields }
func NewTool ¶
func NewTool[In, Out any](name string, handler func(context.Context, In) (Out, error)) *ToolBuilder[In, Out]
NewTool starts building a typed tool plugin. The input schema is inferred from In; any inference error surfaces from Build. Handler output is adapted to model-visible text: string is returned as-is, other values are JSON.
func (*ToolBuilder[In, Out]) Build ¶
func (b *ToolBuilder[In, Out]) Build() (Tool, error)
func (*ToolBuilder[In, Out]) Description ¶
func (b *ToolBuilder[In, Out]) Description(desc string) *ToolBuilder[In, Out]
func (*ToolBuilder[In, Out]) Schema ¶
func (b *ToolBuilder[In, Out]) Schema(schema JSONSchema) *ToolBuilder[In, Out]
Schema replaces the inferred input schema, discarding any inference error.
type ToolCall ¶
type ToolCall struct {
ID ToolCallID
Name string
Input json.RawMessage
}
type ToolCallID ¶
type ToolCallID string
type ToolPack ¶
type ToolPack []Tool
ToolPack is one plugin instance that exposes one or more model-visible tools.
type ToolProvider ¶
ToolProvider supplies tools whose definitions may change between turns. Implementations re-read configuration or rediscover remote tools on each call.
type ToolResult ¶
type ToolResult struct {
ID ToolCallID
Name string
Content string
Audit map[string]string
}
ToolResult is a tool output bound to a specific call, used by session history, hooks, and LLM wire-up. Audit is populated by the tool runtime (policy deny, timeout, etc.), not by Tool.Call.
func ResultFromCall ¶ added in v0.1.2
func ResultFromCall(call ToolCall, output string) ToolResult
ResultFromCall attaches call identity to a tool output.
type ToolRuntime ¶
type ToolSpec ¶
type ToolSpec struct {
Name string
Description string
InputSchema JSONSchema
}
type TurnEnvelope ¶ added in v0.2.1
type TurnEnvelope struct {
Route RouteRef `json:"route"`
Conversation string `json:"conversation"`
Workspace string `json:"workspace"`
AgentID AgentID `json:"agentId,omitempty"`
Actor ActorRef `json:"actor"`
Metadata map[string]any `json:"metadata,omitempty"`
}
TurnEnvelope is the normalized routing context for one turn.
- Route: where outbound replies go (default: captured at inbound)
- Conversation: history file and Loop lock key
- Workspace: tenant directory for fs, shell, local MCP, skills, memory
- AgentID: agent executing this turn
- Actor: end-user identity for audit, inject, and permission
- Metadata: platform and plugin extensions
func (TurnEnvelope) WithAgentID ¶ added in v0.2.1
func (e TurnEnvelope) WithAgentID(agentID AgentID) TurnEnvelope
WithAgentID returns a copy with AgentID replaced.
func (TurnEnvelope) WithConversation ¶ added in v0.2.1
func (e TurnEnvelope) WithConversation(conversation string) TurnEnvelope
WithConversation returns a copy with Conversation replaced.
func (TurnEnvelope) WithMetadata ¶ added in v0.2.1
func (e TurnEnvelope) WithMetadata(metadata map[string]any) TurnEnvelope
WithMetadata returns a copy with Metadata replaced.
func (TurnEnvelope) WithRoute ¶ added in v0.2.1
func (e TurnEnvelope) WithRoute(route RouteRef) TurnEnvelope
WithRoute returns a copy with Route replaced.
func (TurnEnvelope) WithWorkspace ¶ added in v0.2.1
func (e TurnEnvelope) WithWorkspace(workspace string) TurnEnvelope
WithWorkspace returns a copy with Workspace replaced.
type TurnInput ¶
type TurnInput struct {
Message ModelMessage
Emit OutboundEmit
}
TurnInput carries one turn's payload. Routing context is available through TurnEnvelope on ctx (SessionIDFromContext, AgentIDFromContext, PlatformFromContext, UserIDFromContext).
type TurnStopReason ¶
type TurnStopReason string
TurnStopReason explains why the agent reached the end of a turn segment.
const ( // StopNoToolCalls means the assistant answered without requesting tools. StopNoToolCalls TurnStopReason = "no-tool-calls" // StopStepLimit means the per-segment step allowance ran out. StopStepLimit TurnStopReason = "step-limit" // StopBudget means a hard run budget is exhausted; Continue is ignored. StopBudget TurnStopReason = "budget" )
type TurnStopping ¶
type TurnStopping struct {
Reason TurnStopReason
Steps int
Segments int
Budget BudgetState
// Messages is the derived history at the stopping point. Read-only for hooks.
Messages []ModelMessage
// Continue holds messages that extend the turn. Hooks append to it.
Continue []ModelMessage
Stop bool
StopReason string
}
TurnStopping is invoked when the agent is about to end a turn. Hooks may append Continue messages to extend the turn with another segment, or set Stop to force the turn to end. Stop wins over Continue, and the agent ignores Continue when Budget.Exhausted is true: no hook can outrun a hard budget.
type TurnStoppingHook ¶
type TurnStoppingHook interface {
Hook
TurnStopping(context.Context, *TurnStopping) error
}
func OnTurnStopping ¶
func OnTurnStopping(fn func(context.Context, *TurnStopping) error) TurnStoppingHook
OnTurnStopping wraps a function as a TurnStoppingHook.
type UserTimezoneProvider ¶ added in v0.1.12
UserTimezoneProvider is optional on leaf platforms. Runner uses it when runner.config.inject includes timestamp.
Source Files
¶
- admin.go
- agentkit.go
- envelope.go
- events.go
- generate.go
- hook_helper.go
- jsonschema.go
- plugin_agent.go
- plugin_agent_acp.go
- plugin_agent_bind.go
- plugin_appinit.go
- plugin_command.go
- plugin_hook.go
- plugin_llm.go
- plugin_loop.go
- plugin_policy.go
- plugin_prompt.go
- plugin_runner.go
- plugin_session.go
- plugin_tool.go
- policy_helper.go
- streaming.go
- tool_builder.go
Directories
¶
| Path | Synopsis |
|---|---|
|
cap
|
|
|
filesystem
Package filesystem holds shared request/result types used by file tools.
|
Package filesystem holds shared request/result types used by file tools. |
|
permission
Package permission is the capability boundary for human-in-the-loop decisions routed through the inbound platform (tool approval, ask_user, etc.).
|
Package permission is the capability boundary for human-in-the-loop decisions routed through the inbound platform (tool approval, ask_user, etc.). |
|
schedule
Package schedule defines the calendar-scheduling capability: a durable set of cron jobs that schedule/cron fires and a tool can edit.
|
Package schedule defines the calendar-scheduling capability: a durable set of cron jobs that schedule/cron fires and a tool can edit. |
|
subagent
Package subagent defines the delegation capability: running a scoped child agent and bringing back only its conclusion.
|
Package subagent defines the delegation capability: running a scoped child agent and bringing back only its conclusion. |
|
telemetry
Package telemetry defines the observability exporter boundary for AgentKit.
|
Package telemetry defines the observability exporter boundary for AgentKit. |
|
cmd
|
|
|
agent
command
|
|
|
runtime
|
|
|
helpdoc
Package helpdoc resolves pluginkit kind documentation for slash commands.
|
Package helpdoc resolves pluginkit kind documentation for slash commands. |
|
platform/common
Package common holds shared platform helpers for inbound routing, slash commands, and outbound delivery.
|
Package common holds shared platform helpers for inbound routing, slash commands, and outbound delivery. |
|
platform/headless
Package headless holds the platforms that run without an interactive terminal: platform/worker for one-shot batches and platform/timer for in-process schedules.
|
Package headless holds the platforms that run without an interactive terminal: platform/worker for one-shot batches and platform/timer for in-process schedules. |
|
subagent
Package subagent runs child agents in-process.
|
Package subagent runs child agents in-process. |
|
scripts
|
|
|
check-plugin-imports
command
|
|
|
gen-imports
command
|
|
|
testing
|
|
|
agenttest
Package agenttest provides shared helpers for AgentKit tests.
|
Package agenttest provides shared helpers for AgentKit tests. |
|
mcptest
Package mcptest builds the stdio MCP test server and returns a tool/mcp provider for smoke tests.
|
Package mcptest builds the stdio MCP test server and returns a tool/mcp provider for smoke tests. |
|
openapitest
Package openapitest provides a reusable mock HTTP API, fixture workspace materialization, and helpers for OpenAPI dynamic tool smoke tests.
|
Package openapitest provides a reusable mock HTTP API, fixture workspace materialization, and helpers for OpenAPI dynamic tool smoke tests. |
|
presettest
Package presettest loads real preset graphs and runs scripted Runner smoke flows.
|
Package presettest loads real preset graphs and runs scripted Runner smoke flows. |
|
smoke
Smoke tests exercise keyless scripted flows end-to-end without preset graphs.
|
Smoke tests exercise keyless scripted flows end-to-end without preset graphs. |