@pikku/mongodb 0.12.15 → 0.12.18

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.
@@ -6,6 +6,7 @@ export class MongoDBAIStorageService {
6
6
  toolCalls;
7
7
  workingMemory;
8
8
  aiRuns;
9
+ aiRunScores;
9
10
  constructor(db) {
10
11
  this.db = db;
11
12
  }
@@ -18,12 +19,14 @@ export class MongoDBAIStorageService {
18
19
  this.workingMemory =
19
20
  this.db.collection('ai_working_memory');
20
21
  this.aiRuns = this.db.collection('ai_run');
22
+ this.aiRunScores = this.db.collection('ai_run_score');
21
23
  await this.threads.createIndex({ resourceId: 1 });
22
24
  await this.aiMessages.createIndex({ threadId: 1, createdAt: 1 });
23
25
  await this.toolCalls.createIndex({ threadId: 1 });
24
26
  await this.toolCalls.createIndex({ messageId: 1 });
25
27
  await this.workingMemory.createIndex({ id: 1, scope: 1 }, { unique: true });
26
28
  await this.aiRuns.createIndex({ threadId: 1, createdAt: 1 });
29
+ await this.aiRunScores.createIndex({ runId: 1, createdAt: 1 });
27
30
  this.initialized = true;
28
31
  }
29
32
  async createThread(resourceId, options) {
@@ -406,5 +409,30 @@ export class MongoDBAIStorageService {
406
409
  const result = await this.toolCalls.updateOne({ _id: toolCallId, approvalStatus: 'pending' }, { $set: { approvalStatus: status } });
407
410
  return result.modifiedCount > 0;
408
411
  }
412
+ async saveScore(score) {
413
+ await this.aiRunScores.insertOne({
414
+ _id: crypto.randomUUID(),
415
+ runId: score.runId,
416
+ scorerName: score.scorerName,
417
+ score: score.score,
418
+ reason: score.reason ?? null,
419
+ metadata: score.metadata ?? null,
420
+ createdAt: new Date(),
421
+ });
422
+ }
423
+ async getScores(runId) {
424
+ const rows = await this.aiRunScores
425
+ .find({ runId })
426
+ .sort({ createdAt: 1 })
427
+ .toArray();
428
+ return rows.map((row) => ({
429
+ runId: row.runId,
430
+ scorerName: row.scorerName,
431
+ score: row.score,
432
+ reason: row.reason ?? undefined,
433
+ metadata: row.metadata ?? undefined,
434
+ createdAt: row.createdAt,
435
+ }));
436
+ }
409
437
  async close() { }
410
438
  }
@@ -1,4 +1,4 @@
1
- import type { DeploymentService, DeploymentServiceConfig, DeploymentConfig } from '@pikku/core/services';
1
+ import type { DeploymentService, DeploymentServiceConfig, DeploymentConfig } from '@pikku/core/ecosystem/services';
2
2
  import type { JWTService, SecretService } from '@pikku/core/services';
3
3
  import type { Db } from 'mongodb';
4
4
  export declare class MongoDBDeploymentService implements DeploymentService {
@@ -1,5 +1,5 @@
1
- import { buildRemoteHeaders } from '@pikku/core/remote';
2
- import { getAllFunctionNames } from '@pikku/core/function';
1
+ import { buildRemoteHeaders } from '@pikku/core/ecosystem/remote';
2
+ import { getAllFunctionNames } from '@pikku/core/ecosystem/function';
3
3
  export class MongoDBDeploymentService {
4
4
  db;
5
5
  jwt;
@@ -1,4 +1,4 @@
1
- import { EventHubStore } from '@pikku/core/channel';
1
+ import { EventHubStore } from '@pikku/core/ecosystem/channel';
2
2
  import type { Db } from 'mongodb';
3
3
  export declare class MongoDBEventHubStore extends EventHubStore {
4
4
  private db;
@@ -1,4 +1,4 @@
1
- import { EventHubStore } from '@pikku/core/channel';
1
+ import { EventHubStore } from '@pikku/core/ecosystem/channel';
2
2
  export class MongoDBEventHubStore extends EventHubStore {
3
3
  db;
4
4
  initialized = false;
@@ -1,4 +1,4 @@
1
- import type { WorkflowRun, StepState, WorkflowRunService } from '@pikku/core/workflow';
1
+ import type { WorkflowRun, StepState, WorkflowRunService } from '@pikku/core/ecosystem/workflow';
2
2
  import type { Db } from 'mongodb';
3
3
  export declare class MongoDBWorkflowRunService implements WorkflowRunService {
4
4
  private runs;
@@ -1,5 +1,6 @@
1
- import type { SerializedError } from '@pikku/core';
2
- import { PikkuWorkflowService, type WorkflowPlannedStep, type WorkflowQueueOptions, type WorkflowRun, type WorkflowRunWire, type StepState, type StepStatus, type WorkflowStatus, type WorkflowVersionStatus } from '@pikku/core/workflow';
1
+ import type { SerializedError } from '@pikku/core/ecosystem/types';
2
+ import { PikkuWorkflowService } from '@pikku/core/workflow';
3
+ import type { WorkflowPlannedStep, WorkflowQueueOptions, WorkflowRun, WorkflowRunWire, StepState, StepStatus, WorkflowStatus, WorkflowVersionStatus } from '@pikku/core/ecosystem/workflow';
3
4
  import type { Db } from 'mongodb';
4
5
  export declare class MongoDBWorkflowService extends PikkuWorkflowService {
5
6
  private initialized;
@@ -1,4 +1,4 @@
1
- import { PikkuWorkflowService, } from '@pikku/core/workflow';
1
+ import { PikkuWorkflowService } from '@pikku/core/workflow';
2
2
  import { MongoDBWorkflowRunService } from './mongodb-workflow-run-service.js';
3
3
  export class MongoDBWorkflowService extends PikkuWorkflowService {
4
4
  initialized = false;
@@ -1 +1 @@
1
- {"root":["../src/index.ts","../src/mongodb-agent-run-service.ts","../src/mongodb-ai-storage-service.ts","../src/mongodb-channel-store.ts","../src/mongodb-deployment-service.ts","../src/mongodb-eventhub-store.ts","../src/mongodb-secret-service.ts","../src/mongodb-session-store.ts","../src/mongodb-workflow-run-service.ts","../src/mongodb-workflow-service.ts","../src/pikku-mongodb.ts"],"version":"6.0.3"}
1
+ {"root":["../src/index.ts","../src/mongodb-agent-run-service.ts","../src/mongodb-agent-storage-service.ts","../src/mongodb-channel-store.ts","../src/mongodb-deployment-service.ts","../src/mongodb-eventhub-store.ts","../src/mongodb-secret-service.ts","../src/mongodb-session-store.ts","../src/mongodb-workflow-run-service.ts","../src/mongodb-workflow-service.ts","../src/pikku-mongodb.ts"],"version":"6.0.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/mongodb",
3
- "version": "0.12.15",
3
+ "version": "0.12.18",
4
4
  "description": "MongoDB services for Pikku — workflow state, agent runs, secrets and channel stores",
5
5
  "author": "yasser.fadl@gmail.com",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@
18
18
  "prepublishOnly": "yarn build"
19
19
  },
20
20
  "peerDependencies": {
21
- "@pikku/core": "^0.12.80"
21
+ "@pikku/core": "^0.12.84"
22
22
  },
23
23
  "dependencies": {
24
24
  "mongodb": "^6.12.0"
package/src/index.ts CHANGED
@@ -5,11 +5,13 @@ export { MongoDBEventHubStore } from './mongodb-eventhub-store.js'
5
5
  export { MongoDBWorkflowService } from './mongodb-workflow-service.js'
6
6
  export { MongoDBWorkflowRunService } from './mongodb-workflow-run-service.js'
7
7
  export { MongoDBDeploymentService } from './mongodb-deployment-service.js'
8
- export { MongoDBAIStorageService } from './mongodb-ai-storage-service.js'
8
+ export { MongoDBAgentStorageService } from './mongodb-agent-storage-service.js'
9
9
  export { MongoDBAgentRunService } from './mongodb-agent-run-service.js'
10
10
  export { MongoDBSecretService } from './mongodb-secret-service.js'
11
- export type { MongoDBSecretServiceConfig } from './mongodb-secret-service.js'
12
11
 
13
- export type { WorkflowRunService } from '@pikku/core/workflow'
14
- export type { AgentRunService, AgentRunRow } from '@pikku/core/ai-agent'
12
+ export type { WorkflowRunService } from '@pikku/core/ecosystem/workflow'
13
+ export type {
14
+ AgentRunService,
15
+ AgentRunRow,
16
+ } from '@pikku/core/ecosystem/agent'
15
17
  export { MongoDBSessionStore } from './mongodb-session-store.js'
@@ -1,9 +1,8 @@
1
+ import type { AgentThread, AgentMessage } from '@pikku/core/agent'
1
2
  import type {
2
- AIThread,
3
- AIMessage,
4
3
  AgentRunRow,
5
4
  AgentRunService,
6
- } from '@pikku/core/ai-agent'
5
+ } from '@pikku/core/ecosystem/agent'
7
6
  import type { Db, Collection } from 'mongodb'
8
7
 
9
8
  // Owner ids are untrusted input to the regex, so metacharacters must not be
@@ -11,7 +10,7 @@ import type { Db, Collection } from 'mongodb'
11
10
  const escapeRegExp = (value: string) =>
12
11
  value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
13
12
 
14
- interface AIThreadDoc {
13
+ interface AgentThreadDoc {
15
14
  _id: string
16
15
  resourceId: string
17
16
  title: string | null
@@ -20,7 +19,7 @@ interface AIThreadDoc {
20
19
  updatedAt: Date
21
20
  }
22
21
 
23
- interface AIMessageDoc {
22
+ interface AgentMessageDoc {
24
23
  _id: string
25
24
  threadId: string
26
25
  role: string
@@ -28,7 +27,7 @@ interface AIMessageDoc {
28
27
  createdAt: Date
29
28
  }
30
29
 
31
- interface AIToolCallDoc {
30
+ interface AgentToolCallDoc {
32
31
  _id: string
33
32
  threadId: string
34
33
  messageId: string
@@ -44,7 +43,7 @@ interface AIToolCallDoc {
44
43
  createdAt: Date
45
44
  }
46
45
 
47
- interface AIRunDoc {
46
+ interface AgentRunDoc {
48
47
  _id: string
49
48
  agentName: string
50
49
  threadId: string
@@ -61,16 +60,16 @@ interface AIRunDoc {
61
60
  }
62
61
 
63
62
  export class MongoDBAgentRunService implements AgentRunService {
64
- private threads: Collection<AIThreadDoc>
65
- private messages: Collection<AIMessageDoc>
66
- private toolCalls: Collection<AIToolCallDoc>
67
- private runs: Collection<AIRunDoc>
63
+ private threads: Collection<AgentThreadDoc>
64
+ private messages: Collection<AgentMessageDoc>
65
+ private toolCalls: Collection<AgentToolCallDoc>
66
+ private runs: Collection<AgentRunDoc>
68
67
 
69
68
  constructor(db: Db) {
70
- this.threads = db.collection<AIThreadDoc>('ai_threads')
71
- this.messages = db.collection<AIMessageDoc>('ai_message')
72
- this.toolCalls = db.collection<AIToolCallDoc>('ai_tool_call')
73
- this.runs = db.collection<AIRunDoc>('ai_run')
69
+ this.threads = db.collection<AgentThreadDoc>('agent_threads')
70
+ this.messages = db.collection<AgentMessageDoc>('agent_message')
71
+ this.toolCalls = db.collection<AgentToolCallDoc>('agent_tool_call')
72
+ this.runs = db.collection<AgentRunDoc>('agent_run')
74
73
  }
75
74
 
76
75
  async listThreads(options?: {
@@ -79,7 +78,7 @@ export class MongoDBAgentRunService implements AgentRunService {
79
78
  owners?: string[]
80
79
  limit?: number
81
80
  offset?: number
82
- }): Promise<AIThread[]> {
81
+ }): Promise<AgentThread[]> {
83
82
  const {
84
83
  agentName,
85
84
  resourceId,
@@ -122,13 +121,13 @@ export class MongoDBAgentRunService implements AgentRunService {
122
121
  return result.map((row) => this.mapThreadRow(row))
123
122
  }
124
123
 
125
- async getThread(threadId: string): Promise<AIThread | null> {
124
+ async getThread(threadId: string): Promise<AgentThread | null> {
126
125
  const row = await this.threads.findOne({ _id: threadId })
127
126
  if (!row) return null
128
127
  return this.mapThreadRow(row)
129
128
  }
130
129
 
131
- async getThreadMessages(threadId: string): Promise<AIMessage[]> {
130
+ async getThreadMessages(threadId: string): Promise<AgentMessage[]> {
132
131
  const [msgResult, tcResult] = await Promise.all([
133
132
  this.messages.find({ threadId }).sort({ createdAt: 1 }).toArray(),
134
133
  this.toolCalls.find({ threadId }).sort({ createdAt: 1 }).toArray(),
@@ -141,11 +140,11 @@ export class MongoDBAgentRunService implements AgentRunService {
141
140
  tcByMessage.get(msgId)!.push(tc)
142
141
  }
143
142
 
144
- const messages: AIMessage[] = []
143
+ const messages: AgentMessage[] = []
145
144
  for (const row of msgResult) {
146
- const msg: AIMessage = {
145
+ const msg: AgentMessage = {
147
146
  id: row._id,
148
- role: row.role as AIMessage['role'],
147
+ role: row.role as AgentMessage['role'],
149
148
  content: row.content ?? undefined,
150
149
  createdAt: new Date(row.createdAt),
151
150
  }
@@ -203,7 +202,7 @@ export class MongoDBAgentRunService implements AgentRunService {
203
202
  return result.sort()
204
203
  }
205
204
 
206
- private mapThreadRow(row: AIThreadDoc): AIThread {
205
+ private mapThreadRow(row: AgentThreadDoc): AgentThread {
207
206
  return {
208
207
  id: row._id,
209
208
  resourceId: row.resourceId,
@@ -214,7 +213,7 @@ export class MongoDBAgentRunService implements AgentRunService {
214
213
  }
215
214
  }
216
215
 
217
- private mapRunRow(row: AIRunDoc): AgentRunRow {
216
+ private mapRunRow(row: AgentRunDoc): AgentRunRow {
218
217
  return {
219
218
  runId: row._id,
220
219
  agentName: row.agentName,
@@ -1,12 +1,18 @@
1
1
  import type {
2
- AIStorageService,
3
- AIRunStateService,
2
+ AgentStorageService,
3
+ AgentRunStateService,
4
4
  CreateRunInput,
5
+ SaveScoreInput,
5
6
  } from '@pikku/core/services'
6
- import type { AIThread, AIMessage, AgentRunState } from '@pikku/core/ai-agent'
7
+ import type {
8
+ AgentThread,
9
+ AgentMessage,
10
+ AgentRunState,
11
+ } from '@pikku/core/agent'
12
+ import type { AgentRunScore } from '@pikku/core/agent-scorer'
7
13
  import type { Db, Collection } from 'mongodb'
8
14
 
9
- interface AIThreadDoc {
15
+ interface AgentThreadDoc {
10
16
  _id: string
11
17
  resourceId: string
12
18
  title: string | null
@@ -15,7 +21,7 @@ interface AIThreadDoc {
15
21
  updatedAt: Date
16
22
  }
17
23
 
18
- interface AIMessageDoc {
24
+ interface AgentMessageDoc {
19
25
  _id: string
20
26
  threadId: string
21
27
  role: string
@@ -23,7 +29,7 @@ interface AIMessageDoc {
23
29
  createdAt: Date
24
30
  }
25
31
 
26
- interface AIToolCallDoc {
32
+ interface AgentToolCallDoc {
27
33
  _id: string
28
34
  threadId: string
29
35
  messageId: string
@@ -39,14 +45,24 @@ interface AIToolCallDoc {
39
45
  createdAt: Date
40
46
  }
41
47
 
42
- interface AIWorkingMemoryDoc {
48
+ interface AgentWorkingMemoryDoc {
43
49
  id: string
44
50
  scope: string
45
51
  data: any
46
52
  updatedAt: Date
47
53
  }
48
54
 
49
- interface AIRunDoc {
55
+ interface AgentRunScoreDoc {
56
+ _id: string
57
+ runId: string
58
+ scorerName: string
59
+ score: number
60
+ reason: string | null
61
+ metadata: any | null
62
+ createdAt: Date
63
+ }
64
+
65
+ interface AgentRunDoc {
50
66
  _id: string
51
67
  agentName: string
52
68
  threadId: string
@@ -62,38 +78,44 @@ interface AIRunDoc {
62
78
  updatedAt: Date
63
79
  }
64
80
 
65
- export class MongoDBAIStorageService
66
- implements AIStorageService, AIRunStateService
81
+ export class MongoDBAgentStorageService
82
+ implements AgentStorageService, AgentRunStateService
67
83
  {
68
84
  private initialized = false
69
- private threads!: Collection<AIThreadDoc>
70
- private aiMessages!: Collection<AIMessageDoc>
71
- private toolCalls!: Collection<AIToolCallDoc>
72
- private workingMemory!: Collection<AIWorkingMemoryDoc>
73
- private aiRuns!: Collection<AIRunDoc>
85
+ private threads!: Collection<AgentThreadDoc>
86
+ private agentMessages!: Collection<AgentMessageDoc>
87
+ private toolCalls!: Collection<AgentToolCallDoc>
88
+ private workingMemory!: Collection<AgentWorkingMemoryDoc>
89
+ private agentRuns!: Collection<AgentRunDoc>
90
+ private agentRunScores!: Collection<AgentRunScoreDoc>
74
91
 
75
92
  constructor(private db: Db) {}
76
93
 
77
94
  public async init(): Promise<void> {
78
95
  if (this.initialized) return
79
96
 
80
- this.threads = this.db.collection<AIThreadDoc>('ai_threads')
81
- this.aiMessages = this.db.collection<AIMessageDoc>('ai_message')
82
- this.toolCalls = this.db.collection<AIToolCallDoc>('ai_tool_call')
83
- this.workingMemory =
84
- this.db.collection<AIWorkingMemoryDoc>('ai_working_memory')
85
- this.aiRuns = this.db.collection<AIRunDoc>('ai_run')
97
+ this.threads = this.db.collection<AgentThreadDoc>('agent_threads')
98
+ this.agentMessages = this.db.collection<AgentMessageDoc>('agent_message')
99
+ this.toolCalls = this.db.collection<AgentToolCallDoc>('agent_tool_call')
100
+ this.workingMemory = this.db.collection<AgentWorkingMemoryDoc>(
101
+ 'agent_working_memory'
102
+ )
103
+ this.agentRuns = this.db.collection<AgentRunDoc>('agent_run')
104
+ this.agentRunScores =
105
+ this.db.collection<AgentRunScoreDoc>('agent_run_score')
86
106
 
87
107
  await this.threads.createIndex({ resourceId: 1 })
88
108
 
89
- await this.aiMessages.createIndex({ threadId: 1, createdAt: 1 })
109
+ await this.agentMessages.createIndex({ threadId: 1, createdAt: 1 })
90
110
 
91
111
  await this.toolCalls.createIndex({ threadId: 1 })
92
112
  await this.toolCalls.createIndex({ messageId: 1 })
93
113
 
94
114
  await this.workingMemory.createIndex({ id: 1, scope: 1 }, { unique: true })
95
115
 
96
- await this.aiRuns.createIndex({ threadId: 1, createdAt: 1 })
116
+ await this.agentRuns.createIndex({ threadId: 1, createdAt: 1 })
117
+
118
+ await this.agentRunScores.createIndex({ runId: 1, createdAt: 1 })
97
119
 
98
120
  this.initialized = true
99
121
  }
@@ -105,7 +127,7 @@ export class MongoDBAIStorageService
105
127
  title?: string
106
128
  metadata?: Record<string, unknown>
107
129
  }
108
- ): Promise<AIThread> {
130
+ ): Promise<AgentThread> {
109
131
  const id = options?.threadId ?? crypto.randomUUID()
110
132
  const now = new Date()
111
133
 
@@ -128,7 +150,7 @@ export class MongoDBAIStorageService
128
150
  }
129
151
  }
130
152
 
131
- async getThread(threadId: string): Promise<AIThread> {
153
+ async getThread(threadId: string): Promise<AgentThread> {
132
154
  const row = await this.threads.findOne({ _id: threadId })
133
155
 
134
156
  if (!row) {
@@ -145,7 +167,7 @@ export class MongoDBAIStorageService
145
167
  }
146
168
  }
147
169
 
148
- async getThreads(resourceId: string): Promise<AIThread[]> {
170
+ async getThreads(resourceId: string): Promise<AgentThread[]> {
149
171
  const result = await this.threads
150
172
  .find({ resourceId })
151
173
  .sort({ updatedAt: -1 })
@@ -163,19 +185,21 @@ export class MongoDBAIStorageService
163
185
 
164
186
  async deleteThread(threadId: string): Promise<void> {
165
187
  await this.toolCalls.deleteMany({ threadId })
166
- await this.aiMessages.deleteMany({ threadId })
167
- await this.aiRuns.deleteMany({ threadId })
188
+ await this.agentMessages.deleteMany({ threadId })
189
+ await this.agentRuns.deleteMany({ threadId })
168
190
  await this.threads.deleteOne({ _id: threadId })
169
191
  }
170
192
 
171
193
  async getMessages(
172
194
  threadId: string,
173
195
  options?: { lastN?: number; cursor?: string }
174
- ): Promise<AIMessage[]> {
196
+ ): Promise<AgentMessage[]> {
175
197
  let filter: Record<string, any> = { threadId }
176
198
 
177
199
  if (options?.cursor) {
178
- const cursorRow = await this.aiMessages.findOne({ _id: options.cursor })
200
+ const cursorRow = await this.agentMessages.findOne({
201
+ _id: options.cursor,
202
+ })
179
203
  if (cursorRow) {
180
204
  filter.createdAt = { $lt: cursorRow.createdAt }
181
205
  }
@@ -183,7 +207,7 @@ export class MongoDBAIStorageService
183
207
 
184
208
  let msgResult
185
209
  if (options?.cursor || options?.lastN) {
186
- const innerResult = await this.aiMessages
210
+ const innerResult = await this.agentMessages
187
211
  .find(filter)
188
212
  .sort({ createdAt: -1 })
189
213
  .limit(options?.lastN ?? 50)
@@ -191,7 +215,7 @@ export class MongoDBAIStorageService
191
215
  innerResult.reverse()
192
216
  msgResult = innerResult
193
217
  } else {
194
- msgResult = await this.aiMessages
218
+ msgResult = await this.agentMessages
195
219
  .find(filter)
196
220
  .sort({ createdAt: 1 })
197
221
  .toArray()
@@ -209,9 +233,9 @@ export class MongoDBAIStorageService
209
233
  tcByMessage.get(msgId)!.push(tc)
210
234
  }
211
235
 
212
- const messages: AIMessage[] = []
236
+ const messages: AgentMessage[] = []
213
237
  for (const row of msgResult) {
214
- let parsedContent: AIMessage['content'] = row.content ?? undefined
238
+ let parsedContent: AgentMessage['content'] = row.content ?? undefined
215
239
  if (typeof row.content === 'string') {
216
240
  try {
217
241
  const parsed = JSON.parse(row.content)
@@ -225,9 +249,9 @@ export class MongoDBAIStorageService
225
249
  }
226
250
  }
227
251
 
228
- const msg: AIMessage = {
252
+ const msg: AgentMessage = {
229
253
  id: row._id,
230
- role: row.role as AIMessage['role'],
254
+ role: row.role as AgentMessage['role'],
231
255
  content: parsedContent,
232
256
  createdAt: new Date(row.createdAt),
233
257
  }
@@ -263,14 +287,17 @@ export class MongoDBAIStorageService
263
287
  return messages
264
288
  }
265
289
 
266
- async saveMessages(threadId: string, messages: AIMessage[]): Promise<void> {
290
+ async saveMessages(
291
+ threadId: string,
292
+ messages: AgentMessage[]
293
+ ): Promise<void> {
267
294
  if (messages.length === 0) return
268
295
 
269
296
  const toolMessages = messages.filter((m) => m.role === 'tool')
270
297
  const nonToolMessages = messages.filter((m) => m.role !== 'tool')
271
298
 
272
299
  if (nonToolMessages.length > 0) {
273
- await this.aiMessages.insertMany(
300
+ await this.agentMessages.insertMany(
274
301
  nonToolMessages.map((msg) => ({
275
302
  _id: msg.id,
276
303
  threadId,
@@ -353,7 +380,7 @@ export class MongoDBAIStorageService
353
380
  async createRun(run: CreateRunInput): Promise<string> {
354
381
  const runId = crypto.randomUUID()
355
382
 
356
- await this.aiRuns.insertOne({
383
+ await this.agentRuns.insertOne({
357
384
  _id: runId,
358
385
  agentName: run.agentName,
359
386
  threadId: run.threadId,
@@ -400,7 +427,7 @@ export class MongoDBAIStorageService
400
427
  setValues.usageModel = updates.usage.model
401
428
  }
402
429
 
403
- await this.aiRuns.updateOne({ _id: runId }, { $set: setValues })
430
+ await this.agentRuns.updateOne({ _id: runId }, { $set: setValues })
404
431
 
405
432
  if (updates.pendingApprovals !== undefined) {
406
433
  await this.toolCalls.updateMany(
@@ -424,7 +451,7 @@ export class MongoDBAIStorageService
424
451
  }
425
452
 
426
453
  async getRun(runId: string): Promise<AgentRunState | null> {
427
- const row = await this.aiRuns.findOne({ _id: runId })
454
+ const row = await this.agentRuns.findOne({ _id: runId })
428
455
  if (!row) return null
429
456
 
430
457
  const approvals = await this.toolCalls
@@ -435,7 +462,7 @@ export class MongoDBAIStorageService
435
462
  }
436
463
 
437
464
  async getRunsByThread(threadId: string): Promise<AgentRunState[]> {
438
- const result = await this.aiRuns
465
+ const result = await this.agentRuns
439
466
  .find({ threadId })
440
467
  .sort({ createdAt: -1 })
441
468
  .toArray()
@@ -574,5 +601,32 @@ export class MongoDBAIStorageService
574
601
  return result.modifiedCount > 0
575
602
  }
576
603
 
604
+ async saveScore(score: SaveScoreInput): Promise<void> {
605
+ await this.agentRunScores.insertOne({
606
+ _id: crypto.randomUUID(),
607
+ runId: score.runId,
608
+ scorerName: score.scorerName,
609
+ score: score.score,
610
+ reason: score.reason ?? null,
611
+ metadata: score.metadata ?? null,
612
+ createdAt: new Date(),
613
+ })
614
+ }
615
+
616
+ async getScores(runId: string): Promise<AgentRunScore[]> {
617
+ const rows = await this.agentRunScores
618
+ .find({ runId })
619
+ .sort({ createdAt: 1 })
620
+ .toArray()
621
+ return rows.map((row) => ({
622
+ runId: row.runId,
623
+ scorerName: row.scorerName,
624
+ score: row.score,
625
+ reason: row.reason ?? undefined,
626
+ metadata: row.metadata ?? undefined,
627
+ createdAt: row.createdAt,
628
+ }))
629
+ }
630
+
577
631
  public async close(): Promise<void> {}
578
632
  }
@@ -1,11 +1,11 @@
1
- import { buildRemoteHeaders } from '@pikku/core/remote'
1
+ import { buildRemoteHeaders } from '@pikku/core/ecosystem/remote'
2
2
  import type {
3
3
  DeploymentService,
4
4
  DeploymentServiceConfig,
5
5
  DeploymentConfig,
6
- } from '@pikku/core/services'
6
+ } from '@pikku/core/ecosystem/services'
7
7
  import type { JWTService, SecretService } from '@pikku/core/services'
8
- import { getAllFunctionNames } from '@pikku/core/function'
8
+ import { getAllFunctionNames } from '@pikku/core/ecosystem/function'
9
9
  import type { Db, Collection } from 'mongodb'
10
10
 
11
11
  interface DeploymentDoc {
@@ -1,4 +1,4 @@
1
- import { EventHubStore } from '@pikku/core/channel'
1
+ import { EventHubStore } from '@pikku/core/ecosystem/channel'
2
2
  import type { Db, Collection } from 'mongodb'
3
3
 
4
4
  interface ChannelSubscriptionDoc {
@@ -2,14 +2,14 @@ import { describe, test, before, after } from 'node:test'
2
2
  import assert from 'node:assert/strict'
3
3
  import { MongoClient, type Db } from 'mongodb'
4
4
  import { MongoMemoryServer } from 'mongodb-memory-server'
5
- import { defineServiceTests } from '@pikku/core/testing'
5
+ import { defineServiceTests } from '@pikku/core/ecosystem/testing'
6
6
 
7
7
  import { MongoDBChannelStore } from './mongodb-channel-store.js'
8
8
  import { MongoDBEventHubStore } from './mongodb-eventhub-store.js'
9
9
  import { MongoDBWorkflowService } from './mongodb-workflow-service.js'
10
10
  import { MongoDBWorkflowRunService } from './mongodb-workflow-run-service.js'
11
11
  import { MongoDBDeploymentService } from './mongodb-deployment-service.js'
12
- import { MongoDBAIStorageService } from './mongodb-ai-storage-service.js'
12
+ import { MongoDBAgentStorageService } from './mongodb-agent-storage-service.js'
13
13
  import { MongoDBAgentRunService } from './mongodb-agent-run-service.js'
14
14
  import { MongoDBSecretService } from './mongodb-secret-service.js'
15
15
  import { MongoDBSessionStore } from './mongodb-session-store.js'
@@ -42,8 +42,8 @@ function registerTests(name: string, getDb: () => Db) {
42
42
  await s.init()
43
43
  return s
44
44
  },
45
- aiStorageService: async () => {
46
- const s = new MongoDBAIStorageService(getDb())
45
+ agentStorageService: async () => {
46
+ const s = new MongoDBAgentStorageService(getDb())
47
47
  await s.init()
48
48
  return s
49
49
  },
@@ -4,7 +4,7 @@ import type {
4
4
  StepState,
5
5
  WorkflowStatus,
6
6
  WorkflowRunService,
7
- } from '@pikku/core/workflow'
7
+ } from '@pikku/core/ecosystem/workflow'
8
8
  import type { Db, Collection } from 'mongodb'
9
9
 
10
10
  interface WorkflowRunDoc {
@@ -1,15 +1,6 @@
1
- import type { SerializedError } from '@pikku/core'
2
- import {
3
- PikkuWorkflowService,
4
- type WorkflowPlannedStep,
5
- type WorkflowQueueOptions,
6
- type WorkflowRun,
7
- type WorkflowRunWire,
8
- type StepState,
9
- type StepStatus,
10
- type WorkflowStatus,
11
- type WorkflowVersionStatus,
12
- } from '@pikku/core/workflow'
1
+ import type { SerializedError } from '@pikku/core/ecosystem/types'
2
+ import { PikkuWorkflowService } from '@pikku/core/workflow'
3
+ import type { WorkflowPlannedStep, WorkflowQueueOptions, WorkflowRun, WorkflowRunWire, StepState, StepStatus, WorkflowStatus, WorkflowVersionStatus } from '@pikku/core/ecosystem/workflow'
13
4
  import type { Db, Collection } from 'mongodb'
14
5
  import { MongoDBWorkflowRunService } from './mongodb-workflow-run-service.js'
15
6