@akagilnc/pi-workflow-roles 0.1.5375 → 0.1.5406
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/README.md +2 -0
- package/README.zh-CN.md +2 -0
- package/dist/acp-host/production-host.js +6381 -5684
- package/dist/archivist-record-pointer.js +38 -0
- package/dist/collector-tool-schemas.js +18 -0
- package/dist/compliance-transport.js +5 -0
- package/dist/diarist-contracts.js +26 -0
- package/dist/doctor-auditor.js +1 -0
- package/dist/engine-detour-usage.js +6 -6
- package/dist/filed-submission.js +28 -0
- package/dist/gatekeeper-role.js +6 -10
- package/dist/gleaner-left-contracts.js +16 -0
- package/dist/headless-host/production-host.js +1644 -947
- package/dist/judge-role.js +21 -16
- package/dist/migrate-book-topology.js +452 -81
- package/dist/navigator-attendance.js +10 -9
- package/dist/navigator-invocation-identity.js +18 -0
- package/dist/package-contracts/reviewer-output.js +16 -0
- package/dist/package-contracts/worker-output.js +18 -2
- package/dist/pi/role-turn-host.js +9 -0
- package/dist/public-cli/cli.js +1 -0
- package/dist/public-cli/instruction-seat-run.js +258 -55
- package/dist/public-cli/main.js +1209 -346
- package/dist/public-cli/post-admission.js +427 -244
- package/dist/public-cli/settlement.js +111 -48
- package/dist/public-cli/terminal.js +12 -1
- package/dist/public-cli/turn-request.js +3 -0
- package/dist/receipt-delivery-policy.js +152 -17
- package/dist/role-submission-declarations.js +131 -0
- package/dist/secretariat-contracts.js +23 -1
- package/dist/submission-errors.js +11 -1
- package/dist/submission-gate.js +32 -12
- package/package.json +1 -1
- package/src/archivist-record-pointer.ts +48 -0
- package/src/auditor-role.ts +2 -8
- package/src/collector-role.ts +5 -28
- package/src/compliance-transport.ts +10 -2
- package/src/countersign-role.ts +2 -7
- package/src/diarist-contracts.ts +37 -0
- package/src/diarist-role.ts +4 -44
- package/src/doctor-auditor.ts +3 -0
- package/src/doctor-role.ts +16 -11
- package/src/engine-detour-usage.ts +7 -6
- package/src/external-host-turn-loop.ts +24 -12
- package/src/filed-submission.ts +44 -0
- package/src/gatekeeper-role.ts +8 -16
- package/src/gleaner-left-contracts.ts +26 -1
- package/src/gleaner-left-role.ts +4 -32
- package/src/host-contracts.ts +7 -0
- package/src/inspector-role.ts +2 -7
- package/src/judge-role.ts +31 -24
- package/src/merger-role.ts +5 -8
- package/src/navigator-attendance.ts +17 -12
- package/src/navigator-invocation-identity.ts +31 -0
- package/src/navigator-role.ts +2 -8
- package/src/notary-role.ts +5 -20
- package/src/package-contracts/reviewer-output.ts +25 -0
- package/src/package-contracts/worker-output.ts +43 -5
- package/src/pi/adapter.ts +33 -8
- package/src/pi/role-turn-host.ts +7 -0
- package/src/public-cli/cli.ts +1 -0
- package/src/public-cli/instruction-seat-run.ts +292 -61
- package/src/public-cli/post-admission.ts +556 -324
- package/src/public-cli/settlement.ts +112 -50
- package/src/public-cli/terminal.ts +16 -4
- package/src/public-cli/turn-request.ts +10 -1
- package/src/receipt-delivery-policy.ts +209 -17
- package/src/reviewer-role.ts +7 -35
- package/src/role-envelope.ts +5 -1
- package/src/role-runtime-dependencies.ts +1 -0
- package/src/role-runtime.ts +72 -56
- package/src/role-submission-declarations.ts +143 -0
- package/src/secretariat-contracts.ts +35 -0
- package/src/secretariat-role.ts +4 -40
- package/src/submission-correctable-error.ts +5 -2
- package/src/submission-errors.ts +12 -1
- package/src/submission-gate.ts +41 -12
- package/src/worker-role.ts +81 -86
- package/src/worker-submission-gates.ts +32 -7
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
2
3
|
import { dirname, join } from "node:path";
|
|
4
|
+
import { isRecord } from "./unknown-value.js";
|
|
3
5
|
/** Typed parent-side pointer to an independent officer run 正本 (ADR 0079 / #675). */
|
|
4
6
|
export const DIRECT_OFFICER_RUN_POINTER_KIND = "direct-officer-run-pointer";
|
|
5
7
|
/**
|
|
@@ -14,6 +16,7 @@ export const DIRECT_OFFICER_RUN_POINTER_KIND = "direct-officer-run-pointer";
|
|
|
14
16
|
export function bookDirectOfficerRunPointer(options) {
|
|
15
17
|
const nest = join(dirname(options.parentSessionFile), "auditor-roles");
|
|
16
18
|
mkdirSync(nest, { recursive: true });
|
|
19
|
+
const submissionToolCallId = options.submissionToolCallId?.trim() ?? "";
|
|
17
20
|
const pointer = {
|
|
18
21
|
version: 1,
|
|
19
22
|
kind: DIRECT_OFFICER_RUN_POINTER_KIND,
|
|
@@ -22,7 +25,42 @@ export function bookDirectOfficerRunPointer(options) {
|
|
|
22
25
|
...(options.runDirectory !== undefined && options.runDirectory.trim() !== ""
|
|
23
26
|
? { runDirectory: options.runDirectory }
|
|
24
27
|
: {}),
|
|
28
|
+
...(submissionToolCallId === "" ? {} : { submissionToolCallId }),
|
|
25
29
|
};
|
|
26
30
|
writeFileSync(join(nest, `${options.officer}.pointer.json`), `${JSON.stringify(pointer)}\n`, "utf8");
|
|
27
31
|
return pointer;
|
|
28
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Read the one officer pointer. Missing or unreadable is not a pass:
|
|
35
|
+
* the caller re-runs the gate.
|
|
36
|
+
*/
|
|
37
|
+
export async function readDirectOfficerRunPointer(parentSessionFile, officer) {
|
|
38
|
+
try {
|
|
39
|
+
const raw = JSON.parse(await readFile(join(dirname(parentSessionFile), "auditor-roles", `${officer}.pointer.json`), "utf8"));
|
|
40
|
+
if (!isRecord(raw) || raw.kind !== DIRECT_OFFICER_RUN_POINTER_KIND || raw.version !== 1) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
if (raw.officer !== officer)
|
|
44
|
+
return undefined;
|
|
45
|
+
if (typeof raw.sessionFile !== "string" || raw.sessionFile.trim() === "")
|
|
46
|
+
return undefined;
|
|
47
|
+
const runDirectory = typeof raw.runDirectory === "string" && raw.runDirectory.trim() !== ""
|
|
48
|
+
? raw.runDirectory
|
|
49
|
+
: undefined;
|
|
50
|
+
const submissionToolCallId = typeof raw.submissionToolCallId === "string"
|
|
51
|
+
&& raw.submissionToolCallId.trim() !== ""
|
|
52
|
+
? raw.submissionToolCallId
|
|
53
|
+
: undefined;
|
|
54
|
+
return {
|
|
55
|
+
version: 1,
|
|
56
|
+
kind: DIRECT_OFFICER_RUN_POINTER_KIND,
|
|
57
|
+
officer,
|
|
58
|
+
sessionFile: raw.sessionFile,
|
|
59
|
+
...(runDirectory === undefined ? {} : { runDirectory }),
|
|
60
|
+
...(submissionToolCallId === undefined ? {} : { submissionToolCallId }),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { openToolObject } from "./open-tool-schema.js";
|
|
3
|
+
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.js";
|
|
4
|
+
/**
|
|
5
|
+
* #1088: LLM gathers evidence via host CLI and submits the receipt.
|
|
6
|
+
* Field declarations guide the model — host must not pure-shape-reject (第 0 条 / ADR 0057).
|
|
7
|
+
* Presence of `groups` remains the Collector terminal discriminator for settlement/analyst.
|
|
8
|
+
*/
|
|
9
|
+
export const collectorOutputBaseSchema = openToolObject(Type.Object({
|
|
10
|
+
groups: Type.Unsafe({
|
|
11
|
+
description: "按机器身份归组的出席、材料与逐条 findings(LLM 自行从宿主 CLI 取证整理;代码不代收不归并)。",
|
|
12
|
+
}),
|
|
13
|
+
unfinishedReasons: Type.Unknown({
|
|
14
|
+
description: "未完成原因;取证受限时如实报告。",
|
|
15
|
+
}),
|
|
16
|
+
}));
|
|
17
|
+
/** Runtime does not enrich findings; the model submits the receipt and signals sole-final. */
|
|
18
|
+
export const collectorOutputArgsSchema = withTerminatingOutputDeclarations(collectorOutputBaseSchema);
|
|
@@ -3,6 +3,7 @@ import { officerConclusionReask } from "./gatekeeper-role.js";
|
|
|
3
3
|
import { receivedDiscriminator } from "./submission-errors.js";
|
|
4
4
|
import { coalesceSubmissionRows } from "./public-cli/terminal.js";
|
|
5
5
|
import { readableGateItem } from "./readable-gate-item.js";
|
|
6
|
+
import { deliveryLimitFromConfig } from "./receipt-delivery-policy.js";
|
|
6
7
|
import { isRecord } from "./unknown-value.js";
|
|
7
8
|
const AUDITOR_DOSSIER_PROMPT = "\u5377\u5B97\u6307\u9488\uFF1A";
|
|
8
9
|
const COMPLIANCE_RESPONSE_ENTRY_TYPE = "ak_compliance_response";
|
|
@@ -120,10 +121,14 @@ async function runComplianceAudit(options) {
|
|
|
120
121
|
});
|
|
121
122
|
});
|
|
122
123
|
let reask;
|
|
124
|
+
let reasksSpent = 0;
|
|
125
|
+
const reaskLimit = deliveryLimitFromConfig(options.autoResumeLimit);
|
|
123
126
|
for (; ; ) {
|
|
124
127
|
const summoned = await summon(subject, runDirectory, options.signal, reask, submission);
|
|
125
128
|
const decision = await projectAuditorTerminal(summoned);
|
|
126
129
|
if (decision.status === "received") {
|
|
130
|
+
if (reasksSpent >= reaskLimit) return decision;
|
|
131
|
+
reasksSpent += 1;
|
|
127
132
|
reask = officerConclusionReask(receivedDiscriminator(decision.reply, "status"));
|
|
128
133
|
continue;
|
|
129
134
|
}
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
* #901: LLM submits bounds; the mechanical layer projects source bytes.
|
|
8
8
|
*/
|
|
9
|
+
import { Type } from "typebox";
|
|
10
|
+
import { openToolObject } from "./open-tool-schema.js";
|
|
11
|
+
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.js";
|
|
9
12
|
import { projectTicketProvenanceSessions, } from "./ticket-provenance-contracts.js";
|
|
10
13
|
import { isSafePositiveTicketNumber } from "./run-ticket-number.js";
|
|
11
14
|
import { isRecord } from "./unknown-value.js";
|
|
@@ -55,3 +58,26 @@ export function projectDiaristTicketSessions(value) {
|
|
|
55
58
|
}
|
|
56
59
|
return Array.from(perTicket, ([ticketNumber, sessions]) => ({ ticketNumber, sessions }));
|
|
57
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* 起居郎交卷形状。
|
|
63
|
+
* #901:交边界(sessions);正文与不可解析原字节由机械投影。
|
|
64
|
+
* status 的合法词(completed | escalate)写在 description,结算认这些词。
|
|
65
|
+
* sessions / ticketSessions 是投影所读的边界:卷路径或端点读不出时走既有 reask,不中止本轮。
|
|
66
|
+
* 声明只留字段名和语义说明,不留类型、嵌套、长度、必填。
|
|
67
|
+
*/
|
|
68
|
+
const DIARIST_SESSIONS_DESCRIPTION = "对话边界。每卷含 path(会话卷绝对或可读路径)与 ranges(本卷本轮各区间)。每段区间含 from / to;起点与终点各写 id(原生 id)或 line(本轮行号),二选一。空列表=本轮无对话可划。端点无法指名时走 reask,不中止。";
|
|
69
|
+
export const diaristOutputSchema = withTerminatingOutputDeclarations(openToolObject(Type.Object({
|
|
70
|
+
status: Type.Unknown({
|
|
71
|
+
description: "completed | escalate",
|
|
72
|
+
}),
|
|
73
|
+
ticketNumber: Type.Optional(Type.Unknown({
|
|
74
|
+
description: "本庭对象票号(正整数)或 null/省略=真无票;下游走 typed 键;认不出用 status=escalate,不洗成无录。机械层不重判。",
|
|
75
|
+
})),
|
|
76
|
+
reason: Type.Unknown({
|
|
77
|
+
description: "status 为 escalate 时:认不出本庭对象的原因",
|
|
78
|
+
}),
|
|
79
|
+
sessions: Type.Optional(Type.Unknown({ description: DIARIST_SESSIONS_DESCRIPTION })),
|
|
80
|
+
ticketSessions: Type.Unknown({
|
|
81
|
+
description: `多票庭逐票对话边界;每票含 ticketNumber(本条边界所归票号,正整数)与 sessions(${DIARIST_SESSIONS_DESCRIPTION})。一次交卷各票各自分录。与单票 sessions 二选一。`,
|
|
82
|
+
}),
|
|
83
|
+
})));
|
package/dist/doctor-auditor.js
CHANGED
|
@@ -20,6 +20,7 @@ export function createPiDoctorAuditor() {
|
|
|
20
20
|
? {}
|
|
21
21
|
: { runDirectory: auditorRunDirectory(options.context) }),
|
|
22
22
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
23
|
+
...(options.autoResumeLimit === undefined ? {} : { autoResumeLimit: options.autoResumeLimit }),
|
|
23
24
|
...(options.summonAuditor === undefined ? {} : { summonAuditor: options.summonAuditor }),
|
|
24
25
|
});
|
|
25
26
|
};
|
|
@@ -248,14 +248,14 @@ export function sessionFileFromSessionDirectory(sessionDirectory) {
|
|
|
248
248
|
return join(sessionDirectory, "session.jsonl");
|
|
249
249
|
}
|
|
250
250
|
/**
|
|
251
|
-
* Mint one public-invocation scope id
|
|
251
|
+
* Mint one public-invocation scope id.
|
|
252
252
|
* Call once at the public-entry boundary — never inside the auto-resume loop.
|
|
253
|
-
*
|
|
253
|
+
* Auto-resume reuses it; an explicit new public call, including manual resume,
|
|
254
|
+
* mints another. The id lives on RoleTurnRequest / HostContext only.
|
|
255
|
+
* Receipt facts and detour rows both use this id, including calls with no
|
|
256
|
+
* engine mounted — a missing engine must not merge two public calls.
|
|
254
257
|
*/
|
|
255
|
-
export function mintEngineDetourInvocationScope(
|
|
256
|
-
const engine = input.effectiveEngine?.trim();
|
|
257
|
-
if (engine === undefined || engine.length === 0)
|
|
258
|
-
return undefined;
|
|
258
|
+
export function mintEngineDetourInvocationScope(_input) {
|
|
259
259
|
return randomUUID();
|
|
260
260
|
}
|
|
261
261
|
/** Attach a minted scope onto a turn request (shared Host envelope field). */
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One host-neutral submission execute for every public seat.
|
|
3
|
+
* Records nothing itself — the ledger seam already appends the original payload.
|
|
4
|
+
* Ends this tool call. Does not summon an auditor and does not end the role run.
|
|
5
|
+
* Shape is not an admission gate (ADR 0055). Seat reminders stay on beforeAccept.
|
|
6
|
+
*/
|
|
7
|
+
export function registerFiledSubmissionTool(roleHost, tool, options) {
|
|
8
|
+
roleHost.registerTool({
|
|
9
|
+
name: tool.name,
|
|
10
|
+
label: tool.label,
|
|
11
|
+
description: tool.description,
|
|
12
|
+
...(tool.promptSnippet === undefined ? {} : { promptSnippet: tool.promptSnippet }),
|
|
13
|
+
parameters: tool.parameters,
|
|
14
|
+
async execute(toolCallId, parameters, signal, _onUpdate, ctx) {
|
|
15
|
+
const blocked = options.readyError();
|
|
16
|
+
if (blocked !== undefined)
|
|
17
|
+
throw new Error(blocked);
|
|
18
|
+
const projected = options.beforeAccept === undefined
|
|
19
|
+
? undefined
|
|
20
|
+
: await options.beforeAccept({ toolCallId, parameters, signal, ctx });
|
|
21
|
+
return {
|
|
22
|
+
content: [],
|
|
23
|
+
details: projected === undefined ? parameters : projected,
|
|
24
|
+
terminate: true,
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
package/dist/gatekeeper-role.js
CHANGED
|
@@ -3,7 +3,8 @@ import { packagedGateStageLabel } from "./packaged-role-registry.js";
|
|
|
3
3
|
import { GatekeeperDecisionError, receivedDiscriminator, unreadableDiscriminatorNotice } from "./submission-errors.js";
|
|
4
4
|
import { INSPECTOR_OUTPUT_TOOL_NAME } from "./inspector-contracts.js";
|
|
5
5
|
import { REVIEW_QUEUE_STATUSES, REVIEW_SUBMISSION_OUTPUT_TOOL_NAME } from "./review-submission.js";
|
|
6
|
-
import { GATEKEEPER_OUTPUT_TOOL_NAME
|
|
6
|
+
import { GATEKEEPER_OUTPUT_TOOL_NAME } from "./package-contracts/gatekeeper-output.js";
|
|
7
|
+
import { roleSubmissionDeclaration } from "./role-submission-declarations.js";
|
|
7
8
|
import { runIdFromRunDirectory } from "./run-terminal-artifacts.js";
|
|
8
9
|
import { isRecord } from "./unknown-value.js";
|
|
9
10
|
export const INSPECTOR_OUTPUT_TOOL = INSPECTOR_OUTPUT_TOOL_NAME;
|
|
@@ -29,13 +30,7 @@ export { GatekeeperDecisionError } from "./submission-errors.js";
|
|
|
29
30
|
* registration envelope — src/role-runtime.ts (ADR 0018). Schema authority is
|
|
30
31
|
* the shared contract module (with infrastructure-failure declaration).
|
|
31
32
|
*/
|
|
32
|
-
export const GATEKEEPER_TOOL_SPEC =
|
|
33
|
-
name: GATEKEEPER_OUTPUT_TOOL_NAME,
|
|
34
|
-
label: "门下省决议",
|
|
35
|
-
description: "门下省终局决议。status 为 dispatch 或 pass。",
|
|
36
|
-
promptSnippet: "门下省决议",
|
|
37
|
-
parameters: gatekeeperOutputSchema,
|
|
38
|
-
};
|
|
33
|
+
export const GATEKEEPER_TOOL_SPEC = roleSubmissionDeclaration("gatekeeper");
|
|
39
34
|
function failureReason(error) {
|
|
40
35
|
if (error instanceof AggregateError)
|
|
41
36
|
return error.errors.map(failureReason).join("; ");
|
|
@@ -59,8 +54,9 @@ function reviewQueueStatus(status) {
|
|
|
59
54
|
function projectOfficerDecision(officer, decision, fallbackStatus) {
|
|
60
55
|
const receipt = retainedReceipt(decision);
|
|
61
56
|
const record = isRecord(decision) ? decision : undefined;
|
|
62
|
-
const status =
|
|
63
|
-
|
|
57
|
+
const status = record !== undefined && Object.hasOwn(record, "status")
|
|
58
|
+
? receivedDiscriminator(record, "status")
|
|
59
|
+
: fallbackStatus;
|
|
64
60
|
const queueStatus = typeof status === "string" ? reviewQueueStatus(status) : undefined;
|
|
65
61
|
if (queueStatus === "converged") {
|
|
66
62
|
return { status: "converged", officer, receipt };
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { openToolObject } from "./open-tool-schema.js";
|
|
3
|
+
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.js";
|
|
1
4
|
import { isRecord } from "./unknown-value.js";
|
|
2
5
|
const GLEANER_LEFT_OUTPUT_TOOL_NAME = "ak_gleaner_left_output";
|
|
6
|
+
const gleanerLeftOutputSchema = withTerminatingOutputDeclarations(
|
|
7
|
+
openToolObject(
|
|
8
|
+
Type.Object({
|
|
9
|
+
status: Type.Unknown({
|
|
10
|
+
description: "completed"
|
|
11
|
+
}),
|
|
12
|
+
findings: Type.Unknown({
|
|
13
|
+
description: "\u5F39\u7AE0\u5217\u8868\uFF1B\u6BCF\u6761\u53EF\u542B pointer\uFF08\u6587\u4EF6/\u884C\u6307\u9488\uFF09\u4E0E statement\uFF08\u7591\u70B9\u9648\u8FF0\uFF09\uFF0C\u539F\u6837\u7559\u5B58\u3002\u7A7A\u5217\u8868\u5408\u6CD5\u5B8C\u5C40\uFF1B\u673A\u5668\u4E0D\u5224\u5F39\u7AE0\u662F\u5426\u6210\u7ACB\u3002"
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
)
|
|
17
|
+
);
|
|
3
18
|
const GLEANER_LEFT_BASE_FLAG = {
|
|
4
19
|
name: "ak-gleaner-left-base",
|
|
5
20
|
definition: {
|
|
@@ -25,5 +40,6 @@ function validateRecordedGleanerLeftOutput(value) {
|
|
|
25
40
|
export {
|
|
26
41
|
GLEANER_LEFT_BASE_FLAG,
|
|
27
42
|
GLEANER_LEFT_OUTPUT_TOOL_NAME,
|
|
43
|
+
gleanerLeftOutputSchema,
|
|
28
44
|
validateRecordedGleanerLeftOutput
|
|
29
45
|
};
|