@evelinka-ai/core 0.3.0 → 0.4.0
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/README.md +14 -0
- package/dist/agent-lib/llm-semaphore.d.ts.map +1 -1
- package/dist/agent-lib/llm-semaphore.js +2 -34
- package/dist/agent-lib/llm-semaphore.js.map +1 -1
- package/dist/channels/capabilities.d.ts +14 -0
- package/dist/channels/capabilities.d.ts.map +1 -0
- package/dist/channels/capabilities.js +16 -0
- package/dist/channels/capabilities.js.map +1 -0
- package/dist/channels/catalog.js +1 -1
- package/dist/channels/catalog.js.map +1 -1
- package/dist/channels/model-provider-ids.d.ts +3 -0
- package/dist/channels/model-provider-ids.d.ts.map +1 -0
- package/dist/channels/model-provider-ids.js +2 -0
- package/dist/channels/model-provider-ids.js.map +1 -0
- package/dist/channels/model-providers.d.ts +10 -0
- package/dist/channels/model-providers.d.ts.map +1 -1
- package/dist/channels/model-providers.js +34 -0
- package/dist/channels/model-providers.js.map +1 -1
- package/dist/channels/providers.d.ts +7 -0
- package/dist/channels/providers.d.ts.map +1 -1
- package/dist/channels/providers.js +62 -39
- package/dist/channels/providers.js.map +1 -1
- package/dist/channels/token-budgets.d.ts +3 -0
- package/dist/channels/token-budgets.d.ts.map +1 -0
- package/dist/channels/token-budgets.js +33 -0
- package/dist/channels/token-budgets.js.map +1 -0
- package/dist/channels/usage.d.ts.map +1 -1
- package/dist/channels/usage.js +9 -1
- package/dist/channels/usage.js.map +1 -1
- package/dist/db/connection-pool.d.ts +18 -0
- package/dist/db/connection-pool.d.ts.map +1 -0
- package/dist/db/connection-pool.js +125 -0
- package/dist/db/connection-pool.js.map +1 -0
- package/dist/db/migrate.d.ts +33 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +183 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/migrations/0000_core_ledgers.sql +118 -0
- package/dist/db/migrations/0001_memory.sql +47 -0
- package/dist/db/migrations/0002_memory_search.sql +21 -0
- package/dist/db/migrations/0003_token_usage_account.sql +1 -0
- package/dist/db/migrations/meta/0000_snapshot.json +729 -0
- package/dist/db/migrations/meta/0001_snapshot.json +1069 -0
- package/dist/db/migrations/meta/0002_snapshot.json +1100 -0
- package/dist/db/migrations/meta/0003_snapshot.json +1106 -0
- package/dist/db/migrations/meta/_journal.json +34 -0
- package/dist/db/pool.d.ts +9 -0
- package/dist/db/pool.d.ts.map +1 -0
- package/dist/db/pool.js +44 -0
- package/dist/db/pool.js.map +1 -0
- package/dist/db/schema/auth.d.ts +195 -0
- package/dist/db/schema/auth.d.ts.map +1 -0
- package/dist/db/schema/auth.js +15 -0
- package/dist/db/schema/auth.js.map +1 -0
- package/dist/db/schema/budgets.d.ts +372 -0
- package/dist/db/schema/budgets.d.ts.map +1 -0
- package/dist/db/schema/budgets.js +32 -0
- package/dist/db/schema/budgets.js.map +1 -0
- package/dist/db/schema/bugs.d.ts +314 -0
- package/dist/db/schema/bugs.d.ts.map +1 -0
- package/dist/db/schema/bugs.js +26 -0
- package/dist/db/schema/bugs.js.map +1 -0
- package/dist/db/schema/control-plane.d.ts +110 -0
- package/dist/db/schema/control-plane.d.ts.map +1 -0
- package/dist/db/schema/control-plane.js +10 -0
- package/dist/db/schema/control-plane.js.map +1 -0
- package/dist/db/schema/coordination.d.ts +231 -0
- package/dist/db/schema/coordination.d.ts.map +1 -0
- package/dist/db/schema/coordination.js +81 -0
- package/dist/db/schema/coordination.js.map +1 -0
- package/dist/db/schema/delivery.d.ts +192 -0
- package/dist/db/schema/delivery.d.ts.map +1 -0
- package/dist/db/schema/delivery.js +18 -0
- package/dist/db/schema/delivery.js.map +1 -0
- package/dist/db/schema/index.d.ts +8 -0
- package/dist/db/schema/index.d.ts.map +1 -0
- package/dist/db/schema/index.js +8 -0
- package/dist/db/schema/index.js.map +1 -0
- package/dist/db/schema/memory.d.ts +581 -0
- package/dist/db/schema/memory.d.ts.map +1 -0
- package/dist/db/schema/memory.js +54 -0
- package/dist/db/schema/memory.js.map +1 -0
- package/dist/db/schema/observability.d.ts +212 -0
- package/dist/db/schema/observability.d.ts.map +1 -0
- package/dist/db/schema/observability.js +16 -0
- package/dist/db/schema/observability.js.map +1 -0
- package/dist/db/schema/workflow-read.d.ts +116 -0
- package/dist/db/schema/workflow-read.d.ts.map +1 -0
- package/dist/db/schema/workflow-read.js +13 -0
- package/dist/db/schema/workflow-read.js.map +1 -0
- package/dist/lib/budgets/account.d.ts +12 -0
- package/dist/lib/budgets/account.d.ts.map +1 -0
- package/dist/lib/budgets/account.js +84 -0
- package/dist/lib/budgets/account.js.map +1 -0
- package/dist/lib/budgets/prepaid-response-store.js +1 -1
- package/dist/lib/budgets/record-call-usage.d.ts +1 -0
- package/dist/lib/budgets/record-call-usage.d.ts.map +1 -1
- package/dist/lib/budgets/record-call-usage.js +1 -0
- package/dist/lib/budgets/record-call-usage.js.map +1 -1
- package/dist/lib/budgets/token-budget.d.ts +15 -0
- package/dist/lib/budgets/token-budget.d.ts.map +1 -1
- package/dist/lib/budgets/token-budget.js +145 -14
- package/dist/lib/budgets/token-budget.js.map +1 -1
- package/dist/lib/budgets/token-usage-pg.d.ts +20 -1
- package/dist/lib/budgets/token-usage-pg.d.ts.map +1 -1
- package/dist/lib/budgets/token-usage-pg.js +219 -225
- package/dist/lib/budgets/token-usage-pg.js.map +1 -1
- package/dist/lib/budgets/usage.d.ts +37 -8
- package/dist/lib/budgets/usage.d.ts.map +1 -1
- package/dist/lib/budgets/usage.js +90 -5
- package/dist/lib/budgets/usage.js.map +1 -1
- package/dist/lib/control-plane/ambient-session.d.ts +3 -0
- package/dist/lib/control-plane/ambient-session.d.ts.map +1 -0
- package/dist/lib/control-plane/ambient-session.js +34 -0
- package/dist/lib/control-plane/ambient-session.js.map +1 -0
- package/dist/lib/control-plane/catalog.d.ts +2 -0
- package/dist/lib/control-plane/catalog.d.ts.map +1 -1
- package/dist/lib/control-plane/catalog.js +15 -12
- package/dist/lib/control-plane/catalog.js.map +1 -1
- package/dist/lib/control-plane/console-caps.d.ts +8 -0
- package/dist/lib/control-plane/console-caps.d.ts.map +1 -0
- package/dist/lib/control-plane/console-caps.js +45 -0
- package/dist/lib/control-plane/console-caps.js.map +1 -0
- package/dist/lib/control-plane/flow-settings.d.ts +81 -1
- package/dist/lib/control-plane/flow-settings.d.ts.map +1 -1
- package/dist/lib/control-plane/flow-settings.js +181 -24
- package/dist/lib/control-plane/flow-settings.js.map +1 -1
- package/dist/lib/control-plane/tools-config.d.ts.map +1 -1
- package/dist/lib/control-plane/tools-config.js.map +1 -1
- package/dist/lib/coordination/checkpoints.d.ts +0 -1
- package/dist/lib/coordination/checkpoints.d.ts.map +1 -1
- package/dist/lib/coordination/checkpoints.js +54 -39
- package/dist/lib/coordination/checkpoints.js.map +1 -1
- package/dist/lib/coordination/head-lease.d.ts +6 -6
- package/dist/lib/coordination/head-lease.d.ts.map +1 -1
- package/dist/lib/coordination/head-lease.js +149 -85
- package/dist/lib/coordination/head-lease.js.map +1 -1
- package/dist/lib/coordination/pg.d.ts +1 -2
- package/dist/lib/coordination/pg.d.ts.map +1 -1
- package/dist/lib/coordination/pg.js +3 -22
- package/dist/lib/coordination/pg.js.map +1 -1
- package/dist/lib/coordination/work-queue.d.ts +0 -1
- package/dist/lib/coordination/work-queue.d.ts.map +1 -1
- package/dist/lib/coordination/work-queue.js +159 -142
- package/dist/lib/coordination/work-queue.js.map +1 -1
- package/dist/lib/delivery/host-operation-store.d.ts +10 -0
- package/dist/lib/delivery/host-operation-store.d.ts.map +1 -0
- package/dist/lib/delivery/host-operation-store.js +68 -0
- package/dist/lib/delivery/host-operation-store.js.map +1 -0
- package/dist/lib/delivery/push.js +1 -1
- package/dist/lib/delivery/push.js.map +1 -1
- package/dist/lib/delivery/schedule-lock.d.ts.map +1 -1
- package/dist/lib/delivery/schedule-lock.js +2 -5
- package/dist/lib/delivery/schedule-lock.js.map +1 -1
- package/dist/lib/media/webp.d.ts +4 -0
- package/dist/lib/media/webp.d.ts.map +1 -1
- package/dist/lib/media/webp.js +7 -0
- package/dist/lib/media/webp.js.map +1 -1
- package/dist/lib/memory/memory-events.d.ts +25 -0
- package/dist/lib/memory/memory-events.d.ts.map +1 -0
- package/dist/lib/memory/memory-events.js +135 -0
- package/dist/lib/memory/memory-events.js.map +1 -0
- package/dist/lib/memory/memory-vault-git.js.map +1 -1
- package/dist/lib/memory/vault-explorer.d.ts.map +1 -1
- package/dist/lib/memory/vault-explorer.js +3 -2
- package/dist/lib/memory/vault-explorer.js.map +1 -1
- package/dist/lib/models/ai-settings.d.ts +38 -0
- package/dist/lib/models/ai-settings.d.ts.map +1 -0
- package/dist/lib/models/ai-settings.js +204 -0
- package/dist/lib/models/ai-settings.js.map +1 -0
- package/dist/lib/models/custom-providers.d.ts +6 -0
- package/dist/lib/models/custom-providers.d.ts.map +1 -1
- package/dist/lib/models/custom-providers.js +13 -3
- package/dist/lib/models/custom-providers.js.map +1 -1
- package/dist/lib/models/lane-uses.d.ts +10 -0
- package/dist/lib/models/lane-uses.d.ts.map +1 -0
- package/dist/lib/models/lane-uses.js +64 -0
- package/dist/lib/models/lane-uses.js.map +1 -0
- package/dist/lib/models/model-catalog.d.ts.map +1 -1
- package/dist/lib/models/model-catalog.js.map +1 -1
- package/dist/lib/models/model-config.d.ts.map +1 -1
- package/dist/lib/models/model-config.js +15 -2
- package/dist/lib/models/model-config.js.map +1 -1
- package/dist/lib/models/slots.d.ts +19 -0
- package/dist/lib/models/slots.d.ts.map +1 -0
- package/dist/lib/models/slots.js +77 -0
- package/dist/lib/models/slots.js.map +1 -0
- package/dist/lib/observability/console-read.d.ts +32 -0
- package/dist/lib/observability/console-read.d.ts.map +1 -0
- package/dist/lib/observability/console-read.js +84 -0
- package/dist/lib/observability/console-read.js.map +1 -0
- package/dist/lib/observability/logger.d.ts +4 -1
- package/dist/lib/observability/logger.d.ts.map +1 -1
- package/dist/lib/observability/logger.js +98 -7
- package/dist/lib/observability/logger.js.map +1 -1
- package/dist/lib/observability/model-events.d.ts +54 -0
- package/dist/lib/observability/model-events.d.ts.map +1 -0
- package/dist/lib/observability/model-events.js +111 -0
- package/dist/lib/observability/model-events.js.map +1 -0
- package/dist/lib/observability/recorder-hook.d.ts +1 -1
- package/dist/lib/observability/recorder-hook.d.ts.map +1 -1
- package/dist/lib/observability/recorder-hook.js +16 -3
- package/dist/lib/observability/recorder-hook.js.map +1 -1
- package/dist/lib/observability/recorder.d.ts +6 -0
- package/dist/lib/observability/recorder.d.ts.map +1 -1
- package/dist/lib/observability/recorder.js +10 -1
- package/dist/lib/observability/recorder.js.map +1 -1
- package/dist/tenant.d.ts +16 -7
- package/dist/tenant.d.ts.map +1 -1
- package/dist/tenant.js.map +1 -1
- package/package.json +43 -3
package/dist/channels/usage.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { defineChannel, GET } from "eve/channels";
|
|
2
|
-
import { logger } from "../lib/observability/logger.js";
|
|
3
2
|
import { readRunUsageByModel } from "../lib/budgets/token-usage-pg.js";
|
|
4
3
|
import { buildRunUsage, buildUsage, buildUsageLogs, UsageQueryError, } from "../lib/budgets/usage.js";
|
|
4
|
+
import { logger } from "../lib/observability/logger.js";
|
|
5
|
+
import { parseModelEventsQuery, readModelEventsPage } from "../lib/observability/model-events.js";
|
|
5
6
|
const log = logger.child({ module: "usage" });
|
|
6
7
|
export default defineChannel({
|
|
7
8
|
routes: [
|
|
@@ -26,10 +27,17 @@ export default defineChannel({
|
|
|
26
27
|
return Response.json(await buildUsageLogs(req.url, new Date()));
|
|
27
28
|
}
|
|
28
29
|
catch (err) {
|
|
30
|
+
if (err instanceof UsageQueryError) {
|
|
31
|
+
return Response.json({ error: err.message }, { status: 400 });
|
|
32
|
+
}
|
|
29
33
|
log.error({ err }, "failed to build usage logs");
|
|
30
34
|
return Response.json({ error: "failed to build usage logs" }, { status: 500 });
|
|
31
35
|
}
|
|
32
36
|
}),
|
|
37
|
+
GET("/eve/v1/usage/events", async (req) => {
|
|
38
|
+
const page = await readModelEventsPage(parseModelEventsQuery(req.url));
|
|
39
|
+
return Response.json({ ...page, generatedAt: new Date().toISOString() });
|
|
40
|
+
}),
|
|
33
41
|
],
|
|
34
42
|
});
|
|
35
43
|
//# sourceMappingURL=usage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/channels/usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/channels/usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,eAAe,GAChB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAElG,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;AAO9C,eAAe,aAAa,CAAC;IAC3B,MAAM,EAAE;QACN,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACjC,IAAI,CAAC;gBACH,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAC9D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBAEb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;oBACnC,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;gBAChE,CAAC;gBAED,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,iCAAiC,CAAC,CAAC;gBACtD,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC,CAAC;QAMF,GAAG,CAAC,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;YACtD,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClD,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QACnE,CAAC,CAAC;QACF,GAAG,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACtC,IAAI,CAAC;gBACH,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAClE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;oBACnC,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;gBAChE,CAAC;gBACD,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,4BAA4B,CAAC,CAAC;gBACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACjF,CAAC;QACH,CAAC,CAAC;QAIF,GAAG,CAAC,sBAAsB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACxC,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACvE,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC3E,CAAC,CAAC;KACH;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Pool, type PoolClient, type PoolConfig } from "pg";
|
|
2
|
+
type ConnectCallback = Parameters<Pool["connect"]>[0];
|
|
3
|
+
export declare class ConnectionPool extends Pool {
|
|
4
|
+
private readonly ordinary;
|
|
5
|
+
private readonly leases;
|
|
6
|
+
private closing;
|
|
7
|
+
constructor(config: PoolConfig);
|
|
8
|
+
get queuedCount(): number;
|
|
9
|
+
connect(): Promise<PoolClient>;
|
|
10
|
+
connect(callback: ConnectCallback): void;
|
|
11
|
+
connectLease(name: string, slots: number): Promise<PoolClient>;
|
|
12
|
+
private drain;
|
|
13
|
+
private borrow;
|
|
14
|
+
end(): Promise<void>;
|
|
15
|
+
end(callback: () => void): void;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=connection-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-pool.d.ts","sourceRoot":"","sources":["../../src/db/connection-pool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,IAAI,CAAC;AAE5D,KAAK,eAAe,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAgBtD,qBAAa,cAAe,SAAQ,IAAI;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAO;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAClD,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,UAAU;IAK9B,IAAI,WAAW,IAAI,MAAM,CAMxB;IAEQ,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAC9B,OAAO,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAajD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiB9D,OAAO,CAAC,KAAK;IASb,OAAO,CAAC,MAAM;IAwEL,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IACpB,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;CASzC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Pool } from "pg";
|
|
2
|
+
export class ConnectionPool extends Pool {
|
|
3
|
+
ordinary;
|
|
4
|
+
leases = new Map();
|
|
5
|
+
closing = false;
|
|
6
|
+
constructor(config) {
|
|
7
|
+
super(config);
|
|
8
|
+
this.ordinary = { limit: this.options.max, active: 0, waiting: new Set() };
|
|
9
|
+
}
|
|
10
|
+
get queuedCount() {
|
|
11
|
+
return (this.waitingCount +
|
|
12
|
+
this.ordinary.waiting.size +
|
|
13
|
+
[...this.leases.values()].reduce((sum, lane) => sum + lane.waiting.size, 0));
|
|
14
|
+
}
|
|
15
|
+
connect(callback) {
|
|
16
|
+
const result = this.borrow(this.ordinary);
|
|
17
|
+
if (!callback)
|
|
18
|
+
return result;
|
|
19
|
+
void result.then((client) => callback(undefined, client, client.release), (error) => callback(error, undefined, () => { }));
|
|
20
|
+
}
|
|
21
|
+
connectLease(name, slots) {
|
|
22
|
+
if (!name || !Number.isSafeInteger(slots) || slots < 1) {
|
|
23
|
+
return Promise.reject(new Error("Invalid shared-pool lease capacity"));
|
|
24
|
+
}
|
|
25
|
+
let lane = this.leases.get(name);
|
|
26
|
+
if (!lane) {
|
|
27
|
+
lane = { limit: slots, active: 0, waiting: new Set() };
|
|
28
|
+
this.leases.set(name, lane);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
lane.limit = Math.max(lane.limit, slots);
|
|
32
|
+
}
|
|
33
|
+
this.options.max =
|
|
34
|
+
this.ordinary.limit + [...this.leases.values()].reduce((sum, l) => sum + l.limit, 0);
|
|
35
|
+
this.drain(lane);
|
|
36
|
+
return this.borrow(lane);
|
|
37
|
+
}
|
|
38
|
+
drain(lane) {
|
|
39
|
+
while (!this.closing && lane.active < lane.limit) {
|
|
40
|
+
const next = lane.waiting.values().next().value;
|
|
41
|
+
if (!next)
|
|
42
|
+
break;
|
|
43
|
+
lane.waiting.delete(next);
|
|
44
|
+
next.start();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
borrow(lane) {
|
|
48
|
+
if (this.closing || this.ending)
|
|
49
|
+
return Promise.reject(new Error("Cannot use a pool after calling end"));
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
let settled = false;
|
|
52
|
+
let active = false;
|
|
53
|
+
const releaseSlot = () => {
|
|
54
|
+
if (!active)
|
|
55
|
+
return;
|
|
56
|
+
active = false;
|
|
57
|
+
lane.active--;
|
|
58
|
+
this.drain(lane);
|
|
59
|
+
};
|
|
60
|
+
const borrower = {
|
|
61
|
+
cancel: (error) => {
|
|
62
|
+
if (settled)
|
|
63
|
+
return;
|
|
64
|
+
settled = true;
|
|
65
|
+
lane.waiting.delete(borrower);
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
reject(error);
|
|
68
|
+
},
|
|
69
|
+
start: () => {
|
|
70
|
+
active = true;
|
|
71
|
+
lane.active++;
|
|
72
|
+
try {
|
|
73
|
+
super.connect((error, client, release) => {
|
|
74
|
+
if (error || !client) {
|
|
75
|
+
releaseSlot();
|
|
76
|
+
borrower.cancel(error ?? new Error("Postgres returned no client"));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (settled) {
|
|
80
|
+
try {
|
|
81
|
+
release();
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
releaseSlot();
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
settled = true;
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
let released = false;
|
|
91
|
+
client.release = (destroy) => {
|
|
92
|
+
if (released)
|
|
93
|
+
throw new Error("Release called on client which has already been released to the pool.");
|
|
94
|
+
released = true;
|
|
95
|
+
try {
|
|
96
|
+
release(destroy);
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
releaseSlot();
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
resolve(client);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
releaseSlot();
|
|
107
|
+
borrower.cancel(error instanceof Error ? error : new Error(String(error)));
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
const timer = setTimeout(() => borrower.cancel(new Error("timeout exceeded when trying to connect")), this.options.connectionTimeoutMillis || 5000);
|
|
112
|
+
lane.waiting.add(borrower);
|
|
113
|
+
this.drain(lane);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
end(callback) {
|
|
117
|
+
this.closing = true;
|
|
118
|
+
for (const lane of [this.ordinary, ...this.leases.values()]) {
|
|
119
|
+
for (const borrower of lane.waiting)
|
|
120
|
+
borrower.cancel(new Error("Cannot use a pool after calling end"));
|
|
121
|
+
}
|
|
122
|
+
return callback ? super.end(callback) : super.end();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=connection-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-pool.js","sourceRoot":"","sources":["../../src/db/connection-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type ClientConfig } from "pg";
|
|
2
|
+
export declare const CORE_MIGRATIONS_FOLDER: string;
|
|
3
|
+
export declare const CORE_LEDGER_TABLE = "eve_core_schema_migrations";
|
|
4
|
+
export type MigrationFile = {
|
|
5
|
+
id: string;
|
|
6
|
+
sql: string;
|
|
7
|
+
checksum: string;
|
|
8
|
+
};
|
|
9
|
+
export type RunMigrationsOptions = {
|
|
10
|
+
connectionString: string;
|
|
11
|
+
clientConfig?: Omit<ClientConfig, "connectionString">;
|
|
12
|
+
migrationsFolder?: string;
|
|
13
|
+
migrations?: {
|
|
14
|
+
id: string;
|
|
15
|
+
sql: string;
|
|
16
|
+
}[];
|
|
17
|
+
ledgerTable: string;
|
|
18
|
+
legacyLedger?: {
|
|
19
|
+
tableName: string;
|
|
20
|
+
checksums: Readonly<Record<string, string>>;
|
|
21
|
+
};
|
|
22
|
+
dryRun?: boolean;
|
|
23
|
+
log?: (line: string) => void;
|
|
24
|
+
};
|
|
25
|
+
export type RunMigrationsResult = {
|
|
26
|
+
applied: string[];
|
|
27
|
+
pending: string[];
|
|
28
|
+
alreadyApplied: number;
|
|
29
|
+
};
|
|
30
|
+
export declare function listMigrationFiles(folder: string): MigrationFile[];
|
|
31
|
+
export declare function runMigrations(opts: RunMigrationsOptions): Promise<RunMigrationsResult>;
|
|
32
|
+
export declare function runCoreMigrations(opts: Omit<RunMigrationsOptions, "migrationsFolder" | "ledgerTable">): Promise<RunMigrationsResult>;
|
|
33
|
+
//# sourceMappingURL=migrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,IAAI,CAAC;AA6B/C,eAAO,MAAM,sBAAsB,QAA2D,CAAC;AAC/F,eAAO,MAAM,iBAAiB,+BAA+B,CAAC;AAI9D,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1E,MAAM,MAAM,oBAAoB,GAAG;IACjC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,YAAY,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;IAEtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAO1B,UAAU,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAE3C,WAAW,EAAE,MAAM,CAAC;IAGpB,YAAY,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAE,CAAC;IAElF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAIF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,EAAE,CAQlE;AAqCD,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAqJ5F;AAGD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,CAAC,oBAAoB,EAAE,kBAAkB,GAAG,aAAa,CAAC,GACnE,OAAO,CAAC,mBAAmB,CAAC,CAM9B"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { Client } from "pg";
|
|
6
|
+
export const CORE_MIGRATIONS_FOLDER = fileURLToPath(new URL("./migrations/", import.meta.url));
|
|
7
|
+
export const CORE_LEDGER_TABLE = "eve_core_schema_migrations";
|
|
8
|
+
const LEDGER_NAME = /^[a-z_][a-z0-9_]*$/;
|
|
9
|
+
const checksumOf = (sql) => createHash("sha256").update(sql).digest("hex");
|
|
10
|
+
export function listMigrationFiles(folder) {
|
|
11
|
+
return readdirSync(folder)
|
|
12
|
+
.filter((f) => f.endsWith(".sql"))
|
|
13
|
+
.sort()
|
|
14
|
+
.map((id) => {
|
|
15
|
+
const sql = readFileSync(join(folder, id), "utf8");
|
|
16
|
+
return { id, sql, checksum: checksumOf(sql) };
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function lineageOf(opts) {
|
|
20
|
+
if (opts.migrations) {
|
|
21
|
+
const ids = new Set();
|
|
22
|
+
for (const m of opts.migrations) {
|
|
23
|
+
if (ids.has(m.id))
|
|
24
|
+
throw new Error(`[eve-core/db] duplicate migration id ${m.id}`);
|
|
25
|
+
ids.add(m.id);
|
|
26
|
+
}
|
|
27
|
+
return opts.migrations.map((m) => ({ ...m, checksum: checksumOf(m.sql) }));
|
|
28
|
+
}
|
|
29
|
+
if (opts.migrationsFolder)
|
|
30
|
+
return listMigrationFiles(opts.migrationsFolder);
|
|
31
|
+
throw new Error("[eve-core/db] runMigrations needs `migrationsFolder` or `migrations`");
|
|
32
|
+
}
|
|
33
|
+
async function protectLedger(client, ledgerTable) {
|
|
34
|
+
const grants = await client.query(`SELECT DISTINCT CASE WHEN a.grantee = 0 THEN 'PUBLIC'
|
|
35
|
+
ELSE quote_ident(r.rolname) END AS grantee
|
|
36
|
+
FROM pg_class c
|
|
37
|
+
CROSS JOIN LATERAL aclexplode(c.relacl) a
|
|
38
|
+
LEFT JOIN pg_roles r ON r.oid = a.grantee
|
|
39
|
+
WHERE c.oid = to_regclass($1) AND a.grantee <> c.relowner
|
|
40
|
+
AND a.privilege_type IN
|
|
41
|
+
('INSERT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER')`, [ledgerTable]);
|
|
42
|
+
for (const { grantee } of grants.rows) {
|
|
43
|
+
await client.query(`REVOKE INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER
|
|
44
|
+
ON TABLE ${ledgerTable} FROM ${grantee}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function runMigrations(opts) {
|
|
48
|
+
const { ledgerTable, dryRun = false, log = () => undefined } = opts;
|
|
49
|
+
if (!LEDGER_NAME.test(ledgerTable)) {
|
|
50
|
+
throw new Error(`[eve-core/db] ledger table name must match ${LEDGER_NAME}: ${ledgerTable}`);
|
|
51
|
+
}
|
|
52
|
+
if (opts.legacyLedger &&
|
|
53
|
+
(!LEDGER_NAME.test(opts.legacyLedger.tableName) || opts.legacyLedger.tableName === ledgerTable)) {
|
|
54
|
+
throw new Error("[eve-core/db] legacy ledger must be a distinct lower-snake identifier");
|
|
55
|
+
}
|
|
56
|
+
const files = lineageOf(opts);
|
|
57
|
+
const client = new Client({
|
|
58
|
+
connectionString: opts.connectionString,
|
|
59
|
+
connectionTimeoutMillis: 10_000,
|
|
60
|
+
...opts.clientConfig,
|
|
61
|
+
});
|
|
62
|
+
await client.connect();
|
|
63
|
+
try {
|
|
64
|
+
await client.query("SET statement_timeout = 0");
|
|
65
|
+
await client.query("SET lock_timeout = '30s'");
|
|
66
|
+
await client.query("SELECT pg_advisory_lock(hashtext($1))", [ledgerTable]);
|
|
67
|
+
try {
|
|
68
|
+
let adopted;
|
|
69
|
+
if (opts.legacyLedger) {
|
|
70
|
+
const legacy = opts.legacyLedger;
|
|
71
|
+
const existing = await client.query("SELECT to_regclass($1) AS old_ledger, to_regclass($2) AS new_ledger", [
|
|
72
|
+
legacy.tableName,
|
|
73
|
+
ledgerTable,
|
|
74
|
+
]);
|
|
75
|
+
if (existing.rows[0]?.old_ledger) {
|
|
76
|
+
if (existing.rows[0].new_ledger)
|
|
77
|
+
throw new Error("[eve-core/db] both legacy and current ledgers exist; reconcile their history before migrating");
|
|
78
|
+
const history = await client.query(`SELECT id FROM ${legacy.tableName}`);
|
|
79
|
+
const known = new Map(files.map((file) => [file.id, file.checksum]));
|
|
80
|
+
adopted = history.rows.map(({ id }) => {
|
|
81
|
+
const checksum = legacy.checksums[id];
|
|
82
|
+
if (!checksum || known.get(id) !== checksum)
|
|
83
|
+
throw new Error(`[eve-core/db] legacy migration ${id} is unknown or differs from its pinned history`);
|
|
84
|
+
return { id, checksum };
|
|
85
|
+
});
|
|
86
|
+
if (!dryRun) {
|
|
87
|
+
await client.query("BEGIN");
|
|
88
|
+
try {
|
|
89
|
+
await client.query(`ALTER TABLE ${legacy.tableName} RENAME TO ${ledgerTable}`);
|
|
90
|
+
await client.query(`ALTER TABLE ${ledgerTable} ADD COLUMN checksum TEXT`);
|
|
91
|
+
for (const row of adopted)
|
|
92
|
+
await client.query(`UPDATE ${ledgerTable} SET checksum = $2 WHERE id = $1`, [
|
|
93
|
+
row.id,
|
|
94
|
+
row.checksum,
|
|
95
|
+
]);
|
|
96
|
+
await client.query(`ALTER TABLE ${ledgerTable} ALTER COLUMN checksum SET NOT NULL`);
|
|
97
|
+
await protectLedger(client, ledgerTable);
|
|
98
|
+
await client.query("COMMIT");
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
await client.query("ROLLBACK");
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (!dryRun) {
|
|
108
|
+
await client.query("BEGIN");
|
|
109
|
+
try {
|
|
110
|
+
await client.query(`CREATE TABLE IF NOT EXISTS ${ledgerTable} (
|
|
111
|
+
id TEXT PRIMARY KEY,
|
|
112
|
+
checksum TEXT NOT NULL,
|
|
113
|
+
applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
114
|
+
)`);
|
|
115
|
+
await protectLedger(client, ledgerTable);
|
|
116
|
+
await client.query("COMMIT");
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
await client.query("ROLLBACK");
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const exists = await client.query("SELECT to_regclass($1) AS name", [
|
|
124
|
+
ledgerTable,
|
|
125
|
+
]);
|
|
126
|
+
const rows = adopted ??
|
|
127
|
+
(exists.rows[0]?.name
|
|
128
|
+
? (await client.query(`SELECT id, checksum FROM ${ledgerTable}`)).rows
|
|
129
|
+
: []);
|
|
130
|
+
const recorded = new Map(rows.map((r) => [r.id, r.checksum]));
|
|
131
|
+
const pending = [];
|
|
132
|
+
for (const file of files) {
|
|
133
|
+
const seen = recorded.get(file.id);
|
|
134
|
+
if (seen === undefined) {
|
|
135
|
+
pending.push(file);
|
|
136
|
+
}
|
|
137
|
+
else if (seen !== file.checksum) {
|
|
138
|
+
throw new Error(`[eve-core/db] ${file.id} was applied with a different content (ledger ${ledgerTable}); migrations are append-only — add a new file`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const result = {
|
|
142
|
+
applied: [],
|
|
143
|
+
pending: pending.map((f) => f.id),
|
|
144
|
+
alreadyApplied: files.length - pending.length,
|
|
145
|
+
};
|
|
146
|
+
if (dryRun)
|
|
147
|
+
return result;
|
|
148
|
+
for (const file of pending) {
|
|
149
|
+
try {
|
|
150
|
+
await client.query("BEGIN");
|
|
151
|
+
await client.query(file.sql);
|
|
152
|
+
await client.query(`INSERT INTO ${ledgerTable} (id, checksum) VALUES ($1, $2)`, [
|
|
153
|
+
file.id,
|
|
154
|
+
file.checksum,
|
|
155
|
+
]);
|
|
156
|
+
await client.query("COMMIT");
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
await client.query("ROLLBACK").catch(() => undefined);
|
|
160
|
+
throw new Error(`[eve-core/db] migration ${file.id} failed: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
|
|
161
|
+
}
|
|
162
|
+
result.applied.push(file.id);
|
|
163
|
+
log(`applied ${file.id}`);
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
finally {
|
|
168
|
+
await client.query("SELECT pg_advisory_unlock(hashtext($1))", [ledgerTable]).catch(() => {
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
await client.end().catch(() => undefined);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
export function runCoreMigrations(opts) {
|
|
177
|
+
return runMigrations({
|
|
178
|
+
...opts,
|
|
179
|
+
migrationsFolder: CORE_MIGRATIONS_FOLDER,
|
|
180
|
+
ledgerTable: CORE_LEDGER_TABLE,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/db/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
-- 0000_core_ledgers — HAND-EDITED after `drizzle-kit generate` (2026-09-09).
|
|
2
|
+
--
|
|
3
|
+
-- Every table here already exists on live DBs, created by the stores' old lazy
|
|
4
|
+
-- `CREATE TABLE IF NOT EXISTS` on first use. This migration relocates their
|
|
5
|
+
-- definitions into the schema without touching data, so it MUST be a no-op on a
|
|
6
|
+
-- populated DB: every CREATE carries IF NOT EXISTS, and the columns that were
|
|
7
|
+
-- added to pre-existing tables by later `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`
|
|
8
|
+
-- patches are re-asserted the same way before the indexes (CREATE TABLE IF NOT EXISTS
|
|
9
|
+
-- skips silently on an existing table, so a DB created before those patches
|
|
10
|
+
-- would otherwise keep the old column set). drizzle-kit's snapshot in meta/ is
|
|
11
|
+
-- untouched — the drift gate compares journal entries, not SQL text.
|
|
12
|
+
-- Migrations after this one are plain generated DDL: the lazy DDL is gone.
|
|
13
|
+
|
|
14
|
+
CREATE TABLE IF NOT EXISTS "external_call_budget" (
|
|
15
|
+
"call_key" text PRIMARY KEY NOT NULL,
|
|
16
|
+
"provider" text NOT NULL,
|
|
17
|
+
"op" text,
|
|
18
|
+
"meta" jsonb,
|
|
19
|
+
"called_on" date DEFAULT current_date NOT NULL,
|
|
20
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
21
|
+
);
|
|
22
|
+
--> statement-breakpoint
|
|
23
|
+
CREATE TABLE IF NOT EXISTS "token_usage" (
|
|
24
|
+
"id" bigserial PRIMARY KEY NOT NULL,
|
|
25
|
+
"session_id" text NOT NULL,
|
|
26
|
+
"root_id" text NOT NULL,
|
|
27
|
+
"flow" text,
|
|
28
|
+
"model" text NOT NULL,
|
|
29
|
+
"turn_id" text,
|
|
30
|
+
"step_index" integer,
|
|
31
|
+
"at" timestamp with time zone NOT NULL,
|
|
32
|
+
"input_tokens" integer DEFAULT 0 NOT NULL,
|
|
33
|
+
"output_tokens" integer DEFAULT 0 NOT NULL,
|
|
34
|
+
"cache_read_tokens" integer DEFAULT 0 NOT NULL,
|
|
35
|
+
"cache_write_tokens" integer DEFAULT 0 NOT NULL,
|
|
36
|
+
"instance" text DEFAULT 'eve' NOT NULL,
|
|
37
|
+
"scope" text
|
|
38
|
+
);
|
|
39
|
+
--> statement-breakpoint
|
|
40
|
+
CREATE TABLE IF NOT EXISTS "bugs" (
|
|
41
|
+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
|
|
42
|
+
"project" text NOT NULL,
|
|
43
|
+
"title" text NOT NULL,
|
|
44
|
+
"summary" text NOT NULL,
|
|
45
|
+
"affected_surface" text,
|
|
46
|
+
"repro_steps" text,
|
|
47
|
+
"severity" integer DEFAULT 3 NOT NULL,
|
|
48
|
+
"confidence" real DEFAULT 0.5 NOT NULL,
|
|
49
|
+
"reporter_ref" text,
|
|
50
|
+
"screenshot_file_ids" jsonb DEFAULT '[]'::jsonb NOT NULL,
|
|
51
|
+
"screenshot_urls" jsonb DEFAULT '[]'::jsonb NOT NULL,
|
|
52
|
+
"locale" text,
|
|
53
|
+
"status" text DEFAULT 'open' NOT NULL,
|
|
54
|
+
"session_id" text,
|
|
55
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
56
|
+
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
57
|
+
"fix_state" text,
|
|
58
|
+
"fix_pr_url" text
|
|
59
|
+
);
|
|
60
|
+
--> statement-breakpoint
|
|
61
|
+
CREATE TABLE IF NOT EXISTS "ui_documents" (
|
|
62
|
+
"id" text PRIMARY KEY NOT NULL,
|
|
63
|
+
"session_id" text NOT NULL,
|
|
64
|
+
"root_id" text NOT NULL,
|
|
65
|
+
"source" text,
|
|
66
|
+
"doc" jsonb NOT NULL,
|
|
67
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
68
|
+
);
|
|
69
|
+
--> statement-breakpoint
|
|
70
|
+
CREATE TABLE IF NOT EXISTS "github_delivery_claims" (
|
|
71
|
+
"key" text PRIMARY KEY NOT NULL,
|
|
72
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
|
73
|
+
);
|
|
74
|
+
--> statement-breakpoint
|
|
75
|
+
CREATE TABLE IF NOT EXISTS "notifications" (
|
|
76
|
+
"id" bigserial PRIMARY KEY NOT NULL,
|
|
77
|
+
"ts" timestamp with time zone DEFAULT now() NOT NULL,
|
|
78
|
+
"flow" text,
|
|
79
|
+
"title" text NOT NULL,
|
|
80
|
+
"body" text NOT NULL
|
|
81
|
+
);
|
|
82
|
+
--> statement-breakpoint
|
|
83
|
+
CREATE TABLE IF NOT EXISTS "telegram_dedup" (
|
|
84
|
+
"session_id" text NOT NULL,
|
|
85
|
+
"content_hash" text NOT NULL,
|
|
86
|
+
"delivered_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
87
|
+
CONSTRAINT "telegram_dedup_session_id_content_hash_pk" PRIMARY KEY("session_id","content_hash")
|
|
88
|
+
);
|
|
89
|
+
--> statement-breakpoint
|
|
90
|
+
CREATE TABLE IF NOT EXISTS "model_events" (
|
|
91
|
+
"id" bigserial PRIMARY KEY NOT NULL,
|
|
92
|
+
"at" timestamp with time zone NOT NULL,
|
|
93
|
+
"instance" text DEFAULT 'eve' NOT NULL,
|
|
94
|
+
"key" text,
|
|
95
|
+
"session_id" text,
|
|
96
|
+
"root_id" text,
|
|
97
|
+
"main" text,
|
|
98
|
+
"error_code" text,
|
|
99
|
+
"error" text NOT NULL,
|
|
100
|
+
"elapsed_ms" integer,
|
|
101
|
+
"outcome" text NOT NULL,
|
|
102
|
+
"leg_model" text
|
|
103
|
+
);
|
|
104
|
+
--> statement-breakpoint
|
|
105
|
+
-- Re-asserted BEFORE the indexes: token_usage_instance_idx needs `instance`.
|
|
106
|
+
ALTER TABLE "token_usage" ADD COLUMN IF NOT EXISTS "instance" text DEFAULT 'eve' NOT NULL;--> statement-breakpoint
|
|
107
|
+
ALTER TABLE "token_usage" ADD COLUMN IF NOT EXISTS "scope" text;--> statement-breakpoint
|
|
108
|
+
ALTER TABLE "bugs" ADD COLUMN IF NOT EXISTS "fix_state" text;--> statement-breakpoint
|
|
109
|
+
ALTER TABLE "bugs" ADD COLUMN IF NOT EXISTS "fix_pr_url" text;--> statement-breakpoint
|
|
110
|
+
CREATE INDEX IF NOT EXISTS "external_call_budget_provider_day_idx" ON "external_call_budget" USING btree ("provider","called_on");--> statement-breakpoint
|
|
111
|
+
CREATE INDEX IF NOT EXISTS "token_usage_at_idx" ON "token_usage" USING btree ("at");--> statement-breakpoint
|
|
112
|
+
CREATE INDEX IF NOT EXISTS "token_usage_root_idx" ON "token_usage" USING btree ("root_id");--> statement-breakpoint
|
|
113
|
+
CREATE INDEX IF NOT EXISTS "token_usage_instance_idx" ON "token_usage" USING btree ("instance");--> statement-breakpoint
|
|
114
|
+
CREATE INDEX IF NOT EXISTS "bugs_project_created_idx" ON "bugs" USING btree ("project","created_at" DESC NULLS LAST,"id" DESC NULLS LAST);--> statement-breakpoint
|
|
115
|
+
CREATE INDEX IF NOT EXISTS "bugs_project_status_created_idx" ON "bugs" USING btree ("project","status","created_at" DESC NULLS LAST,"id" DESC NULLS LAST);--> statement-breakpoint
|
|
116
|
+
CREATE INDEX IF NOT EXISTS "notifications_ts_idx" ON "notifications" USING btree ("ts" DESC NULLS LAST,"id" DESC NULLS LAST);--> statement-breakpoint
|
|
117
|
+
CREATE INDEX IF NOT EXISTS "model_events_at_idx" ON "model_events" USING btree ("at");--> statement-breakpoint
|
|
118
|
+
CREATE INDEX IF NOT EXISTS "model_events_root_idx" ON "model_events" USING btree ("root_id");
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
-- Adopt the six existing memory stores without replacing their tables or rows.
|
|
2
|
+
CREATE TABLE IF NOT EXISTS "memory_dream_runs" (
|
|
3
|
+
"id" uuid PRIMARY KEY NOT NULL,
|
|
4
|
+
"kind" text DEFAULT 'nightly' NOT NULL,
|
|
5
|
+
"started_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
6
|
+
"finished_at" timestamp with time zone,
|
|
7
|
+
"summary" text DEFAULT '' NOT NULL,
|
|
8
|
+
"scopes" jsonb DEFAULT '[]'::jsonb NOT NULL,
|
|
9
|
+
"ops" jsonb DEFAULT '[]'::jsonb NOT NULL,
|
|
10
|
+
"counts" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
|
11
|
+
"error" text
|
|
12
|
+
);
|
|
13
|
+
--> statement-breakpoint
|
|
14
|
+
CREATE TABLE IF NOT EXISTS "memory_events" (
|
|
15
|
+
"id" uuid PRIMARY KEY NOT NULL,
|
|
16
|
+
"scope" text NOT NULL,
|
|
17
|
+
"kind" text NOT NULL,
|
|
18
|
+
"summary" text NOT NULL,
|
|
19
|
+
"payload" jsonb DEFAULT '{}'::jsonb NOT NULL,
|
|
20
|
+
"source_session" text,
|
|
21
|
+
"source_key" text,
|
|
22
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
23
|
+
"processed_at" timestamp with time zone
|
|
24
|
+
);
|
|
25
|
+
--> statement-breakpoint
|
|
26
|
+
CREATE TABLE IF NOT EXISTS "memory_rules" (
|
|
27
|
+
"id" uuid PRIMARY KEY NOT NULL,
|
|
28
|
+
"scope" text NOT NULL,
|
|
29
|
+
"layer" text DEFAULT 'domain' NOT NULL,
|
|
30
|
+
"rule" text NOT NULL,
|
|
31
|
+
"why" text,
|
|
32
|
+
"confidence" integer DEFAULT 50 NOT NULL,
|
|
33
|
+
"support" integer DEFAULT 1 NOT NULL,
|
|
34
|
+
"provenance" text DEFAULT 'dreamed' NOT NULL,
|
|
35
|
+
"pinned" boolean DEFAULT false NOT NULL,
|
|
36
|
+
"sources" jsonb DEFAULT '[]'::jsonb NOT NULL,
|
|
37
|
+
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
38
|
+
"last_reinforced_at" timestamp with time zone DEFAULT now() NOT NULL,
|
|
39
|
+
"invalidated_at" timestamp with time zone,
|
|
40
|
+
"invalidated_by" uuid
|
|
41
|
+
);
|
|
42
|
+
--> statement-breakpoint
|
|
43
|
+
CREATE INDEX IF NOT EXISTS "memory_dream_runs_started_idx" ON "memory_dream_runs" USING btree ("started_at" DESC NULLS FIRST);--> statement-breakpoint
|
|
44
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "memory_events_source_key_uniq" ON "memory_events" USING btree ("source_key") WHERE "memory_events"."source_key" IS NOT NULL;--> statement-breakpoint
|
|
45
|
+
CREATE INDEX IF NOT EXISTS "memory_events_scope_idx" ON "memory_events" USING btree ("scope","created_at" DESC NULLS FIRST);--> statement-breakpoint
|
|
46
|
+
CREATE INDEX IF NOT EXISTS "memory_events_unprocessed_idx" ON "memory_events" USING btree ("created_at") WHERE "memory_events"."processed_at" IS NULL;--> statement-breakpoint
|
|
47
|
+
CREATE INDEX IF NOT EXISTS "memory_rules_scope_idx" ON "memory_rules" USING btree ("scope","confidence" DESC NULLS FIRST) WHERE "memory_rules"."invalidated_at" IS NULL;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
-- Move legacy search indexes into the memory lineage. Trigram support is optional.
|
|
2
|
+
CREATE INDEX IF NOT EXISTS "memory_rules_fts_idx" ON "memory_rules" USING gin (to_tsvector('simple', coalesce("rule",'') || ' ' || coalesce("why",'') || ' ' || coalesce("scope",'')));--> statement-breakpoint
|
|
3
|
+
DO $$
|
|
4
|
+
DECLARE extension_schema text;
|
|
5
|
+
BEGIN
|
|
6
|
+
IF NOT EXISTS (SELECT 1 FROM pg_extension WHERE extname = 'pg_trgm') THEN
|
|
7
|
+
IF EXISTS (SELECT 1 FROM pg_available_extensions WHERE name = 'pg_trgm') THEN
|
|
8
|
+
BEGIN
|
|
9
|
+
CREATE EXTENSION IF NOT EXISTS pg_trgm WITH SCHEMA public;
|
|
10
|
+
EXCEPTION WHEN insufficient_privilege THEN
|
|
11
|
+
RAISE NOTICE 'pg_trgm installation denied; search will use full-text and substring matching';
|
|
12
|
+
END;
|
|
13
|
+
END IF;
|
|
14
|
+
END IF;
|
|
15
|
+
SELECT n.nspname INTO extension_schema FROM pg_extension e
|
|
16
|
+
JOIN pg_namespace n ON n.oid = e.extnamespace
|
|
17
|
+
WHERE e.extname = 'pg_trgm' AND has_schema_privilege(n.oid, 'USAGE');
|
|
18
|
+
IF extension_schema IS NOT NULL THEN
|
|
19
|
+
EXECUTE format('CREATE INDEX IF NOT EXISTS "memory_rules_rule_trgm_idx" ON "memory_rules" USING gin ("rule" %I.gin_trgm_ops)', extension_schema);
|
|
20
|
+
END IF;
|
|
21
|
+
END $$;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "token_usage" ADD COLUMN "account" text;
|