@pikku/mongodb 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/src/index.d.ts +12 -0
  3. package/dist/src/index.js +9 -0
  4. package/dist/src/mongodb-agent-run-service.d.ts +21 -0
  5. package/dist/src/mongodb-agent-run-service.js +127 -0
  6. package/dist/src/mongodb-ai-storage-service.d.ts +41 -0
  7. package/dist/src/mongodb-ai-storage-service.js +408 -0
  8. package/dist/src/mongodb-channel-store.d.ts +19 -0
  9. package/dist/src/mongodb-channel-store.js +52 -0
  10. package/dist/src/mongodb-deployment-service.d.ts +17 -0
  11. package/dist/src/mongodb-deployment-service.js +75 -0
  12. package/dist/src/mongodb-eventhub-store.d.ts +13 -0
  13. package/dist/src/mongodb-eventhub-store.js +37 -0
  14. package/dist/src/mongodb-secret-service.d.ts +30 -0
  15. package/dist/src/mongodb-secret-service.js +110 -0
  16. package/dist/src/mongodb-workflow-run-service.d.ts +36 -0
  17. package/dist/src/mongodb-workflow-run-service.js +146 -0
  18. package/dist/src/mongodb-workflow-service.d.ts +55 -0
  19. package/dist/src/mongodb-workflow-service.js +351 -0
  20. package/dist/src/pikku-mongodb.d.ts +12 -0
  21. package/dist/src/pikku-mongodb.js +37 -0
  22. package/dist/tsconfig.tsbuildinfo +1 -0
  23. package/package.json +29 -0
  24. package/run-tests.sh +53 -0
  25. package/src/index.ts +14 -0
  26. package/src/mongodb-agent-run-service.ts +206 -0
  27. package/src/mongodb-ai-storage-service.ts +576 -0
  28. package/src/mongodb-channel-store.ts +96 -0
  29. package/src/mongodb-deployment-service.ts +114 -0
  30. package/src/mongodb-eventhub-store.ts +52 -0
  31. package/src/mongodb-secret-service.ts +178 -0
  32. package/src/mongodb-services.test.ts +149 -0
  33. package/src/mongodb-workflow-run-service.ts +246 -0
  34. package/src/mongodb-workflow-service.ts +583 -0
  35. package/src/pikku-mongodb.ts +41 -0
  36. package/tsconfig.json +17 -0
@@ -0,0 +1,206 @@
1
+ import type {
2
+ AIThread,
3
+ AIMessage,
4
+ AgentRunRow,
5
+ AgentRunService,
6
+ } from '@pikku/core/ai-agent'
7
+ import type { Db, Collection } from 'mongodb'
8
+
9
+ interface AIThreadDoc {
10
+ _id: string
11
+ resourceId: string
12
+ title: string | null
13
+ metadata: any | null
14
+ createdAt: Date
15
+ updatedAt: Date
16
+ }
17
+
18
+ interface AIMessageDoc {
19
+ _id: string
20
+ threadId: string
21
+ role: string
22
+ content: string | null
23
+ createdAt: Date
24
+ }
25
+
26
+ interface AIToolCallDoc {
27
+ _id: string
28
+ threadId: string
29
+ messageId: string
30
+ runId: string | null
31
+ toolName: string
32
+ args: any
33
+ result: string | null
34
+ approvalStatus: string | null
35
+ approvalType: string | null
36
+ agentRunId: string | null
37
+ displayToolName: string | null
38
+ displayArgs: any | null
39
+ createdAt: Date
40
+ }
41
+
42
+ interface AIRunDoc {
43
+ _id: string
44
+ agentName: string
45
+ threadId: string
46
+ resourceId: string
47
+ status: string
48
+ errorMessage: string | null
49
+ suspendReason: string | null
50
+ missingRpcs: any | null
51
+ usageInputTokens: number
52
+ usageOutputTokens: number
53
+ usageModel: string
54
+ createdAt: Date
55
+ updatedAt: Date
56
+ }
57
+
58
+ export class MongoDBAgentRunService implements AgentRunService {
59
+ private threads: Collection<AIThreadDoc>
60
+ private messages: Collection<AIMessageDoc>
61
+ private toolCalls: Collection<AIToolCallDoc>
62
+ private runs: Collection<AIRunDoc>
63
+
64
+ constructor(db: Db) {
65
+ this.threads = db.collection<AIThreadDoc>('ai_threads')
66
+ this.messages = db.collection<AIMessageDoc>('ai_message')
67
+ this.toolCalls = db.collection<AIToolCallDoc>('ai_tool_call')
68
+ this.runs = db.collection<AIRunDoc>('ai_run')
69
+ }
70
+
71
+ async listThreads(options?: {
72
+ agentName?: string
73
+ limit?: number
74
+ offset?: number
75
+ }): Promise<AIThread[]> {
76
+ const { agentName, limit = 50, offset = 0 } = options ?? {}
77
+
78
+ let filter: Record<string, any> = {}
79
+
80
+ if (agentName) {
81
+ const threadIds = await this.runs.distinct('threadId', {
82
+ agentName,
83
+ })
84
+ filter._id = { $in: threadIds }
85
+ }
86
+
87
+ const result = await this.threads
88
+ .find(filter)
89
+ .sort({ updatedAt: -1 })
90
+ .skip(offset)
91
+ .limit(limit)
92
+ .toArray()
93
+
94
+ return result.map((row) => this.mapThreadRow(row))
95
+ }
96
+
97
+ async getThread(threadId: string): Promise<AIThread | null> {
98
+ const row = await this.threads.findOne({ _id: threadId })
99
+ if (!row) return null
100
+ return this.mapThreadRow(row)
101
+ }
102
+
103
+ async getThreadMessages(threadId: string): Promise<AIMessage[]> {
104
+ const [msgResult, tcResult] = await Promise.all([
105
+ this.messages.find({ threadId }).sort({ createdAt: 1 }).toArray(),
106
+ this.toolCalls.find({ threadId }).sort({ createdAt: 1 }).toArray(),
107
+ ])
108
+
109
+ const tcByMessage = new Map<string, (typeof tcResult)[number][]>()
110
+ for (const tc of tcResult) {
111
+ const msgId = tc.messageId
112
+ if (!tcByMessage.has(msgId)) tcByMessage.set(msgId, [])
113
+ tcByMessage.get(msgId)!.push(tc)
114
+ }
115
+
116
+ const messages: AIMessage[] = []
117
+ for (const row of msgResult) {
118
+ const msg: AIMessage = {
119
+ id: row._id,
120
+ role: row.role as AIMessage['role'],
121
+ content: row.content ?? undefined,
122
+ createdAt: new Date(row.createdAt),
123
+ }
124
+
125
+ const tcs = tcByMessage.get(msg.id)
126
+ if (tcs?.length) {
127
+ msg.toolCalls = tcs.map((tc) => ({
128
+ id: tc._id,
129
+ name: tc.toolName,
130
+ args: tc.args as Record<string, unknown>,
131
+ }))
132
+
133
+ const completed = tcs.filter((tc) => tc.result != null)
134
+ if (completed.length) {
135
+ messages.push(msg)
136
+ messages.push({
137
+ id: `tool-results-${msg.id}`,
138
+ role: 'tool',
139
+ toolResults: completed.map((tc) => ({
140
+ id: tc._id,
141
+ name: tc.toolName,
142
+ result: tc.result!,
143
+ })),
144
+ createdAt: msg.createdAt,
145
+ })
146
+ continue
147
+ }
148
+ }
149
+
150
+ messages.push(msg)
151
+ }
152
+
153
+ return messages
154
+ }
155
+
156
+ async getThreadRuns(threadId: string): Promise<AgentRunRow[]> {
157
+ const result = await this.runs
158
+ .find({ threadId })
159
+ .sort({ createdAt: -1 })
160
+ .toArray()
161
+
162
+ return result.map((row) => this.mapRunRow(row))
163
+ }
164
+
165
+ async deleteThread(threadId: string): Promise<boolean> {
166
+ await this.toolCalls.deleteMany({ threadId })
167
+ await this.messages.deleteMany({ threadId })
168
+ await this.runs.deleteMany({ threadId })
169
+ const result = await this.threads.deleteOne({ _id: threadId })
170
+ return result.deletedCount > 0
171
+ }
172
+
173
+ async getDistinctAgentNames(): Promise<string[]> {
174
+ const result = await this.runs.distinct('agentName')
175
+ return result.sort()
176
+ }
177
+
178
+ private mapThreadRow(row: AIThreadDoc): AIThread {
179
+ return {
180
+ id: row._id,
181
+ resourceId: row.resourceId,
182
+ title: row.title ?? undefined,
183
+ metadata: row.metadata ?? undefined,
184
+ createdAt: new Date(row.createdAt),
185
+ updatedAt: new Date(row.updatedAt),
186
+ }
187
+ }
188
+
189
+ private mapRunRow(row: AIRunDoc): AgentRunRow {
190
+ return {
191
+ runId: row._id,
192
+ agentName: row.agentName,
193
+ threadId: row.threadId,
194
+ resourceId: row.resourceId,
195
+ status: row.status,
196
+ errorMessage: row.errorMessage ?? undefined,
197
+ suspendReason: row.suspendReason ?? undefined,
198
+ missingRpcs: row.missingRpcs ?? undefined,
199
+ usageInputTokens: Number(row.usageInputTokens),
200
+ usageOutputTokens: Number(row.usageOutputTokens),
201
+ usageModel: row.usageModel,
202
+ createdAt: new Date(row.createdAt),
203
+ updatedAt: new Date(row.updatedAt),
204
+ }
205
+ }
206
+ }