mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
d9717b5632
Deprecate the legacy agent event APIs and add a runtime event test helper, then migrate the follow-up queued test to the runtime event stream. Validation: go test ./pkg/agent; make lint
279 lines
7.6 KiB
Go
279 lines
7.6 KiB
Go
package agent
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// EventKind identifies a structured agent-loop event.
|
|
//
|
|
// Deprecated: use github.com/sipeed/picoclaw/pkg/events.Kind for new runtime
|
|
// event consumers. This legacy kind exists only during the runtime event
|
|
// migration window.
|
|
type EventKind uint8
|
|
|
|
const (
|
|
// EventKindTurnStart is emitted when a turn begins processing.
|
|
EventKindTurnStart EventKind = iota
|
|
// EventKindTurnEnd is emitted when a turn finishes, successfully or with an error.
|
|
EventKindTurnEnd
|
|
// EventKindLLMRequest is emitted before a provider chat request is made.
|
|
EventKindLLMRequest
|
|
// EventKindLLMDelta is emitted when a streaming provider yields a partial delta.
|
|
EventKindLLMDelta
|
|
// EventKindLLMResponse is emitted after a provider chat response is received.
|
|
EventKindLLMResponse
|
|
// EventKindLLMRetry is emitted when an LLM request is retried.
|
|
EventKindLLMRetry
|
|
// EventKindContextCompress is emitted when session history is forcibly compressed.
|
|
EventKindContextCompress
|
|
// EventKindSessionSummarize is emitted when asynchronous summarization completes.
|
|
EventKindSessionSummarize
|
|
// EventKindToolExecStart is emitted immediately before a tool executes.
|
|
EventKindToolExecStart
|
|
// EventKindToolExecEnd is emitted immediately after a tool finishes executing.
|
|
EventKindToolExecEnd
|
|
// EventKindToolExecSkipped is emitted when a queued tool call is skipped.
|
|
EventKindToolExecSkipped
|
|
// EventKindSteeringInjected is emitted when queued steering is injected into context.
|
|
EventKindSteeringInjected
|
|
// EventKindFollowUpQueued is emitted when an async tool queues a follow-up system message.
|
|
EventKindFollowUpQueued
|
|
// EventKindInterruptReceived is emitted when a soft interrupt message is accepted.
|
|
EventKindInterruptReceived
|
|
// EventKindSubTurnSpawn is emitted when a sub-turn is spawned.
|
|
EventKindSubTurnSpawn
|
|
// EventKindSubTurnEnd is emitted when a sub-turn finishes.
|
|
EventKindSubTurnEnd
|
|
// EventKindSubTurnResultDelivered is emitted when a sub-turn result is delivered.
|
|
EventKindSubTurnResultDelivered
|
|
// EventKindSubTurnOrphan is emitted when a sub-turn result cannot be delivered.
|
|
EventKindSubTurnOrphan
|
|
// EventKindError is emitted when a turn encounters an execution error.
|
|
EventKindError
|
|
|
|
eventKindCount
|
|
)
|
|
|
|
var eventKindNames = [...]string{
|
|
"turn_start",
|
|
"turn_end",
|
|
"llm_request",
|
|
"llm_delta",
|
|
"llm_response",
|
|
"llm_retry",
|
|
"context_compress",
|
|
"session_summarize",
|
|
"tool_exec_start",
|
|
"tool_exec_end",
|
|
"tool_exec_skipped",
|
|
"steering_injected",
|
|
"follow_up_queued",
|
|
"interrupt_received",
|
|
"subturn_spawn",
|
|
"subturn_end",
|
|
"subturn_result_delivered",
|
|
"subturn_orphan",
|
|
"error",
|
|
}
|
|
|
|
// String returns the stable string form of an EventKind.
|
|
func (k EventKind) String() string {
|
|
if k >= eventKindCount {
|
|
return fmt.Sprintf("event_kind(%d)", k)
|
|
}
|
|
return eventKindNames[k]
|
|
}
|
|
|
|
// Event is the structured envelope broadcast by the agent EventBus.
|
|
//
|
|
// Deprecated: use github.com/sipeed/picoclaw/pkg/events.Event for new
|
|
// observation code. Agent payload types remain supported.
|
|
type Event struct {
|
|
Kind EventKind
|
|
Time time.Time
|
|
Meta EventMeta
|
|
Context *TurnContext
|
|
Payload any
|
|
}
|
|
|
|
// EventMeta contains correlation fields shared by all agent-loop events.
|
|
type EventMeta struct {
|
|
AgentID string
|
|
TurnID string
|
|
ParentTurnID string
|
|
SessionKey string
|
|
Iteration int
|
|
TracePath string
|
|
Source string
|
|
turnContext *TurnContext
|
|
}
|
|
|
|
// TurnEndStatus describes the terminal state of a turn.
|
|
type TurnEndStatus string
|
|
|
|
const (
|
|
// TurnEndStatusCompleted indicates the turn finished normally.
|
|
TurnEndStatusCompleted TurnEndStatus = "completed"
|
|
// TurnEndStatusError indicates the turn ended because of an error.
|
|
TurnEndStatusError TurnEndStatus = "error"
|
|
// TurnEndStatusAborted indicates the turn was hard-aborted and rolled back.
|
|
TurnEndStatusAborted TurnEndStatus = "aborted"
|
|
)
|
|
|
|
// TurnStartPayload describes the start of a turn.
|
|
type TurnStartPayload struct {
|
|
UserMessage string
|
|
MediaCount int
|
|
}
|
|
|
|
// TurnEndPayload describes the completion of a turn.
|
|
type TurnEndPayload struct {
|
|
Status TurnEndStatus
|
|
Iterations int
|
|
Duration time.Duration
|
|
FinalContentLen int
|
|
}
|
|
|
|
// LLMRequestPayload describes an outbound LLM request.
|
|
type LLMRequestPayload struct {
|
|
Model string
|
|
MessagesCount int
|
|
ToolsCount int
|
|
MaxTokens int
|
|
Temperature float64
|
|
}
|
|
|
|
// LLMResponsePayload describes an inbound LLM response.
|
|
type LLMResponsePayload struct {
|
|
ContentLen int
|
|
ToolCalls int
|
|
HasReasoning bool
|
|
}
|
|
|
|
// LLMDeltaPayload describes a streamed LLM delta.
|
|
type LLMDeltaPayload struct {
|
|
ContentDeltaLen int
|
|
ReasoningDeltaLen int
|
|
}
|
|
|
|
// LLMRetryPayload describes a retry of an LLM request.
|
|
type LLMRetryPayload struct {
|
|
Attempt int
|
|
MaxRetries int
|
|
Reason string
|
|
Error string
|
|
Backoff time.Duration
|
|
}
|
|
|
|
// ContextCompressReason identifies why emergency compression ran.
|
|
type ContextCompressReason string
|
|
|
|
const (
|
|
// ContextCompressReasonProactive indicates compression before the first LLM call.
|
|
ContextCompressReasonProactive ContextCompressReason = "proactive_budget"
|
|
// ContextCompressReasonRetry indicates compression during context-error retry handling.
|
|
ContextCompressReasonRetry ContextCompressReason = "llm_retry"
|
|
// ContextCompressReasonSummarize indicates post-turn async summarization.
|
|
ContextCompressReasonSummarize ContextCompressReason = "summarize"
|
|
)
|
|
|
|
// ContextCompressPayload describes a forced history compression.
|
|
type ContextCompressPayload struct {
|
|
Reason ContextCompressReason
|
|
DroppedMessages int
|
|
RemainingMessages int
|
|
}
|
|
|
|
// SessionSummarizePayload describes a completed async session summarization.
|
|
type SessionSummarizePayload struct {
|
|
SummarizedMessages int
|
|
KeptMessages int
|
|
SummaryLen int
|
|
OmittedOversized bool
|
|
}
|
|
|
|
// ToolExecStartPayload describes a tool execution request.
|
|
type ToolExecStartPayload struct {
|
|
Tool string
|
|
Arguments map[string]any
|
|
}
|
|
|
|
// ToolExecEndPayload describes the outcome of a tool execution.
|
|
type ToolExecEndPayload struct {
|
|
Tool string
|
|
Duration time.Duration
|
|
ForLLMLen int
|
|
ForUserLen int
|
|
IsError bool
|
|
Async bool
|
|
}
|
|
|
|
// ToolExecSkippedPayload describes a skipped tool call.
|
|
type ToolExecSkippedPayload struct {
|
|
Tool string
|
|
Reason string
|
|
}
|
|
|
|
// SteeringInjectedPayload describes steering messages appended before the next LLM call.
|
|
type SteeringInjectedPayload struct {
|
|
Count int
|
|
TotalContentLen int
|
|
}
|
|
|
|
// FollowUpQueuedPayload describes an async follow-up queued back into the inbound bus.
|
|
type FollowUpQueuedPayload struct {
|
|
SourceTool string
|
|
ContentLen int
|
|
}
|
|
|
|
type InterruptKind string
|
|
|
|
const (
|
|
InterruptKindSteering InterruptKind = "steering"
|
|
InterruptKindGraceful InterruptKind = "graceful"
|
|
InterruptKindHard InterruptKind = "hard_abort"
|
|
)
|
|
|
|
// InterruptReceivedPayload describes accepted turn-control input.
|
|
type InterruptReceivedPayload struct {
|
|
Kind InterruptKind
|
|
Role string
|
|
ContentLen int
|
|
QueueDepth int
|
|
HintLen int
|
|
}
|
|
|
|
// SubTurnSpawnPayload describes the creation of a child turn.
|
|
type SubTurnSpawnPayload struct {
|
|
AgentID string
|
|
Label string
|
|
ParentTurnID string
|
|
}
|
|
|
|
// SubTurnEndPayload describes the completion of a child turn.
|
|
type SubTurnEndPayload struct {
|
|
AgentID string
|
|
Status string
|
|
}
|
|
|
|
// SubTurnResultDeliveredPayload describes delivery of a sub-turn result.
|
|
type SubTurnResultDeliveredPayload struct {
|
|
TargetChannel string
|
|
TargetChatID string
|
|
ContentLen int
|
|
}
|
|
|
|
// SubTurnOrphanPayload describes a sub-turn result that could not be delivered.
|
|
type SubTurnOrphanPayload struct {
|
|
ParentTurnID string
|
|
ChildTurnID string
|
|
Reason string
|
|
}
|
|
|
|
// ErrorPayload describes an execution error inside the agent loop.
|
|
type ErrorPayload struct {
|
|
Stage string
|
|
Message string
|
|
}
|