mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
795ee362ea
Remove the legacy EventKind/Event envelope mapping and let agent event emission build pkg/events.Event values directly. Keep HookMeta as the shared hook metadata shape and preserve legacy observe string aliases by mapping them to runtime event kinds. Validation: GOCACHE=/tmp/picoclaw-go-cache go test ./pkg/agent; make lint
83 lines
2.2 KiB
Go
83 lines
2.2 KiB
Go
// PicoClaw - Ultra-lightweight personal AI agent
|
|
|
|
package agent
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/sipeed/picoclaw/pkg/bus"
|
|
runtimeevents "github.com/sipeed/picoclaw/pkg/events"
|
|
"github.com/sipeed/picoclaw/pkg/providers"
|
|
)
|
|
|
|
// Finalize handles turn finalization, either:
|
|
// - Early return when allResponsesHandled=true (ExecuteTools already finalized)
|
|
// - Normal finalization for allResponsesHandled=false (sets finalContent, saves session, compact)
|
|
func (p *Pipeline) Finalize(
|
|
ctx context.Context,
|
|
turnCtx context.Context,
|
|
ts *turnState,
|
|
exec *turnExecution,
|
|
turnStatus TurnEndStatus,
|
|
finalContent string,
|
|
) (turnResult, error) {
|
|
al := p.al
|
|
|
|
// When allResponsesHandled=true, ExecuteTools already finalized
|
|
// (added handledToolResponseSummary, saved session, set phase to Completed).
|
|
// But still check for hard abort - if requested, abort the turn.
|
|
if exec.allResponsesHandled {
|
|
if ts.hardAbortRequested() {
|
|
return al.abortTurn(ts)
|
|
}
|
|
ts.setPhase(TurnPhaseCompleted)
|
|
return turnResult{
|
|
finalContent: finalContent,
|
|
status: turnStatus,
|
|
followUps: append([]bus.InboundMessage(nil), ts.followUps...),
|
|
}, nil
|
|
}
|
|
|
|
ts.setPhase(TurnPhaseFinalizing)
|
|
ts.setFinalContent(finalContent)
|
|
if !ts.opts.NoHistory {
|
|
finalMsg := providers.Message{
|
|
Role: "assistant",
|
|
Content: finalContent,
|
|
ReasoningContent: responseReasoningContent(exec.response),
|
|
}
|
|
ts.agent.Sessions.AddFullMessage(ts.sessionKey, finalMsg)
|
|
ts.recordPersistedMessage(finalMsg)
|
|
ts.ingestMessage(turnCtx, al, finalMsg)
|
|
if err := ts.agent.Sessions.Save(ts.sessionKey); err != nil {
|
|
al.emitEvent(
|
|
runtimeevents.KindAgentError,
|
|
ts.eventMeta("runTurn", "turn.error"),
|
|
ErrorPayload{
|
|
Stage: "session_save",
|
|
Message: err.Error(),
|
|
},
|
|
)
|
|
return turnResult{status: TurnEndStatusError}, err
|
|
}
|
|
}
|
|
|
|
if ts.opts.EnableSummary {
|
|
al.contextManager.Compact(
|
|
turnCtx,
|
|
&CompactRequest{
|
|
SessionKey: ts.sessionKey,
|
|
Reason: ContextCompressReasonSummarize,
|
|
Budget: ts.agent.ContextWindow,
|
|
},
|
|
)
|
|
}
|
|
|
|
ts.setPhase(TurnPhaseCompleted)
|
|
return turnResult{
|
|
finalContent: finalContent,
|
|
status: turnStatus,
|
|
followUps: append([]bus.InboundMessage(nil), ts.followUps...),
|
|
}, nil
|
|
}
|