History

Support active Claude steering and turn replay mapping

- add active steering and interrupt-restart replay fixtures - update Claude adapter/orchestrator turn handling for steering - refresh replay and integration test coverage

Julius Marminge committed 6 months ago

Commit e127dfd1 parent a6042da15 files · +837 −126Browse files

Showing the changes to apps/server/scripts (2 of 15 files). Show all

Unified · Split

2 files
  1. apps/server/scripts/record-claude-agent-sdk-replay-fixture.ts +26 −3
  2. apps/server/scripts/record-codex-app-server-replay-fixture.ts +2 −9
apps/server/scripts/record-claude-agent-sdk-replay-fixture.ts+26−3
@@ -14,7 +14,9 @@ import type { RuntimePolicyV2Override } from "../src/orchestration-v2/RuntimePol · 13 unmodified lines
14import { makeCheckpointWorkspace } from "../src/orchestration-v2/testkit/ReplayFixtureWorkspace.ts";14import { makeCheckpointWorkspace } from "../src/orchestration-v2/testkit/ReplayFixtureWorkspace.ts";
15import { CLAUDE_MODEL_SELECTION } from "../src/orchestration-v2/testkit/fixtures/shared.ts";15import { CLAUDE_MODEL_SELECTION } from "../src/orchestration-v2/testkit/fixtures/shared.ts";
16import {16import {
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
91function selectedQueryMode(defaultMode: "streaming" | "restart"): "streaming" | "restart" {105type ClaudeRecordingQueryMode = "streaming" | "restart" | "active_steering" | "interrupt_restart";
106
107function 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
102const scenario = readArgValue("--scenario") ?? process.env.T3_CLAUDE_REPLAY_SCENARIO ?? "simple";125const scenario = readArgValue("--scenario") ?? process.env.T3_CLAUDE_REPLAY_SCENARIO ?? "simple";
apps/server/scripts/record-codex-app-server-replay-fixture.ts+2−9
@@ -8,6 +8,7 @@ import * as CodexClient from "effect-codex-app-server/client"; · 7 unmodified lines
8import type * as CodexSchema from "effect-codex-app-server/schema";8import type * as CodexSchema from "effect-codex-app-server/schema";
9 9
10import {10import {
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 },