@amodalai/runtime 0.2.0 → 0.2.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.
Files changed (209) hide show
  1. package/dist/src/__fixtures__/README.md +4 -0
  2. package/dist/src/__fixtures__/e2e.test.d.ts +6 -0
  3. package/dist/src/__fixtures__/e2e.test.js +211 -0
  4. package/dist/src/__fixtures__/e2e.test.js.map +1 -0
  5. package/dist/src/__fixtures__/smoke-agent/automations/delivery-callback-test.json +9 -0
  6. package/dist/src/__fixtures__/smoke-agent/connections/mock-mcp/spec.json +1 -1
  7. package/dist/src/__fixtures__/smoke.test.js +715 -29
  8. package/dist/src/__fixtures__/smoke.test.js.map +1 -1
  9. package/dist/src/__fixtures__/test-env.d.ts +27 -0
  10. package/dist/src/__fixtures__/test-env.js +64 -0
  11. package/dist/src/__fixtures__/test-env.js.map +1 -0
  12. package/dist/src/__fixtures__/test-helpers.d.ts +30 -0
  13. package/dist/src/__fixtures__/test-helpers.js +120 -0
  14. package/dist/src/__fixtures__/test-helpers.js.map +1 -0
  15. package/dist/src/agent/agent-types.d.ts +22 -0
  16. package/dist/src/agent/agent-types.js.map +1 -1
  17. package/dist/src/agent/automation-bridge.d.ts +9 -0
  18. package/dist/src/agent/automation-bridge.js +26 -0
  19. package/dist/src/agent/automation-bridge.js.map +1 -1
  20. package/dist/src/agent/automation-bridge.test.js +63 -0
  21. package/dist/src/agent/automation-bridge.test.js.map +1 -1
  22. package/dist/src/agent/local-server.d.ts +0 -7
  23. package/dist/src/agent/local-server.js +230 -86
  24. package/dist/src/agent/local-server.js.map +1 -1
  25. package/dist/src/agent/local-server.test.js +14 -8
  26. package/dist/src/agent/local-server.test.js.map +1 -1
  27. package/dist/src/agent/loop-types.d.ts +81 -2
  28. package/dist/src/agent/loop-types.js +4 -0
  29. package/dist/src/agent/loop-types.js.map +1 -1
  30. package/dist/src/agent/loop.js +16 -3
  31. package/dist/src/agent/loop.js.map +1 -1
  32. package/dist/src/agent/loop.test.js +572 -8
  33. package/dist/src/agent/loop.test.js.map +1 -1
  34. package/dist/src/agent/proactive/delivery-router.d.ts +68 -0
  35. package/dist/src/agent/proactive/delivery-router.js +337 -0
  36. package/dist/src/agent/proactive/delivery-router.js.map +1 -0
  37. package/dist/src/agent/proactive/delivery-router.test.d.ts +6 -0
  38. package/dist/src/agent/proactive/delivery-router.test.js +455 -0
  39. package/dist/src/agent/proactive/delivery-router.test.js.map +1 -0
  40. package/dist/src/agent/proactive/proactive-runner.d.ts +23 -1
  41. package/dist/src/agent/proactive/proactive-runner.js +42 -10
  42. package/dist/src/agent/proactive/proactive-runner.js.map +1 -1
  43. package/dist/src/agent/proactive/proactive-runner.test.js +0 -2
  44. package/dist/src/agent/proactive/proactive-runner.test.js.map +1 -1
  45. package/dist/src/agent/routes/admin-chat-abort.test.d.ts +6 -0
  46. package/dist/src/agent/routes/admin-chat-abort.test.js +206 -0
  47. package/dist/src/agent/routes/admin-chat-abort.test.js.map +1 -0
  48. package/dist/src/agent/routes/admin-chat.js +0 -2
  49. package/dist/src/agent/routes/admin-chat.js.map +1 -1
  50. package/dist/src/agent/routes/task.test.js +0 -2
  51. package/dist/src/agent/routes/task.test.js.map +1 -1
  52. package/dist/src/agent/snapshot-server.js +0 -2
  53. package/dist/src/agent/snapshot-server.js.map +1 -1
  54. package/dist/src/agent/states/compacting.js +5 -3
  55. package/dist/src/agent/states/compacting.js.map +1 -1
  56. package/dist/src/agent/states/confirming.js +3 -0
  57. package/dist/src/agent/states/confirming.js.map +1 -1
  58. package/dist/src/agent/states/dispatching.js +45 -1
  59. package/dist/src/agent/states/dispatching.js.map +1 -1
  60. package/dist/src/agent/states/executing.js +225 -81
  61. package/dist/src/agent/states/executing.js.map +1 -1
  62. package/dist/src/agent/states/streaming.js +14 -0
  63. package/dist/src/agent/states/streaming.js.map +1 -1
  64. package/dist/src/agent/states/thinking.d.ts +1 -1
  65. package/dist/src/agent/states/thinking.js +246 -29
  66. package/dist/src/agent/states/thinking.js.map +1 -1
  67. package/dist/src/agent/token-estimate.d.ts +20 -6
  68. package/dist/src/agent/token-estimate.js +24 -3
  69. package/dist/src/agent/token-estimate.js.map +1 -1
  70. package/dist/src/agent/token-estimate.test.d.ts +6 -0
  71. package/dist/src/agent/token-estimate.test.js +44 -0
  72. package/dist/src/agent/token-estimate.test.js.map +1 -0
  73. package/dist/src/api/create-agent.js +0 -3
  74. package/dist/src/api/create-agent.js.map +1 -1
  75. package/dist/src/api/types.d.ts +0 -2
  76. package/dist/src/env-ref.d.ts +13 -0
  77. package/dist/src/env-ref.js +31 -0
  78. package/dist/src/env-ref.js.map +1 -0
  79. package/dist/src/env-ref.test.d.ts +6 -0
  80. package/dist/src/env-ref.test.js +34 -0
  81. package/dist/src/env-ref.test.js.map +1 -0
  82. package/dist/src/errors.d.ts +15 -0
  83. package/dist/src/errors.js +22 -0
  84. package/dist/src/errors.js.map +1 -1
  85. package/dist/src/errors.test.js +2 -2
  86. package/dist/src/errors.test.js.map +1 -1
  87. package/dist/src/events/event-bus.d.ts +54 -0
  88. package/dist/src/events/event-bus.js +84 -0
  89. package/dist/src/events/event-bus.js.map +1 -0
  90. package/dist/src/events/event-bus.test.d.ts +6 -0
  91. package/dist/src/events/event-bus.test.js +112 -0
  92. package/dist/src/events/event-bus.test.js.map +1 -0
  93. package/dist/src/events/events-route.d.ts +36 -0
  94. package/dist/src/events/events-route.js +80 -0
  95. package/dist/src/events/events-route.js.map +1 -0
  96. package/dist/src/events/events-route.test.d.ts +6 -0
  97. package/dist/src/events/events-route.test.js +134 -0
  98. package/dist/src/events/events-route.test.js.map +1 -0
  99. package/dist/src/events/store-event-wrapper.d.ts +19 -0
  100. package/dist/src/events/store-event-wrapper.js +57 -0
  101. package/dist/src/events/store-event-wrapper.js.map +1 -0
  102. package/dist/src/events/store-event-wrapper.test.d.ts +6 -0
  103. package/dist/src/events/store-event-wrapper.test.js +91 -0
  104. package/dist/src/events/store-event-wrapper.test.js.map +1 -0
  105. package/dist/src/middleware/auth.d.ts +0 -2
  106. package/dist/src/middleware/auth.js.map +1 -1
  107. package/dist/src/providers/search-provider.d.ts +64 -0
  108. package/dist/src/providers/search-provider.js +174 -0
  109. package/dist/src/providers/search-provider.js.map +1 -0
  110. package/dist/src/providers/types.d.ts +8 -0
  111. package/dist/src/routes/ai-stream.d.ts +15 -0
  112. package/dist/src/routes/ai-stream.js +9 -0
  113. package/dist/src/routes/ai-stream.js.map +1 -1
  114. package/dist/src/routes/chat-stream.d.ts +6 -0
  115. package/dist/src/routes/chat-stream.js +2 -0
  116. package/dist/src/routes/chat-stream.js.map +1 -1
  117. package/dist/src/routes/chat.d.ts +6 -0
  118. package/dist/src/routes/chat.js +2 -0
  119. package/dist/src/routes/chat.js.map +1 -1
  120. package/dist/src/routes/session-resolver.d.ts +5 -0
  121. package/dist/src/routes/session-resolver.js +1 -15
  122. package/dist/src/routes/session-resolver.js.map +1 -1
  123. package/dist/src/routes/session-resolver.test.js +7 -6
  124. package/dist/src/routes/session-resolver.test.js.map +1 -1
  125. package/dist/src/server.d.ts +6 -0
  126. package/dist/src/server.js +2 -0
  127. package/dist/src/server.js.map +1 -1
  128. package/dist/src/session/drizzle-session-store.d.ts +56 -0
  129. package/dist/src/session/drizzle-session-store.js +203 -0
  130. package/dist/src/session/drizzle-session-store.js.map +1 -0
  131. package/dist/src/session/manager.d.ts +6 -3
  132. package/dist/src/session/manager.js +46 -16
  133. package/dist/src/session/manager.js.map +1 -1
  134. package/dist/src/session/manager.test.js +12 -18
  135. package/dist/src/session/manager.test.js.map +1 -1
  136. package/dist/src/session/pglite-session-store.d.ts +23 -0
  137. package/dist/src/session/pglite-session-store.js +70 -0
  138. package/dist/src/session/pglite-session-store.js.map +1 -0
  139. package/dist/src/session/postgres-session-store.d.ts +44 -0
  140. package/dist/src/session/postgres-session-store.js +138 -0
  141. package/dist/src/session/postgres-session-store.js.map +1 -0
  142. package/dist/src/session/session-builder.d.ts +0 -2
  143. package/dist/src/session/session-builder.js +22 -2
  144. package/dist/src/session/session-builder.js.map +1 -1
  145. package/dist/src/session/session-builder.test.js +0 -2
  146. package/dist/src/session/session-builder.test.js.map +1 -1
  147. package/dist/src/session/session-store-selector.d.ts +49 -0
  148. package/dist/src/session/session-store-selector.js +60 -0
  149. package/dist/src/session/session-store-selector.js.map +1 -0
  150. package/dist/src/session/session-store-selector.test.d.ts +6 -0
  151. package/dist/src/session/session-store-selector.test.js +79 -0
  152. package/dist/src/session/session-store-selector.test.js.map +1 -0
  153. package/dist/src/session/store.d.ts +146 -32
  154. package/dist/src/session/store.js +126 -138
  155. package/dist/src/session/store.js.map +1 -1
  156. package/dist/src/session/store.test.js +385 -107
  157. package/dist/src/session/store.test.js.map +1 -1
  158. package/dist/src/session/tool-context-factory.d.ts +3 -2
  159. package/dist/src/session/tool-context-factory.js +1 -2
  160. package/dist/src/session/tool-context-factory.js.map +1 -1
  161. package/dist/src/session/tool-context-factory.test.js +1 -4
  162. package/dist/src/session/tool-context-factory.test.js.map +1 -1
  163. package/dist/src/session/types.d.ts +13 -6
  164. package/dist/src/stores/schema.d.ts +0 -34
  165. package/dist/src/stores/schema.js +6 -4
  166. package/dist/src/stores/schema.js.map +1 -1
  167. package/dist/src/tools/admin-file-tools.d.ts +29 -0
  168. package/dist/src/tools/admin-file-tools.js +525 -11
  169. package/dist/src/tools/admin-file-tools.js.map +1 -1
  170. package/dist/src/tools/admin-file-tools.test.js +373 -4
  171. package/dist/src/tools/admin-file-tools.test.js.map +1 -1
  172. package/dist/src/tools/custom-tool-adapter.test.js +0 -1
  173. package/dist/src/tools/custom-tool-adapter.test.js.map +1 -1
  174. package/dist/src/tools/dispatch-tool.d.ts +4 -4
  175. package/dist/src/tools/fetch-url-tool.d.ts +23 -0
  176. package/dist/src/tools/fetch-url-tool.js +333 -0
  177. package/dist/src/tools/fetch-url-tool.js.map +1 -0
  178. package/dist/src/tools/fetch-url-tool.test.d.ts +6 -0
  179. package/dist/src/tools/fetch-url-tool.test.js +228 -0
  180. package/dist/src/tools/fetch-url-tool.test.js.map +1 -0
  181. package/dist/src/tools/mcp-tool-adapter.test.js +0 -1
  182. package/dist/src/tools/mcp-tool-adapter.test.js.map +1 -1
  183. package/dist/src/tools/registry.test.js +0 -1
  184. package/dist/src/tools/registry.test.js.map +1 -1
  185. package/dist/src/tools/request-tool.test.js +0 -1
  186. package/dist/src/tools/request-tool.test.js.map +1 -1
  187. package/dist/src/tools/store-tools.test.js +0 -1
  188. package/dist/src/tools/store-tools.test.js.map +1 -1
  189. package/dist/src/tools/types.d.ts +20 -2
  190. package/dist/src/tools/web-search-tool.d.ts +31 -0
  191. package/dist/src/tools/web-search-tool.js +170 -0
  192. package/dist/src/tools/web-search-tool.js.map +1 -0
  193. package/dist/src/tools/web-search-tool.test.d.ts +6 -0
  194. package/dist/src/tools/web-search-tool.test.js +153 -0
  195. package/dist/src/tools/web-search-tool.test.js.map +1 -0
  196. package/dist/src/tools/web-tools-shared.d.ts +21 -0
  197. package/dist/src/tools/web-tools-shared.js +32 -0
  198. package/dist/src/tools/web-tools-shared.js.map +1 -0
  199. package/dist/src/types.d.ts +20 -0
  200. package/dist/src/types.js +13 -0
  201. package/dist/src/types.js.map +1 -1
  202. package/dist/tsconfig.tsbuildinfo +1 -1
  203. package/package.json +17 -3
  204. package/dist/src/agent/session-store.d.ts +0 -71
  205. package/dist/src/agent/session-store.js +0 -151
  206. package/dist/src/agent/session-store.js.map +0 -1
  207. package/dist/src/session/admin-file-tools.d.ts +0 -136
  208. package/dist/src/session/admin-file-tools.js +0 -240
  209. package/dist/src/session/admin-file-tools.js.map +0 -1
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Amodal Labs, Inc.
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ import { describe, it, expect, afterEach } from 'vitest';
7
+ import { selectSessionStore } from './session-store-selector.js';
8
+ import { DrizzleSessionStore } from './drizzle-session-store.js';
9
+ import { createLogger } from '../logger.js';
10
+ const logger = createLogger({ component: 'test:selector' });
11
+ /**
12
+ * Both backends return `DrizzleSessionStore` today; we assert on the
13
+ * `backendName` tag to tell them apart in tests. If that instance type
14
+ * ever changes, this narrow cast is the one place to update.
15
+ */
16
+ function asDrizzle(store) {
17
+ expect(store).toBeInstanceOf(DrizzleSessionStore);
18
+ return store;
19
+ }
20
+ describe('selectSessionStore', () => {
21
+ const created = [];
22
+ afterEach(async () => {
23
+ while (created.length > 0) {
24
+ const s = created.pop();
25
+ await s.close();
26
+ }
27
+ });
28
+ it('defaults to PGLite when no backend specified', async () => {
29
+ const store = await selectSessionStore({ logger });
30
+ created.push(store);
31
+ expect(asDrizzle(store).backendName).toBe('pglite');
32
+ });
33
+ it('uses PGLite when backend is explicitly pglite', async () => {
34
+ const store = await selectSessionStore({ backend: 'pglite', logger });
35
+ created.push(store);
36
+ expect(asDrizzle(store).backendName).toBe('pglite');
37
+ });
38
+ it('falls back to PGLite when backend=postgres but no URL is set', async () => {
39
+ const store = await selectSessionStore({ backend: 'postgres', logger });
40
+ created.push(store);
41
+ expect(asDrizzle(store).backendName).toBe('pglite');
42
+ });
43
+ it('falls back to PGLite when postgresUrl is an empty string', async () => {
44
+ // Caller is responsible for resolving env: refs; empty string is
45
+ // what they pass when `env:VAR` was unset.
46
+ const store = await selectSessionStore({
47
+ backend: 'postgres',
48
+ postgresUrl: '',
49
+ logger,
50
+ });
51
+ created.push(store);
52
+ expect(asDrizzle(store).backendName).toBe('pglite');
53
+ });
54
+ it('falls back to PGLite when Postgres connection fails to initialize', async () => {
55
+ // Unreachable host + very short connect timeout → init throws →
56
+ // selector logs error and falls back to PGLite. This is the
57
+ // "runtime must boot even on misconfigured Postgres" path.
58
+ const store = await selectSessionStore({
59
+ backend: 'postgres',
60
+ // Port 1 is reserved and connection will be refused fast
61
+ postgresUrl: 'postgres://nobody:nothing@127.0.0.1:1/missing?connect_timeout=1',
62
+ logger,
63
+ });
64
+ created.push(store);
65
+ expect(asDrizzle(store).backendName).toBe('pglite');
66
+ });
67
+ const pgUrl = process.env['TEST_POSTGRES_URL'] ?? '';
68
+ const itPg = pgUrl ? it : it.skip;
69
+ itPg('uses Postgres backend when backend=postgres and URL is set', async () => {
70
+ const store = await selectSessionStore({
71
+ backend: 'postgres',
72
+ postgresUrl: pgUrl,
73
+ logger,
74
+ });
75
+ created.push(store);
76
+ expect(asDrizzle(store).backendName).toBe('postgres');
77
+ });
78
+ });
79
+ //# sourceMappingURL=session-store-selector.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store-selector.test.js","sourceRoot":"","sources":["../../../src/session/session-store-selector.test.ts"],"names":[],"mappings":"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"}
@@ -3,55 +3,169 @@
3
3
  * Copyright 2026 Amodal Labs, Inc.
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
+ /**
7
+ * Session persistence layer — interface, types, and shared helpers.
8
+ *
9
+ * Concrete implementations:
10
+ * - `DrizzleSessionStore` (./drizzle-session-store.ts) — the single
11
+ * query layer shared by both backends.
12
+ * - `createPGLiteSessionStore` (./pglite-session-store.ts) — factory
13
+ * for local-dev / in-memory PGLite.
14
+ * - `createPostgresSessionStore` (./postgres-session-store.ts) —
15
+ * factory for hosted runtime / ISV production.
16
+ *
17
+ * The Drizzle schema lives in `../stores/schema.ts`, shared with the
18
+ * store document tables.
19
+ */
20
+ import { and } from 'drizzle-orm';
21
+ import type { AnyPgColumn } from 'drizzle-orm/pg-core';
22
+ import type { agentSessions } from '../stores/schema.js';
6
23
  import type { PersistedSession } from './types.js';
7
- import type { Logger } from '../logger.js';
24
+ /**
25
+ * Options for `SessionStore.list()`.
26
+ *
27
+ * Cursor-based pagination over `updated_at` (newest first). The cursor
28
+ * encodes the updatedAt/id pair of the last row returned — pass it back
29
+ * unchanged to fetch the next page.
30
+ *
31
+ * Filters match against metadata JSONB paths using equality. Only
32
+ * `snake_case` / simple identifier keys are accepted — see
33
+ * `validateFilterKey` for the exact rules. Passing an untrusted key
34
+ * throws `SessionStoreError`.
35
+ *
36
+ * `updatedAfter` / `updatedBefore` filter by the `updated_at` column
37
+ * (inclusive). Useful for "sessions touched this week" queries.
38
+ */
39
+ export interface SessionListOptions {
40
+ readonly limit?: number;
41
+ readonly cursor?: string;
42
+ readonly filter?: Readonly<Record<string, unknown>>;
43
+ readonly updatedAfter?: Date;
44
+ readonly updatedBefore?: Date;
45
+ }
46
+ /**
47
+ * Result of `SessionStore.list()` — sessions plus an opaque cursor
48
+ * for the next page. `nextCursor` is `null` when there are no more rows.
49
+ */
50
+ export interface SessionListResult {
51
+ readonly sessions: PersistedSession[];
52
+ readonly nextCursor: string | null;
53
+ }
54
+ /**
55
+ * Optional callbacks fired after mutations. Each hook is awaited, so
56
+ * a failing hook propagates to the caller. Keep hooks fast — they sit
57
+ * on the write path.
58
+ *
59
+ * Intended use: dual-write to a consumer's own table (hosted-runtime
60
+ * adoption path), emit observability events, invalidate caches.
61
+ */
62
+ export interface SessionStoreHooks {
63
+ onAfterSave?: (session: PersistedSession) => Promise<void> | void;
64
+ onAfterDelete?: (sessionId: string) => Promise<void> | void;
65
+ onAfterCleanup?: (opts: {
66
+ deleted: number;
67
+ before: Date;
68
+ }) => Promise<void> | void;
69
+ }
8
70
  /**
9
71
  * Interface for session persistence backends.
10
72
  *
11
- * Implementations: PGLiteSessionStore (local dev), future Postgres
12
- * (hosted runtime via shared Drizzle schema).
73
+ * One concrete implementation (`DrizzleSessionStore`) with two factories:
74
+ * `createPGLiteSessionStore` for local dev, `createPostgresSessionStore`
75
+ * for hosted runtime / ISV production. Both share the `agentSessions`
76
+ * Drizzle schema and the query helpers in this module.
13
77
  */
14
78
  export interface SessionStore {
15
79
  /** Initialize the backing store (create tables, run migrations). */
16
80
  initialize(): Promise<void>;
17
- /** Save or update a session. */
81
+ /**
82
+ * Save or update a session.
83
+ *
84
+ * **Semantics: last-write-wins.** The implementation does an
85
+ * unconditional `onConflictDoUpdate` — no optimistic-concurrency
86
+ * version check. If two concurrent `save()` calls target the same
87
+ * session ID, the later write silently overwrites the earlier one,
88
+ * including any messages the earlier caller added.
89
+ *
90
+ * **Callers must serialize per-session writes.** The built-in
91
+ * `StandaloneSessionManager` does this by routing all writes for a
92
+ * session through a single in-memory object. External callers that
93
+ * share a session across workers must either (a) use a single
94
+ * writer per session, or (b) wrap `save()` with their own advisory
95
+ * locking. The `version` column is persisted and surfaced on read
96
+ * but is currently informational only — reserved for future OCC.
97
+ */
18
98
  save(session: PersistedSession): Promise<void>;
19
- /** Load a session by ID. Returns null if not found. */
99
+ /** Load a session by id. Returns null if not found. */
20
100
  load(sessionId: string): Promise<PersistedSession | null>;
21
- /** List sessions for a tenant, newest first. */
22
- list(tenantId: string, opts?: {
23
- limit?: number;
24
- }): Promise<PersistedSession[]>;
25
- /** Delete a session by ID. Returns true if deleted. */
101
+ /**
102
+ * List sessions newest first. Returns sessions + a pagination cursor.
103
+ * Callers that need any form of scoping should namespace their
104
+ * session IDs directly (e.g. `app-a:session-123`) and/or filter by
105
+ * `metadata` fields via `opts.filter`.
106
+ */
107
+ list(opts?: SessionListOptions): Promise<SessionListResult>;
108
+ /** Delete a session by id. Returns true if a row was deleted. */
26
109
  delete(sessionId: string): Promise<boolean>;
27
110
  /** Delete sessions not updated since `before`. Returns count deleted. */
28
111
  cleanup(before: Date): Promise<number>;
29
112
  /** Close the backing store. */
30
113
  close(): Promise<void>;
31
114
  }
115
+ export declare function validateFilterKey(backend: string, key: string): void;
116
+ /** Encode a cursor as opaque base64 of "updatedAt.ms|id". */
117
+ export declare function encodeCursor(updatedAt: Date, id: string): string;
118
+ /** Decode a cursor; throws SessionStoreError on malformed input. */
119
+ export declare function decodeCursor(backend: string, cursor: string): {
120
+ updatedAt: Date;
121
+ id: string;
122
+ };
123
+ /**
124
+ * Map a `PersistedSession` to its row shape for insert/update. Separate
125
+ * function so both backends do the exact same type conversion.
126
+ */
127
+ export declare function sessionToRow(session: PersistedSession): {
128
+ id: string;
129
+ messages: unknown[];
130
+ tokenUsage: {
131
+ inputTokens: number;
132
+ outputTokens: number;
133
+ totalTokens: number;
134
+ };
135
+ metadata: Record<string, unknown>;
136
+ version: number;
137
+ createdAt: Date;
138
+ updatedAt: Date;
139
+ };
32
140
  /**
33
- * PGLite-backed session store using Drizzle ORM.
141
+ * Inverse of `sessionToRow`.
34
142
  *
35
- * Runs an in-process WASM Postgres instance. Data is persisted to a
36
- * configurable directory (default: in-memory).
143
+ * Validates at the JSONB boundary: rejects rows with an unknown
144
+ * `version` (future schema migration signal) or a non-array `messages`
145
+ * payload (would indicate a malformed write from an older runtime or
146
+ * manual DB edit). Throws `SessionStoreError` with context when a row
147
+ * fails validation rather than returning a quietly-broken session
148
+ * that crashes deep in the agent loop.
37
149
  */
38
- export declare class PGLiteSessionStore implements SessionStore {
39
- private db;
40
- private pglite;
41
- private readonly dataDir;
42
- private readonly logger;
43
- constructor(opts: {
44
- dataDir?: string;
45
- logger: Logger;
46
- });
47
- initialize(): Promise<void>;
48
- save(session: PersistedSession): Promise<void>;
49
- load(sessionId: string): Promise<PersistedSession | null>;
50
- list(tenantId: string, opts?: {
51
- limit?: number;
52
- }): Promise<PersistedSession[]>;
53
- delete(sessionId: string): Promise<boolean>;
54
- cleanup(before: Date): Promise<number>;
55
- close(): Promise<void>;
56
- private ensureDb;
150
+ export declare function rowToPersistedSession(backend: string, row: typeof agentSessions.$inferSelect): PersistedSession;
151
+ /**
152
+ * Structural shape the `buildListConditions` helper needs. Any
153
+ * `agent_sessions`-compatible Drizzle pgTable (default name or a
154
+ * consumer-supplied one) satisfies this — both backends use the same
155
+ * column names, only the table name differs.
156
+ */
157
+ export interface AgentSessionsColumns {
158
+ updatedAt: AnyPgColumn;
159
+ id: AnyPgColumn;
160
+ metadata: AnyPgColumn;
57
161
  }
162
+ /**
163
+ * Build the where-clause fragments for `list()`. Generic over the
164
+ * table's column bindings so both PGLite (static `agentSessions`) and
165
+ * Postgres (dynamic `makeAgentSessionsTable(name)`) pass their own
166
+ * tables without a cast.
167
+ *
168
+ * Returns `undefined` when `opts` yields no conditions — drizzle's
169
+ * `.where(undefined)` is a no-op, equivalent to "no filter".
170
+ */
171
+ export declare function buildListConditions(backend: string, opts: SessionListOptions | undefined, table: AgentSessionsColumns): ReturnType<typeof and>;
@@ -4,159 +4,109 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
6
  /**
7
- * Session persistence layer.
7
+ * Session persistence layer — interface, types, and shared helpers.
8
8
  *
9
- * Defines the `SessionStore` interface and a PGLite implementation
10
- * backed by Drizzle ORM. The Drizzle schema is in `stores/schema.ts`,
11
- * shared with the store document tables.
9
+ * Concrete implementations:
10
+ * - `DrizzleSessionStore` (./drizzle-session-store.ts) the single
11
+ * query layer shared by both backends.
12
+ * - `createPGLiteSessionStore` (./pglite-session-store.ts) — factory
13
+ * for local-dev / in-memory PGLite.
14
+ * - `createPostgresSessionStore` (./postgres-session-store.ts) —
15
+ * factory for hosted runtime / ISV production.
16
+ *
17
+ * The Drizzle schema lives in `../stores/schema.ts`, shared with the
18
+ * store document tables.
12
19
  */
13
- import { eq, lt, desc } from 'drizzle-orm';
14
- import { drizzle } from 'drizzle-orm/pglite';
15
- import { agentSessions } from '../stores/schema.js';
16
- import { ConfigError } from '../errors.js';
20
+ import { and, eq, lt, or, gte, lte, sql } from 'drizzle-orm';
21
+ import { SessionStoreError } from '../errors.js';
17
22
  // ---------------------------------------------------------------------------
18
- // PGLite implementation
23
+ // Shared helpers — used by both PGLite and Postgres implementations
19
24
  // ---------------------------------------------------------------------------
20
25
  /**
21
- * PGLite-backed session store using Drizzle ORM.
22
- *
23
- * Runs an in-process WASM Postgres instance. Data is persisted to a
24
- * configurable directory (default: in-memory).
26
+ * Reject filter keys that could be used for SQL injection. We only
27
+ * allow simple identifiers: letters, digits, underscores. The keys
28
+ * become part of a JSONB path (`metadata->>'key'`) so they must be
29
+ * safe to interpolate.
25
30
  */
26
- export class PGLiteSessionStore {
27
- db = null;
28
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- PGLite instance type is not exported cleanly
29
- pglite = null;
30
- dataDir;
31
- logger;
32
- constructor(opts) {
33
- this.dataDir = opts.dataDir;
34
- this.logger = opts.logger;
35
- }
36
- async initialize() {
37
- if (this.db)
38
- return;
39
- if (this.dataDir) {
40
- const { mkdirSync } = await import('node:fs');
41
- mkdirSync(this.dataDir, { recursive: true });
42
- }
43
- const { PGlite } = await import('@electric-sql/pglite');
44
- this.pglite = new PGlite(this.dataDir ?? undefined);
45
- this.db = drizzle(this.pglite);
46
- // Create table via raw SQL — Drizzle schema defines the shape,
47
- // but we use raw DDL for initialization (no drizzle-kit in runtime).
48
- await this.pglite.exec(`
49
- CREATE TABLE IF NOT EXISTS agent_sessions (
50
- id TEXT PRIMARY KEY,
51
- tenant_id TEXT NOT NULL,
52
- user_id TEXT NOT NULL,
53
- messages JSONB NOT NULL,
54
- token_usage JSONB NOT NULL,
55
- metadata JSONB DEFAULT '{}',
56
- version INTEGER NOT NULL DEFAULT 1,
57
- created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
58
- updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
59
- );
60
-
61
- CREATE INDEX IF NOT EXISTS idx_agent_sessions_tenant
62
- ON agent_sessions (tenant_id, updated_at DESC);
63
- `);
64
- this.logger.info('session_store_initialized', {
65
- dataDir: this.dataDir ?? 'in-memory',
31
+ const SAFE_KEY_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
32
+ export function validateFilterKey(backend, key) {
33
+ if (!SAFE_KEY_RE.test(key)) {
34
+ throw new SessionStoreError(`Invalid filter field name: ${JSON.stringify(key)}`, {
35
+ backend,
36
+ operation: 'list',
37
+ context: { key, expected: 'identifier: letters, digits, underscore only' },
66
38
  });
67
39
  }
68
- async save(session) {
69
- this.ensureDb();
70
- const values = {
71
- id: session.id,
72
- tenantId: session.tenantId,
73
- userId: session.userId,
74
- messages: session.messages,
75
- tokenUsage: session.tokenUsage,
76
- metadata: session.metadata,
77
- version: session.version,
78
- createdAt: session.createdAt,
79
- updatedAt: session.updatedAt,
80
- };
81
- await this.db
82
- .insert(agentSessions)
83
- .values(values)
84
- .onConflictDoUpdate({
85
- target: agentSessions.id,
86
- set: {
87
- messages: values.messages,
88
- tokenUsage: values.tokenUsage,
89
- metadata: values.metadata,
90
- updatedAt: values.updatedAt,
91
- },
92
- });
93
- }
94
- async load(sessionId) {
95
- this.ensureDb();
96
- const rows = await this.db
97
- .select()
98
- .from(agentSessions)
99
- .where(eq(agentSessions.id, sessionId))
100
- .limit(1);
101
- if (rows.length === 0)
102
- return null;
103
- return rowToPersistedSession(rows[0]);
104
- }
105
- async list(tenantId, opts) {
106
- this.ensureDb();
107
- const rows = await this.db
108
- .select()
109
- .from(agentSessions)
110
- .where(eq(agentSessions.tenantId, tenantId))
111
- .orderBy(desc(agentSessions.updatedAt))
112
- .limit(opts?.limit ?? 50);
113
- return rows.map(rowToPersistedSession);
114
- }
115
- async delete(sessionId) {
116
- this.ensureDb();
117
- const result = await this.db
118
- .delete(agentSessions)
119
- .where(eq(agentSessions.id, sessionId))
120
- .returning({ id: agentSessions.id });
121
- return result.length > 0;
40
+ }
41
+ /** Encode a cursor as opaque base64 of "updatedAt.ms|id". */
42
+ export function encodeCursor(updatedAt, id) {
43
+ return Buffer.from(`${updatedAt.getTime()}|${id}`, 'utf8').toString('base64url');
44
+ }
45
+ /** Decode a cursor; throws SessionStoreError on malformed input. */
46
+ export function decodeCursor(backend, cursor) {
47
+ try {
48
+ const decoded = Buffer.from(cursor, 'base64url').toString('utf8');
49
+ const sep = decoded.indexOf('|');
50
+ if (sep < 0)
51
+ throw new Error('missing separator');
52
+ const ms = Number(decoded.slice(0, sep));
53
+ const id = decoded.slice(sep + 1);
54
+ if (!Number.isFinite(ms) || !id)
55
+ throw new Error('bad parts');
56
+ return { updatedAt: new Date(ms), id };
122
57
  }
123
- async cleanup(before) {
124
- this.ensureDb();
125
- const result = await this.db
126
- .delete(agentSessions)
127
- .where(lt(agentSessions.updatedAt, before))
128
- .returning({ id: agentSessions.id });
129
- if (result.length > 0) {
130
- this.logger.info('session_store_cleanup', { deleted: result.length });
131
- }
132
- return result.length;
58
+ catch (cause) {
59
+ throw new SessionStoreError('Invalid pagination cursor', {
60
+ backend,
61
+ operation: 'list',
62
+ cause,
63
+ });
133
64
  }
134
- async close() {
135
- if (this.pglite) {
136
- await this.pglite.close();
137
- this.pglite = null;
138
- this.db = null;
139
- }
65
+ }
66
+ /**
67
+ * Map a `PersistedSession` to its row shape for insert/update. Separate
68
+ * function so both backends do the exact same type conversion.
69
+ */
70
+ export function sessionToRow(session) {
71
+ return {
72
+ id: session.id,
73
+ messages: session.messages,
74
+ tokenUsage: session.tokenUsage,
75
+ metadata: session.metadata,
76
+ version: session.version,
77
+ createdAt: session.createdAt,
78
+ updatedAt: session.updatedAt,
79
+ };
80
+ }
81
+ /**
82
+ * Inverse of `sessionToRow`.
83
+ *
84
+ * Validates at the JSONB boundary: rejects rows with an unknown
85
+ * `version` (future schema migration signal) or a non-array `messages`
86
+ * payload (would indicate a malformed write from an older runtime or
87
+ * manual DB edit). Throws `SessionStoreError` with context when a row
88
+ * fails validation rather than returning a quietly-broken session
89
+ * that crashes deep in the agent loop.
90
+ */
91
+ export function rowToPersistedSession(backend, row) {
92
+ if (row.version !== 1) {
93
+ throw new SessionStoreError(`Unsupported persisted session version: ${row.version}`, {
94
+ backend,
95
+ operation: 'load',
96
+ context: { sessionId: row.id, version: row.version, supported: 1 },
97
+ });
140
98
  }
141
- ensureDb() {
142
- if (!this.db) {
143
- throw new ConfigError('PGLiteSessionStore not initialized — call initialize() first', {
144
- key: 'sessionStore',
145
- suggestion: 'Call initialize() before using the session store',
146
- });
147
- }
99
+ if (!Array.isArray(row.messages)) {
100
+ throw new SessionStoreError('Persisted session has non-array messages payload', {
101
+ backend,
102
+ operation: 'load',
103
+ context: { sessionId: row.id, messagesType: typeof row.messages },
104
+ });
148
105
  }
149
- }
150
- // ---------------------------------------------------------------------------
151
- // Row conversion
152
- // ---------------------------------------------------------------------------
153
- function rowToPersistedSession(row) {
154
106
  return {
155
107
  version: 1,
156
108
  id: row.id,
157
- tenantId: row.tenantId,
158
- userId: row.userId,
159
- // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- JSONB boundary: we wrote these values
109
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- JSONB boundary: array-shape checked above; element shape is not validated
160
110
  messages: row.messages,
161
111
  tokenUsage: row.tokenUsage,
162
112
  metadata: (row.metadata ?? {}),
@@ -164,4 +114,42 @@ function rowToPersistedSession(row) {
164
114
  updatedAt: row.updatedAt,
165
115
  };
166
116
  }
117
+ /**
118
+ * Build the where-clause fragments for `list()`. Generic over the
119
+ * table's column bindings so both PGLite (static `agentSessions`) and
120
+ * Postgres (dynamic `makeAgentSessionsTable(name)`) pass their own
121
+ * tables without a cast.
122
+ *
123
+ * Returns `undefined` when `opts` yields no conditions — drizzle's
124
+ * `.where(undefined)` is a no-op, equivalent to "no filter".
125
+ */
126
+ export function buildListConditions(backend, opts, table) {
127
+ const conditions = [];
128
+ if (opts?.cursor) {
129
+ const { updatedAt: cursorTs, id: cursorId } = decodeCursor(backend, opts.cursor);
130
+ // Compound (updated_at, id) comparison makes pagination stable even
131
+ // when multiple rows share the same `updated_at` (batch inserts in
132
+ // the same ms, clock-skewed sources). Matches the secondary sort
133
+ // key on `id` used by list() so every row is visited exactly once.
134
+ const cursorCondition = or(lt(table.updatedAt, cursorTs), and(eq(table.updatedAt, cursorTs), lt(table.id, cursorId)));
135
+ if (cursorCondition)
136
+ conditions.push(cursorCondition);
137
+ }
138
+ if (opts?.updatedAfter)
139
+ conditions.push(gte(table.updatedAt, opts.updatedAfter));
140
+ if (opts?.updatedBefore)
141
+ conditions.push(lte(table.updatedAt, opts.updatedBefore));
142
+ if (opts?.filter) {
143
+ for (const [key, val] of Object.entries(opts.filter)) {
144
+ validateFilterKey(backend, key);
145
+ // metadata->>'key' = value (string equality). JSONB `->>` returns
146
+ // text; we coerce the user-supplied value to its JSON string form
147
+ // via parameter binding, so non-string values like numbers/bools
148
+ // compare correctly: metadata->>'n' = '42'.
149
+ const textVal = typeof val === 'string' ? val : JSON.stringify(val);
150
+ conditions.push(sql `${table.metadata}->>${sql.raw(`'${key}'`)} = ${textVal}`);
151
+ }
152
+ }
153
+ return and(...conditions);
154
+ }
167
155
  //# sourceMappingURL=store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/session/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/session/store.ts"],"names":[],"mappings":"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"}