@pikku/kysely 0.13.13 → 0.13.15

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/CHANGELOG.md CHANGED
@@ -1,3 +1,37 @@
1
+ ## 0.13.15
2
+
3
+ ### Patch Changes
4
+
5
+ - fd9d834: Stop publishing internals that only their own package or file used. The declarations stay; only the entrypoint re-export is removed, so nothing that imported a name from where it is declared is affected.
6
+ - Updated dependencies [063f43a]
7
+ - Updated dependencies [ce66bf8]
8
+ - Updated dependencies [d0307a8]
9
+ - Updated dependencies [ce66bf8]
10
+ - Updated dependencies [3ad2131]
11
+ - Updated dependencies [b930dca]
12
+ - Updated dependencies [b95e77d]
13
+ - Updated dependencies [fd9d834]
14
+ - Updated dependencies [8978fbd]
15
+ - @pikku/core@0.12.82
16
+
17
+ ## 0.13.14
18
+
19
+ ### Patch Changes
20
+
21
+ - e110c55: Add runtime scoring for AI agents: `pikkuAIScorer` for heuristic grades and
22
+ `pikkuAIJudge` for LLM-judged ones, graded off the request path on two queue
23
+ lanes so a slow judge cannot starve the cheap checks. Grades are sampled
24
+ deterministically per `(run, scorer)` and persisted to `ai_run_score`.
25
+ - Updated dependencies [e110c55]
26
+ - Updated dependencies [e110c55]
27
+ - Updated dependencies [e110c55]
28
+ - Updated dependencies [acc8077]
29
+ - Updated dependencies [905f737]
30
+ - Updated dependencies [3cc6428]
31
+ - Updated dependencies [c524adf]
32
+ - Updated dependencies [e110c55]
33
+ - @pikku/core@0.12.81
34
+
1
35
  ## 0.13.13
2
36
 
3
37
  ### Patch Changes
@@ -8,18 +8,15 @@ export { KyselyAIStorageService } from './kysely-ai-storage-service.js';
8
8
  export { KyselyAgentRunService } from './kysely-ai-agent-run-service.js';
9
9
  export { KyselyAIRunStateService } from './kysely-ai-run-state-service.js';
10
10
  export { KyselySecretService } from './kysely-secret-service.js';
11
- export type { KyselySecretServiceConfig } from './kysely-secret-service.js';
12
11
  export { KyselyCredentialService } from './kysely-credential-service.js';
13
- export type { KyselyCredentialServiceConfig } from './kysely-credential-service.js';
14
12
  export { KyselySessionStore } from './kysely-session-store.js';
15
13
  export { KyselyScopeService } from './kysely-scope-service.js';
16
14
  export { KyselyWebhookService } from './kysely-webhook-service.js';
17
15
  export { createAuditedKysely, type CreateAuditedKyselyOptions, } from './create-audited-kysely.js';
18
16
  export { KyselyAuditService } from './kysely-audit-service.js';
19
17
  export { KyselyVirtualUserRunStore } from './kysely-virtual-user-run-store.js';
20
- export { SerializePlugin, SqliteSerializePlugin, BaseSerializePlugin, defaultSerializer, defaultDeserializer, maybeJson, skipTransform, dateRegex, type Serializer, type Deserializer, type SerializePluginOptions, } from './serialize-plugin.js';
21
- export { virtualUserSchema } from './schema/virtual-user.schema.js';
22
- export { auditSchema, pikkuSchemas, applyPikkuSchemas, compilePikkuSchemas, ensurePikkuSchema, type EnsureOutcome, resolveRequirements, unsatisfiedRequirements, rawStatement, requiredType, type PikkuSchema, type RequiredTypes, type SchemaRequirement, type UnmetRequirement, type SchemaStatement, type SchemaStatementFactory, } from './schema/index.js';
18
+ export { SerializePlugin, SqliteSerializePlugin, BaseSerializePlugin, type Serializer, type Deserializer, } from './serialize-plugin.js';
19
+ export { auditSchema, pikkuSchemas, applyPikkuSchemas, compilePikkuSchemas, ensurePikkuSchema, type EnsureOutcome, resolveRequirements, type PikkuSchema, type RequiredTypes, type UnmetRequirement, type SchemaStatementFactory, } from './schema/index.js';
23
20
  export type { KyselyPikkuDB } from './kysely-tables.js';
24
21
  export type { WorkflowRunService } from '@pikku/core/workflow';
25
22
  export type { AgentRunService, AgentRunRow } from '@pikku/core/ai-agent';
package/dist/src/index.js CHANGED
@@ -15,6 +15,5 @@ export { KyselyWebhookService } from './kysely-webhook-service.js';
15
15
  export { createAuditedKysely, } from './create-audited-kysely.js';
16
16
  export { KyselyAuditService } from './kysely-audit-service.js';
17
17
  export { KyselyVirtualUserRunStore } from './kysely-virtual-user-run-store.js';
18
- export { SerializePlugin, SqliteSerializePlugin, BaseSerializePlugin, defaultSerializer, defaultDeserializer, maybeJson, skipTransform, dateRegex, } from './serialize-plugin.js';
19
- export { virtualUserSchema } from './schema/virtual-user.schema.js';
20
- export { auditSchema, pikkuSchemas, applyPikkuSchemas, compilePikkuSchemas, ensurePikkuSchema, resolveRequirements, unsatisfiedRequirements, rawStatement, requiredType, } from './schema/index.js';
18
+ export { SerializePlugin, SqliteSerializePlugin, BaseSerializePlugin, } from './serialize-plugin.js';
19
+ export { auditSchema, pikkuSchemas, applyPikkuSchemas, compilePikkuSchemas, ensurePikkuSchema, resolveRequirements, } from './schema/index.js';
@@ -0,0 +1,10 @@
1
+ import type { Kysely } from 'kysely';
2
+ import type { KyselyPikkuDB } from './kysely-tables.js';
3
+ import type { SaveScoreInput } from '@pikku/core/services';
4
+ import type { AIRunScore } from '@pikku/core/ai-scorer';
5
+ /**
6
+ * Shared by the two Kysely services that implement `AIRunStateService` — they
7
+ * differ in how they store approvals, not in how they store grades.
8
+ */
9
+ export declare const saveRunScore: (db: Kysely<KyselyPikkuDB>, score: SaveScoreInput) => Promise<void>;
10
+ export declare const getRunScores: (db: Kysely<KyselyPikkuDB>, runId: string) => Promise<AIRunScore[]>;
@@ -0,0 +1,34 @@
1
+ import { parseJson } from './kysely-json.js';
2
+ /**
3
+ * Shared by the two Kysely services that implement `AIRunStateService` — they
4
+ * differ in how they store approvals, not in how they store grades.
5
+ */
6
+ export const saveRunScore = async (db, score) => {
7
+ await db
8
+ .insertInto('aiRunScore')
9
+ .values({
10
+ id: crypto.randomUUID(),
11
+ runId: score.runId,
12
+ scorerName: score.scorerName,
13
+ score: score.score,
14
+ reason: score.reason ?? null,
15
+ metadata: score.metadata ? JSON.stringify(score.metadata) : null,
16
+ })
17
+ .execute();
18
+ };
19
+ export const getRunScores = async (db, runId) => {
20
+ const rows = await db
21
+ .selectFrom('aiRunScore')
22
+ .selectAll()
23
+ .where('runId', '=', runId)
24
+ .orderBy('createdAt', 'asc')
25
+ .execute();
26
+ return rows.map((row) => ({
27
+ runId: row.runId,
28
+ scorerName: row.scorerName,
29
+ score: Number(row.score),
30
+ reason: row.reason ?? undefined,
31
+ metadata: parseJson(row.metadata),
32
+ createdAt: new Date(row.createdAt),
33
+ }));
34
+ };
@@ -1,7 +1,8 @@
1
1
  import type { Kysely } from 'kysely';
2
2
  import type { KyselyPikkuDB } from './kysely-tables.js';
3
- import type { AIRunStateService, CreateRunInput } from '@pikku/core/services';
3
+ import type { AIRunStateService, CreateRunInput, SaveScoreInput } from '@pikku/core/services';
4
4
  import type { AgentRunState, PendingApproval } from '@pikku/core/ai-agent';
5
+ import type { AIRunScore } from '@pikku/core/ai-scorer';
5
6
  export declare class KyselyAIRunStateService implements AIRunStateService {
6
7
  private db;
7
8
  private initialized;
@@ -16,5 +17,7 @@ export declare class KyselyAIRunStateService implements AIRunStateService {
16
17
  run: AgentRunState;
17
18
  approval: PendingApproval;
18
19
  } | null>;
20
+ saveScore(score: SaveScoreInput): Promise<void>;
21
+ getScores(runId: string): Promise<AIRunScore[]>;
19
22
  private toRunState;
20
23
  }
@@ -1,6 +1,7 @@
1
1
  import { sql } from 'kysely';
2
2
  import { ensurePikkuSchema } from './schema/index.js';
3
3
  import { aiSchema } from './schema/ai.schema.js';
4
+ import { getRunScores, saveRunScore } from './kysely-ai-run-scores.js';
4
5
  export class KyselyAIRunStateService {
5
6
  db;
6
7
  initialized = false;
@@ -137,6 +138,12 @@ export class KyselyAIRunStateService {
137
138
  }
138
139
  return null;
139
140
  }
141
+ async saveScore(score) {
142
+ await saveRunScore(this.db, score);
143
+ }
144
+ async getScores(runId) {
145
+ return getRunScores(this.db, runId);
146
+ }
140
147
  toRunState(row) {
141
148
  return {
142
149
  runId: row.runId,
@@ -1,5 +1,6 @@
1
- import type { AIStorageService, AIRunStateService, CreateRunInput } from '@pikku/core/services';
1
+ import type { AIStorageService, AIRunStateService, CreateRunInput, SaveScoreInput } from '@pikku/core/services';
2
2
  import type { AIThread, AIMessage, AgentRunState } from '@pikku/core/ai-agent';
3
+ import type { AIRunScore } from '@pikku/core/ai-scorer';
3
4
  import type { Kysely } from 'kysely';
4
5
  import type { KyselyPikkuDB } from './kysely-tables.js';
5
6
  export declare class KyselyAIStorageService implements AIStorageService, AIRunStateService {
@@ -33,5 +34,7 @@ export declare class KyselyAIStorageService implements AIStorageService, AIRunSt
33
34
  approval: NonNullable<AgentRunState['pendingApprovals']>[number];
34
35
  } | null>;
35
36
  resolveApproval(toolCallId: string, status: 'approved' | 'denied'): Promise<boolean>;
37
+ saveScore(score: SaveScoreInput): Promise<void>;
38
+ getScores(runId: string): Promise<AIRunScore[]>;
36
39
  close(): Promise<void>;
37
40
  }
@@ -1,4 +1,5 @@
1
1
  import { parseJson } from './kysely-json.js';
2
+ import { getRunScores, saveRunScore } from './kysely-ai-run-scores.js';
2
3
  import { ensurePikkuSchema } from './schema/index.js';
3
4
  import { aiSchema } from './schema/ai.schema.js';
4
5
  export class KyselyAIStorageService {
@@ -519,5 +520,11 @@ export class KyselyAIStorageService {
519
520
  .executeTakeFirst();
520
521
  return Number(result?.numUpdatedRows ?? 0) > 0;
521
522
  }
523
+ async saveScore(score) {
524
+ await saveRunScore(this.db, score);
525
+ }
526
+ async getScores(runId) {
527
+ return getRunScores(this.db, runId);
528
+ }
522
529
  async close() { }
523
530
  }
@@ -133,6 +133,17 @@ export interface AIRunTable {
133
133
  createdAt: Generated<Date>;
134
134
  updatedAt: Generated<Date>;
135
135
  }
136
+ export interface AIRunScoreTable {
137
+ id: string;
138
+ runId: string;
139
+ scorerName: string;
140
+ /** 0..1, so grades are comparable across scorers. */
141
+ score: number;
142
+ reason: string | null;
143
+ /** JSON-serialized structured detail the scorer returned alongside the score. */
144
+ metadata: string | null;
145
+ createdAt: Generated<Date>;
146
+ }
136
147
  export interface PikkuDeploymentsTable {
137
148
  deploymentId: string;
138
149
  endpoint: string;
@@ -295,6 +306,7 @@ export interface KyselyPikkuDB {
295
306
  aiToolCall: AIToolCallTable;
296
307
  aiWorkingMemory: AIWorkingMemoryTable;
297
308
  aiRun: AIRunTable;
309
+ aiRunScore: AIRunScoreTable;
298
310
  pikkuDeployments: PikkuDeploymentsTable;
299
311
  pikkuDeploymentFunctions: PikkuDeploymentFunctionsTable;
300
312
  secrets: SecretsTable;
@@ -85,5 +85,18 @@ export const aiSchema = {
85
85
  .createIndex('idx_ai_run_thread')
86
86
  .on('aiRun')
87
87
  .columns(['threadId', 'createdAt']),
88
+ (db) => db.schema
89
+ .createTable('aiRunScore')
90
+ .addColumn('id', 'varchar(36)', (col) => col.primaryKey())
91
+ .addColumn('runId', 'varchar(36)', (col) => col.notNull().references('aiRun.runId').onDelete('cascade'))
92
+ .addColumn('scorerName', 'varchar(255)', (col) => col.notNull())
93
+ .addColumn('score', 'real', (col) => col.notNull())
94
+ .addColumn('reason', 'text')
95
+ .addColumn('metadata', 'text')
96
+ .addColumn('createdAt', 'timestamp', (col) => col.defaultTo(sql `CURRENT_TIMESTAMP`).notNull()),
97
+ (db) => db.schema
98
+ .createIndex('idx_ai_run_score_run')
99
+ .on('aiRunScore')
100
+ .columns(['runId', 'createdAt']),
88
101
  ],
89
102
  };
@@ -1 +1 @@
1
- {"root":["../src/create-audited-kysely.ts","../src/index.ts","../src/kysely-ai-agent-run-service.ts","../src/kysely-ai-run-state-service.ts","../src/kysely-ai-storage-service.ts","../src/kysely-audit-service.ts","../src/kysely-channel-store.ts","../src/kysely-credential-service.ts","../src/kysely-deployment-service.ts","../src/kysely-eventhub-store.ts","../src/kysely-json.ts","../src/kysely-scope-service.ts","../src/kysely-secret-service.ts","../src/kysely-session-store.ts","../src/kysely-tables.ts","../src/kysely-virtual-user-run-store.ts","../src/kysely-webhook-service.ts","../src/kysely-workflow-mirror.ts","../src/kysely-workflow-run-service.ts","../src/kysely-workflow-service.ts","../src/serialize-plugin.ts","../src/schema/ai.schema.ts","../src/schema/audit.schema.ts","../src/schema/channel.schema.ts","../src/schema/credential.schema.ts","../src/schema/deployment.schema.ts","../src/schema/index.ts","../src/schema/pikku-schema.types.ts","../src/schema/scope.schema.ts","../src/schema/secret.schema.ts","../src/schema/session.schema.ts","../src/schema/virtual-user.schema.ts","../src/schema/webhook.schema.ts","../src/schema/workflow.schema.ts","../bin/pikku-kysely-pure.ts"],"version":"6.0.3"}
1
+ {"root":["../src/create-audited-kysely.ts","../src/index.ts","../src/kysely-ai-agent-run-service.ts","../src/kysely-ai-run-scores.ts","../src/kysely-ai-run-state-service.ts","../src/kysely-ai-storage-service.ts","../src/kysely-audit-service.ts","../src/kysely-channel-store.ts","../src/kysely-credential-service.ts","../src/kysely-deployment-service.ts","../src/kysely-eventhub-store.ts","../src/kysely-json.ts","../src/kysely-scope-service.ts","../src/kysely-secret-service.ts","../src/kysely-session-store.ts","../src/kysely-tables.ts","../src/kysely-virtual-user-run-store.ts","../src/kysely-webhook-service.ts","../src/kysely-workflow-mirror.ts","../src/kysely-workflow-run-service.ts","../src/kysely-workflow-service.ts","../src/serialize-plugin.ts","../src/schema/ai.schema.ts","../src/schema/audit.schema.ts","../src/schema/channel.schema.ts","../src/schema/credential.schema.ts","../src/schema/deployment.schema.ts","../src/schema/index.ts","../src/schema/pikku-schema.types.ts","../src/schema/scope.schema.ts","../src/schema/secret.schema.ts","../src/schema/session.schema.ts","../src/schema/virtual-user.schema.ts","../src/schema/webhook.schema.ts","../src/schema/workflow.schema.ts","../bin/pikku-kysely-pure.ts"],"version":"6.0.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/kysely",
3
- "version": "0.13.13",
3
+ "version": "0.13.15",
4
4
  "description": "Kysely-backed Pikku services — workflow state, secrets, sessions, scopes and audit",
5
5
  "author": "yasser.fadl@gmail.com",
6
6
  "license": "MIT",
@@ -21,7 +21,7 @@
21
21
  "prepublishOnly": "yarn build"
22
22
  },
23
23
  "peerDependencies": {
24
- "@pikku/core": "^0.12.80"
24
+ "@pikku/core": "^0.12.82"
25
25
  },
26
26
  "dependencies": {
27
27
  "kysely": "^0.29.0"
package/src/index.ts CHANGED
@@ -8,9 +8,7 @@ export { KyselyAIStorageService } from './kysely-ai-storage-service.js'
8
8
  export { KyselyAgentRunService } from './kysely-ai-agent-run-service.js'
9
9
  export { KyselyAIRunStateService } from './kysely-ai-run-state-service.js'
10
10
  export { KyselySecretService } from './kysely-secret-service.js'
11
- export type { KyselySecretServiceConfig } from './kysely-secret-service.js'
12
11
  export { KyselyCredentialService } from './kysely-credential-service.js'
13
- export type { KyselyCredentialServiceConfig } from './kysely-credential-service.js'
14
12
  export { KyselySessionStore } from './kysely-session-store.js'
15
13
  export { KyselyScopeService } from './kysely-scope-service.js'
16
14
  export { KyselyWebhookService } from './kysely-webhook-service.js'
@@ -25,17 +23,9 @@ export {
25
23
  SerializePlugin,
26
24
  SqliteSerializePlugin,
27
25
  BaseSerializePlugin,
28
- defaultSerializer,
29
- defaultDeserializer,
30
- maybeJson,
31
- skipTransform,
32
- dateRegex,
33
26
  type Serializer,
34
27
  type Deserializer,
35
- type SerializePluginOptions,
36
28
  } from './serialize-plugin.js'
37
-
38
- export { virtualUserSchema } from './schema/virtual-user.schema.js'
39
29
  export {
40
30
  auditSchema,
41
31
  pikkuSchemas,
@@ -44,14 +34,9 @@ export {
44
34
  ensurePikkuSchema,
45
35
  type EnsureOutcome,
46
36
  resolveRequirements,
47
- unsatisfiedRequirements,
48
- rawStatement,
49
- requiredType,
50
37
  type PikkuSchema,
51
38
  type RequiredTypes,
52
- type SchemaRequirement,
53
39
  type UnmetRequirement,
54
- type SchemaStatement,
55
40
  type SchemaStatementFactory,
56
41
  } from './schema/index.js'
57
42
 
@@ -0,0 +1,47 @@
1
+ import type { Kysely } from 'kysely'
2
+ import type { KyselyPikkuDB } from './kysely-tables.js'
3
+ import type { SaveScoreInput } from '@pikku/core/services'
4
+ import type { AIRunScore } from '@pikku/core/ai-scorer'
5
+ import { parseJson } from './kysely-json.js'
6
+
7
+ /**
8
+ * Shared by the two Kysely services that implement `AIRunStateService` — they
9
+ * differ in how they store approvals, not in how they store grades.
10
+ */
11
+ export const saveRunScore = async (
12
+ db: Kysely<KyselyPikkuDB>,
13
+ score: SaveScoreInput
14
+ ): Promise<void> => {
15
+ await db
16
+ .insertInto('aiRunScore')
17
+ .values({
18
+ id: crypto.randomUUID(),
19
+ runId: score.runId,
20
+ scorerName: score.scorerName,
21
+ score: score.score,
22
+ reason: score.reason ?? null,
23
+ metadata: score.metadata ? JSON.stringify(score.metadata) : null,
24
+ })
25
+ .execute()
26
+ }
27
+
28
+ export const getRunScores = async (
29
+ db: Kysely<KyselyPikkuDB>,
30
+ runId: string
31
+ ): Promise<AIRunScore[]> => {
32
+ const rows = await db
33
+ .selectFrom('aiRunScore')
34
+ .selectAll()
35
+ .where('runId', '=', runId)
36
+ .orderBy('createdAt', 'asc')
37
+ .execute()
38
+
39
+ return rows.map((row) => ({
40
+ runId: row.runId,
41
+ scorerName: row.scorerName,
42
+ score: Number(row.score),
43
+ reason: row.reason ?? undefined,
44
+ metadata: parseJson(row.metadata),
45
+ createdAt: new Date(row.createdAt),
46
+ }))
47
+ }
@@ -1,10 +1,16 @@
1
1
  import { sql } from 'kysely'
2
2
  import type { Kysely } from 'kysely'
3
3
  import type { KyselyPikkuDB } from './kysely-tables.js'
4
- import type { AIRunStateService, CreateRunInput } from '@pikku/core/services'
4
+ import type {
5
+ AIRunStateService,
6
+ CreateRunInput,
7
+ SaveScoreInput,
8
+ } from '@pikku/core/services'
5
9
  import type { AgentRunState, PendingApproval } from '@pikku/core/ai-agent'
10
+ import type { AIRunScore } from '@pikku/core/ai-scorer'
6
11
  import { ensurePikkuSchema } from './schema/index.js'
7
12
  import { aiSchema } from './schema/ai.schema.js'
13
+ import { getRunScores, saveRunScore } from './kysely-ai-run-scores.js'
8
14
 
9
15
  export class KyselyAIRunStateService implements AIRunStateService {
10
16
  private initialized = false
@@ -160,6 +166,14 @@ export class KyselyAIRunStateService implements AIRunStateService {
160
166
  return null
161
167
  }
162
168
 
169
+ async saveScore(score: SaveScoreInput): Promise<void> {
170
+ await saveRunScore(this.db, score)
171
+ }
172
+
173
+ async getScores(runId: string): Promise<AIRunScore[]> {
174
+ return getRunScores(this.db, runId)
175
+ }
176
+
163
177
  private toRunState(row: any): AgentRunState {
164
178
  return {
165
179
  runId: row.runId,
@@ -2,11 +2,14 @@ import type {
2
2
  AIStorageService,
3
3
  AIRunStateService,
4
4
  CreateRunInput,
5
+ SaveScoreInput,
5
6
  } from '@pikku/core/services'
6
7
  import type { AIThread, AIMessage, AgentRunState } from '@pikku/core/ai-agent'
8
+ import type { AIRunScore } from '@pikku/core/ai-scorer'
7
9
  import type { Kysely } from 'kysely'
8
10
  import type { KyselyPikkuDB } from './kysely-tables.js'
9
11
  import { parseJson } from './kysely-json.js'
12
+ import { getRunScores, saveRunScore } from './kysely-ai-run-scores.js'
10
13
  import { ensurePikkuSchema } from './schema/index.js'
11
14
  import { aiSchema } from './schema/ai.schema.js'
12
15
 
@@ -607,5 +610,13 @@ export class KyselyAIStorageService
607
610
  return Number(result?.numUpdatedRows ?? 0) > 0
608
611
  }
609
612
 
613
+ async saveScore(score: SaveScoreInput): Promise<void> {
614
+ await saveRunScore(this.db, score)
615
+ }
616
+
617
+ async getScores(runId: string): Promise<AIRunScore[]> {
618
+ return getRunScores(this.db, runId)
619
+ }
620
+
610
621
  public async close(): Promise<void> {}
611
622
  }
@@ -44,6 +44,7 @@ async function dropAllTables(db: Kysely<KyselyPikkuDB>): Promise<void> {
44
44
  'pikku_deployments',
45
45
  'ai_tool_call',
46
46
  'ai_message',
47
+ 'ai_run_score',
47
48
  'ai_run',
48
49
  'ai_working_memory',
49
50
  'ai_threads',
@@ -151,6 +151,18 @@ export interface AIRunTable {
151
151
  updatedAt: Generated<Date>
152
152
  }
153
153
 
154
+ export interface AIRunScoreTable {
155
+ id: string
156
+ runId: string
157
+ scorerName: string
158
+ /** 0..1, so grades are comparable across scorers. */
159
+ score: number
160
+ reason: string | null
161
+ /** JSON-serialized structured detail the scorer returned alongside the score. */
162
+ metadata: string | null
163
+ createdAt: Generated<Date>
164
+ }
165
+
154
166
  export interface PikkuDeploymentsTable {
155
167
  deploymentId: string
156
168
  endpoint: string
@@ -329,6 +341,7 @@ export interface KyselyPikkuDB {
329
341
  aiToolCall: AIToolCallTable
330
342
  aiWorkingMemory: AIWorkingMemoryTable
331
343
  aiRun: AIRunTable
344
+ aiRunScore: AIRunScoreTable
332
345
  pikkuDeployments: PikkuDeploymentsTable
333
346
  pikkuDeploymentFunctions: PikkuDeploymentFunctionsTable
334
347
  secrets: SecretsTable
@@ -136,5 +136,26 @@ export const aiSchema: PikkuSchema = {
136
136
  .createIndex('idx_ai_run_thread')
137
137
  .on('aiRun')
138
138
  .columns(['threadId', 'createdAt']),
139
+
140
+ (db) =>
141
+ db.schema
142
+ .createTable('aiRunScore')
143
+ .addColumn('id', 'varchar(36)', (col) => col.primaryKey())
144
+ .addColumn('runId', 'varchar(36)', (col) =>
145
+ col.notNull().references('aiRun.runId').onDelete('cascade')
146
+ )
147
+ .addColumn('scorerName', 'varchar(255)', (col) => col.notNull())
148
+ .addColumn('score', 'real', (col) => col.notNull())
149
+ .addColumn('reason', 'text')
150
+ .addColumn('metadata', 'text')
151
+ .addColumn('createdAt', 'timestamp', (col) =>
152
+ col.defaultTo(sql`CURRENT_TIMESTAMP`).notNull()
153
+ ),
154
+
155
+ (db) =>
156
+ db.schema
157
+ .createIndex('idx_ai_run_score_run')
158
+ .on('aiRunScore')
159
+ .columns(['runId', 'createdAt']),
139
160
  ],
140
161
  }