Skip to content
Source
Sign inSign up

CommandPolicy.test.ts

303 lines9.3 KB

1import { assert, it } from "@effect/vitest";
2import {
3 CommandId,
4 MessageId,
5 type OrchestrationV2ProviderCapabilities,
6 type OrchestrationV2ThreadProjection,
7 ProviderInstanceId,
8 ProviderSessionId,
9 ProviderThreadId,
10 RunAttemptId,
11 RunId,
12 ThreadId,
13} from "@t3tools/contracts";
14import * as Effect from "effect/Effect";
15​
16import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts";
17import { CursorProviderCapabilitiesV2 } from "@t3tools/provider-cursor/testing";
18import * as CommandPolicy from "./CommandPolicy.ts";
19​
20const commandId = CommandId.make("command-policy-test");
21const threadId = ThreadId.make("command-policy-thread");
22const activeRunId = RunId.make("command-policy-active-run");
23const activeAttemptId = RunAttemptId.make("command-policy-active-attempt");
24const userMessageId = MessageId.make("command-policy-user-message");
25​
26const baseCapabilities: OrchestrationV2ProviderCapabilities = CodexProviderCapabilitiesV2;
27​
28function capabilities(
29 override: (current: OrchestrationV2ProviderCapabilities) => OrchestrationV2ProviderCapabilities,
30): OrchestrationV2ProviderCapabilities {
31 return override(baseCapabilities);
33​
34function dispatchProjection(
35 sessionCapabilities?: OrchestrationV2ProviderCapabilities,
36): OrchestrationV2ThreadProjection {
37 const providerThreadId = ProviderThreadId.make("command-policy-provider-thread");
38 const providerSessionId = ProviderSessionId.make("command-policy-provider-session");
39 return {
40 runs:
41 sessionCapabilities === undefined
42 ? []
43 : [
44 {
45 id: activeRunId,
46 status: "running",
47 providerThreadId,
48 activeAttemptId,
49 userMessageId,
50 },
51 ],
52 messages: [{ id: userMessageId, text: "first", attachments: [] }],
53 providerThreads:
54 sessionCapabilities === undefined ? [] : [{ id: providerThreadId, providerSessionId }],
55 providerSessions:
56 sessionCapabilities === undefined
57 ? []
58 : [{ id: providerSessionId, capabilities: sessionCapabilities }],
59 providerTurns:
60 sessionCapabilities === undefined
61 ? []
62 : [{ runAttemptId: activeAttemptId, status: "running" }],
63 } as unknown as OrchestrationV2ThreadProjection;
65​
66it("resolves automatic message delivery from authoritative provider capabilities", () => {
67 assert.deepEqual(
68 CommandPolicy.resolveMessageDispatchIntent(
69 dispatchProjection(),
70 { type: "start_immediately" },
71 "auto",
72 ),
73 { type: "start_immediately" },
74 );
75 assert.deepEqual(
76 CommandPolicy.resolveMessageDispatchIntent(
77 dispatchProjection(baseCapabilities),
78 { type: "start_immediately" },
79 "auto",
80 ),
81 { type: "steer_active", targetRunId: activeRunId },
82 );
83 assert.deepEqual(
84 CommandPolicy.resolveMessageDispatchIntent(
85 dispatchProjection(
86 capabilities((current) => ({
87 ...current,
88 turns: {
89 ...current.turns,
90 supportsActiveSteering: false,
91 supportsQueuedMessages: true,
92 supportsSteeringByInterruptRestart: true,
93 },
94 })),
95 ),
96 { type: "start_immediately" },
97 "auto",
98 ),
99 { type: "queue_after_active" },
100 );
101 assert.deepEqual(
102 CommandPolicy.resolveMessageDispatchIntent(
103 dispatchProjection(
104 capabilities((current) => ({
105 ...current,
106 turns: {
107 ...current.turns,
108 supportsActiveSteering: false,
109 supportsQueuedMessages: false,
110 supportsSteeringByInterruptRestart: true,
111 },
112 })),
113 ),
114 { type: "start_immediately" },
115 "auto",
116 ),
117 { type: "restart_active", targetRunId: activeRunId },
118 );
119});
120​
121it.each(["preparing", "starting"] as const)(
122 "queues an automatic message while the handoff run is %s",
123 (status) => {
124 const projection = dispatchProjection(baseCapabilities);
125 assert.deepEqual(
126 CommandPolicy.resolveMessageDispatchIntent(
127 { ...projection, runs: projection.runs.map((run) => ({ ...run, status })) },
128 { type: "start_immediately" },
129 "auto",
130 ),
131 { type: "queue_after_active" },
132 );
133 },
134);
135​
136it.each([
137 ["has not started", []],
138 ["is pending", [{ runAttemptId: activeAttemptId, status: "pending" }]],
139 ["has completed", [{ runAttemptId: activeAttemptId, status: "completed" }]],
140 [
141 "belongs to a previous attempt",
142 [{ runAttemptId: RunAttemptId.make("previous-attempt"), status: "running" }],
143 ],
144])("queues only automatic delivery when the active run's provider turn %s", (_, providerTurns) => {
145 const projection = {
146 ...dispatchProjection(baseCapabilities),
147 providerTurns,
148 } as unknown as OrchestrationV2ThreadProjection;
149 assert.deepEqual(
150 CommandPolicy.resolveMessageDispatchIntent(projection, { type: "start_immediately" }, "auto"),
151 { type: "queue_after_active" },
152 );
153 assert.deepEqual(
154 CommandPolicy.resolveMessageDispatchIntent(projection, { type: "start_immediately" }, "steer"),
155 { type: "steer_active", targetRunId: activeRunId },
156 );
157 assert.deepEqual(
158 CommandPolicy.resolveMessageDispatchIntent(
159 projection,
160 { type: "start_immediately" },
161 "restart",
162 ),
163 { type: "restart_active", targetRunId: activeRunId },
164 );
165});
166​
167// regression: #26695 an interrupt-restart steer cancels Copilot's background agents
168it("queues a steer for a provider that cannot steer either way", () => {
169 const projection = dispatchProjection(
170 capabilities((current) => ({
171 ...current,
172 turns: {
173 ...current.turns,
174 supportsActiveSteering: false,
175 supportsSteeringByInterruptRestart: false,
176 supportsQueuedMessages: true,
177 },
178 })),
179 );
180 for (const deliveryIntent of ["auto", "steer"] as const) {
181 assert.deepEqual(
182 CommandPolicy.resolveMessageDispatchIntent(
183 projection,
184 { type: "start_immediately" },
185 deliveryIntent,
186 ),
187 { type: "queue_after_active" },
188 );
189 }
190 assert.deepEqual(
191 CommandPolicy.resolveMessageDispatchIntent(projection, {
192 type: "steer_active",
193 targetRunId: activeRunId,
194 }),
195 { type: "queue_after_active" },
196 );
197 assert.deepEqual(
198 CommandPolicy.resolveMessageDispatchIntent(
199 projection,
200 { type: "start_immediately" },
201 "restart",
202 ),
203 { type: "restart_active", targetRunId: activeRunId },
204 );
205 assert.deepEqual(
206 CommandPolicy.resolveMessageDispatchIntent(projection, {
207 type: "steer_active",
208 targetRunId: RunId.make("command-policy-missing-run"),
209 }),
210 { type: "steer_active", targetRunId: RunId.make("command-policy-missing-run") },
211 );
212});
213​
214it.each(["/compact", " /LOGOUT "])("queues a steer sent while %s runs", (text) => {
215 const projection = dispatchProjection(baseCapabilities);
216 const maintenance = {
217 ...projection,
218 messages: [{ id: userMessageId, text, attachments: [] }],
219 } as unknown as OrchestrationV2ThreadProjection;
220 for (const deliveryIntent of ["auto", "steer"] as const) {
221 assert.deepEqual(
222 CommandPolicy.resolveMessageDispatchIntent(
223 maintenance,
224 { type: "start_immediately" },
225 deliveryIntent,
226 ),
227 { type: "queue_after_active" },
228 );
229 }
230 assert.deepEqual(
231 CommandPolicy.resolveMessageDispatchIntent(maintenance, {
232 type: "steer_active",
233 targetRunId: activeRunId,
234 }),
235 { type: "queue_after_active" },
236 );
237 assert.deepEqual(
238 CommandPolicy.resolveMessageDispatchIntent(
239 maintenance,
240 { type: "start_immediately" },
241 "restart",
242 ),
243 { type: "restart_active", targetRunId: activeRunId },
244 );
245});
246​
247const layer = it.layer(CommandPolicy.layer);
248​
249layer("CommandPolicyV2", (it) => {
250 it.effect("steers a live Cursor turn in place", () =>
251 Effect.gen(function* () {
252 const policy = yield* CommandPolicy.CommandPolicyV2;
253 const result = yield* policy.decideSteeringExecution({
254 commandId,
255 threadId,
256 providerInstanceId: ProviderInstanceId.make("cursor"),
257 capabilities: CursorProviderCapabilitiesV2,
258 });
259 assert.equal(result, "active_steering");
260 }),
261 );
262​
263 it.effect("falls back to portable context when Cursor cannot fork natively", () =>
264 Effect.gen(function* () {
265 const policy = yield* CommandPolicy.CommandPolicyV2;
266​
267 const result = yield* policy.decideForkExecution({
268 commandId,
269 threadId,
270 providerInstanceId: ProviderInstanceId.make("cursor"),
271 capabilities: CursorProviderCapabilitiesV2,
272 sameProvider: true,
273 hasStrongNativeSource: true,
274 sourceRunStatus: "completed",
275 fromSpecificTurn: true,
276 sourceBusy: false,
277 });
278​
279 assert.equal(result, "portable_context");
280 }),
281 );
282​
283 it.effect("forks a busy source through portable context", () =>
284 Effect.gen(function* () {
285 const policy = yield* CommandPolicy.CommandPolicyV2;
286 const decide = (sourceBusy: boolean) =>
287 policy.decideForkExecution({
288 commandId,
289 threadId,
290 providerInstanceId: ProviderInstanceId.make("codex"),
291 capabilities: CodexProviderCapabilitiesV2,
292 sameProvider: true,
293 hasStrongNativeSource: true,
294 sourceRunStatus: "completed",
295 fromSpecificTurn: true,
296 sourceBusy,
297 });
298​
299 assert.equal(yield* decide(false), "native_fork");
300 assert.equal(yield* decide(true), "portable_context");
301 }),
302 );
303});