@akagilnc/pi-workflow-roles 0.1.3236 → 0.1.3249
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/grok/production-host.js +229 -48
- package/dist/package-contracts/collector-output.js +1 -1
- package/dist/package-contracts/terminating-infrastructure.js +12 -1
- package/dist/public-cli/main.js +25 -5
- package/package.json +1 -1
- package/souls/collector.md +1 -1
- package/src/collector-identity.ts +128 -81
- package/src/collector-ledger.ts +101 -19
- package/src/collector-receipt.ts +42 -7
- package/src/collector-role.ts +89 -9
- package/src/collector-tool-schemas.ts +25 -2
- package/src/host-contracts.ts +7 -1
- package/src/package-contracts/collector-output.ts +10 -2
- package/src/package-contracts/terminating-infrastructure.ts +12 -0
- package/src/public-cli/settlement.ts +16 -0
- package/src/role-runtime.ts +2 -0
- package/src/submission-ledger.ts +16 -10
package/src/collector-role.ts
CHANGED
|
@@ -18,9 +18,11 @@ import type { CollectorGitHubTransport } from "./collector-github.ts";
|
|
|
18
18
|
import {
|
|
19
19
|
COLLECTOR_OBSERVE_TOOL,
|
|
20
20
|
COLLECTOR_OUTPUT_TOOL,
|
|
21
|
+
COLLECTOR_READ_TOOL,
|
|
21
22
|
COLLECTOR_REQUEST_TOOL,
|
|
22
23
|
COLLECTOR_WAIT_TOOL,
|
|
23
24
|
createCollectorLedger,
|
|
25
|
+
projectEvidenceEntryView,
|
|
24
26
|
type CollectorLedger,
|
|
25
27
|
} from "./collector-ledger.ts";
|
|
26
28
|
import {
|
|
@@ -30,32 +32,55 @@ import {
|
|
|
30
32
|
import {
|
|
31
33
|
collectorObserveArgsSchema,
|
|
32
34
|
collectorOutputArgsSchema,
|
|
35
|
+
collectorReadArgsSchema,
|
|
33
36
|
collectorRequestArgsSchema,
|
|
34
37
|
collectorWaitArgsSchema,
|
|
35
38
|
} from "./collector-tool-schemas.ts";
|
|
36
39
|
import { COLLECTOR_ACCEPTED_TEXT } from "./package-contracts/collector-output.ts";
|
|
40
|
+
import { CorrectableSubmissionError, isCorrectableExecuteError } from "./submission-correctable-error.ts";
|
|
41
|
+
import { CollectorUnknownEvidenceError } from "./collector-identity.ts";
|
|
42
|
+
|
|
43
|
+
export { CollectorUnknownEvidenceError } from "./collector-identity.ts";
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* #641 chain②: normal completion must never declare `infrastructureFailure`.
|
|
47
|
+
* When the runtime can machine-verify a lawful receipt assembly, a declaration
|
|
48
|
+
* is model misuse — bounce it as correctable guidance instead of host failure.
|
|
49
|
+
*/
|
|
50
|
+
export class CollectorNormalCompletionDeclarationError extends CorrectableSubmissionError {
|
|
51
|
+
constructor() {
|
|
52
|
+
super("runtime 已按机器状态核验本局为正常完工(回执可合法组装):正常完工的交件不得填 infrastructureFailure,请省略该字段后重新提交。");
|
|
53
|
+
this.name = "CollectorNormalCompletionDeclarationError";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
37
56
|
|
|
38
|
-
export {
|
|
57
|
+
export {
|
|
58
|
+
COLLECTOR_FIXED_KICKOFF,
|
|
59
|
+
} from "./collector-config.ts";
|
|
39
60
|
export {
|
|
40
61
|
COLLECTOR_OBSERVE_TOOL,
|
|
41
62
|
COLLECTOR_OUTPUT_TOOL,
|
|
63
|
+
COLLECTOR_READ_TOOL,
|
|
42
64
|
COLLECTOR_REQUEST_TOOL,
|
|
43
65
|
COLLECTOR_WAIT_TOOL,
|
|
44
66
|
};
|
|
45
67
|
|
|
46
68
|
export const COLLECTOR_REQUIRED_TOOLS = [
|
|
47
69
|
COLLECTOR_OBSERVE_TOOL,
|
|
70
|
+
COLLECTOR_READ_TOOL,
|
|
48
71
|
COLLECTOR_REQUEST_TOOL,
|
|
49
72
|
COLLECTOR_WAIT_TOOL,
|
|
50
73
|
COLLECTOR_OUTPUT_TOOL,
|
|
51
74
|
] as const;
|
|
52
75
|
|
|
53
76
|
const observeSchema = collectorObserveArgsSchema;
|
|
77
|
+
const readSchema = collectorReadArgsSchema;
|
|
54
78
|
const requestSchema = collectorRequestArgsSchema;
|
|
55
79
|
const waitSchema = collectorWaitArgsSchema;
|
|
56
80
|
const outputSchema = collectorOutputArgsSchema;
|
|
57
81
|
|
|
58
82
|
type RequestParams = Static<typeof requestSchema>;
|
|
83
|
+
type ReadParams = Static<typeof readSchema>;
|
|
59
84
|
type WaitParams = Static<typeof waitSchema>;
|
|
60
85
|
type OutputParams = Static<typeof outputSchema>;
|
|
61
86
|
|
|
@@ -260,7 +285,7 @@ export function createCollectorRoleRuntime(
|
|
|
260
285
|
pi.registerTool({
|
|
261
286
|
name: COLLECTOR_OBSERVE_TOOL,
|
|
262
287
|
label: "通进司观察",
|
|
263
|
-
description: "抓取配置目标的完整 GitHub PR
|
|
288
|
+
description: "抓取配置目标的完整 GitHub PR 证据,存不可变快照入卷。正文在上下文中只给头部摘录加指针;需要头部之外的正文时,用 ak_collector_read 按 evidenceId 开卷;findings 的拆分与归类由你在交件时完成。",
|
|
264
289
|
promptSnippet: "抓取配置目标 PR 证据",
|
|
265
290
|
parameters: observeSchema,
|
|
266
291
|
async execute(toolCallId: string, _params: unknown, signal: AbortSignal | undefined, _onUpdate: unknown, ctx: HostContext) {
|
|
@@ -269,7 +294,7 @@ export function createCollectorRoleRuntime(
|
|
|
269
294
|
}
|
|
270
295
|
try {
|
|
271
296
|
activation.ledger.beginOperational(COLLECTOR_OBSERVE_TOOL, toolCallId);
|
|
272
|
-
const { snapshot,
|
|
297
|
+
const { snapshot, contextView } = await activation.ledger.observe(
|
|
273
298
|
activation.transport,
|
|
274
299
|
activation.clock,
|
|
275
300
|
signal,
|
|
@@ -282,12 +307,55 @@ export function createCollectorRoleRuntime(
|
|
|
282
307
|
return {
|
|
283
308
|
content: [{
|
|
284
309
|
type: "text" as const,
|
|
285
|
-
|
|
310
|
+
// #641 chain①: model context carries bounded body heads + pointers only.
|
|
311
|
+
text: JSON.stringify(contextView),
|
|
312
|
+
}],
|
|
313
|
+
// #641 the bounded projection is the only provider-visible face on every host
|
|
314
|
+
// (Grok/ACP relays tool details as MCP structuredContent); full bodies stay
|
|
315
|
+
// in the ledger volume and enter context only by explicit ak_collector_read.
|
|
316
|
+
details: contextView,
|
|
317
|
+
};
|
|
318
|
+
} catch (error) {
|
|
319
|
+
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
pi.registerTool({
|
|
325
|
+
name: COLLECTOR_READ_TOOL,
|
|
326
|
+
label: "通进司开卷",
|
|
327
|
+
description: "按 evidenceId 开卷读取一条已观测材料的全量正文与指针;只在观察头部摘录不足以判读时调用。",
|
|
328
|
+
promptSnippet: "按指针开卷读材料",
|
|
329
|
+
parameters: readSchema,
|
|
330
|
+
async execute(toolCallId: string, params: ReadParams, _signal: AbortSignal | undefined, _onUpdate: unknown, ctx: HostContext) {
|
|
331
|
+
if (activation === undefined) {
|
|
332
|
+
throw new Error("通进司未激活");
|
|
333
|
+
}
|
|
334
|
+
try {
|
|
335
|
+
activation.ledger.beginOperational(COLLECTOR_READ_TOOL, toolCallId);
|
|
336
|
+
const record = activation.ledger.getEvidence(params.evidenceId);
|
|
337
|
+
if (
|
|
338
|
+
record === undefined ||
|
|
339
|
+
(record.kind !== "review" && record.kind !== "issue_comment" && record.kind !== "review_comment" && record.kind !== "reaction") ||
|
|
340
|
+
typeof record.body !== "string"
|
|
341
|
+
) {
|
|
342
|
+
throw new CollectorUnknownEvidenceError(params.evidenceId);
|
|
343
|
+
}
|
|
344
|
+
const material = projectEvidenceEntryView(record);
|
|
345
|
+
activation.ledger.completeOperational(toolCallId);
|
|
346
|
+
return {
|
|
347
|
+
content: [{
|
|
348
|
+
type: "text" as const,
|
|
349
|
+
// #641 chain①: full bodies enter provider context only by explicit pointer.
|
|
350
|
+
text: JSON.stringify(material),
|
|
286
351
|
}],
|
|
287
|
-
details:
|
|
352
|
+
details: material,
|
|
288
353
|
};
|
|
289
354
|
} catch (error) {
|
|
290
|
-
|
|
355
|
+
if (isCorrectableExecuteError(error)) throw error;
|
|
356
|
+
// typed toolCallId books the shared infrastructure fact so settlement can
|
|
357
|
+
// tell a read tool's real host failure from a correctable pointer bounce.
|
|
358
|
+
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
291
359
|
}
|
|
292
360
|
},
|
|
293
361
|
});
|
|
@@ -319,7 +387,7 @@ export function createCollectorRoleRuntime(
|
|
|
319
387
|
details,
|
|
320
388
|
};
|
|
321
389
|
} catch (error) {
|
|
322
|
-
hostActions.failInfrastructure(error, ctx);
|
|
390
|
+
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
323
391
|
}
|
|
324
392
|
},
|
|
325
393
|
});
|
|
@@ -350,7 +418,7 @@ export function createCollectorRoleRuntime(
|
|
|
350
418
|
details,
|
|
351
419
|
};
|
|
352
420
|
} catch (error) {
|
|
353
|
-
hostActions.failInfrastructure(error, ctx);
|
|
421
|
+
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
354
422
|
}
|
|
355
423
|
},
|
|
356
424
|
});
|
|
@@ -358,8 +426,20 @@ export function createCollectorRoleRuntime(
|
|
|
358
426
|
pi.registerTool({
|
|
359
427
|
name: COLLECTOR_OUTPUT_TOOL,
|
|
360
428
|
label: "通进司输出",
|
|
361
|
-
description: "观察完成后提交;回执由 runtime
|
|
429
|
+
description: "观察完成后提交;回执由 runtime 组装。正常完工提交空对象 {}(如需报 finding,填 findings 指针数组);仅在基础设施真实失败时才可填 infrastructureFailure,无失败时必须省略该字段。",
|
|
362
430
|
promptSnippet: "提交通进司回执",
|
|
431
|
+
// #641 chain②: the seat owns the normal-completion decision. The probe
|
|
432
|
+
// runs the exact receipt assembly (validation only, no accept side
|
|
433
|
+
// effects); success ⇒ machine-verified normal completion ⇒ bounce.
|
|
434
|
+
bounceInfrastructureDeclaration(params) {
|
|
435
|
+
if (activation === undefined) return undefined;
|
|
436
|
+
try {
|
|
437
|
+
buildCollectorReceipt(activation.ledger, params, activation.clock);
|
|
438
|
+
} catch {
|
|
439
|
+
return undefined;
|
|
440
|
+
}
|
|
441
|
+
return new CollectorNormalCompletionDeclarationError();
|
|
442
|
+
},
|
|
363
443
|
parameters: outputSchema,
|
|
364
444
|
async execute(toolCallId: string, params: OutputParams, _signal: AbortSignal | undefined, _onUpdate: unknown, ctx: HostContext) {
|
|
365
445
|
if (activation === undefined) {
|
|
@@ -7,16 +7,39 @@ export const collectorRequestArgsSchema = Type.Object({
|
|
|
7
7
|
requestId: Type.String({ minLength: 1, description: "配置请求身份" }),
|
|
8
8
|
snapshotId: Type.String({ minLength: 1, description: "最新留存观察快照" }),
|
|
9
9
|
}, { additionalProperties: false });
|
|
10
|
+
export const collectorReadArgsSchema = Type.Object({
|
|
11
|
+
evidenceId: Type.String({ minLength: 1, description: "observe 返回的材料证据 id(evidenceId)" }),
|
|
12
|
+
}, { additionalProperties: false });
|
|
10
13
|
export const collectorWaitArgsSchema = Type.Object({
|
|
11
14
|
durationMs: Type.Integer({ minimum: 1, maximum: COLLECTOR_ELIGIBILITY_MS, description: "等待毫秒;单次上限五分钟且不超剩余资格" }),
|
|
12
15
|
}, { additionalProperties: false });
|
|
13
|
-
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* #641 chain①: the collector LLM does the splitting/classification (#245:
|
|
19
|
+
* 他自己就是llm为什么不能读不能拆). Findings are submitted as pointer refs into
|
|
20
|
+
* the stored evidence; the runtime enriches each with the machine pointer
|
|
21
|
+
* (repo/PR/comment id/url/author/kind/时间) and validates resolvability.
|
|
22
|
+
* Category is a short LLM classification label, never a body transcription.
|
|
23
|
+
*/
|
|
24
|
+
export const collectorFindingArgsSchema = Type.Object({
|
|
25
|
+
evidenceId: Type.String({ minLength: 1, description: "observe 返回的材料证据 id(evidenceId)" }),
|
|
26
|
+
category: Type.Optional(Type.String({ minLength: 1, maxLength: 200, description: "该 finding 的简短归类标签;需要头部之外的正文时先用 ak_collector_read 开卷再判读,不得誊写评论正文" })),
|
|
27
|
+
}, { additionalProperties: false });
|
|
28
|
+
|
|
29
|
+
export const collectorOutputBaseSchema = Type.Object({
|
|
30
|
+
findings: Type.Optional(Type.Array(collectorFindingArgsSchema, {
|
|
31
|
+
description: "本次收集到的逐条 findings;零 finding 的模板通知不得进入。正常完工无 finding 时省略。",
|
|
32
|
+
})),
|
|
33
|
+
}, { additionalProperties: true, description: "正常完工提交空对象 {};仅在基础设施真实失败时才填写 infrastructureFailure,无失败时必须省略该字段。" });
|
|
34
|
+
|
|
35
|
+
/** Runtime owns the observed evidence; the model submits findings and signals sole-final submission. */
|
|
14
36
|
export const collectorOutputArgsSchema = withInfrastructureFailureDeclaration(
|
|
15
|
-
|
|
37
|
+
collectorOutputBaseSchema,
|
|
16
38
|
);
|
|
17
39
|
(collectorOutputArgsSchema as unknown as { required: string[] }).required = [];
|
|
18
40
|
|
|
19
41
|
export type CollectorObserveArgs = Static<typeof collectorObserveArgsSchema>;
|
|
20
42
|
export type CollectorRequestArgs = Static<typeof collectorRequestArgsSchema>;
|
|
43
|
+
export type CollectorReadArgs = Static<typeof collectorReadArgsSchema>;
|
|
21
44
|
export type CollectorWaitArgs = Static<typeof collectorWaitArgsSchema>;
|
|
22
45
|
export type CollectorOutputArgs = Static<typeof collectorOutputArgsSchema>;
|
package/src/host-contracts.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Type, type Static, type TLiteral, type TSchema } from "typebox";
|
|
2
|
+
import type { CorrectableSubmissionError } from "./submission-correctable-error.ts";
|
|
2
3
|
|
|
3
4
|
type HostContentPart = { type: "text"; text: string } | { type: "toolCall"; id: string; name: string; arguments?: unknown } | { type: string };
|
|
4
5
|
type HostMessage = { role: string; content?: unknown; toolName?: string; isError?: boolean; stopReason?: string };
|
|
@@ -209,7 +210,12 @@ type HostSessionManager = { getLeafEntry(): HostSessionEntry | undefined; getLea
|
|
|
209
210
|
/** Context supplied by a host for one activation and its interceptable events. */
|
|
210
211
|
export type HostContext = { cwd: string; mode: string; model: { readonly provider: string } | undefined; sessionManager: HostSessionManager; signal?: AbortSignal | undefined; ui?: { notify?(message: string, type?: "info" | "warning" | "error"): void }; transcript?(): string; abort(): void; };
|
|
211
212
|
|
|
212
|
-
export type HostToolDefinition<S extends TSchema = TSchema, D = unknown, C = HostContext> = { name: string; label: string; description: string; promptSnippet?: string; parameters: S; execute( toolCallId: string, params: Static<S>, signal: AbortSignal | undefined, update: ((result: HostToolResult<D>) => void) | undefined, context: C, ): Promise<HostToolResult<D>>;
|
|
213
|
+
export type HostToolDefinition<S extends TSchema = TSchema, D = unknown, C = HostContext> = { name: string; label: string; description: string; promptSnippet?: string; parameters: S; execute( toolCallId: string, params: Static<S>, signal: AbortSignal | undefined, update: ((result: HostToolResult<D>) => void) | undefined, context: C, ): Promise<HostToolResult<D>>; /**
|
|
214
|
+
* #641 chain② opt-in: when the output params carry the shared infrastructure
|
|
215
|
+
* declaration but the seat can machine-verify a lawful normal completion, the
|
|
216
|
+
* registration may bounce the submission as a correctable error instead of
|
|
217
|
+
* failing the host. Return the correctable error to bounce, or undefined to
|
|
218
|
+
* keep the shared host-failure path. */ bounceInfrastructureDeclaration?(params: unknown, toolCallId: string, context: C): CorrectableSubmissionError | undefined; };
|
|
213
219
|
|
|
214
220
|
type BeforeAgentStartEvent = { prompt: string; systemPrompt: string; systemPromptOptions: { skills?: readonly unknown[]; contextFiles?: readonly unknown[]; appendSystemPrompt?: string } };
|
|
215
221
|
type InputEvent = { text: string; images?: Array<{ type: "image"; data: string; mimeType: string }>; source?: string };
|
|
@@ -42,13 +42,21 @@ export type CollectorSnapshot = {
|
|
|
42
42
|
normalizedByteLength: number;
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* #641 chain① receipt evidence record: pointer/integrity facts only. Bodies and
|
|
47
|
+
* raw payloads stay in the volume (observe details + GitHub pointer) and are
|
|
48
|
+
* never transcribed into the receipt.
|
|
49
|
+
*/
|
|
45
50
|
export type CollectorEvidenceRecord = {
|
|
46
51
|
evidenceId: string;
|
|
47
52
|
kind: string;
|
|
48
53
|
versionId: string;
|
|
49
54
|
contentDigest: string;
|
|
50
55
|
firstObservedAt: string;
|
|
51
|
-
|
|
56
|
+
githubId?: number;
|
|
57
|
+
authorLogin?: string;
|
|
58
|
+
htmlUrl?: string;
|
|
59
|
+
authoritativeTime?: string | null;
|
|
52
60
|
};
|
|
53
61
|
|
|
54
62
|
export type CollectorReceipt = {
|
|
@@ -104,6 +112,6 @@ export function validateAcceptedCollectorReceipt(value: unknown): CollectorRecei
|
|
|
104
112
|
snapshots: records(safeGet(value, "snapshots")).map((snapshot) => ({
|
|
105
113
|
snapshotId: safeGet(snapshot, "snapshotId"), observedAt: safeGet(snapshot, "observedAt"), completedAt: safeGet(snapshot, "completedAt"), completedMono: safeGet(snapshot, "completedMono"), host: safeGet(snapshot, "host"), repository: safeGet(snapshot, "repository"), prNumber: safeGet(snapshot, "prNumber"), prState: safeGet(snapshot, "prState"), headOid: safeGet(snapshot, "headOid"), complete: safeGet(snapshot, "complete"), evidenceIds: strings(safeGet(snapshot, "evidenceIds")), pageDiagnostics: records(safeGet(snapshot, "pageDiagnostics")), normalizedByteLength: safeGet(snapshot, "normalizedByteLength"),
|
|
106
114
|
} as CollectorSnapshot)),
|
|
107
|
-
evidenceRecords: records(safeGet(value, "evidenceRecords")).map((record) => ({ evidenceId: safeGet(record, "evidenceId"), kind: safeGet(record, "kind"), versionId: safeGet(record, "versionId"), contentDigest: safeGet(record, "contentDigest"), firstObservedAt: safeGet(record, "firstObservedAt"),
|
|
115
|
+
evidenceRecords: records(safeGet(value, "evidenceRecords")).map((record) => ({ evidenceId: safeGet(record, "evidenceId"), kind: safeGet(record, "kind"), versionId: safeGet(record, "versionId"), contentDigest: safeGet(record, "contentDigest"), firstObservedAt: safeGet(record, "firstObservedAt"), githubId: safeGet(record, "githubId"), authorLogin: safeGet(record, "authorLogin"), htmlUrl: safeGet(record, "htmlUrl"), authoritativeTime: safeGet(record, "authoritativeTime") } as CollectorEvidenceRecord)),
|
|
108
116
|
};
|
|
109
117
|
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* Error so settlement keeps the original cause (kind=failure, exit 1).
|
|
13
13
|
*/
|
|
14
14
|
import { Type, type TSchema } from "typebox";
|
|
15
|
+
import type { CorrectableSubmissionError } from "../submission-correctable-error.ts";
|
|
15
16
|
|
|
16
17
|
export const INFRASTRUCTURE_FAILURE_DECLARATION_KEY =
|
|
17
18
|
"infrastructureFailure" as const;
|
|
@@ -115,15 +116,26 @@ function infrastructureFailureError(diagnostic: string): Error {
|
|
|
115
116
|
* The one early call for every terminating output `execute`: if the parameters
|
|
116
117
|
* carry the infra declaration, hand the diagnostic error to the shared host
|
|
117
118
|
* `failInfrastructure` seam (which aborts the run). No-op otherwise.
|
|
119
|
+
*
|
|
120
|
+
* #641 chain②: an optional seat-owned bounce hook may intercept the
|
|
121
|
+
* declaration first — when the seat can machine-verify a lawful normal
|
|
122
|
+
* completion, it returns a correctable error and the declaration is treated as
|
|
123
|
+
* model misuse (交件契约封驳) instead of a host failure. Returning undefined
|
|
124
|
+
* keeps the shared failure path.
|
|
118
125
|
*/
|
|
119
126
|
export function failOnInfrastructureFailureDeclaration<C>(
|
|
120
127
|
parameters: unknown,
|
|
121
128
|
hostActions: TerminatingInfrastructureHostActions<C>,
|
|
122
129
|
ctx: C,
|
|
123
130
|
toolCallId: string,
|
|
131
|
+
bounceInfrastructureDeclaration?: (params: unknown, toolCallId: string, ctx: C) => CorrectableSubmissionError | undefined,
|
|
124
132
|
): void {
|
|
125
133
|
const diagnostic = infrastructureFailureDiagnostic(parameters);
|
|
126
134
|
if (diagnostic === undefined) return;
|
|
135
|
+
if (bounceInfrastructureDeclaration !== undefined) {
|
|
136
|
+
const bounce = bounceInfrastructureDeclaration(parameters, toolCallId, ctx);
|
|
137
|
+
if (bounce !== undefined) throw bounce;
|
|
138
|
+
}
|
|
127
139
|
hostActions.failInfrastructure(
|
|
128
140
|
infrastructureFailureError(diagnostic),
|
|
129
141
|
ctx,
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
// interval binding on historical session bytes). Provider-stop retain authority is Sitian.
|
|
45
45
|
import {
|
|
46
46
|
COLLECTOR_OBSERVE_TOOL,
|
|
47
|
+
COLLECTOR_READ_TOOL,
|
|
47
48
|
COLLECTOR_REQUEST_TOOL,
|
|
48
49
|
COLLECTOR_WAIT_TOOL,
|
|
49
50
|
} from "../collector-ledger.ts";
|
|
@@ -109,6 +110,7 @@ import {
|
|
|
109
110
|
import {
|
|
110
111
|
classifyPackagedRoleTerminalResult,
|
|
111
112
|
findLatestDurablePackagedRoleTerminal,
|
|
113
|
+
hasNavigatorInfrastructureFailureBase,
|
|
112
114
|
isAcceptedPackagedRoleTerminalResult,
|
|
113
115
|
isReceiptSettlementBindingClear,
|
|
114
116
|
NAVIGATOR_INVOCATION_ENTRY,
|
|
@@ -1604,6 +1606,7 @@ function boundErroredToolCandidate(
|
|
|
1604
1606
|
/** Collector operational tools that fail closed via host infrastructure abort. */
|
|
1605
1607
|
const COLLECTOR_INFRASTRUCTURE_TOOLS = new Set<string>([
|
|
1606
1608
|
COLLECTOR_OBSERVE_TOOL,
|
|
1609
|
+
COLLECTOR_READ_TOOL,
|
|
1607
1610
|
COLLECTOR_REQUEST_TOOL,
|
|
1608
1611
|
COLLECTOR_WAIT_TOOL,
|
|
1609
1612
|
]);
|
|
@@ -1613,12 +1616,22 @@ type InfrastructureFailureSpec = Readonly<{
|
|
|
1613
1616
|
matchTool: (toolName: string) => boolean;
|
|
1614
1617
|
cause: ControlledFailureCause;
|
|
1615
1618
|
identityName: string;
|
|
1619
|
+
/**
|
|
1620
|
+
* Errored results only count as infrastructure when the durable details carry
|
|
1621
|
+
* the typed navigator fact. ak_collector_read also rejects known correctable
|
|
1622
|
+
* misuses (CollectorUnknownEvidenceError pointer bounces) as errored tool
|
|
1623
|
+
* results — those must not surface as CollectorInfrastructureError.
|
|
1624
|
+
*/
|
|
1625
|
+
requireInfrastructureFact?: (toolName: string) => boolean;
|
|
1616
1626
|
}>;
|
|
1617
1627
|
|
|
1618
1628
|
const COLLECTOR_INFRASTRUCTURE_FAILURE_SPEC: InfrastructureFailureSpec = {
|
|
1619
1629
|
matchTool: (toolName) => COLLECTOR_INFRASTRUCTURE_TOOLS.has(toolName),
|
|
1620
1630
|
cause: "activation",
|
|
1621
1631
|
identityName: "CollectorInfrastructureError",
|
|
1632
|
+
// read alone has a correctable rejection mode (unknown/non-openable pointers);
|
|
1633
|
+
// only its typed infrastructure-failure fact counts as a real host failure.
|
|
1634
|
+
requireInfrastructureFact: (toolName) => toolName === COLLECTOR_READ_TOOL,
|
|
1622
1635
|
};
|
|
1623
1636
|
|
|
1624
1637
|
const ENGINE_DETOUR_INFRASTRUCTURE_FAILURE_SPEC: InfrastructureFailureSpec = {
|
|
@@ -1648,6 +1661,9 @@ function extractInfrastructureToolFailure(
|
|
|
1648
1661
|
) {
|
|
1649
1662
|
continue;
|
|
1650
1663
|
}
|
|
1664
|
+
if (spec.requireInfrastructureFact?.(message.toolName) === true) {
|
|
1665
|
+
if (!hasNavigatorInfrastructureFailureBase(message.details)) continue;
|
|
1666
|
+
}
|
|
1651
1667
|
const diagnostic = toolResultText(message);
|
|
1652
1668
|
if (diagnostic.length === 0) continue;
|
|
1653
1669
|
return {
|
package/src/role-runtime.ts
CHANGED
|
@@ -45,6 +45,7 @@ import type { CollectorGitHubTransport } from "./collector-github.ts";
|
|
|
45
45
|
import {
|
|
46
46
|
COLLECTOR_OBSERVE_TOOL,
|
|
47
47
|
COLLECTOR_OUTPUT_TOOL,
|
|
48
|
+
COLLECTOR_READ_TOOL,
|
|
48
49
|
COLLECTOR_REQUEST_TOOL,
|
|
49
50
|
COLLECTOR_WAIT_TOOL,
|
|
50
51
|
createCollectorRoleRuntime,
|
|
@@ -388,6 +389,7 @@ export type { ComplianceDecision } from "./compliance-transport.ts";
|
|
|
388
389
|
export {
|
|
389
390
|
COLLECTOR_OBSERVE_TOOL,
|
|
390
391
|
COLLECTOR_OUTPUT_TOOL,
|
|
392
|
+
COLLECTOR_READ_TOOL,
|
|
391
393
|
COLLECTOR_REQUEST_TOOL,
|
|
392
394
|
COLLECTOR_WAIT_TOOL,
|
|
393
395
|
} from "./collector-role.ts";
|
package/src/submission-ledger.ts
CHANGED
|
@@ -283,19 +283,25 @@ export function createSubmissionLedgerHost(
|
|
|
283
283
|
if (state.sealed) throw new Error("提交账已封账");
|
|
284
284
|
// #541 / #575: shared infra-declaration fail lives on the ledger seam,
|
|
285
285
|
// before any role execute or sole-final work (one owner for every seat).
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
},
|
|
292
|
-
},
|
|
293
|
-
context,
|
|
294
|
-
toolCallId,
|
|
295
|
-
);
|
|
286
|
+
// #641 chain②: seats may opt into bouncing a machine-verified normal
|
|
287
|
+
// completion misdeclared as infrastructure failure — the bounce throws a
|
|
288
|
+
// correctable error from the declaration call, so it lands in the same
|
|
289
|
+
// correctable-rejection path as execute-thrown rejections below. The
|
|
290
|
+
// candidate is booked first so the bounced attempt stays observable.
|
|
296
291
|
append({ type: "candidate", attemptId, toolCallId, toolName: tool.name, sequence: ++state.sequence });
|
|
297
292
|
let result: HostToolResult<unknown>;
|
|
298
293
|
try {
|
|
294
|
+
failOnInfrastructureFailureDeclaration(
|
|
295
|
+
params,
|
|
296
|
+
{
|
|
297
|
+
failInfrastructure(error, ctx) {
|
|
298
|
+
failInfrastructure(error, ctx);
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
context,
|
|
302
|
+
toolCallId,
|
|
303
|
+
tool.bounceInfrastructureDeclaration,
|
|
304
|
+
);
|
|
299
305
|
result = await tool.execute(toolCallId, params, signal, update, context);
|
|
300
306
|
} catch (error) {
|
|
301
307
|
if (isCorrectableExecuteError(error)) {
|