@kindgi/api 0.1.0 → 0.1.2

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.
@@ -293,74 +293,25 @@ export function runsRouter(
293
293
  });
294
294
 
295
295
  // ---------- POST /:runId/resume ----------
296
- r.post('/:runId/resume', async (c) => {
297
- const requestId = c.get('requestId');
298
- const tenantId = c.get('tenantId') as TenantId;
299
- const runId = c.req.param('runId') as RunId;
300
-
301
- let body: unknown = {};
302
- const hasBody =
303
- (c.req.header('content-type') ?? '').includes('json') ||
304
- (c.req.header('content-length') !== undefined && c.req.header('content-length') !== '0');
305
- if (hasBody) {
306
- try {
307
- const text = await c.req.text();
308
- body = text.length > 0 ? JSON.parse(text) : {};
309
- } catch {
310
- c.status(statusFor('bad-input') as never);
311
- return c.json(
312
- toWireError({ code: 'bad-input', message: 'Request body must be valid JSON' }, requestId),
313
- );
314
- }
315
- }
316
- const parsed = parseResumeBody(body);
317
- if (parsed.kind === 'err') {
318
- c.status(statusFor(parsed.error.code) as never);
319
- return c.json(toWireError(parsed.error, requestId));
320
- }
321
-
322
- // Resume completes a waitpoint (`completeToken`) and then drives the
323
- // run on. Resuming without a `waitpointId` is not supported.
324
- if (parsed.value.waitpointId === undefined) {
325
- c.status(statusFor('bad-input') as never);
326
- return c.json(
327
- toWireError(
328
- {
329
- code: 'bad-input',
330
- message:
331
- 'Programmatic resume without `waitpointId` is not supported yet — supply a waitpoint id to complete a wait token.',
332
- },
333
- requestId,
334
- ),
335
- );
336
- }
337
-
338
- const completed = await runBinding.completeToken(
339
- tenantId,
340
- runId,
341
- parsed.value.waitpointId,
342
- parsed.value.value,
343
- eventBus,
296
+ // Not available in this release. Every waitpoint a run can wait at
297
+ // belongs to an approval or to the runtime itself (a flow's agent step
298
+ // waiting on its child turn). Completing one here would skip what owns
299
+ // it: an approval's reviewer check and recorded decision, or the
300
+ // runtime's own wake-up. A run waiting for an approval continues
301
+ // through `POST /v1/approvals/:id/complete`. So nothing is read or
302
+ // completed; the route stays mounted for a clear answer.
303
+ r.post('/:runId/resume', (c) => {
304
+ c.status(statusFor('run-resume-not-supported') as never);
305
+ return c.json(
306
+ toWireError(
307
+ {
308
+ code: 'run-resume-not-supported',
309
+ message:
310
+ 'Resuming a run at a waitpoint is not available in this release: every waitpoint belongs to an approval or to the runtime. A run waiting for an approval continues when a reviewer decides it (POST /v1/approvals/{approvalId}/complete, or `kindgi approvals complete`).',
311
+ },
312
+ c.get('requestId'),
313
+ ),
344
314
  );
345
- if (completed.kind === 'err') {
346
- const err = completed.error;
347
- c.status(statusFor(err.code) as never);
348
- return c.json(toWireError(err as never, requestId));
349
- }
350
-
351
- // Drive the run on in the same request, as approvals do. Soft on
352
- // failure: the token completion is already durable, so the run is
353
- // resumable later; the response shows the status it reached.
354
- await binding.resumeRun({ tenantId, runId }).catch(() => undefined);
355
-
356
- const reloaded = await runBinding.getRun(tenantId, runId);
357
- if (reloaded === null) {
358
- c.status(statusFor('run-not-found') as never);
359
- return c.json(
360
- toWireError({ code: 'run-not-found', message: `No run with id ${runId}` }, requestId),
361
- );
362
- }
363
- return c.json(serializeRun(reloaded, { output: true }));
364
315
  });
365
316
 
366
317
  // ---------- GET /:runId/stream and /:runId/progress/stream (SSE) ----------
@@ -770,9 +721,6 @@ function listRunsInput(input: {
770
721
  };
771
722
  }
772
723
 
773
- /** Waitpoint ids the runtime reserves for a parent waiting on a child run. */
774
- const RESERVED_WAITPOINT_PREFIX = 'child:';
775
-
776
724
  interface RunListFilter {
777
725
  readonly parentRunId?: RunId;
778
726
  readonly topLevelOnly: boolean;
@@ -809,43 +757,6 @@ function parseRunListFilter(
809
757
  };
810
758
  }
811
759
 
812
- function parseResumeBody(
813
- body: unknown,
814
- ):
815
- | { kind: 'ok'; value: { waitpointId?: string; value?: unknown } }
816
- | { kind: 'err'; error: { code: string; message: string } } {
817
- if (body === null || typeof body !== 'object') {
818
- return { kind: 'err', error: { code: 'bad-input', message: 'Request body must be an object' } };
819
- }
820
- const b = body as Record<string, unknown>;
821
- const waitpointId = b.waitpointId;
822
- if (waitpointId !== undefined && (typeof waitpointId !== 'string' || waitpointId.length === 0)) {
823
- return {
824
- kind: 'err',
825
- error: {
826
- code: 'bad-input',
827
- message: '`waitpointId` must be a non-empty string when supplied',
828
- },
829
- };
830
- }
831
- if (typeof waitpointId === 'string' && waitpointId.startsWith(RESERVED_WAITPOINT_PREFIX)) {
832
- return {
833
- kind: 'err',
834
- error: {
835
- code: 'bad-input',
836
- message: `Waitpoint ids starting with "${RESERVED_WAITPOINT_PREFIX}" belong to the runtime (a parent waiting on a child run) and cannot be completed by a caller.`,
837
- },
838
- };
839
- }
840
- return {
841
- kind: 'ok',
842
- value: {
843
- ...(waitpointId !== undefined && { waitpointId: waitpointId as string }),
844
- ...('value' in b && { value: b.value }),
845
- },
846
- };
847
- }
848
-
849
760
  /** `options` of a start body: `dryRun?`, `wait?` (booleans). */
850
761
  function parseStartOptions(
851
762
  raw: unknown,
package/src/routes/sse.ts CHANGED
@@ -12,7 +12,7 @@ import type { RunId, TenantId } from '@kindgi/types';
12
12
  * Source of truth: `@kindgi/specs/run-event.schema.json`. Names are dotted
13
13
  * `run.<xxx>-<yyy>` (e.g. `run.step-completed`) — matches the
14
14
  * conventions doc §6 example. Internal-only kernel journal kinds
15
- * (e.g. `clock.read`) and kinds absent from the wire enum
15
+ * (e.g. `value.recorded`) and kinds absent from the wire enum
16
16
  * (`edge.evaluated`) are dropped by the mapper — the journal endpoint
17
17
  * still exposes them.
18
18
  */
@@ -54,7 +54,7 @@ const TERMINAL_KINDS: ReadonlySet<RunEventKind> = new Set([
54
54
  /**
55
55
  * Project a kernel `JournalEntry` into the wire `RunEvent` shape
56
56
  * consumed over SSE. Returns `null` for kernel kinds not exposed on
57
- * the wire (`edge.evaluated`, `clock.read`).
57
+ * the wire (`edge.evaluated`, `value.recorded`).
58
58
  */
59
59
  export function projectJournalEntry(
60
60
  entry: JournalEntry,