@tenetkit/pg 0.40.1 → 0.41.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.
Files changed (42) hide show
  1. package/dist/postgres/{event-stream.d.ts → events/event-stream.d.ts} +2 -2
  2. package/dist/postgres/{event-stream.js → events/event-stream.js} +2 -2
  3. package/dist/postgres/{transaction-events.d.ts → events/transaction-events.d.ts} +2 -2
  4. package/dist/postgres/{transaction-events.js → events/transaction-events.js} +4 -4
  5. package/dist/postgres/run-schema.js +6 -6
  6. package/dist/postgres/{claims.d.ts → runs/claims.d.ts} +2 -2
  7. package/dist/postgres/{claims.js → runs/claims.js} +1 -1
  8. package/dist/postgres/{locks.d.ts → runs/locks.d.ts} +1 -1
  9. package/dist/postgres/{locks.js → runs/locks.js} +2 -2
  10. package/dist/postgres/runtime-layer.d.ts +4 -5
  11. package/dist/postgres/runtime-layer.js +9 -9
  12. package/dist/postgres/{session-cancellation.js → sessions/session-cancellation.js} +1 -1
  13. package/dist/postgres/{session-storage.d.ts → sessions/session-storage.d.ts} +4 -3
  14. package/dist/postgres/{session-storage.js → sessions/session-storage.js} +1 -1
  15. package/dist/postgres/{session-store.d.ts → sessions/session-store.d.ts} +5 -5
  16. package/dist/postgres/{session-store.js → sessions/session-store.js} +46 -40
  17. package/dist/postgres/{store-admit.d.ts → store/admit.d.ts} +2 -2
  18. package/dist/postgres/{store-admit.js → store/admit.js} +6 -6
  19. package/dist/postgres/{store-cancel.d.ts → store/cancel.d.ts} +1 -1
  20. package/dist/postgres/{store-cancel.js → store/cancel.js} +42 -46
  21. package/dist/postgres/{store-claims.d.ts → store/claims.d.ts} +3 -3
  22. package/dist/postgres/{store-claims.js → store/claims.js} +9 -7
  23. package/dist/postgres/{store-fan-out.d.ts → store/fan-out.d.ts} +2 -2
  24. package/dist/postgres/{store-fan-out.js → store/fan-out.js} +2 -2
  25. package/dist/postgres/{store.d.ts → store/index.d.ts} +7 -4
  26. package/dist/postgres/{store.js → store/index.js} +56 -54
  27. package/dist/postgres/{store-inspection.d.ts → store/inspection.d.ts} +3 -3
  28. package/dist/postgres/{store-inspection.js → store/inspection.js} +10 -10
  29. package/dist/postgres/{store-messaging.d.ts → store/messaging.d.ts} +2 -2
  30. package/dist/postgres/{store-messaging.js → store/messaging.js} +1 -1
  31. package/dist/postgres/{store-model-response.d.ts → store/model-response.d.ts} +4 -4
  32. package/dist/postgres/{store-model-response.js → store/model-response.js} +46 -38
  33. package/dist/postgres/{store-ops.d.ts → store/ops.d.ts} +4 -4
  34. package/dist/postgres/{store-ops.js → store/ops.js} +102 -94
  35. package/dist/postgres/{store-program.d.ts → store/program.d.ts} +2 -2
  36. package/dist/postgres/{store-program.js → store/program.js} +5 -5
  37. package/dist/postgres/{pg-helpers.d.ts → store/runtime.d.ts} +18 -12
  38. package/dist/postgres/{pg-helpers.js → store/runtime.js} +49 -48
  39. package/dist/postgres/{store-suspend.d.ts → store/suspend.d.ts} +1 -1
  40. package/dist/postgres/{store-suspend.js → store/suspend.js} +14 -14
  41. package/package.json +2 -2
  42. /package/dist/postgres/{session-cancellation.d.ts → sessions/session-cancellation.d.ts} +0 -0
@@ -2,10 +2,10 @@ import { Effect, Stream } from "effect";
2
2
  import type { PgClient } from "@effect/sql-pg";
3
3
  import type { Cursor } from "tenetkit/runtime/driver/cursor";
4
4
  import type { CursorExpired, RunNotFound, RuntimeUnavailable, SubscriberLagged } from "tenetkit/runtime/driver/errors";
5
- import type { RunEvent } from "tenetkit/runtime/driver/run-event";
5
+ import type { RunEvent } from "tenetkit/runtime/driver/run/event";
6
6
  import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
7
7
  type EventsError = CursorExpired | RunNotFound | RuntimeUnavailable | SubscriberLagged;
8
- export declare const makeEventStream: (input: {
8
+ export declare const eventStream: (input: {
9
9
  readonly hub: EventHub;
10
10
  readonly pg: PgClient.PgClient;
11
11
  readonly runId: string;
@@ -1,6 +1,6 @@
1
1
  import { Effect, Schedule, Stream, SynchronizedRef } from "effect";
2
- import { NOTIFY_CHANNEL } from "./schema.js";
3
- export const makeEventStream = (input) => Stream.unwrap(Effect.gen(function* () {
2
+ import { NOTIFY_CHANNEL } from "../schema.js";
3
+ export const eventStream = (input) => Stream.unwrap(Effect.gen(function* () {
4
4
  const cursor = yield* SynchronizedRef.make(input.cursor);
5
5
  const catchUp = SynchronizedRef.modifyEffect(cursor, (current) => input.loadAfter(current).pipe(Effect.flatMap((events) => Effect.forEach(events, (event) => input.hub.publish(input.runId, event)).pipe(Effect.as(events.at(-1)?.sequence ?? current))), Effect.map((last) => [last, last]))).pipe(Effect.ignore);
6
6
  return input.hub.subscribe({
@@ -2,8 +2,8 @@ import { Effect } from "effect";
2
2
  import { PgClient } from "@effect/sql-pg";
3
3
  import { SqlClient } from "effect/unstable/sql";
4
4
  import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
5
- import type { RunFn } from "./store-ops.js";
6
- export declare const makeTransactionRunner: (input: {
5
+ import type { RunFn } from "../store/ops.js";
6
+ export declare const transactionRunner: (input: {
7
7
  readonly sql: SqlClient.SqlClient;
8
8
  readonly pg: PgClient.PgClient;
9
9
  readonly hub: EventHub;
@@ -1,10 +1,10 @@
1
1
  import { Context, Effect, Random } from "effect";
2
2
  import { PgClient } from "@effect/sql-pg";
3
3
  import { SqlClient } from "effect/unstable/sql";
4
- import { withSql } from "tenetkit/runtime/driver/sql/sql-effect";
5
- import { NOTIFY_CHANNEL } from "./schema.js";
6
- const TransactionEvents = Context.Reference("tenetkit/runtime/sql/postgres/TransactionEvents", { defaultValue: () => [] });
7
- export const makeTransactionRunner = (input) => {
4
+ import { withSql } from "tenetkit/runtime/driver/sql/effect";
5
+ import { NOTIFY_CHANNEL } from "../schema.js";
6
+ const TransactionEvents = Context.Reference("tenetkit/runtime/driver/sql/postgres/TransactionEvents", { defaultValue: () => [] });
7
+ export const transactionRunner = (input) => {
8
8
  const transactionHub = {
9
9
  ...input.hub,
10
10
  publish: (runId, event) => Effect.flatMap(TransactionEvents, (events) => Effect.sync(() => void events.push([runId, event]))),
@@ -2,11 +2,11 @@ import { Cause, DateTime, Effect, Layer, Redacted } from "effect";
2
2
  import { Migrator, SqlClient } from "effect/unstable/sql";
3
3
  import { PgClient } from "@effect/sql-pg";
4
4
  import { SchemaChecksumMismatch, SchemaDirty, SchemaMigrationFailed, SchemaUpgradeRequired, SchemaVersionUnsupported, } from "tenetkit/runtime/driver/sql/errors";
5
- import { mapSqlError } from "tenetkit/runtime/driver/sql/sql-effect";
5
+ import { mapSqlError } from "tenetkit/runtime/driver/sql/effect";
6
6
  import { MIGRATION_NAME, MIGRATIONS_TABLE, SCHEMA_META_TABLE, SCHEMA_STATEMENTS, SCHEMA_TABLES, SCHEMA_VERSION, schemaChecksum, } from "./schema.js";
7
7
  const migrationFailure = (source, fallback) => (error) => SchemaMigrationFailed.make({
8
8
  source,
9
- message: typeof error === "object" && error !== null && "message" in error ? String(error.message) : fallback,
9
+ message: error.message || fallback,
10
10
  });
11
11
  const readMeta = (source) => mapSqlError(Effect.gen(function* () {
12
12
  const sql = yield* SqlClient.SqlClient;
@@ -24,10 +24,10 @@ const readMeta = (source) => mapSqlError(Effect.gen(function* () {
24
24
  const row = rows[0];
25
25
  if (row === undefined)
26
26
  return { version: 0, checksum: "", dirty: false, present: false };
27
- return { version: Number(row.version), checksum: row.checksum, dirty: row.dirty, present: true };
27
+ return { version: row.version, checksum: row.checksum, dirty: row.dirty, present: true };
28
28
  })).pipe(Effect.mapError((error) => SchemaMigrationFailed.make({
29
29
  source,
30
- message: "message" in error ? String(error.message) : "schema meta read failed",
30
+ message: "message" in error ? error.message : "schema meta read failed",
31
31
  })));
32
32
  const verifyMigrationIdentity = (source) => Effect.gen(function* () {
33
33
  const sql = yield* SqlClient.SqlClient;
@@ -90,7 +90,7 @@ export const apply = (source) => Effect.gen(function* () {
90
90
  SELECT COUNT(*) AS present FROM information_schema.tables
91
91
  WHERE table_schema = current_schema() AND table_name IN ${sql.in(SCHEMA_TABLES)}
92
92
  `;
93
- if (Number(existing[0]?.present ?? 0) > 0) {
93
+ if ((existing[0]?.present ?? 0) > 0) {
94
94
  return yield* SchemaMigrationFailed.make({
95
95
  source,
96
96
  message: "cannot create the baseline over an existing TenetKit schema",
@@ -104,7 +104,7 @@ export const markDirty = (source) => mapSqlError(Effect.gen(function* () {
104
104
  yield* sql `UPDATE ${sql(SCHEMA_META_TABLE)} SET dirty = TRUE WHERE id = 1`;
105
105
  })).pipe(Effect.mapError((error) => SchemaMigrationFailed.make({
106
106
  source,
107
- message: "message" in error ? String(error.message) : "failed to mark schema dirty",
107
+ message: "message" in error ? error.message : "failed to mark schema dirty",
108
108
  })));
109
109
  export const RunSchema = { plan, check, apply, markDirty };
110
110
  export const layerClient = (url) => PgClient.layer({ url: Redacted.make(url) });
@@ -1,7 +1,7 @@
1
1
  import { Duration, Effect } from "effect";
2
2
  import { SqlClient } from "effect/unstable/sql";
3
3
  import { StaleClaim } from "tenetkit/runtime/driver/sql/errors";
4
- import type { ClaimedRun } from "tenetkit/runtime/driver/sql/run-claims";
4
+ import type { ClaimedRun } from "tenetkit/runtime/driver/sql/run/claims";
5
5
  export interface ClaimOptions {
6
6
  readonly workerId: string;
7
7
  readonly limit: number;
@@ -19,7 +19,7 @@ export declare const requireClaim: (input: {
19
19
  readonly runId: string;
20
20
  readonly workerId: string;
21
21
  readonly attemptFence: number;
22
- }) => Effect.Effect<import("tenetkit/runtime/driver/sql/rows").DecodedRun, import("tenetkit/runtime/driver/errors").RuntimeUnavailable | import("effect/unstable/sql/SqlError").SqlError | StaleClaim, SqlClient.SqlClient>;
22
+ }) => Effect.Effect<import("tenetkit/runtime/driver/sql/codec/rows").DecodedRun, import("tenetkit/runtime/driver/errors").RuntimeUnavailable | import("effect/unstable/sql/SqlError").SqlError | StaleClaim, SqlClient.SqlClient>;
23
23
  export declare const releaseClaim: (input: {
24
24
  readonly runId: string;
25
25
  readonly workerId: string;
@@ -1,7 +1,7 @@
1
1
  import { Clock, DateTime, Duration, Effect } from "effect";
2
2
  import { SqlClient } from "effect/unstable/sql";
3
3
  import { StaleClaim } from "tenetkit/runtime/driver/sql/errors";
4
- import { decodeRunEffect, loadRun } from "tenetkit/runtime/driver/sql/store-helpers";
4
+ import { decodeRunEffect, loadRun } from "tenetkit/runtime/driver/sql/store/statements";
5
5
  export const claimReadyRuns = (options) => Effect.gen(function* () {
6
6
  const sql = yield* SqlClient.SqlClient;
7
7
  const leaseMs = Duration.toMillis(options.lease);
@@ -15,4 +15,4 @@ export declare const lockRunHierarchy: (runId: string) => Effect.Effect<void, im
15
15
  * on the target rather than on any one sender's Run.
16
16
  */
17
17
  export declare const lockMailbox: (targetSessionId: string) => Effect.Effect<void, import("effect/unstable/sql/SqlError").SqlError, SqlClient.SqlClient>;
18
- export declare const lockSpawnParent: (runId: string) => Effect.Effect<import("tenetkit/runtime/driver/sql/rows").DecodedRun, RunNotFound | RunTerminal | import("tenetkit/runtime/driver/errors").RuntimeUnavailable | import("effect/unstable/sql/SqlError").SqlError, SqlClient.SqlClient>;
18
+ export declare const lockSpawnParent: (runId: string) => Effect.Effect<import("tenetkit/runtime/driver/sql/codec/rows").DecodedRun, RunNotFound | RunTerminal | import("tenetkit/runtime/driver/errors").RuntimeUnavailable | import("effect/unstable/sql/SqlError").SqlError, SqlClient.SqlClient>;
@@ -2,7 +2,7 @@ import { Effect } from "effect";
2
2
  import { SqlClient } from "effect/unstable/sql";
3
3
  import { RunNotFound, RunTerminal } from "tenetkit/runtime/driver/errors";
4
4
  import { isTerminal } from "tenetkit/runtime/driver/run";
5
- import { loadRun } from "./pg-helpers.js";
5
+ import { loadRun } from "../store/runtime.js";
6
6
  /**
7
7
  * One Run-level lock serializing admission, steering, response, resume, timeout,
8
8
  * cancellation, and terminal settlement. Always taken advisory-first, then row,
@@ -26,7 +26,7 @@ export const lockRunHierarchy = (runId) => Effect.gen(function* () {
26
26
  hierarchy.push(row.parent_run_id);
27
27
  current = row.parent_run_id;
28
28
  }
29
- for (const id of hierarchy.reverse())
29
+ for (const id of hierarchy.toReversed())
30
30
  yield* lockRun(id);
31
31
  });
32
32
  /**
@@ -1,10 +1,9 @@
1
1
  import { Layer } from "effect";
2
2
  import type { SqlError } from "effect/unstable/sql/SqlError";
3
- import { Runtime } from "tenetkit/runtime/driver/runtime";
4
- import { RunStore } from "tenetkit/runtime/driver/run-store";
5
- import { RunClaims } from "tenetkit/runtime/driver/sql/run-claims";
6
- import { ExecutionHost } from "tenetkit/runtime/driver/execution-host";
7
- import type { LayerOptions } from "tenetkit/runtime/driver/runtime";
3
+ import { Runtime, type LayerOptions } from "tenetkit/runtime/driver/service";
4
+ import { RunStore } from "tenetkit/runtime/driver/run/store";
5
+ import { RunClaims } from "tenetkit/runtime/driver/sql/run/claims";
6
+ import { ExecutionHost } from "tenetkit/runtime/driver/execution/host";
8
7
  import { SchemaMigrationFailed, type SchemaChecksumMismatch, type SchemaDirty, type SchemaUpgradeRequired, type SchemaVersionUnsupported } from "tenetkit/runtime/driver/sql/errors";
9
8
  export interface PostgresStoreOptions extends LayerOptions {
10
9
  readonly url: string;
@@ -1,13 +1,13 @@
1
1
  import { Context, Effect, Layer, Redacted } from "effect";
2
2
  import { PgClient } from "@effect/sql-pg";
3
- import { makeRuntime } from "tenetkit/runtime/driver/memory/runtime-layer";
4
- import { Runtime } from "tenetkit/runtime/driver/runtime";
5
- import { RunStore } from "tenetkit/runtime/driver/run-store";
6
- import { RunClaims } from "tenetkit/runtime/driver/sql/run-claims";
7
- import { makePostgresServices } from "./store.js";
8
- import { ExecutionHost, make as makeExecutionHost } from "tenetkit/runtime/driver/execution-host";
9
- import { layer as activeExecutionsLayer } from "tenetkit/runtime/driver/active-executions";
10
- import { layer as modelPreviewLayer } from "tenetkit/runtime/driver/model-preview";
3
+ import { makeRuntime } from "tenetkit/runtime/driver/memory/layer";
4
+ import { Runtime } from "tenetkit/runtime/driver/service";
5
+ import { RunStore } from "tenetkit/runtime/driver/run/store";
6
+ import { RunClaims } from "tenetkit/runtime/driver/sql/run/claims";
7
+ import { postgresServices } from "./store/index.js";
8
+ import { ExecutionHost, make as makeExecutionHost } from "tenetkit/runtime/driver/execution/host";
9
+ import { layer as activeExecutionsLayer } from "tenetkit/runtime/driver/execution/active-executions";
10
+ import { layer as modelPreviewLayer } from "tenetkit/runtime/driver/execution/model-response/preview";
11
11
  import { SchemaMigrationFailed, } from "tenetkit/runtime/driver/sql/errors";
12
12
  export const layerPostgres = (options) => {
13
13
  const maxConnections = options.maxConnections ?? 10;
@@ -20,7 +20,7 @@ export const layerPostgres = (options) => {
20
20
  }
21
21
  return PgClient.layer({ url: Redacted.make(options.url), maxConnections });
22
22
  }));
23
- const services = Layer.effectContext(makePostgresServices(options).pipe(Effect.map(({ store, claims }) => Context.make(RunStore, store).pipe(Context.add(RunClaims, claims))))).pipe(Layer.provide(client));
23
+ const services = Layer.effectContext(postgresServices(options).pipe(Effect.map(({ store, claims }) => Context.make(RunStore, store).pipe(Context.add(RunClaims, claims))))).pipe(Layer.provide(client));
24
24
  const dependencies = Layer.mergeAll(services, activeExecutionsLayer, modelPreviewLayer);
25
25
  const runtime = Layer.effect(Runtime, makeRuntime(options)).pipe(Layer.provide(dependencies));
26
26
  const host = Layer.effect(ExecutionHost, makeExecutionHost({ workerId: "postgres", resolver: options.resolver })).pipe(Layer.provide(dependencies));
@@ -1,5 +1,5 @@
1
1
  import { Effect } from "effect";
2
- import { activeSessionRuns, sessionRoots, sessionRuns } from "tenetkit/runtime/driver/sql/session-lifecycle";
2
+ import { activeSessionRuns, sessionRoots, sessionRuns } from "tenetkit/runtime/driver/sql/session/lifecycle";
3
3
  export const cancelSessionRuns = (input) => Effect.gen(function* () {
4
4
  const roots = yield* sessionRoots(input.sessionId);
5
5
  const runs = yield* sessionRuns(input.sessionId);
@@ -2,7 +2,7 @@ import { Effect } from "effect";
2
2
  import { Session } from "tenetkit";
3
3
  import { SqlClient } from "effect/unstable/sql";
4
4
  import type { SqlError } from "effect/unstable/sql/SqlError";
5
- import { type EntryRow, type SessionRow } from "tenetkit/runtime/driver/sql/session-store";
5
+ import { type EntryRow, type SessionRow } from "tenetkit/runtime/driver/sql/session/store";
6
6
  declare const insertEntry: (input: {
7
7
  readonly sessionId: string;
8
8
  readonly id: string;
@@ -17,7 +17,7 @@ declare const advanceSession: (input: {
17
17
  readonly nextSeq: number;
18
18
  readonly ownerToken?: string;
19
19
  }) => Effect.Effect<void, SqlError, SqlClient.SqlClient>;
20
- export declare const PostgresSessionStorage: {
20
+ interface PostgresSessionStorage {
21
21
  readonly encodePayload: (payload: Session.EntryPayload) => string;
22
22
  readonly entryPayloadEquivalence: (self: Session.EntryPayload, that: Session.EntryPayload) => boolean;
23
23
  readonly storeError: (message: string) => Session.SessionStoreError;
@@ -28,5 +28,6 @@ export declare const PostgresSessionStorage: {
28
28
  readonly requireActive: (rows: ReadonlyArray<EntryRow>, leaf: string | null, entryId: string, reason?: "stale-leaf" | "checkpoint-not-on-active-path") => Session.SessionConflict | undefined;
29
29
  readonly insertEntry: typeof insertEntry;
30
30
  readonly advanceSession: typeof advanceSession;
31
- };
31
+ }
32
+ export declare const PostgresSessionStorage: PostgresSessionStorage;
32
33
  export {};
@@ -1,7 +1,7 @@
1
1
  import { Effect } from "effect";
2
2
  import { Session } from "tenetkit";
3
3
  import { SqlClient } from "effect/unstable/sql";
4
- import { SessionStorage } from "tenetkit/runtime/driver/sql/session-store";
4
+ import { SessionStorage } from "tenetkit/runtime/driver/sql/session/store";
5
5
  const { encodePayload, entryPayloadEquivalence, pathFromRows, requireActive, storeError, toEntry } = SessionStorage;
6
6
  const lockSession = (sessionId) => Effect.gen(function* () {
7
7
  const sql = yield* SqlClient.SqlClient;
@@ -2,10 +2,10 @@ import { Effect } from "effect";
2
2
  import { Session } from "tenetkit";
3
3
  import { SqlClient } from "effect/unstable/sql";
4
4
  import type { SqlError } from "effect/unstable/sql/SqlError";
5
- import type { CompletedSessionEntry } from "tenetkit/runtime/driver/model-response-commit";
6
- import type { InterruptedSessionEntry } from "tenetkit/runtime/driver/agent-event";
7
- import { type HandoffSessionEntry } from "tenetkit/runtime/driver/handoff-session";
8
- import type { RunFn } from "./store-ops.js";
5
+ import type { CompletedSessionEntry } from "tenetkit/runtime/driver/execution/model-response/commit";
6
+ import type { InterruptedSessionEntry } from "tenetkit/runtime/driver/execution/agent/event";
7
+ import { type HandoffSessionEntry } from "tenetkit/runtime/driver/session/handoff";
8
+ import type { RunFn } from "../store/ops.js";
9
9
  /** Append or verify one exact completed assistant projection in the caller's PostgreSQL transaction. */
10
10
  export declare const appendCompletedSessionEntry: (input: CompletedSessionEntry) => Effect.Effect<Session.Entry, Session.SessionConflict | Session.SessionStoreError | SqlError, SqlClient.SqlClient>;
11
11
  /** Verify an exact completed assistant projection in the caller's PostgreSQL transaction. */
@@ -17,7 +17,7 @@ export declare const verifyInterruptedSessionEntry: (input: InterruptedSessionEn
17
17
  export declare const appendHandoffSessionEntry: (input: HandoffSessionEntry) => Effect.Effect<Session.HandoffEntry, Session.SessionConflict | Session.SessionStoreError | SqlError, SqlClient.SqlClient>;
18
18
  export declare const verifyHandoffSessionEntry: (input: HandoffSessionEntry) => Effect.Effect<void, Session.SessionConflict | Session.SessionStoreError | SqlError, SqlClient.SqlClient>;
19
19
  /** Dialect-native durable PostgreSQL Session authority bound to one session identity. */
20
- export declare const makePostgresSessionStore: (options: {
20
+ export declare const postgresSessionStore: (options: {
21
21
  readonly sessionId: string;
22
22
  readonly run: RunFn;
23
23
  readonly runNoTxn: RunFn;
@@ -1,11 +1,22 @@
1
1
  import { Effect, Schema } from "effect";
2
2
  import { Session } from "tenetkit";
3
3
  import { SqlClient } from "effect/unstable/sql";
4
- import { handoffPayload } from "tenetkit/runtime/driver/handoff-session";
5
- import {} from "tenetkit/runtime/driver/sql/session-store";
4
+ import { handoffPayload } from "tenetkit/runtime/driver/session/handoff";
6
5
  import { PostgresSessionStorage } from "./session-storage.js";
7
6
  const { advanceSession, entryPayloadEquivalence, insertEntry, loadEntries, lockSession, pathFromRows, requireActive, storeError, toEntry, } = PostgresSessionStorage;
8
7
  const appendMatches = (entry, input, parentId) => entry.parentId === parentId && entryPayloadEquivalence(entry, input);
8
+ const nextGeneratedId = (sql, sessionId, firstSequence) => Effect.gen(function* () {
9
+ let sequence = firstSequence;
10
+ while (true) {
11
+ const collision = yield* sql `
12
+ SELECT entry_id FROM tenetkit_session_entries
13
+ WHERE session_id = ${sessionId} AND entry_id = ${String(sequence)}
14
+ `;
15
+ if (collision[0] === undefined)
16
+ return { id: String(sequence), sequence };
17
+ sequence += 1;
18
+ }
19
+ });
9
20
  const completedPayload = (input) => ({
10
21
  _tag: "ModelResponse",
11
22
  content: input.content,
@@ -27,8 +38,7 @@ export const appendCompletedSessionEntry = (input) => Effect.gen(function* () {
27
38
  const existing = rows[0];
28
39
  const payload = completedPayload(input);
29
40
  if (existing !== undefined) {
30
- if (existing.parent_id !== input.parentId ||
31
- !entryPayloadEquivalence(toEntry(existing), payload)) {
41
+ if (existing.parent_id !== input.parentId || !entryPayloadEquivalence(toEntry(existing), payload)) {
32
42
  return yield* Session.SessionConflict.make({
33
43
  reason: "entry-id-reused",
34
44
  message: `Session entry id ${input.entryId} does not match the completed response`,
@@ -49,14 +59,14 @@ export const appendCompletedSessionEntry = (input) => Effect.gen(function* () {
49
59
  sessionId: input.sessionId,
50
60
  id: input.entryId,
51
61
  parentId: input.parentId,
52
- seq: Number(session.next_seq),
62
+ seq: session.next_seq,
53
63
  tag: "ModelResponse",
54
- payload: payload,
64
+ payload,
55
65
  });
56
66
  yield* advanceSession({
57
67
  sessionId: input.sessionId,
58
68
  leafId: input.entryId,
59
- nextSeq: Number(session.next_seq) + 1,
69
+ nextSeq: session.next_seq + 1,
60
70
  });
61
71
  return { ...payload, id: input.entryId, parentId: input.parentId };
62
72
  });
@@ -92,8 +102,7 @@ export const appendInterruptedSessionEntry = (input) => Effect.gen(function* ()
92
102
  const existing = rows[0];
93
103
  const payload = interruptedPayload(input);
94
104
  if (existing !== undefined) {
95
- if (existing.parent_id !== input.parentId ||
96
- !entryPayloadEquivalence(toEntry(existing), payload)) {
105
+ if (existing.parent_id !== input.parentId || !entryPayloadEquivalence(toEntry(existing), payload)) {
97
106
  return yield* Session.SessionConflict.make({
98
107
  reason: "entry-id-reused",
99
108
  message: `Session entry id ${input.entryId} was reused with different interrupted response content`,
@@ -114,14 +123,14 @@ export const appendInterruptedSessionEntry = (input) => Effect.gen(function* ()
114
123
  sessionId: input.sessionId,
115
124
  id: input.entryId,
116
125
  parentId: input.parentId,
117
- seq: Number(session.next_seq),
126
+ seq: session.next_seq,
118
127
  tag: "ModelResponse",
119
- payload: payload,
128
+ payload,
120
129
  });
121
130
  yield* advanceSession({
122
131
  sessionId: input.sessionId,
123
132
  leafId: input.entryId,
124
- nextSeq: Number(session.next_seq) + 1,
133
+ nextSeq: session.next_seq + 1,
125
134
  });
126
135
  return { ...payload, id: input.entryId, parentId: input.parentId };
127
136
  });
@@ -156,8 +165,7 @@ export const appendHandoffSessionEntry = (input) => Effect.gen(function* () {
156
165
  const existing = rows[0];
157
166
  const payload = handoffPayload(input);
158
167
  if (existing !== undefined) {
159
- if (existing.parent_id !== input.parentId ||
160
- !entryPayloadEquivalence(toEntry(existing), payload)) {
168
+ if (existing.parent_id !== input.parentId || !entryPayloadEquivalence(toEntry(existing), payload)) {
161
169
  return yield* Session.SessionConflict.make({
162
170
  reason: "entry-id-reused",
163
171
  message: `Session entry id ${input.entryId} does not match the handoff projection`,
@@ -166,7 +174,14 @@ export const appendHandoffSessionEntry = (input) => Effect.gen(function* () {
166
174
  const conflict = requireActive(yield* loadEntries(input.sessionId), session.leaf_id, input.entryId);
167
175
  if (conflict !== undefined)
168
176
  return yield* conflict;
169
- return toEntry(existing);
177
+ const entry = toEntry(existing);
178
+ if (entry._tag !== "Handoff") {
179
+ return yield* Session.SessionConflict.make({
180
+ reason: "entry-id-reused",
181
+ message: `Session entry id ${input.entryId} does not contain a handoff projection`,
182
+ });
183
+ }
184
+ return entry;
170
185
  }
171
186
  if (session.leaf_id !== input.parentId) {
172
187
  return yield* Session.SessionConflict.make({
@@ -178,14 +193,14 @@ export const appendHandoffSessionEntry = (input) => Effect.gen(function* () {
178
193
  sessionId: input.sessionId,
179
194
  id: input.entryId,
180
195
  parentId: input.parentId,
181
- seq: Number(session.next_seq),
196
+ seq: session.next_seq,
182
197
  tag: "Handoff",
183
198
  payload,
184
199
  });
185
200
  yield* advanceSession({
186
201
  sessionId: input.sessionId,
187
202
  leafId: input.entryId,
188
- nextSeq: Number(session.next_seq) + 1,
203
+ nextSeq: session.next_seq + 1,
189
204
  });
190
205
  return { ...payload, id: input.entryId, parentId: input.parentId };
191
206
  });
@@ -214,7 +229,7 @@ const mapSessionError = (effect) => Effect.mapError(effect, (error) => Schema.is
214
229
  : storeError(String(error)));
215
230
  const mapReadError = (effect) => Effect.mapError(effect, (error) => (Schema.is(Session.SessionStoreError)(error) ? error : storeError(String(error))));
216
231
  /** Dialect-native durable PostgreSQL Session authority bound to one session identity. */
217
- export const makePostgresSessionStore = (options) => {
232
+ export const postgresSessionStore = (options) => {
218
233
  const { sessionId, run, runNoTxn } = options;
219
234
  const append = (entry, appendOptions) => Effect.gen(function* () {
220
235
  const sql = yield* SqlClient.SqlClient;
@@ -245,32 +260,23 @@ export const makePostgresSessionStore = (options) => {
245
260
  message: `Expected Session leaf ${String(appendOptions.expectedLeafId)} but found ${String(session.leaf_id)}`,
246
261
  });
247
262
  }
248
- let generatedSequence = Number(session.next_seq);
249
- if (appendOptions?.id === undefined) {
250
- while (true) {
251
- const collision = yield* sql `
252
- SELECT entry_id FROM tenetkit_session_entries
253
- WHERE session_id = ${sessionId} AND entry_id = ${String(generatedSequence)}
254
- `;
255
- if (collision[0] === undefined)
256
- break;
257
- generatedSequence += 1;
258
- }
259
- }
260
- const id = appendOptions?.id ?? String(generatedSequence);
263
+ const generated = appendOptions?.id === undefined
264
+ ? yield* nextGeneratedId(sql, sessionId, session.next_seq)
265
+ : { id: appendOptions.id, sequence: session.next_seq };
266
+ const id = generated.id;
261
267
  yield* insertEntry({
262
268
  sessionId,
263
269
  id,
264
270
  parentId: session.leaf_id,
265
- seq: Number(session.next_seq),
271
+ seq: session.next_seq,
266
272
  tag: entry._tag,
267
273
  payload: entry,
268
274
  });
269
275
  yield* advanceSession({
270
276
  sessionId,
271
277
  leafId: id,
272
- nextSeq: appendOptions?.id === undefined ? generatedSequence + 1 : Number(session.next_seq) + 1,
273
- ...(appendOptions?.ownerToken === undefined ? {} : { ownerToken: appendOptions.ownerToken }),
278
+ nextSeq: generated.sequence + 1,
279
+ ...(appendOptions?.ownerToken === undefined ? undefined : { ownerToken: appendOptions.ownerToken }),
274
280
  });
275
281
  return { ...entry, id, parentId: session.leaf_id };
276
282
  });
@@ -317,22 +323,22 @@ export const makePostgresSessionStore = (options) => {
317
323
  parentId: prepared.parentId,
318
324
  projectedHistory: prepared.projectedHistory,
319
325
  telemetry: prepared.telemetry,
320
- ...(prepared.compactionCommit === undefined ? {} : { compactionCommit: prepared.compactionCommit }),
321
- ...(prepared.summary === undefined ? {} : { summary: prepared.summary }),
326
+ ...(prepared.compactionCommit === undefined ? undefined : { compactionCommit: prepared.compactionCommit }),
327
+ ...(prepared.summary === undefined ? undefined : { summary: prepared.summary }),
322
328
  };
323
329
  yield* insertEntry({
324
330
  sessionId,
325
331
  id: checkpoint.id,
326
332
  parentId: checkpoint.parentId,
327
- seq: Number(session.next_seq),
333
+ seq: session.next_seq,
328
334
  tag: "Compaction",
329
335
  payload: checkpoint,
330
336
  });
331
337
  yield* advanceSession({
332
338
  sessionId,
333
339
  leafId: checkpoint.id,
334
- nextSeq: Number(session.next_seq) + 1,
335
- ...(prepared.ownerToken === undefined ? {} : { ownerToken: prepared.ownerToken }),
340
+ nextSeq: session.next_seq + 1,
341
+ ...(prepared.ownerToken === undefined ? undefined : { ownerToken: prepared.ownerToken }),
336
342
  });
337
343
  return { _tag: "Appended", checkpoint, leafId: checkpoint.id };
338
344
  });
@@ -340,7 +346,7 @@ export const makePostgresSessionStore = (options) => {
340
346
  reserveEntryId: run(Effect.gen(function* () {
341
347
  const sql = yield* SqlClient.SqlClient;
342
348
  const session = yield* lockSession(sessionId);
343
- let sequence = Number(session.next_seq);
349
+ let sequence = session.next_seq;
344
350
  while (true) {
345
351
  const collision = yield* sql `
346
352
  SELECT entry_id FROM tenetkit_session_entries
@@ -1,8 +1,8 @@
1
1
  import { Effect } from "effect";
2
2
  import { SqlClient } from "effect/unstable/sql";
3
3
  import { AddressNotFound, IdempotencyConflict, RunIdConflict, TreePolicyInvalid } from "tenetkit/runtime/driver/errors";
4
- import type { PinnedExecutable } from "tenetkit/runtime/driver/executable-manifest";
5
- import type { AdmitSendInput } from "tenetkit/runtime/driver/run-store";
4
+ import { type PinnedExecutable } from "tenetkit/runtime/driver/executable/manifest";
5
+ import type { AdmitSendInput } from "tenetkit/runtime/driver/run/store";
6
6
  import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
7
7
  /** Exact addressed admission for the PostgreSQL store. */
8
8
  export declare const admitSend: {
@@ -1,12 +1,12 @@
1
1
  import { Effect, Function } from "effect";
2
2
  import { SqlClient } from "effect/unstable/sql";
3
3
  import { AddressNotFound, IdempotencyConflict, RunIdConflict, TreePolicyInvalid } from "tenetkit/runtime/driver/errors";
4
- import { equals } from "tenetkit/runtime/driver/executable-manifest";
4
+ import { equals } from "tenetkit/runtime/driver/executable/manifest";
5
5
  import { rootDigest } from "tenetkit/runtime/driver/memory/digest";
6
- import { appendEvent, enqueueLane, insertRun, loadRun } from "./pg-helpers.js";
7
- import { associateRegistrations, persistRegistrations } from "tenetkit/runtime/driver/sql/executable-registrations";
8
- import { decodePinnedEffect, decodeStoredPinnedEffect } from "tenetkit/runtime/driver/sql/codecs";
9
- import { normalize as normalizeTreePolicy } from "tenetkit/runtime/driver/tree-policy";
6
+ import { appendEvent, enqueueLane, insertRun, loadRun } from "./runtime.js";
7
+ import { associateRegistrations, persistRegistrations } from "tenetkit/runtime/driver/sql/executable/registrations";
8
+ import { decodePinnedEffect, decodeStoredPinnedEffect } from "tenetkit/runtime/driver/sql/codec/codecs";
9
+ import { normalize as normalizeTreePolicy } from "tenetkit/runtime/driver/tree/policy";
10
10
  /** Exact addressed admission for the PostgreSQL store. */
11
11
  export const admitSend = Function.dual(4, (hub, addressBindings, nextId, input) => Effect.gen(function* () {
12
12
  const sql = yield* SqlClient.SqlClient;
@@ -50,7 +50,7 @@ export const admitSend = Function.dual(4, (hub, addressBindings, nextId, input)
50
50
  return {
51
51
  runId: prior.run_id,
52
52
  messageId: prior.message_id,
53
- acceptedSequence: Number(prior.accepted_sequence),
53
+ acceptedSequence: prior.accepted_sequence,
54
54
  duplicate: true,
55
55
  };
56
56
  }
@@ -8,7 +8,7 @@ export declare const deferCancelledFanOutParent: {
8
8
  (runId: string): (sql: SqlClient.SqlClient) => Effect.Effect<boolean, SqlError, SqlClient.SqlClient>;
9
9
  (sql: SqlClient.SqlClient, runId: string): Effect.Effect<boolean, SqlError, SqlClient.SqlClient>;
10
10
  };
11
- export declare const makeCancelRun: (input: {
11
+ export declare const cancelRunFor: (input: {
12
12
  readonly sql: SqlClient.SqlClient;
13
13
  readonly hub: EventHub;
14
14
  }) => (runId: string, reason: string | undefined) => Effect.Effect<void, RunNotFound | RuntimeUnavailable | SqlError, SqlClient.SqlClient | PgClient.PgClient>;