kiokuko-dsh 0.1.26 → 0.1.28

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.
@@ -2,6 +2,7 @@ import { Context } from '@deepseek-ai/cordis';
2
2
  import { KIOKUKO_DSH_HOST_SERVICE, type DshCompositionHost } from './composition.js';
3
3
  import { type DshLlm, type DshSessionQuery } from './session-memory-finalizer.js';
4
4
  import { type DshAdvisoryCall } from './advisory-runner.js';
5
+ import { type EnnoNextAction } from '../enno-oduno/types.js';
5
6
  export interface DshAdvisoryHost {
6
7
  readonly verifyReadOnly: (call: DshAdvisoryCall) => boolean | PromiseLike<boolean>;
7
8
  readonly execute: (call: DshAdvisoryCall) => Promise<unknown>;
@@ -23,6 +24,10 @@ export interface DshHostAdapter {
23
24
  readonly host: DshCompositionHost;
24
25
  readonly dispose: () => Promise<void>;
25
26
  }
27
+ export declare function pluginContinuationId(value: unknown): string | undefined;
28
+ export declare function recoveryMessage(continuationId: string, answer: string): unknown;
29
+ export declare function eventContinuationId(data: unknown): string | undefined;
30
+ export declare function continuationMessage(continuationId: string, nextAction: EnnoNextAction): unknown;
26
31
  export declare function createDshHostAdapter(ctx: Context, options?: DshHostAdapterOptions): DshHostAdapter;
27
32
  export { KIOKUKO_DSH_HOST_SERVICE };
28
33
  //# sourceMappingURL=host-adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host-adapter.d.ts","sourceRoot":"","sources":["../../src/dsh/host-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EACL,wBAAwB,EACxB,KAAK,kBAAkB,EAExB,MAAM,kBAAkB,CAAA;AAkBzB,OAAO,EAA0C,KAAK,MAAM,EAAgD,KAAK,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAEvK,OAAO,EAAqB,KAAK,eAAe,EAA+B,MAAM,sBAAsB,CAAA;AAoG3G,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;IAClF,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC9D;AAMD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe,CAAA;IACvC,oEAAoE;IACpE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAA;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAmOD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,qBAA0B,GAAG,cAAc,CA8xDtG;AAsBD,OAAO,EAAE,wBAAwB,EAAE,CAAA"}
1
+ {"version":3,"file":"host-adapter.d.ts","sourceRoot":"","sources":["../../src/dsh/host-adapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EACL,wBAAwB,EACxB,KAAK,kBAAkB,EAExB,MAAM,kBAAkB,CAAA;AAkBzB,OAAO,EAA0C,KAAK,MAAM,EAAgD,KAAK,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAEvK,OAAO,EAAqB,KAAK,eAAe,EAA+B,MAAM,sBAAsB,CAAA;AAiB3G,OAAO,EAAuD,KAAK,cAAc,EAAuB,MAAM,wBAAwB,CAAA;AAmFtI,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;IAClF,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC9D;AAMD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IACrC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe,CAAA;IACvC,oEAAoE;IACpE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,eAAe,CAAA;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACtC;AAoED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAWvE;AAOD,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAU/E;AAsBD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAKrE;AAED,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,OAAO,CAU/F;AAiGD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,qBAA0B,GAAG,cAAc,CA+yDtG;AAsBD,OAAO,EAAE,wBAAwB,EAAE,CAAA"}
@@ -95,21 +95,26 @@ function isHumanMessage(value) {
95
95
  const source = objectRecord(message?.source);
96
96
  return source?.kind === 'user';
97
97
  }
98
- function pluginContinuationId(value) {
98
+ const CONTINUATION_ID = /^[0-9a-f]{64}$/u;
99
+ export function pluginContinuationId(value) {
99
100
  const message = objectRecord(value);
100
101
  const source = objectRecord(message?.source);
101
- if (source?.kind !== 'plugin' || source.plugin !== 'kiokuko-dsh'
102
- || (source.form !== 'continuation' && source.form !== 'loop-recovery'))
102
+ if (source?.kind !== 'plugin' || source.plugin !== 'kiokuko-dsh')
103
103
  return undefined;
104
- return typeof source.deliveryId === 'string' && /^[0-9a-f]{64}$/u.test(source.deliveryId)
105
- ? source.deliveryId
106
- : undefined;
104
+ const messageId = message?.id;
105
+ if (source.form === 'instructions' && typeof messageId === 'string' && CONTINUATION_ID.test(messageId)) {
106
+ return messageId;
107
+ }
108
+ if ((source.form !== 'continuation' && source.form !== 'loop-recovery' && source.form !== 'instructions')
109
+ || typeof source.deliveryId !== 'string' || !CONTINUATION_ID.test(source.deliveryId))
110
+ return undefined;
111
+ return source.deliveryId;
107
112
  }
108
113
  function isLoopRecoveryMessage(value) {
109
114
  const source = objectRecord(objectRecord(value)?.source);
110
115
  return source?.kind === 'plugin' && source.plugin === 'kiokuko-dsh' && source.form === 'loop-recovery';
111
116
  }
112
- function recoveryMessage(continuationId, answer) {
117
+ export function recoveryMessage(continuationId, answer) {
113
118
  return Object.freeze({
114
119
  id: continuationId,
115
120
  role: 'user',
@@ -117,7 +122,7 @@ function recoveryMessage(continuationId, answer) {
117
122
  type: 'text',
118
123
  text: `The user reviewed the stopped Kiokuko loop and supplied this recovery instruction:\n\n${answer}`,
119
124
  }],
120
- source: { kind: 'plugin', plugin: 'kiokuko-dsh', form: 'loop-recovery', deliveryId: continuationId },
125
+ source: { kind: 'plugin', plugin: 'kiokuko-dsh', form: 'instructions' },
121
126
  });
122
127
  }
123
128
  function boundedMessageText(value) {
@@ -141,14 +146,14 @@ function boundedUtf8Text(value, maximumBytes) {
141
146
  }
142
147
  return result;
143
148
  }
144
- function eventContinuationId(data) {
149
+ export function eventContinuationId(data) {
145
150
  const direct = pluginContinuationId(data);
146
151
  if (direct !== undefined)
147
152
  return direct;
148
153
  const record = objectRecord(data);
149
154
  return pluginContinuationId(record?.message);
150
155
  }
151
- function continuationMessage(continuationId, nextAction) {
156
+ export function continuationMessage(continuationId, nextAction) {
152
157
  const work = nextAction === 'execute_work_unit'
153
158
  ? 'The current WorkUnit is not accepted unless the latest Enno result says so. Correct or report only that WorkUnit.'
154
159
  : `Continue only the current Kiokuko phase for nextAction=${nextAction}. Do not skip ahead.`;
@@ -156,7 +161,7 @@ function continuationMessage(continuationId, nextAction) {
156
161
  id: continuationId,
157
162
  role: 'user',
158
163
  content: [{ type: 'text', text: work }],
159
- source: { kind: 'plugin', plugin: 'kiokuko-dsh', form: 'continuation', deliveryId: continuationId },
164
+ source: { kind: 'plugin', plugin: 'kiokuko-dsh', form: 'instructions' },
160
165
  });
161
166
  }
162
167
  function phaseForState(state) {
@@ -842,7 +847,17 @@ export function createDshHostAdapter(ctx, options = {}) {
842
847
  terminalizeLedgerRunInTransaction(database, runId, 'cancelled');
843
848
  return undefined;
844
849
  }
845
- const automaticMessage = event.nativeMessages?.find((message) => pluginContinuationId(message) !== undefined && !isLoopRecoveryMessage(message));
850
+ const automaticMessage = event.nativeMessages?.find((message) => {
851
+ const continuationId = pluginContinuationId(message);
852
+ if (continuationId === undefined)
853
+ return false;
854
+ const outbox = database.prepare(`
855
+ SELECT message_form AS messageForm
856
+ FROM dsh_continuation_outbox
857
+ WHERE continuation_id = ?
858
+ `).get(continuationId);
859
+ return outbox === undefined ? !isLoopRecoveryMessage(message) : outbox.messageForm !== 'loop-recovery';
860
+ });
846
861
  const automaticClaimId = automaticMessage === undefined ? undefined : pluginContinuationId(automaticMessage);
847
862
  const decision = snapshot ? decideDshContinuation(database, {
848
863
  dshSessionId: event.sessionId, cwd: event.cwd,
@@ -1490,7 +1505,7 @@ export function createDshHostAdapter(ctx, options = {}) {
1490
1505
  });
1491
1506
  const outbox = readPendingOutbox(database, item.sessionId).find((candidate) => candidate.receiptId === job.receiptId);
1492
1507
  if (outbox !== undefined) {
1493
- replacePendingOutboxMessageInTransaction(database, job.receiptId, recoveryMessage(outbox.continuationId, answer), options.now?.() ?? new Date().toISOString());
1508
+ replacePendingOutboxMessageInTransaction(database, job.receiptId, recoveryMessage(outbox.continuationId, answer), 'loop-recovery', options.now?.() ?? new Date().toISOString());
1494
1509
  }
1495
1510
  }));
1496
1511
  return { kind: 'completed', nextKind: 'delivery' };
@@ -1542,7 +1557,7 @@ export function createDshHostAdapter(ctx, options = {}) {
1542
1557
  await runtime.withDatabase((database) => withImmediateTransaction(database, () => {
1543
1558
  const outbox = readPendingOutbox(database, item.sessionId).find((candidate) => candidate.receiptId === job.receiptId);
1544
1559
  if (outbox !== undefined)
1545
- replacePendingOutboxMessageInTransaction(database, job.receiptId, continuationMessage(outbox.continuationId, state.nextAction));
1560
+ replacePendingOutboxMessageInTransaction(database, job.receiptId, continuationMessage(outbox.continuationId, state.nextAction), 'continuation');
1546
1561
  }));
1547
1562
  return { kind: 'completed', nextKind: 'delivery' };
1548
1563
  }
@@ -1562,7 +1577,7 @@ export function createDshHostAdapter(ctx, options = {}) {
1562
1577
  },
1563
1578
  beforeDelivery: async (job, outbox, signal) => {
1564
1579
  boundarySignals.set(job.dshSessionId, signal);
1565
- if (isLoopRecoveryMessage(outbox.message))
1580
+ if (outbox.messageForm === 'loop-recovery')
1566
1581
  return 'deliver';
1567
1582
  const item = currentSession(job.dshSessionId);
1568
1583
  if (item === undefined || item.closed || item.runId !== job.runId)
@@ -1612,7 +1627,7 @@ export function createDshHostAdapter(ctx, options = {}) {
1612
1627
  claimId: guarded.claim.claimId,
1613
1628
  ...(options.now === undefined ? {} : { now: options.now() }),
1614
1629
  });
1615
- replacePendingOutboxMessageInTransaction(database, job.receiptId, recoveryMessage(outbox.continuationId, answer), options.now?.() ?? new Date().toISOString());
1630
+ replacePendingOutboxMessageInTransaction(database, job.receiptId, recoveryMessage(outbox.continuationId, answer), 'loop-recovery', options.now?.() ?? new Date().toISOString());
1616
1631
  }));
1617
1632
  return 'deliver';
1618
1633
  },
@@ -1652,7 +1667,7 @@ export function createDshHostAdapter(ctx, options = {}) {
1652
1667
  });
1653
1668
  const outbox = readPendingOutbox(database, item.sessionId).find((candidate) => candidate.receiptId === job.receiptId);
1654
1669
  if (outbox !== undefined) {
1655
- replacePendingOutboxMessageInTransaction(database, job.receiptId, recoveryMessage(outbox.continuationId, answer), options.now?.() ?? new Date().toISOString());
1670
+ replacePendingOutboxMessageInTransaction(database, job.receiptId, recoveryMessage(outbox.continuationId, answer), 'loop-recovery', options.now?.() ?? new Date().toISOString());
1656
1671
  }
1657
1672
  database.prepare(`
1658
1673
  UPDATE dsh_boundary_jobs