@axiom-lattice/pg-stores 2.0.6 → 2.0.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiom-lattice/pg-stores",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "description": "PG stores implementation for Axiom Lattice framework",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -25,8 +25,8 @@
25
25
  "@langchain/core": "1.1.30",
26
26
  "pg": "^8.16.3",
27
27
  "uuid": "^9.0.1",
28
- "@axiom-lattice/core": "3.0.6",
29
- "@axiom-lattice/protocols": "3.0.2"
28
+ "@axiom-lattice/core": "3.1.0",
29
+ "@axiom-lattice/protocols": "3.0.3"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/jest": "^29.5.14",
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Eval task_id migration tests
3
+ *
4
+ * Verifies the add_task_id_to_eval_runs migration adds (and removes)
5
+ * the task_id column on lattice_eval_runs.
6
+ */
7
+
8
+ import { describe, expect, it, jest } from "@jest/globals";
9
+ import { addTaskIdToEvalRuns, evalMigrations } from "../migrations/eval_migrations";
10
+
11
+ describe("add_task_id_to_eval_runs migration", () => {
12
+ it("is registered in evalMigrations", () => {
13
+ expect(evalMigrations.map((m) => m.name)).toContain("add_task_id_to_eval_runs");
14
+ });
15
+
16
+ it("has a version greater than all existing eval migrations", () => {
17
+ const versions = evalMigrations.map((m) => m.version);
18
+ expect(addTaskIdToEvalRuns.version).toBe(Math.max(...versions));
19
+ });
20
+
21
+ it("emits ADD COLUMN task_id in up()", async () => {
22
+ const queries: string[] = [];
23
+ const client = { query: jest.fn(async (sql: string) => { queries.push(sql); }) };
24
+ await addTaskIdToEvalRuns.up(client as never);
25
+ expect(queries.some((q) => q.includes("ADD COLUMN IF NOT EXISTS task_id TEXT"))).toBe(true);
26
+ });
27
+
28
+ it("emits DROP COLUMN task_id in down()", async () => {
29
+ const queries: string[] = [];
30
+ const client = { query: jest.fn(async (sql: string) => { queries.push(sql); }) };
31
+ await addTaskIdToEvalRuns.down(client as never);
32
+ expect(queries.some((q) => q.includes("DROP COLUMN IF EXISTS task_id"))).toBe(true);
33
+ });
34
+ });
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Task files migration tests
3
+ *
4
+ * Verifies the add_files_to_tasks migration adds (and removes)
5
+ * the files column on lattice_tasks.
6
+ */
7
+
8
+ import { describe, expect, it, jest } from "@jest/globals";
9
+ import { addFilesToTasks, taskMigrations } from "../migrations/task_migration";
10
+
11
+ describe("add_files_to_tasks migration", () => {
12
+ it("is registered in taskMigrations", () => {
13
+ expect(taskMigrations.map((m) => m.name)).toContain("add_files_to_tasks");
14
+ });
15
+
16
+ it("has a version greater than all existing task migrations", () => {
17
+ const versions = taskMigrations.map((m) => m.version);
18
+ expect(addFilesToTasks.version).toBe(Math.max(...versions));
19
+ });
20
+
21
+ it("emits ADD COLUMN files JSONB in up()", async () => {
22
+ const queries: string[] = [];
23
+ const client = { query: jest.fn(async (sql: string) => { queries.push(sql); }) };
24
+ await addFilesToTasks.up(client as never);
25
+ expect(queries.some((q) => q.includes("ADD COLUMN IF NOT EXISTS files JSONB"))).toBe(true);
26
+ });
27
+
28
+ it("emits DROP COLUMN files in down()", async () => {
29
+ const queries: string[] = [];
30
+ const client = { query: jest.fn(async (sql: string) => { queries.push(sql); }) };
31
+ await addFilesToTasks.down(client as never);
32
+ expect(queries.some((q) => q.includes("DROP COLUMN IF EXISTS files"))).toBe(true);
33
+ });
34
+ });
@@ -63,7 +63,7 @@ import { addWorkspaceProjectToQueue } from "./migrations/add_workspace_project_t
63
63
  import { createWorkflowTrackingTables, addStepThreadId, addWorkflowRunsTenantStatusUpdatedIndex } from "./migrations/workflow_tracking_migrations";
64
64
  import { evalMigrations } from "./migrations/eval_migrations";
65
65
  import { createA2AApiKeysTable } from "./migrations/a2a_api_key_migration";
66
- import { createTasksTable, addTaskFieldsMigration, addTaskProjectFieldsMigration } from "./migrations/task_migration";
66
+ import { taskMigrations } from "./migrations/task_migration";
67
67
  import { createMenuItemsTable } from "./migrations/menu_items_migration";
68
68
  import { addFileContentType } from "./migrations/menu_items_add_file_type";
69
69
  import { createSharedResourcesTable } from "./migrations/shared_resources_migration";
@@ -115,14 +115,14 @@ export async function createPgStoreConfig(connectionString: string) {
115
115
  mm.register(createA2AApiKeysTable); // v130
116
116
  mm.register(addWorkspaceProjectToQueue); // v131
117
117
  mm.register(addAssistantOwnerUserId); // v132
118
- mm.register(createTasksTable); // v133
118
+ for (const m of taskMigrations) { // v133, v139, v140, v141
119
+ mm.register(m);
120
+ }
119
121
  mm.register(createMenuItemsTable); // v134
120
122
  mm.register(createSharedResourcesTable); // v135
121
123
  mm.register(addFileContentType); // v136
122
124
  mm.register(createCollectionsTable); // v137
123
- mm.register(addTaskFieldsMigration); // v139
124
125
  mm.register(createTaskWorkItemsMigration); // v138
125
- mm.register(addTaskProjectFieldsMigration); // v140
126
126
  mm.register(addWorkItemProjectFieldsMigration); // v140
127
127
  mm.register(createConnectionConfigsTable); // v160
128
128
  mm.register(addWorkflowRunsTenantStatusUpdatedIndex); // v161
@@ -359,6 +359,28 @@ export const enforceUniqueEvalProjectName: Migration = {
359
359
  },
360
360
  };
361
361
 
362
+ /** Add task_id to eval runs (training round association, 1 task : N runs) */
363
+ export const addTaskIdToEvalRuns: Migration = {
364
+ version: 164,
365
+ name: "add_task_id_to_eval_runs",
366
+ up: async (client: PoolClient) => {
367
+ await client.query(`
368
+ ALTER TABLE lattice_eval_runs
369
+ ADD COLUMN IF NOT EXISTS task_id TEXT
370
+ `);
371
+ await client.query(`
372
+ CREATE INDEX IF NOT EXISTS idx_lattice_eval_runs_task_id
373
+ ON lattice_eval_runs(task_id)
374
+ `);
375
+ },
376
+ down: async (client: PoolClient) => {
377
+ await client.query(`DROP INDEX IF EXISTS idx_lattice_eval_runs_task_id`);
378
+ await client.query(`
379
+ ALTER TABLE lattice_eval_runs DROP COLUMN IF EXISTS task_id
380
+ `);
381
+ },
382
+ };
383
+
362
384
  /** All eval migrations in version order */
363
385
  export const evalMigrations: Migration[] = [
364
386
  createEvalProjectsTable,
@@ -371,4 +393,5 @@ export const evalMigrations: Migration[] = [
371
393
  addInterruptColumnsToEval,
372
394
  addInterruptPolicyToEvalCases,
373
395
  enforceUniqueEvalProjectName,
396
+ addTaskIdToEvalRuns,
374
397
  ];
@@ -80,3 +80,28 @@ export const addTaskProjectFieldsMigration: Migration = {
80
80
  `);
81
81
  },
82
82
  };
83
+
84
+ /** Add files column to tasks (URI file references) */
85
+ export const addFilesToTasks: Migration = {
86
+ version: 141,
87
+ name: "add_files_to_tasks",
88
+ up: async (client: PoolClient) => {
89
+ await client.query(`
90
+ ALTER TABLE lattice_tasks
91
+ ADD COLUMN IF NOT EXISTS files JSONB
92
+ `);
93
+ },
94
+ down: async (client: PoolClient) => {
95
+ await client.query(`
96
+ ALTER TABLE lattice_tasks DROP COLUMN IF EXISTS files
97
+ `);
98
+ },
99
+ };
100
+
101
+ /** All task migrations in version order */
102
+ export const taskMigrations: Migration[] = [
103
+ createTasksTable,
104
+ addTaskFieldsMigration,
105
+ addTaskProjectFieldsMigration,
106
+ addFilesToTasks,
107
+ ];
@@ -183,6 +183,7 @@ export class PostgreSQLEvalStore implements EvalStore {
183
183
  holdout: row.holdout as boolean | undefined,
184
184
  envProjectId: row.env_project_id as string | undefined,
185
185
  envWorkspaceId: row.env_workspace_id as string | undefined,
186
+ taskId: row.task_id as string | undefined,
186
187
  createdAt: new Date(row.created_at as string),
187
188
  startedAt: row.started_at ? new Date(row.started_at as string) : undefined,
188
189
  completedAt: row.completed_at ? new Date(row.completed_at as string) : undefined,
@@ -609,7 +610,7 @@ export class PostgreSQLEvalStore implements EvalStore {
609
610
  `SELECT id, project_id, tenant_id,
610
611
  status, concurrency, total_cases,
611
612
  passed_cases, failed_cases, interrupted_cases, avg_score,
612
- error, holdout, env_project_id, env_workspace_id, created_at, started_at, completed_at
613
+ error, holdout, env_project_id, env_workspace_id, task_id, created_at, started_at, completed_at
613
614
  FROM lattice_eval_runs
614
615
  WHERE ${conditions.join(" AND ")}
615
616
  ORDER BY created_at DESC`,
@@ -631,7 +632,7 @@ export class PostgreSQLEvalStore implements EvalStore {
631
632
  `SELECT id, project_id, tenant_id,
632
633
  status, concurrency, total_cases,
633
634
  passed_cases, failed_cases, interrupted_cases, avg_score,
634
- error, holdout, env_project_id, env_workspace_id, created_at, started_at, completed_at
635
+ error, holdout, env_project_id, env_workspace_id, task_id, created_at, started_at, completed_at
635
636
  FROM lattice_eval_runs
636
637
  WHERE id = $1 AND tenant_id = $2`,
637
638
  [id, tenantId]
@@ -656,12 +657,12 @@ export class PostgreSQLEvalStore implements EvalStore {
656
657
  completed_at: string | null;
657
658
  }>(
658
659
  `INSERT INTO lattice_eval_runs
659
- (id, project_id, tenant_id, status, concurrency, total_cases, passed_cases, failed_cases, avg_score, holdout, env_project_id, env_workspace_id, started_at)
660
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)
660
+ (id, project_id, tenant_id, status, concurrency, total_cases, passed_cases, failed_cases, avg_score, holdout, env_project_id, env_workspace_id, task_id, started_at)
661
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)
661
662
  RETURNING id, project_id, tenant_id,
662
663
  status, concurrency, total_cases,
663
664
  passed_cases, failed_cases, interrupted_cases, avg_score,
664
- error, holdout, env_project_id, env_workspace_id, created_at, started_at, completed_at`,
665
+ error, holdout, env_project_id, env_workspace_id, task_id, created_at, started_at, completed_at`,
665
666
  [
666
667
  actualId,
667
668
  projectId,
@@ -675,6 +676,7 @@ export class PostgreSQLEvalStore implements EvalStore {
675
676
  data.holdout ?? false,
676
677
  data.envProjectId || null,
677
678
  data.envWorkspaceId || null,
679
+ data.taskId || null,
678
680
  new Date(),
679
681
  ]
680
682
  );
@@ -720,7 +722,7 @@ export class PostgreSQLEvalStore implements EvalStore {
720
722
  RETURNING id, project_id, tenant_id,
721
723
  status, concurrency, total_cases,
722
724
  passed_cases, failed_cases, interrupted_cases, avg_score,
723
- error, holdout, env_project_id, env_workspace_id, created_at, started_at, completed_at`,
725
+ error, holdout, env_project_id, env_workspace_id, task_id, created_at, started_at, completed_at`,
724
726
  vals
725
727
  );
726
728
  return rows.length ? this.mapRowToRun(rows[0] as unknown as Record<string, unknown>) : null;
@@ -10,9 +10,10 @@ import type {
10
10
  CreateTaskRequest,
11
11
  UpdateTaskRequest,
12
12
  TaskListFilter,
13
+ TaskFileRef,
13
14
  } from "@axiom-lattice/protocols";
14
15
  import { MigrationManager } from "../migrations/migration";
15
- import { createTasksTable, addTaskFieldsMigration, addTaskProjectFieldsMigration } from "../migrations/task_migration";
16
+ import { createTasksTable, addTaskFieldsMigration, addTaskProjectFieldsMigration, addFilesToTasks } from "../migrations/task_migration";
16
17
  import { v4 as uuidv4 } from "uuid";
17
18
 
18
19
  interface TaskRow {
@@ -35,10 +36,22 @@ interface TaskRow {
35
36
  failure_reason: string | null;
36
37
  workspace_id: string | null;
37
38
  project_id: string | null;
39
+ files: unknown;
38
40
  created_at: string;
39
41
  updated_at: string;
40
42
  }
41
43
 
44
+ function parseTaskFiles(raw: unknown): TaskFileRef[] | undefined {
45
+ if (!raw) return undefined;
46
+ try {
47
+ const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
48
+ if (!Array.isArray(parsed)) return undefined;
49
+ return parsed as TaskFileRef[];
50
+ } catch {
51
+ return undefined;
52
+ }
53
+ }
54
+
42
55
  function mapRowToTask(row: TaskRow): TaskItem {
43
56
  return {
44
57
  id: row.id,
@@ -60,6 +73,7 @@ function mapRowToTask(row: TaskRow): TaskItem {
60
73
  failureReason: row.failure_reason ?? undefined,
61
74
  workspaceId: row.workspace_id ?? undefined,
62
75
  projectId: row.project_id ?? undefined,
76
+ files: parseTaskFiles(row.files),
63
77
  createdAt: new Date(row.created_at),
64
78
  updatedAt: new Date(row.updated_at),
65
79
  };
@@ -99,6 +113,7 @@ export class PostgreSQLTaskStore implements TaskStore {
99
113
  this.migrationManager.register(createTasksTable);
100
114
  this.migrationManager.register(addTaskFieldsMigration);
101
115
  this.migrationManager.register(addTaskProjectFieldsMigration);
116
+ this.migrationManager.register(addFilesToTasks);
102
117
 
103
118
  if (options.autoMigrate !== false) {
104
119
  this.initialize().catch((error) => {
@@ -137,8 +152,8 @@ export class PostgreSQLTaskStore implements TaskStore {
137
152
  const now = new Date().toISOString();
138
153
 
139
154
  await this.pool.query(
140
- `INSERT INTO lattice_tasks (id, tenant_id, owner_type, owner_id, title, description, status, priority, due_date, metadata, parent_id, source_id, context, require_review, dependencies, result, failure_reason, workspace_id, project_id, created_at, updated_at)
141
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21)`,
155
+ `INSERT INTO lattice_tasks (id, tenant_id, owner_type, owner_id, title, description, status, priority, due_date, metadata, parent_id, source_id, context, require_review, dependencies, result, failure_reason, workspace_id, project_id, files, created_at, updated_at)
156
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22)`,
142
157
  [
143
158
  id,
144
159
  params.tenantId,
@@ -159,6 +174,7 @@ export class PostgreSQLTaskStore implements TaskStore {
159
174
  params.failureReason ?? null,
160
175
  params.workspaceId || null,
161
176
  params.projectId || null,
177
+ params.files ? JSON.stringify(params.files) : null,
162
178
  now,
163
179
  now,
164
180
  ],
@@ -276,6 +292,10 @@ export class PostgreSQLTaskStore implements TaskStore {
276
292
  setClauses.push(`metadata = $${paramIndex++}`);
277
293
  params.push(JSON.stringify(updates.metadata));
278
294
  }
295
+ if (updates.files !== undefined) {
296
+ setClauses.push(`files = $${paramIndex++}`);
297
+ params.push(JSON.stringify(updates.files));
298
+ }
279
299
  if (updates.parentId !== undefined) {
280
300
  setClauses.push(`parent_id = $${paramIndex++}`);
281
301
  params.push(updates.parentId);