Files
tutti/services/tuttid/api/daemon_agent_sessions_interactive_test.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

72 lines
3.0 KiB
Go

package api
import (
"context"
"testing"
agenthost "github.com/tutti-os/tutti/packages/agent/host"
tuttigenerated "github.com/tutti-os/tutti/services/tuttid/api/generated"
"github.com/tutti-os/tutti/services/tuttid/apierrors"
agentservice "github.com/tutti-os/tutti/services/tuttid/service/agent"
)
func TestSubmitWorkspaceAgentInteractiveBuildsTypedHostCommand(t *testing.T) {
var gotRef agenthost.InteractionRef
var gotInput agenthost.SubmitInteractiveInput
action, option := "approve", "allow-once"
payload := map[string]any{"answer": "yes"}
api := DaemonAPI{AgentSessionService: stubAgentSessionService{
submitInteractiveFn: func(_ context.Context, ref agenthost.InteractionRef, input agenthost.SubmitInteractiveInput) (agentservice.Session, error) {
gotRef, gotInput = ref, input
return agentservice.Session{ID: ref.AgentSessionID}, nil
},
}}
response, err := api.SubmitWorkspaceAgentInteractive(context.Background(), tuttigenerated.SubmitWorkspaceAgentInteractiveRequestObject{
WorkspaceID: "workspace-1", AgentSessionID: "session-1", RequestID: "request-1",
Body: &tuttigenerated.SubmitWorkspaceAgentInteractiveJSONRequestBody{
TurnId: "turn-1", Action: &action, OptionId: &option, Payload: &payload,
},
})
if err != nil {
t.Fatalf("SubmitWorkspaceAgentInteractive() error = %v", err)
}
if _, ok := response.(tuttigenerated.SubmitWorkspaceAgentInteractive200JSONResponse); !ok {
t.Fatalf("response = %T, want 200", response)
}
if gotRef != (agenthost.InteractionRef{
WorkspaceID: "workspace-1", AgentSessionID: "session-1", TurnID: "turn-1", RequestID: "request-1",
}) {
t.Fatalf("interaction ref = %#v", gotRef)
}
if gotInput.Action == nil || *gotInput.Action != action || gotInput.OptionID == nil || *gotInput.OptionID != option || gotInput.Payload["answer"] != "yes" {
t.Fatalf("interactive input = %#v", gotInput)
}
}
func TestSubmitWorkspaceAgentInteractiveReturnsConflictForStaleRequest(t *testing.T) {
action := "approve"
api := DaemonAPI{AgentSessionService: stubAgentSessionService{
submitInteractiveFn: func(context.Context, agenthost.InteractionRef, agenthost.SubmitInteractiveInput) (agentservice.Session, error) {
return agentservice.Session{}, agentservice.ErrInteractiveRequestNotLive
},
}}
response, err := api.SubmitWorkspaceAgentInteractive(context.Background(), tuttigenerated.SubmitWorkspaceAgentInteractiveRequestObject{
WorkspaceID: "workspace-1", AgentSessionID: "session-1", RequestID: "request-1",
Body: &tuttigenerated.SubmitWorkspaceAgentInteractiveJSONRequestBody{
TurnId: "turn-1", Action: &action,
},
})
if err != nil {
t.Fatalf("SubmitWorkspaceAgentInteractive() error = %v", err)
}
conflict, ok := response.(tuttigenerated.SubmitWorkspaceAgentInteractive409JSONResponse)
if !ok {
t.Fatalf("response = %T, want 409 conflict", response)
}
if conflict.Error.Reason == nil || *conflict.Error.Reason != apierrors.ReasonAgentInteractiveRequestStale {
t.Fatalf("error = %#v, want stale interactive reason", conflict.Error)
}
}