kiokuko-dsh 0.1.21 → 0.1.23
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/client.cjs +23 -1
- package/dist/client.d.ts +9 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/dsh/boundary-worker.d.ts +8 -1
- package/dist/dsh/boundary-worker.d.ts.map +1 -1
- package/dist/dsh/boundary-worker.js +100 -22
- package/dist/dsh/boundary-worker.js.map +1 -1
- package/dist/dsh/completion-report.d.ts +25 -0
- package/dist/dsh/completion-report.d.ts.map +1 -0
- package/dist/dsh/completion-report.js +88 -0
- package/dist/dsh/completion-report.js.map +1 -0
- package/dist/dsh/continuation.d.ts +1 -0
- package/dist/dsh/continuation.d.ts.map +1 -1
- package/dist/dsh/continuation.js +19 -5
- package/dist/dsh/continuation.js.map +1 -1
- package/dist/dsh/enno-controller.d.ts +6 -0
- package/dist/dsh/enno-controller.d.ts.map +1 -1
- package/dist/dsh/enno-controller.js +42 -14
- package/dist/dsh/enno-controller.js.map +1 -1
- package/dist/dsh/host-adapter.d.ts.map +1 -1
- package/dist/dsh/host-adapter.js +365 -19
- package/dist/dsh/host-adapter.js.map +1 -1
- package/dist/dsh/loop-guard.d.ts +43 -0
- package/dist/dsh/loop-guard.d.ts.map +1 -0
- package/dist/dsh/loop-guard.js +206 -0
- package/dist/dsh/loop-guard.js.map +1 -0
- package/dist/dsh/tools.d.ts.map +1 -1
- package/dist/dsh/tools.js +41 -20
- package/dist/dsh/tools.js.map +1 -1
- package/dist/dsh/turn-process.d.ts +15 -1
- package/dist/dsh/turn-process.d.ts.map +1 -1
- package/dist/dsh/turn-process.js +69 -11
- package/dist/dsh/turn-process.js.map +1 -1
- package/dist/model-tools/registry.d.ts +6 -0
- package/dist/model-tools/registry.d.ts.map +1 -1
- package/dist/model-tools/registry.js +35 -0
- package/dist/model-tools/registry.js.map +1 -1
- package/docs/database.md +14 -0
- package/docs/dsh-plugin.md +24 -6
- package/migrations/004_dsh_loop_guard.sql +46 -0
- package/migrations/005_dsh_completion_recovery.sql +118 -0
- package/package.json +1 -1
- package/skills/kiokuko-enno-oduno/SKILL.md +1 -0
package/dist/client.cjs
CHANGED
|
@@ -198,9 +198,31 @@ window.__ModuleLoader__.load({
|
|
|
198
198
|
document.head.appendChild(style);
|
|
199
199
|
return () => style.remove();
|
|
200
200
|
}
|
|
201
|
-
const inject = ['slots', 'locale'];
|
|
201
|
+
const inject = ['slots', 'locale', 'uiConversation'];
|
|
202
|
+
/** A plugin-owned result in chat, never forged as a model assistant message. */
|
|
203
|
+
const completionReportDefinition = {
|
|
204
|
+
kind: 'kiokuko-completion-report', target: 'chat',
|
|
205
|
+
match: (event) => event.type === 'kiokuko/completion-report' && typeof event.data.reportId === 'string' && typeof event.data.text === 'string'
|
|
206
|
+
? { id: event.data.reportId, role: 'start' } : null,
|
|
207
|
+
start: (_context, match) => ({ seq: match.event.seq, text: match.event.data.text }),
|
|
208
|
+
update: (context) => context.state,
|
|
209
|
+
buildViewNode: (context) => context.state === undefined ? null : {
|
|
210
|
+
key: context.key, id: context.id, kind: 'kiokuko-completion-report', target: 'chat',
|
|
211
|
+
anchorSeq: context.state.seq, location: context.start?.location ?? { kind: 'session' },
|
|
212
|
+
visibility: 'visible', data: { text: context.state.text },
|
|
213
|
+
},
|
|
214
|
+
};
|
|
215
|
+
function CompletionReport(props) {
|
|
216
|
+
const node = props.node;
|
|
217
|
+
return jsx('section', { role: 'status', 'aria-live': 'polite',
|
|
218
|
+
style: { whiteSpace: 'pre-wrap', overflowWrap: 'anywhere', padding: '12px 0' }, children: node.data.text });
|
|
219
|
+
}
|
|
202
220
|
/** Register Kiokuko's streaming Session-export browser surface. */
|
|
203
221
|
function apply(ctx) {
|
|
222
|
+
ctx.uiConversation.events.register(completionReportDefinition);
|
|
223
|
+
ctx.slots.inject('conversation.chat.node', () => ctx.slots.register({
|
|
224
|
+
name: 'conversation.chat.node', key: 'kiokuko-completion-report', locale: LOCALE_NAMESPACE,
|
|
225
|
+
}, CompletionReport));
|
|
204
226
|
const controller = new SessionLogDownloadController();
|
|
205
227
|
ctx.effect(() => async () => controller.dispose(), 'kiokuko-dsh: browser download lifecycle');
|
|
206
228
|
ctx.effect(installStyle, 'kiokuko-dsh: browser download style');
|
package/dist/client.d.ts
CHANGED
|
@@ -14,6 +14,11 @@ export interface DshSessionDownloadOptions {
|
|
|
14
14
|
readonly window?: DshSessionDownloadWindow;
|
|
15
15
|
}
|
|
16
16
|
interface DshClientContext {
|
|
17
|
+
readonly uiConversation: {
|
|
18
|
+
readonly events: {
|
|
19
|
+
register(definition: unknown): unknown;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
17
22
|
readonly locale: {
|
|
18
23
|
register(namespace: string, dictionaries: Record<string, Record<string, string>>): unknown;
|
|
19
24
|
};
|
|
@@ -21,9 +26,10 @@ interface DshClientContext {
|
|
|
21
26
|
inject(name: string, register: () => unknown): unknown;
|
|
22
27
|
register(definition: {
|
|
23
28
|
readonly name: string;
|
|
24
|
-
readonly id
|
|
29
|
+
readonly id?: string;
|
|
30
|
+
readonly key?: string;
|
|
25
31
|
readonly locale: string;
|
|
26
|
-
readonly inject
|
|
32
|
+
readonly inject?: () => Record<string, unknown>;
|
|
27
33
|
}, component: (props: Record<string, unknown>) => unknown): unknown;
|
|
28
34
|
};
|
|
29
35
|
effect(setup: () => void | (() => void | Promise<void>), label: string): unknown;
|
|
@@ -33,7 +39,7 @@ interface DshClientContext {
|
|
|
33
39
|
}
|
|
34
40
|
/** Browser helper that never builds a whole-log Blob in application memory. */
|
|
35
41
|
export declare function downloadDshSessionLog(options: DshSessionDownloadOptions): Promise<'streamed' | 'navigated'>;
|
|
36
|
-
export declare const inject: readonly ["slots", "locale"];
|
|
42
|
+
export declare const inject: readonly ["slots", "locale", "uiConversation"];
|
|
37
43
|
/** Register Kiokuko's streaming Session-export browser surface. */
|
|
38
44
|
export declare function apply(ctx: DshClientContext): void;
|
|
39
45
|
export {};
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAKA,UAAU,wBAAwB;IAChC,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;QAAE,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,CAAC,CAAA;IAC7G,QAAQ,EAAE;QAAE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CACxC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,wBAAwB,CAAA;CAC3C;AAYD,UAAU,gBAAgB;IACxB,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,OAAO,CAAA;KAC3F,CAAA;IACD,QAAQ,CAAC,KAAK,EAAE;QACd,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,GAAG,OAAO,CAAA;QACtD,QAAQ,CACN,UAAU,EAAE;YACV,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;YACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAKA,UAAU,wBAAwB;IAChC,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;QAAE,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,CAAC,CAAA;IAC7G,QAAQ,EAAE;QAAE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CACxC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,wBAAwB,CAAA;CAC3C;AAYD,UAAU,gBAAgB;IACxB,QAAQ,CAAC,cAAc,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE;YAAE,QAAQ,CAAC,UAAU,EAAE,OAAO,GAAG,OAAO,CAAA;SAAE,CAAA;KAAE,CAAA;IACxF,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,OAAO,CAAA;KAC3F,CAAA;IACD,QAAQ,CAAC,KAAK,EAAE;QACd,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,GAAG,OAAO,CAAA;QACtD,QAAQ,CACN,UAAU,EAAE;YACV,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;YACrB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;YACpB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;YACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;YACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAChD,EACD,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,GACrD,OAAO,CAAA;KACX,CAAA;IACD,MAAM,CAAC,KAAK,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;IAChF,EAAE,CAAC,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAA;CACtI;AAuED,+EAA+E;AAC/E,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,UAAU,GAAG,WAAW,CAAC,CAqBjH;AAuHD,eAAO,MAAM,MAAM,gDAAiD,CAAA;AAwBpE,mEAAmE;AACnE,wBAAgB,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAsBjD"}
|
|
@@ -3,11 +3,15 @@ import { type DshBoundaryCompletion, type DshBoundaryJob, type DshContinuationOu
|
|
|
3
3
|
export interface DshBoundaryWorkerOptions {
|
|
4
4
|
readonly runtime: Pick<DshRuntime, 'withDatabase'>;
|
|
5
5
|
/** One bounded job stage. It must be idempotent under lease recovery. */
|
|
6
|
-
readonly process: (job: DshBoundaryJob) => DshBoundaryCompletion | PromiseLike<DshBoundaryCompletion>;
|
|
6
|
+
readonly process: (job: DshBoundaryJob, signal: AbortSignal) => DshBoundaryCompletion | PromiseLike<DshBoundaryCompletion>;
|
|
7
7
|
/** Native durability barrier. Failure is fail-closed for delivery only. */
|
|
8
8
|
readonly flush: (job: DshBoundaryJob) => void | PromiseLike<void>;
|
|
9
9
|
/** Enqueue one deterministic plugin-owned message into the native Agent. */
|
|
10
10
|
readonly dispatch: (job: DshBoundaryJob, item: DshContinuationOutboxItem) => void | PromiseLike<void>;
|
|
11
|
+
/** Last durable gate before native delivery. */
|
|
12
|
+
readonly beforeDelivery?: (job: DshBoundaryJob, item: DshContinuationOutboxItem, signal: AbortSignal) => 'deliver' | 'waiting_user' | 'superseded' | PromiseLike<'deliver' | 'waiting_user' | 'superseded'>;
|
|
13
|
+
/** Best-effort notification after retries are durably exhausted. Never retried by this worker. */
|
|
14
|
+
readonly onWaitingUser?: (job: DshBoundaryJob, error: unknown, signal: AbortSignal) => boolean | PromiseLike<boolean>;
|
|
11
15
|
readonly bindNativeAgent?: (sessionId: string, nativeAgent: object) => void;
|
|
12
16
|
readonly now?: () => string;
|
|
13
17
|
}
|
|
@@ -20,7 +24,10 @@ export declare class DshBoundaryWorker {
|
|
|
20
24
|
#private;
|
|
21
25
|
constructor(options: DshBoundaryWorkerOptions);
|
|
22
26
|
kick(sessionId?: string, nativeAgent?: object): void;
|
|
27
|
+
cancelSession(sessionId: string): void;
|
|
23
28
|
whenIdle(): Promise<void>;
|
|
24
29
|
dispose(): Promise<void>;
|
|
25
30
|
}
|
|
31
|
+
/** Uncooperative question adapters cannot hold shutdown or a newer user turn. */
|
|
32
|
+
export declare function abortable<T>(value: T | PromiseLike<T>, signal: AbortSignal): Promise<T>;
|
|
26
33
|
//# sourceMappingURL=boundary-worker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundary-worker.d.ts","sourceRoot":"","sources":["../../src/dsh/boundary-worker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,
|
|
1
|
+
{"version":3,"file":"boundary-worker.d.ts","sourceRoot":"","sources":["../../src/dsh/boundary-worker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAOL,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC/B,MAAM,mBAAmB,CAAA;AAE1B,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;IAClD,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,KAAK,qBAAqB,GAAG,WAAW,CAAC,qBAAqB,CAAC,CAAA;IAC1H,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;IACjE,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,yBAAyB,KAAK,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;IACrG,gDAAgD;IAChD,QAAQ,CAAC,cAAc,CAAC,EAAE,CACxB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,yBAAyB,EAC/B,MAAM,EAAE,WAAW,KAChB,SAAS,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,CAAC,SAAS,GAAG,cAAc,GAAG,YAAY,CAAC,CAAA;IACvG,kGAAkG;IAClG,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;IACrH,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3E,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CAC5B;AAED;;;;GAIG;AACH,qBAAa,iBAAiB;;gBAchB,OAAO,EAAE,wBAAwB;IAW7C,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAapD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAuGhC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAO/B;AAED,iFAAiF;AACjF,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAOvF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { withImmediateTransaction } from '../db/transaction.js';
|
|
3
|
-
import { claimBoundaryJobInTransaction, completeBoundaryJobInTransaction, failBoundaryJobInTransaction, markOutboxDispatchedInTransaction, readPendingOutbox, } from './turn-process.js';
|
|
3
|
+
import { claimBoundaryJobInTransaction, completeBoundaryJobInTransaction, failBoundaryJobInTransaction, markOutboxDispatchedInTransaction, readPendingOutbox, nextBoundaryWakeAt, } from './turn-process.js';
|
|
4
4
|
/**
|
|
5
5
|
* Durable, no-idle outbox driver. `agent/turn-stopping` only calls `kick`;
|
|
6
6
|
* confirmation, verification, advisory, context, and delivery run as separate
|
|
@@ -11,9 +11,12 @@ export class DshBoundaryWorker {
|
|
|
11
11
|
#process;
|
|
12
12
|
#flush;
|
|
13
13
|
#dispatch;
|
|
14
|
+
#beforeDelivery;
|
|
15
|
+
#onWaitingUser;
|
|
14
16
|
#now;
|
|
15
17
|
#bindNativeAgent;
|
|
16
|
-
#
|
|
18
|
+
#tails = new Map();
|
|
19
|
+
#controllers = new Map();
|
|
17
20
|
#disposed = false;
|
|
18
21
|
#retryTimers = new Map();
|
|
19
22
|
constructor(options) {
|
|
@@ -21,6 +24,8 @@ export class DshBoundaryWorker {
|
|
|
21
24
|
this.#process = options.process;
|
|
22
25
|
this.#flush = options.flush;
|
|
23
26
|
this.#dispatch = options.dispatch;
|
|
27
|
+
this.#beforeDelivery = options.beforeDelivery;
|
|
28
|
+
this.#onWaitingUser = options.onWaitingUser;
|
|
24
29
|
this.#bindNativeAgent = options.bindNativeAgent;
|
|
25
30
|
this.#now = options.now ?? (() => new Date().toISOString());
|
|
26
31
|
}
|
|
@@ -31,12 +36,17 @@ export class DshBoundaryWorker {
|
|
|
31
36
|
this.#bindNativeAgent?.(sessionId, nativeAgent);
|
|
32
37
|
if (sessionId === undefined)
|
|
33
38
|
return;
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.#
|
|
38
|
-
}
|
|
39
|
-
this.#
|
|
39
|
+
const tail = (this.#tails.get(sessionId) ?? Promise.resolve())
|
|
40
|
+
.then(() => this.#drain(sessionId)).catch(() => {
|
|
41
|
+
// A failed claim must not permanently lose the durable wake-up.
|
|
42
|
+
this.#scheduleRetry(sessionId, new Date(Date.parse(this.#now()) + 1_000).toISOString());
|
|
43
|
+
});
|
|
44
|
+
this.#tails.set(sessionId, tail);
|
|
45
|
+
void tail.finally(() => { if (this.#tails.get(sessionId) === tail)
|
|
46
|
+
this.#tails.delete(sessionId); });
|
|
47
|
+
}
|
|
48
|
+
cancelSession(sessionId) {
|
|
49
|
+
this.#controllers.get(sessionId)?.abort(new Error('Boundary superseded or disposed'));
|
|
40
50
|
}
|
|
41
51
|
#scheduleRetry(sessionId, retryAt) {
|
|
42
52
|
if (this.#disposed)
|
|
@@ -56,8 +66,30 @@ export class DshBoundaryWorker {
|
|
|
56
66
|
while (!this.#disposed) {
|
|
57
67
|
const ownerNonce = randomUUID();
|
|
58
68
|
const job = await this.#runtime.withDatabase((database) => withImmediateTransaction(database, () => (claimBoundaryJobInTransaction(database, ownerNonce, this.#now(), sessionId))));
|
|
59
|
-
|
|
69
|
+
// Disposal can race the asynchronous claim before a controller exists.
|
|
70
|
+
// Leave the durable lease recoverable; never start new work after shutdown.
|
|
71
|
+
if (this.#disposed)
|
|
60
72
|
return;
|
|
73
|
+
if (job === undefined) {
|
|
74
|
+
const next = await this.#runtime.withDatabase(database => nextBoundaryWakeAt(database, sessionId));
|
|
75
|
+
if (next !== undefined)
|
|
76
|
+
this.#scheduleRetry(sessionId, next);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const controller = new AbortController();
|
|
80
|
+
const { signal } = controller;
|
|
81
|
+
this.#controllers.set(sessionId, controller);
|
|
82
|
+
// User questions can outlive a job lease. Renew only while we own it.
|
|
83
|
+
const heartbeat = setInterval(() => {
|
|
84
|
+
void this.#runtime.withDatabase(database => {
|
|
85
|
+
const changed = database.prepare(`UPDATE dsh_boundary_jobs SET lease_expires_at = ?
|
|
86
|
+
WHERE job_id = ? AND status = 'processing' AND owner_nonce = ? RETURNING job_id`)
|
|
87
|
+
.get(new Date(Date.parse(this.#now()) + 60_000).toISOString(), job.jobId, job.ownerNonce);
|
|
88
|
+
if (changed === undefined)
|
|
89
|
+
controller.abort(new Error('Boundary lease lost'));
|
|
90
|
+
}).catch(error => controller.abort(error));
|
|
91
|
+
}, 20_000);
|
|
92
|
+
heartbeat.unref?.();
|
|
61
93
|
try {
|
|
62
94
|
let completion;
|
|
63
95
|
if (job.kind === 'delivery') {
|
|
@@ -67,45 +99,91 @@ export class DshBoundaryWorker {
|
|
|
67
99
|
completion = { kind: 'superseded' };
|
|
68
100
|
}
|
|
69
101
|
else {
|
|
70
|
-
await this.#
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
102
|
+
const gate = await abortable(this.#beforeDelivery?.(job, outbox, signal) ?? 'deliver', signal);
|
|
103
|
+
if (gate !== 'deliver') {
|
|
104
|
+
completion = { kind: gate };
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
await this.#flush(job);
|
|
108
|
+
signal.throwIfAborted();
|
|
109
|
+
const delivered = await this.#runtime.withDatabase(async (database) => {
|
|
110
|
+
const owned = database.prepare(`SELECT job_id FROM dsh_boundary_jobs
|
|
111
|
+
WHERE job_id = ? AND status = 'processing' AND owner_nonce = ?`).get(job.jobId, job.ownerNonce);
|
|
112
|
+
const fresh = readPendingOutbox(database, job.dshSessionId).find(item => item.receiptId === job.receiptId);
|
|
113
|
+
if (!owned || !fresh || signal.aborted)
|
|
114
|
+
return false;
|
|
115
|
+
// No await between the last authoritative check and native enqueue.
|
|
116
|
+
await this.#dispatch(job, fresh);
|
|
117
|
+
markOutboxDispatchedInTransaction(database, fresh.continuationId, this.#now());
|
|
118
|
+
return true;
|
|
119
|
+
});
|
|
120
|
+
completion = { kind: delivered ? 'completed' : 'superseded' };
|
|
121
|
+
}
|
|
76
122
|
}
|
|
77
123
|
}
|
|
78
124
|
else {
|
|
79
|
-
completion = await this.#process(job);
|
|
125
|
+
completion = await abortable(this.#process(job, signal), signal);
|
|
80
126
|
}
|
|
81
127
|
await this.#runtime.withDatabase((database) => withImmediateTransaction(database, () => {
|
|
82
128
|
completeBoundaryJobInTransaction(database, job, completion, this.#now());
|
|
83
129
|
}));
|
|
84
130
|
}
|
|
85
131
|
catch (error) {
|
|
86
|
-
|
|
132
|
+
if (signal.aborted)
|
|
133
|
+
return;
|
|
134
|
+
let failure;
|
|
87
135
|
try {
|
|
88
136
|
await this.#runtime.withDatabase((database) => withImmediateTransaction(database, () => {
|
|
89
|
-
|
|
137
|
+
failure = failBoundaryJobInTransaction(database, job, error, this.#now());
|
|
90
138
|
}));
|
|
91
139
|
}
|
|
92
140
|
catch {
|
|
93
141
|
// A Core DB failure cannot be repaired in-memory. The expired lease
|
|
94
142
|
// is the recovery mechanism on the next kick/startup.
|
|
95
143
|
}
|
|
96
|
-
if (
|
|
97
|
-
this.#scheduleRetry(job.dshSessionId, retryAt);
|
|
144
|
+
if (failure?.kind === 'retry')
|
|
145
|
+
this.#scheduleRetry(job.dshSessionId, failure.retryAt);
|
|
146
|
+
if (failure?.kind === 'waiting_user') {
|
|
147
|
+
clearInterval(heartbeat);
|
|
148
|
+
try {
|
|
149
|
+
if (await abortable(this.#onWaitingUser?.(job, error, signal) ?? false, signal))
|
|
150
|
+
this.kick(job.dshSessionId);
|
|
151
|
+
}
|
|
152
|
+
catch { /* durable wait is authoritative */ }
|
|
153
|
+
}
|
|
98
154
|
return;
|
|
99
155
|
}
|
|
156
|
+
finally {
|
|
157
|
+
clearInterval(heartbeat);
|
|
158
|
+
if (this.#controllers.get(sessionId) === controller)
|
|
159
|
+
this.#controllers.delete(sessionId);
|
|
160
|
+
}
|
|
100
161
|
}
|
|
101
162
|
}
|
|
102
|
-
async whenIdle() {
|
|
163
|
+
async whenIdle() {
|
|
164
|
+
while (this.#tails.size > 0)
|
|
165
|
+
await Promise.all([...this.#tails.values()]);
|
|
166
|
+
}
|
|
103
167
|
async dispose() {
|
|
104
168
|
this.#disposed = true;
|
|
169
|
+
for (const controller of this.#controllers.values())
|
|
170
|
+
controller.abort(new Error('Boundary worker disposed'));
|
|
105
171
|
for (const timer of this.#retryTimers.values())
|
|
106
172
|
clearTimeout(timer);
|
|
107
173
|
this.#retryTimers.clear();
|
|
108
|
-
await this
|
|
174
|
+
await this.whenIdle();
|
|
109
175
|
}
|
|
110
176
|
}
|
|
177
|
+
/** Uncooperative question adapters cannot hold shutdown or a newer user turn. */
|
|
178
|
+
export function abortable(value, signal) {
|
|
179
|
+
return new Promise((resolve, reject) => {
|
|
180
|
+
const aborted = () => reject(signal.reason);
|
|
181
|
+
if (signal.aborted) {
|
|
182
|
+
reject(signal.reason);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
signal.addEventListener('abort', aborted, { once: true });
|
|
186
|
+
Promise.resolve(value).then(resolve, reject).finally(() => signal.removeEventListener('abort', aborted));
|
|
187
|
+
});
|
|
188
|
+
}
|
|
111
189
|
//# sourceMappingURL=boundary-worker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundary-worker.js","sourceRoot":"","sources":["../../src/dsh/boundary-worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAE/D,OAAO,EACL,6BAA6B,EAC7B,gCAAgC,EAChC,4BAA4B,EAC5B,iCAAiC,EACjC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"boundary-worker.js","sourceRoot":"","sources":["../../src/dsh/boundary-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DshRuntime } from './runtime.js';
|
|
2
|
+
import type { DshLogEvent } from './session-memory-finalizer.js';
|
|
3
|
+
import type { EnnoRunSnapshot } from '../enno-oduno/types.js';
|
|
4
|
+
export declare const DSH_COMPLETION_REPORT_EVENT = "kiokuko/completion-report";
|
|
5
|
+
interface ReportSession {
|
|
6
|
+
readonly id: string;
|
|
7
|
+
snapshotEvents(): readonly DshLogEvent[];
|
|
8
|
+
append(type: string, data: unknown, options: {
|
|
9
|
+
ignorable: true;
|
|
10
|
+
}): {
|
|
11
|
+
seq: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Recorded facts only; a missing model response is never interpreted as failed implementation. */
|
|
15
|
+
export declare function completionReportText(snapshot: EnnoRunSnapshot): string;
|
|
16
|
+
/** Flush-before-ack outbox. Native event identity makes crash replay harmless. */
|
|
17
|
+
export declare class DshCompletionReporter {
|
|
18
|
+
#private;
|
|
19
|
+
private readonly runtime;
|
|
20
|
+
private readonly flush;
|
|
21
|
+
constructor(runtime: Pick<DshRuntime, 'withDatabase'>, flush: (session: object) => PromiseLike<unknown>);
|
|
22
|
+
deliver(session: ReportSession): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=completion-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion-report.d.ts","sourceRoot":"","sources":["../../src/dsh/completion-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAI7D,eAAO,MAAM,2BAA2B,8BAA8B,CAAA;AAEtE,UAAU,aAAa;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,cAAc,IAAI,SAAS,WAAW,EAAE,CAAA;IACxC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;QAAE,SAAS,EAAE,IAAI,CAAA;KAAE,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CACnF;AAMD,mGAAmG;AACnG,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAiBtE;AAED,kFAAkF;AAClF,qBAAa,qBAAqB;;IAEpB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAoC,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAjE,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,EAAmB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,CAAC,OAAO,CAAC;IAEzI,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CA8C/C"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { readEnnoSnapshot } from '../enno-oduno/store.js';
|
|
2
|
+
import { canonicalContentHash } from '../serialization/validate.js';
|
|
3
|
+
export const DSH_COMPLETION_REPORT_EVENT = 'kiokuko/completion-report';
|
|
4
|
+
function record(value) {
|
|
5
|
+
return typeof value === 'object' && value !== null ? value : undefined;
|
|
6
|
+
}
|
|
7
|
+
/** Recorded facts only; a missing model response is never interpreted as failed implementation. */
|
|
8
|
+
export function completionReportText(snapshot) {
|
|
9
|
+
const ja = snapshot.userFacingLanguage === 'ja';
|
|
10
|
+
const done = snapshot.status === 'completed';
|
|
11
|
+
const heading = ja ? (done ? '依頼された作業は完了しました。' : '作業は未完了のまま停止しました。')
|
|
12
|
+
: (done ? 'The requested work is complete.' : 'Work stopped before completion.');
|
|
13
|
+
const lines = [heading, '', ja ? '記録済みの作業結果:' : 'Recorded work results:'];
|
|
14
|
+
for (const unit of snapshot.workUnits) {
|
|
15
|
+
lines.push(`- ${unit.workUnit.objective}: ${unit.status}${unit.result?.summary ? ` — ${unit.result.summary}` : ''}`);
|
|
16
|
+
if (unit.result?.changedPaths.length)
|
|
17
|
+
lines.push(` ${unit.result.changedPaths.join(', ')}`);
|
|
18
|
+
}
|
|
19
|
+
lines.push('', ja ? '最終検証:' : 'Final verification:');
|
|
20
|
+
for (const check of snapshot.finalEvidence)
|
|
21
|
+
lines.push(`- ${check.verifier.id}: ${check.status}`);
|
|
22
|
+
if (!snapshot.finalEvidence.length)
|
|
23
|
+
lines.push(ja ? '- 記録なし。検証成功とは判定していません。' : '- No recorded results; verification success is not assumed.');
|
|
24
|
+
if (snapshot.blocker)
|
|
25
|
+
lines.push('', snapshot.blocker);
|
|
26
|
+
if (snapshot.meditation)
|
|
27
|
+
lines.push('', snapshot.meditation.summary);
|
|
28
|
+
lines.push('', ja ? '最終回答が表示されなかったため、ホストの記録から結果を表示しています。' : 'The final response was missing; this report is provided from host records.');
|
|
29
|
+
return lines.join('\n').slice(0, 32_768);
|
|
30
|
+
}
|
|
31
|
+
/** Flush-before-ack outbox. Native event identity makes crash replay harmless. */
|
|
32
|
+
export class DshCompletionReporter {
|
|
33
|
+
runtime;
|
|
34
|
+
flush;
|
|
35
|
+
#active = new Map();
|
|
36
|
+
constructor(runtime, flush) {
|
|
37
|
+
this.runtime = runtime;
|
|
38
|
+
this.flush = flush;
|
|
39
|
+
}
|
|
40
|
+
deliver(session) {
|
|
41
|
+
const existing = this.#active.get(session.id);
|
|
42
|
+
if (existing)
|
|
43
|
+
return existing;
|
|
44
|
+
const done = this.#deliver(session).finally(() => this.#active.delete(session.id));
|
|
45
|
+
this.#active.set(session.id, done);
|
|
46
|
+
return done;
|
|
47
|
+
}
|
|
48
|
+
async #deliver(session) {
|
|
49
|
+
const pending = await this.runtime.withDatabase(database => database.prepare(`
|
|
50
|
+
SELECT report.run_id AS runId, report.native_turn AS nativeTurn,
|
|
51
|
+
contract.workspace, contract.orchestration_session_id AS orchestrationId
|
|
52
|
+
FROM dsh_completion_reports AS report JOIN enno_contracts AS contract ON contract.run_id = report.run_id
|
|
53
|
+
WHERE report.dsh_session_id = ? AND report.status = 'pending' ORDER BY report.native_turn
|
|
54
|
+
`).all(session.id));
|
|
55
|
+
for (const item of pending) {
|
|
56
|
+
const id = canonicalContentHash({ runId: item.runId, kind: DSH_COMPLETION_REPORT_EVENT });
|
|
57
|
+
const events = session.snapshotEvents();
|
|
58
|
+
const resultIndex = events.findIndex(event => event.type === 'tool/result' && record(event.data)?.turn === item.nativeTurn
|
|
59
|
+
&& JSON.stringify(event.data).includes('ennoOduno'));
|
|
60
|
+
let delivered = events.find(event => event.type === DSH_COMPLETION_REPORT_EVENT && record(event.data)?.reportId === id);
|
|
61
|
+
if (!delivered && resultIndex >= 0)
|
|
62
|
+
delivered = events.slice(resultIndex + 1).find(event => {
|
|
63
|
+
const data = record(event.data);
|
|
64
|
+
const message = record(data?.message);
|
|
65
|
+
return event.type === 'assistant/message' && data?.turn === item.nativeTurn && data?.interrupted !== true
|
|
66
|
+
&& Array.isArray(message?.content) && message.content.some(block => {
|
|
67
|
+
const value = record(block);
|
|
68
|
+
return value?.type === 'text' && typeof value.text === 'string' && value.text.trim().length > 0;
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
let seq = delivered?.seq;
|
|
72
|
+
if (seq === undefined) {
|
|
73
|
+
const snapshot = await this.runtime.withDatabase(database => readEnnoSnapshot(database, item));
|
|
74
|
+
// Re-read after the DB await: another native callback may have published the same report.
|
|
75
|
+
const replay = session.snapshotEvents().find(event => event.type === DSH_COMPLETION_REPORT_EVENT && record(event.data)?.reportId === id);
|
|
76
|
+
seq = replay?.seq ?? session.append(DSH_COMPLETION_REPORT_EVENT, {
|
|
77
|
+
reportId: id, text: completionReportText(snapshot), source: { kind: 'plugin', plugin: 'kiokuko-dsh' },
|
|
78
|
+
}, { ignorable: true }).seq;
|
|
79
|
+
}
|
|
80
|
+
await this.flush(session);
|
|
81
|
+
await this.runtime.withDatabase(database => {
|
|
82
|
+
database.prepare(`UPDATE dsh_completion_reports SET status = 'delivered', delivered_seq = ? WHERE run_id = ?`)
|
|
83
|
+
.run(seq, item.runId);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=completion-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion-report.js","sourceRoot":"","sources":["../../src/dsh/completion-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ export interface DshExactResumeExpectation {
|
|
|
10
10
|
}
|
|
11
11
|
export interface DshResumeDecision {
|
|
12
12
|
readonly continue: boolean;
|
|
13
|
+
readonly waitingUser?: boolean;
|
|
13
14
|
readonly runId: string | null;
|
|
14
15
|
readonly status: EnnoOdunoState['status'] | null;
|
|
15
16
|
readonly directive: RoleDirective | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continuation.d.ts","sourceRoot":"","sources":["../../src/dsh/continuation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,kBAAkB,CAAA;AAYjE,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACd,aAAa,EACd,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"continuation.d.ts","sourceRoot":"","sources":["../../src/dsh/continuation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAa,MAAM,kBAAkB,CAAA;AAYjE,OAAO,KAAK,EACV,kBAAkB,EAClB,cAAc,EACd,aAAa,EACd,MAAM,wBAAwB,CAAA;AAG/B,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,sBAAsB,EAAE,IAAI,CAAA;CACtC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAA;IAChD,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAA;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,QAAQ,CAAC,cAAc,EAAE,kBAAkB,GAAG,IAAI,CAAA;CACnD;AAmOD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,cAAc,EACxB,QAAQ,EAAE,OAAO,EACjB,WAAW,CAAC,EAAE,MAAM,GAAG,yBAAyB,GAC/C,iBAAiB,CA4DnB"}
|
package/dist/dsh/continuation.js
CHANGED
|
@@ -7,9 +7,11 @@ import { canonicalContentHash } from '../serialization/validate.js';
|
|
|
7
7
|
import { directiveForRun } from '../enno-oduno/directives.js';
|
|
8
8
|
import { PLAN_START_RECOVERY_BLOCKER_PREFIX } from '../enno-oduno/plan-recovery.js';
|
|
9
9
|
import { appendEnnoEventInTransaction, claimExecutionLeaseInTransaction, readEnnoSnapshot, } from '../enno-oduno/store.js';
|
|
10
|
+
import { claimAutomaticContinuationInTransaction, ennoInstructionDigest } from './loop-guard.js';
|
|
10
11
|
const inputSchema = z.object({
|
|
11
12
|
dshSessionId: z.string().min(1).max(256),
|
|
12
13
|
cwd: z.string().min(1).max(4_096),
|
|
14
|
+
claimId: z.string().regex(/^[0-9a-f]{64}$/u).optional(),
|
|
13
15
|
}).strict();
|
|
14
16
|
function candidates(database, repositoryRoot, dshSessionId, expectedRunId) {
|
|
15
17
|
return database.prepare(`
|
|
@@ -169,25 +171,37 @@ export function decideDshContinuation(database, rawInput, expectedRun) {
|
|
|
169
171
|
const directive = directiveForRun(snapshot);
|
|
170
172
|
if (directive === null)
|
|
171
173
|
throw new KiokukoError('INTEGRITY_ERROR', 'Enno active run has no role directive');
|
|
172
|
-
const
|
|
174
|
+
const loopClaim = parsed.data.claimId !== undefined
|
|
175
|
+
? claimAutomaticContinuationInTransaction(database, {
|
|
176
|
+
claimId: parsed.data.claimId,
|
|
177
|
+
runId: snapshot.runId,
|
|
178
|
+
dshSessionId: parsed.data.dshSessionId,
|
|
179
|
+
instructionDigest: ennoInstructionDigest(snapshot, directive),
|
|
180
|
+
})
|
|
181
|
+
: null;
|
|
182
|
+
const legacyClaimed = loopClaim?.decision === 'wait_user' || loopClaim?.replayed === true
|
|
183
|
+
? true
|
|
184
|
+
: claimContinuation(database, snapshot, canonicalContentHash(directive));
|
|
185
|
+
const claimed = legacyClaimed && (loopClaim === null || loopClaim.decision === 'deliver');
|
|
173
186
|
const resumeToken = claimed ? issueResumeToken(database, snapshot) : null;
|
|
174
187
|
const executionLease = claimed && directive.role === 'goki' && directive.workUnit !== null
|
|
175
188
|
? claimExecutionLeaseInTransaction(database, snapshot, directive.workUnit.id, { dshSessionId: parsed.data.dshSessionId })
|
|
176
189
|
: null;
|
|
177
|
-
return { kind: 'continuation', snapshot, directive, claimed, resumeToken, executionLease };
|
|
190
|
+
return { kind: 'continuation', snapshot, directive, claimed, loopClaim, resumeToken, executionLease };
|
|
178
191
|
});
|
|
179
192
|
if (continuation.kind === 'none') {
|
|
180
|
-
return { continue: false, runId: null, status: null, directive: null, reason: null, warning: null, resumeToken: null, routeEpoch: null, executionLease: null };
|
|
193
|
+
return { continue: false, waitingUser: false, runId: null, status: null, directive: null, reason: null, warning: null, resumeToken: null, routeEpoch: null, executionLease: null };
|
|
181
194
|
}
|
|
182
195
|
if (continuation.kind === 'ambiguous') {
|
|
183
|
-
return { continue: false, runId: null, status: null, directive: null, reason: null, warning: 'Multiple Enno-Oduno runs match this DSH repository; refusing to guess.', resumeToken: null, routeEpoch: null, executionLease: null };
|
|
196
|
+
return { continue: false, waitingUser: false, runId: null, status: null, directive: null, reason: null, warning: 'Multiple Enno-Oduno runs match this DSH repository; refusing to guess.', resumeToken: null, routeEpoch: null, executionLease: null };
|
|
184
197
|
}
|
|
185
198
|
const { snapshot } = continuation;
|
|
186
199
|
if (!continuation.claimed) {
|
|
187
|
-
return { continue: false, runId: snapshot.runId, status: snapshot.status, directive: null, reason: null, warning: 'Enno-Oduno continuation limit reached for this DSH session.', resumeToken: null, routeEpoch: snapshot.routeEpoch ?? 0, executionLease: null };
|
|
200
|
+
return { continue: false, waitingUser: continuation.loopClaim?.decision === 'wait_user', runId: snapshot.runId, status: snapshot.status, directive: null, reason: null, warning: 'Enno-Oduno continuation limit reached for this DSH session.', resumeToken: null, routeEpoch: snapshot.routeEpoch ?? 0, executionLease: null };
|
|
188
201
|
}
|
|
189
202
|
return {
|
|
190
203
|
continue: true,
|
|
204
|
+
waitingUser: false,
|
|
191
205
|
runId: snapshot.runId,
|
|
192
206
|
status: snapshot.status,
|
|
193
207
|
directive: continuation.directive,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continuation.js","sourceRoot":"","sources":["../../src/dsh/continuation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAA;AAE3B,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAC7D,OAAO,EAAE,kCAAkC,EAAE,MAAM,gCAAgC,CAAA;AACnF,OAAO,EACL,4BAA4B,EAC5B,gCAAgC,EAChC,gBAAgB,GACjB,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"continuation.js","sourceRoot":"","sources":["../../src/dsh/continuation.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,6 +35,12 @@ export interface DshEnnoControllerDependencies {
|
|
|
35
35
|
readonly state: EnnoOdunoState;
|
|
36
36
|
}) => void | PromiseLike<void>;
|
|
37
37
|
readonly maxSteersPerDirective?: number;
|
|
38
|
+
/** Optional legacy-controller recovery prompt after three unchanged turns. */
|
|
39
|
+
readonly requestLoopRecovery?: (input: {
|
|
40
|
+
readonly event: DshTurnStoppingEvent;
|
|
41
|
+
readonly state: EnnoOdunoState;
|
|
42
|
+
readonly automaticCount: number;
|
|
43
|
+
}) => string | undefined | PromiseLike<string | undefined>;
|
|
38
44
|
readonly advisoryRunner?: DshAdvisoryRunner;
|
|
39
45
|
readonly submitAdvisory?: (result: DshAdvisoryRoundResult, input: {
|
|
40
46
|
readonly event: DshTurnStoppingEvent;
|