- add active steering and interrupt-restart replay fixtures - update Claude adapter/orchestrator turn handling for steering - refresh replay and integration test coverage
Showing the changes to apps/server/scripts (2 of 15 files). Show all
Unified · Split
| @@ -14,7 +14,9 @@ import type { RuntimePolicyV2Override } from "../src/orchestration-v2/RuntimePol · 13 unmodified lines | |||
| 14 | import { makeCheckpointWorkspace } from "../src/orchestration-v2/testkit/ReplayFixtureWorkspace.ts"; | 14 | import { makeCheckpointWorkspace } from "../src/orchestration-v2/testkit/ReplayFixtureWorkspace.ts"; |
| 15 | import { CLAUDE_MODEL_SELECTION } from "../src/orchestration-v2/testkit/fixtures/shared.ts"; | 15 | import { CLAUDE_MODEL_SELECTION } from "../src/orchestration-v2/testkit/fixtures/shared.ts"; |
| 16 | import { | 16 | import { |
| 17 | MESSAGE_STEERING_INITIAL_PROMPT, | ||
| 17 | MULTI_TURN_FIRST_PROMPT, | 18 | MULTI_TURN_FIRST_PROMPT, |
| 19 | MESSAGE_STEERING_STEER_PROMPT, | ||
| 18 | READ_ONLY_NEVER_POLICY, | 20 | READ_ONLY_NEVER_POLICY, |
| 19 | READ_ONLY_ON_REQUEST_POLICY, | 21 | READ_ONLY_ON_REQUEST_POLICY, |
| 20 | RESTRICTED_GRANULAR_POLICY, | 22 | RESTRICTED_GRANULAR_POLICY, |
| @@ -46,6 +48,18 @@ const CLAUDE_RECORDINGS = { · 25 unmodified lines | |||
| 46 | queryMode: "restart", | 48 | queryMode: "restart", |
| 47 | enableTools: true, | 49 | enableTools: true, |
| 48 | }, | 50 | }, |
| 51 | queued_turn: { | ||
| 52 | prompts: [MULTI_TURN_FIRST_PROMPT, MULTI_TURN_SECOND_PROMPT], | ||
| 53 | defaultTranscriptFile: "fixtures/queued_turn/claude_transcript.ndjson", | ||
| 54 | queryMode: "streaming", | ||
| 55 | enableTools: true, | ||
| 56 | }, | ||
| 57 | message_steering: { | ||
| 58 | prompts: [MESSAGE_STEERING_INITIAL_PROMPT, MESSAGE_STEERING_STEER_PROMPT], | ||
| 59 | defaultTranscriptFile: "fixtures/message_steering/claude_transcript.ndjson", | ||
| 60 | queryMode: "active_steering", | ||
| 61 | enableTools: true, | ||
| 62 | }, | ||
| 49 | tool_call_read_only: { | 63 | tool_call_read_only: { |
| 50 | prompts: [TOOL_CALL_READ_ONLY_PROMPT], | 64 | prompts: [TOOL_CALL_READ_ONLY_PROMPT], |
| 51 | defaultTranscriptFile: "fixtures/tool_call_read_only/claude_transcript.ndjson", | 65 | defaultTranscriptFile: "fixtures/tool_call_read_only/claude_transcript.ndjson", |
| @@ -88,15 +102,24 @@ function readArgValue(name: string): string | undefined { · 36 unmodified lines | |||
| 88 | return index >= 0 ? args[index + 1] : undefined; | 102 | return index >= 0 ? args[index + 1] : undefined; |
| 89 | } | 103 | } |
| 90 | 104 | ||
| 91 | function selectedQueryMode(defaultMode: "streaming" | "restart"): "streaming" | "restart" { | 105 | type ClaudeRecordingQueryMode = "streaming" | "restart" | "active_steering" | "interrupt_restart"; |
| 106 | |||
| 107 | function selectedQueryMode(defaultMode: ClaudeRecordingQueryMode): ClaudeRecordingQueryMode { | ||
| 92 | const raw = readArgValue("--query-mode") ?? process.env.T3_CLAUDE_REPLAY_QUERY_MODE; | 108 | const raw = readArgValue("--query-mode") ?? process.env.T3_CLAUDE_REPLAY_QUERY_MODE; |
| 93 | if (raw === undefined) { | 109 | if (raw === undefined) { |
| 94 | return defaultMode; | 110 | return defaultMode; |
| 95 | } | 111 | } |
| 96 | if (raw === "streaming" || raw === "restart") { | 112 | if ( |
| 113 | raw === "streaming" || | ||
| 114 | raw === "restart" || | ||
| 115 | raw === "active_steering" || | ||
| 116 | raw === "interrupt_restart" | ||
| 117 | ) { | ||
| 97 | return raw; | 118 | return raw; |
| 98 | } | 119 | } |
| 99 | throw new Error(`Unsupported Claude replay query mode '${raw}'. Use 'streaming' or 'restart'.`); | 120 | throw new Error( |
| 121 | `Unsupported Claude replay query mode '${raw}'. Use 'streaming', 'restart', 'active_steering', or 'interrupt_restart'.`, | ||
| 122 | ); | ||
| 100 | } | 123 | } |
| 101 | 124 | ||
| 102 | const scenario = readArgValue("--scenario") ?? process.env.T3_CLAUDE_REPLAY_SCENARIO ?? "simple"; | 125 | const scenario = readArgValue("--scenario") ?? process.env.T3_CLAUDE_REPLAY_SCENARIO ?? "simple"; |
| @@ -8,6 +8,7 @@ import * as CodexClient from "effect-codex-app-server/client"; · 7 unmodified lines | |||
| 8 | import type * as CodexSchema from "effect-codex-app-server/schema"; | 8 | import type * as CodexSchema from "effect-codex-app-server/schema"; |
| 9 | 9 | ||
| 10 | import { | 10 | import { |
| 11 | MESSAGE_STEERING_INITIAL_PROMPT, | ||
| 11 | MESSAGE_STEERING_STEER_PROMPT, | 12 | MESSAGE_STEERING_STEER_PROMPT, |
| 12 | MULTI_TURN_FIRST_PROMPT, | 13 | MULTI_TURN_FIRST_PROMPT, |
| 13 | MULTI_TURN_SECOND_PROMPT, | 14 | MULTI_TURN_SECOND_PROMPT, |
| @@ -491,20 +492,12 @@ function scenarios(): ReadonlyArray<ReplayScenario> { · 477 unmodified lines | |||
| 491 | { | 492 | { |
| 492 | name: "immediate-steer", | 493 | name: "immediate-steer", |
| 493 | description: "Start a turn, then immediately steer the active root turn.", | 494 | description: "Start a turn, then immediately steer the active root turn.", |
| 494 | turnDefaults: { | ||
| 495 | approvalPolicy: "never", | ||
| 496 | sandboxPolicy: workspaceWriteSandbox(), | ||
| 497 | }, | ||
| 498 | steps: [ | 495 | steps: [ |
| 499 | { | 496 | { |
| 500 | type: "steeredTurn", | 497 | type: "steeredTurn", |
| 501 | label: "steered", | 498 | label: "steered", |
| 502 | prompt: TOOL_CALL_WRITE_PROMPT, | 499 | prompt: MESSAGE_STEERING_INITIAL_PROMPT, |
| 503 | steer: MESSAGE_STEERING_STEER_PROMPT, | 500 | steer: MESSAGE_STEERING_STEER_PROMPT, |
| 504 | turnOverrides: { | ||
| 505 | approvalPolicy: "on-request", | ||
| 506 | sandboxPolicy: readOnlyFullAccessSandbox(), | ||
| 507 | }, | ||
| 508 | }, | 501 | }, |
| 509 | ], | 502 | ], |
| 510 | }, | 503 | }, |