@jini-ai/sqlite 0.1.1 → 0.3.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 +110 -0
- package/dist/db/chat-history/index.d.ts +15 -0
- package/dist/db/chat-history/index.d.ts.map +1 -0
- package/dist/db/chat-history/index.js +15 -0
- package/dist/db/chat-history/index.js.map +1 -0
- package/dist/db/chat-history/schema.d.ts +61 -0
- package/dist/db/chat-history/schema.d.ts.map +1 -0
- package/dist/db/chat-history/schema.js +80 -0
- package/dist/db/chat-history/schema.js.map +1 -0
- package/dist/db/chat-history/store.d.ts +41 -0
- package/dist/db/chat-history/store.d.ts.map +1 -0
- package/dist/db/chat-history/store.js +254 -0
- package/dist/db/chat-history/store.js.map +1 -0
- package/dist/db/index.d.ts +6 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +6 -0
- package/dist/db/index.js.map +1 -1
- package/dist/event-log.d.ts +1 -1
- package/dist/event-log.d.ts.map +1 -1
- package/package.json +9 -5
package/README.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# `@jini-ai/sqlite`
|
|
2
|
+
|
|
3
|
+
The durable SQLite adapter layer for a Jini host. Its headline export is `createSqliteEventLog`, a
|
|
4
|
+
real on-disk implementation of `@jini-ai/protocol`'s `EventLog` port (the dedupe-aware,
|
|
5
|
+
gap-detecting run-event log that `@jini-ai/daemon` also implements in memory) — swap one for the
|
|
6
|
+
other and runs survive a process restart. Alongside it sits the application schema and typed query
|
|
7
|
+
helpers a chat/agent host needs: projects, conversations, messages, agent sessions, a searchable
|
|
8
|
+
tool catalog, plus migration and integrity-inspection utilities. This package depends only on
|
|
9
|
+
`@jini-ai/protocol` and `better-sqlite3`; it does **not** depend on `@jini-ai/daemon`.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install @jini-ai/sqlite
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`better-sqlite3` is a regular dependency (not an optional peer) because opening the database is this
|
|
18
|
+
package's entire job. It is a **native compiled addon**, so it needs a prebuild matching the exact
|
|
19
|
+
Node ABI it runs under — inside an Electron/Tauri shell that means an `electron-rebuild` step
|
|
20
|
+
whenever the shell's bundled Node/Electron version changes, not just a plain install.
|
|
21
|
+
|
|
22
|
+
## What you get
|
|
23
|
+
|
|
24
|
+
**Durable event log** — `createSqliteEventLog(dbPath, { maxEntriesPerRun })` returning a
|
|
25
|
+
`SqliteEventLog` (an `EventLog` plus its own close/lifecycle surface), and
|
|
26
|
+
`DEFAULT_MAX_ENTRIES_PER_RUN` (2000). Unlike the in-memory reference log, a durable store defaults
|
|
27
|
+
to a *bounded* retention window per run, because unbounded on-disk growth is a real unattended
|
|
28
|
+
operational risk; pass an explicit cap (larger, smaller, or `0`) to own that tradeoff yourself.
|
|
29
|
+
|
|
30
|
+
**Connection and migration** — `openDatabase(projectRoot, { dataDir })` (opens/creates
|
|
31
|
+
`<dataDir ?? projectRoot/.jini>/app.sqlite` and memoizes the handle), `closeDatabase()`, and
|
|
32
|
+
`migrate(db)`. Core types: `SqliteDb`, `DbRow`, `JsonObject`, `ChatSessionMode`.
|
|
33
|
+
|
|
34
|
+
**Backend selection** — `resolveSqliteBackendConfig(env)` → `SqliteBackendConfig`
|
|
35
|
+
(`kind: 'sqlite' | 'postgres'` plus Postgres resolution metadata a future adapter will read, with
|
|
36
|
+
secrets deliberately never read through env at this layer), and `SqliteBackendConfigError`.
|
|
37
|
+
|
|
38
|
+
**Application queries** — plain functions over a `SqliteDb`, grouped by table:
|
|
39
|
+
- projects: `listProjects`, `getProject`, `insertProject`, `updateProject`, `deleteProject`, and the
|
|
40
|
+
run-status rollups (`listLatestRunStatuses`, `listLatestProjectRunStatuses`,
|
|
41
|
+
`listLatestConversationRunStatuses`, `listFirstConversationRunStatuses`,
|
|
42
|
+
`listProjectsAwaitingInput`, `listConversationsAwaitingInput`)
|
|
43
|
+
- conversations: `listConversations`, `getConversation`, `insertConversation`, `updateConversation`,
|
|
44
|
+
`deleteConversation`, `normalizeConversationSessionMode`
|
|
45
|
+
- messages: `listMessages`, `upsertMessage`, `deleteMessage`, `appendMessageStatusEvent`,
|
|
46
|
+
`appendMessageAgentEvent`, `getMessageTelemetryFinalizationState`, and
|
|
47
|
+
`MessageConversationMismatchError`
|
|
48
|
+
- agent sessions: `getAgentSession`, `getAgentSessionRecord`, `upsertAgentSession`,
|
|
49
|
+
`clearAgentSession`, `updateAgentSessionStableHash`, `latestCompletedAssistantMessageId`
|
|
50
|
+
|
|
51
|
+
**Tool catalog** — `ensureToolCatalogTables`, `reseedToolCatalog`, `getToolCatalogEntry`,
|
|
52
|
+
`searchToolCatalog` (FTS-backed), with `ToolCatalogEntry` / `ToolCatalogSearchHit`.
|
|
53
|
+
|
|
54
|
+
**Inspection** — `inspectSqliteDatabase({ db, file })` → `DaemonDbStatusReport` (table/row
|
|
55
|
+
inventory) and `verifySqliteIntegrity(opts)` → `DbIntegrityReport` (`PRAGMA integrity_check` plus
|
|
56
|
+
foreign-key violations).
|
|
57
|
+
|
|
58
|
+
**Row utilities** — `row`, `rows`, `parseJsonOrUndef`.
|
|
59
|
+
|
|
60
|
+
## Usage
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import {
|
|
64
|
+
createSqliteEventLog,
|
|
65
|
+
openDatabase,
|
|
66
|
+
migrate,
|
|
67
|
+
listProjects,
|
|
68
|
+
searchToolCatalog,
|
|
69
|
+
verifySqliteIntegrity,
|
|
70
|
+
} from '@jini-ai/sqlite';
|
|
71
|
+
import type { EventLog } from '@jini-ai/protocol';
|
|
72
|
+
|
|
73
|
+
// The durable EventLog port — drop-in for @jini-ai/daemon's in-memory log.
|
|
74
|
+
const eventLog: EventLog = createSqliteEventLog('/var/lib/example/events.sqlite', {
|
|
75
|
+
maxEntriesPerRun: 5000,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
await eventLog.append({ runId: 'run_123', event: 'stdout', data: { text: 'hello' } });
|
|
79
|
+
const replay = await eventLog.replay('run_123', null);
|
|
80
|
+
if (replay.kind === 'replay-gap') {
|
|
81
|
+
// The requested cursor was already evicted — resync rather than trusting a hole.
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// The application database.
|
|
85
|
+
const db = openDatabase('/srv/workspace');
|
|
86
|
+
migrate(db);
|
|
87
|
+
|
|
88
|
+
const projects = listProjects(db);
|
|
89
|
+
const hits = searchToolCatalog(db, 'deploy', 5);
|
|
90
|
+
const integrity = verifySqliteIntegrity({ db });
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## What's swappable
|
|
94
|
+
|
|
95
|
+
This package *is* an adapter — it implements `@jini-ai/protocol`'s `EventLog` so a host can bind
|
|
96
|
+
either it or an in-memory log behind the same token. Going the other way, very little inside is
|
|
97
|
+
injectable: `createSqliteEventLog` takes only a path plus the retention cap, and the query helpers
|
|
98
|
+
take an already-open `SqliteDb` handle (so you control connection lifetime, and can pass a
|
|
99
|
+
`:memory:` database in tests) but the SQL and schema themselves are fixed.
|
|
100
|
+
`resolveSqliteBackendConfig` reads a caller-supplied `env` record rather than `process.env` directly.
|
|
101
|
+
|
|
102
|
+
## Runtime
|
|
103
|
+
|
|
104
|
+
`jini.runtime: "node"` — `better-sqlite3` plus `node:fs`/`node:path`.
|
|
105
|
+
ESM only — ships `"type": "module"` with no CommonJS `require` build.
|
|
106
|
+
|
|
107
|
+
## Provenance
|
|
108
|
+
|
|
109
|
+
See [source-map.md](./source-map.md) for per-file provenance and scope decisions. Apache-2.0,
|
|
110
|
+
inherited from Open Design — see the repo `NOTICE`.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module db/chat-history
|
|
3
|
+
*
|
|
4
|
+
* Durable, owner-scoped chat history — the SQLite side of `@jini-ai/chat/core`'s
|
|
5
|
+
* `ChatHistoryStore`. Takes an injected handle and never opens a database of its own, so a host
|
|
6
|
+
* with its own file (and its own migration tooling) can use it without adopting this package's
|
|
7
|
+
* `app.sqlite`.
|
|
8
|
+
*
|
|
9
|
+
* Distinct from the older `db/conversations` module, which is `project_id`-scoped with no owner
|
|
10
|
+
* predicate at all — correct for a single-user local app, unsafe for a shared one. See
|
|
11
|
+
* `store.ts`'s header.
|
|
12
|
+
*/
|
|
13
|
+
export * from './schema.js';
|
|
14
|
+
export * from './store.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/db/chat-history/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module db/chat-history
|
|
3
|
+
*
|
|
4
|
+
* Durable, owner-scoped chat history — the SQLite side of `@jini-ai/chat/core`'s
|
|
5
|
+
* `ChatHistoryStore`. Takes an injected handle and never opens a database of its own, so a host
|
|
6
|
+
* with its own file (and its own migration tooling) can use it without adopting this package's
|
|
7
|
+
* `app.sqlite`.
|
|
8
|
+
*
|
|
9
|
+
* Distinct from the older `db/conversations` module, which is `project_id`-scoped with no owner
|
|
10
|
+
* predicate at all — correct for a single-user local app, unsafe for a shared one. See
|
|
11
|
+
* `store.ts`'s header.
|
|
12
|
+
*/
|
|
13
|
+
export * from './schema.js';
|
|
14
|
+
export * from './store.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/db/chat-history/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module db/chat-history/schema
|
|
3
|
+
*
|
|
4
|
+
* DDL for durable chat history (`ai_chats` + `ai_chat_messages`), exported as a constant so a
|
|
5
|
+
* host that owns its own migration tooling applies the *same* statements this package's
|
|
6
|
+
* {@link ensureChatHistoryTables} would — the schema is defined once and cannot drift between
|
|
7
|
+
* the two paths.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately NOT wired into `schema/migrate.ts`, following `tool-catalog.ts`'s precedent and
|
|
10
|
+
* for its stated reason: `migrate()` opens and owns `<dataDir>/app.sqlite`, so anything it
|
|
11
|
+
* creates lands in *this package's* database. A host with its own database (the reference
|
|
12
|
+
* implementation's `content.db`)
|
|
13
|
+
* must not have a second migrator writing DDL into it behind its backup and snapshot tooling.
|
|
14
|
+
* Such a host copies {@link CHAT_HISTORY_DDL} into its own numbered migration and never calls
|
|
15
|
+
* `ensureChatHistoryTables`; a host with no migration system of its own calls the function.
|
|
16
|
+
* Both end up at the same schema.
|
|
17
|
+
*
|
|
18
|
+
* Two tables, not one. `session_key_hash` is a bearer credential and must not repeat on every
|
|
19
|
+
* message row; retention becomes one cascading `DELETE`; an empty conversation has to be
|
|
20
|
+
* representable so "New chat" can exist before the first message; and a list view needs a row
|
|
21
|
+
* to list without touching message storage at all.
|
|
22
|
+
*/
|
|
23
|
+
import type { SqliteDb } from '../core/types.js';
|
|
24
|
+
/**
|
|
25
|
+
* The canonical chat-history schema.
|
|
26
|
+
*
|
|
27
|
+
* Notes on the parts that are easy to get wrong:
|
|
28
|
+
*
|
|
29
|
+
* - **`scope_id`** is the host's partition key (workspace/tenant/project). It is `NOT NULL` from
|
|
30
|
+
* the first migration on purpose: adding it later is trivial, but *backfilling* it is not —
|
|
31
|
+
* pre-existing rows carry no evidence of which partition they belonged to, so a late addition
|
|
32
|
+
* forces a choice between deleting history and guessing.
|
|
33
|
+
* - **`owner_kind` + the CHECK pair** make "a guest row with a `user_id`" unrepresentable rather
|
|
34
|
+
* than merely discouraged.
|
|
35
|
+
* - **`owner_id`** holds a user id for `user`, and a *hash* of the session key for `guest`. The
|
|
36
|
+
* raw token never reaches this table.
|
|
37
|
+
* - **`title_source`** exists so an agent-generated title cannot clobber a manual rename. That
|
|
38
|
+
* rule is enforced in the store, but it needs a column to be enforceable at all.
|
|
39
|
+
* - **`position`** orders messages, not `created_at`: two inserts inside the same millisecond
|
|
40
|
+
* are ordinary under concurrent writers, and a tie there corrupts replay order permanently.
|
|
41
|
+
* `UNIQUE (conversation_id, position)` turns a position-assignment bug into a loud constraint
|
|
42
|
+
* violation instead of a silently scrambled transcript.
|
|
43
|
+
* - **`expires_at NULL`** means "never expires". The retention sweep filters on
|
|
44
|
+
* `expires_at IS NOT NULL`, so authenticated history is out of its reach by construction, not
|
|
45
|
+
* by a predicate that could drift.
|
|
46
|
+
*/
|
|
47
|
+
export declare const CHAT_HISTORY_DDL = "\nCREATE TABLE IF NOT EXISTS ai_chats (\n id TEXT PRIMARY KEY,\n scope_id TEXT NOT NULL,\n owner_kind TEXT NOT NULL CHECK (owner_kind IN ('user','guest')),\n owner_id TEXT NOT NULL,\n title TEXT,\n title_source TEXT NOT NULL DEFAULT 'fallback'\n CHECK (title_source IN ('fallback','generated','manual')),\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n expires_at INTEGER\n);\n\nCREATE INDEX IF NOT EXISTS idx_ai_chats_owner\n ON ai_chats(scope_id, owner_kind, owner_id, updated_at DESC);\n\nCREATE INDEX IF NOT EXISTS idx_ai_chats_expiry\n ON ai_chats(expires_at) WHERE expires_at IS NOT NULL;\n\nCREATE TABLE IF NOT EXISTS ai_chat_messages (\n id TEXT PRIMARY KEY,\n conversation_id TEXT NOT NULL REFERENCES ai_chats(id) ON DELETE CASCADE,\n role TEXT NOT NULL CHECK (role IN ('user','assistant')),\n content TEXT NOT NULL,\n agent_id TEXT,\n agent_name TEXT,\n events_json TEXT,\n attachments_json TEXT,\n run_id TEXT,\n run_status TEXT,\n position INTEGER NOT NULL,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n ended_at INTEGER,\n UNIQUE (conversation_id, position)\n);\n\nCREATE INDEX IF NOT EXISTS idx_ai_chat_messages_order\n ON ai_chat_messages(conversation_id, position);\n";
|
|
48
|
+
/**
|
|
49
|
+
* Creates the chat-history tables in the given database if they are absent.
|
|
50
|
+
*
|
|
51
|
+
* Idempotent, matching `ensureToolCatalogTables`'s convention. For a host whose database is
|
|
52
|
+
* managed by its own migration system, prefer copying {@link CHAT_HISTORY_DDL} into a numbered
|
|
53
|
+
* migration instead — see this module's header for why two migrators over one file is a hazard.
|
|
54
|
+
*
|
|
55
|
+
* The caller is responsible for `PRAGMA foreign_keys = ON`; without it the `ON DELETE CASCADE`
|
|
56
|
+
* above is silently inert and deleting a conversation orphans its messages. This function does
|
|
57
|
+
* not set it, because pragmas are connection-wide and a library has no business reconfiguring a
|
|
58
|
+
* handle it was merely lent.
|
|
59
|
+
*/
|
|
60
|
+
export declare function ensureChatHistoryTables(db: SqliteDb): void;
|
|
61
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/db/chat-history/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,gBAAgB,u2CAwC5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAE1D"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The canonical chat-history schema.
|
|
3
|
+
*
|
|
4
|
+
* Notes on the parts that are easy to get wrong:
|
|
5
|
+
*
|
|
6
|
+
* - **`scope_id`** is the host's partition key (workspace/tenant/project). It is `NOT NULL` from
|
|
7
|
+
* the first migration on purpose: adding it later is trivial, but *backfilling* it is not —
|
|
8
|
+
* pre-existing rows carry no evidence of which partition they belonged to, so a late addition
|
|
9
|
+
* forces a choice between deleting history and guessing.
|
|
10
|
+
* - **`owner_kind` + the CHECK pair** make "a guest row with a `user_id`" unrepresentable rather
|
|
11
|
+
* than merely discouraged.
|
|
12
|
+
* - **`owner_id`** holds a user id for `user`, and a *hash* of the session key for `guest`. The
|
|
13
|
+
* raw token never reaches this table.
|
|
14
|
+
* - **`title_source`** exists so an agent-generated title cannot clobber a manual rename. That
|
|
15
|
+
* rule is enforced in the store, but it needs a column to be enforceable at all.
|
|
16
|
+
* - **`position`** orders messages, not `created_at`: two inserts inside the same millisecond
|
|
17
|
+
* are ordinary under concurrent writers, and a tie there corrupts replay order permanently.
|
|
18
|
+
* `UNIQUE (conversation_id, position)` turns a position-assignment bug into a loud constraint
|
|
19
|
+
* violation instead of a silently scrambled transcript.
|
|
20
|
+
* - **`expires_at NULL`** means "never expires". The retention sweep filters on
|
|
21
|
+
* `expires_at IS NOT NULL`, so authenticated history is out of its reach by construction, not
|
|
22
|
+
* by a predicate that could drift.
|
|
23
|
+
*/
|
|
24
|
+
export const CHAT_HISTORY_DDL = `
|
|
25
|
+
CREATE TABLE IF NOT EXISTS ai_chats (
|
|
26
|
+
id TEXT PRIMARY KEY,
|
|
27
|
+
scope_id TEXT NOT NULL,
|
|
28
|
+
owner_kind TEXT NOT NULL CHECK (owner_kind IN ('user','guest')),
|
|
29
|
+
owner_id TEXT NOT NULL,
|
|
30
|
+
title TEXT,
|
|
31
|
+
title_source TEXT NOT NULL DEFAULT 'fallback'
|
|
32
|
+
CHECK (title_source IN ('fallback','generated','manual')),
|
|
33
|
+
created_at INTEGER NOT NULL,
|
|
34
|
+
updated_at INTEGER NOT NULL,
|
|
35
|
+
expires_at INTEGER
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_ai_chats_owner
|
|
39
|
+
ON ai_chats(scope_id, owner_kind, owner_id, updated_at DESC);
|
|
40
|
+
|
|
41
|
+
CREATE INDEX IF NOT EXISTS idx_ai_chats_expiry
|
|
42
|
+
ON ai_chats(expires_at) WHERE expires_at IS NOT NULL;
|
|
43
|
+
|
|
44
|
+
CREATE TABLE IF NOT EXISTS ai_chat_messages (
|
|
45
|
+
id TEXT PRIMARY KEY,
|
|
46
|
+
conversation_id TEXT NOT NULL REFERENCES ai_chats(id) ON DELETE CASCADE,
|
|
47
|
+
role TEXT NOT NULL CHECK (role IN ('user','assistant')),
|
|
48
|
+
content TEXT NOT NULL,
|
|
49
|
+
agent_id TEXT,
|
|
50
|
+
agent_name TEXT,
|
|
51
|
+
events_json TEXT,
|
|
52
|
+
attachments_json TEXT,
|
|
53
|
+
run_id TEXT,
|
|
54
|
+
run_status TEXT,
|
|
55
|
+
position INTEGER NOT NULL,
|
|
56
|
+
created_at INTEGER NOT NULL,
|
|
57
|
+
started_at INTEGER,
|
|
58
|
+
ended_at INTEGER,
|
|
59
|
+
UNIQUE (conversation_id, position)
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_ai_chat_messages_order
|
|
63
|
+
ON ai_chat_messages(conversation_id, position);
|
|
64
|
+
`;
|
|
65
|
+
/**
|
|
66
|
+
* Creates the chat-history tables in the given database if they are absent.
|
|
67
|
+
*
|
|
68
|
+
* Idempotent, matching `ensureToolCatalogTables`'s convention. For a host whose database is
|
|
69
|
+
* managed by its own migration system, prefer copying {@link CHAT_HISTORY_DDL} into a numbered
|
|
70
|
+
* migration instead — see this module's header for why two migrators over one file is a hazard.
|
|
71
|
+
*
|
|
72
|
+
* The caller is responsible for `PRAGMA foreign_keys = ON`; without it the `ON DELETE CASCADE`
|
|
73
|
+
* above is silently inert and deleting a conversation orphans its messages. This function does
|
|
74
|
+
* not set it, because pragmas are connection-wide and a library has no business reconfiguring a
|
|
75
|
+
* handle it was merely lent.
|
|
76
|
+
*/
|
|
77
|
+
export function ensureChatHistoryTables(db) {
|
|
78
|
+
db.exec(CHAT_HISTORY_DDL);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/db/chat-history/schema.ts"],"names":[],"mappings":"AAwBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwC/B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CAAC,EAAY;IAClD,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module db/chat-history/store
|
|
3
|
+
*
|
|
4
|
+
* The SQLite implementation of `@jini-ai/chat/core`'s `ChatHistoryStore`, bound to one owner.
|
|
5
|
+
*
|
|
6
|
+
* The load-bearing property of this file is that **there is no way to obtain an unscoped store**.
|
|
7
|
+
* {@link createChatHistoryStore} takes the scope up front and closes over it; every statement
|
|
8
|
+
* below carries `scope_id = ? AND owner_kind = ? AND owner_id = ?` in its `WHERE` clause, and no
|
|
9
|
+
* exported function accepts a bare conversation id without one. A route handler that forgets the
|
|
10
|
+
* predicate cannot compile, because it never holds the pieces to write the query itself.
|
|
11
|
+
*
|
|
12
|
+
* This is a deliberate departure from this package's older `db/conversations` module, whose
|
|
13
|
+
* `getConversation(db, id)` / `deleteConversation(db, id)` / `listMessages(db, conversationId)`
|
|
14
|
+
* take no owner at all. That module's trust boundary is "you can open this local SQLite file",
|
|
15
|
+
* which is correct for a single-user desktop app and unusable for a shared multi-tenant one.
|
|
16
|
+
* Both exist; pick by trust model, not by convenience.
|
|
17
|
+
*
|
|
18
|
+
* The handle is **injected, never opened here**. `connection.ts`'s `openDatabase` owns
|
|
19
|
+
* `<dataDir>/app.sqlite`; a host with its own database passes its own handle and this module
|
|
20
|
+
* writes into it without ever knowing its path. That injection is what lets the same adapter
|
|
21
|
+
* serve this package's daemon and a host CMS without either one adopting the other's file.
|
|
22
|
+
*/
|
|
23
|
+
import type { ChatHistoryMaintenance, ChatHistoryStore, ChatOwnerScope } from '@jini-ai/chat';
|
|
24
|
+
import type { SqliteDb } from '../core/types.js';
|
|
25
|
+
/**
|
|
26
|
+
* Returns a {@link ChatHistoryStore} that can only ever see `scope`'s own conversations.
|
|
27
|
+
*
|
|
28
|
+
* @param db an open `better-sqlite3` handle owned by the caller. This function neither opens nor
|
|
29
|
+
* closes it, and does not set pragmas on it — see `schema.ts` on `foreign_keys`.
|
|
30
|
+
* @param scope the isolation predicate, resolved from the host's authentication. For a `guest`,
|
|
31
|
+
* `ownerId` must already be a hash of the session key; this module never hashes and never
|
|
32
|
+
* verifies that it was hashed.
|
|
33
|
+
* @param now injectable clock, for tests that need deterministic timestamps.
|
|
34
|
+
*/
|
|
35
|
+
export declare function createChatHistoryStore(db: SqliteDb, scope: ChatOwnerScope, now?: () => number): ChatHistoryStore;
|
|
36
|
+
/**
|
|
37
|
+
* Retention, across every owner — which is why it is a separate factory rather than a method on
|
|
38
|
+
* a scoped store. Handing this to a store would mean an unscoped store had to exist.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createChatHistoryMaintenance(db: SqliteDb): ChatHistoryMaintenance;
|
|
41
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/db/chat-history/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAEV,sBAAsB,EACtB,gBAAgB,EAEhB,cAAc,EAGf,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAS,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AA0FxD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,QAAQ,EACZ,KAAK,EAAE,cAAc,EACrB,GAAG,GAAE,MAAM,MAAiB,GAC3B,gBAAgB,CAgLlB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,QAAQ,GAAG,sBAAsB,CAmBjF"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/** Columns that make up a `ChatConversation`, aliased once so every read projects identically. */
|
|
2
|
+
const CONVERSATION_COLUMNS = `
|
|
3
|
+
c.id AS id,
|
|
4
|
+
c.title AS title,
|
|
5
|
+
c.title_source AS titleSource,
|
|
6
|
+
c.created_at AS createdAt,
|
|
7
|
+
c.updated_at AS updatedAt,
|
|
8
|
+
c.expires_at AS expiresAt,
|
|
9
|
+
(SELECT COUNT(*) FROM ai_chat_messages m WHERE m.conversation_id = c.id) AS messageCount
|
|
10
|
+
`;
|
|
11
|
+
/** The isolation predicate. Every statement in this file uses this exact clause. */
|
|
12
|
+
const OWNER_PREDICATE = `c.scope_id = ? AND c.owner_kind = ? AND c.owner_id = ?`;
|
|
13
|
+
function toConversation(row) {
|
|
14
|
+
return {
|
|
15
|
+
id: row.id,
|
|
16
|
+
title: row.title ?? null,
|
|
17
|
+
titleSource: (row.titleSource ?? 'fallback'),
|
|
18
|
+
messageCount: Number(row.messageCount ?? 0),
|
|
19
|
+
createdAt: Number(row.createdAt),
|
|
20
|
+
updatedAt: Number(row.updatedAt),
|
|
21
|
+
...(row.expiresAt === null || row.expiresAt === undefined ? {} : { expiresAt: Number(row.expiresAt) }),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* KNOWN GAP — `resumable` and `lastRunEventId` are dropped, deliberately, and adding columns is
|
|
26
|
+
* NOT the fix.
|
|
27
|
+
*
|
|
28
|
+
* `ChatMessage` declares both (`@jini-ai/chat/core`'s `messages.ts`): `resumable` marks a failed run
|
|
29
|
+
* recoverable by resuming the agent's existing session rather than restarting it, and
|
|
30
|
+
* `lastRunEventId` is the cursor to resume from. Neither the projection below, nor `appendMessage`'s
|
|
31
|
+
* insert, nor `CHAT_HISTORY_DDL` carries them, so a message round-tripped through this store comes
|
|
32
|
+
* back with both `undefined` and a failed run cannot be resumed at its cursor. It fails silently —
|
|
33
|
+
* `toMessage` omits absent keys rather than throwing, so the caller gets a well-formed `ChatMessage`.
|
|
34
|
+
*
|
|
35
|
+
* Why the obvious fix is wrong. Both fields describe a RUN, and the daemon owns run state
|
|
36
|
+
* (`@jini-ai/daemon`'s `run-lifecycle.ts` is what decides `resumable` from the terminal event). The
|
|
37
|
+
* component writing through this store today is the host's BROWSER, which knows only what its chat
|
|
38
|
+
* pane handed it. Adding the columns would ask the component that does not own the data to persist
|
|
39
|
+
* it — the values would be as trustworthy as whatever the client happened to send. The ordering that
|
|
40
|
+
* actually works is: associate a run with a conversation id first, then let the daemon persist
|
|
41
|
+
* run-linked state as it streams, and only then add storage for it, at which point there is a
|
|
42
|
+
* consumer to validate the shape against.
|
|
43
|
+
*
|
|
44
|
+
* Two further facts worth having before touching this. First, this is the multi-tenant store; its
|
|
45
|
+
* sibling `db/messages/messages.ts` DOES carry `last_run_event_id`, so the two message stores in
|
|
46
|
+
* this package genuinely disagree and neither is evidence about the other. Second,
|
|
47
|
+
* `CHAT_HISTORY_DDL` is copied verbatim into the reference implementation's
|
|
48
|
+
* `0023_ai_chat_history.sql` and guarded by a
|
|
49
|
+
* structural parity test there; that migration is already applied, so any column added here also
|
|
50
|
+
* needs a follow-up `ALTER TABLE` on the host side and a parity test taught to compare the pair
|
|
51
|
+
* against this constant.
|
|
52
|
+
*/
|
|
53
|
+
function toMessage(row) {
|
|
54
|
+
return {
|
|
55
|
+
id: row.id,
|
|
56
|
+
role: row.role,
|
|
57
|
+
content: row.content,
|
|
58
|
+
...(row.agentId ? { agentId: row.agentId } : {}),
|
|
59
|
+
...(row.agentName ? { agentName: row.agentName } : {}),
|
|
60
|
+
...(row.eventsJson ? { events: safeParse(row.eventsJson) } : {}),
|
|
61
|
+
...(row.attachmentsJson ? { attachments: safeParse(row.attachmentsJson) } : {}),
|
|
62
|
+
...(row.runId ? { runId: row.runId } : {}),
|
|
63
|
+
...(row.runStatus ? { runStatus: row.runStatus } : {}),
|
|
64
|
+
...(row.createdAt === null || row.createdAt === undefined ? {} : { createdAt: Number(row.createdAt) }),
|
|
65
|
+
...(row.startedAt === null || row.startedAt === undefined ? {} : { startedAt: Number(row.startedAt) }),
|
|
66
|
+
...(row.endedAt === null || row.endedAt === undefined ? {} : { endedAt: Number(row.endedAt) }),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A malformed JSON column yields `undefined` rather than throwing.
|
|
71
|
+
*
|
|
72
|
+
* A single corrupt `events_json` — a half-written row from a crash mid-stream, say — must not
|
|
73
|
+
* make an entire conversation unreadable. The message's text lives in its own column and is
|
|
74
|
+
* still recoverable; losing the event timeline for one turn is a far better outcome than a list
|
|
75
|
+
* view that throws.
|
|
76
|
+
*/
|
|
77
|
+
function safeParse(value) {
|
|
78
|
+
try {
|
|
79
|
+
return JSON.parse(value);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Returns a {@link ChatHistoryStore} that can only ever see `scope`'s own conversations.
|
|
87
|
+
*
|
|
88
|
+
* @param db an open `better-sqlite3` handle owned by the caller. This function neither opens nor
|
|
89
|
+
* closes it, and does not set pragmas on it — see `schema.ts` on `foreign_keys`.
|
|
90
|
+
* @param scope the isolation predicate, resolved from the host's authentication. For a `guest`,
|
|
91
|
+
* `ownerId` must already be a hash of the session key; this module never hashes and never
|
|
92
|
+
* verifies that it was hashed.
|
|
93
|
+
* @param now injectable clock, for tests that need deterministic timestamps.
|
|
94
|
+
*/
|
|
95
|
+
export function createChatHistoryStore(db, scope, now = Date.now) {
|
|
96
|
+
const owner = [scope.scopeId, scope.ownerKind, scope.ownerId];
|
|
97
|
+
/** `true` only when this scope owns the conversation — the gate every message write passes. */
|
|
98
|
+
function owns(conversationId) {
|
|
99
|
+
const row = db
|
|
100
|
+
.prepare(`SELECT 1 FROM ai_chats c WHERE c.id = ? AND ${OWNER_PREDICATE}`)
|
|
101
|
+
.get(conversationId, ...owner);
|
|
102
|
+
return row !== undefined;
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
async list() {
|
|
106
|
+
const rows = db
|
|
107
|
+
.prepare(`SELECT ${CONVERSATION_COLUMNS} FROM ai_chats c
|
|
108
|
+
WHERE ${OWNER_PREDICATE}
|
|
109
|
+
ORDER BY c.updated_at DESC`)
|
|
110
|
+
.all(...owner);
|
|
111
|
+
return rows.map(toConversation);
|
|
112
|
+
},
|
|
113
|
+
async get(id) {
|
|
114
|
+
const row = db
|
|
115
|
+
.prepare(`SELECT ${CONVERSATION_COLUMNS} FROM ai_chats c
|
|
116
|
+
WHERE c.id = ? AND ${OWNER_PREDICATE}`)
|
|
117
|
+
.get(id, ...owner);
|
|
118
|
+
return row ? toConversation(row) : null;
|
|
119
|
+
},
|
|
120
|
+
async create(input) {
|
|
121
|
+
const ts = now();
|
|
122
|
+
db.prepare(`INSERT INTO ai_chats
|
|
123
|
+
(id, scope_id, owner_kind, owner_id, title, title_source, created_at, updated_at, expires_at)
|
|
124
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(input.id, scope.scopeId, scope.ownerKind, scope.ownerId, input.title ?? null, input.titleSource ?? 'fallback', ts, ts, input.expiresAt ?? null);
|
|
125
|
+
const created = await this.get(input.id);
|
|
126
|
+
// Unreachable in practice: the INSERT above used this exact scope, so the scoped read
|
|
127
|
+
// that follows cannot miss it. Asserted rather than `!`-ed so a future change to either
|
|
128
|
+
// statement fails loudly here instead of returning a malformed conversation.
|
|
129
|
+
if (!created)
|
|
130
|
+
throw new Error(`ai_chats: created conversation ${input.id} was not readable in its own scope`);
|
|
131
|
+
return created;
|
|
132
|
+
},
|
|
133
|
+
async rename(id, title, source = 'manual') {
|
|
134
|
+
// A generated title never overwrites one the user typed. Expressed in the WHERE clause
|
|
135
|
+
// rather than a read-then-write so a concurrent rename cannot slip between the two.
|
|
136
|
+
const guard = source === 'generated' ? ` AND c.title_source <> 'manual'` : '';
|
|
137
|
+
db.prepare(`UPDATE ai_chats AS c
|
|
138
|
+
SET title = ?, title_source = ?, updated_at = ?
|
|
139
|
+
WHERE c.id = ? AND ${OWNER_PREDICATE}${guard}`).run(title, source, now(), id, ...owner);
|
|
140
|
+
return this.get(id);
|
|
141
|
+
},
|
|
142
|
+
async touch(id, options) {
|
|
143
|
+
const ts = now();
|
|
144
|
+
if (options?.expiresAt === undefined) {
|
|
145
|
+
db.prepare(`UPDATE ai_chats AS c SET updated_at = ? WHERE c.id = ? AND ${OWNER_PREDICATE}`)
|
|
146
|
+
.run(ts, id, ...owner);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
db.prepare(`UPDATE ai_chats AS c SET updated_at = ?, expires_at = ? WHERE c.id = ? AND ${OWNER_PREDICATE}`).run(ts, options.expiresAt, id, ...owner);
|
|
150
|
+
},
|
|
151
|
+
async delete(id) {
|
|
152
|
+
// Messages go via `ON DELETE CASCADE`, which requires `PRAGMA foreign_keys = ON` on this
|
|
153
|
+
// connection. See `schema.ts` — a library setting connection-wide pragmas on a borrowed
|
|
154
|
+
// handle would be worse than documenting the requirement.
|
|
155
|
+
db.prepare(`DELETE FROM ai_chats AS c WHERE c.id = ? AND ${OWNER_PREDICATE}`).run(id, ...owner);
|
|
156
|
+
},
|
|
157
|
+
async messages(conversationId) {
|
|
158
|
+
const rows = db
|
|
159
|
+
.prepare(`SELECT m.id, m.role, m.content, m.agent_id AS agentId, m.agent_name AS agentName,
|
|
160
|
+
m.events_json AS eventsJson, m.attachments_json AS attachmentsJson,
|
|
161
|
+
m.run_id AS runId, m.run_status AS runStatus, m.created_at AS createdAt,
|
|
162
|
+
m.started_at AS startedAt, m.ended_at AS endedAt
|
|
163
|
+
FROM ai_chat_messages m
|
|
164
|
+
JOIN ai_chats c ON c.id = m.conversation_id
|
|
165
|
+
WHERE m.conversation_id = ? AND ${OWNER_PREDICATE}
|
|
166
|
+
ORDER BY m.position`)
|
|
167
|
+
.all(conversationId, ...owner);
|
|
168
|
+
return rows.map(toMessage);
|
|
169
|
+
},
|
|
170
|
+
async appendMessage(conversationId, message) {
|
|
171
|
+
if (!owns(conversationId))
|
|
172
|
+
return null;
|
|
173
|
+
// One `BEGIN IMMEDIATE` around read-then-write: `MAX(position) + 1` computed outside a
|
|
174
|
+
// write transaction is the classic way two concurrent turns claim the same slot. The
|
|
175
|
+
// `UNIQUE (conversation_id, position)` constraint is the backstop if this is ever bypassed.
|
|
176
|
+
//
|
|
177
|
+
// `owns()` above is NOT sufficient on its own, which is why the upsert below carries its own
|
|
178
|
+
// conversation predicate. `owns()` authorizes the *conversation* being written to; the upsert's
|
|
179
|
+
// conflict target is `id`, the GLOBAL primary key on messages. Without the `WHERE`, appending a
|
|
180
|
+
// message id that already exists in someone else's conversation updated THAT row — the caller
|
|
181
|
+
// legitimately owned the conversation it named, so nothing here refused it, and it then got
|
|
182
|
+
// `null` back (a 404 at the route) after the write had landed. See the
|
|
183
|
+
// "colliding id to its OWN chat" case in `__tests__/isolation.test.ts`.
|
|
184
|
+
const write = db.transaction((m) => {
|
|
185
|
+
const existing = db
|
|
186
|
+
.prepare(`SELECT position FROM ai_chat_messages WHERE id = ? AND conversation_id = ?`)
|
|
187
|
+
.get(m.id, conversationId);
|
|
188
|
+
const position = existing
|
|
189
|
+
? Number(existing.position)
|
|
190
|
+
: Number(db
|
|
191
|
+
.prepare(`SELECT COALESCE(MAX(position), -1) + 1 AS next FROM ai_chat_messages WHERE conversation_id = ?`)
|
|
192
|
+
.get(conversationId).next);
|
|
193
|
+
db.prepare(`INSERT INTO ai_chat_messages
|
|
194
|
+
(id, conversation_id, role, content, agent_id, agent_name, events_json,
|
|
195
|
+
attachments_json, run_id, run_status, position, created_at, started_at, ended_at)
|
|
196
|
+
VALUES (@id, @conversationId, @role, @content, @agentId, @agentName, @eventsJson,
|
|
197
|
+
@attachmentsJson, @runId, @runStatus, @position, @createdAt, @startedAt, @endedAt)
|
|
198
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
199
|
+
content = excluded.content,
|
|
200
|
+
events_json = excluded.events_json,
|
|
201
|
+
attachments_json = excluded.attachments_json,
|
|
202
|
+
run_id = excluded.run_id,
|
|
203
|
+
run_status = excluded.run_status,
|
|
204
|
+
started_at = excluded.started_at,
|
|
205
|
+
ended_at = excluded.ended_at
|
|
206
|
+
WHERE ai_chat_messages.conversation_id = excluded.conversation_id`).run({
|
|
207
|
+
id: m.id,
|
|
208
|
+
conversationId,
|
|
209
|
+
role: m.role,
|
|
210
|
+
content: m.content,
|
|
211
|
+
agentId: m.agentId ?? null,
|
|
212
|
+
agentName: m.agentName ?? null,
|
|
213
|
+
eventsJson: m.events ? JSON.stringify(m.events) : null,
|
|
214
|
+
attachmentsJson: m.attachments ? JSON.stringify(m.attachments) : null,
|
|
215
|
+
runId: m.runId ?? null,
|
|
216
|
+
runStatus: m.runStatus ?? null,
|
|
217
|
+
position,
|
|
218
|
+
createdAt: m.createdAt ?? now(),
|
|
219
|
+
startedAt: m.startedAt ?? null,
|
|
220
|
+
endedAt: m.endedAt ?? null,
|
|
221
|
+
});
|
|
222
|
+
// A new message is activity on the conversation; the list orders by `updated_at`, so
|
|
223
|
+
// skipping this would leave an actively-used chat sinking down the list.
|
|
224
|
+
db.prepare(`UPDATE ai_chats SET updated_at = ? WHERE id = ?`).run(now(), conversationId);
|
|
225
|
+
});
|
|
226
|
+
write(message);
|
|
227
|
+
const saved = await this.messages(conversationId);
|
|
228
|
+
return saved.find((m) => m.id === message.id) ?? null;
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Retention, across every owner — which is why it is a separate factory rather than a method on
|
|
234
|
+
* a scoped store. Handing this to a store would mean an unscoped store had to exist.
|
|
235
|
+
*/
|
|
236
|
+
export function createChatHistoryMaintenance(db) {
|
|
237
|
+
return {
|
|
238
|
+
async sweepExpired(now, limit = 500) {
|
|
239
|
+
// Bounded by `limit` so a large backlog drains in chunks. An unbounded `DELETE` holds the
|
|
240
|
+
// write lock long enough that concurrent inserts exhaust `busy_timeout` and fail outright.
|
|
241
|
+
// `expires_at IS NOT NULL` keeps never-expiring history structurally out of reach.
|
|
242
|
+
const result = db
|
|
243
|
+
.prepare(`DELETE FROM ai_chats
|
|
244
|
+
WHERE id IN (
|
|
245
|
+
SELECT id FROM ai_chats
|
|
246
|
+
WHERE expires_at IS NOT NULL AND expires_at <= ?
|
|
247
|
+
LIMIT ?
|
|
248
|
+
)`)
|
|
249
|
+
.run(now, limit);
|
|
250
|
+
return result.changes;
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/db/chat-history/store.ts"],"names":[],"mappings":"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"}
|
package/dist/db/index.d.ts
CHANGED
|
@@ -15,4 +15,10 @@ export { parseJsonOrUndef, row, rows } from './core/index.js';
|
|
|
15
15
|
export { migrate } from './schema/index.js';
|
|
16
16
|
export type { ToolCatalogEntry, ToolCatalogSearchHit } from './tool-catalog/index.js';
|
|
17
17
|
export { ensureToolCatalogTables, reseedToolCatalog, getToolCatalogEntry, searchToolCatalog } from './tool-catalog/index.js';
|
|
18
|
+
/**
|
|
19
|
+
* Owner-scoped chat history. Not to be confused with `./conversations/index.js` above: that one
|
|
20
|
+
* is `project_id`-scoped with no owner predicate (single-user local trust model), this one binds
|
|
21
|
+
* an owner into the store so no query can read across tenants. Pick by trust model.
|
|
22
|
+
*/
|
|
23
|
+
export { CHAT_HISTORY_DDL, ensureChatHistoryTables, createChatHistoryStore, createChatHistoryMaintenance } from './chat-history/index.js';
|
|
18
24
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,gCAAgC,EAChC,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,oCAAoC,EACpC,wBAAwB,EACxB,uBAAuB,EACvB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,YAAY,EACZ,4BAA4B,EAC5B,iCAAiC,EACjC,gCAAgC,EAChC,qBAAqB,EACrB,yBAAyB,EACzB,8BAA8B,EAC9B,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,iCAAiC,EACjC,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACtF,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,gCAAgC,EAChC,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,oCAAoC,EACpC,wBAAwB,EACxB,uBAAuB,EACvB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,YAAY,EACZ,4BAA4B,EAC5B,iCAAiC,EACjC,gCAAgC,EAChC,qBAAqB,EACrB,yBAAyB,EACzB,8BAA8B,EAC9B,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,iCAAiC,EACjC,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACtF,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC7H;;;;GAIG;AACH,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/db/index.js
CHANGED
|
@@ -13,4 +13,10 @@ export { getAgentSession, upsertAgentSession, getAgentSessionRecord, latestCompl
|
|
|
13
13
|
export { parseJsonOrUndef, row, rows } from './core/index.js';
|
|
14
14
|
export { migrate } from './schema/index.js';
|
|
15
15
|
export { ensureToolCatalogTables, reseedToolCatalog, getToolCatalogEntry, searchToolCatalog } from './tool-catalog/index.js';
|
|
16
|
+
/**
|
|
17
|
+
* Owner-scoped chat history. Not to be confused with `./conversations/index.js` above: that one
|
|
18
|
+
* is `project_id`-scoped with no owner predicate (single-user local trust model), this one binds
|
|
19
|
+
* an owner into the store so no query can read across tenants. Pick by trust model.
|
|
20
|
+
*/
|
|
21
|
+
export { CHAT_HISTORY_DDL, ensureChatHistoryTables, createChatHistoryStore, createChatHistoryMaintenance } from './chat-history/index.js';
|
|
16
22
|
//# sourceMappingURL=index.js.map
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,gCAAgC,EAChC,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,oCAAoC,EACpC,wBAAwB,EACxB,uBAAuB,EACvB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,YAAY,EACZ,4BAA4B,EAC5B,iCAAiC,EACjC,gCAAgC,EAChC,qBAAqB,EACrB,yBAAyB,EACzB,8BAA8B,EAC9B,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,iCAAiC,EACjC,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,gCAAgC,EAChC,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,oCAAoC,EACpC,wBAAwB,EACxB,uBAAuB,EACvB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,YAAY,EACZ,4BAA4B,EAC5B,iCAAiC,EACjC,gCAAgC,EAChC,qBAAqB,EACrB,yBAAyB,EACzB,8BAA8B,EAC9B,UAAU,EACV,aAAa,EACb,aAAa,EACb,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,iCAAiC,EACjC,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC7H;;;;GAIG;AACH,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/event-log.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EventLog } from '@jini-ai/
|
|
1
|
+
import type { EventLog } from '@jini-ai/protocol';
|
|
2
2
|
/**
|
|
3
3
|
* Default per-run retention cap applied when `SqliteEventLogOptions.maxEntriesPerRun` is
|
|
4
4
|
* omitted — see that option's doc for why a durable adapter defaults to a bound instead of
|
package/dist/event-log.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-log.d.ts","sourceRoot":"","sources":["../src/event-log.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,QAAQ,EAIT,MAAM,
|
|
1
|
+
{"version":3,"file":"event-log.d.ts","sourceRoot":"","sources":["../src/event-log.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,QAAQ,EAIT,MAAM,mBAAmB,CAAC;AAE3B;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAwBD,yHAAyH;AACzH,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC9C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAyBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,cAAc,CAuKhB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/sqlite",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "better-sqlite3-backed persistence adapters for @jini-ai/daemon’s ports: durable event log, backend selection, schema migration, and database inspection.",
|
|
4
5
|
"license": "Apache-2.0",
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
@@ -10,10 +11,12 @@
|
|
|
10
11
|
"jini": {
|
|
11
12
|
"domain": "server",
|
|
12
13
|
"kind": "persistence-adapter",
|
|
13
|
-
"runtime": "node"
|
|
14
|
-
"admission": "locked"
|
|
14
|
+
"runtime": "node"
|
|
15
15
|
},
|
|
16
16
|
"type": "module",
|
|
17
|
+
"sideEffects": false,
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
17
20
|
"exports": {
|
|
18
21
|
".": {
|
|
19
22
|
"types": "./dist/index.d.ts",
|
|
@@ -34,8 +37,9 @@
|
|
|
34
37
|
"registry": "https://registry.npmjs.org"
|
|
35
38
|
},
|
|
36
39
|
"dependencies": {
|
|
37
|
-
"better-sqlite3": "^
|
|
38
|
-
"@jini-ai/
|
|
40
|
+
"better-sqlite3": "^13.0.0",
|
|
41
|
+
"@jini-ai/chat": "0.3.0",
|
|
42
|
+
"@jini-ai/protocol": "0.3.0"
|
|
39
43
|
},
|
|
40
44
|
"devDependencies": {
|
|
41
45
|
"@types/better-sqlite3": "^7.6.11",
|