@tenetkit/pg 0.40.0 → 0.41.1
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/postgres/{event-stream.d.ts → events/event-stream.d.ts} +2 -2
- package/dist/postgres/{event-stream.js → events/event-stream.js} +2 -2
- package/dist/postgres/{transaction-events.d.ts → events/transaction-events.d.ts} +2 -2
- package/dist/postgres/{transaction-events.js → events/transaction-events.js} +4 -4
- package/dist/postgres/run-schema.js +6 -6
- package/dist/postgres/{claims.d.ts → runs/claims.d.ts} +2 -2
- package/dist/postgres/{claims.js → runs/claims.js} +1 -1
- package/dist/postgres/{locks.d.ts → runs/locks.d.ts} +1 -1
- package/dist/postgres/{locks.js → runs/locks.js} +2 -2
- package/dist/postgres/runtime-layer.d.ts +4 -5
- package/dist/postgres/runtime-layer.js +9 -9
- package/dist/postgres/{session-cancellation.js → sessions/session-cancellation.js} +1 -1
- package/dist/postgres/{session-storage.d.ts → sessions/session-storage.d.ts} +4 -3
- package/dist/postgres/{session-storage.js → sessions/session-storage.js} +1 -1
- package/dist/postgres/{session-store.d.ts → sessions/session-store.d.ts} +5 -5
- package/dist/postgres/{session-store.js → sessions/session-store.js} +46 -40
- package/dist/postgres/{store-admit.d.ts → store/admit.d.ts} +2 -2
- package/dist/postgres/{store-admit.js → store/admit.js} +6 -6
- package/dist/postgres/{store-cancel.d.ts → store/cancel.d.ts} +1 -1
- package/dist/postgres/{store-cancel.js → store/cancel.js} +42 -46
- package/dist/postgres/{store-claims.d.ts → store/claims.d.ts} +3 -3
- package/dist/postgres/{store-claims.js → store/claims.js} +9 -7
- package/dist/postgres/{store-fan-out.d.ts → store/fan-out.d.ts} +2 -2
- package/dist/postgres/{store-fan-out.js → store/fan-out.js} +2 -2
- package/dist/postgres/{store.d.ts → store/index.d.ts} +7 -4
- package/dist/postgres/{store.js → store/index.js} +56 -54
- package/dist/postgres/{store-inspection.d.ts → store/inspection.d.ts} +3 -3
- package/dist/postgres/{store-inspection.js → store/inspection.js} +10 -10
- package/dist/postgres/{store-messaging.d.ts → store/messaging.d.ts} +2 -2
- package/dist/postgres/{store-messaging.js → store/messaging.js} +1 -1
- package/dist/postgres/{store-model-response.d.ts → store/model-response.d.ts} +4 -4
- package/dist/postgres/{store-model-response.js → store/model-response.js} +46 -38
- package/dist/postgres/{store-ops.d.ts → store/ops.d.ts} +4 -4
- package/dist/postgres/{store-ops.js → store/ops.js} +102 -94
- package/dist/postgres/{store-program.d.ts → store/program.d.ts} +2 -2
- package/dist/postgres/{store-program.js → store/program.js} +5 -5
- package/dist/postgres/{pg-helpers.d.ts → store/runtime.d.ts} +18 -12
- package/dist/postgres/{pg-helpers.js → store/runtime.js} +49 -48
- package/dist/postgres/{store-suspend.d.ts → store/suspend.d.ts} +1 -1
- package/dist/postgres/{store-suspend.js → store/suspend.js} +14 -14
- package/package.json +2 -2
- /package/dist/postgres/{session-cancellation.d.ts → sessions/session-cancellation.d.ts} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Effect, Function } from "effect";
|
|
2
2
|
import { RunNotFound, RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
3
3
|
import { isTerminal } from "tenetkit/runtime/driver/run";
|
|
4
|
-
import { hasPendingOperationCancellation, hasUnsettledChild } from "tenetkit/runtime/driver/sql/store
|
|
5
|
-
import { markOperationCancellations } from "tenetkit/runtime/driver/sql/store
|
|
6
|
-
import { afterTerminal, appendEvent, loadRun, settleParent } from "./
|
|
7
|
-
import { cancelOwnedFanOuts } from "./
|
|
8
|
-
import { reconcileProgramCancellation } from "tenetkit/runtime/driver/sql/store
|
|
4
|
+
import { hasPendingOperationCancellation, hasUnsettledChild } from "tenetkit/runtime/driver/sql/store/child/settlement";
|
|
5
|
+
import { markOperationCancellations } from "tenetkit/runtime/driver/sql/store/operation/operations";
|
|
6
|
+
import { afterTerminal, appendEvent, loadRun, settleParent } from "./runtime.js";
|
|
7
|
+
import { cancelOwnedFanOuts } from "./fan-out.js";
|
|
8
|
+
import { reconcileProgramCancellation } from "tenetkit/runtime/driver/sql/store/program";
|
|
9
9
|
export const deferCancelledFanOutParent = Function.dual(2, (sql, runId) => Effect.gen(function* () {
|
|
10
10
|
const running = yield* sql `
|
|
11
11
|
SELECT fan_out_id FROM tenetkit_fan_outs WHERE parent_run_id = ${runId} AND status = 'running' LIMIT 1
|
|
@@ -15,14 +15,46 @@ export const deferCancelledFanOutParent = Function.dual(2, (sql, runId) => Effec
|
|
|
15
15
|
yield* sql `UPDATE tenetkit_runs SET owner_worker_id = NULL, lease_expires_at = NULL WHERE run_id = ${runId}`;
|
|
16
16
|
return true;
|
|
17
17
|
}));
|
|
18
|
-
|
|
18
|
+
const cancelChildren = (input, cancelRun, runId, reason) => Effect.gen(function* () {
|
|
19
|
+
const linked = yield* input.sql `
|
|
20
|
+
SELECT l.child_run_id FROM tenetkit_run_links l
|
|
21
|
+
LEFT JOIN tenetkit_fan_out_members m ON m.child_run_id = l.child_run_id
|
|
22
|
+
WHERE l.parent_run_id = ${runId} AND m.child_run_id IS NULL
|
|
23
|
+
ORDER BY l.child_run_id ASC
|
|
24
|
+
`;
|
|
25
|
+
const owned = yield* cancelOwnedFanOuts(input.sql, runId);
|
|
26
|
+
for (const childRunId of [...linked.map((link) => link.child_run_id), ...owned]) {
|
|
27
|
+
const child = yield* loadRun(childRunId);
|
|
28
|
+
if (child !== undefined && !isTerminal(child.status)) {
|
|
29
|
+
yield* cancelRun(child.runId, reason ?? "parent cancelled");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return linked.length + owned.length;
|
|
33
|
+
});
|
|
34
|
+
const settleCancellation = (input, current, reason) => Effect.gen(function* () {
|
|
35
|
+
const running = yield* input.sql `
|
|
36
|
+
SELECT fan_out_id FROM tenetkit_fan_outs WHERE parent_run_id = ${current.runId} AND status = 'running' LIMIT 1
|
|
37
|
+
`;
|
|
38
|
+
if (running.length > 0)
|
|
39
|
+
return;
|
|
40
|
+
if (yield* hasPendingOperationCancellation(current.runId))
|
|
41
|
+
return;
|
|
42
|
+
if (yield* hasUnsettledChild(current.runId))
|
|
43
|
+
return;
|
|
44
|
+
const event = yield* appendEvent(input.hub, current, { _tag: "RunCancelled", ...(reason === undefined ? undefined : { reason }) }, "cancelled");
|
|
45
|
+
const settled = (yield* loadRun(current.runId));
|
|
46
|
+
yield* settleParent(input.hub, settled, event.eventId);
|
|
47
|
+
yield* afterTerminal(input.hub, settled);
|
|
48
|
+
});
|
|
49
|
+
const shouldSettleCancellation = (terminal, executing, current) => !terminal && !executing && !isTerminal(current.status);
|
|
50
|
+
export const cancelRunFor = (input) => {
|
|
19
51
|
const cancelRun = (runId, reason) => Effect.gen(function* () {
|
|
20
52
|
let current = yield* loadRun(runId).pipe(Effect.flatMap((run) => (run === undefined ? RunNotFound.make({ runId }) : Effect.succeed(run))));
|
|
21
53
|
const terminal = isTerminal(current.status);
|
|
22
54
|
const needsResolution = current.status === "needs-resolution";
|
|
23
55
|
const executing = current.ownerWorkerId !== undefined && (current.status === "running" || current.status === "cancelling");
|
|
24
56
|
if (!terminal && !current.cancellationRequested) {
|
|
25
|
-
yield* appendEvent(input.hub, current, { _tag: "RunCancellationRequested", ...(reason === undefined ?
|
|
57
|
+
yield* appendEvent(input.hub, current, { _tag: "RunCancellationRequested", ...(reason === undefined ? undefined : { reason }) }, needsResolution ? "needs-resolution" : "cancelling");
|
|
26
58
|
current = (yield* loadRun(runId));
|
|
27
59
|
}
|
|
28
60
|
const marked = terminal ? 0 : yield* markOperationCancellations(runId);
|
|
@@ -36,46 +68,10 @@ export const makeCancelRun = (input) => {
|
|
|
36
68
|
UPDATE tenetkit_run_waits SET status = 'cancelled', closed_at = NOW()
|
|
37
69
|
WHERE run_id = ${runId} AND status = 'open'
|
|
38
70
|
`;
|
|
39
|
-
|
|
40
|
-
SELECT l.child_run_id FROM tenetkit_run_links l
|
|
41
|
-
LEFT JOIN tenetkit_fan_out_members m ON m.child_run_id = l.child_run_id
|
|
42
|
-
WHERE l.parent_run_id = ${runId} AND m.child_run_id IS NULL
|
|
43
|
-
ORDER BY l.child_run_id ASC
|
|
44
|
-
`;
|
|
45
|
-
for (const link of linked) {
|
|
46
|
-
const child = yield* loadRun(link.child_run_id);
|
|
47
|
-
if (child !== undefined && !isTerminal(child.status))
|
|
48
|
-
yield* cancelRun(child.runId, reason ?? "parent cancelled");
|
|
49
|
-
}
|
|
50
|
-
if (linked.length > 0)
|
|
51
|
-
current = (yield* loadRun(runId));
|
|
52
|
-
const owned = yield* cancelOwnedFanOuts(input.sql, runId);
|
|
53
|
-
for (const childRunId of owned) {
|
|
54
|
-
const child = yield* loadRun(childRunId);
|
|
55
|
-
if (child !== undefined && !isTerminal(child.status))
|
|
56
|
-
yield* cancelRun(child.runId, reason ?? "parent cancelled");
|
|
57
|
-
}
|
|
58
|
-
if (owned.length > 0)
|
|
71
|
+
if ((yield* cancelChildren(input, cancelRun, runId, reason)) > 0)
|
|
59
72
|
current = (yield* loadRun(runId));
|
|
60
|
-
if (terminal)
|
|
61
|
-
|
|
62
|
-
if (executing)
|
|
63
|
-
return;
|
|
64
|
-
if (isTerminal(current.status))
|
|
65
|
-
return;
|
|
66
|
-
const running = yield* input.sql `
|
|
67
|
-
SELECT fan_out_id FROM tenetkit_fan_outs WHERE parent_run_id = ${runId} AND status = 'running' LIMIT 1
|
|
68
|
-
`;
|
|
69
|
-
if (running.length > 0)
|
|
70
|
-
return;
|
|
71
|
-
if (yield* hasPendingOperationCancellation(runId))
|
|
72
|
-
return;
|
|
73
|
-
if (yield* hasUnsettledChild(runId))
|
|
74
|
-
return;
|
|
75
|
-
const event = yield* appendEvent(input.hub, current, { _tag: "RunCancelled", ...(reason === undefined ? {} : { reason }) }, "cancelled");
|
|
76
|
-
const settled = (yield* loadRun(runId));
|
|
77
|
-
yield* settleParent(input.hub, settled, event.eventId);
|
|
78
|
-
yield* afterTerminal(input.hub, settled);
|
|
73
|
+
if (shouldSettleCancellation(terminal, executing, current))
|
|
74
|
+
yield* settleCancellation(input, current, reason);
|
|
79
75
|
});
|
|
80
76
|
return cancelRun;
|
|
81
77
|
};
|
|
@@ -4,11 +4,11 @@ import { SqlClient } from "effect/unstable/sql";
|
|
|
4
4
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
5
5
|
import { RunNotFound, RunTerminal, RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
6
6
|
import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
7
|
-
import { type Interface as ClaimsInterface } from "tenetkit/runtime/driver/sql/run
|
|
8
|
-
import type { WithoutSqlError } from "tenetkit/runtime/driver/sql/
|
|
7
|
+
import { type Interface as ClaimsInterface } from "tenetkit/runtime/driver/sql/run/claims";
|
|
8
|
+
import type { WithoutSqlError } from "tenetkit/runtime/driver/sql/effect";
|
|
9
9
|
type SqlR = SqlClient.SqlClient | PgClient.PgClient;
|
|
10
10
|
export type RunFn = <A, E>(effect: Effect.Effect<A, E | SqlError, SqlR>) => Effect.Effect<A, WithoutSqlError<E | SqlError> | RuntimeUnavailable>;
|
|
11
|
-
export declare const
|
|
11
|
+
export declare const postgresClaims: (input: {
|
|
12
12
|
readonly sql: SqlClient.SqlClient;
|
|
13
13
|
readonly hub: EventHub;
|
|
14
14
|
readonly run: RunFn;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
2
|
import { SqlClient } from "effect/unstable/sql";
|
|
3
3
|
import { AgentExecutionFailure, RunNotFound, RunTerminal, RuntimeUnavailable, failureMessage, } from "tenetkit/runtime/driver/errors";
|
|
4
4
|
import { isTerminal } from "tenetkit/runtime/driver/run";
|
|
5
5
|
import { StaleClaim } from "tenetkit/runtime/driver/sql/errors";
|
|
6
|
-
import { claimReadyRuns, refreshLease, releaseClaim } from "
|
|
7
|
-
import { RunClaims } from "tenetkit/runtime/driver/sql/run
|
|
8
|
-
import { afterTerminal, appendEvent, completeRun, loadEventsAfter, loadRun, settleParent } from "./
|
|
9
|
-
import { lockRunHierarchy } from "
|
|
10
|
-
|
|
6
|
+
import { claimReadyRuns, refreshLease, releaseClaim } from "../runs/claims.js";
|
|
7
|
+
import { RunClaims } from "tenetkit/runtime/driver/sql/run/claims";
|
|
8
|
+
import { afterTerminal, appendEvent, completeRun, loadEventsAfter, loadRun, settleParent } from "./runtime.js";
|
|
9
|
+
import { lockRunHierarchy } from "../runs/locks.js";
|
|
10
|
+
import { ExecutionResult } from "tenetkit/runtime/driver/execution/state";
|
|
11
|
+
export const postgresClaims = (input) => {
|
|
11
12
|
const { hub, run, cancelRun } = input;
|
|
12
13
|
return RunClaims.of({
|
|
13
14
|
claimReadyRuns: (claimInput) => run(Effect.gen(function* () {
|
|
@@ -58,7 +59,8 @@ export const makePostgresClaims = (input) => {
|
|
|
58
59
|
return yield* RunTerminal.make({ runId: loaded.runId, status: loaded.status });
|
|
59
60
|
}
|
|
60
61
|
if (commitInput.transition === "complete") {
|
|
61
|
-
yield*
|
|
62
|
+
const result = yield* Schema.decodeUnknownEffect(ExecutionResult)(commitInput.result).pipe(Effect.mapError((error) => RuntimeUnavailable.make({ message: String(error) })));
|
|
63
|
+
yield* completeRun(hub, loaded, result);
|
|
62
64
|
return;
|
|
63
65
|
}
|
|
64
66
|
const event = yield* appendEvent(hub, loaded, {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import type { PgClient } from "@effect/sql-pg";
|
|
3
3
|
import type { SqlClient } from "effect/unstable/sql";
|
|
4
|
-
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run
|
|
4
|
+
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run/store";
|
|
5
5
|
import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
6
|
-
import type { WithoutSqlError } from "tenetkit/runtime/driver/sql/
|
|
6
|
+
import type { WithoutSqlError } from "tenetkit/runtime/driver/sql/effect";
|
|
7
7
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
8
8
|
type SqlR = SqlClient.SqlClient | PgClient.PgClient;
|
|
9
9
|
export type Run = <A, E>(effect: Effect.Effect<A, E | SqlError, SqlR>) => Effect.Effect<A, WithoutSqlError<E | SqlError> | import("tenetkit/runtime/driver/errors").RuntimeUnavailable>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect, Function } from "effect";
|
|
2
|
-
import { admitFanOut, inspectFanOut } from "tenetkit/runtime/driver/sql/store
|
|
3
|
-
import { NOTIFY_CHANNEL } from "
|
|
2
|
+
import { admitFanOut, inspectFanOut } from "tenetkit/runtime/driver/sql/store/fan-out/service";
|
|
3
|
+
import { NOTIFY_CHANNEL } from "../schema.js";
|
|
4
4
|
export const fanOutStoreMethods = (input) => ({
|
|
5
5
|
admitFanOut: (fanOut) => input
|
|
6
6
|
.run(input.sql `SELECT run_id FROM tenetkit_runs WHERE run_id = ${fanOut.parentRunId} FOR UPDATE`.pipe(Effect.andThen(input.sql `SELECT pg_advisory_xact_lock(hashtext(${`fanout:${fanOut.parentRunId}:${fanOut.idempotencyKey}`}))`), Effect.andThen(admitFanOut(input.hub, fanOut))))
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import { SqlClient } from "effect/unstable/sql";
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import "../schema.js";
|
|
4
|
+
import "tenetkit/runtime/driver/sql/tree-history";
|
|
5
|
+
import "tenetkit/runtime/driver/sql/inspection/service";
|
|
6
|
+
import type { PostgresStoreOptions } from "../runtime-layer.js";
|
|
7
|
+
export declare const postgresServices: (options: PostgresStoreOptions) => Effect.Effect<{
|
|
8
|
+
store: import("tenetkit/runtime/driver/run/store").Interface;
|
|
9
|
+
claims: import("tenetkit/runtime/driver/sql/run/claims").Interface;
|
|
7
10
|
}, import("tenetkit/runtime/driver/sql/errors").SchemaChecksumMismatch | import("tenetkit/runtime/driver/sql/errors").SchemaDirty | import("tenetkit/runtime/driver/sql/errors").SchemaMigrationFailed | import("tenetkit/runtime/driver/sql/errors").SchemaUpgradeRequired | import("tenetkit/runtime/driver/sql/errors").SchemaVersionUnsupported | import("effect/unstable/sql/SqlError").SqlError, import("effect/Scope").Scope | SqlClient.SqlClient>;
|
|
@@ -1,52 +1,51 @@
|
|
|
1
1
|
import { Effect, Equal, Option } from "effect";
|
|
2
|
-
import { listRuns } from "tenetkit/runtime/driver/sql/store
|
|
2
|
+
import { listRuns } from "tenetkit/runtime/driver/sql/store/list";
|
|
3
3
|
import { SqlClient } from "effect/unstable/sql";
|
|
4
|
-
import { claimExecution, loadExecution, requireExecutionClaim, retryExecution, saveExecution, } from "tenetkit/runtime/driver/sql/store
|
|
4
|
+
import { claimExecution, loadExecution, requireExecutionClaim, retryExecution, saveExecution, } from "tenetkit/runtime/driver/sql/store/execution";
|
|
5
5
|
import { PgClient } from "@effect/sql-pg";
|
|
6
|
-
import { ApprovalStale, IdempotencyConflict, ResponseConflict } from "tenetkit/runtime/driver/errors";
|
|
7
|
-
import { ChildSelectionMissing, RunTerminal, RuntimeUnavailable, WaitNotOpen } from "tenetkit/runtime/driver/errors";
|
|
6
|
+
import { ApprovalStale, ChildSelectionMissing, IdempotencyConflict, ResponseConflict, RunTerminal, RuntimeUnavailable, WaitNotOpen, } from "tenetkit/runtime/driver/errors";
|
|
8
7
|
import { childDigest } from "tenetkit/runtime/driver/memory/digest";
|
|
9
|
-
import { enforceChildAdmission } from "tenetkit/runtime/driver/sql/store
|
|
10
|
-
import { equals, resolveChild } from "tenetkit/runtime/driver/executable
|
|
8
|
+
import { enforceChildAdmission } from "tenetkit/runtime/driver/sql/store/admit-send";
|
|
9
|
+
import { equals, resolveChild } from "tenetkit/runtime/driver/executable/manifest";
|
|
11
10
|
import { isTerminal } from "tenetkit/runtime/driver/run";
|
|
12
|
-
import { PendingRunOutcome, RunStore } from "tenetkit/runtime/driver/run
|
|
13
|
-
import { admitSteering, readSteering, saveCompletionContinuation } from "tenetkit/runtime/driver/sql/store
|
|
14
|
-
import { messagingStoreMethods } from "./
|
|
15
|
-
import { withSql } from "tenetkit/runtime/driver/sql/
|
|
16
|
-
import { makeEventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
17
|
-
import { check as checkSchema } from "
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import { postgresOperations } from "./
|
|
23
|
-
import { releaseLeasedExecution as releaseExecution } from "tenetkit/runtime/driver/sql/store
|
|
24
|
-
import { hasAdmission, loadRunWait } from "tenetkit/runtime/driver/sql/store
|
|
25
|
-
import { WaitResolution } from "tenetkit/runtime/driver/run
|
|
26
|
-
import { fanOutStoreMethods } from "./
|
|
27
|
-
import { deferCancelledFanOutParent,
|
|
28
|
-
import
|
|
29
|
-
import
|
|
30
|
-
import { withConsistentSnapshot } from "tenetkit/runtime/driver/sql/inspection
|
|
31
|
-
import { StringArray, decodePinnedEffect, decodeStoredPinnedEffect, encodeJson, } from "tenetkit/runtime/driver/sql/codecs";
|
|
32
|
-
import { suspend } from "./
|
|
33
|
-
import { afterTerminal, appendEvent, completeRun, emitAgentEvent, insertRun, loadEventsAfter, loadRun, requireRun, settleParent, } from "./
|
|
34
|
-
import { lockMailbox, lockRun, lockRunHierarchy, lockSpawnParent } from "
|
|
35
|
-
import { inspectionStoreMethods } from "./
|
|
36
|
-
import { programStoreMethods } from "./
|
|
37
|
-
import { admitStart as admitExactStart } from "tenetkit/runtime/driver/sql/store
|
|
38
|
-
import { activateRoot } from "tenetkit/runtime/driver/sql/store
|
|
39
|
-
import { admitSend } from "./
|
|
40
|
-
import { associateRegistrations, loadRegistrations } from "tenetkit/runtime/driver/sql/executable
|
|
41
|
-
import { narrow } from "tenetkit/runtime/driver/executable
|
|
11
|
+
import { PendingRunOutcome, RunStore } from "tenetkit/runtime/driver/run/store";
|
|
12
|
+
import { admitSteering, readSteering, saveCompletionContinuation, } from "tenetkit/runtime/driver/sql/store/steering/service";
|
|
13
|
+
import { messagingStoreMethods } from "./messaging.js";
|
|
14
|
+
import { withSql } from "tenetkit/runtime/driver/sql/effect";
|
|
15
|
+
import { make as makeEventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
16
|
+
import { check as checkSchema } from "../run-schema.js";
|
|
17
|
+
import "../schema.js";
|
|
18
|
+
import { transactionRunner, nextId } from "../events/transaction-events.js";
|
|
19
|
+
import { eventStream } from "../events/event-stream.js";
|
|
20
|
+
import { postgresClaims } from "./claims.js";
|
|
21
|
+
import { postgresOperations } from "./ops.js";
|
|
22
|
+
import { releaseLeasedExecution as releaseExecution } from "tenetkit/runtime/driver/sql/store/release-leased";
|
|
23
|
+
import { hasAdmission, loadRunWait } from "tenetkit/runtime/driver/sql/store/statements";
|
|
24
|
+
import { WaitResolution } from "tenetkit/runtime/driver/run/wait";
|
|
25
|
+
import { fanOutStoreMethods } from "./fan-out.js";
|
|
26
|
+
import { deferCancelledFanOutParent, cancelRunFor } from "./cancel.js";
|
|
27
|
+
import "tenetkit/runtime/driver/sql/tree-history";
|
|
28
|
+
import "tenetkit/runtime/driver/sql/inspection/service";
|
|
29
|
+
import { withConsistentSnapshot } from "tenetkit/runtime/driver/sql/inspection/transaction";
|
|
30
|
+
import { StringArray, decodePinnedEffect, decodeStoredPinnedEffect, encodeJson, } from "tenetkit/runtime/driver/sql/codec/codecs";
|
|
31
|
+
import { suspend } from "./suspend.js";
|
|
32
|
+
import { afterTerminal, appendEvent, completeRun, emitAgentEvent, insertRun, loadEventsAfter, loadRun, requireRun, settleParent, } from "./runtime.js";
|
|
33
|
+
import { lockMailbox, lockRun, lockRunHierarchy, lockSpawnParent } from "../runs/locks.js";
|
|
34
|
+
import { inspectionStoreMethods } from "./inspection.js";
|
|
35
|
+
import { programStoreMethods } from "./program.js";
|
|
36
|
+
import { admitStart as admitExactStart } from "tenetkit/runtime/driver/sql/store/admit";
|
|
37
|
+
import { activateRoot } from "tenetkit/runtime/driver/sql/store/activate";
|
|
38
|
+
import { admitSend } from "./admit.js";
|
|
39
|
+
import { associateRegistrations, loadRegistrations } from "tenetkit/runtime/driver/sql/executable/registrations";
|
|
40
|
+
import { narrow } from "tenetkit/runtime/driver/executable/registration";
|
|
42
41
|
import { approvalResponse } from "tenetkit/runtime/driver/sql/respond-approval";
|
|
43
42
|
import { settlementNotifications } from "tenetkit/runtime/driver/sql/settlement-notifications";
|
|
44
|
-
import { reconcileCancellationRequested } from "tenetkit/runtime/driver/sql/session
|
|
45
|
-
import { cancelSessionRuns } from "
|
|
46
|
-
import {
|
|
47
|
-
import { readinessForAdmission } from "tenetkit/runtime/driver/sql/store
|
|
48
|
-
import { hasPendingOperationCancellation } from "tenetkit/runtime/driver/sql/store
|
|
49
|
-
export const
|
|
43
|
+
import { reconcileCancellationRequested } from "tenetkit/runtime/driver/sql/session/lifecycle";
|
|
44
|
+
import { cancelSessionRuns } from "../sessions/session-cancellation.js";
|
|
45
|
+
import { postgresSessionStore } from "../sessions/session-store.js";
|
|
46
|
+
import { readinessForAdmission } from "tenetkit/runtime/driver/sql/store/child/capacity";
|
|
47
|
+
import { hasPendingOperationCancellation } from "tenetkit/runtime/driver/sql/store/child/settlement";
|
|
48
|
+
export const postgresServices = (options) => Effect.gen(function* () {
|
|
50
49
|
const source = options.source ?? "postgres";
|
|
51
50
|
const addressBindings = new Map(options.addresses.map((entry) => [entry.address, entry.executable]));
|
|
52
51
|
yield* checkSchema(source);
|
|
@@ -56,9 +55,9 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
56
55
|
const sql = yield* SqlClient.SqlClient;
|
|
57
56
|
yield* reconcileCancellationRequested;
|
|
58
57
|
const pg = yield* PgClient.PgClient;
|
|
59
|
-
const { run, runNoTxn, transactionHub } =
|
|
58
|
+
const { run, runNoTxn, transactionHub } = transactionRunner({ sql, pg, hub });
|
|
60
59
|
const runInspection = (effect) => withSql(sql, withConsistentSnapshot(sql, "postgres", effect.pipe(Effect.provideService(PgClient.PgClient, pg))));
|
|
61
|
-
const cancelRun =
|
|
60
|
+
const cancelRun = cancelRunFor({ sql, hub: transactionHub });
|
|
62
61
|
const operations = postgresOperations({
|
|
63
62
|
sql,
|
|
64
63
|
hub: transactionHub,
|
|
@@ -70,7 +69,7 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
70
69
|
});
|
|
71
70
|
const store = RunStore.of({
|
|
72
71
|
info: Effect.succeed({ durability: "durable", backend: "postgres", multiWorker: true }),
|
|
73
|
-
sessionStore: (sessionId) => Effect.succeed(Option.some(
|
|
72
|
+
sessionStore: (sessionId) => Effect.succeed(Option.some(postgresSessionStore({ sessionId, run, runNoTxn }))),
|
|
74
73
|
hasAdmission: (input) => runNoTxn(hasAdmission(input)),
|
|
75
74
|
admitSend: (input) => run(admitSend(transactionHub, addressBindings, nextId, input)),
|
|
76
75
|
admitStart: (input, startOptions) => run(sql `SELECT pg_advisory_xact_lock(hashtext('tenetkit:executable-registrations'))`.pipe(Effect.andThen(admitExactStart(transactionHub, input, startOptions)))),
|
|
@@ -84,8 +83,8 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
84
83
|
const digest = childDigest(input.message, executableRef, {
|
|
85
84
|
parentRunId: parent.runId,
|
|
86
85
|
invocationId: input.invocationId,
|
|
87
|
-
...(input.label === undefined ?
|
|
88
|
-
...(input.origin === undefined ?
|
|
86
|
+
...(input.label === undefined ? undefined : { label: input.label }),
|
|
87
|
+
...(input.origin === undefined ? undefined : { origin: input.origin }),
|
|
89
88
|
});
|
|
90
89
|
const executable = yield* decodePinnedEffect({
|
|
91
90
|
ref: executableRef,
|
|
@@ -112,7 +111,7 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
112
111
|
return {
|
|
113
112
|
runId: prior.run_id,
|
|
114
113
|
messageId: prior.message_id,
|
|
115
|
-
acceptedSequence:
|
|
114
|
+
acceptedSequence: prior.accepted_sequence,
|
|
116
115
|
duplicate: true,
|
|
117
116
|
};
|
|
118
117
|
}
|
|
@@ -146,8 +145,8 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
146
145
|
prompt: input.message.prompt,
|
|
147
146
|
childDepth: parent.depth + 1,
|
|
148
147
|
readiness: childReadiness,
|
|
149
|
-
...(input.label === undefined ?
|
|
150
|
-
...(input.origin === undefined ?
|
|
148
|
+
...(input.label === undefined ? undefined : { label: input.label }),
|
|
149
|
+
...(input.origin === undefined ? undefined : { origin: input.origin }),
|
|
151
150
|
});
|
|
152
151
|
const child = (yield* loadRun(runId));
|
|
153
152
|
yield* appendEvent(transactionHub, child, { _tag: "RunAccepted", messageId: input.message.id, address: input.message.to }, "queued");
|
|
@@ -159,7 +158,7 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
159
158
|
yield* appendEvent(transactionHub, { ...started, attempt: 1 }, { _tag: "RunAttemptStarted", attempt: 1 }, "running");
|
|
160
159
|
return { runId, messageId: input.message.id, acceptedSequence: 0, duplicate: false };
|
|
161
160
|
})),
|
|
162
|
-
events: (input) =>
|
|
161
|
+
events: (input) => eventStream({
|
|
163
162
|
hub,
|
|
164
163
|
pg,
|
|
165
164
|
runId: input.runId,
|
|
@@ -255,7 +254,7 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
255
254
|
const resolution = {
|
|
256
255
|
_tag: "Signal",
|
|
257
256
|
name: input.name,
|
|
258
|
-
...(input.payload === undefined ?
|
|
257
|
+
...(input.payload === undefined ? undefined : { payload: input.payload }),
|
|
259
258
|
};
|
|
260
259
|
yield* sql `
|
|
261
260
|
UPDATE tenetkit_run_waits SET status = 'signaled', response_json = ${encodeJson(WaitResolution, resolution)}, closed_at = NOW()
|
|
@@ -295,7 +294,10 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
295
294
|
if ((yield* deferCancelledFanOutParent(sql, loaded.runId)) ||
|
|
296
295
|
(yield* hasPendingOperationCancellation(loaded.runId)))
|
|
297
296
|
return;
|
|
298
|
-
const event = yield* appendEvent(transactionHub, loaded, {
|
|
297
|
+
const event = yield* appendEvent(transactionHub, loaded, {
|
|
298
|
+
_tag: "RunCancelled",
|
|
299
|
+
...(loaded.cancelReason === undefined ? undefined : { reason: loaded.cancelReason }),
|
|
300
|
+
}, "cancelled");
|
|
299
301
|
const settled = (yield* loadRun(loaded.runId));
|
|
300
302
|
yield* settleParent(transactionHub, settled, event.eventId);
|
|
301
303
|
yield* afterTerminal(transactionHub, settled);
|
|
@@ -372,6 +374,6 @@ export const makePostgresServices = (options) => Effect.gen(function* () {
|
|
|
372
374
|
...operations,
|
|
373
375
|
...programStoreMethods({ sql, hub: transactionHub, run, runNoTxn, lockRunHierarchy }),
|
|
374
376
|
});
|
|
375
|
-
const claims =
|
|
377
|
+
const claims = postgresClaims({ sql, hub: transactionHub, run, cancelRun });
|
|
376
378
|
return { store, claims };
|
|
377
379
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { PgClient } from "@effect/sql-pg";
|
|
2
|
-
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run
|
|
2
|
+
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run/store";
|
|
3
3
|
import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
4
|
-
import type { RunFn } from "./
|
|
5
|
-
import type { Run } from "./
|
|
4
|
+
import type { RunFn } from "./ops.js";
|
|
5
|
+
import type { Run } from "./fan-out.js";
|
|
6
6
|
export declare const inspectionStoreMethods: (deps: {
|
|
7
7
|
readonly hub: EventHub;
|
|
8
8
|
readonly pg: PgClient.PgClient;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Effect, Stream } from "effect";
|
|
2
2
|
import { CursorExpired } from "tenetkit/runtime/driver/errors";
|
|
3
|
-
import { loadRunSnapshot, loadTreeInspection } from "tenetkit/runtime/driver/sql/inspection";
|
|
4
|
-
import { sessionRoots } from "tenetkit/runtime/driver/sql/session
|
|
5
|
-
import { loadChildReadiness } from "tenetkit/runtime/driver/sql/store
|
|
6
|
-
import { loadRunWait } from "tenetkit/runtime/driver/sql/store
|
|
3
|
+
import { loadRunSnapshot, loadTreeInspection } from "tenetkit/runtime/driver/sql/inspection/service";
|
|
4
|
+
import { sessionRoots } from "tenetkit/runtime/driver/sql/session/lifecycle";
|
|
5
|
+
import { loadChildReadiness } from "tenetkit/runtime/driver/sql/store/child/capacity";
|
|
6
|
+
import { loadRunWait } from "tenetkit/runtime/driver/sql/store/statements";
|
|
7
7
|
import { loadTreeHistory } from "tenetkit/runtime/driver/sql/tree-history";
|
|
8
|
-
import { loadEventsAfter, loadRun, requireRun } from "./
|
|
9
|
-
import { NOTIFY_CHANNEL } from "
|
|
8
|
+
import { loadEventsAfter, loadRun, requireRun } from "./runtime.js";
|
|
9
|
+
import { NOTIFY_CHANNEL } from "../schema.js";
|
|
10
10
|
export const inspectionStoreMethods = (deps) => ({
|
|
11
11
|
inspect: (runId) => deps.runNoTxn(Effect.gen(function* () {
|
|
12
12
|
const loaded = yield* requireRun(runId);
|
|
@@ -21,9 +21,9 @@ export const inspectionStoreMethods = (deps) => ({
|
|
|
21
21
|
treePolicy: loaded.treePolicy,
|
|
22
22
|
lastSequence: loaded.lastSequence,
|
|
23
23
|
durability: "durable",
|
|
24
|
-
...(loaded.parentRunId === undefined ?
|
|
25
|
-
...(childReadiness === undefined ?
|
|
26
|
-
...(wait === undefined ?
|
|
24
|
+
...(loaded.parentRunId === undefined ? undefined : { parentRunId: loaded.parentRunId }),
|
|
25
|
+
...(childReadiness === undefined ? undefined : { childReadiness }),
|
|
26
|
+
...(wait === undefined ? undefined : { wait }),
|
|
27
27
|
};
|
|
28
28
|
})),
|
|
29
29
|
snapshot: (runId) => deps.runInspection(loadRunSnapshot(runId)),
|
|
@@ -39,6 +39,6 @@ export const inspectionStoreMethods = (deps) => ({
|
|
|
39
39
|
treeHistory: (input) => deps.runNoTxn(loadTreeHistory(input)),
|
|
40
40
|
treeChanges: (rootRunId) => deps.hub.subscribeTree({
|
|
41
41
|
rootRunId,
|
|
42
|
-
onSubscribed: deps.pg.listen(NOTIFY_CHANNEL).pipe(Stream.runForEach((runId) => deps.runNoTxn(loadRun(
|
|
42
|
+
onSubscribed: deps.pg.listen(NOTIFY_CHANNEL).pipe(Stream.runForEach((runId) => deps.runNoTxn(loadRun(runId)).pipe(Effect.flatMap((loaded) => (loaded?.rootRunId === rootRunId ? deps.hub.wakeTree(rootRunId) : Effect.void)), Effect.ignore)), Effect.ignore),
|
|
43
43
|
}),
|
|
44
44
|
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import type { SqlClient } from "effect/unstable/sql";
|
|
3
|
-
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run
|
|
3
|
+
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run/store";
|
|
4
4
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
5
|
-
import type { RunFn } from "./
|
|
5
|
+
import type { RunFn } from "./ops.js";
|
|
6
6
|
import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
7
7
|
/** The addressed-messaging half of the Postgres RunStore, kept beside the store it completes. */
|
|
8
8
|
export declare const messagingStoreMethods: (input: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { admitMessage, deliverPendingMessages, directory, listRelated, pendingMessages, registerAgentName, resolveAddress, } from "tenetkit/runtime/driver/sql/store
|
|
2
|
+
import { admitMessage, deliverPendingMessages, directory, listRelated, pendingMessages, registerAgentName, resolveAddress, } from "tenetkit/runtime/driver/sql/store/directory";
|
|
3
3
|
/** The addressed-messaging half of the Postgres RunStore, kept beside the store it completes. */
|
|
4
4
|
export const messagingStoreMethods = (input) => ({
|
|
5
5
|
directory: (runId) => input.runNoTxn(directory(runId)),
|
|
@@ -3,16 +3,16 @@ import type { PgClient } from "@effect/sql-pg";
|
|
|
3
3
|
import { SqlClient } from "effect/unstable/sql";
|
|
4
4
|
import type { SqlError } from "effect/unstable/sql/SqlError";
|
|
5
5
|
import { RuntimeUnavailable, type RunNotFound } from "tenetkit/runtime/driver/errors";
|
|
6
|
-
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run
|
|
7
|
-
import type { DecodedRun } from "tenetkit/runtime/driver/sql/rows";
|
|
6
|
+
import type { Interface as RunStoreInterface } from "tenetkit/runtime/driver/run/store";
|
|
7
|
+
import type { DecodedRun } from "tenetkit/runtime/driver/sql/codec/rows";
|
|
8
8
|
import type { EventHub } from "tenetkit/runtime/driver/sql/subscribers";
|
|
9
|
-
import type { RunFn } from "./
|
|
9
|
+
import type { RunFn } from "./ops.js";
|
|
10
10
|
type SqlR = SqlClient.SqlClient | PgClient.PgClient;
|
|
11
11
|
export declare const postgresModelResponseOperations: (input: {
|
|
12
12
|
readonly sql: SqlClient.SqlClient;
|
|
13
13
|
readonly hub: EventHub;
|
|
14
14
|
readonly run: RunFn;
|
|
15
15
|
readonly requireRun: (runId: string) => Effect.Effect<DecodedRun, RunNotFound | RuntimeUnavailable | SqlError, SqlR>;
|
|
16
|
-
readonly requireClaim: (claim: import("tenetkit/runtime/driver/run
|
|
16
|
+
readonly requireClaim: (claim: import("tenetkit/runtime/driver/run/store").ExecutionClaim) => Effect.Effect<void, import("tenetkit/runtime/driver/sql/errors").StaleClaim | RunNotFound | RuntimeUnavailable | SqlError, SqlR>;
|
|
17
17
|
}) => Pick<RunStoreInterface, "commitModelResponse" | "commitInterruptedModelResponse">;
|
|
18
18
|
export {};
|
|
@@ -1,14 +1,47 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
2
|
import { SqlClient } from "effect/unstable/sql";
|
|
3
3
|
import { RuntimeUnavailable } from "tenetkit/runtime/driver/errors";
|
|
4
|
-
import { appendEvent, loadEventsAfter, toOperationRecord } from "./
|
|
5
|
-
import { encodeExecutableRef, encodeJson, encodeJsonValue } from "tenetkit/runtime/driver/sql/codecs";
|
|
6
|
-
import { ExecutionCheckpoint } from "tenetkit/runtime/driver/execution
|
|
7
|
-
import { encodeContinuation } from "tenetkit/runtime/driver/steering";
|
|
8
|
-
import { checkpointRef } from "tenetkit/runtime/driver/executable
|
|
9
|
-
import { sameModelResponseEvent, validateModelResponseCommit } from "tenetkit/runtime/driver/model-response
|
|
10
|
-
import { sameInterruptedModelOutcome, sameInterruptedModelResponse, validateInterruptedModelResponse, } from "tenetkit/runtime/driver/model-response
|
|
11
|
-
import { appendCompletedSessionEntry, appendInterruptedSessionEntry, verifyCompletedSessionEntry, verifyInterruptedSessionEntry, } from "
|
|
4
|
+
import { appendEvent, loadEventsAfter, toOperationRecord } from "./runtime.js";
|
|
5
|
+
import { encodeExecutableRef, encodeJson, encodeJsonValue } from "tenetkit/runtime/driver/sql/codec/codecs";
|
|
6
|
+
import { ExecutionCheckpoint } from "tenetkit/runtime/driver/execution/state";
|
|
7
|
+
import { encodeContinuation } from "tenetkit/runtime/driver/run/steering";
|
|
8
|
+
import { checkpointRef } from "tenetkit/runtime/driver/executable/manifest";
|
|
9
|
+
import { sameModelResponseEvent, validateModelResponseCommit, } from "tenetkit/runtime/driver/execution/model-response/commit";
|
|
10
|
+
import { sameInterruptedModelOutcome, sameInterruptedModelResponse, validateInterruptedModelResponse, } from "tenetkit/runtime/driver/execution/model-response/interrupted";
|
|
11
|
+
import { appendCompletedSessionEntry, appendInterruptedSessionEntry, verifyCompletedSessionEntry, verifyInterruptedSessionEntry, } from "../sessions/session-store.js";
|
|
12
|
+
const verifyCompletedModelRetry = (input) => Effect.gen(function* () {
|
|
13
|
+
const { current, loaded, op } = input;
|
|
14
|
+
const validated = validateModelResponseCommit({
|
|
15
|
+
record: current,
|
|
16
|
+
input: op,
|
|
17
|
+
sessionId: loaded.message.sessionId,
|
|
18
|
+
});
|
|
19
|
+
if (Schema.is(RuntimeUnavailable)(validated))
|
|
20
|
+
return yield* validated;
|
|
21
|
+
const prior = (yield* loadEventsAfter(op.runId, -1)).filter((event) => event._tag === "ModelResponseCommitted" && event.operationKey === op.event.operationKey);
|
|
22
|
+
if (prior.length !== 1 ||
|
|
23
|
+
prior[0]?._tag !== "ModelResponseCommitted" ||
|
|
24
|
+
!sameModelResponseEvent({ left: prior[0], right: validated.event })) {
|
|
25
|
+
return yield* RuntimeUnavailable.make({
|
|
26
|
+
message: `model operation ${op.operationId} has a divergent outbox retry`,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
yield* verifyCompletedSessionEntry(validated.entry).pipe(Effect.mapError((error) => RuntimeUnavailable.make({ message: error.message })));
|
|
30
|
+
return current;
|
|
31
|
+
});
|
|
32
|
+
const verifySteeringOwnership = (sql, op) => Effect.gen(function* () {
|
|
33
|
+
for (const entryId of new Set(op.steeringEntryIds ?? [])) {
|
|
34
|
+
const rows = yield* sql `
|
|
35
|
+
SELECT consumed_operation_id FROM tenetkit_run_steering
|
|
36
|
+
WHERE run_id = ${op.runId} AND entry_id = ${entryId}
|
|
37
|
+
`;
|
|
38
|
+
if (rows[0]?.consumed_operation_id !== op.operationId) {
|
|
39
|
+
return yield* RuntimeUnavailable.make({
|
|
40
|
+
message: `steering entry ${entryId} does not belong to operation`,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
12
45
|
export const postgresModelResponseOperations = (input) => {
|
|
13
46
|
const { sql, hub, run, requireRun, requireClaim } = input;
|
|
14
47
|
const fenced = (claim, effect) => run(sql `SELECT run_id FROM tenetkit_runs WHERE run_id = ${claim.runId} FOR UPDATE`.pipe(Effect.andThen(requireClaim(claim)), Effect.andThen(effect)));
|
|
@@ -88,43 +121,18 @@ export const postgresModelResponseOperations = (input) => {
|
|
|
88
121
|
return yield* validated;
|
|
89
122
|
const sessionEntry = validated.entry;
|
|
90
123
|
if (current.status === "succeeded") {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
outcome: { _tag: "Succeeded", value: current.result },
|
|
96
|
-
},
|
|
97
|
-
sessionId: loaded.message.sessionId,
|
|
124
|
+
return yield* verifyCompletedModelRetry({
|
|
125
|
+
current,
|
|
126
|
+
loaded,
|
|
127
|
+
op: { ...op, outcome: { _tag: "Succeeded", value: current.result } },
|
|
98
128
|
});
|
|
99
|
-
if (Schema.is(RuntimeUnavailable)(priorValidation))
|
|
100
|
-
return yield* priorValidation;
|
|
101
|
-
const prior = (yield* loadEventsAfter(op.runId, -1)).filter((event) => event._tag === "ModelResponseCommitted" && event.operationKey === op.event.operationKey);
|
|
102
|
-
if (prior.length !== 1 ||
|
|
103
|
-
prior[0]?._tag !== "ModelResponseCommitted" ||
|
|
104
|
-
!sameModelResponseEvent({ left: prior[0], right: validated.event })) {
|
|
105
|
-
return yield* RuntimeUnavailable.make({
|
|
106
|
-
message: `model operation ${op.operationId} has a divergent outbox retry`,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
yield* verifyCompletedSessionEntry(sessionEntry).pipe(Effect.mapError((error) => RuntimeUnavailable.make({ message: error.message })));
|
|
110
|
-
return current;
|
|
111
129
|
}
|
|
112
130
|
if (current.status === "failed" || current.status === "unknown") {
|
|
113
131
|
return yield* RuntimeUnavailable.make({
|
|
114
132
|
message: `model operation ${op.operationId} already completed as ${current.status}`,
|
|
115
133
|
});
|
|
116
134
|
}
|
|
117
|
-
|
|
118
|
-
const rows = yield* sql `
|
|
119
|
-
SELECT consumed_operation_id FROM tenetkit_run_steering
|
|
120
|
-
WHERE run_id = ${op.runId} AND entry_id = ${entryId}
|
|
121
|
-
`;
|
|
122
|
-
if (rows[0]?.consumed_operation_id !== op.operationId) {
|
|
123
|
-
return yield* RuntimeUnavailable.make({
|
|
124
|
-
message: `steering entry ${entryId} does not belong to operation`,
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
}
|
|
135
|
+
yield* verifySteeringOwnership(sql, op);
|
|
128
136
|
const executableRef = yield* Effect.try({
|
|
129
137
|
try: () => checkpointRef(loaded.executableRef, loaded.executableManifest, op.checkpoint),
|
|
130
138
|
catch: (error) => RuntimeUnavailable.make({ message: String(error) }),
|