@akagilnc/pi-workflow-roles 0.1.5207 → 0.1.5212
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 +1 -1
- package/dist/acp-host/production-host.js +133 -289
- package/dist/headless-host/production-host.js +109 -265
- package/dist/public-cli/main.js +0 -1
- package/dist/sitian-appender.js +0 -1
- package/dist/submission-ledger.js +8 -29
- package/package.json +2 -3
- package/scripts/build-package.mjs +1 -3
- package/src/host-contracts.ts +0 -100
- package/src/role-runtime.ts +4 -57
- package/src/sitian-appender.ts +0 -1
- package/src/sitian-contracts.ts +0 -3
- package/src/submission-ledger.ts +10 -31
- package/dist/pi/in-process-session.js +0 -660
- package/dist/stream-idle-guard.js +0 -67
- package/schemas/tool-execution-observation.schema.json +0 -107
- package/scripts/generate-tool-execution-observation-schema.ts +0 -7
- package/src/in-process-session.ts +0 -1
- package/src/pi/in-process-session.ts +0 -861
- package/src/stream-idle-guard.ts +0 -98
- package/src/tool-execution-observation.ts +0 -168
|
@@ -312,26 +312,14 @@ export async function readLatestSubmissionOutcome(cwd, runId, homeOrScope) {
|
|
|
312
312
|
}
|
|
313
313
|
async function restoreState(cwd, runId, scope) {
|
|
314
314
|
const located = await readOwnedSubmissionRecords(cwd, runId, scope);
|
|
315
|
-
// Unknown-run empty set: no prior chain. Owned rows without a file are an internal bug.
|
|
316
315
|
if (located.file === undefined) {
|
|
317
316
|
if (located.owned.length !== 0) {
|
|
318
317
|
throw new Error(`submission ledger invariant: owned rows present without recordFile for run ${runId}`);
|
|
319
318
|
}
|
|
320
319
|
return { sequence: 0 };
|
|
321
320
|
}
|
|
322
|
-
const {
|
|
323
|
-
const last = owned.at(-1);
|
|
321
|
+
const { owned } = located;
|
|
324
322
|
return {
|
|
325
|
-
...(last === undefined
|
|
326
|
-
? {}
|
|
327
|
-
: {
|
|
328
|
-
prior: {
|
|
329
|
-
identity: last.identity,
|
|
330
|
-
recordFile: file,
|
|
331
|
-
kind: last.kind,
|
|
332
|
-
level: last.level,
|
|
333
|
-
},
|
|
334
|
-
}),
|
|
335
323
|
sequence: owned.reduce((maximum, record) => {
|
|
336
324
|
const payload = record.payload;
|
|
337
325
|
return payload?.type === "candidate" && typeof payload.sequence === "number"
|
|
@@ -362,7 +350,7 @@ function homeFromHostContext(context, home) {
|
|
|
362
350
|
}
|
|
363
351
|
/**
|
|
364
352
|
* #959: seal one accepted submission without a model tool call.
|
|
365
|
-
* Same ledger row shape
|
|
353
|
+
* Same ledger row shape as the terminating-tool wrap.
|
|
366
354
|
* Used when a prose-exit seat (navigator) harvests the final assistant text.
|
|
367
355
|
*/
|
|
368
356
|
export async function sealAcceptedSubmission(options) {
|
|
@@ -370,15 +358,10 @@ export async function sealAcceptedSubmission(options) {
|
|
|
370
358
|
const attemptId = attemptIdentity(options.context, runId);
|
|
371
359
|
const sessionParent = sessionParentFromHostContext(options.context);
|
|
372
360
|
const home = homeFromHostContext(options.context, options.home);
|
|
373
|
-
|
|
374
|
-
...(home === undefined ? {} : { home }),
|
|
375
|
-
...(sessionParent === undefined ? {} : { sessionParent }),
|
|
376
|
-
});
|
|
377
|
-
const pointer = sitianReport({
|
|
361
|
+
sitianReport({
|
|
378
362
|
level: "event",
|
|
379
363
|
kind: "sealed",
|
|
380
364
|
subject: { runId, attemptId },
|
|
381
|
-
...(state.prior === undefined ? {} : { priorEventId: state.prior.identity }),
|
|
382
365
|
payload: {
|
|
383
366
|
type: "sealed",
|
|
384
367
|
attemptId,
|
|
@@ -391,7 +374,6 @@ export async function sealAcceptedSubmission(options) {
|
|
|
391
374
|
...(home !== undefined ? { home } : {}),
|
|
392
375
|
...(sessionParent === undefined ? {} : { sessionParent }),
|
|
393
376
|
});
|
|
394
|
-
state.prior = pointer;
|
|
395
377
|
}
|
|
396
378
|
/**
|
|
397
379
|
* Submission ledger host — record only (#836).
|
|
@@ -412,31 +394,28 @@ export function createSubmissionLedgerHost(host, outputTools, failInfrastructure
|
|
|
412
394
|
states.set(runId, pending);
|
|
413
395
|
return pending;
|
|
414
396
|
})();
|
|
415
|
-
const appendFor = (
|
|
397
|
+
const appendFor = (context, runId, attemptId, event) => {
|
|
416
398
|
const home = resolveHomeFromContext(context);
|
|
417
399
|
const sessionParent = sessionParentFromHostContext(context);
|
|
418
|
-
|
|
400
|
+
return sitianReport({
|
|
419
401
|
level: "event",
|
|
420
402
|
kind: event.type,
|
|
421
403
|
subject: { runId, attemptId },
|
|
422
|
-
...(state.prior === undefined ? {} : { priorEventId: state.prior.identity }),
|
|
423
404
|
payload: event,
|
|
424
405
|
source: "role-runtime",
|
|
425
406
|
cwd: context.cwd,
|
|
426
407
|
...(home !== undefined ? { home } : {}),
|
|
427
408
|
...(sessionParent === undefined ? {} : { sessionParent }),
|
|
428
409
|
});
|
|
429
|
-
state.prior = pointer;
|
|
430
|
-
return pointer;
|
|
431
410
|
};
|
|
432
411
|
host.on("turn_end", async (event, context) => {
|
|
433
412
|
try {
|
|
434
413
|
const runId = runIdentity(context);
|
|
435
414
|
const attemptId = attemptIdentity(context, runId);
|
|
436
|
-
const state = await stateFor(context, runId);
|
|
437
415
|
const calls = event.calls.map(({ toolCallId: id, toolName: name }) => ({ id, name }));
|
|
438
416
|
if (calls.length > 0) {
|
|
439
|
-
|
|
417
|
+
await stateFor(context, runId);
|
|
418
|
+
appendFor(context, runId, attemptId, { type: "roundContext", attemptId, calls });
|
|
440
419
|
}
|
|
441
420
|
}
|
|
442
421
|
catch (error) {
|
|
@@ -465,7 +444,7 @@ export function createSubmissionLedgerHost(host, outputTools, failInfrastructure
|
|
|
465
444
|
const runId = runIdentity(context);
|
|
466
445
|
const attemptId = attemptIdentity(context, runId);
|
|
467
446
|
const state = await stateFor(context, runId);
|
|
468
|
-
const append = (event) => appendFor(
|
|
447
|
+
const append = (event) => appendFor(context, runId, attemptId, event);
|
|
469
448
|
// #541 / #575: shared infra-declaration fail lives on the ledger seam.
|
|
470
449
|
// #641 chain②: seats may bounce a misdeclared infrastructure failure
|
|
471
450
|
// as correctable (2.1/2.2/2.3 keep paths).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akagilnc/pi-workflow-roles",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5212",
|
|
4
4
|
"description": "Soul-bound workflow roles for Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"!dist/package-resources/method-skill.js",
|
|
30
30
|
"!dist/package-resources/method-skill-binding.js",
|
|
31
31
|
"extensions",
|
|
32
|
-
"scripts/generate-tool-execution-observation-schema.ts",
|
|
33
32
|
"scripts/build-package.mjs",
|
|
34
33
|
"src",
|
|
35
34
|
"souls",
|
|
@@ -43,7 +42,7 @@
|
|
|
43
42
|
"CLAUDE.md"
|
|
44
43
|
],
|
|
45
44
|
"scripts": {
|
|
46
|
-
"build": "
|
|
45
|
+
"build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.build.json && node scripts/build-package.mjs",
|
|
47
46
|
"prepack": "npm run build",
|
|
48
47
|
"test": "node --import tsx --import ./scripts/test-process-env-preload.mjs --test test/unit/**/*.test.ts test/contract/**/*.test.ts",
|
|
49
48
|
"test:fast": "node --import tsx --import ./scripts/test-process-env-preload.mjs --test-timeout=300000 --test test/unit/**/*.test.ts test/contract/**/*.test.ts",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { chmod, copyFile, mkdir, readFile,
|
|
1
|
+
import { chmod, copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
2
|
import { dirname, join, resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { build } from "esbuild";
|
|
@@ -20,7 +20,6 @@ const entries = [
|
|
|
20
20
|
// Static import of navigator-work-base.
|
|
21
21
|
"atomic-write",
|
|
22
22
|
"public-role-summons",
|
|
23
|
-
"pi/in-process-session",
|
|
24
23
|
"activation-ledger-git",
|
|
25
24
|
"activation-ledger-topology",
|
|
26
25
|
"archivist-record-entry",
|
|
@@ -70,7 +69,6 @@ const entries = [
|
|
|
70
69
|
"sitian-contracts",
|
|
71
70
|
"sitian-facade",
|
|
72
71
|
"sitian-reader",
|
|
73
|
-
"stream-idle-guard",
|
|
74
72
|
"typed-provider-http",
|
|
75
73
|
"upstream-error-testimony",
|
|
76
74
|
];
|
package/src/host-contracts.ts
CHANGED
|
@@ -386,109 +386,9 @@ export interface RoleHost {
|
|
|
386
386
|
getCommands?(): Array<{ name: string }>;
|
|
387
387
|
}
|
|
388
388
|
|
|
389
|
-
/** Institutional sub-session seats (#518 §1). */
|
|
390
|
-
export type InstitutionalSeat =
|
|
391
|
-
| "gatekeeper"
|
|
392
|
-
| "inspector"
|
|
393
|
-
| "notary"
|
|
394
|
-
| "auditor"
|
|
395
|
-
| (string & {});
|
|
396
|
-
|
|
397
389
|
/** Non-secret host-neutral seat model selection. Single truth source is RoleTurnModelConfig. */
|
|
398
390
|
export type HostInstitutionalModelSelection = RoleTurnModelConfig;
|
|
399
391
|
|
|
400
|
-
/** Usage statistics for institutional sub-session events and turns. */
|
|
401
|
-
export type HostSessionUsage = {
|
|
402
|
-
readonly input: number;
|
|
403
|
-
readonly output: number;
|
|
404
|
-
readonly cacheRead: number;
|
|
405
|
-
readonly cacheWrite: number;
|
|
406
|
-
readonly totalTokens: number;
|
|
407
|
-
readonly cost: {
|
|
408
|
-
readonly input: number;
|
|
409
|
-
readonly output: number;
|
|
410
|
-
readonly cacheRead: number;
|
|
411
|
-
readonly cacheWrite: number;
|
|
412
|
-
readonly total: number;
|
|
413
|
-
};
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
/** Closed stream event union consumed by institutional callers (#518 §1③). */
|
|
417
|
-
export type HostInstitutionalSessionEvent =
|
|
418
|
-
| {
|
|
419
|
-
readonly type: "message_end";
|
|
420
|
-
readonly role: "assistant" | "user" | string;
|
|
421
|
-
readonly message?: unknown;
|
|
422
|
-
readonly usage?: HostSessionUsage;
|
|
423
|
-
}
|
|
424
|
-
| {
|
|
425
|
-
readonly type: "turn_end";
|
|
426
|
-
readonly stopReason?: string;
|
|
427
|
-
}
|
|
428
|
-
| {
|
|
429
|
-
readonly type: "tool_call";
|
|
430
|
-
readonly toolCallId: string;
|
|
431
|
-
readonly toolName: string;
|
|
432
|
-
readonly args?: unknown;
|
|
433
|
-
}
|
|
434
|
-
| {
|
|
435
|
-
readonly type: "tool_result";
|
|
436
|
-
readonly toolCallId: string;
|
|
437
|
-
readonly toolName: string;
|
|
438
|
-
readonly isError?: boolean;
|
|
439
|
-
readonly details?: unknown;
|
|
440
|
-
};
|
|
441
|
-
|
|
442
|
-
/** Terminal result of an institutional assistant turn (#518 §1③). */
|
|
443
|
-
export type HostAssistantTurnResult = {
|
|
444
|
-
readonly text: string;
|
|
445
|
-
readonly stopReason?: string;
|
|
446
|
-
readonly errorMessage?: string;
|
|
447
|
-
readonly usage?: HostSessionUsage;
|
|
448
|
-
readonly messages?: readonly unknown[];
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
/**
|
|
452
|
-
* Handle to an active institutional sub-session (#518 §1②).
|
|
453
|
-
* Does not leak AgentSession, ModelRuntime, or Provider objects out of the adapter.
|
|
454
|
-
*/
|
|
455
|
-
export interface HostInstitutionalSessionHandle {
|
|
456
|
-
readonly sessionFile?: string;
|
|
457
|
-
readonly sessionId?: string;
|
|
458
|
-
prompt(text: string): Promise<HostAssistantTurnResult>;
|
|
459
|
-
subscribe(listener: (event: HostInstitutionalSessionEvent) => void): () => void;
|
|
460
|
-
abort(): void;
|
|
461
|
-
close(): Promise<void>;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/** Open options for an institutional sub-session (#518 §1①). */
|
|
465
|
-
export type HostInstitutionalSessionOptions = {
|
|
466
|
-
readonly cwd: string;
|
|
467
|
-
readonly selection: HostInstitutionalModelSelection;
|
|
468
|
-
readonly systemPrompt: string;
|
|
469
|
-
readonly tools?: readonly HostToolDefinition[];
|
|
470
|
-
readonly customTools?: readonly unknown[];
|
|
471
|
-
readonly noTools?: "all" | "builtin";
|
|
472
|
-
readonly toolsAllowlist?: readonly string[];
|
|
473
|
-
readonly agentDir?: string;
|
|
474
|
-
readonly credentialScratchParent?: string;
|
|
475
|
-
readonly signal?: AbortSignal;
|
|
476
|
-
readonly idleRetry?: boolean;
|
|
477
|
-
readonly sessionIdentity?: {
|
|
478
|
-
readonly kind: string;
|
|
479
|
-
readonly subject?: string;
|
|
480
|
-
readonly parent?: { getSessionFile(): string | undefined };
|
|
481
|
-
};
|
|
482
|
-
readonly sessionManager?: unknown;
|
|
483
|
-
};
|
|
484
|
-
|
|
485
|
-
/** Host-neutral institutional sub-session open seam. */
|
|
486
|
-
export interface InstitutionalSessionHost {
|
|
487
|
-
openInstitutionalSession(
|
|
488
|
-
options: HostInstitutionalSessionOptions,
|
|
489
|
-
): Promise<HostInstitutionalSessionHandle>;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
392
|
/** Host-owned durable record session used by AK ledger placement. */
|
|
493
393
|
export interface HostRecordSession {
|
|
494
394
|
getSessionFile(): string | undefined;
|
package/src/role-runtime.ts
CHANGED
|
@@ -24,12 +24,6 @@ import {
|
|
|
24
24
|
} from "./activation-ledger.ts";
|
|
25
25
|
import { readPackageMaterial } from "./session-opening-materials.ts";
|
|
26
26
|
import { writeStderrJsonlRecord } from "./stderr-jsonl.ts";
|
|
27
|
-
import {
|
|
28
|
-
createToolExecutionObservationFace,
|
|
29
|
-
systemToolExecutionObservationMonoNow,
|
|
30
|
-
writeToolExecutionObservationRecord,
|
|
31
|
-
type ToolExecutionObservationWriter,
|
|
32
|
-
} from "./tool-execution-observation.ts";
|
|
33
27
|
import {
|
|
34
28
|
ENGINE_DETOUR_TOOL_NAME,
|
|
35
29
|
ENGINE_MODEL_FLAG_NAME,
|
|
@@ -286,17 +280,6 @@ export type {
|
|
|
286
280
|
ActivationSessionManager,
|
|
287
281
|
ActivationSessionPointer,
|
|
288
282
|
} from "./activation-ledger.ts";
|
|
289
|
-
export {
|
|
290
|
-
TOOL_EXECUTION_UPDATE_HEARTBEAT,
|
|
291
|
-
TOOL_EXECUTION_UPDATE_THROTTLE_MS,
|
|
292
|
-
createToolExecutionObservationFace,
|
|
293
|
-
isProducingToolUpdate,
|
|
294
|
-
systemToolExecutionObservationMonoNow,
|
|
295
|
-
toolExecutionObservationRecordSchema,
|
|
296
|
-
validateToolExecutionObservationRecord,
|
|
297
|
-
writeToolExecutionObservationRecord,
|
|
298
|
-
} from "./tool-execution-observation.ts";
|
|
299
|
-
export type { ToolExecutionObservationRecord, ToolExecutionObservationWriter } from "./tool-execution-observation.ts";
|
|
300
283
|
import {
|
|
301
284
|
NOTARY_OUTPUT_TOOL,
|
|
302
285
|
INSPECTOR_OUTPUT_TOOL,
|
|
@@ -477,11 +460,6 @@ export type RoleRuntimeDependencies = {
|
|
|
477
460
|
loadNavigatorWorkContext?(options: { context: HostContext; role: string; phase: NavigatorPhase; getFlag?: (name: string) => unknown }): Promise<NavigatorWorkContext>;
|
|
478
461
|
activationClock?(): string;
|
|
479
462
|
activationTraceWriter?: (record: ActivationTraceRecord) => void | Promise<void>;
|
|
480
|
-
/** Wall-clock ISO timestamps for tool-execution observation records; defaults to activationClock/Date. */
|
|
481
|
-
toolExecutionObservationClock?(): string;
|
|
482
|
-
/** Monotonic ms clock for update throttling; defaults to performance.now (not Date.now). */
|
|
483
|
-
toolExecutionObservationMonoNow?(): number;
|
|
484
|
-
toolExecutionObservationWriter?: ToolExecutionObservationWriter;
|
|
485
463
|
};
|
|
486
464
|
|
|
487
465
|
function abortContext(ctx: { abort(): void }): void {
|
|
@@ -1081,7 +1059,7 @@ export function createRoleRuntimeExtension(
|
|
|
1081
1059
|
// terminating-tool rejections and mechanical delivery requests share two turns.
|
|
1082
1060
|
let receiptDelivery = createReceiptDeliveryPolicy();
|
|
1083
1061
|
let noReceiptRecorded = false;
|
|
1084
|
-
// Public-run fetch observation
|
|
1062
|
+
// Public-run fetch observation.
|
|
1085
1063
|
let priorFetch: typeof globalThis.fetch | undefined;
|
|
1086
1064
|
let fetchWrapped = false;
|
|
1087
1065
|
/** Envelope-owned: abort/teardown attendance without re-blocking the parent court (#959). */
|
|
@@ -1498,7 +1476,6 @@ export function createRoleRuntimeExtension(
|
|
|
1498
1476
|
disposeNavigatorAttendanceNonBlocking(attendanceToDispose);
|
|
1499
1477
|
pendingInfrastructureFailures.clear();
|
|
1500
1478
|
pendingSubmissionNonPassByToolCallId.clear();
|
|
1501
|
-
observationFace.reset();
|
|
1502
1479
|
});
|
|
1503
1480
|
|
|
1504
1481
|
const hostActions = {
|
|
@@ -1736,38 +1713,9 @@ export function createRoleRuntimeExtension(
|
|
|
1736
1713
|
|
|
1737
1714
|
const clock = dependencies.activationClock ?? (() => new Date().toISOString());
|
|
1738
1715
|
const writeTrace = dependencies.activationTraceWriter ?? writeActivationTraceRecord;
|
|
1739
|
-
const observationFace = createToolExecutionObservationFace({
|
|
1740
|
-
role: () => selectedRole,
|
|
1741
|
-
admitted: () => admitted,
|
|
1742
|
-
clock: dependencies.toolExecutionObservationClock ?? clock,
|
|
1743
|
-
monoNow: dependencies.toolExecutionObservationMonoNow ?? systemToolExecutionObservationMonoNow,
|
|
1744
|
-
write: dependencies.toolExecutionObservationWriter ?? writeToolExecutionObservationRecord,
|
|
1745
|
-
});
|
|
1746
|
-
// ExtensionRunner.emit catches ordinary handler throws, emits extension error, and continues.
|
|
1747
|
-
// Observation plane failures must still hit the shared infrastructure termination path
|
|
1748
|
-
// (abort + nonzero print/json exit) with the original cause before that swallow.
|
|
1749
|
-
const observe = async (
|
|
1750
|
-
run: () => void | Promise<void>,
|
|
1751
|
-
ctx: HostContext,
|
|
1752
|
-
): Promise<void> => {
|
|
1753
|
-
try {
|
|
1754
|
-
await run();
|
|
1755
|
-
} catch (error) {
|
|
1756
|
-
failInfrastructure(error, ctx);
|
|
1757
|
-
}
|
|
1758
|
-
};
|
|
1759
|
-
roleHost.on("tool_execution_start", async (event, ctx) => {
|
|
1760
|
-
await observe(() => observationFace.onStart(event), ctx);
|
|
1761
|
-
});
|
|
1762
|
-
roleHost.on("tool_execution_update", async (event, ctx) => {
|
|
1763
|
-
await observe(() => observationFace.onUpdate(event), ctx);
|
|
1764
|
-
});
|
|
1765
|
-
roleHost.on("tool_execution_end", async (event, ctx) => {
|
|
1766
|
-
await observe(() => observationFace.onEnd(event), ctx);
|
|
1767
|
-
});
|
|
1768
1716
|
|
|
1769
1717
|
// Public Role run: record typed non-success HTTP for error evidence + v1 resume.
|
|
1770
|
-
// Same observation owner
|
|
1718
|
+
// Same observation owner → typed-provider-http
|
|
1771
1719
|
// sidecar (settlement already merges observation.httpStatus into knownFailure).
|
|
1772
1720
|
// after_provider_response covers the success-path onResponse face; fetch wrap covers
|
|
1773
1721
|
// non-2xx Responses where openai-completions throws before onResponse (#675).
|
|
@@ -1805,7 +1753,7 @@ export function createRoleRuntimeExtension(
|
|
|
1805
1753
|
});
|
|
1806
1754
|
|
|
1807
1755
|
roleHost.on("session_start", async (event, ctx) => {
|
|
1808
|
-
// Scope fetch observation to this public run
|
|
1756
|
+
// Scope fetch observation to this public run.
|
|
1809
1757
|
if (!fetchWrapped && typeof globalThis.fetch === "function") {
|
|
1810
1758
|
priorFetch = globalThis.fetch.bind(globalThis);
|
|
1811
1759
|
const underlying = priorFetch;
|
|
@@ -1827,7 +1775,7 @@ export function createRoleRuntimeExtension(
|
|
|
1827
1775
|
provider,
|
|
1828
1776
|
});
|
|
1829
1777
|
} catch {
|
|
1830
|
-
// Observation must not break the provider stream
|
|
1778
|
+
// Observation must not break the provider stream.
|
|
1831
1779
|
}
|
|
1832
1780
|
}
|
|
1833
1781
|
return response;
|
|
@@ -1842,7 +1790,6 @@ export function createRoleRuntimeExtension(
|
|
|
1842
1790
|
collectorFirstDispatchDone = false;
|
|
1843
1791
|
receiptDelivery = createReceiptDeliveryPolicy();
|
|
1844
1792
|
noReceiptRecorded = false;
|
|
1845
|
-
observationFace.reset();
|
|
1846
1793
|
pendingNavigatorPresentation = undefined;
|
|
1847
1794
|
pendingNavigatorSettlement = undefined;
|
|
1848
1795
|
pendingInfrastructureFailures.clear();
|
package/src/sitian-appender.ts
CHANGED
|
@@ -353,7 +353,6 @@ export function appendSitianRecord(input: SitianRecordInput): RecordPointer {
|
|
|
353
353
|
identity,
|
|
354
354
|
...(input.subject === undefined ? {} : { subject: input.subject }),
|
|
355
355
|
...(input.sessionParent === undefined ? {} : { sessionParent: input.sessionParent }),
|
|
356
|
-
...(input.priorEventId === undefined ? {} : { priorEventId: input.priorEventId }),
|
|
357
356
|
timestamp,
|
|
358
357
|
host,
|
|
359
358
|
...(input.source === undefined ? {} : { source: input.source }),
|
package/src/sitian-contracts.ts
CHANGED
|
@@ -37,8 +37,6 @@ export type SitianRecord = {
|
|
|
37
37
|
readonly subject?: SitianSubject | undefined;
|
|
38
38
|
/** Parent session principal link / nesting origin. */
|
|
39
39
|
readonly sessionParent?: string | undefined;
|
|
40
|
-
/** Prior event identity in a submission ledger chain (S4; distinct from sessionParent). */
|
|
41
|
-
readonly priorEventId?: string | undefined;
|
|
42
40
|
readonly timestamp: string;
|
|
43
41
|
readonly host: string;
|
|
44
42
|
readonly source?: string | undefined;
|
|
@@ -65,7 +63,6 @@ export type SitianRecordInput = {
|
|
|
65
63
|
readonly sessionParent?: string | undefined;
|
|
66
64
|
/** Run owner for ticket provenance before a ticket is known. */
|
|
67
65
|
readonly runDirectory?: string | undefined;
|
|
68
|
-
readonly priorEventId?: string | undefined;
|
|
69
66
|
readonly timestamp?: string | undefined;
|
|
70
67
|
readonly host?: string | undefined;
|
|
71
68
|
readonly source?: string | undefined;
|
package/src/submission-ledger.ts
CHANGED
|
@@ -146,7 +146,7 @@ async function submissionRecordFile(cwd: string, runId: string, scope: Submissio
|
|
|
146
146
|
/**
|
|
147
147
|
* Discriminated owned-row view:
|
|
148
148
|
* - unknown run → file absent + empty owned (read APIs only)
|
|
149
|
-
* - located ledger → file is string;
|
|
149
|
+
* - located ledger → file is string; write consumers may build RecordPointer
|
|
150
150
|
*/
|
|
151
151
|
type OwnedSubmissionRecords =
|
|
152
152
|
| { readonly file: undefined; readonly owned: readonly [] }
|
|
@@ -491,11 +491,10 @@ export async function readLatestSubmissionOutcome(
|
|
|
491
491
|
return undefined;
|
|
492
492
|
}
|
|
493
493
|
|
|
494
|
-
type LedgerState = {
|
|
494
|
+
type LedgerState = { sequence: number };
|
|
495
495
|
|
|
496
496
|
async function restoreState(cwd: string, runId: string, scope: SubmissionLedgerReadScope): Promise<LedgerState> {
|
|
497
497
|
const located = await readOwnedSubmissionRecords(cwd, runId, scope);
|
|
498
|
-
// Unknown-run empty set: no prior chain. Owned rows without a file are an internal bug.
|
|
499
498
|
if (located.file === undefined) {
|
|
500
499
|
if (located.owned.length !== 0) {
|
|
501
500
|
throw new Error(
|
|
@@ -504,19 +503,8 @@ async function restoreState(cwd: string, runId: string, scope: SubmissionLedgerR
|
|
|
504
503
|
}
|
|
505
504
|
return { sequence: 0 };
|
|
506
505
|
}
|
|
507
|
-
const {
|
|
508
|
-
const last = owned.at(-1);
|
|
506
|
+
const { owned } = located;
|
|
509
507
|
return {
|
|
510
|
-
...(last === undefined
|
|
511
|
-
? {}
|
|
512
|
-
: {
|
|
513
|
-
prior: {
|
|
514
|
-
identity: last.identity,
|
|
515
|
-
recordFile: file,
|
|
516
|
-
kind: last.kind,
|
|
517
|
-
level: last.level,
|
|
518
|
-
},
|
|
519
|
-
}),
|
|
520
508
|
sequence: owned.reduce((maximum, record) => {
|
|
521
509
|
const payload = record.payload as Partial<SubmissionLedgerEvent> | undefined;
|
|
522
510
|
return payload?.type === "candidate" && typeof payload.sequence === "number"
|
|
@@ -547,7 +535,7 @@ function homeFromHostContext(context: HostContext, home?: string): string | unde
|
|
|
547
535
|
|
|
548
536
|
/**
|
|
549
537
|
* #959: seal one accepted submission without a model tool call.
|
|
550
|
-
* Same ledger row shape
|
|
538
|
+
* Same ledger row shape as the terminating-tool wrap.
|
|
551
539
|
* Used when a prose-exit seat (navigator) harvests the final assistant text.
|
|
552
540
|
*/
|
|
553
541
|
export async function sealAcceptedSubmission(options: {
|
|
@@ -561,15 +549,10 @@ export async function sealAcceptedSubmission(options: {
|
|
|
561
549
|
const attemptId = attemptIdentity(options.context, runId);
|
|
562
550
|
const sessionParent = sessionParentFromHostContext(options.context);
|
|
563
551
|
const home = homeFromHostContext(options.context, options.home);
|
|
564
|
-
|
|
565
|
-
...(home === undefined ? {} : { home }),
|
|
566
|
-
...(sessionParent === undefined ? {} : { sessionParent }),
|
|
567
|
-
});
|
|
568
|
-
const pointer = sitianReport({
|
|
552
|
+
sitianReport({
|
|
569
553
|
level: "event",
|
|
570
554
|
kind: "sealed",
|
|
571
555
|
subject: { runId, attemptId },
|
|
572
|
-
...(state.prior === undefined ? {} : { priorEventId: state.prior.identity }),
|
|
573
556
|
payload: {
|
|
574
557
|
type: "sealed",
|
|
575
558
|
attemptId,
|
|
@@ -582,7 +565,6 @@ export async function sealAcceptedSubmission(options: {
|
|
|
582
565
|
...(home !== undefined ? { home } : {}),
|
|
583
566
|
...(sessionParent === undefined ? {} : { sessionParent }),
|
|
584
567
|
});
|
|
585
|
-
state.prior = pointer;
|
|
586
568
|
}
|
|
587
569
|
|
|
588
570
|
/**
|
|
@@ -611,32 +593,29 @@ export function createSubmissionLedgerHost(
|
|
|
611
593
|
states.set(runId, pending);
|
|
612
594
|
return pending;
|
|
613
595
|
})();
|
|
614
|
-
const appendFor = (
|
|
596
|
+
const appendFor = (context: HostContext, runId: string, attemptId: string, event: SubmissionLedgerEvent): RecordPointer => {
|
|
615
597
|
const home = resolveHomeFromContext(context);
|
|
616
598
|
const sessionParent = sessionParentFromHostContext(context);
|
|
617
|
-
|
|
599
|
+
return sitianReport({
|
|
618
600
|
level: "event",
|
|
619
601
|
kind: event.type,
|
|
620
602
|
subject: { runId, attemptId },
|
|
621
|
-
...(state.prior === undefined ? {} : { priorEventId: state.prior.identity }),
|
|
622
603
|
payload: event,
|
|
623
604
|
source: "role-runtime",
|
|
624
605
|
cwd: context.cwd,
|
|
625
606
|
...(home !== undefined ? { home } : {}),
|
|
626
607
|
...(sessionParent === undefined ? {} : { sessionParent }),
|
|
627
608
|
});
|
|
628
|
-
state.prior = pointer;
|
|
629
|
-
return pointer;
|
|
630
609
|
};
|
|
631
610
|
|
|
632
611
|
host.on("turn_end", async (event, context) => {
|
|
633
612
|
try {
|
|
634
613
|
const runId = runIdentity(context);
|
|
635
614
|
const attemptId = attemptIdentity(context, runId);
|
|
636
|
-
const state = await stateFor(context, runId);
|
|
637
615
|
const calls = event.calls.map(({ toolCallId: id, toolName: name }) => ({ id, name }));
|
|
638
616
|
if (calls.length > 0) {
|
|
639
|
-
|
|
617
|
+
await stateFor(context, runId);
|
|
618
|
+
appendFor(context, runId, attemptId, { type: "roundContext", attemptId, calls });
|
|
640
619
|
}
|
|
641
620
|
} catch (error) {
|
|
642
621
|
failInfrastructure(error, context);
|
|
@@ -663,7 +642,7 @@ export function createSubmissionLedgerHost(
|
|
|
663
642
|
const runId = runIdentity(context);
|
|
664
643
|
const attemptId = attemptIdentity(context, runId);
|
|
665
644
|
const state = await stateFor(context, runId);
|
|
666
|
-
const append = (event: SubmissionLedgerEvent) => appendFor(
|
|
645
|
+
const append = (event: SubmissionLedgerEvent) => appendFor(context, runId, attemptId, event);
|
|
667
646
|
// #541 / #575: shared infra-declaration fail lives on the ledger seam.
|
|
668
647
|
// #641 chain②: seats may bounce a misdeclared infrastructure failure
|
|
669
648
|
// as correctable (2.1/2.2/2.3 keep paths).
|