Files
tutti/packages/agent/daemon/runtime/controller_goal_reconcile.go
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

82 lines
2.6 KiB
Go

package agentruntime
import (
"context"
"fmt"
)
type GoalReconcileInput struct {
RoomID string
AgentSessionID string
RequireLive bool
}
type GoalReconcileResult struct {
AgentSessionID string
Goal map[string]any
Evidence map[string]any
Capabilities GoalAdapterCapabilities
}
func (c *Controller) GoalCapabilities(ctx context.Context, input GoalReconcileInput) (GoalAdapterCapabilities, error) {
release, err := c.acquireLifecycleLockContext(ctx, input.RoomID, input.AgentSessionID)
if err != nil {
return GoalAdapterCapabilities{}, err
}
defer release()
session, adapter, err := c.sessionAndAdapter(input.RoomID, input.AgentSessionID)
if err != nil {
return GoalAdapterCapabilities{}, err
}
if session.IsSideConversation() {
return GoalAdapterCapabilities{}, ErrSideConversationUnsupported
}
goalAdapter, ok := adapter.(GoalAdapter)
if !ok {
return GoalAdapterCapabilities{}, fmt.Errorf("agent provider does not support goals")
}
return goalAdapter.GoalCapabilities(), nil
}
// ReconcileGoal queries or inspects the provider through the GoalAdapter and
// returns normalized evidence. It never mutates durable desired state and
// never creates a Turn.
func (c *Controller) ReconcileGoal(ctx context.Context, input GoalReconcileInput) (GoalReconcileResult, error) {
releaseLifecycleLock, err := c.acquireLifecycleLockContext(ctx, input.RoomID, input.AgentSessionID)
if err != nil {
return GoalReconcileResult{}, err
}
defer releaseLifecycleLock()
session, adapter, err := c.sessionAndAdapter(input.RoomID, input.AgentSessionID)
if err != nil {
return GoalReconcileResult{}, err
}
if session.IsSideConversation() {
return GoalReconcileResult{}, ErrSideConversationUnsupported
}
goalAdapter, ok := adapter.(GoalAdapter)
if !ok {
return GoalReconcileResult{}, fmt.Errorf("agent provider does not support goals")
}
if input.RequireLive {
if probe, ok := adapter.(LiveSessionProbeAdapter); ok && !probe.HasLiveSession(session) {
return GoalReconcileResult{}, ErrSessionDisconnected
}
} else {
if err := c.ensureLiveAdapterSession(ctx, session, adapter); err != nil {
return GoalReconcileResult{}, err
}
}
result, err := goalAdapter.ReconcileGoal(ctx, session)
if err != nil {
return GoalReconcileResult{}, err
}
c.applySessionEventsByAgentSessionID(session.AgentSessionID, result.Events)
return GoalReconcileResult{
AgentSessionID: session.AgentSessionID,
Goal: goalAdapter.NormalizeGoalObservation(result.Observation),
Evidence: clonePayload(result.Evidence),
Capabilities: goalAdapter.GoalCapabilities(),
}, nil
}