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
252 lines
8.2 KiB
Go
252 lines
8.2 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"reflect"
|
|
"testing"
|
|
|
|
tuttigenerated "github.com/tutti-os/tutti/services/tuttid/api/generated"
|
|
agenttargetbiz "github.com/tutti-os/tutti/services/tuttid/biz/agenttarget"
|
|
workspacebiz "github.com/tutti-os/tutti/services/tuttid/biz/workspace"
|
|
agentservice "github.com/tutti-os/tutti/services/tuttid/service/agent"
|
|
agentstatusservice "github.com/tutti-os/tutti/services/tuttid/service/agentstatus"
|
|
)
|
|
|
|
func TestDaemonAPIRoutesWorkspaceAppAgentPreferencesRejectInvalidPath(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
mux := http.NewServeMux()
|
|
RegisterRoutes(mux, NewRoutes(DaemonAPI{}))
|
|
recorder := performGeneratedRouteRequest(
|
|
t,
|
|
mux,
|
|
http.MethodGet,
|
|
"/v1/workspaces/%20/apps/canvas/preferences/agent",
|
|
nil,
|
|
)
|
|
if recorder.Code != http.StatusBadRequest {
|
|
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusBadRequest, recorder.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestDaemonAPIRoutesWorkspaceAppAgentProviderStatusesDefaultToEnabledAgentTargets(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var capturedProviders []string
|
|
mux := http.NewServeMux()
|
|
RegisterRoutes(mux, NewRoutes(DaemonAPI{
|
|
AgentStatusService: stubAgentStatusService{
|
|
listFn: func(_ context.Context, input agentstatusservice.ListInput) (agentstatusservice.Snapshot, error) {
|
|
capturedProviders = append([]string(nil), input.Providers...)
|
|
return agentstatusservice.Snapshot{
|
|
Providers: []agentstatusservice.ProviderStatus{
|
|
{Provider: "codex"},
|
|
{Provider: "hermes"},
|
|
{Provider: "opencode"},
|
|
},
|
|
}, nil
|
|
},
|
|
},
|
|
AgentTargetService: stubAgentTargetService{
|
|
listFn: func(context.Context) ([]agenttargetbiz.Target, error) {
|
|
return []agenttargetbiz.Target{
|
|
{
|
|
ID: agenttargetbiz.IDLocalCodex,
|
|
Provider: "codex",
|
|
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("codex"),
|
|
Name: "Codex",
|
|
Enabled: true,
|
|
Source: agenttargetbiz.SourceSystem,
|
|
},
|
|
{
|
|
ID: "local:hermes",
|
|
Provider: "hermes",
|
|
LaunchRefJSON: `{"type":"local_cli","provider":"hermes"}`,
|
|
Name: "Hermes",
|
|
Enabled: true,
|
|
Source: agenttargetbiz.SourceSystem,
|
|
},
|
|
{
|
|
ID: agenttargetbiz.IDLocalCursor,
|
|
Provider: "cursor",
|
|
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("cursor"),
|
|
Name: "Cursor",
|
|
Enabled: false,
|
|
Source: agenttargetbiz.SourceSystem,
|
|
},
|
|
{
|
|
ID: agenttargetbiz.IDLocalOpenCode,
|
|
Provider: "opencode",
|
|
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("opencode"),
|
|
Name: "OpenCode",
|
|
Enabled: true,
|
|
Source: agenttargetbiz.SourceSystem,
|
|
},
|
|
}, nil
|
|
},
|
|
},
|
|
AppCenterService: installedWorkspaceAppCenter("canvas"),
|
|
}))
|
|
|
|
recorder := performGeneratedRouteRequest(
|
|
t,
|
|
mux,
|
|
http.MethodGet,
|
|
"/v1/workspaces/ws-1/apps/canvas/agent-providers/status",
|
|
nil,
|
|
)
|
|
if recorder.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusOK, recorder.Body.String())
|
|
}
|
|
if !reflect.DeepEqual(capturedProviders, []string{"codex", "hermes", "opencode"}) {
|
|
t.Fatalf("providers = %#v, want [codex hermes opencode]", capturedProviders)
|
|
}
|
|
|
|
var response tuttigenerated.AgentProviderStatusListResponse
|
|
decodeGeneratedRouteResponse(t, recorder, &response)
|
|
gotProviders := make([]string, 0, len(response.Providers))
|
|
for _, provider := range response.Providers {
|
|
gotProviders = append(gotProviders, string(provider.Provider))
|
|
}
|
|
if !reflect.DeepEqual(gotProviders, []string{"codex", "hermes", "opencode"}) {
|
|
t.Fatalf("response providers = %#v, want [codex hermes opencode]", gotProviders)
|
|
}
|
|
}
|
|
|
|
func TestDaemonAPIRoutesWorkspaceAppAgentProviderStatusesNarrowExplicitProvidersToAgentTargets(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var capturedProviders []string
|
|
mux := http.NewServeMux()
|
|
RegisterRoutes(mux, NewRoutes(DaemonAPI{
|
|
AgentStatusService: stubAgentStatusService{
|
|
listFn: func(_ context.Context, input agentstatusservice.ListInput) (agentstatusservice.Snapshot, error) {
|
|
capturedProviders = append([]string(nil), input.Providers...)
|
|
return agentstatusservice.Snapshot{
|
|
Providers: []agentstatusservice.ProviderStatus{{Provider: "codex"}},
|
|
}, nil
|
|
},
|
|
},
|
|
AgentTargetService: stubAgentTargetService{
|
|
listFn: func(context.Context) ([]agenttargetbiz.Target, error) {
|
|
return []agenttargetbiz.Target{
|
|
{
|
|
ID: agenttargetbiz.IDLocalCodex,
|
|
Provider: "codex",
|
|
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("codex"),
|
|
Name: "Codex",
|
|
Enabled: true,
|
|
Source: agenttargetbiz.SourceSystem,
|
|
},
|
|
}, nil
|
|
},
|
|
},
|
|
AppCenterService: installedWorkspaceAppCenter("canvas"),
|
|
}))
|
|
|
|
recorder := performGeneratedRouteRequest(
|
|
t,
|
|
mux,
|
|
http.MethodGet,
|
|
"/v1/workspaces/ws-1/apps/canvas/agent-providers/status?providers=codex&providers=hermes",
|
|
nil,
|
|
)
|
|
if recorder.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusOK, recorder.Body.String())
|
|
}
|
|
if !reflect.DeepEqual(capturedProviders, []string{"codex"}) {
|
|
t.Fatalf("providers = %#v, want [codex]", capturedProviders)
|
|
}
|
|
}
|
|
|
|
func TestDaemonAPIRoutesWorkspaceAppComposerOptionsBindPathWorkspace(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
mux := http.NewServeMux()
|
|
RegisterRoutes(mux, NewRoutes(DaemonAPI{
|
|
AgentSessionService: stubAgentSessionService{
|
|
composerOptionsFn: func(_ context.Context, input agentservice.ComposerOptionsInput) (agentservice.ComposerOptions, error) {
|
|
if input.WorkspaceID != "ws-1" {
|
|
t.Fatalf("workspaceID = %q, want ws-1", input.WorkspaceID)
|
|
}
|
|
return agentservice.ComposerOptions{Provider: input.Provider}, nil
|
|
},
|
|
},
|
|
AgentTargetService: stubAgentTargetService{
|
|
listFn: func(context.Context) ([]agenttargetbiz.Target, error) {
|
|
return []agenttargetbiz.Target{{
|
|
ID: agenttargetbiz.IDLocalCodex,
|
|
Provider: "codex",
|
|
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("codex"),
|
|
Name: "Codex",
|
|
Enabled: true,
|
|
Source: agenttargetbiz.SourceSystem,
|
|
}}, nil
|
|
},
|
|
},
|
|
AppCenterService: installedWorkspaceAppCenter("canvas"),
|
|
}))
|
|
|
|
recorder := performGeneratedRouteRequest(
|
|
t,
|
|
mux,
|
|
http.MethodPost,
|
|
"/v1/workspaces/ws-1/apps/canvas/agent-providers/codex/composer-options",
|
|
map[string]any{"workspaceId": "ws-2"},
|
|
)
|
|
if recorder.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusOK, recorder.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestDaemonAPIRoutesWorkspaceAppComposerOptionsRejectHiddenProvider(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
composerOptionsCalled := false
|
|
mux := http.NewServeMux()
|
|
RegisterRoutes(mux, NewRoutes(DaemonAPI{
|
|
AgentSessionService: stubAgentSessionService{
|
|
composerOptionsFn: func(_ context.Context, input agentservice.ComposerOptionsInput) (agentservice.ComposerOptions, error) {
|
|
composerOptionsCalled = true
|
|
return agentservice.ComposerOptions{Provider: input.Provider}, nil
|
|
},
|
|
},
|
|
AgentTargetService: stubAgentTargetService{
|
|
listFn: func(context.Context) ([]agenttargetbiz.Target, error) {
|
|
return []agenttargetbiz.Target{{
|
|
ID: agenttargetbiz.IDLocalCodex,
|
|
Provider: "codex",
|
|
LaunchRefJSON: agenttargetbiz.MustLocalCLILaunchRefJSON("codex"),
|
|
Name: "Codex",
|
|
Enabled: true,
|
|
Source: agenttargetbiz.SourceSystem,
|
|
}}, nil
|
|
},
|
|
},
|
|
AppCenterService: installedWorkspaceAppCenter("canvas"),
|
|
}))
|
|
|
|
recorder := performGeneratedRouteRequest(
|
|
t,
|
|
mux,
|
|
http.MethodPost,
|
|
"/v1/workspaces/ws-1/apps/canvas/agent-providers/opencode/composer-options",
|
|
nil,
|
|
)
|
|
if recorder.Code != http.StatusBadRequest {
|
|
t.Fatalf("status = %d, want %d; body: %s", recorder.Code, http.StatusBadRequest, recorder.Body.String())
|
|
}
|
|
if composerOptionsCalled {
|
|
t.Fatal("composer options service called for hidden provider")
|
|
}
|
|
}
|
|
|
|
func installedWorkspaceAppCenter(appID string) stubWorkspaceAppCenterService {
|
|
return stubWorkspaceAppCenterService{
|
|
listFn: func(_ context.Context, _ string) ([]workspacebiz.WorkspaceApp, error) {
|
|
return []workspacebiz.WorkspaceApp{workspaceAppForRouteTest(appID, workspacebiz.AppRuntimeStatusIdle)}, nil
|
|
},
|
|
}
|
|
}
|