package agentruntime import ( "context" "strings" "testing" "time" activityshared "github.com/tutti-os/tutti/packages/agent/daemon/activity/events" ) func testActiveTuttiModeSnapshot() *TuttiModeTurnSnapshot { return &TuttiModeTurnSnapshot{ ActivationID: "activation-1", RevisionID: "revision-7", Revision: 7, State: TuttiModeStateActive, Source: "slash_command", PreferenceVersion: TuttiModePreferenceVersionEffectSpeed, Effect: 80, Speed: 70, OrchestrationIntensity: 80, } } func TestRenderTuttiModeHostContextCarriesEffectAndSpeed(t *testing.T) { t.Parallel() contextText := renderTuttiModeHostContextForCLI(testActiveTuttiModeSnapshot(), "tutti") for _, expected := range []string{ `"effect":80`, `"speed":70`, `"parallelTarget":3`, "Effect drives outcome quality", "Speed drives completion latency", "parallel Agent target", "`tutti plan propose` shell command", "Combine them rather than averaging them", "`$tutti-model-allocation` skill", "C0-C3 capability ladder", } { if !strings.Contains(contextText, expected) { t.Fatalf("host context = %q, want %q", contextText, expected) } } } func TestTuttiModeParallelTargetUsesFourSpeedBands(t *testing.T) { t.Parallel() for _, testCase := range []struct { speed int want int }{ {speed: 0, want: 1}, {speed: 24, want: 1}, {speed: 25, want: 2}, {speed: 49, want: 2}, {speed: 50, want: 3}, {speed: 74, want: 3}, {speed: 75, want: 4}, {speed: 100, want: 4}, } { if got := tuttiModeParallelTarget(testCase.speed); got != testCase.want { t.Fatalf( "tuttiModeParallelTarget(%d) = %d, want %d", testCase.speed, got, testCase.want, ) } } } func TestRenderTuttiModeHostContextReadsLegacyIntensitySnapshot(t *testing.T) { t.Parallel() snapshot := testActiveTuttiModeSnapshot() snapshot.PreferenceVersion = 0 snapshot.Effect = 0 snapshot.Speed = 0 snapshot.OrchestrationIntensity = 73 contextText := renderTuttiModeHostContextForCLI(snapshot, "tutti") for _, expected := range []string{ `"effect":73`, `"speed":50`, `"parallelTarget":3`, `"orchestrationIntensity":73`, } { if !strings.Contains(contextText, expected) { t.Fatalf("legacy host context = %q, want %q", contextText, expected) } } } func TestRenderTuttiModeHostContextCarriesWorkedWorkflowExamples(t *testing.T) { t.Parallel() contextText := renderTuttiModeHostContextForCLI(testActiveTuttiModeSnapshot(), "tutti") for _, expected := range []string{ "every plan command below is a shell command, not a built-in tool", "update_plan, TodoWrite, plan mode", "tutti agent list --json", "tutti agent composer-options --agent-id --json", "tutti plan propose --file /abs/path/plan.md --request-id plan-faq-v1", "complete launch configuration: agentTargetId, model, and permissionModeId", "never invent these ids", "model table is a tiering prior, never an availability source", "semantic is \"full-access\" (codex: full-access, claude-code: bypassPermissions)", "the user approves once at plan review", "Set execution.reasoningIntensity for the plan's actual provider reasoning strength", "schema: tutti-mode-plan/v1", "topicId: default", "effect: 80", "speed: 70", "reasoningIntensity: 80", "dependsOn: [task-1]", "permissionModeId: bypassPermissions", "parallelizable: true", "Identify independent workstreams and shape them as parallel groups", "parallelTarget", "each runs in an isolated git worktree branched from the shared checkout", "follow every parallel group with an integration task", "No task starts automatically after plan acceptance", "`autoAccept` is retained only for compatibility and has no dispatch authority", "`tutti plan issue schedule --issue-id ", "schedule exactly the task IDs you selected", "unsafe concurrent set is rejected", "schedule those tasks one at a time", "the first task must initialize one (`git init` plus an initial commit)", "this conversation becomes the plan's orchestrator", "stopping this conversation stops every running task", "A dispatch-paused Issue must stay quiet", "`tutti plan issue resume --issue-id --json`", "all tasks becoming terminal starts Goal Review", "`tutti plan issue complete --issue-id --checkpoint-id ", "review whether the user's goal is actually satisfied", "never infer completion from task counts", "end the turn as soon as propose returns a workflowId", "`tutti plan revise --workflow-id --file --request-id `", "`tutti issue topic list --json`", "a plan that was only shown in chat was never submitted", } { if !strings.Contains(contextText, expected) { t.Fatalf("host context = %q, want %q", contextText, expected) } } for _, forbidden := range []string{ "plan wait", "plan-wait", "dispatches the tasks", "Set `autoAccept: true` on every task by default so accepted plans run unattended", "adjust the remaining graph through `tutti issue` commands", "autoAccept: true", "silently degrades to one-at-a-time execution", } { if strings.Contains(contextText, forbidden) { t.Fatalf("host context = %q, must not instruct a wait command (%q)", contextText, forbidden) } } } func TestRenderTuttiModeHostContextUsesResolvedCLICommandName(t *testing.T) { t.Parallel() contextText := renderTuttiModeHostContextForCLI(testActiveTuttiModeSnapshot(), "tutti-dev") for _, expected := range []string{ "`tutti-dev plan propose` shell command", "tutti-dev plan propose --file /abs/path/plan.md", "`tutti-dev plan revise --workflow-id", } { if !strings.Contains(contextText, expected) { t.Fatalf("host context = %q, want %q", contextText, expected) } } if strings.Contains(contextText, "`tutti plan propose`") { t.Fatalf("host context = %q, must not fall back to the production CLI name", contextText) } } func TestTuttiCLICommandNameFollowsEnvironment(t *testing.T) { t.Setenv("TUTTI_ENV", "") if got := tuttiCLICommandName(); got != "tutti" { t.Fatalf("cli command name = %q, want tutti", got) } t.Setenv("TUTTI_ENV", "dev") if got := tuttiCLICommandName(); got != "tutti-dev" { t.Fatalf("cli command name = %q, want tutti-dev", got) } } func TestRenderTuttiModeHostContextRejectsOutOfRangePreference(t *testing.T) { t.Parallel() snapshot := testActiveTuttiModeSnapshot() snapshot.Speed = 101 if got := renderTuttiModeHostContext(snapshot); got != "" { t.Fatalf("host context = %q, want empty for out-of-range preference", got) } } func TestRenderTuttiModeHostContextCarriesTypedActiveState(t *testing.T) { t.Parallel() contextText := renderTuttiModeHostContextForCLI(testActiveTuttiModeSnapshot(), "tutti") for _, expected := range []string{ "