Documentation
¶
Overview ¶
Package translate handles ACP → domain event translation.
The Translator receives raw ACP notifications from kiro-cli bridges and converts them into domain events (SSE broadcasts, chat-store mutations). Hub remains the coordinator; this package owns the protocol-specific decode + dispatch logic.
Index ¶
- Constants
- func DecodeGovernanceState(raw json.RawMessage) (api.GovernanceStatePayload, bool)
- type ACPChunkWire
- type ACPKiroMeta
- type ACPModeUpdateWire
- type ACPPlanWire
- type ACPRefusalMeta
- type ACPSessionUpdateBase
- type ACPSessionUpdateEnvelope
- type ACPToolCallContentBlock
- type ACPToolCallUpdateWire
- type ACPToolCallWire
- type BridgeComm
- type BufferAccess
- type ChatStoreDeps
- type Deps
- type LineRecorder
- type MCPRecorder
- type Option
- type PermissionAccess
- type StreamingAccess
- type Translator
- func (t *Translator) HandleAgentConfigError(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleAgentNotFound(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleAssistantChunk(ctx context.Context, chatID api.ChatID, raw json.RawMessage, isReasoning bool)
- func (t *Translator) HandleAvailableCommandsUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage, ...)
- func (t *Translator) HandleCodeReferences(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleConfigOptionUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage)
- func (t *Translator) HandleElicitationCreate(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleGovernanceState(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleKnowledgeIndexing(ctx context.Context, _ api.ChatID, msg *api.RPCResponse, started bool)
- func (t *Translator) HandleMCPStatus(ctx context.Context, _ api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleModeUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage)
- func (t *Translator) HandlePermissionRequest(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandlePlan(ctx context.Context, chatID api.ChatID, raw json.RawMessage)
- func (t *Translator) HandlePolicyChanged(ctx context.Context, _ api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandlePolicyError(ctx context.Context, _ api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleRateLimit(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleSafetyPropertiesChanged(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleSafetyStatusChanged(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleSessionInfoUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage, ...)
- func (t *Translator) HandleSpecTaskChanged(ctx context.Context, _ api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleSystemNotify(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) HandleToolCall(ctx context.Context, chatID api.ChatID, raw json.RawMessage, ...)
- func (t *Translator) HandleToolCallUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage, ...)
- func (t *Translator) HandleUsageUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage)
- func (t *Translator) HandleUserInput(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
- func (t *Translator) MCP() MCPRecorder
Constants ¶
const ( // PrimePreambleSwitch opens the model-switch recovery prime. PrimePreambleSwitch = "The context was just switched (new agent, new model, " + "or both). Below is the full conversation history. Read it " + "silently and reply with a single short line confirming " + "you're caught up.\n\n" // PrimePreambleRewind opens the degraded-rewind prime. PrimePreambleRewind = "This conversation was rewound to an earlier turn and is " + "resuming in a fresh session. Below is the conversation history " + "up to the rewind point. Read it silently and reply with a " + "single short line confirming you're caught up.\n\n" )
Prime preambles: the fixed prefixes of the invisible priming prompt the bridge coordinator sends on a fresh session after a model-switch fallback or a degraded rewind (hub bridge_coord.go builds the prime as preamble + history). Exported so the coordinator and the focus filter share one definition — KAS derives a first-prompt title from whatever prompt text it sees first, and on a primed session that is this text.
const ContentTypeContent = "content"
ContentTypeContent is the ACP content-block type discriminator value "content". Distinct from jsonFieldContent which is the JSON field *name* "content".
const ContentTypeDiff = "diff"
ContentTypeDiff is the ACP content-block type for file-change diffs in tool_call and tool_call_update payloads.
Variables ¶
This section is empty.
Functions ¶
func DecodeGovernanceState ¶ added in v0.1.165
func DecodeGovernanceState(raw json.RawMessage) (api.GovernanceStatePayload, bool)
DecodeGovernanceState decodes a raw _kiro/governance/state params object into the domain payload. Exported so the hub can reuse it for the copy the utility bridge receives (whose notifications don't flow through this dispatcher) — keeping one wire→domain conversion. Returns false on empty/invalid params.
Types ¶
type ACPChunkWire ¶
type ACPChunkWire struct {
Content struct {
Type string `json:"type"`
Text string `json:"text"`
} `json:"content"`
Meta ACPKiroMeta `json:"_meta"`
}
ACPChunkWire is the wire shape for agent_message_chunk and agent_thought_chunk session updates. On v3 (KAS) a nested subagent's chunks ride the parent session id and carry _meta.kiro.agentSubtaskId identifying which agent-subtask tool call they belong to.
type ACPKiroMeta ¶ added in v0.1.165
type ACPKiroMeta struct {
Kiro struct {
// Refusal is present only on the agent_message_chunk carrying a
// model-refusal explanation (kiro-cli 2.13+, modelStopReason
// "content_filtered"). KAS calls it a progressive-enhancement
// marker: plain clients render the text, capable clients key off
// it for a distinct refusal affordance. The turn then ends with
// core stopReason "refusal".
Refusal *ACPRefusalMeta `json:"refusal"`
Kind string `json:"kind"`
AgentSubtaskID string `json:"agentSubtaskId"`
HookAsk json.RawMessage `json:"hookAsk,omitempty"`
} `json:"kiro"`
}
ACPKiroMeta is the top-level `_meta.kiro` block carried on v3 (KAS) tool_call / tool_call_update session updates. When Kind=="agent-subtask" the tool call is a subagent card (the model invoked invoke_sub_agent); AgentSubtaskID is the stable id that links the card to its nested agent_message_chunk / agent_thought_chunk deltas (which carry the same id under their own _meta.kiro).
HookAsk is present (non-empty) only on the synthetic tool call KAS emits to surface a pre-tool-use hook's ask-permission gate: KAS sends a kind:"other" tool_call/tool_call_update tagged _meta.kiro.hookAsk={kind:"pre-tool-use",toolName,reason[,decision]} — NOT a ToolKind "hook" (v3's zToolKind has no "hook"). Its presence is the signal HandleToolCall uses to suppress hook cards when the hooks.showStatus setting is off; the contents are opaque here.
type ACPModeUpdateWire ¶
type ACPModeUpdateWire struct {
ModeID string `json:"currentModeId"`
}
ACPModeUpdateWire is the wire shape for the current_mode_update session/update sub-kind. KAS keys the new mode on `currentModeId` (the bundle's zCurrentModeUpdate object), NOT `modeId` — `modeId` is the field name on the outbound session/set_mode REQUEST (command/mode.go), a different message. Reading the wrong key here left ModeID empty, so HandleModeUpdate never persisted agent-initiated mode changes.
type ACPPlanWire ¶
ACPPlanWire is the wire shape for plan session updates.
type ACPRefusalMeta ¶ added in v0.2.8
type ACPRefusalMeta struct {
Category string `json:"category"`
Explanation string `json:"explanation"`
RecommendedModel string `json:"recommendedModel"`
}
ACPRefusalMeta is the _meta.kiro.refusal block on a refusal explanation chunk. Explanation duplicates the chunk text (KAS falls back to a canned message when absent), so only Category / RecommendedModel flow into the domain api.RefusalInfo.
type ACPSessionUpdateBase ¶
type ACPSessionUpdateBase struct {
Kind api.ACPUpdateKind `json:"sessionUpdate"`
}
ACPSessionUpdateBase extracts the sessionUpdate kind discriminator.
type ACPSessionUpdateEnvelope ¶
type ACPSessionUpdateEnvelope struct {
SessionID string `json:"sessionId"`
Update json.RawMessage `json:"update"`
}
ACPSessionUpdateEnvelope is the outer envelope for session/update notifications.
type ACPToolCallContentBlock ¶
type ACPToolCallContentBlock struct {
Type string `json:"type"`
Path string `json:"path"`
OldText string `json:"oldText"`
NewText string `json:"newText"`
Content struct {
Text string `json:"text"`
} `json:"content"`
}
ACPToolCallContentBlock is one element in a tool_call or tool_call_update's content array.
type ACPToolCallUpdateWire ¶
type ACPToolCallUpdateWire struct {
Meta ACPKiroMeta `json:"_meta"`
ToolCallID string `json:"toolCallId"`
Title string `json:"title"`
Kind api.ToolKind `json:"kind"`
Status api.ToolStatus `json:"status"`
Locations []api.ToolLocation `json:"locations"`
Content []ACPToolCallContentBlock `json:"content"`
}
ACPToolCallUpdateWire is the wire shape for tool_call_update session updates. KAS's zToolCallUpdate also carries optional title/kind (a mid-flight card refinement) and rawOutput; we decode title/kind so the card can be relabelled, but leave rawOutput undecoded — the tool's textual output already arrives through the `content` blocks below and the domain ToolCall has no structured-output field.
type ACPToolCallWire ¶
type ACPToolCallWire struct {
Meta ACPKiroMeta `json:"_meta"`
ToolCallID string `json:"toolCallId"`
Title string `json:"title"`
Kind api.ToolKind `json:"kind"`
Status api.ToolStatus `json:"status"`
RawInput json.RawMessage `json:"rawInput"`
Locations []api.ToolLocation `json:"locations"`
Content []ACPToolCallContentBlock `json:"content"`
}
ACPToolCallWire is the wire shape for tool_call session updates.
type BridgeComm ¶
type BridgeComm interface {
BridgeNotify(ctx context.Context, chatID api.ChatID, method string, params map[string]any) error
BridgeRespond(ctx context.Context, chatID api.ChatID, requestID int64, result any, err error) error
}
BridgeComm provides bridge communication methods needed by compact.go and permission_handler.go for sending notifications and responses.
type BufferAccess ¶
BufferAccess is the consumer-side interface for buffer store access. Narrows the coupling: translate only needs GetOrInit.
type ChatStoreDeps ¶
type ChatStoreDeps interface {
Broadcast(ctx context.Context, evt api.ServerEvent)
ChatStore() api.ChatStore
ParentACPSession(chatID api.ChatID) string
}
ChatStoreDeps provides the minimal interface needed by handlers that only require chat store access and broadcast (init_errors).
type Deps ¶
type Deps interface {
StreamingAccess
PermissionAccess
BridgeComm
// MCPRecorder returns the MCP state recorder sub-interface.
MCPRecorder() MCPRecorder
// SetGovernance caches the latest account/workspace governance state so
// GET /api/governance can serve it with no chat open (see hub/governance.go).
SetGovernance(state api.GovernanceStatePayload)
}
Deps abstracts the Hub methods that stateful translate handlers need. Hub satisfies this interface, allowing the Translator to operate without importing the hub package.
type LineRecorder ¶
type LineRecorder interface {
RecordFromDiffs(chatID api.ChatID, diffs []api.ToolDiff, turn int, kind string)
}
LineRecorder is the consumer-side interface for line tracking. Narrows the coupling: translate only needs RecordFromDiffs.
type MCPRecorder ¶
type MCPRecorder interface {
// RecordConnected marks a server connected and records the prompts +
// resources it advertises (from _kiro/mcp/status). Both may be nil.
RecordConnected(ctx context.Context, serverName string, prompts []api.MCPPromptInfo, resources []api.MCPResourceInfo)
RecordOAuth(ctx context.Context, serverName, oauthURL string)
RecordInitFailure(ctx context.Context, serverName, errMsg string)
SignalReady()
SetKnownTools(ctx context.Context, name string, tools []string)
}
MCPRecorder groups MCP server state tracking methods. Extracted from Deps to narrow the interface (21→17 methods) and allow independent stubbing in tests.
type Option ¶
type Option func(*Translator)
Option configures a Translator.
func WithIDGenerator ¶
WithIDGenerator overrides the default message ID generator (for tests).
type PermissionAccess ¶
type PermissionAccess interface {
Broadcast(ctx context.Context, evt api.ServerEvent)
BridgeRespond(ctx context.Context, chatID api.ChatID, requestID int64, result any, err error) error
ChatStore() api.ChatStore
NotifyPush(ctx context.Context, body string, kind api.PushKind)
ParentACPSession(chatID api.ChatID) string
PendingPermsAdd(requestID int64, evt api.ServerEvent)
PendingPermsRemove(requestID int64)
}
PermissionAccess provides the methods needed by permission_handler.go for permission request handling and push notifications. Shell-command authorization is owned by kiro-cli's native Cedar policy: any session/request_permission that reaches vibekit is a genuine ask, so there is no auto-approval surface here.
type StreamingAccess ¶
type StreamingAccess interface {
Broadcast(ctx context.Context, evt api.ServerEvent)
BufferStore() BufferAccess
LineTracker() LineRecorder
OpenPartialFile(ctx context.Context, chatID api.ChatID, buf *buffer.Buffer)
IsHookStatusEnabled() bool
ChatStore() api.ChatStore
ParentACPSession(chatID api.ChatID) string
WorkDir() string
}
StreamingAccess provides the methods needed by streaming_content.go / streaming_tools.go for content buffering, partial file recovery, and line tracking.
type Translator ¶
type Translator struct {
// contains filtered or unexported fields
}
Translator holds stateful translate logic extracted from Hub. It delegates Hub access through Deps.
func New ¶
func New(deps Deps, opts ...Option) *Translator
New constructs a Translator with the given Hub dependency surface.
func (*Translator) HandleAgentConfigError ¶
func (t *Translator) HandleAgentConfigError(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleAgentConfigError handles the _kiro/customAgent/config_error notification ({path, error}); the extra v3 sessionId is ignored.
func (*Translator) HandleAgentNotFound ¶
func (t *Translator) HandleAgentNotFound(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleAgentNotFound handles the _kiro/customAgent/not_found notification: the requested agent (a mode id on v3) doesn't exist. Persists the fallback mode (always "vibe" on v3) as the chat's CurrentModeID and broadcasts a typed error — on v3 the fallback agent IS a mode id. v3 carries no model fields here — a bad model is an InvalidModelError RPC error on the set_config_option/prompt call, not a notification, so there is no model-not-found handler.
func (*Translator) HandleAssistantChunk ¶
func (t *Translator) HandleAssistantChunk(ctx context.Context, chatID api.ChatID, raw json.RawMessage, isReasoning bool)
HandleAssistantChunk streams a text delta to clients and accumulates it for later persistence. Reasoning chunks (isReasoning=true) flow into buf.Reasoning; regular content chunks flow into buf.Content. The IsReasoning flag is forwarded on the SSE so the client routes each delta to the correct bubble (reasoning details vs content).
func (*Translator) HandleAvailableCommandsUpdate ¶ added in v0.1.165
func (t *Translator) HandleAvailableCommandsUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage, subSessionID string)
HandleAvailableCommandsUpdate maps the v3 command catalog onto the same commands_updated SSE the v2 _kiro.dev/commands/available handler emits, so the client slash-command type-ahead is engine-agnostic. Parent-only.
func (*Translator) HandleCodeReferences ¶ added in v0.1.165
func (t *Translator) HandleCodeReferences(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleCodeReferences accumulates the turn's licensed-code attributions onto the in-flight assistant buffer and broadcasts a code_references SSE so the client attaches an attribution chip to that turn. The references are also persisted onto the finalized assistant message at turn end (bridge_coord.go) so the chip survives reload — the streamed assistant turn is never re-broadcast as message_appended.
func (*Translator) HandleConfigOptionUpdate ¶ added in v0.1.165
func (t *Translator) HandleConfigOptionUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage)
HandleConfigOptionUpdate refreshes the chat's model catalog from the v3 config_option_update. Modes are intentionally NOT refreshed here: the config catalog omits the bundled/workspace source tag the picker groups by, so the authoritative mode list stays the one captured on session/new.
func (*Translator) HandleElicitationCreate ¶ added in v0.1.39
func (t *Translator) HandleElicitationCreate(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleElicitationCreate processes a _kiro/mcp/elicitation request from KAS. An MCP server has asked for structured input mid-tool-call; KAS forwarded it to us because we advertised the elicitation client capability. We surface a form to the user and the eventual reply is sent by CmdElicitationResponse via bridge.Respond.
The request is a real JSON-RPC request (envelope id present), routed here the same way fs/read_text_file is — so the correlation id is msg.ID. On v3 the elicitation body is NESTED under an "elicitation" object; sessionId/toolCallId stay top-level. We reuse the pending-permissions tracker for SSE replay so a dialog survives a reconnect, exactly like a permission prompt. There is no v3 elicitation-complete method (upstream cancel is not signalled).
func (*Translator) HandleGovernanceState ¶ added in v0.1.165
func (t *Translator) HandleGovernanceState(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleGovernanceState translates _kiro/governance/state into a governance_state SSE and caches the latest state hub-side. The SSE is broadcast with an empty chat id because the policy is account-global (a client on Settings with no active chat must still receive it). A subagent-session copy is skipped (KAS may re-emit per session; the parent copy carries the identical account-global flags) — the same dedup guard safety.go / code_references.go use.
func (*Translator) HandleKnowledgeIndexing ¶ added in v0.1.165
func (t *Translator) HandleKnowledgeIndexing(ctx context.Context, _ api.ChatID, msg *api.RPCResponse, started bool)
HandleKnowledgeIndexing translates a _kiro/knowledge/indexingStarted (started == true) or indexingCompleted (started == false) notification into a knowledge_indexing SSE. started stamps Status="started" and carries FileCount; completed carries the wire Status ("success"/failure) and, on success, ItemCount.
func (*Translator) HandleMCPStatus ¶ added in v0.1.165
func (t *Translator) HandleMCPStatus(ctx context.Context, _ api.ChatID, msg *api.RPCResponse)
HandleMCPStatus maps the consolidated v3 _kiro/mcp/status notification onto the same MCP-registry state the v2 mcp/* handlers drive: connected servers record their tool names + connected state; failed servers record an init failure, or an OAuth prompt when an authorization URL is present.
func (*Translator) HandleModeUpdate ¶
func (t *Translator) HandleModeUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage)
HandleModeUpdate persists the agent's new mode and broadcasts mode_changed.
func (*Translator) HandlePermissionRequest ¶
func (t *Translator) HandlePermissionRequest(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandlePermissionRequest processes session/request_permission from kiro-cli.
The v3 params object is FLAT — {sessionId, toolCall{...}, options[]} — and the JSON-RPC correlation id is on the envelope (msg.ID), NOT inside params. unmarshalParams decodes msg.Params directly, so the decode struct must match those fields at top level; a `params`-wrapped struct (or an `id` field read from params) decodes to all-zero, yielding an empty dialog and request_id=0 (the outcome would then be answered on id 0, wedging the tool call and disabling the shell auto-policy). Mirror HandleElicitationCreate, which decodes flat and reads *msg.ID.
func (*Translator) HandlePlan ¶
func (t *Translator) HandlePlan(ctx context.Context, chatID api.ChatID, raw json.RawMessage)
HandlePlan persists a plan message directly.
func (*Translator) HandlePolicyChanged ¶ added in v0.1.165
func (t *Translator) HandlePolicyChanged(ctx context.Context, _ api.ChatID, msg *api.RPCResponse)
HandlePolicyChanged translates _kiro/policy/changed → the permissions_changed SSE. Clients refetch the native policy view.
func (*Translator) HandlePolicyError ¶ added in v0.1.165
func (t *Translator) HandlePolicyError(ctx context.Context, _ api.ChatID, msg *api.RPCResponse)
HandlePolicyError translates _kiro/policy/error → the policy_error SSE (rendered as a banner so a bad hand-edit or rejected rule is visible).
func (*Translator) HandleRateLimit ¶
func (t *Translator) HandleRateLimit(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleRateLimit handles the _kiro/error/rate_limit notification ({message}); the extra v3 sessionId is ignored. Rendered as an auto-clearing amber banner.
func (*Translator) HandleSafetyPropertiesChanged ¶ added in v0.1.165
func (t *Translator) HandleSafetyPropertiesChanged(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleSafetyPropertiesChanged translates _kiro/safety/propertiesChanged into a safety_properties SSE (chat-scoped). A subagent-session copy is skipped so a subagent's formalized properties aren't attributed to the parent chat (mirrors code_references' subagent guard).
func (*Translator) HandleSafetyStatusChanged ¶ added in v0.1.165
func (t *Translator) HandleSafetyStatusChanged(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleSafetyStatusChanged translates _kiro/safety/statusChanged into a safety_status SSE (chat-scoped). status="idle" is forwarded too — the client uses it to clear a stale banner.
Enforcement model (verified against the KAS 2.12 acp-server bundle): the gate is a PreToolUse hook wrapping the tool executor. In ENFORCE mode a blocked write/shell tool is INTERCEPTED before execution — KAS returns the block as the tool's own result ("The tool was NOT executed") and never calls the inner executor, so it never issues the fs/write_text_file A→C request to us. Vibekit therefore cannot circumvent an enforced block: its fs write handler (hub.respondFSWrite) only ever writes in response to a KAS request, and a blocked tool produces no request. This handler's job is to SURFACE the refusal, not to gate a write (there is no write to gate). A block is non-tool-scoped here: the notification's toolId is the tool NAME (fs_write / str_replace / …), not the per-call tool_call id we round-trip, so it cannot be correlated to a specific rendered tool card.
func (*Translator) HandleSessionInfoUpdate ¶ added in v0.1.165
func (t *Translator) HandleSessionInfoUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage, subSessionID string)
HandleSessionInfoUpdate folds v3 context-usage into the chat's usage so the context ring works on the KAS engine (v2 sourced this from _kiro.dev/metadata), and routes v3 compaction status (v2 sourced this from _kiro.dev/compaction/status). Parent-only: subagent updates are dropped so they don't overwrite the parent chat.
func (*Translator) HandleSpecTaskChanged ¶ added in v0.1.165
func (t *Translator) HandleSpecTaskChanged(ctx context.Context, _ api.ChatID, msg *api.RPCResponse)
HandleSpecTaskChanged translates a _kiro/spec/taskStatusChanged notification into a spec_task_changed SSE. The feature name is derived from tasksFilePath so the client can target the affected spec; the raw path is forwarded too.
func (*Translator) HandleSystemNotify ¶ added in v0.1.165
func (t *Translator) HandleSystemNotify(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleSystemNotify handles the v3 _kiro/system/notify notification ({level, message}) — the replacement for v2's session/retry banner. KAS emits it as a connection-level "model under high load" notice: no attempt counter and no sessionId, so it is a bridge-scope broadcast (chatID may be empty). The message is surfaced verbatim as an auto-clearing banner; level (info/warning/error) is decoded for forward-compatibility but not separately surfaced — banner styling keys off the error code.
func (*Translator) HandleToolCall ¶
func (t *Translator) HandleToolCall(ctx context.Context, chatID api.ChatID, raw json.RawMessage, subSessionID string)
HandleToolCall adds a tool call to the current assistant message buffer and broadcasts it. On v3 (KAS) a subagent is an ordinary tool call tagged _meta.kiro.kind=="agent-subtask"; AgentSubtaskID is threaded onto the domain ToolCall so the client can render a subagent card and nest the subagent's chunks (which carry the same id) under it.
func (*Translator) HandleToolCallUpdate ¶
func (t *Translator) HandleToolCallUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage, subSessionID string)
HandleToolCallUpdate mutates an in-flight tool call's status and appends any new output chunks.
func (*Translator) HandleUsageUpdate ¶ added in v0.1.165
func (t *Translator) HandleUsageUpdate(ctx context.Context, chatID api.ChatID, raw json.RawMessage)
HandleUsageUpdate folds v3 usage_update into the chat's usage (context %, window size, and credits). Parent attribution is handled by ignoreSubSession in the dispatch table.
func (*Translator) HandleUserInput ¶ added in v0.2.43
func (t *Translator) HandleUserInput(ctx context.Context, chatID api.ChatID, msg *api.RPCResponse)
HandleUserInput processes a _kiro/userInput request from KAS (2.14+): the agent's user_input tool asked a structured question (plan-mode clarification, spec gate) and KAS forwarded it because we advertised the _meta.kiro.userInput initialize capability. We surface a question dialog and the eventual reply is sent by CmdUserInputResponse via bridge.Respond ({action:"answered", answer} — anything else advances the agent to its next phase upstream).
The request is a real JSON-RPC request (envelope id present), routed here like _kiro/mcp/elicitation; the correlation id is msg.ID. The pending-permissions tracker replays the dialog on reconnect, exactly like a permission prompt. The question also arrives as a pending tool_call (kind "other", _meta.kiro.toolId "user_input") that KAS completes itself once answered — no tool bookkeeping here.
func (*Translator) MCP ¶
func (t *Translator) MCP() MCPRecorder
MCP returns the MCP state recorder sub-interface.