@akagilnc/pi-workflow-roles 0.1.3816 → 0.1.3826
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/acp-host/production-host.js +28 -10
- package/dist/headless-host/production-host.js +28 -10
- package/dist/pi/adapter.js +2 -1
- package/dist/submission-correctable-error.js +12 -0
- package/package.json +1 -1
- package/src/acp-host/role-envelope.ts +34 -9
- package/src/acp-host/role-turn-host.ts +11 -2
- package/src/headless-host/role-turn-host.ts +2 -2
- package/src/pi/adapter.ts +2 -1
- package/src/submission-correctable-error.ts +14 -0
|
@@ -2712,6 +2712,10 @@ var init_submission_errors = __esm({
|
|
|
2712
2712
|
});
|
|
2713
2713
|
|
|
2714
2714
|
// src/submission-correctable-error.ts
|
|
2715
|
+
function mechanicalSubmissionRejectionResumeMessage(code) {
|
|
2716
|
+
if (code === "non-sole-round") return NON_SOLE_ROUND_RESUME_MESSAGE;
|
|
2717
|
+
return code;
|
|
2718
|
+
}
|
|
2715
2719
|
function isCorrectableSubmissionError(error) {
|
|
2716
2720
|
return error instanceof CorrectableSubmissionError;
|
|
2717
2721
|
}
|
|
@@ -2736,11 +2740,12 @@ function projectCorrectableExecuteRejection(error) {
|
|
|
2736
2740
|
}
|
|
2737
2741
|
};
|
|
2738
2742
|
}
|
|
2739
|
-
var correctableSubmissionErrorBrand, CorrectableSubmissionError;
|
|
2743
|
+
var NON_SOLE_ROUND_RESUME_MESSAGE, correctableSubmissionErrorBrand, CorrectableSubmissionError;
|
|
2740
2744
|
var init_submission_correctable_error = __esm({
|
|
2741
2745
|
"src/submission-correctable-error.ts"() {
|
|
2742
2746
|
"use strict";
|
|
2743
2747
|
init_submission_errors();
|
|
2748
|
+
NON_SOLE_ROUND_RESUME_MESSAGE = "\u7EC8\u5C40\u4EA4\u5377\u5E76\u975E\u672C\u8F6E\u552F\u4E00\u5DE5\u5177\u8C03\u7528\u3002";
|
|
2744
2749
|
correctableSubmissionErrorBrand = /* @__PURE__ */ Symbol("ak-roles.correctable-submission-error");
|
|
2745
2750
|
CorrectableSubmissionError = class extends Error {
|
|
2746
2751
|
[correctableSubmissionErrorBrand] = true;
|
|
@@ -24413,7 +24418,7 @@ function createPiRoleHostAdapter(pi, options = {}) {
|
|
|
24413
24418
|
deliverSubmissionRejection(rejection) {
|
|
24414
24419
|
pi.sendMessage({
|
|
24415
24420
|
customType: "ak-role-submission-rejection",
|
|
24416
|
-
content:
|
|
24421
|
+
content: mechanicalSubmissionRejectionResumeMessage(rejection.code),
|
|
24417
24422
|
display: true,
|
|
24418
24423
|
details: rejection
|
|
24419
24424
|
}, { triggerTurn: true, deliverAs: "followUp" });
|
|
@@ -24528,6 +24533,7 @@ var init_adapter = __esm({
|
|
|
24528
24533
|
init_oauth_keepalive();
|
|
24529
24534
|
init_role_runtime();
|
|
24530
24535
|
init_agent_start_materials();
|
|
24536
|
+
init_submission_correctable_error();
|
|
24531
24537
|
piContexts = /* @__PURE__ */ new WeakMap();
|
|
24532
24538
|
}
|
|
24533
24539
|
});
|
|
@@ -26192,7 +26198,7 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
|
|
|
26192
26198
|
if ("failure" in closure) {
|
|
26193
26199
|
return { code: null, stderr: "", timedOut: false, knownFailure: closure.failure };
|
|
26194
26200
|
}
|
|
26195
|
-
prompt =
|
|
26201
|
+
prompt = closure.retry.message;
|
|
26196
26202
|
}
|
|
26197
26203
|
return failure("output", "AcpRoundLimit", "round-retry-limit", { sessionId });
|
|
26198
26204
|
} finally {
|
|
@@ -26390,7 +26396,11 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
26390
26396
|
};
|
|
26391
26397
|
const host = {
|
|
26392
26398
|
deliverSubmissionRejection(value) {
|
|
26393
|
-
rejection =
|
|
26399
|
+
rejection = {
|
|
26400
|
+
code: value.code,
|
|
26401
|
+
toolCallIds: value.toolCallIds,
|
|
26402
|
+
message: mechanicalSubmissionRejectionResumeMessage(value.code)
|
|
26403
|
+
};
|
|
26394
26404
|
},
|
|
26395
26405
|
capabilities: {
|
|
26396
26406
|
skillExpansion(prompt) {
|
|
@@ -26460,18 +26470,22 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
26460
26470
|
createRoleRuntimeExtension(options.dependencies)(envelope);
|
|
26461
26471
|
const token = randomUUID7();
|
|
26462
26472
|
const server = createServer((socket) => serveSocket(socket));
|
|
26463
|
-
function rememberProjectedRejection(details, toolCallId) {
|
|
26473
|
+
function rememberProjectedRejection(details, toolCallId, content) {
|
|
26464
26474
|
if (typeof details !== "object" || details === null) return;
|
|
26465
26475
|
const record4 = details;
|
|
26466
26476
|
if (record4.cause === "infrastructure") return;
|
|
26467
26477
|
if (record4.kind === "role_infrastructure_failure") return;
|
|
26468
26478
|
const code = typeof record4.code === "string" && record4.code.length > 0 ? record4.code : record4.status === "bounce" || record4.status === "escalate" || record4.status === "no_receipt" ? record4.status : void 0;
|
|
26469
26479
|
if (code === void 0) return;
|
|
26470
|
-
rejection = {
|
|
26480
|
+
rejection = {
|
|
26481
|
+
code,
|
|
26482
|
+
toolCallIds: [toolCallId],
|
|
26483
|
+
message: textDiagnostic(content) ?? code
|
|
26484
|
+
};
|
|
26471
26485
|
}
|
|
26472
26486
|
function textDiagnostic(content) {
|
|
26473
|
-
const text = content.map((part) => part.type === "text" ? part.text : "").join("")
|
|
26474
|
-
return text.length > 0 ? text : void 0;
|
|
26487
|
+
const text = content.map((part) => part.type === "text" ? part.text : "").join("");
|
|
26488
|
+
return text.trim().length > 0 ? text : void 0;
|
|
26475
26489
|
}
|
|
26476
26490
|
function rememberInfrastructureFailure(details, content) {
|
|
26477
26491
|
if (infrastructureRoundFailure !== void 0) return;
|
|
@@ -26527,7 +26541,7 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
26527
26541
|
sessionEntries.push(toolResultEntry);
|
|
26528
26542
|
if (projected.isError) {
|
|
26529
26543
|
rememberInfrastructureFailure(projected.details, projected.content);
|
|
26530
|
-
rememberProjectedRejection(projected.details, toolCallId);
|
|
26544
|
+
rememberProjectedRejection(projected.details, toolCallId, projected.content);
|
|
26531
26545
|
}
|
|
26532
26546
|
await emit("tool_execution_end", { toolCallId, toolName, isError: projected.isError });
|
|
26533
26547
|
return projected;
|
|
@@ -26718,7 +26732,11 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
26718
26732
|
return { accepted: true };
|
|
26719
26733
|
}
|
|
26720
26734
|
if (rejection !== void 0) {
|
|
26721
|
-
const retry = {
|
|
26735
|
+
const retry = {
|
|
26736
|
+
code: rejection.code,
|
|
26737
|
+
toolCallIds: rejection.toolCallIds,
|
|
26738
|
+
message: rejection.message
|
|
26739
|
+
};
|
|
26722
26740
|
rejection = void 0;
|
|
26723
26741
|
return { accepted: false, retry };
|
|
26724
26742
|
}
|
|
@@ -2712,6 +2712,10 @@ var init_submission_errors = __esm({
|
|
|
2712
2712
|
});
|
|
2713
2713
|
|
|
2714
2714
|
// src/submission-correctable-error.ts
|
|
2715
|
+
function mechanicalSubmissionRejectionResumeMessage(code) {
|
|
2716
|
+
if (code === "non-sole-round") return NON_SOLE_ROUND_RESUME_MESSAGE;
|
|
2717
|
+
return code;
|
|
2718
|
+
}
|
|
2715
2719
|
function isCorrectableSubmissionError(error) {
|
|
2716
2720
|
return error instanceof CorrectableSubmissionError;
|
|
2717
2721
|
}
|
|
@@ -2736,11 +2740,12 @@ function projectCorrectableExecuteRejection(error) {
|
|
|
2736
2740
|
}
|
|
2737
2741
|
};
|
|
2738
2742
|
}
|
|
2739
|
-
var correctableSubmissionErrorBrand, CorrectableSubmissionError;
|
|
2743
|
+
var NON_SOLE_ROUND_RESUME_MESSAGE, correctableSubmissionErrorBrand, CorrectableSubmissionError;
|
|
2740
2744
|
var init_submission_correctable_error = __esm({
|
|
2741
2745
|
"src/submission-correctable-error.ts"() {
|
|
2742
2746
|
"use strict";
|
|
2743
2747
|
init_submission_errors();
|
|
2748
|
+
NON_SOLE_ROUND_RESUME_MESSAGE = "\u7EC8\u5C40\u4EA4\u5377\u5E76\u975E\u672C\u8F6E\u552F\u4E00\u5DE5\u5177\u8C03\u7528\u3002";
|
|
2744
2749
|
correctableSubmissionErrorBrand = /* @__PURE__ */ Symbol("ak-roles.correctable-submission-error");
|
|
2745
2750
|
CorrectableSubmissionError = class extends Error {
|
|
2746
2751
|
[correctableSubmissionErrorBrand] = true;
|
|
@@ -24413,7 +24418,7 @@ function createPiRoleHostAdapter(pi, options = {}) {
|
|
|
24413
24418
|
deliverSubmissionRejection(rejection) {
|
|
24414
24419
|
pi.sendMessage({
|
|
24415
24420
|
customType: "ak-role-submission-rejection",
|
|
24416
|
-
content:
|
|
24421
|
+
content: mechanicalSubmissionRejectionResumeMessage(rejection.code),
|
|
24417
24422
|
display: true,
|
|
24418
24423
|
details: rejection
|
|
24419
24424
|
}, { triggerTurn: true, deliverAs: "followUp" });
|
|
@@ -24528,6 +24533,7 @@ var init_adapter = __esm({
|
|
|
24528
24533
|
init_oauth_keepalive();
|
|
24529
24534
|
init_role_runtime();
|
|
24530
24535
|
init_agent_start_materials();
|
|
24536
|
+
init_submission_correctable_error();
|
|
24531
24537
|
piContexts = /* @__PURE__ */ new WeakMap();
|
|
24532
24538
|
}
|
|
24533
24539
|
});
|
|
@@ -26086,7 +26092,11 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
26086
26092
|
};
|
|
26087
26093
|
const host = {
|
|
26088
26094
|
deliverSubmissionRejection(value) {
|
|
26089
|
-
rejection =
|
|
26095
|
+
rejection = {
|
|
26096
|
+
code: value.code,
|
|
26097
|
+
toolCallIds: value.toolCallIds,
|
|
26098
|
+
message: mechanicalSubmissionRejectionResumeMessage(value.code)
|
|
26099
|
+
};
|
|
26090
26100
|
},
|
|
26091
26101
|
capabilities: {
|
|
26092
26102
|
skillExpansion(prompt) {
|
|
@@ -26156,18 +26166,22 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
26156
26166
|
createRoleRuntimeExtension(options.dependencies)(envelope);
|
|
26157
26167
|
const token = randomUUID7();
|
|
26158
26168
|
const server = createServer((socket) => serveSocket(socket));
|
|
26159
|
-
function rememberProjectedRejection(details, toolCallId) {
|
|
26169
|
+
function rememberProjectedRejection(details, toolCallId, content) {
|
|
26160
26170
|
if (typeof details !== "object" || details === null) return;
|
|
26161
26171
|
const record4 = details;
|
|
26162
26172
|
if (record4.cause === "infrastructure") return;
|
|
26163
26173
|
if (record4.kind === "role_infrastructure_failure") return;
|
|
26164
26174
|
const code = typeof record4.code === "string" && record4.code.length > 0 ? record4.code : record4.status === "bounce" || record4.status === "escalate" || record4.status === "no_receipt" ? record4.status : void 0;
|
|
26165
26175
|
if (code === void 0) return;
|
|
26166
|
-
rejection = {
|
|
26176
|
+
rejection = {
|
|
26177
|
+
code,
|
|
26178
|
+
toolCallIds: [toolCallId],
|
|
26179
|
+
message: textDiagnostic(content) ?? code
|
|
26180
|
+
};
|
|
26167
26181
|
}
|
|
26168
26182
|
function textDiagnostic(content) {
|
|
26169
|
-
const text = content.map((part) => part.type === "text" ? part.text : "").join("")
|
|
26170
|
-
return text.length > 0 ? text : void 0;
|
|
26183
|
+
const text = content.map((part) => part.type === "text" ? part.text : "").join("");
|
|
26184
|
+
return text.trim().length > 0 ? text : void 0;
|
|
26171
26185
|
}
|
|
26172
26186
|
function rememberInfrastructureFailure(details, content) {
|
|
26173
26187
|
if (infrastructureRoundFailure !== void 0) return;
|
|
@@ -26223,7 +26237,7 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
26223
26237
|
sessionEntries.push(toolResultEntry);
|
|
26224
26238
|
if (projected.isError) {
|
|
26225
26239
|
rememberInfrastructureFailure(projected.details, projected.content);
|
|
26226
|
-
rememberProjectedRejection(projected.details, toolCallId);
|
|
26240
|
+
rememberProjectedRejection(projected.details, toolCallId, projected.content);
|
|
26227
26241
|
}
|
|
26228
26242
|
await emit("tool_execution_end", { toolCallId, toolName, isError: projected.isError });
|
|
26229
26243
|
return projected;
|
|
@@ -26414,7 +26428,11 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
26414
26428
|
return { accepted: true };
|
|
26415
26429
|
}
|
|
26416
26430
|
if (rejection !== void 0) {
|
|
26417
|
-
const retry = {
|
|
26431
|
+
const retry = {
|
|
26432
|
+
code: rejection.code,
|
|
26433
|
+
toolCallIds: rejection.toolCallIds,
|
|
26434
|
+
message: rejection.message
|
|
26435
|
+
};
|
|
26418
26436
|
rejection = void 0;
|
|
26419
26437
|
return { accepted: false, retry };
|
|
26420
26438
|
}
|
|
@@ -26937,7 +26955,7 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
|
|
|
26937
26955
|
outcome = { code: null, stderr: spawned.stderr, timedOut: false, knownFailure: closure.failure };
|
|
26938
26956
|
break;
|
|
26939
26957
|
}
|
|
26940
|
-
prompt =
|
|
26958
|
+
prompt = closure.retry.message;
|
|
26941
26959
|
sessionKind = "resume";
|
|
26942
26960
|
if (attempt === 7) {
|
|
26943
26961
|
outcome = failure("output", "HeadlessRoundLimit", "round-retry-limit", { sessionId });
|
package/dist/pi/adapter.js
CHANGED
|
@@ -3,6 +3,7 @@ import { requireGatekeeperPass } from "../gatekeeper-pass-envelope.js";
|
|
|
3
3
|
import { createOAuthKeepalive } from "../oauth-keepalive.js";
|
|
4
4
|
import { createRoleRuntimeExtension } from "../role-runtime.js";
|
|
5
5
|
import { renderAgentStartMaterials } from "../agent-start-materials.js";
|
|
6
|
+
import { mechanicalSubmissionRejectionResumeMessage } from "../submission-correctable-error.js";
|
|
6
7
|
const piContexts = new WeakMap();
|
|
7
8
|
/** Pi-only entrypoint adapter around the host-neutral shared composition. */
|
|
8
9
|
export function createPiRoleRuntimeExtension(dependencies, options = {}) {
|
|
@@ -87,7 +88,7 @@ export function createPiRoleHostAdapter(pi, options = {}) {
|
|
|
87
88
|
deliverSubmissionRejection(rejection) {
|
|
88
89
|
pi.sendMessage({
|
|
89
90
|
customType: "ak-role-submission-rejection",
|
|
90
|
-
content:
|
|
91
|
+
content: mechanicalSubmissionRejectionResumeMessage(rejection.code),
|
|
91
92
|
display: true,
|
|
92
93
|
details: rejection,
|
|
93
94
|
}, { triggerTurn: true, deliverAs: "followUp" });
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { GatekeeperDecisionError, ParentQueueReaskError, WorkerCommitReminderError, WorkerPrefixReminderError, WorkerUnfinishedReasonReminderError, } from "./submission-errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Mechanical non-sole resume text — one shared authority for Pi followUp and
|
|
4
|
+
* ACP/headless closeRound retry (#813). Officer bounce/escalate use projected
|
|
5
|
+
* receipt text instead; this string is only the round-shape correction.
|
|
6
|
+
*/
|
|
7
|
+
export const NON_SOLE_ROUND_RESUME_MESSAGE = "终局交卷并非本轮唯一工具调用。";
|
|
8
|
+
/** Resume text for mechanical deliverSubmissionRejection codes (no officer receipt). */
|
|
9
|
+
export function mechanicalSubmissionRejectionResumeMessage(code) {
|
|
10
|
+
if (code === "non-sole-round")
|
|
11
|
+
return NON_SOLE_ROUND_RESUME_MESSAGE;
|
|
12
|
+
return code;
|
|
13
|
+
}
|
|
2
14
|
/** Shared, unforgeable identity for submission errors that the same session may correct. */
|
|
3
15
|
const correctableSubmissionErrorBrand = Symbol("ak-roles.correctable-submission-error");
|
|
4
16
|
export class CorrectableSubmissionError extends Error {
|
package/package.json
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
} from "./role-turn-host.ts";
|
|
29
29
|
import {
|
|
30
30
|
isCorrectableExecuteError,
|
|
31
|
+
mechanicalSubmissionRejectionResumeMessage,
|
|
31
32
|
projectCorrectableExecuteRejection,
|
|
32
33
|
} from "../submission-correctable-error.ts";
|
|
33
34
|
import {
|
|
@@ -184,7 +185,9 @@ export async function prepareAcpRoleEnvelope(options: {
|
|
|
184
185
|
const sessionEntries: Array<Record<string, unknown>> = [];
|
|
185
186
|
const methodSkills = new Map<string, { path: string; body: string }>();
|
|
186
187
|
let preferredTools: string[] = [];
|
|
187
|
-
let rejection:
|
|
188
|
+
let rejection:
|
|
189
|
+
| { readonly code: string; readonly toolCallIds: readonly string[]; readonly message: string }
|
|
190
|
+
| undefined;
|
|
188
191
|
/** Typed infrastructure failure for this ACP round; closeRound returns it as knownFailure (#593). */
|
|
189
192
|
let infrastructureRoundFailure: RoleTurnKnownFailure | undefined;
|
|
190
193
|
const hostAbort = new AbortController();
|
|
@@ -263,7 +266,14 @@ export async function prepareAcpRoleEnvelope(options: {
|
|
|
263
266
|
};
|
|
264
267
|
|
|
265
268
|
const host: RoleHost = {
|
|
266
|
-
deliverSubmissionRejection(value) {
|
|
269
|
+
deliverSubmissionRejection(value) {
|
|
270
|
+
// Mechanical round rejection has no officer receipt; shared resume text is the fact (#813).
|
|
271
|
+
rejection = {
|
|
272
|
+
code: value.code,
|
|
273
|
+
toolCallIds: value.toolCallIds,
|
|
274
|
+
message: mechanicalSubmissionRejectionResumeMessage(value.code),
|
|
275
|
+
};
|
|
276
|
+
},
|
|
267
277
|
capabilities: {
|
|
268
278
|
skillExpansion(prompt): HostSkillExpansionEvidence | undefined {
|
|
269
279
|
return buildAcpSkillExpansion(methodSkills, prompt);
|
|
@@ -321,7 +331,11 @@ export async function prepareAcpRoleEnvelope(options: {
|
|
|
321
331
|
const token = randomUUID();
|
|
322
332
|
const server = createServer((socket) => serveSocket(socket));
|
|
323
333
|
/** Correctable non-pass must arm the existing rejection state so closeRound returns retry. */
|
|
324
|
-
function rememberProjectedRejection(
|
|
334
|
+
function rememberProjectedRejection(
|
|
335
|
+
details: unknown,
|
|
336
|
+
toolCallId: string,
|
|
337
|
+
content: ContentPart[],
|
|
338
|
+
): void {
|
|
325
339
|
if (typeof details !== "object" || details === null) return;
|
|
326
340
|
const record = details as Record<string, unknown>;
|
|
327
341
|
if (record.cause === "infrastructure") return;
|
|
@@ -332,14 +346,21 @@ export async function prepareAcpRoleEnvelope(options: {
|
|
|
332
346
|
? record.status
|
|
333
347
|
: undefined;
|
|
334
348
|
if (code === undefined) return;
|
|
335
|
-
|
|
349
|
+
// Officer bounce/escalate text is already the tool_result content (GatekeeperDecisionError
|
|
350
|
+
// message = raw receipt). Adapters resume with this message — never a host-invented line (#813).
|
|
351
|
+
rejection = {
|
|
352
|
+
code,
|
|
353
|
+
toolCallIds: [toolCallId],
|
|
354
|
+
message: textDiagnostic(content) ?? code,
|
|
355
|
+
};
|
|
336
356
|
}
|
|
337
357
|
function textDiagnostic(content: ContentPart[]): string | undefined {
|
|
358
|
+
// Keep concatenated text bytes intact for resume relay (#813 online P2):
|
|
359
|
+
// only emptiness uses the trimmed form; do not alter Markdown/spacing.
|
|
338
360
|
const text = content
|
|
339
361
|
.map((part) => (part.type === "text" ? part.text : ""))
|
|
340
|
-
.join("")
|
|
341
|
-
|
|
342
|
-
return text.length > 0 ? text : undefined;
|
|
362
|
+
.join("");
|
|
363
|
+
return text.trim().length > 0 ? text : undefined;
|
|
343
364
|
}
|
|
344
365
|
/** Arm closeRound + abort path with the durable infrastructure failure for this round. */
|
|
345
366
|
function rememberInfrastructureFailure(
|
|
@@ -430,7 +451,7 @@ export async function prepareAcpRoleEnvelope(options: {
|
|
|
430
451
|
sessionEntries.push(toolResultEntry);
|
|
431
452
|
if (projected.isError) {
|
|
432
453
|
rememberInfrastructureFailure(projected.details, projected.content);
|
|
433
|
-
rememberProjectedRejection(projected.details, toolCallId);
|
|
454
|
+
rememberProjectedRejection(projected.details, toolCallId, projected.content);
|
|
434
455
|
}
|
|
435
456
|
await emit("tool_execution_end", { toolCallId, toolName, isError: projected.isError });
|
|
436
457
|
return projected;
|
|
@@ -646,7 +667,11 @@ export async function prepareAcpRoleEnvelope(options: {
|
|
|
646
667
|
return { accepted: true as const };
|
|
647
668
|
}
|
|
648
669
|
if (rejection !== undefined) {
|
|
649
|
-
const retry = {
|
|
670
|
+
const retry = {
|
|
671
|
+
code: rejection.code,
|
|
672
|
+
toolCallIds: rejection.toolCallIds,
|
|
673
|
+
message: rejection.message,
|
|
674
|
+
};
|
|
650
675
|
rejection = undefined;
|
|
651
676
|
return { accepted: false as const, retry };
|
|
652
677
|
}
|
|
@@ -39,7 +39,15 @@ export type AcpPreparedTurn = Readonly<{
|
|
|
39
39
|
/** Shared ledger consumes the complete ACP round after session/prompt resolves. */
|
|
40
40
|
closeRound(): Promise<
|
|
41
41
|
| { readonly accepted: true }
|
|
42
|
-
| {
|
|
42
|
+
| {
|
|
43
|
+
readonly accepted: false;
|
|
44
|
+
/** Shared envelope provides officer/correctable text; adapters only deliver it (#813). */
|
|
45
|
+
readonly retry: {
|
|
46
|
+
readonly code: string;
|
|
47
|
+
readonly toolCallIds: readonly string[];
|
|
48
|
+
readonly message: string;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
43
51
|
| { readonly accepted: false; readonly failure: RoleTurnKnownFailure }
|
|
44
52
|
>;
|
|
45
53
|
dispose?(): Promise<void>;
|
|
@@ -400,7 +408,8 @@ export function createAcpRoleTurnHost(config: AcpRoleTurnHostConfig): RoleTurnHo
|
|
|
400
408
|
if ("failure" in closure) {
|
|
401
409
|
return { code: null, stderr: "", timedOut: false, knownFailure: closure.failure };
|
|
402
410
|
}
|
|
403
|
-
|
|
411
|
+
// Shared envelope already owns the officer/correctable text (#813).
|
|
412
|
+
prompt = closure.retry.message;
|
|
404
413
|
}
|
|
405
414
|
return failure("output", "AcpRoundLimit", "round-retry-limit", { sessionId });
|
|
406
415
|
} finally {
|
|
@@ -401,8 +401,8 @@ export function createHeadlessRoleTurnHost(config: HeadlessRoleTurnHostConfig):
|
|
|
401
401
|
outcome = { code: null, stderr: spawned.stderr, timedOut: false, knownFailure: closure.failure };
|
|
402
402
|
break;
|
|
403
403
|
}
|
|
404
|
-
//
|
|
405
|
-
prompt =
|
|
404
|
+
// Shared envelope already owns the officer/correctable text (#813).
|
|
405
|
+
prompt = closure.retry.message;
|
|
406
406
|
sessionKind = "resume";
|
|
407
407
|
if (attempt === 7) {
|
|
408
408
|
outcome = failure("output", "HeadlessRoundLimit", "round-retry-limit", { sessionId });
|
package/src/pi/adapter.ts
CHANGED
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
import { createOAuthKeepalive, type OAuthKeepaliveOptions } from "../oauth-keepalive.ts";
|
|
22
22
|
import { createRoleRuntimeExtension, type RoleRuntimeDependencies } from "../role-runtime.ts";
|
|
23
23
|
import { renderAgentStartMaterials } from "../agent-start-materials.ts";
|
|
24
|
+
import { mechanicalSubmissionRejectionResumeMessage } from "../submission-correctable-error.ts";
|
|
24
25
|
|
|
25
26
|
export type PiRoleHostAdapter = RoleEnvelopeHost;
|
|
26
27
|
|
|
@@ -139,7 +140,7 @@ export function createPiRoleHostAdapter(
|
|
|
139
140
|
deliverSubmissionRejection(rejection) {
|
|
140
141
|
pi.sendMessage({
|
|
141
142
|
customType: "ak-role-submission-rejection",
|
|
142
|
-
content:
|
|
143
|
+
content: mechanicalSubmissionRejectionResumeMessage(rejection.code),
|
|
143
144
|
display: true,
|
|
144
145
|
details: rejection,
|
|
145
146
|
}, { triggerTurn: true, deliverAs: "followUp" });
|
|
@@ -6,6 +6,20 @@ import {
|
|
|
6
6
|
WorkerUnfinishedReasonReminderError,
|
|
7
7
|
} from "./submission-errors.ts";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Mechanical non-sole resume text — one shared authority for Pi followUp and
|
|
11
|
+
* ACP/headless closeRound retry (#813). Officer bounce/escalate use projected
|
|
12
|
+
* receipt text instead; this string is only the round-shape correction.
|
|
13
|
+
*/
|
|
14
|
+
export const NON_SOLE_ROUND_RESUME_MESSAGE =
|
|
15
|
+
"终局交卷并非本轮唯一工具调用。";
|
|
16
|
+
|
|
17
|
+
/** Resume text for mechanical deliverSubmissionRejection codes (no officer receipt). */
|
|
18
|
+
export function mechanicalSubmissionRejectionResumeMessage(code: string): string {
|
|
19
|
+
if (code === "non-sole-round") return NON_SOLE_ROUND_RESUME_MESSAGE;
|
|
20
|
+
return code;
|
|
21
|
+
}
|
|
22
|
+
|
|
9
23
|
/** Shared, unforgeable identity for submission errors that the same session may correct. */
|
|
10
24
|
const correctableSubmissionErrorBrand = Symbol("ak-roles.correctable-submission-error");
|
|
11
25
|
|