@node-llm/orm 0.4.0 → 0.5.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.
@@ -4,7 +4,7 @@
4
4
  * Prisma adapter for NodeLLM ORM.
5
5
  * Provides automatic persistence of chats, messages, tool calls, and API requests.
6
6
  *
7
- * @example
7
+ * @example Chat API (low-level)
8
8
  * ```typescript
9
9
  * import { PrismaClient } from '@prisma/client';
10
10
  * import { createLLM } from '@node-llm/core';
@@ -21,7 +21,30 @@
21
21
  * const response = await chat.ask('Hello!');
22
22
  * console.log(response.content);
23
23
  * ```
24
+ *
25
+ * @example AgentSession API (recommended for agents)
26
+ * ```typescript
27
+ * import { Agent } from '@node-llm/core';
28
+ * import { createAgentSession, loadAgentSession } from '@node-llm/orm/prisma';
29
+ *
30
+ * class SupportAgent extends Agent {
31
+ * static model = 'gpt-4.1';
32
+ * static instructions = 'You are a helpful support agent.';
33
+ * }
34
+ *
35
+ * // Create new session
36
+ * const session = await createAgentSession(prisma, llm, SupportAgent, {
37
+ * metadata: { userId: 'user_123' }
38
+ * });
39
+ * await session.ask('Hello!');
40
+ *
41
+ * // Resume later (Code Wins - model/tools from class, history from DB)
42
+ * const session = await loadAgentSession(prisma, llm, SupportAgent, sessionId);
43
+ * await session.ask('Continue our conversation');
44
+ * ```
24
45
  */
25
46
  export { Chat, createChat, loadChat } from "./Chat.js";
26
- export type { ChatRecord, MessageRecord, ChatOptions, TableNames } from "./Chat.js";
47
+ export type { ChatRecord, MessageRecord, ChatOptions } from "./Chat.js";
48
+ export { AgentSession, createAgentSession, loadAgentSession } from "./AgentSession.js";
49
+ export type { AgentSessionRecord, CreateAgentSessionOptions, LoadAgentSessionOptions, TableNames } from "./AgentSession.js";
27
50
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/prisma/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/prisma/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACvD,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvF,YAAY,EACV,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,EACvB,UAAU,EACX,MAAM,mBAAmB,CAAC"}
@@ -4,7 +4,7 @@
4
4
  * Prisma adapter for NodeLLM ORM.
5
5
  * Provides automatic persistence of chats, messages, tool calls, and API requests.
6
6
  *
7
- * @example
7
+ * @example Chat API (low-level)
8
8
  * ```typescript
9
9
  * import { PrismaClient } from '@prisma/client';
10
10
  * import { createLLM } from '@node-llm/core';
@@ -21,5 +21,29 @@
21
21
  * const response = await chat.ask('Hello!');
22
22
  * console.log(response.content);
23
23
  * ```
24
+ *
25
+ * @example AgentSession API (recommended for agents)
26
+ * ```typescript
27
+ * import { Agent } from '@node-llm/core';
28
+ * import { createAgentSession, loadAgentSession } from '@node-llm/orm/prisma';
29
+ *
30
+ * class SupportAgent extends Agent {
31
+ * static model = 'gpt-4.1';
32
+ * static instructions = 'You are a helpful support agent.';
33
+ * }
34
+ *
35
+ * // Create new session
36
+ * const session = await createAgentSession(prisma, llm, SupportAgent, {
37
+ * metadata: { userId: 'user_123' }
38
+ * });
39
+ * await session.ask('Hello!');
40
+ *
41
+ * // Resume later (Code Wins - model/tools from class, history from DB)
42
+ * const session = await loadAgentSession(prisma, llm, SupportAgent, sessionId);
43
+ * await session.ask('Continue our conversation');
44
+ * ```
24
45
  */
46
+ // Chat API
25
47
  export { Chat, createChat, loadChat } from "./Chat.js";
48
+ // AgentSession API
49
+ export { AgentSession, createAgentSession, loadAgentSession } from "./AgentSession.js";
package/dist/index.d.ts CHANGED
@@ -23,13 +23,33 @@
23
23
  * await chat.ask('Hello!');
24
24
  * ```
25
25
  *
26
+ * ## Agent Sessions (Recommended for Agents)
27
+ *
28
+ * ```typescript
29
+ * import { Agent } from '@node-llm/core';
30
+ * import { createAgentSession, loadAgentSession } from '@node-llm/orm/prisma';
31
+ *
32
+ * class SupportAgent extends Agent {
33
+ * static model = 'gpt-4.1';
34
+ * static instructions = 'You are a helpful support agent.';
35
+ * }
36
+ *
37
+ * // Create and persist
38
+ * const session = await createAgentSession(prisma, llm, SupportAgent);
39
+ * await session.ask('Hello!');
40
+ *
41
+ * // Resume later (Code Wins - model/tools from class, history from DB)
42
+ * const session = await loadAgentSession(prisma, llm, SupportAgent, sessionId);
43
+ * ```
44
+ *
26
45
  * ## Adapters
27
46
  *
28
47
  * - `@node-llm/orm/prisma` - Prisma adapter (recommended)
29
48
  *
30
49
  * ## Schema
31
50
  *
32
- * The ORM tracks four core entities:
51
+ * The ORM tracks five core entities:
52
+ * - **AgentSession** - Links Agent class to persistent Chat (v0.5.0+)
33
53
  * - **Chat** - Session container (model, provider, instructions)
34
54
  * - **Message** - User/Assistant conversation history
35
55
  * - **ToolCall** - Tool executions (name, arguments, results)
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAGH,cAAc,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -23,13 +23,33 @@
23
23
  * await chat.ask('Hello!');
24
24
  * ```
25
25
  *
26
+ * ## Agent Sessions (Recommended for Agents)
27
+ *
28
+ * ```typescript
29
+ * import { Agent } from '@node-llm/core';
30
+ * import { createAgentSession, loadAgentSession } from '@node-llm/orm/prisma';
31
+ *
32
+ * class SupportAgent extends Agent {
33
+ * static model = 'gpt-4.1';
34
+ * static instructions = 'You are a helpful support agent.';
35
+ * }
36
+ *
37
+ * // Create and persist
38
+ * const session = await createAgentSession(prisma, llm, SupportAgent);
39
+ * await session.ask('Hello!');
40
+ *
41
+ * // Resume later (Code Wins - model/tools from class, history from DB)
42
+ * const session = await loadAgentSession(prisma, llm, SupportAgent, sessionId);
43
+ * ```
44
+ *
26
45
  * ## Adapters
27
46
  *
28
47
  * - `@node-llm/orm/prisma` - Prisma adapter (recommended)
29
48
  *
30
49
  * ## Schema
31
50
  *
32
- * The ORM tracks four core entities:
51
+ * The ORM tracks five core entities:
52
+ * - **AgentSession** - Links Agent class to persistent Chat (v0.5.0+)
33
53
  * - **Chat** - Session container (model, provider, instructions)
34
54
  * - **Message** - User/Assistant conversation history
35
55
  * - **ToolCall** - Tool executions (name, arguments, results)
@@ -0,0 +1,53 @@
1
+ # @node-llm/orm Migrations
2
+
3
+ Reference SQL migrations for upgrading your database schema.
4
+
5
+ ## Who Needs These?
6
+
7
+ | User Type | Action |
8
+ | ----------------- | ------------------------------------------------------------------ |
9
+ | **New user** | ❌ Skip these. Run `npx @node-llm/orm init` → full schema included |
10
+ | **Existing user** | ✅ Use these to upgrade without losing data |
11
+
12
+ > **Note:** These migrations are **idempotent** — safe to run multiple times. They use `IF NOT EXISTS` and conditional checks, so running them on a fresh database won't cause errors.
13
+
14
+ ## Available Migrations
15
+
16
+ | File | Version | Description |
17
+ | -------------------------- | ------- | --------------------------------------------------- |
18
+ | `add_thinking_support.sql` | v0.2.0+ | Extended Thinking columns (Claude 3.7, DeepSeek R1) |
19
+ | `add_agent_session.sql` | v0.5.0+ | AgentSession for persistent agent conversations |
20
+
21
+ ## How to Use
22
+
23
+ ### Option 1: Copy and Apply
24
+
25
+ ```bash
26
+ # Create migration folder
27
+ mkdir -p prisma/migrations/$(date +%Y%m%d%H%M%S)_add_agent_session
28
+
29
+ # Copy the SQL
30
+ cp node_modules/@node-llm/orm/migrations/add_agent_session.sql \
31
+ prisma/migrations/$(date +%Y%m%d%H%M%S)_add_agent_session/migration.sql
32
+
33
+ # Mark as applied
34
+ npx prisma migrate resolve --applied $(date +%Y%m%d%H%M%S)_add_agent_session
35
+ ```
36
+
37
+ ### Option 2: Let Prisma Generate
38
+
39
+ 1. Update your `schema.prisma` with the new models from `@node-llm/orm/schema.prisma`
40
+ 2. Run: `npx prisma migrate dev --name add_agent_session`
41
+
42
+ ## Custom Table Names
43
+
44
+ If you're using custom table names (e.g., `AssistantMessage` instead of `LlmMessage`),
45
+ edit the SQL file to match your table names before applying.
46
+
47
+ ## Documentation
48
+
49
+ See the full [Migration Guide](https://node-llm.eshaiju.com/orm/migrations) for:
50
+
51
+ - Baseline migrations
52
+ - Production deployment
53
+ - Renaming columns safely
@@ -0,0 +1,44 @@
1
+ -- Migration: Add AgentSession support
2
+ -- Version: @node-llm/orm v0.5.0+
3
+ --
4
+ -- This migration adds the LlmAgentSession table for persistent agent conversations.
5
+ -- Run this if you're upgrading from a previous version of @node-llm/orm.
6
+ --
7
+ -- Usage:
8
+ -- 1. Copy this file to your prisma/migrations/<timestamp>_add_agent_session/ folder
9
+ -- 2. Run: npx prisma migrate resolve --applied <timestamp>_add_agent_session
10
+ -- Or simply run: npx prisma migrate dev --name add_agent_session
11
+
12
+ -- Create the AgentSession table
13
+ CREATE TABLE IF NOT EXISTS "LlmAgentSession" (
14
+ "id" TEXT NOT NULL,
15
+ "agentClass" TEXT NOT NULL,
16
+ "chatId" TEXT NOT NULL,
17
+ "metadata" JSONB,
18
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
19
+ "updatedAt" TIMESTAMP(3) NOT NULL,
20
+
21
+ CONSTRAINT "LlmAgentSession_pkey" PRIMARY KEY ("id")
22
+ );
23
+
24
+ -- Create unique constraint on chatId (1:1 with LlmChat)
25
+ CREATE UNIQUE INDEX IF NOT EXISTS "LlmAgentSession_chatId_key" ON "LlmAgentSession"("chatId");
26
+
27
+ -- Create indexes for common queries
28
+ CREATE INDEX IF NOT EXISTS "LlmAgentSession_agentClass_idx" ON "LlmAgentSession"("agentClass");
29
+ CREATE INDEX IF NOT EXISTS "LlmAgentSession_createdAt_idx" ON "LlmAgentSession"("createdAt");
30
+
31
+ -- Add foreign key constraint (idempotent - skips if already exists)
32
+ DO $$
33
+ BEGIN
34
+ IF NOT EXISTS (
35
+ SELECT 1 FROM pg_constraint WHERE conname = 'LlmAgentSession_chatId_fkey'
36
+ ) THEN
37
+ ALTER TABLE "LlmAgentSession"
38
+ ADD CONSTRAINT "LlmAgentSession_chatId_fkey"
39
+ FOREIGN KEY ("chatId")
40
+ REFERENCES "LlmChat"("id")
41
+ ON DELETE CASCADE
42
+ ON UPDATE CASCADE;
43
+ END IF;
44
+ END $$;
@@ -0,0 +1,34 @@
1
+ -- Migration: Add Extended Thinking support
2
+ -- Version: @node-llm/orm v0.2.0+
3
+ --
4
+ -- This migration adds columns for Extended Thinking (Claude 3.7+, DeepSeek R1).
5
+ -- Run this if you're upgrading from a previous version of @node-llm/orm.
6
+ --
7
+ -- Usage:
8
+ -- 1. Copy this file to your prisma/migrations/<timestamp>_add_thinking_support/ folder
9
+ -- 2. Run: npx prisma migrate resolve --applied <timestamp>_add_thinking_support
10
+ -- Or simply run: npx prisma migrate dev --name add_thinking_support
11
+ --
12
+ -- Note: Adjust table names if using custom names (e.g., AssistantMessage instead of LlmMessage)
13
+ -- Note: This migration is idempotent - safe to run multiple times.
14
+
15
+ -- AlterTable: Convert metadata to native JSONB (idempotent - skips if already JSONB)
16
+ DO $$
17
+ BEGIN
18
+ IF EXISTS (
19
+ SELECT 1 FROM information_schema.columns
20
+ WHERE table_name = 'LlmChat' AND column_name = 'metadata' AND data_type != 'jsonb'
21
+ ) THEN
22
+ ALTER TABLE "LlmChat" ALTER COLUMN "metadata" TYPE JSONB USING metadata::JSONB;
23
+ END IF;
24
+ END $$;
25
+
26
+ -- AlterTable: Add thinking columns to Message
27
+ ALTER TABLE "LlmMessage"
28
+ ADD COLUMN IF NOT EXISTS "thinkingText" TEXT,
29
+ ADD COLUMN IF NOT EXISTS "thinkingSignature" TEXT,
30
+ ADD COLUMN IF NOT EXISTS "thinkingTokens" INTEGER;
31
+
32
+ -- AlterTable: Add thought signature to ToolCall
33
+ ALTER TABLE "LlmToolCall"
34
+ ADD COLUMN IF NOT EXISTS "thoughtSignature" TEXT;
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "@node-llm/orm",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Database persistence layer for NodeLLM - Chat, Message, and ToolCall tracking with streaming support",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
5
8
  "type": "module",
6
9
  "main": "./dist/index.js",
7
10
  "types": "./dist/index.d.ts",
@@ -68,6 +71,7 @@
68
71
  "scripts": {
69
72
  "build": "prisma generate --schema=schema.prisma && tsc",
70
73
  "test": "vitest run",
74
+ "test:docs": "vitest run test/docs",
71
75
  "test:watch": "vitest"
72
76
  }
73
77
  }
package/schema.prisma CHANGED
@@ -12,53 +12,70 @@ datasource db {
12
12
 
13
13
  // NodeLLM ORM Models (matches @node-llm/orm schema)
14
14
  model LlmChat {
15
- id String @id @default(uuid())
15
+ id String @id @default(uuid())
16
16
  model String?
17
17
  provider String?
18
- instructions String? // System instructions
19
- metadata Json? // JSON metadata
20
- createdAt DateTime @default(now())
21
- updatedAt DateTime @updatedAt
18
+ instructions String? // System instructions
19
+ metadata Json? // JSON metadata
20
+ createdAt DateTime @default(now())
21
+ updatedAt DateTime @updatedAt
22
22
  messages LlmMessage[]
23
23
  requests LlmRequest[]
24
+ agentSession LlmAgentSession?
25
+ }
26
+
27
+ // Agent Session - Links Agent class to persistent Chat
28
+ // "Code defines behavior, DB provides history"
29
+ model LlmAgentSession {
30
+ id String @id @default(uuid())
31
+ agentClass String // Class name for validation (e.g., 'SupportAgent')
32
+ chatId String @unique
33
+ metadata Json? // Session context (userId, ticketId, etc.)
34
+ createdAt DateTime @default(now())
35
+ updatedAt DateTime @updatedAt
36
+
37
+ chat LlmChat @relation(fields: [chatId], references: [id], onDelete: Cascade)
38
+
39
+ @@index([agentClass])
40
+ @@index([createdAt])
24
41
  }
25
42
 
26
43
  model LlmMessage {
27
- id String @id @default(uuid())
44
+ id String @id @default(uuid())
28
45
  chatId String
29
- role String // user, assistant, system, tool
46
+ role String // user, assistant, system, tool
30
47
  content String?
31
- contentRaw String? // JSON raw payload
32
- reasoning String? // Chain of thought (deprecated)
33
- thinkingText String? // Extended thinking text
34
- thinkingSignature String? // Cryptographic signature
35
- thinkingTokens Int? // Tokens spent on thinking
48
+ contentRaw String? // JSON raw payload
49
+ reasoning String? // Chain of thought (deprecated)
50
+ thinkingText String? // Extended thinking text
51
+ thinkingSignature String? // Cryptographic signature
52
+ thinkingTokens Int? // Tokens spent on thinking
36
53
  inputTokens Int?
37
54
  outputTokens Int?
38
55
  modelId String?
39
56
  provider String?
40
- createdAt DateTime @default(now())
57
+ createdAt DateTime @default(now())
41
58
 
42
- chat LlmChat @relation(fields: [chatId], references: [id], onDelete: Cascade)
43
- toolCalls LlmToolCall[]
44
- requests LlmRequest[]
59
+ chat LlmChat @relation(fields: [chatId], references: [id], onDelete: Cascade)
60
+ toolCalls LlmToolCall[]
61
+ requests LlmRequest[]
45
62
 
46
63
  @@index([chatId])
47
64
  @@index([createdAt])
48
65
  }
49
66
 
50
67
  model LlmToolCall {
51
- id String @id @default(uuid())
68
+ id String @id @default(uuid())
52
69
  messageId String
53
- toolCallId String // ID from the provider
70
+ toolCallId String // ID from the provider
54
71
  name String
55
- arguments String // JSON string
56
- thought String? // The LLM's reasoning for this tool call
57
- thoughtSignature String? // Signature for the thought
58
- result String? // Tool execution result
59
- createdAt DateTime @default(now())
72
+ arguments String // JSON string
73
+ thought String? // The LLM's reasoning for this tool call
74
+ thoughtSignature String? // Signature for the thought
75
+ result String? // Tool execution result
76
+ createdAt DateTime @default(now())
60
77
 
61
- message LlmMessage @relation(fields: [messageId], references: [id], onDelete: Cascade)
78
+ message LlmMessage @relation(fields: [messageId], references: [id], onDelete: Cascade)
62
79
 
63
80
  @@unique([messageId, toolCallId])
64
81
  @@index([messageId])
@@ -66,22 +83,22 @@ model LlmToolCall {
66
83
  }
67
84
 
68
85
  model LlmRequest {
69
- id String @id @default(uuid())
70
- chatId String
71
- messageId String? // Optional because requests might fail before message creation
72
-
86
+ id String @id @default(uuid())
87
+ chatId String
88
+ messageId String? // Optional because requests might fail before message creation
89
+
73
90
  provider String
74
91
  model String
75
92
  statusCode Int
76
- duration Int // milliseconds
93
+ duration Int // milliseconds
77
94
  inputTokens Int
78
95
  outputTokens Int
79
96
  cost Float?
80
-
81
- createdAt DateTime @default(now())
82
97
 
83
- chat LlmChat @relation(fields: [chatId], references: [id], onDelete: Cascade)
84
- message LlmMessage? @relation(fields: [messageId], references: [id], onDelete: Cascade)
98
+ createdAt DateTime @default(now())
99
+
100
+ chat LlmChat @relation(fields: [chatId], references: [id], onDelete: Cascade)
101
+ message LlmMessage? @relation(fields: [messageId], references: [id], onDelete: Cascade)
85
102
 
86
103
  @@index([chatId])
87
104
  @@index([createdAt])