@nylorun/runtime 0.13.0-beta → 0.15.0-beta
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/CHANGELOG.md +434 -0
- package/README.md +137 -41
- package/dist/adapters/execution/restate.d.ts +7 -2
- package/dist/adapters/execution/restate.js +40 -10
- package/dist/adapters/replication/pgoutput.d.ts +21 -0
- package/dist/adapters/replication/pgoutput.js +170 -0
- package/dist/adapters/streams/s2.js +37 -20
- package/dist/admin-openapi.json +570 -0
- package/dist/api/a2a/card.d.ts +15 -0
- package/dist/api/a2a/card.js +24 -0
- package/dist/api/a2a/endpoint.d.ts +8 -0
- package/dist/api/a2a/endpoint.js +81 -0
- package/dist/api/a2a/protocol.d.ts +144 -0
- package/dist/api/a2a/protocol.js +188 -0
- package/dist/api/a2a/routes.d.ts +19 -0
- package/dist/api/a2a/routes.js +289 -0
- package/dist/api/a2a/tasks.d.ts +50 -0
- package/dist/api/a2a/tasks.js +186 -0
- package/dist/api/ag-ui/endpoint.d.ts +8 -0
- package/dist/api/ag-ui/endpoint.js +126 -0
- package/dist/api/ag-ui/history.d.ts +7 -0
- package/dist/api/ag-ui/history.js +60 -0
- package/dist/api/ag-ui/routes.d.ts +32 -0
- package/dist/api/ag-ui/routes.js +305 -0
- package/dist/api/ag-ui/session-id.d.ts +1 -0
- package/dist/api/ag-ui/session-id.js +12 -0
- package/dist/api/ag-ui/sse.d.ts +9 -0
- package/dist/api/ag-ui/sse.js +7 -0
- package/dist/api/ag-ui/translate.d.ts +38 -0
- package/dist/api/ag-ui/translate.js +222 -0
- package/dist/api/components.d.ts +8065 -0
- package/dist/api/components.js +82 -0
- package/dist/api/gate/keys.d.ts +14 -0
- package/dist/api/gate/keys.js +59 -0
- package/dist/api/gate/routes.d.ts +34 -0
- package/dist/api/gate/routes.js +235 -0
- package/dist/api/http/app.d.ts +18 -0
- package/dist/api/http/app.js +58 -0
- package/dist/api/http/body.d.ts +4 -0
- package/dist/api/http/body.js +37 -0
- package/dist/api/http/define.d.ts +39 -0
- package/dist/api/http/define.js +122 -0
- package/dist/api/http/respond.d.ts +9 -0
- package/dist/api/http/respond.js +44 -0
- package/dist/api/http/routes/access.d.ts +24 -0
- package/dist/api/http/routes/access.js +266 -0
- package/dist/api/http/routes/actions.d.ts +8 -0
- package/dist/api/http/routes/actions.js +76 -0
- package/dist/api/http/routes/endpoints.d.ts +7 -0
- package/dist/api/http/routes/endpoints.js +100 -0
- package/dist/api/http/routes/sessions.d.ts +3 -0
- package/dist/api/http/routes/sessions.js +205 -0
- package/dist/api/http/routes/tenant.d.ts +11 -0
- package/dist/api/http/routes/tenant.js +244 -0
- package/dist/api/http/routes/vaults.d.ts +8 -0
- package/dist/api/http/routes/vaults.js +167 -0
- package/dist/api/openapi.d.ts +19 -0
- package/dist/api/openapi.js +137 -0
- package/dist/api/route.d.ts +12 -0
- package/dist/api/route.js +4 -0
- package/dist/core/bearer.d.ts +8 -0
- package/dist/core/bearer.js +11 -0
- package/dist/core/flow-host.d.ts +7 -15
- package/dist/core/flow-host.js +16 -41
- package/dist/core/sandbox-routes.d.ts +12 -7
- package/dist/core/sandbox-routes.js +24 -25
- package/dist/execution/memory.d.ts +8 -5
- package/dist/execution/memory.js +33 -13
- package/dist/execution/types.d.ts +38 -6
- package/dist/execution/types.js +12 -3
- package/dist/gates/contract.d.ts +51 -0
- package/dist/gates/contract.js +37 -0
- package/dist/gates/handler.d.ts +21 -0
- package/dist/gates/handler.js +55 -0
- package/dist/gates/http-client.d.ts +12 -0
- package/dist/gates/http-client.js +160 -0
- package/dist/gates/in-process.d.ts +32 -0
- package/dist/gates/in-process.js +42 -0
- package/dist/gates/inflight.d.ts +39 -0
- package/dist/gates/inflight.js +70 -0
- package/dist/gates/mcp-handler.d.ts +35 -0
- package/dist/gates/mcp-handler.js +142 -0
- package/dist/gates/meter.d.ts +24 -0
- package/dist/gates/meter.js +165 -0
- package/dist/gates/model-gate.d.ts +45 -0
- package/dist/gates/model-gate.js +1 -0
- package/dist/gates/tenant-vaults.d.ts +64 -0
- package/dist/gates/tenant-vaults.js +94 -0
- package/dist/gates/tool-calls.d.ts +51 -0
- package/dist/gates/tool-calls.js +64 -0
- package/dist/gates/tool-client.d.ts +12 -0
- package/dist/gates/tool-client.js +201 -0
- package/dist/gates/tool-contract.d.ts +116 -0
- package/dist/gates/tool-contract.js +64 -0
- package/dist/gates/tool-gate.d.ts +45 -0
- package/dist/gates/tool-gate.js +10 -0
- package/dist/host/admin-api.d.ts +23 -0
- package/dist/host/admin-api.js +74 -0
- package/dist/host/app.d.ts +34 -0
- package/dist/host/app.js +181 -0
- package/dist/host/config-for.d.ts +3 -1
- package/dist/host/config-for.js +3 -2
- package/dist/host/config.d.ts +11 -0
- package/dist/host/cors.d.ts +27 -0
- package/dist/host/cors.js +64 -0
- package/dist/host/create-host.d.ts +36 -8
- package/dist/host/create-host.js +161 -330
- package/dist/host/execution.d.ts +20 -18
- package/dist/host/execution.js +2 -2
- package/dist/host/gates.d.ts +58 -0
- package/dist/host/gates.js +127 -0
- package/dist/host/http.d.ts +20 -4
- package/dist/host/http.js +81 -23
- package/dist/host/index.d.ts +1 -1
- package/dist/host/main.js +189 -58
- package/dist/host/stack-config.d.ts +91 -19
- package/dist/host/stack-config.js +246 -17
- package/dist/infra/database.d.ts +2 -2
- package/dist/infra/execution.d.ts +5 -5
- package/dist/infra/execution.js +8 -6
- package/dist/infra/index.d.ts +1 -1
- package/dist/infra/workers.d.ts +17 -17
- package/dist/infra/workers.js +9 -9
- package/dist/keys/client.d.ts +9 -0
- package/dist/keys/client.js +70 -0
- package/dist/keys/contract.d.ts +24 -0
- package/dist/keys/contract.js +12 -0
- package/dist/keys/keys.d.ts +41 -0
- package/dist/keys/keys.js +50 -0
- package/dist/mcp/connect.d.ts +43 -3
- package/dist/mcp/connect.js +12 -5
- package/dist/mcp/pool.d.ts +39 -3
- package/dist/mcp/pool.js +74 -11
- package/dist/model/catalog.d.ts +2 -10
- package/dist/model/classify.d.ts +13 -0
- package/dist/model/classify.js +61 -0
- package/dist/model/models.d.ts +10 -1
- package/dist/model/models.js +14 -6
- package/dist/model/pi-model.d.ts +17 -2
- package/dist/model/pi-model.js +366 -222
- package/dist/openapi.json +25889 -0
- package/dist/record/append.d.ts +51 -0
- package/dist/record/append.js +20 -0
- package/dist/record/envelope.d.ts +19 -0
- package/dist/record/envelope.js +49 -0
- package/dist/record/index.d.ts +11 -0
- package/dist/record/index.js +11 -0
- package/dist/sandbox/manager.d.ts +13 -1
- package/dist/sandbox/manager.js +8 -11
- package/dist/sandbox/resolve.d.ts +33 -0
- package/dist/sandbox/resolve.js +81 -0
- package/dist/sandbox/session-sandbox.d.ts +11 -0
- package/dist/sandbox/session-sandbox.js +51 -0
- package/dist/sandbox/share.d.ts +14 -2
- package/dist/sandbox/share.js +33 -3
- package/dist/sandbox/tenant-config.d.ts +37 -0
- package/dist/sandbox/tenant-config.js +51 -0
- package/dist/sandbox/tools.d.ts +7 -9
- package/dist/sandbox/tools.js +11 -3
- package/dist/sandbox/types.d.ts +8 -2
- package/dist/store/postgres/connect.d.ts +25 -9
- package/dist/store/postgres/connect.js +27 -10
- package/dist/store/postgres/db.d.ts +16 -0
- package/dist/store/postgres/db.js +28 -0
- package/dist/store/postgres/drizzle/0000_foundation.sql +22 -0
- package/dist/store/postgres/drizzle/0001_baseline.sql +255 -0
- package/dist/store/postgres/drizzle/0002_stream_relay.sql +4 -0
- package/dist/store/postgres/drizzle/0003_tool_crossings.sql +9 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +34 -0
- package/dist/store/postgres/migrate.d.ts +68 -0
- package/dist/store/postgres/migrate.js +183 -0
- package/dist/store/postgres/record-writer.d.ts +4 -0
- package/dist/store/postgres/record-writer.js +34 -0
- package/dist/store/postgres/record.d.ts +5 -0
- package/dist/store/postgres/record.js +60 -0
- package/dist/store/postgres/schema.d.ts +3096 -0
- package/dist/store/postgres/schema.js +363 -0
- package/dist/store/postgres/store.d.ts +2 -4
- package/dist/store/postgres/store.js +590 -434
- package/dist/store/postgres/tenant.d.ts +56 -0
- package/dist/store/postgres/tenant.js +154 -0
- package/dist/store/types.d.ts +183 -132
- package/dist/store/types.js +0 -1
- package/dist/streams/basin.d.ts +18 -1
- package/dist/streams/basin.js +34 -2
- package/dist/streams/control.d.ts +18 -0
- package/dist/streams/control.js +33 -0
- package/dist/streams/memory.d.ts +3 -1
- package/dist/streams/memory.js +14 -8
- package/dist/streams/relay/core.d.ts +35 -0
- package/dist/streams/relay/core.js +366 -0
- package/dist/streams/relay/types.d.ts +78 -0
- package/dist/streams/relay/types.js +8 -0
- package/dist/streams/types.d.ts +71 -36
- package/dist/streams/types.js +18 -53
- package/dist/tenant/access-policy.d.ts +30 -0
- package/dist/tenant/access-policy.js +52 -0
- package/dist/tenant/actions.d.ts +10 -149
- package/dist/tenant/actions.js +5 -167
- package/dist/tenant/advance.d.ts +7 -2
- package/dist/tenant/advance.js +125 -14
- package/dist/tenant/auth.d.ts +19 -17
- package/dist/tenant/auth.js +90 -93
- package/dist/tenant/browser.d.ts +15 -0
- package/dist/tenant/browser.js +39 -0
- package/dist/tenant/cause.d.ts +25 -0
- package/dist/tenant/cause.js +45 -0
- package/dist/tenant/commands.d.ts +18 -2
- package/dist/tenant/commands.js +111 -115
- package/dist/tenant/context.d.ts +101 -21
- package/dist/tenant/context.js +14 -10
- package/dist/tenant/delivery-token.d.ts +41 -0
- package/dist/tenant/delivery-token.js +104 -0
- package/dist/tenant/delivery.d.ts +62 -0
- package/dist/tenant/delivery.js +481 -0
- package/dist/tenant/effects.d.ts +20 -1
- package/dist/tenant/effects.js +159 -42
- package/dist/tenant/endpoints.d.ts +67 -0
- package/dist/tenant/endpoints.js +90 -0
- package/dist/tenant/ephemeral.d.ts +22 -7
- package/dist/tenant/ephemeral.js +83 -125
- package/dist/tenant/history.d.ts +64 -0
- package/dist/tenant/history.js +120 -0
- package/dist/tenant/http.d.ts +8 -9
- package/dist/tenant/http.js +13 -27
- package/dist/tenant/jwt.d.ts +16 -0
- package/dist/tenant/jwt.js +50 -0
- package/dist/tenant/model-setting.d.ts +2 -2
- package/dist/tenant/module.d.ts +17 -28
- package/dist/tenant/module.js +133 -279
- package/dist/tenant/outbound.d.ts +44 -0
- package/dist/tenant/outbound.js +127 -0
- package/dist/tenant/paths.d.ts +11 -16
- package/dist/tenant/paths.js +24 -68
- package/dist/tenant/pool.d.ts +1 -3
- package/dist/tenant/pool.js +1 -19
- package/dist/tenant/principals.d.ts +23 -11
- package/dist/tenant/principals.js +61 -49
- package/dist/tenant/reset.d.ts +0 -4
- package/dist/tenant/reset.js +0 -5
- package/dist/tenant/runtime.d.ts +28 -20
- package/dist/tenant/runtime.js +95 -64
- package/dist/tenant/scheduler.d.ts +10 -3
- package/dist/tenant/scheduler.js +9 -5
- package/dist/tenant/session-streams.d.ts +127 -0
- package/dist/tenant/session-streams.js +404 -0
- package/dist/tenant/sessions.d.ts +28 -4
- package/dist/tenant/sessions.js +118 -24
- package/dist/tenant/signing-keys.d.ts +55 -0
- package/dist/tenant/signing-keys.js +172 -0
- package/dist/tenant/slim.d.ts +8 -0
- package/dist/tenant/slim.js +21 -0
- package/dist/tenant/status.d.ts +3 -3
- package/dist/tenant/status.js +20 -13
- package/dist/tenant/store-pg.d.ts +9 -6
- package/dist/tenant/store-pg.js +60 -125
- package/dist/tenant/streams.d.ts +62 -85
- package/dist/tenant/streams.js +143 -226
- package/dist/tenant/subject-limits.d.ts +16 -0
- package/dist/tenant/subject-limits.js +45 -0
- package/dist/tenant/sweep.d.ts +1 -10
- package/dist/tenant/sweep.js +29 -69
- package/dist/tenant/tokens.d.ts +14 -0
- package/dist/tenant/tokens.js +180 -0
- package/dist/tenant/transcript.d.ts +48 -5
- package/dist/tenant/transcript.js +58 -1
- package/dist/tenant/types.d.ts +69 -98
- package/dist/tenant/types.js +4 -15
- package/dist/tenant/worker.d.ts +3 -1
- package/dist/tenant/worker.js +13 -7
- package/dist/vault/host-model.d.ts +31 -0
- package/dist/vault/host-model.js +57 -0
- package/dist/vault/service.d.ts +44 -17
- package/dist/vault/service.js +126 -121
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +25 -9
- package/dist/core/executors.d.ts +0 -44
- package/dist/core/executors.js +0 -95
- package/dist/store/memory.d.ts +0 -57
- package/dist/store/memory.js +0 -645
- package/dist/store/postgres/migrations/001_initial.d.ts +0 -27
- package/dist/store/postgres/migrations/001_initial.js +0 -196
- package/dist/store/postgres/migrations/002_session_owner.d.ts +0 -6
- package/dist/store/postgres/migrations/002_session_owner.js +0 -13
- package/dist/store/postgres/migrations/index.d.ts +0 -49
- package/dist/store/postgres/migrations/index.js +0 -76
- package/dist/store/postgres/names.d.ts +0 -11
- package/dist/store/postgres/names.js +0 -42
- package/dist/store/postgres/tenants.d.ts +0 -90
- package/dist/store/postgres/tenants.js +0 -214
- package/dist/streams/relay.d.ts +0 -37
- package/dist/streams/relay.js +0 -254
- package/dist/tenant/envelope.d.ts +0 -7
- package/dist/tenant/envelope.js +0 -22
- package/dist/tenant/live.d.ts +0 -92
- package/dist/tenant/live.js +0 -290
- package/dist/tenant/quarantine-error.d.ts +0 -6
- package/dist/tenant/quarantine-error.js +0 -9
- package/dist/tenant/quarantine.d.ts +0 -27
- package/dist/tenant/quarantine.js +0 -72
- package/dist/tenant/routes-tenant.d.ts +0 -12
- package/dist/tenant/routes-tenant.js +0 -137
- package/dist/tenant/routes.d.ts +0 -9
- package/dist/tenant/routes.js +0 -151
- package/dist/tenant/store-memory.d.ts +0 -16
- package/dist/tenant/store-memory.js +0 -111
- /package/dist/{store → record}/cursor.d.ts +0 -0
- /package/dist/{store → record}/cursor.js +0 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tables of a Tenant database (session-store.md §2–§3): the source drizzle-kit generates
|
|
3
|
+
* the migrations from (`drizzle/`, `CONTRIBUTING.md` "Adding a migration") and the query
|
|
4
|
+
* builder's view of them. Column names are the camelCase keys in snake_case (`casing:
|
|
5
|
+
* "snake_case"`, here, in `db.ts` and in `drizzle.config.ts`).
|
|
6
|
+
*
|
|
7
|
+
* - `nylorun` holds the Tenant's state: the one `tenant` row, the document tables, Action
|
|
8
|
+
* endpoints, principals, vaults and credentials, signing keys, publishable keys, subject
|
|
9
|
+
* epochs and usage, settings, the model usage ledger, the model budgets and the Tool Gate's
|
|
10
|
+
* crossings.
|
|
11
|
+
* - `nylorun_streams` holds the record (Durable Streams §6): `session_events`,
|
|
12
|
+
* `session_log_heads` and the relay's `relay_slots`. The relay's publication is custom SQL
|
|
13
|
+
* (`drizzle/0002_stream_relay.sql`).
|
|
14
|
+
*
|
|
15
|
+
* What the columns keep:
|
|
16
|
+
*
|
|
17
|
+
* - **Bodies are `json`, not `jsonb`** (`jsonText`), written as the text `JSON.stringify`
|
|
18
|
+
* wrote, so every string round-trips exactly, key order included. `jsonb` rejects the
|
|
19
|
+
* escapes `\u0000` (`22P05`) and unpaired surrogates (`\ud800`), which tool output can
|
|
20
|
+
* contain; `json` stores the text verbatim and checks only its syntax.
|
|
21
|
+
* - **Indexed fields of a body are stored generated columns** read through
|
|
22
|
+
* `nylorun.doc(body)` (custom SQL, `drizzle/0000_foundation.sql`), which casts to `jsonb`
|
|
23
|
+
* after replacing those two escapes with `\ufffd`: the body is untouched, and only an indexed
|
|
24
|
+
* field that itself contained one (never an id, status or timestamp) would see U+FFFD.
|
|
25
|
+
* Queries never apply `->`/`->>` to a `json` body (Postgres de-escapes the whole text and
|
|
26
|
+
* fails on the same escapes); they read the generated columns.
|
|
27
|
+
* - **Ids and timestamps compared as text are `COLLATE "C"`** (`textC`), so they order by code
|
|
28
|
+
* point whatever the database's collation.
|
|
29
|
+
* - **Timestamps are ISO text**, except the session lease `owner_expires_at` and the record's
|
|
30
|
+
* `committed_at` (`timestamptz`).
|
|
31
|
+
* - **Sealed secrets are `bytea` columns** (`bytes`), never inside a JSON body.
|
|
32
|
+
* - Sessions carry the store-managed ownership columns (`owner`, `epoch`,
|
|
33
|
+
* `owner_expires_at`), which are never in `body`.
|
|
34
|
+
*
|
|
35
|
+
* Columns are listed in the order the tables have them, so a database created by these
|
|
36
|
+
* migrations and one created by the hand-written migrations they replaced dump the same.
|
|
37
|
+
*/
|
|
38
|
+
import { sql } from "drizzle-orm";
|
|
39
|
+
import { bigint, boolean, check, customType, doublePrecision, foreignKey, index, integer, pgSchema, primaryKey, text, timestamp, uniqueIndex, } from "drizzle-orm/pg-core";
|
|
40
|
+
export const TENANT_SCHEMA = "nylorun";
|
|
41
|
+
export const STREAMS_SCHEMA = "nylorun_streams";
|
|
42
|
+
/** The publication the stream relay subscribes to (`drizzle/0002_stream_relay.sql`). */
|
|
43
|
+
export const STREAMS_PUBLICATION = "nylorun_stream_relay";
|
|
44
|
+
export const nylorun = pgSchema(TENANT_SCHEMA);
|
|
45
|
+
export const nylorunStreams = pgSchema(STREAMS_SCHEMA);
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// Column types
|
|
48
|
+
/** JSON text of `value`. Throws when `value` is not JSON (`undefined`, a function). */
|
|
49
|
+
export function toJson(value) {
|
|
50
|
+
const json = JSON.stringify(value);
|
|
51
|
+
if (json === undefined)
|
|
52
|
+
throw new Error("Document body must be JSON");
|
|
53
|
+
return json;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A `json` column written as the text `JSON.stringify` makes (`$1::text::json`), so the
|
|
57
|
+
* database keeps exactly that text. postgres.js parses `json` results, so a read gives the
|
|
58
|
+
* parsed value as is.
|
|
59
|
+
*/
|
|
60
|
+
export const jsonText = customType({
|
|
61
|
+
dataType: () => "json",
|
|
62
|
+
toDriver: (value) => sql `${toJson(value)}::text::json`,
|
|
63
|
+
});
|
|
64
|
+
/** `bytea` to and from `Uint8Array` (postgres.js reads a `Buffer`; the row gets a copy). */
|
|
65
|
+
export const bytes = customType({
|
|
66
|
+
dataType: () => "bytea",
|
|
67
|
+
toDriver: (value) => Buffer.from(value.buffer, value.byteOffset, value.byteLength),
|
|
68
|
+
fromDriver: (value) => new Uint8Array(value),
|
|
69
|
+
});
|
|
70
|
+
/** `text COLLATE "C"`: ids and ISO timestamps that order by code point. */
|
|
71
|
+
export const textC = customType({
|
|
72
|
+
dataType: () => 'text COLLATE "C"',
|
|
73
|
+
});
|
|
74
|
+
/** A generated column reading `path` of the body through `nylorun.doc(body)`. */
|
|
75
|
+
const field = (path) => text().generatedAlwaysAs(sql.raw(`nylorun.doc(body)${path}`));
|
|
76
|
+
/** A table of JSON documents keyed by `id`. */
|
|
77
|
+
const documents = (name) => nylorun.table(name, { id: textC().primaryKey(), body: jsonText().notNull() });
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// nylorun: the Tenant's state
|
|
80
|
+
/** The Tenant envelope: one row (`singleton`). */
|
|
81
|
+
export const tenant = nylorun.table("tenant", {
|
|
82
|
+
id: textC().primaryKey(),
|
|
83
|
+
name: text().notNull(),
|
|
84
|
+
createdAt: text().notNull(),
|
|
85
|
+
updatedAt: text().notNull(),
|
|
86
|
+
/** The number of migrations applied when the row was last migrated (`migrate.ts`). */
|
|
87
|
+
schemaVersion: integer().notNull(),
|
|
88
|
+
singleton: boolean().notNull().default(true).unique("tenant_singleton_key"),
|
|
89
|
+
/** The basin generation session streams go to (Durable Streams §8.1). */
|
|
90
|
+
basinGeneration: integer().notNull().default(0),
|
|
91
|
+
/** Earlier generations whose basins are still to be deleted. */
|
|
92
|
+
retiredGenerations: integer().array().notNull().default(sql `'{}'`),
|
|
93
|
+
}, () => [check("tenant_singleton_check", sql `singleton`)]);
|
|
94
|
+
export const definitions = documents("definitions");
|
|
95
|
+
export const sessions = nylorun.table("sessions", {
|
|
96
|
+
id: textC().primaryKey(),
|
|
97
|
+
body: jsonText().notNull(),
|
|
98
|
+
status: field("->>'status'"),
|
|
99
|
+
agentId: field("->>'agentId'"),
|
|
100
|
+
/** The lease holder; store-managed, never in `body`. */
|
|
101
|
+
owner: text(),
|
|
102
|
+
epoch: bigint({ mode: "number" }).notNull().default(0),
|
|
103
|
+
ownerExpiresAt: timestamp({ withTimezone: true, mode: "date" }),
|
|
104
|
+
/** The session owner (`ownerUserId`), not the lease column `owner`. */
|
|
105
|
+
ownerUserId: field("->>'ownerUserId'"),
|
|
106
|
+
}, (t) => [
|
|
107
|
+
index("sessions_status").on(t.status, t.ownerExpiresAt),
|
|
108
|
+
index("sessions_agent").on(t.agentId),
|
|
109
|
+
index("sessions_owner_user").on(t.ownerUserId),
|
|
110
|
+
]);
|
|
111
|
+
export const commands = documents("commands");
|
|
112
|
+
export const effects = nylorun.table("effects", {
|
|
113
|
+
id: textC().primaryKey(),
|
|
114
|
+
body: jsonText().notNull(),
|
|
115
|
+
sessionId: field("->'request'->>'sessionId'"),
|
|
116
|
+
turnId: field("->'request'->>'turnId'"),
|
|
117
|
+
kind: field("->'request'->>'kind'"),
|
|
118
|
+
status: field("->>'status'"),
|
|
119
|
+
}, (t) => [
|
|
120
|
+
index("effects_session").on(t.sessionId, t.turnId, t.status),
|
|
121
|
+
index("effects_status").on(t.status, t.kind),
|
|
122
|
+
]);
|
|
123
|
+
export const actions = nylorun.table("actions", {
|
|
124
|
+
id: textC().primaryKey(),
|
|
125
|
+
body: jsonText().notNull(),
|
|
126
|
+
sessionId: field("->>'sessionId'"),
|
|
127
|
+
turnId: field("->>'turnId'"),
|
|
128
|
+
agentId: field("->>'agentId'"),
|
|
129
|
+
status: field("->>'status'"),
|
|
130
|
+
kind: field("->>'kind'"),
|
|
131
|
+
/** When the Action being delivered is lost (ISO text). */
|
|
132
|
+
deadlineAt: field("->>'deadlineAt'"),
|
|
133
|
+
}, (t) => [
|
|
134
|
+
index("actions_session").on(t.sessionId, t.turnId, t.status),
|
|
135
|
+
index("actions_agent").on(t.agentId, t.status),
|
|
136
|
+
index("actions_status").on(t.status, t.kind),
|
|
137
|
+
index("actions_deadline").on(t.status, t.deadlineAt),
|
|
138
|
+
]);
|
|
139
|
+
export const sandboxes = documents("sandboxes");
|
|
140
|
+
export const links = nylorun.table("links", {
|
|
141
|
+
id: textC().primaryKey(),
|
|
142
|
+
body: jsonText().notNull(),
|
|
143
|
+
workflowSessionId: field("->>'workflowSessionId'"),
|
|
144
|
+
}, (t) => [index("links_workflow").on(t.workflowSessionId)]);
|
|
145
|
+
/** An application principal: who holds a key, by its SHA-256. */
|
|
146
|
+
export const principals = nylorun.table("principals", {
|
|
147
|
+
id: textC().primaryKey(),
|
|
148
|
+
role: text().$type().notNull(),
|
|
149
|
+
tokenHash: text().notNull().unique("principals_token_hash_key"),
|
|
150
|
+
idempotencyKey: text(),
|
|
151
|
+
createdAt: text().notNull(),
|
|
152
|
+
});
|
|
153
|
+
export const vaults = nylorun.table("vaults", {
|
|
154
|
+
id: textC().primaryKey(),
|
|
155
|
+
name: text().notNull(),
|
|
156
|
+
ownerUserId: text().notNull(),
|
|
157
|
+
/** JSON text, or null. */
|
|
158
|
+
metadataJson: text(),
|
|
159
|
+
createdAt: textC().notNull(),
|
|
160
|
+
scope: text({ enum: ["user", "host"] }).notNull().default("user"),
|
|
161
|
+
}, (t) => [
|
|
162
|
+
index("vaults_owner").on(t.ownerUserId, t.createdAt, t.id),
|
|
163
|
+
uniqueIndex("vaults_one_host").on(t.scope).where(sql `scope = 'host'`),
|
|
164
|
+
check("vaults_scope_check", sql `scope IN ('user', 'host')`),
|
|
165
|
+
]);
|
|
166
|
+
/** A credential of a vault: its binding in the clear, its secret sealed. */
|
|
167
|
+
export const vaultCredentials = nylorun.table("vault_credentials", {
|
|
168
|
+
id: textC().primaryKey(),
|
|
169
|
+
vaultId: text().notNull(),
|
|
170
|
+
name: text().notNull(),
|
|
171
|
+
type: text({ enum: ["bearer", "oauth", "model"] }).notNull(),
|
|
172
|
+
/** JSON text of the non-secret binding (url, or provider and model). */
|
|
173
|
+
bindingJson: text().notNull(),
|
|
174
|
+
expiresAt: text(),
|
|
175
|
+
createdAt: textC().notNull(),
|
|
176
|
+
rotatedAt: text(),
|
|
177
|
+
kekId: text().notNull(),
|
|
178
|
+
nonce: bytes().notNull(),
|
|
179
|
+
ciphertext: bytes().notNull(),
|
|
180
|
+
wrappedDek: bytes().notNull(),
|
|
181
|
+
}, (t) => [
|
|
182
|
+
foreignKey({
|
|
183
|
+
name: "vault_credentials_vault_id_fkey",
|
|
184
|
+
columns: [t.vaultId],
|
|
185
|
+
foreignColumns: [vaults.id],
|
|
186
|
+
}).onDelete("cascade"),
|
|
187
|
+
index("vault_credentials_vault").on(t.vaultId, t.createdAt, t.id),
|
|
188
|
+
]);
|
|
189
|
+
export const vaultAudit = nylorun.table("vault_audit", {
|
|
190
|
+
ord: bigint({ mode: "number" }).primaryKey().generatedAlwaysAsIdentity(),
|
|
191
|
+
id: text().notNull().unique("vault_audit_id_key"),
|
|
192
|
+
at: text().notNull(),
|
|
193
|
+
actor: text().notNull(),
|
|
194
|
+
action: text().notNull(),
|
|
195
|
+
vaultId: text(),
|
|
196
|
+
credentialId: text(),
|
|
197
|
+
sessionId: text(),
|
|
198
|
+
target: text(),
|
|
199
|
+
outcome: text().notNull(),
|
|
200
|
+
}, (t) => [index("vault_audit_vault").on(t.vaultId, t.ord)]);
|
|
201
|
+
export const vaultIdempotency = nylorun.table("vault_idempotency", {
|
|
202
|
+
id: text().primaryKey(),
|
|
203
|
+
bodyHash: text().notNull(),
|
|
204
|
+
/** JSON text of the original response. */
|
|
205
|
+
response: text().notNull(),
|
|
206
|
+
});
|
|
207
|
+
export const tenantSettings = nylorun.table("tenant_settings", {
|
|
208
|
+
key: text().primaryKey(),
|
|
209
|
+
value: text().notNull(),
|
|
210
|
+
});
|
|
211
|
+
/** The Tenant's signing keys (subject tokens): the private half sealed, the public JWK not. */
|
|
212
|
+
export const signingKeys = nylorun.table("signing_keys", {
|
|
213
|
+
id: textC().primaryKey(),
|
|
214
|
+
state: text({ enum: ["standby", "current", "previous", "revoked"] }).notNull(),
|
|
215
|
+
alg: text({ enum: ["ES256"] }).notNull(),
|
|
216
|
+
/** JSON text of the public JWK. */
|
|
217
|
+
publicJwk: text().notNull(),
|
|
218
|
+
kekId: text().notNull(),
|
|
219
|
+
nonce: bytes().notNull(),
|
|
220
|
+
ciphertext: bytes().notNull(),
|
|
221
|
+
wrappedDek: bytes().notNull(),
|
|
222
|
+
createdAt: text().notNull(),
|
|
223
|
+
activatedAt: text(),
|
|
224
|
+
retiredAt: text(),
|
|
225
|
+
revokedAt: text(),
|
|
226
|
+
}, (t) => [
|
|
227
|
+
check("signing_keys_state_check", sql `state IN ('standby', 'current', 'previous', 'revoked')`),
|
|
228
|
+
check("signing_keys_alg_check", sql `alg = 'ES256'`),
|
|
229
|
+
uniqueIndex("signing_keys_one_standby").on(t.state).where(sql `state = 'standby'`),
|
|
230
|
+
uniqueIndex("signing_keys_one_current").on(t.state).where(sql `state = 'current'`),
|
|
231
|
+
uniqueIndex("signing_keys_one_previous").on(t.state).where(sql `state = 'previous'`),
|
|
232
|
+
]);
|
|
233
|
+
/** Each subject's revocation epoch. */
|
|
234
|
+
export const subjectEpochs = nylorun.table("subject_epochs", {
|
|
235
|
+
subject: textC().primaryKey(),
|
|
236
|
+
epoch: bigint({ mode: "number" }).notNull(),
|
|
237
|
+
revokedAt: text().notNull(),
|
|
238
|
+
});
|
|
239
|
+
/** Each subject's turn bucket: tokens left and when they were last refilled. */
|
|
240
|
+
export const subjectUsage = nylorun.table("subject_usage", {
|
|
241
|
+
subject: textC().primaryKey(),
|
|
242
|
+
turnTokens: doublePrecision().notNull(),
|
|
243
|
+
refilledAt: text().notNull(),
|
|
244
|
+
});
|
|
245
|
+
/** Publishable keys (Host feature `browser-access`): public by design. */
|
|
246
|
+
export const publishableKeys = nylorun.table("publishable_keys", {
|
|
247
|
+
id: textC().primaryKey(),
|
|
248
|
+
key: textC().notNull().unique("publishable_keys_key_key"),
|
|
249
|
+
name: text().notNull().unique("publishable_keys_name_key"),
|
|
250
|
+
/** JSON array of allowed origins. */
|
|
251
|
+
originsJson: text().notNull(),
|
|
252
|
+
createdAt: text().notNull(),
|
|
253
|
+
revokedAt: text(),
|
|
254
|
+
});
|
|
255
|
+
/**
|
|
256
|
+
* Action endpoints: where the Runtime delivers each agent's Actions over HTTP, and the health
|
|
257
|
+
* recent deliveries and the last ping report.
|
|
258
|
+
*/
|
|
259
|
+
export const endpoints = nylorun.table("endpoints", {
|
|
260
|
+
agentId: textC().primaryKey(),
|
|
261
|
+
url: text().notNull(),
|
|
262
|
+
implementationVersion: text().notNull(),
|
|
263
|
+
manifestHash: text(),
|
|
264
|
+
timeoutMs: integer().notNull(),
|
|
265
|
+
maxConcurrent: integer().notNull(),
|
|
266
|
+
principalId: text(),
|
|
267
|
+
lastDeliveryAt: text(),
|
|
268
|
+
lastSuccessAt: text(),
|
|
269
|
+
lastErrorCode: text(),
|
|
270
|
+
lastErrorMessage: text(),
|
|
271
|
+
consecutiveFailures: integer().notNull().default(0),
|
|
272
|
+
servedImplementationVersion: text(),
|
|
273
|
+
servedManifestHash: text(),
|
|
274
|
+
createdAt: text().notNull(),
|
|
275
|
+
updatedAt: text().notNull(),
|
|
276
|
+
});
|
|
277
|
+
/**
|
|
278
|
+
* The model usage ledger (P1.3): one row per model call a gate served, written after the call.
|
|
279
|
+
* A second row for the same effect (a call the gate ran again after a gateway restart) is
|
|
280
|
+
* flagged `duplicate`; both were billed. Budgets read their spend from it. Token counts are 0
|
|
281
|
+
* when the provider sent none.
|
|
282
|
+
*/
|
|
283
|
+
export const modelUsage = nylorun.table("model_usage", {
|
|
284
|
+
id: textC().primaryKey(),
|
|
285
|
+
/** The model effect's id; unique per Tenant, since it carries the turn id. */
|
|
286
|
+
effectKey: textC().notNull(),
|
|
287
|
+
sessionId: textC().notNull(),
|
|
288
|
+
turnId: textC().notNull(),
|
|
289
|
+
agentId: textC().notNull(),
|
|
290
|
+
provider: text(),
|
|
291
|
+
model: text(),
|
|
292
|
+
inputTokens: integer().notNull(),
|
|
293
|
+
outputTokens: integer().notNull(),
|
|
294
|
+
totalTokens: integer().notNull(),
|
|
295
|
+
cachedTokens: integer().notNull(),
|
|
296
|
+
cacheWriteTokens: integer().notNull(),
|
|
297
|
+
reasoningTokens: integer().notNull(),
|
|
298
|
+
costUsd: doublePrecision().notNull(),
|
|
299
|
+
/** True when an earlier row has the same `effectKey`: the provider billed the call twice. */
|
|
300
|
+
duplicate: boolean().notNull(),
|
|
301
|
+
createdAt: text().notNull(),
|
|
302
|
+
}, (t) => [
|
|
303
|
+
index("model_usage_effect").on(t.effectKey),
|
|
304
|
+
index("model_usage_agent").on(t.agentId, t.createdAt),
|
|
305
|
+
index("model_usage_turn").on(t.turnId),
|
|
306
|
+
index("model_usage_created").on(t.createdAt),
|
|
307
|
+
]);
|
|
308
|
+
/**
|
|
309
|
+
* Model budgets (P1.3): hard caps the model gate checks before each call, at least one limit
|
|
310
|
+
* set. One row per scope: `turn` and `tenant` use `*`, `agent` the agent id. `period` is the
|
|
311
|
+
* UTC `day` or `month` the spend is counted over, or null for `turn`.
|
|
312
|
+
*/
|
|
313
|
+
export const modelBudgets = nylorun.table("model_budgets", {
|
|
314
|
+
scope: text({ enum: ["tenant", "agent", "turn"] }).notNull(),
|
|
315
|
+
scopeId: textC().notNull(),
|
|
316
|
+
period: text({ enum: ["day", "month"] }),
|
|
317
|
+
limitUsd: doublePrecision(),
|
|
318
|
+
limitTokens: bigint({ mode: "number" }),
|
|
319
|
+
updatedAt: text().notNull(),
|
|
320
|
+
}, (t) => [primaryKey({ name: "model_budgets_pkey", columns: [t.scope, t.scopeId] })]);
|
|
321
|
+
/**
|
|
322
|
+
* The Tool Gate's keyed MCP calls (F4.1 G3): one row per call, written by the gates service
|
|
323
|
+
* before it calls the server and given the answer after. A re-send whose row has an answer
|
|
324
|
+
* gets it; one whose row has none, and that the gateway no longer runs, was lost with an
|
|
325
|
+
* earlier gateway and answers `uncertain`, so a call is never run twice. Rows are deleted a
|
|
326
|
+
* day after they settle.
|
|
327
|
+
*/
|
|
328
|
+
export const toolCrossings = nylorun.table("tool_crossings", {
|
|
329
|
+
/** The call's effect id (`Idempotency-Key`). */
|
|
330
|
+
key: textC().primaryKey(),
|
|
331
|
+
/** SHA-256 of the canonical request: a re-send with another request is refused. */
|
|
332
|
+
hash: text().notNull(),
|
|
333
|
+
startedAt: textC().notNull(),
|
|
334
|
+
settledAt: textC(),
|
|
335
|
+
/** The gate's answer (`McpAnswer`), once the call ended; null while it runs or once lost. */
|
|
336
|
+
answer: jsonText(),
|
|
337
|
+
}, (t) => [index("tool_crossings_settled").on(t.settledAt)]);
|
|
338
|
+
// ---------------------------------------------------------------------------
|
|
339
|
+
// nylorun_streams: the record
|
|
340
|
+
/** Each session's log head: the next seq and the basin generation its events go to. */
|
|
341
|
+
export const sessionLogHeads = nylorunStreams.table("session_log_heads", {
|
|
342
|
+
sessionId: textC().primaryKey(),
|
|
343
|
+
generation: integer().notNull(),
|
|
344
|
+
head: bigint({ mode: "number" }).notNull().default(0),
|
|
345
|
+
});
|
|
346
|
+
/** The record of every session event, the `nylorun.event/2` envelope as written. */
|
|
347
|
+
export const sessionEvents = nylorunStreams.table("session_events", {
|
|
348
|
+
sessionId: textC().notNull(),
|
|
349
|
+
seq: bigint({ mode: "number" }).notNull(),
|
|
350
|
+
generation: integer().notNull(),
|
|
351
|
+
type: text().notNull(),
|
|
352
|
+
body: jsonText().notNull(),
|
|
353
|
+
committedAt: timestamp({ withTimezone: true, mode: "string" }).notNull().defaultNow(),
|
|
354
|
+
}, (t) => [primaryKey({ name: "session_events_pkey", columns: [t.sessionId, t.seq] })]);
|
|
355
|
+
/**
|
|
356
|
+
* One row per replication slot: whether the record still has to be reconciled with S2 after
|
|
357
|
+
* the slot was created (a crash during reconciliation leaves it pending). The stream relay's
|
|
358
|
+
* replication adapter reads and writes it (`adapters/replication/pgoutput.ts`).
|
|
359
|
+
*/
|
|
360
|
+
export const relaySlots = nylorunStreams.table("relay_slots", {
|
|
361
|
+
slotName: text().primaryKey(),
|
|
362
|
+
reconcilePending: boolean().notNull(),
|
|
363
|
+
});
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { Sql } from "postgres";
|
|
2
2
|
import type { SessionStore, SessionStoreOptions } from "../types.js";
|
|
3
3
|
export interface PostgresSessionStoreOptions extends SessionStoreOptions {
|
|
4
|
-
/** The
|
|
4
|
+
/** The pool on the Tenant's database. The store never ends it. */
|
|
5
5
|
sql: Sql;
|
|
6
|
-
/** The
|
|
7
|
-
schema?: string;
|
|
8
|
-
/** The version `health()` expects. Defaults to `POSTGRES_SCHEMA_VERSION`. */
|
|
6
|
+
/** The schema version `health()` expects. Defaults to the shipped migrations' count. */
|
|
9
7
|
schemaVersion?: number;
|
|
10
8
|
}
|
|
11
9
|
export declare function createPostgresSessionStore(options: PostgresSessionStoreOptions): SessionStore;
|