@amaster.ai/dsh-storage 0.1.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/LICENSE +21 -0
- package/README.md +66 -0
- package/cordis.patch.yml +3 -0
- package/lib/backends/database.js +198 -0
- package/lib/generated/mysql/browser.js +17 -0
- package/lib/generated/mysql/client.js +34 -0
- package/lib/generated/mysql/commonInputTypes.js +10 -0
- package/lib/generated/mysql/enums.js +10 -0
- package/lib/generated/mysql/internal/class.js +49 -0
- package/lib/generated/mysql/internal/prismaNamespace.js +146 -0
- package/lib/generated/mysql/internal/prismaNamespaceBrowser.js +117 -0
- package/lib/generated/mysql/models/AiChatHistory.js +1 -0
- package/lib/generated/mysql/models/AiMessage.js +1 -0
- package/lib/generated/mysql/models.js +1 -0
- package/lib/generated/postgresql/browser.js +17 -0
- package/lib/generated/postgresql/client.js +34 -0
- package/lib/generated/postgresql/commonInputTypes.js +10 -0
- package/lib/generated/postgresql/enums.js +10 -0
- package/lib/generated/postgresql/internal/class.js +49 -0
- package/lib/generated/postgresql/internal/prismaNamespace.js +131 -0
- package/lib/generated/postgresql/internal/prismaNamespaceBrowser.js +102 -0
- package/lib/generated/postgresql/models/AiChatHistory.js +1 -0
- package/lib/generated/postgresql/models/AiMessage.js +1 -0
- package/lib/generated/postgresql/models.js +1 -0
- package/lib/generated/sqlite/browser.js +17 -0
- package/lib/generated/sqlite/client.js +34 -0
- package/lib/generated/sqlite/commonInputTypes.js +10 -0
- package/lib/generated/sqlite/enums.js +10 -0
- package/lib/generated/sqlite/internal/class.js +49 -0
- package/lib/generated/sqlite/internal/prismaNamespace.js +128 -0
- package/lib/generated/sqlite/internal/prismaNamespaceBrowser.js +99 -0
- package/lib/generated/sqlite/models/AiChatHistory.js +1 -0
- package/lib/generated/sqlite/models/AiMessage.js +1 -0
- package/lib/generated/sqlite/models.js +1 -0
- package/lib/generated/sqlserver/browser.js +17 -0
- package/lib/generated/sqlserver/client.js +34 -0
- package/lib/generated/sqlserver/commonInputTypes.js +10 -0
- package/lib/generated/sqlserver/enums.js +10 -0
- package/lib/generated/sqlserver/internal/class.js +49 -0
- package/lib/generated/sqlserver/internal/prismaNamespace.js +119 -0
- package/lib/generated/sqlserver/internal/prismaNamespaceBrowser.js +90 -0
- package/lib/generated/sqlserver/models/AiChatHistory.js +1 -0
- package/lib/generated/sqlserver/models/AiMessage.js +1 -0
- package/lib/generated/sqlserver/models.js +1 -0
- package/lib/index.js +224 -0
- package/lib/projector.js +153 -0
- package/lib/types/backends/database.d.ts +37 -0
- package/lib/types/generated/mysql/browser.d.ts +15 -0
- package/lib/types/generated/mysql/client.d.ts +34 -0
- package/lib/types/generated/mysql/commonInputTypes.d.ts +396 -0
- package/lib/types/generated/mysql/enums.d.ts +1 -0
- package/lib/types/generated/mysql/internal/class.d.ts +143 -0
- package/lib/types/generated/mysql/internal/prismaNamespace.d.ts +709 -0
- package/lib/types/generated/mysql/internal/prismaNamespaceBrowser.d.ts +112 -0
- package/lib/types/generated/mysql/models/AiChatHistory.d.ts +1258 -0
- package/lib/types/generated/mysql/models/AiMessage.d.ts +1360 -0
- package/lib/types/generated/mysql/models.d.ts +3 -0
- package/lib/types/generated/postgresql/browser.d.ts +15 -0
- package/lib/types/generated/postgresql/client.d.ts +34 -0
- package/lib/types/generated/postgresql/commonInputTypes.d.ts +392 -0
- package/lib/types/generated/postgresql/enums.d.ts +1 -0
- package/lib/types/generated/postgresql/internal/class.d.ts +143 -0
- package/lib/types/generated/postgresql/internal/prismaNamespace.d.ts +728 -0
- package/lib/types/generated/postgresql/internal/prismaNamespaceBrowser.d.ts +95 -0
- package/lib/types/generated/postgresql/models/AiChatHistory.d.ts +1373 -0
- package/lib/types/generated/postgresql/models/AiMessage.d.ts +1497 -0
- package/lib/types/generated/postgresql/models.d.ts +3 -0
- package/lib/types/generated/sqlite/browser.d.ts +15 -0
- package/lib/types/generated/sqlite/client.d.ts +34 -0
- package/lib/types/generated/sqlite/commonInputTypes.d.ts +373 -0
- package/lib/types/generated/sqlite/enums.d.ts +1 -0
- package/lib/types/generated/sqlite/internal/class.d.ts +143 -0
- package/lib/types/generated/sqlite/internal/prismaNamespace.d.ts +705 -0
- package/lib/types/generated/sqlite/internal/prismaNamespaceBrowser.d.ts +92 -0
- package/lib/types/generated/sqlite/models/AiChatHistory.d.ts +1371 -0
- package/lib/types/generated/sqlite/models/AiMessage.d.ts +1494 -0
- package/lib/types/generated/sqlite/models.d.ts +3 -0
- package/lib/types/generated/sqlserver/browser.d.ts +15 -0
- package/lib/types/generated/sqlserver/client.d.ts +34 -0
- package/lib/types/generated/sqlserver/commonInputTypes.d.ts +333 -0
- package/lib/types/generated/sqlserver/enums.d.ts +1 -0
- package/lib/types/generated/sqlserver/internal/class.d.ts +143 -0
- package/lib/types/generated/sqlserver/internal/prismaNamespace.d.ts +669 -0
- package/lib/types/generated/sqlserver/internal/prismaNamespaceBrowser.d.ts +80 -0
- package/lib/types/generated/sqlserver/models/AiChatHistory.d.ts +1257 -0
- package/lib/types/generated/sqlserver/models/AiMessage.d.ts +1376 -0
- package/lib/types/generated/sqlserver/models.d.ts +3 -0
- package/lib/types/index.d.ts +56 -0
- package/lib/types/projector.d.ts +48 -0
- package/lib/types/types.d.ts +49 -0
- package/lib/types.js +8 -0
- package/package.json +85 -0
- package/preview.png +0 -0
- package/prisma/schema.mysql.prisma +75 -0
- package/prisma/schema.postgresql.prisma +67 -0
- package/prisma/schema.sqlite.prisma +67 -0
- package/prisma/schema.sqlserver.prisma +73 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-storage — mirrors the dsh session event stream into the ai_messages /
|
|
3
|
+
* ai_chat_histories tables (MySQL/PostgreSQL/SQLite/SQL Server).
|
|
4
|
+
*
|
|
5
|
+
* Design: dsh's own session persistence (JSONL/SQLite) stays authoritative.
|
|
6
|
+
* This plugin taps `session/event` (the same seam the built-in persistence
|
|
7
|
+
* coordinator uses) and projects events into MessageRow / SessionRow shaped
|
|
8
|
+
* after the source project's ai_messages / ai_chat_histories tables.
|
|
9
|
+
*
|
|
10
|
+
* A2A task state (task metadata in Redis, workspace archives in GCS) is NOT
|
|
11
|
+
* here — that belongs to the A2A layer, see dsh-a2a's TaskStore backends.
|
|
12
|
+
*
|
|
13
|
+
* Resume caveat (docs/subsystems/persistence.md): constructor seeds do not
|
|
14
|
+
* emit events. On agent resume, only events >= `session.firstLiveSeq` fire
|
|
15
|
+
* on this stream — historical rows must come from the database itself, not
|
|
16
|
+
* from replaying the tap.
|
|
17
|
+
*
|
|
18
|
+
* @module dsh-storage
|
|
19
|
+
*/
|
|
20
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
21
|
+
import Schema from '@deepseek-ai/schemastery';
|
|
22
|
+
import { type DatabaseProvider } from './backends/database.js';
|
|
23
|
+
export declare const name = "dsh-storage";
|
|
24
|
+
export declare const inject: string[];
|
|
25
|
+
export declare const Config: Schema<Schemastery.ObjectS<{
|
|
26
|
+
enabled: Schema<boolean, boolean>;
|
|
27
|
+
database: Schema<Schemastery.ObjectS<{
|
|
28
|
+
enabled: Schema<boolean, boolean>;
|
|
29
|
+
provider: Schema<"mysql" | "postgresql" | "sqlite" | "sqlserver", "mysql" | "postgresql" | "sqlite" | "sqlserver">;
|
|
30
|
+
url: Schema<string, string>;
|
|
31
|
+
}>, Schemastery.ObjectT<{
|
|
32
|
+
enabled: Schema<boolean, boolean>;
|
|
33
|
+
provider: Schema<"mysql" | "postgresql" | "sqlite" | "sqlserver", "mysql" | "postgresql" | "sqlite" | "sqlserver">;
|
|
34
|
+
url: Schema<string, string>;
|
|
35
|
+
}>>;
|
|
36
|
+
}>, Schemastery.ObjectT<{
|
|
37
|
+
enabled: Schema<boolean, boolean>;
|
|
38
|
+
database: Schema<Schemastery.ObjectS<{
|
|
39
|
+
enabled: Schema<boolean, boolean>;
|
|
40
|
+
provider: Schema<"mysql" | "postgresql" | "sqlite" | "sqlserver", "mysql" | "postgresql" | "sqlite" | "sqlserver">;
|
|
41
|
+
url: Schema<string, string>;
|
|
42
|
+
}>, Schemastery.ObjectT<{
|
|
43
|
+
enabled: Schema<boolean, boolean>;
|
|
44
|
+
provider: Schema<"mysql" | "postgresql" | "sqlite" | "sqlserver", "mysql" | "postgresql" | "sqlite" | "sqlserver">;
|
|
45
|
+
url: Schema<string, string>;
|
|
46
|
+
}>>;
|
|
47
|
+
}>>;
|
|
48
|
+
export interface StoragePluginConfig {
|
|
49
|
+
enabled: boolean;
|
|
50
|
+
database: {
|
|
51
|
+
enabled: boolean;
|
|
52
|
+
provider: DatabaseProvider;
|
|
53
|
+
url: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export declare function apply(ctx: Context, config: StoragePluginConfig): void;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects dsh session events onto MessageRow / SessionRow.
|
|
3
|
+
*
|
|
4
|
+
* Event shapes verified against the dsh persistence catalog
|
|
5
|
+
* (https://deepseek-harness.github.io/deepseek-harness/reference/persistence-catalog)
|
|
6
|
+
* and the @deepseek-ai/dsh-llm message types:
|
|
7
|
+
* - envelope: `{ type, seq, time, data }` — payload lives under `data`.
|
|
8
|
+
* - surface events (the only ones producing LLM messages, and the only ones
|
|
9
|
+
* projected to rows): `user/message`, `assistant/message`, `tool/result`.
|
|
10
|
+
* - token usage: `assistant/chunk` `{ type: 'usage' }` is authoritative per
|
|
11
|
+
* step; `assistant/message`'s `data.usage` only counts when no usage chunk
|
|
12
|
+
* was seen for the step (dedup in usageOf). `turn/end` carries none — it
|
|
13
|
+
* only serves as a rollup checkpoint.
|
|
14
|
+
* - compaction summaries enter the surface as a `user/message` with
|
|
15
|
+
* `surfaceOp: replace`, so they flow through the user path unchanged.
|
|
16
|
+
*/
|
|
17
|
+
import type { MessageRow } from './types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Map one session event to zero or one message row. Returns null for events
|
|
20
|
+
* that should not be persisted as standalone rows (log-only events: chunks,
|
|
21
|
+
* turn/step lifecycle, approvals, ...).
|
|
22
|
+
*/
|
|
23
|
+
export declare function projectEvent(_session: any, event: any, sessionId: string): MessageRow | null;
|
|
24
|
+
export interface UsageSample {
|
|
25
|
+
input: number;
|
|
26
|
+
output: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Extract the usage sample carried by one event, keyed by its step, or null
|
|
30
|
+
* when the event carries none.
|
|
31
|
+
*
|
|
32
|
+
* dsh-llm emits usage as:
|
|
33
|
+
* - `assistant/chunk` with `chunk.type === 'usage'` — the step's accounting,
|
|
34
|
+
* emitted even when the request later fails (a failed step produces no
|
|
35
|
+
* assistant/message, so message-only accounting would miss it entirely);
|
|
36
|
+
* - `assistant/message.data.usage` — the same step's final accounting.
|
|
37
|
+
*
|
|
38
|
+
* Samples for one `(turn, step)` are REPLACEMENTS, not additive: later
|
|
39
|
+
* samples supersede earlier ones (progressive chunks, then the message).
|
|
40
|
+
* The caller keeps the latest sample per step and folds only the delta into
|
|
41
|
+
* its rollup. Totals include the cache buckets: cacheRead/cacheWrite are
|
|
42
|
+
* billed in their own buckets (observed cacheReadTokens ≫ inputTokens in
|
|
43
|
+
* dsh session logs — they are not subsets of inputTokens).
|
|
44
|
+
*/
|
|
45
|
+
export declare function usageSampleOf(event: any): {
|
|
46
|
+
key: string;
|
|
47
|
+
sample: UsageSample;
|
|
48
|
+
} | null;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared row types and the backend contract.
|
|
3
|
+
*
|
|
4
|
+
* Row shapes mirror the `ai_messages` / `ai_chat_histories` Prisma models
|
|
5
|
+
* (see prisma/schema.{mysql,postgresql,sqlite,sqlserver}.prisma), matching
|
|
6
|
+
* the source project's tables.
|
|
7
|
+
*/
|
|
8
|
+
/** One row in `ai_messages`. */
|
|
9
|
+
export interface MessageRow {
|
|
10
|
+
id: string;
|
|
11
|
+
sessionId: string;
|
|
12
|
+
historyId: string | null;
|
|
13
|
+
/** 'user' | 'model' | 'tool' | 'utility_compressor' | plugin-defined */
|
|
14
|
+
type: string;
|
|
15
|
+
content: string;
|
|
16
|
+
thoughts?: unknown;
|
|
17
|
+
model?: string | null;
|
|
18
|
+
tokens?: unknown;
|
|
19
|
+
toolCalls?: unknown;
|
|
20
|
+
agentId?: string | null;
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
createdAt: Date;
|
|
23
|
+
}
|
|
24
|
+
/** One row in `ai_chat_histories` — a per-session rollup. */
|
|
25
|
+
export interface SessionRow {
|
|
26
|
+
sessionId: string;
|
|
27
|
+
title?: string | null;
|
|
28
|
+
messageCount: number;
|
|
29
|
+
totalTokens: number;
|
|
30
|
+
firstMessageAt?: Date | null;
|
|
31
|
+
lastMessageAt?: Date | null;
|
|
32
|
+
/** Plugin bookkeeping persisted in the row's JSON metadata column. */
|
|
33
|
+
metadata?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A storage backend receives already-projected rows. Backends must be
|
|
37
|
+
* no-throw from the plugin's perspective: implementations report errors to
|
|
38
|
+
* the plugin logger and swallow them, mirroring must never break the agent
|
|
39
|
+
* loop.
|
|
40
|
+
*/
|
|
41
|
+
export interface StorageBackend {
|
|
42
|
+
readonly name: string;
|
|
43
|
+
init?(): Promise<void>;
|
|
44
|
+
/** Read the stored session row, for seeding the live rollup on resume. */
|
|
45
|
+
readSession?(sessionId: string): Promise<SessionRow | null>;
|
|
46
|
+
upsertMessage(row: MessageRow): Promise<void>;
|
|
47
|
+
upsertSession(row: SessionRow): Promise<void>;
|
|
48
|
+
close?(): Promise<void>;
|
|
49
|
+
}
|
package/lib/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@amaster.ai/dsh-storage",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Session storage mirror for DeepSeek Harness: projects the session event stream into MySQL/PostgreSQL/SQLite/SQL Server (ai_messages / ai_chat_histories) without replacing dsh's local persistence.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/types/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"lib",
|
|
17
|
+
"prisma",
|
|
18
|
+
"cordis.patch.yml",
|
|
19
|
+
"preview.png"
|
|
20
|
+
],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/TGYD-helige/dsh-plugins.git",
|
|
28
|
+
"directory": "packages/dsh-storage"
|
|
29
|
+
},
|
|
30
|
+
"dsh": {
|
|
31
|
+
"bundle": {
|
|
32
|
+
"patch": "./cordis.patch.yml"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@deepseek-ai/schemastery": "^3.18.1"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
40
|
+
"@deepseek-ai/dsh-session": "0.1.0-rc.7",
|
|
41
|
+
"@prisma/adapter-libsql": "^7.9.1",
|
|
42
|
+
"@prisma/adapter-mariadb": "^7.9.1",
|
|
43
|
+
"@prisma/adapter-mssql": "^7.9.1",
|
|
44
|
+
"@prisma/adapter-pg": "^7.9.1",
|
|
45
|
+
"@prisma/client": "^7.9.1"
|
|
46
|
+
},
|
|
47
|
+
"peerDependenciesMeta": {
|
|
48
|
+
"@prisma/adapter-libsql": {
|
|
49
|
+
"optional": true
|
|
50
|
+
},
|
|
51
|
+
"@prisma/adapter-mariadb": {
|
|
52
|
+
"optional": true
|
|
53
|
+
},
|
|
54
|
+
"@prisma/adapter-mssql": {
|
|
55
|
+
"optional": true
|
|
56
|
+
},
|
|
57
|
+
"@prisma/adapter-pg": {
|
|
58
|
+
"optional": true
|
|
59
|
+
},
|
|
60
|
+
"@prisma/client": {
|
|
61
|
+
"optional": true
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@deepseek-ai/cordis": "^4.0.1",
|
|
66
|
+
"@prisma/adapter-libsql": "^7.9.1",
|
|
67
|
+
"@prisma/adapter-mariadb": "^7.9.1",
|
|
68
|
+
"@prisma/adapter-mssql": "^7.9.1",
|
|
69
|
+
"@prisma/adapter-pg": "^7.9.1",
|
|
70
|
+
"@prisma/client": "^7.9.1",
|
|
71
|
+
"@types/node": "^22.0.0",
|
|
72
|
+
"prisma": "^7.9.1",
|
|
73
|
+
"typescript": "^5.6.3",
|
|
74
|
+
"vitest": "^4.1.11"
|
|
75
|
+
},
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": "^20.19 || ^22.12 || >=24.0"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "node scripts/prisma-generate.mjs && tsc -p tsconfig.build.json",
|
|
81
|
+
"generate": "node scripts/prisma-generate.mjs",
|
|
82
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
83
|
+
"test": "vitest run"
|
|
84
|
+
}
|
|
85
|
+
}
|
package/preview.png
ADDED
|
Binary file
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Prisma schema for the dsh-storage database backend — MySQL variant (Prisma 7).
|
|
2
|
+
//
|
|
3
|
+
// Table layout matches the source project's ai_messages / ai_chat_histories
|
|
4
|
+
// (packages/core/prisma/schema.prisma) so existing data stays compatible:
|
|
5
|
+
// - `type` values come from the dsh session event map
|
|
6
|
+
// ('user' | 'model' | 'tool' | ...) instead of gemini-cli message roles.
|
|
7
|
+
// - `agent_id` distinguishes the main agent from subagent writers.
|
|
8
|
+
// - no user_id: tenancy is carried by session_id, not a column.
|
|
9
|
+
//
|
|
10
|
+
// The client is pre-generated at package build time (`pnpm generate`, output
|
|
11
|
+
// src/generated/mysql, compiled into lib/generated) — consumers do NOT run
|
|
12
|
+
// `prisma generate`. To create/upgrade tables, run `prisma db push` /
|
|
13
|
+
// migrations against this file; the connection URL lives in prisma.config.ts
|
|
14
|
+
// (Prisma 7 dropped datasource.url from the schema).
|
|
15
|
+
|
|
16
|
+
generator client {
|
|
17
|
+
provider = "prisma-client"
|
|
18
|
+
output = "../src/generated/mysql"
|
|
19
|
+
importFileExtension = "js"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
datasource db {
|
|
23
|
+
provider = "mysql"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// One row per projected session event (user message, assistant message,
|
|
27
|
+
/// tool call/result, compression snapshot, ...).
|
|
28
|
+
model AiMessage {
|
|
29
|
+
id String @id @default(cuid()) @db.Char(36)
|
|
30
|
+
sessionId String @map("session_id") @db.VarChar(100)
|
|
31
|
+
historyId String? @map("history_id") @db.Char(36)
|
|
32
|
+
type String @db.VarChar(50)
|
|
33
|
+
content String @db.LongText
|
|
34
|
+
thoughts Json?
|
|
35
|
+
model String? @db.VarChar(100)
|
|
36
|
+
tokens Json?
|
|
37
|
+
toolCalls Json? @map("tool_calls")
|
|
38
|
+
agentId String? @map("agent_id") @db.VarChar(100)
|
|
39
|
+
metadata Json?
|
|
40
|
+
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0)
|
|
41
|
+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamp(0)
|
|
42
|
+
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
|
|
43
|
+
|
|
44
|
+
// Relations
|
|
45
|
+
history AiChatHistory? @relation(fields: [historyId], references: [id], onDelete: NoAction)
|
|
46
|
+
|
|
47
|
+
@@index([sessionId], map: "idx_session")
|
|
48
|
+
@@index([historyId], map: "idx_history")
|
|
49
|
+
@@index([createdAt], map: "idx_created")
|
|
50
|
+
@@index([deletedAt], map: "idx_deleted")
|
|
51
|
+
@@index([agentId], map: "idx_agent")
|
|
52
|
+
@@index([sessionId, agentId, type, createdAt], map: "idx_session_agent_type_created")
|
|
53
|
+
@@map("ai_messages")
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/// Per-session rollup, maintained incrementally by the projector.
|
|
57
|
+
model AiChatHistory {
|
|
58
|
+
id String @id @default(cuid()) @db.Char(36)
|
|
59
|
+
sessionId String @map("session_id") @db.VarChar(100)
|
|
60
|
+
title String? @db.VarChar(255)
|
|
61
|
+
summary String? @db.Text
|
|
62
|
+
messageCount Int @default(0) @map("message_count")
|
|
63
|
+
totalTokens BigInt @default(0) @map("total_tokens")
|
|
64
|
+
firstMessageAt DateTime? @map("first_message_at") @db.DateTime(6)
|
|
65
|
+
lastMessageAt DateTime? @map("last_message_at") @db.DateTime(6)
|
|
66
|
+
metadata Json?
|
|
67
|
+
deletedAt DateTime? @map("deleted_at") @db.DateTime(6)
|
|
68
|
+
|
|
69
|
+
// Relations
|
|
70
|
+
messages AiMessage[]
|
|
71
|
+
|
|
72
|
+
@@index([sessionId], map: "idx_chat_history_session")
|
|
73
|
+
@@index([deletedAt], map: "idx_chat_history_deleted")
|
|
74
|
+
@@map("ai_chat_histories")
|
|
75
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Prisma schema for the dsh-storage database backend — PostgreSQL variant (Prisma 7).
|
|
2
|
+
//
|
|
3
|
+
// Same models as schema.mysql.prisma, with PostgreSQL native types
|
|
4
|
+
// (`@db.Text` instead of `@db.LongText`, `@db.Timestamp` instead of
|
|
5
|
+
// `@db.DateTime`). Client pre-generation and table creation work as described
|
|
6
|
+
// in schema.mysql.prisma's header.
|
|
7
|
+
|
|
8
|
+
generator client {
|
|
9
|
+
provider = "prisma-client"
|
|
10
|
+
output = "../src/generated/postgresql"
|
|
11
|
+
importFileExtension = "js"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
datasource db {
|
|
15
|
+
provider = "postgresql"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/// One row per projected session event (user message, assistant message,
|
|
19
|
+
/// tool call/result, compression snapshot, ...).
|
|
20
|
+
model AiMessage {
|
|
21
|
+
id String @id @default(cuid()) @db.Char(36)
|
|
22
|
+
sessionId String @map("session_id") @db.VarChar(100)
|
|
23
|
+
historyId String? @map("history_id") @db.Char(36)
|
|
24
|
+
type String @db.VarChar(50)
|
|
25
|
+
content String @db.Text
|
|
26
|
+
thoughts Json?
|
|
27
|
+
model String? @db.VarChar(100)
|
|
28
|
+
tokens Json?
|
|
29
|
+
toolCalls Json? @map("tool_calls")
|
|
30
|
+
agentId String? @map("agent_id") @db.VarChar(100)
|
|
31
|
+
metadata Json?
|
|
32
|
+
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0)
|
|
33
|
+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamp(0)
|
|
34
|
+
deletedAt DateTime? @map("deleted_at") @db.Timestamp(0)
|
|
35
|
+
|
|
36
|
+
// Relations
|
|
37
|
+
history AiChatHistory? @relation(fields: [historyId], references: [id], onDelete: NoAction)
|
|
38
|
+
|
|
39
|
+
@@index([sessionId], map: "idx_session")
|
|
40
|
+
@@index([historyId], map: "idx_history")
|
|
41
|
+
@@index([createdAt], map: "idx_created")
|
|
42
|
+
@@index([deletedAt], map: "idx_deleted")
|
|
43
|
+
@@index([agentId], map: "idx_agent")
|
|
44
|
+
@@index([sessionId, agentId, type, createdAt], map: "idx_session_agent_type_created")
|
|
45
|
+
@@map("ai_messages")
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// Per-session rollup, maintained incrementally by the projector.
|
|
49
|
+
model AiChatHistory {
|
|
50
|
+
id String @id @default(cuid()) @db.Char(36)
|
|
51
|
+
sessionId String @map("session_id") @db.VarChar(100)
|
|
52
|
+
title String? @db.VarChar(255)
|
|
53
|
+
summary String? @db.Text
|
|
54
|
+
messageCount Int @default(0) @map("message_count")
|
|
55
|
+
totalTokens BigInt @default(0) @map("total_tokens")
|
|
56
|
+
firstMessageAt DateTime? @map("first_message_at") @db.Timestamp(6)
|
|
57
|
+
lastMessageAt DateTime? @map("last_message_at") @db.Timestamp(6)
|
|
58
|
+
metadata Json?
|
|
59
|
+
deletedAt DateTime? @map("deleted_at") @db.Timestamp(6)
|
|
60
|
+
|
|
61
|
+
// Relations
|
|
62
|
+
messages AiMessage[]
|
|
63
|
+
|
|
64
|
+
@@index([sessionId], map: "idx_chat_history_session")
|
|
65
|
+
@@index([deletedAt], map: "idx_chat_history_deleted")
|
|
66
|
+
@@map("ai_chat_histories")
|
|
67
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Prisma schema for the dsh-storage database backend — SQLite variant (Prisma 7).
|
|
2
|
+
//
|
|
3
|
+
// Same models as schema.mysql.prisma, without native type attributes
|
|
4
|
+
// (SQLite has no `@db.*` vocabulary here). Client pre-generation and table
|
|
5
|
+
// creation work as described in schema.mysql.prisma's header. Connection URL
|
|
6
|
+
// shape: file:/absolute/path/to/db.sqlite.
|
|
7
|
+
|
|
8
|
+
generator client {
|
|
9
|
+
provider = "prisma-client"
|
|
10
|
+
output = "../src/generated/sqlite"
|
|
11
|
+
importFileExtension = "js"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
datasource db {
|
|
15
|
+
provider = "sqlite"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/// One row per projected session event (user message, assistant message,
|
|
19
|
+
/// tool call/result, compression snapshot, ...).
|
|
20
|
+
model AiMessage {
|
|
21
|
+
id String @id @default(cuid())
|
|
22
|
+
sessionId String @map("session_id")
|
|
23
|
+
historyId String? @map("history_id")
|
|
24
|
+
type String
|
|
25
|
+
content String
|
|
26
|
+
thoughts Json?
|
|
27
|
+
model String?
|
|
28
|
+
tokens Json?
|
|
29
|
+
toolCalls Json? @map("tool_calls")
|
|
30
|
+
agentId String? @map("agent_id")
|
|
31
|
+
metadata Json?
|
|
32
|
+
createdAt DateTime @default(now()) @map("created_at")
|
|
33
|
+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
|
|
34
|
+
deletedAt DateTime? @map("deleted_at")
|
|
35
|
+
|
|
36
|
+
// Relations
|
|
37
|
+
history AiChatHistory? @relation(fields: [historyId], references: [id], onDelete: NoAction)
|
|
38
|
+
|
|
39
|
+
@@index([sessionId], map: "idx_session")
|
|
40
|
+
@@index([historyId], map: "idx_history")
|
|
41
|
+
@@index([createdAt], map: "idx_created")
|
|
42
|
+
@@index([deletedAt], map: "idx_deleted")
|
|
43
|
+
@@index([agentId], map: "idx_agent")
|
|
44
|
+
@@index([sessionId, agentId, type, createdAt], map: "idx_session_agent_type_created")
|
|
45
|
+
@@map("ai_messages")
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// Per-session rollup, maintained incrementally by the projector.
|
|
49
|
+
model AiChatHistory {
|
|
50
|
+
id String @id @default(cuid())
|
|
51
|
+
sessionId String @map("session_id")
|
|
52
|
+
title String?
|
|
53
|
+
summary String?
|
|
54
|
+
messageCount Int @default(0) @map("message_count")
|
|
55
|
+
totalTokens BigInt @default(0) @map("total_tokens")
|
|
56
|
+
firstMessageAt DateTime? @map("first_message_at")
|
|
57
|
+
lastMessageAt DateTime? @map("last_message_at")
|
|
58
|
+
metadata Json?
|
|
59
|
+
deletedAt DateTime? @map("deleted_at")
|
|
60
|
+
|
|
61
|
+
// Relations
|
|
62
|
+
messages AiMessage[]
|
|
63
|
+
|
|
64
|
+
@@index([sessionId], map: "idx_chat_history_session")
|
|
65
|
+
@@index([deletedAt], map: "idx_chat_history_deleted")
|
|
66
|
+
@@map("ai_chat_histories")
|
|
67
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Prisma schema for the dsh-storage database backend — SQL Server variant (Prisma 7).
|
|
2
|
+
//
|
|
3
|
+
// Same models as schema.mysql.prisma, with SQL Server native types. Prisma's
|
|
4
|
+
// sqlserver connector has NO Json type, so every JSON column is a plain text
|
|
5
|
+
// column here — the backend serializes them on write automatically (derived
|
|
6
|
+
// from `provider: sqlserver`; SQL Server's own ISJSON/JSON_VALUE still query
|
|
7
|
+
// the text as JSON).
|
|
8
|
+
//
|
|
9
|
+
// Connection URL shape (parsed by the backend into a node-mssql config):
|
|
10
|
+
// sqlserver://host:1433;database=dbname;user=sa;password=p;encrypt=true;trustServerCertificate=true
|
|
11
|
+
// Client pre-generation and table creation work as described in
|
|
12
|
+
// schema.mysql.prisma's header.
|
|
13
|
+
|
|
14
|
+
generator client {
|
|
15
|
+
provider = "prisma-client"
|
|
16
|
+
output = "../src/generated/sqlserver"
|
|
17
|
+
importFileExtension = "js"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
datasource db {
|
|
21
|
+
provider = "sqlserver"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/// One row per projected session event (user message, assistant message,
|
|
25
|
+
/// tool call/result, compression snapshot, ...).
|
|
26
|
+
model AiMessage {
|
|
27
|
+
id String @id @default(cuid()) @db.Char(36)
|
|
28
|
+
sessionId String @map("session_id") @db.VarChar(100)
|
|
29
|
+
historyId String? @map("history_id") @db.Char(36)
|
|
30
|
+
type String @db.VarChar(50)
|
|
31
|
+
content String @db.NVarChar(Max)
|
|
32
|
+
thoughts String? @db.NVarChar(Max)
|
|
33
|
+
model String? @db.VarChar(100)
|
|
34
|
+
tokens String? @db.NVarChar(Max)
|
|
35
|
+
toolCalls String? @map("tool_calls") @db.NVarChar(Max)
|
|
36
|
+
agentId String? @map("agent_id") @db.VarChar(100)
|
|
37
|
+
metadata String? @db.NVarChar(Max)
|
|
38
|
+
createdAt DateTime @default(now()) @map("created_at") @db.DateTime2
|
|
39
|
+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.DateTime2
|
|
40
|
+
deletedAt DateTime? @map("deleted_at") @db.DateTime2
|
|
41
|
+
|
|
42
|
+
// Relations
|
|
43
|
+
history AiChatHistory? @relation(fields: [historyId], references: [id], onDelete: NoAction)
|
|
44
|
+
|
|
45
|
+
@@index([sessionId], map: "idx_session")
|
|
46
|
+
@@index([historyId], map: "idx_history")
|
|
47
|
+
@@index([createdAt], map: "idx_created")
|
|
48
|
+
@@index([deletedAt], map: "idx_deleted")
|
|
49
|
+
@@index([agentId], map: "idx_agent")
|
|
50
|
+
@@index([sessionId, agentId, type, createdAt], map: "idx_session_agent_type_created")
|
|
51
|
+
@@map("ai_messages")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/// Per-session rollup, maintained incrementally by the projector.
|
|
55
|
+
model AiChatHistory {
|
|
56
|
+
id String @id @default(cuid()) @db.Char(36)
|
|
57
|
+
sessionId String @map("session_id") @db.VarChar(100)
|
|
58
|
+
title String? @db.VarChar(255)
|
|
59
|
+
summary String? @db.NVarChar(Max)
|
|
60
|
+
messageCount Int @default(0) @map("message_count")
|
|
61
|
+
totalTokens BigInt @default(0) @map("total_tokens")
|
|
62
|
+
firstMessageAt DateTime? @map("first_message_at") @db.DateTime2
|
|
63
|
+
lastMessageAt DateTime? @map("last_message_at") @db.DateTime2
|
|
64
|
+
metadata String? @db.NVarChar(Max)
|
|
65
|
+
deletedAt DateTime? @map("deleted_at") @db.DateTime2
|
|
66
|
+
|
|
67
|
+
// Relations
|
|
68
|
+
messages AiMessage[]
|
|
69
|
+
|
|
70
|
+
@@index([sessionId], map: "idx_chat_history_session")
|
|
71
|
+
@@index([deletedAt], map: "idx_chat_history_deleted")
|
|
72
|
+
@@map("ai_chat_histories")
|
|
73
|
+
}
|