@xfey/tutti 0.1.93 → 0.1.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/collaboration-state/clarification-records.d.ts +2 -1
- package/dist/collaboration-state/clarification-records.js +18 -0
- package/dist/collaboration-state/index.d.ts +3 -1
- package/dist/collaboration-state/index.js +2 -1
- package/dist/collaboration-state/messages.js +15 -0
- package/dist/collaboration-state/run-recording.js +18 -1
- package/dist/collaboration-state/run-results.js +6 -0
- package/dist/collaboration-state/task-retry.d.ts +16 -0
- package/dist/collaboration-state/task-retry.js +134 -0
- package/dist/control-plane/command-recovery.js +9 -1
- package/dist/control-plane/index.d.ts +3 -2
- package/dist/control-plane/index.js +14 -0
- package/dist/control-plane/run-retry.d.ts +19 -0
- package/dist/control-plane/run-retry.js +103 -0
- package/dist/control-plane/run-start.d.ts +2 -1
- package/dist/control-plane/run-start.js +18 -1
- package/dist/control-plane/task-compile-clarification-context.d.ts +4 -0
- package/dist/control-plane/task-compile-clarification-context.js +9 -22
- package/dist/control-plane/task-compile-continuation.js +2 -0
- package/dist/control-plane/task-compile-start.js +2 -0
- package/dist/control-plane/task-source-context-types.d.ts +11 -0
- package/dist/control-plane/task-source-context-types.js +2 -0
- package/dist/control-plane/task-source-context.d.ts +7 -0
- package/dist/control-plane/task-source-context.js +31 -0
- package/dist/control-plane/types.d.ts +15 -0
- package/dist/control-plane/workflows/openai.d.ts +1 -0
- package/dist/control-plane/workflows/openai.js +87 -15
- package/dist/control-plane/workflows/types.d.ts +6 -14
- package/dist/control-plane/worklist-terminal-feedback.js +3 -0
- package/dist/prompt-templates/index.d.ts +1 -1
- package/dist/prompt-templates/index.js +4 -3
- package/dist/providers/openai/app-server/durable-session-smoke-cli.d.ts +2 -0
- package/dist/providers/openai/app-server/durable-session-smoke-cli.js +229 -0
- package/dist/providers/openai/app-server/read-only-procedure.d.ts +10 -0
- package/dist/providers/openai/app-server/read-only-procedure.js +42 -13
- package/dist/providers/openai/app-server/session-store.d.ts +74 -0
- package/dist/providers/openai/app-server/session-store.js +305 -0
- package/dist/providers/openai/app-server/workspace-write-run.d.ts +17 -4
- package/dist/providers/openai/app-server/workspace-write-run.js +92 -28
- package/dist/providers/openai/codex-app-server.d.ts +1 -0
- package/dist/providers/openai/codex-app-server.js +2 -0
- package/dist/run-pipeline/openai.d.ts +1 -0
- package/dist/run-pipeline/openai.js +15 -43
- package/dist/run-pipeline/task-run-invocation.js +371 -93
- package/dist/server-shell/http/routes/project-api/execution-routes.js +32 -2
- package/dist/server-shell/http/routes/project-api/invalidations.d.ts +2 -1
- package/dist/server-shell/http/routes/project-api/invalidations.js +13 -0
- package/dist/server-shell/http/routes/project-api/openapi-execution-routes.d.ts +21 -0
- package/dist/server-shell/http/routes/project-api/openapi-execution-routes.js +12 -1
- package/dist/server-shell/http/routes/project-api/openapi.d.ts +7 -0
- package/node_modules/@tutti/shared/dist/schemas/api/clarifications.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/index.d.ts +1 -1
- package/node_modules/@tutti/shared/dist/schemas/api/index.js +1 -1
- package/node_modules/@tutti/shared/dist/schemas/api/messages.d.ts +5 -0
- package/node_modules/@tutti/shared/dist/schemas/api/messages.js +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/runtime-events.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/types.d.ts +4 -1
- package/node_modules/@tutti/shared/dist/schemas/api/viewer-reference.d.ts +1 -0
- package/node_modules/@tutti/shared/dist/schemas/api/work-items.d.ts +4 -0
- package/node_modules/@tutti/shared/dist/schemas/api/work-items.js +3 -0
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.d.ts +33 -0
- package/node_modules/@tutti/shared/dist/schemas/api/workspace-commands.js +35 -1
- package/package.json +1 -1
- package/prompts/README.md +3 -1
- package/prompts/artifacts/README.md +1 -1
- package/prompts/artifacts/applicability.md +1 -1
- package/prompts/procedures/README.md +3 -3
- package/prompts/procedures/follow-up-check.md +1 -1
- package/prompts/procedures/reference-file-summary.md +1 -1
- package/prompts/procedures/task-compile.md +7 -7
- package/prompts/prompt-flow-map.md +16 -10
- package/prompts/runs/README.md +11 -16
- package/prompts/runs/task-execute.md +86 -0
- package/prompts/runs/task-finalize.md +11 -0
- package/prompts/runs/task-recovery.md +15 -0
- package/prompts/runs/task-result-contract.md +64 -0
- package/web/assets/{homepage-motion-scene-CLTkixIk.js → homepage-motion-scene-BFo4r4nz.js} +1 -1
- package/web/assets/index-CNIl4TF8.js +69 -0
- package/web/assets/index-quWLFJgD.css +1 -0
- package/web/index.html +2 -2
- package/prompts/runs/task-continuation.md +0 -199
- package/prompts/runs/task-retry.md +0 -207
- package/prompts/runs/task-run.md +0 -186
- package/web/assets/index-BTNYElB-.js +0 -69
- package/web/assets/index-Deu_eF5K.css +0 -1
|
@@ -8,7 +8,7 @@ import { CodexAppServerJsonRpcClient, CodexAppServerProtocolError, } from "./jso
|
|
|
8
8
|
import { CodexAppServerInvocation, CodexAppServerLifecycleError, createManagedProcess, } from "./invocation-lifecycle.js";
|
|
9
9
|
import { CodexAppServerAdmissionError, } from "./invocation-coordinator.js";
|
|
10
10
|
import { createCodexAppServerRuntimeObserver, } from "./runtime-telemetry.js";
|
|
11
|
-
import { createWorkspaceWriteSandboxPolicy } from "./sandbox-policy.js";
|
|
11
|
+
import { createReadOnlySandboxPolicy, createWorkspaceWriteSandboxPolicy, } from "./sandbox-policy.js";
|
|
12
12
|
import { buildCodexAppServerProviderConfigOverrides, resolveCodexAppServerModelProvider, } from "./provider-config.js";
|
|
13
13
|
import { buildCodexAppServerTurnInput, resolveCodexAppServerContextRuntimeHint, resolveCodexAppServerSkillsListWarmup, resolveCodexAppServerSkillInputs, CodexAppServerSkillSelectionError, } from "./skills.js";
|
|
14
14
|
import { compactText, containsKnownSecret, createCodexSpawnEnv, extractAgentText, extractServerRequestMethod, findJsonObjectCandidates, isApiKeyAccount, readThreadId, readTurnError, readTurnStatus, redactWithKnownValues, } from "./runtime-helpers.js";
|
|
@@ -204,12 +204,14 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
204
204
|
}
|
|
205
205
|
const model = options.defaultModel ?? DEFAULT_OPENAI_MODEL;
|
|
206
206
|
const tempRoot = mkdtempSync(join(tmpdir(), "tutti-codex-workspace-write-run-"));
|
|
207
|
-
const codexHome = join(tempRoot, "codex-home");
|
|
207
|
+
const codexHome = options.session?.codexHome ?? join(tempRoot, "codex-home");
|
|
208
208
|
mkdirSync(codexHome, { recursive: true, mode: 0o700 });
|
|
209
209
|
const requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
210
210
|
const turnTimeoutMs = options.turnTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS;
|
|
211
211
|
const networkEnabled = options.networkAccess ?? true;
|
|
212
|
-
const
|
|
212
|
+
const sandboxMode = options.sandboxMode ?? "workspace-write";
|
|
213
|
+
const approvalPolicy = options.approvalPolicy ??
|
|
214
|
+
(sandboxMode === "read-only" ? "never" : DEFAULT_WORKSPACE_WRITE_APPROVAL_POLICY);
|
|
213
215
|
const approvalsReviewer = resolveWorkspaceWriteApprovalsReviewer({
|
|
214
216
|
...(options.approvalsReviewer === undefined ? {} : { explicit: options.approvalsReviewer }),
|
|
215
217
|
env: options.baseEnv ?? process.env,
|
|
@@ -269,6 +271,7 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
269
271
|
let primaryError;
|
|
270
272
|
let runResult;
|
|
271
273
|
let lifecycleError;
|
|
274
|
+
let turnStartState = "not_started";
|
|
272
275
|
try {
|
|
273
276
|
await client.request("initialize", {
|
|
274
277
|
clientInfo: {
|
|
@@ -291,22 +294,43 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
291
294
|
if (skillsListWarmup !== undefined) {
|
|
292
295
|
await client.request("skills/list", skillsListWarmup, requestTimeoutMs);
|
|
293
296
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
297
|
+
let threadId;
|
|
298
|
+
if (options.session?.threadId === undefined) {
|
|
299
|
+
const threadStartResponse = await client.request("thread/start", {
|
|
300
|
+
cwd: options.workspaceRoot,
|
|
301
|
+
model,
|
|
302
|
+
modelProvider,
|
|
303
|
+
approvalPolicy,
|
|
304
|
+
approvalsReviewer,
|
|
305
|
+
sandbox: sandboxMode,
|
|
306
|
+
config: buildWorkspaceWriteThreadConfig(options),
|
|
307
|
+
ephemeral: options.session === undefined,
|
|
308
|
+
experimentalRawEvents: false,
|
|
309
|
+
persistExtendedHistory: false,
|
|
310
|
+
}, requestTimeoutMs);
|
|
311
|
+
threadId = readThreadId(threadStartResponse);
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
if (options.session.unarchive === true) {
|
|
315
|
+
await client.request("thread/unarchive", { threadId: options.session.threadId }, requestTimeoutMs);
|
|
316
|
+
}
|
|
317
|
+
const threadResumeResponse = await client.request("thread/resume", {
|
|
318
|
+
threadId: options.session.threadId,
|
|
319
|
+
cwd: options.workspaceRoot,
|
|
320
|
+
model,
|
|
321
|
+
modelProvider,
|
|
322
|
+
approvalPolicy,
|
|
323
|
+
approvalsReviewer,
|
|
324
|
+
sandbox: sandboxMode,
|
|
325
|
+
config: buildWorkspaceWriteThreadConfig(options),
|
|
326
|
+
}, requestTimeoutMs);
|
|
327
|
+
threadId = readThreadId(threadResumeResponse) ?? options.session.threadId;
|
|
328
|
+
}
|
|
307
329
|
if (threadId === null) {
|
|
308
330
|
throw new CodexAppServerWorkspaceWriteRunError("thread_start_failed", "Codex app-server did not return a thread id.");
|
|
309
331
|
}
|
|
332
|
+
await options.session?.onThreadReady?.(threadId);
|
|
333
|
+
turnStartState = "start_requested";
|
|
310
334
|
await client.request("turn/start", {
|
|
311
335
|
threadId,
|
|
312
336
|
input: buildCodexAppServerTurnInput({
|
|
@@ -319,12 +343,14 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
319
343
|
cwd: options.workspaceRoot,
|
|
320
344
|
approvalPolicy,
|
|
321
345
|
approvalsReviewer,
|
|
322
|
-
sandboxPolicy:
|
|
323
|
-
networkEnabled
|
|
324
|
-
|
|
346
|
+
sandboxPolicy: sandboxMode === "read-only"
|
|
347
|
+
? createReadOnlySandboxPolicy({ networkEnabled })
|
|
348
|
+
: createWorkspaceWriteSandboxPolicy(options.workspaceRoot, {
|
|
349
|
+
networkEnabled,
|
|
350
|
+
}),
|
|
325
351
|
model,
|
|
326
352
|
modelProvider,
|
|
327
|
-
outputSchema: options.outputSchema,
|
|
353
|
+
...(options.outputSchema === undefined ? {} : { outputSchema: options.outputSchema }),
|
|
328
354
|
}, requestTimeoutMs);
|
|
329
355
|
const turnCompletedNotification = await waitForWorkspaceWriteTurnCompletion({
|
|
330
356
|
client,
|
|
@@ -349,6 +375,7 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
349
375
|
sensitiveValues,
|
|
350
376
|
},
|
|
351
377
|
});
|
|
378
|
+
turnStartState = "terminal";
|
|
352
379
|
if (client.serverRequests.length > 0) {
|
|
353
380
|
const unresolved = client.serverRequests.find((request) => client.isServerRequestPending(request.id));
|
|
354
381
|
if (unresolved !== undefined) {
|
|
@@ -385,17 +412,51 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
385
412
|
const agentText = client.notifications
|
|
386
413
|
.map((notification) => extractAgentText(notification))
|
|
387
414
|
.join("");
|
|
388
|
-
|
|
389
|
-
if (
|
|
390
|
-
|
|
415
|
+
let output;
|
|
416
|
+
if (options.outputSchema === undefined && options.validateOutput === undefined) {
|
|
417
|
+
output = agentText;
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
if (options.outputSchema === undefined || options.validateOutput === undefined) {
|
|
421
|
+
throw new CodexAppServerWorkspaceWriteRunError("output_validation_failed", "Codex app-server structured output configuration is incomplete.");
|
|
422
|
+
}
|
|
423
|
+
let parsed;
|
|
424
|
+
try {
|
|
425
|
+
parsed = parseWorkspaceWriteStructuredJson(agentText);
|
|
426
|
+
}
|
|
427
|
+
catch (error) {
|
|
428
|
+
if (error instanceof CodexAppServerWorkspaceWriteRunError) {
|
|
429
|
+
throw new CodexAppServerWorkspaceWriteRunError(error.code, error.message, {
|
|
430
|
+
...error.details,
|
|
431
|
+
agent_output: redactWithKnownValues(agentText, sensitiveValues).slice(0, 16_000),
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
throw error;
|
|
435
|
+
}
|
|
436
|
+
if (!options.validateOutput(parsed)) {
|
|
437
|
+
throw new CodexAppServerWorkspaceWriteRunError("output_validation_failed", "Codex app-server structured output did not match the expected schema.", {
|
|
438
|
+
agent_output: redactWithKnownValues(agentText, sensitiveValues).slice(0, 16_000),
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
output = parsed;
|
|
391
442
|
}
|
|
392
443
|
const rawOutput = `${client.rawStdout}\n${client.stderr}`;
|
|
393
444
|
if (options.strictLeakCheck === true && containsKnownSecret(rawOutput, strictLeakCheckValues)) {
|
|
394
445
|
throw new CodexAppServerWorkspaceWriteRunError("secret_leak_detected", "Codex app-server output contained a sensitive runtime value.");
|
|
395
446
|
}
|
|
396
447
|
const usage = extractCodexAppServerTokenUsage(client.notifications);
|
|
448
|
+
if (options.session?.archiveAfterTurn?.(output) === true) {
|
|
449
|
+
try {
|
|
450
|
+
await client.request("thread/archive", { threadId }, requestTimeoutMs);
|
|
451
|
+
await options.session.onThreadArchived?.();
|
|
452
|
+
}
|
|
453
|
+
catch {
|
|
454
|
+
await options.session.onThreadArchiveFailure?.();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
397
457
|
runResult = {
|
|
398
|
-
output
|
|
458
|
+
output,
|
|
459
|
+
thread_id: threadId,
|
|
399
460
|
model,
|
|
400
461
|
turn_status: "completed",
|
|
401
462
|
notification_count: client.notifications.length,
|
|
@@ -409,14 +470,17 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
409
470
|
}
|
|
410
471
|
catch (error) {
|
|
411
472
|
if (error instanceof CodexAppServerWorkspaceWriteRunError) {
|
|
412
|
-
primaryError = error
|
|
473
|
+
primaryError = new CodexAppServerWorkspaceWriteRunError(error.code, error.message, {
|
|
474
|
+
...error.details,
|
|
475
|
+
turn_start_state: turnStartState,
|
|
476
|
+
});
|
|
413
477
|
}
|
|
414
478
|
else if (error instanceof CodexAppServerProtocolError) {
|
|
415
|
-
primaryError = new CodexAppServerWorkspaceWriteRunError("app_server_protocol_error", redactWithKnownValues(error.message, sensitiveValues));
|
|
479
|
+
primaryError = new CodexAppServerWorkspaceWriteRunError("app_server_protocol_error", redactWithKnownValues(error.message, sensitiveValues), { turn_start_state: turnStartState });
|
|
416
480
|
}
|
|
417
481
|
else {
|
|
418
482
|
const message = error instanceof Error ? error.message : String(error);
|
|
419
|
-
primaryError = new CodexAppServerWorkspaceWriteRunError("app_server_protocol_error", redactWithKnownValues(message, sensitiveValues));
|
|
483
|
+
primaryError = new CodexAppServerWorkspaceWriteRunError("app_server_protocol_error", redactWithKnownValues(message, sensitiveValues), { turn_start_state: turnStartState });
|
|
420
484
|
}
|
|
421
485
|
}
|
|
422
486
|
finally {
|
|
@@ -435,7 +499,7 @@ export async function runCodexAppServerWorkspaceWriteRun(options) {
|
|
|
435
499
|
if (lifecycleError !== undefined) {
|
|
436
500
|
throw new CodexAppServerWorkspaceWriteRunError("process_lifecycle_failed", lifecycleError instanceof CodexAppServerLifecycleError
|
|
437
501
|
? lifecycleError.message
|
|
438
|
-
: "Codex app-server process lifecycle did not close cleanly.");
|
|
502
|
+
: "Codex app-server process lifecycle did not close cleanly.", { turn_start_state: turnStartState });
|
|
439
503
|
}
|
|
440
504
|
return runResult;
|
|
441
505
|
}
|
|
@@ -2,6 +2,8 @@ import { createRequire } from "node:module";
|
|
|
2
2
|
import { dirname, isAbsolute, join } from "node:path";
|
|
3
3
|
import { DEFAULT_OPENAI_MODEL } from "./model-config.js";
|
|
4
4
|
const require = createRequire(import.meta.url);
|
|
5
|
+
const codexPackage = require("@openai/codex/package.json");
|
|
6
|
+
export const CODEX_APP_SERVER_VERSION = codexPackage.version;
|
|
5
7
|
export const CODEX_APP_SERVER_ENTRYPOINT = join(dirname(require.resolve("@openai/codex/package.json")), "bin", "codex.js");
|
|
6
8
|
export const CODEX_APP_SERVER_COMMAND = process.execPath;
|
|
7
9
|
export const CODEX_APP_SERVER_LISTEN_URL = "stdio://";
|
|
@@ -17,17 +17,18 @@ function summarizeProviderError(error) {
|
|
|
17
17
|
error.message.includes("invalid_json_schema") ||
|
|
18
18
|
error.message.includes("Invalid schema") ||
|
|
19
19
|
error.message.includes("response_format");
|
|
20
|
+
const turnStateUnknown = error.details.turn_start_state === "start_requested";
|
|
20
21
|
const errorCode = looksLikeSchemaError
|
|
21
22
|
? "codex_app_server_output_schema_invalid"
|
|
22
|
-
:
|
|
23
|
+
: turnStateUnknown
|
|
24
|
+
? "codex_app_server_turn_state_unknown"
|
|
25
|
+
: `codex_app_server_${error.code}`;
|
|
23
26
|
return failedBeforeChecks({
|
|
24
27
|
summary: `Provider execution failed before checks. (${errorCode})`,
|
|
25
28
|
errorCode,
|
|
26
29
|
retryable: !looksLikeSchemaError &&
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
error.code === "turn_failed" ||
|
|
30
|
-
error.code === "thread_start_failed"),
|
|
30
|
+
error.details.turn_start_state === "not_started" &&
|
|
31
|
+
(error.code === "app_server_protocol_error" || error.code === "thread_start_failed"),
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
function summarizeWorkspaceOpsError(error, changedPaths) {
|
|
@@ -153,12 +154,12 @@ function loggedSyncStage(options, input, stage, run, completedFields = () => ({}
|
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
const MAX_SELF_CORRECTION_RETRIES = 1;
|
|
156
|
-
const MAX_PROVIDER_TRANSIENT_RETRIES = 1;
|
|
157
157
|
function runPipelineResultPromotion(result) {
|
|
158
158
|
return "promotion" in result ? result.promotion : undefined;
|
|
159
159
|
}
|
|
160
160
|
function buildCorrectionContext(input) {
|
|
161
161
|
const correction = {
|
|
162
|
+
previous_provider_result: input.previousProviderResult,
|
|
162
163
|
summary: input.result.summary,
|
|
163
164
|
reason_code: input.reasonCode,
|
|
164
165
|
guidance: input.guidance,
|
|
@@ -189,23 +190,12 @@ function selfCorrectionInput(input, nextAttempt, correctionContext) {
|
|
|
189
190
|
return {
|
|
190
191
|
...input,
|
|
191
192
|
run_lineage: {
|
|
192
|
-
|
|
193
|
+
...input.run_lineage,
|
|
193
194
|
attempt: nextAttempt,
|
|
194
|
-
parent_activity_ref: input.activity_ref,
|
|
195
|
-
root_activity_ref: input.run_lineage.root_activity_ref ?? input.activity_ref,
|
|
196
195
|
},
|
|
197
196
|
correction_context: correctionContext,
|
|
198
197
|
};
|
|
199
198
|
}
|
|
200
|
-
function providerTransientRetryInput(input) {
|
|
201
|
-
return {
|
|
202
|
-
...input,
|
|
203
|
-
run_lineage: {
|
|
204
|
-
...input.run_lineage,
|
|
205
|
-
attempt: input.run_lineage.attempt + 1,
|
|
206
|
-
},
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
199
|
function appendSelfCorrectionExhaustedSummary(input) {
|
|
210
200
|
if (input.attemptedRetries <= 0) {
|
|
211
201
|
return input.result;
|
|
@@ -218,12 +208,6 @@ function appendSelfCorrectionExhaustedSummary(input) {
|
|
|
218
208
|
function isSelfCorrectionRequest(result) {
|
|
219
209
|
return "request_kind" in result && result.request_kind === "self_correction";
|
|
220
210
|
}
|
|
221
|
-
function isProviderTransientRunFailure(result) {
|
|
222
|
-
return (!isSelfCorrectionRequest(result) &&
|
|
223
|
-
result.result_kind === "failed" &&
|
|
224
|
-
result.retryable &&
|
|
225
|
-
result.error_code.startsWith("codex_app_server_"));
|
|
226
|
-
}
|
|
227
211
|
async function runTaskAttempt(options, input) {
|
|
228
212
|
let changedPaths;
|
|
229
213
|
try {
|
|
@@ -289,8 +273,9 @@ async function runTaskAttempt(options, input) {
|
|
|
289
273
|
});
|
|
290
274
|
return requestSelfCorrection({
|
|
291
275
|
result,
|
|
276
|
+
previousProviderResult: taskOutput,
|
|
292
277
|
reasonCode: "no_candidate_changes",
|
|
293
|
-
guidance: "Produce a concrete candidate diff for the
|
|
278
|
+
guidance: "Produce a concrete candidate diff for the current task goal and scope.",
|
|
294
279
|
});
|
|
295
280
|
}
|
|
296
281
|
const artifactGate = await loggedAsyncStage(options, input, "artifact_candidate_validate", () => runArtifactCandidateGate({
|
|
@@ -336,6 +321,7 @@ async function runTaskAttempt(options, input) {
|
|
|
336
321
|
}
|
|
337
322
|
return requestSelfCorrection({
|
|
338
323
|
result: artifactResult,
|
|
324
|
+
previousProviderResult: taskOutput,
|
|
339
325
|
reasonCode: artifactGate.failure.reason_code,
|
|
340
326
|
guidance: artifactGate.failure.guidance,
|
|
341
327
|
diagnostic: artifactGate.failure.diagnostic,
|
|
@@ -361,6 +347,7 @@ async function runTaskAttempt(options, input) {
|
|
|
361
347
|
});
|
|
362
348
|
return requestSelfCorrection({
|
|
363
349
|
result,
|
|
350
|
+
previousProviderResult: taskOutput,
|
|
364
351
|
reasonCode: "checks_failed",
|
|
365
352
|
guidance: "Use the failed checks summary to fix the candidate so the task can pass Tutti checks.",
|
|
366
353
|
});
|
|
@@ -378,8 +365,9 @@ async function runTaskAttempt(options, input) {
|
|
|
378
365
|
});
|
|
379
366
|
return requestSelfCorrection({
|
|
380
367
|
result,
|
|
368
|
+
previousProviderResult: taskOutput,
|
|
381
369
|
reasonCode: "no_candidate_changes",
|
|
382
|
-
guidance: "Produce a concrete final candidate diff for the
|
|
370
|
+
guidance: "Produce a concrete final candidate diff for the current task goal and scope.",
|
|
383
371
|
});
|
|
384
372
|
}
|
|
385
373
|
const checkpoint = loggedSyncStage(options, input, "accepted_checkpoint", () => createAcceptedCheckpoint({
|
|
@@ -444,25 +432,8 @@ export function createOpenAiRunPipelineRunner(options) {
|
|
|
444
432
|
async runTask(input) {
|
|
445
433
|
let currentInput = input;
|
|
446
434
|
let selfCorrectionRetries = 0;
|
|
447
|
-
let providerTransientRetries = 0;
|
|
448
435
|
for (;;) {
|
|
449
436
|
const result = await runTaskAttempt(options, currentInput);
|
|
450
|
-
if (isProviderTransientRunFailure(result) &&
|
|
451
|
-
providerTransientRetries < MAX_PROVIDER_TRANSIENT_RETRIES) {
|
|
452
|
-
providerTransientRetries += 1;
|
|
453
|
-
input.on_stage?.({
|
|
454
|
-
stage: "provider_retry",
|
|
455
|
-
summary: "retrying Codex task after a transient provider failure.",
|
|
456
|
-
});
|
|
457
|
-
logRunPipelineStage(options, currentInput, {
|
|
458
|
-
stage: "provider_retry",
|
|
459
|
-
next_attempt: currentInput.run_lineage.attempt + 1,
|
|
460
|
-
error_code: result.error_code,
|
|
461
|
-
}, "Run pipeline scheduling provider transient retry");
|
|
462
|
-
currentInput = providerTransientRetryInput(currentInput);
|
|
463
|
-
continue;
|
|
464
|
-
}
|
|
465
|
-
providerTransientRetries = 0;
|
|
466
437
|
if (!isSelfCorrectionRequest(result)) {
|
|
467
438
|
return result;
|
|
468
439
|
}
|
|
@@ -512,6 +483,7 @@ export function resolveProjectOpenAiRunPipelineRunner(options) {
|
|
|
512
483
|
apiKey: credential.secret,
|
|
513
484
|
workspaceRoot: options.workspaceRoot,
|
|
514
485
|
tuttiHome: options.tuttiHome,
|
|
486
|
+
projectId: options.projectId,
|
|
515
487
|
userSkillsRoot: getProjectUserSkillsRoot(options.tuttiHome, options.projectId),
|
|
516
488
|
...(options.agentContext === undefined ? {} : { agentContext: options.agentContext }),
|
|
517
489
|
...(options.approvalManager === undefined
|