@mastra/pg 1.27.0-alpha.0 → 1.27.0-alpha.2

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 (40) hide show
  1. package/dist/docs/SKILL.md +1 -1
  2. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  3. package/dist/docs/references/reference-memory-memory-class.md +2 -0
  4. package/dist/docs/references/reference-storage-retention.md +9 -7
  5. package/dist/index.cjs +296 -228
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.js +296 -228
  8. package/dist/index.js.map +1 -1
  9. package/dist/storage/db/index.d.ts.map +1 -1
  10. package/dist/storage/db/sanitize-json.d.ts +2 -10
  11. package/dist/storage/db/sanitize-json.d.ts.map +1 -1
  12. package/dist/storage/domains/agents/index.d.ts.map +1 -1
  13. package/dist/storage/domains/background-tasks/index.d.ts.map +1 -1
  14. package/dist/storage/domains/channels/index.d.ts.map +1 -1
  15. package/dist/storage/domains/datasets/index.d.ts.map +1 -1
  16. package/dist/storage/domains/experiments/index.d.ts.map +1 -1
  17. package/dist/storage/domains/knowledge/index.d.ts.map +1 -1
  18. package/dist/storage/domains/mcp-clients/index.d.ts.map +1 -1
  19. package/dist/storage/domains/mcp-servers/index.d.ts.map +1 -1
  20. package/dist/storage/domains/memory/index.d.ts.map +1 -1
  21. package/dist/storage/domains/notifications/index.d.ts.map +1 -1
  22. package/dist/storage/domains/observability/index.d.ts.map +1 -1
  23. package/dist/storage/domains/observability/v-next/discovery.d.ts.map +1 -1
  24. package/dist/storage/domains/observability/v-next/index.d.ts +1 -1
  25. package/dist/storage/domains/observability/v-next/index.d.ts.map +1 -1
  26. package/dist/storage/domains/observability/v-next/metrics.d.ts.map +1 -1
  27. package/dist/storage/domains/observability/v-next/scores.d.ts.map +1 -1
  28. package/dist/storage/domains/observability/v-next/trace-query.d.ts.map +1 -1
  29. package/dist/storage/domains/observability/v-next/traces.d.ts.map +1 -1
  30. package/dist/storage/domains/prompt-blocks/index.d.ts.map +1 -1
  31. package/dist/storage/domains/schedules/index.d.ts.map +1 -1
  32. package/dist/storage/domains/scorer-definitions/index.d.ts.map +1 -1
  33. package/dist/storage/domains/scores/index.d.ts.map +1 -1
  34. package/dist/storage/domains/skills/index.d.ts.map +1 -1
  35. package/dist/storage/domains/thread-state/index.d.ts.map +1 -1
  36. package/dist/storage/domains/workflows/index.d.ts +0 -2
  37. package/dist/storage/domains/workflows/index.d.ts.map +1 -1
  38. package/dist/storage/domains/workspaces/index.d.ts.map +1 -1
  39. package/dist/storage/factory-storage.d.ts.map +1 -1
  40. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -15,6 +15,7 @@ import { MessageList } from "@mastra/core/agent";
15
15
  import { coreFeatures } from "@mastra/core/features";
16
16
  import { saveScorePayloadSchema } from "@mastra/core/evals";
17
17
  import { skillSnapshotFieldValuesEqual } from "@mastra/core/storage/domains/skills";
18
+ import { isDeepStrictEqual } from "util";
18
19
  //#region src/shared/config.ts
19
20
  /**
20
21
  * Type guard for pre-configured pg.Pool config
@@ -2408,6 +2409,29 @@ function isDuplicateSchemaError(error) {
2408
2409
  return /schema .* already exists/i.test(message);
2409
2410
  }
2410
2411
  //#endregion
2412
+ //#region src/storage/db/sanitize-json.ts
2413
+ const repair = (value) => value.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "�").replaceAll("\0", "");
2414
+ function repairJson(value) {
2415
+ if (typeof value === "string") return repair(value);
2416
+ if (Array.isArray(value)) return value.map(repairJson);
2417
+ if (value && typeof value === "object") {
2418
+ const repaired = Object.create(null);
2419
+ for (const [key, entry] of Object.entries(value)) {
2420
+ const repairedKey = repair(key);
2421
+ if (Object.hasOwn(repaired, repairedKey)) throw new Error(`JSON keys collide after PostgreSQL normalization: ${repairedKey}`);
2422
+ repaired[repairedKey] = repairJson(entry);
2423
+ }
2424
+ return repaired;
2425
+ }
2426
+ return value;
2427
+ }
2428
+ /** Serialize JSON values without emitting Unicode sequences PostgreSQL rejects. */
2429
+ function toPgJson(value) {
2430
+ const json = JSON.stringify(value);
2431
+ if (json === void 0 || !/\\u(?:0000|[dD][89a-fA-F][0-9a-fA-F]{2})/.test(json)) return json;
2432
+ return JSON.stringify(repairJson(JSON.parse(json)));
2433
+ }
2434
+ //#endregion
2411
2435
  //#region src/storage/db/schema-snapshot.ts
2412
2436
  /**
2413
2437
  * Returns the snapshot currently installed on `client`, but only when it was
@@ -2932,7 +2956,7 @@ var PgDB = class extends MastraBase {
2932
2956
  */
2933
2957
  prepareValuesForInsert(record, tableName) {
2934
2958
  return Object.entries(record).map(([key, value]) => {
2935
- if ((TABLE_SCHEMAS[tableName]?.[key])?.type === "jsonb" && value !== null && value !== void 0) return JSON.stringify(value);
2959
+ if ((TABLE_SCHEMAS[tableName]?.[key])?.type === "jsonb" && value !== null && value !== void 0) return toPgJson(value);
2936
2960
  return value;
2937
2961
  });
2938
2962
  }
@@ -2950,8 +2974,8 @@ var PgDB = class extends MastraBase {
2950
2974
  prepareValue(value, columnName, tableName) {
2951
2975
  if (value === null || value === void 0) return value;
2952
2976
  if (value instanceof Date) return value.toISOString();
2953
- if ((TABLE_SCHEMAS[tableName]?.[columnName])?.type === "jsonb") return JSON.stringify(value);
2954
- if (typeof value === "object") return JSON.stringify(value);
2977
+ if ((TABLE_SCHEMAS[tableName]?.[columnName])?.type === "jsonb") return toPgJson(value);
2978
+ if (typeof value === "object") return toPgJson(value);
2955
2979
  return value;
2956
2980
  }
2957
2981
  async setupSchema() {
@@ -4205,7 +4229,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4205
4229
  "published",
4206
4230
  versionId,
4207
4231
  row.ownerId ?? row.authorId ?? null,
4208
- row.metadata ? JSON.stringify(row.metadata) : null,
4232
+ row.metadata ? toPgJson(row.metadata) : null,
4209
4233
  row.createdAt ?? now,
4210
4234
  row.updatedAt ?? now
4211
4235
  ]);
@@ -4221,17 +4245,17 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4221
4245
  row.name ?? agentId,
4222
4246
  row.description ?? null,
4223
4247
  this.serializeInstructions(row.instructions ?? ""),
4224
- row.model ? JSON.stringify(row.model) : "{}",
4225
- row.tools ? JSON.stringify(row.tools) : null,
4226
- row.defaultOptions ? JSON.stringify(row.defaultOptions) : null,
4227
- row.workflows ? JSON.stringify(row.workflows) : null,
4228
- row.agents ? JSON.stringify(row.agents) : null,
4229
- row.integrationTools ? JSON.stringify(row.integrationTools) : null,
4230
- row.toolProviders ? JSON.stringify(row.toolProviders) : null,
4231
- row.inputProcessors ? JSON.stringify(row.inputProcessors) : null,
4232
- row.outputProcessors ? JSON.stringify(row.outputProcessors) : null,
4233
- row.memory ? JSON.stringify(row.memory) : null,
4234
- row.scorers ? JSON.stringify(row.scorers) : null,
4248
+ row.model ? toPgJson(row.model) : "{}",
4249
+ row.tools ? toPgJson(row.tools) : null,
4250
+ row.defaultOptions ? toPgJson(row.defaultOptions) : null,
4251
+ row.workflows ? toPgJson(row.workflows) : null,
4252
+ row.agents ? toPgJson(row.agents) : null,
4253
+ row.integrationTools ? toPgJson(row.integrationTools) : null,
4254
+ row.toolProviders ? toPgJson(row.toolProviders) : null,
4255
+ row.inputProcessors ? toPgJson(row.inputProcessors) : null,
4256
+ row.outputProcessors ? toPgJson(row.outputProcessors) : null,
4257
+ row.memory ? toPgJson(row.memory) : null,
4258
+ row.scorers ? toPgJson(row.scorers) : null,
4235
4259
  null,
4236
4260
  "Migrated from legacy schema",
4237
4261
  row.createdAt ?? now
@@ -4281,7 +4305,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4281
4305
  for (const toolKey of toolsArray) toolsObject[toolKey] = {};
4282
4306
  await this.#db.client.none(`UPDATE ${fullVersionsTableName}
4283
4307
  SET tools = $1::jsonb
4284
- WHERE id = $2`, [JSON.stringify(toolsObject), record.id]);
4308
+ WHERE id = $2`, [toPgJson(toolsObject), record.id]);
4285
4309
  }
4286
4310
  this.logger?.info?.(`Migrated ${recordsWithArrayTools.length} agent version(s) tools from array to object format`);
4287
4311
  } catch (error) {
@@ -4378,6 +4402,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4378
4402
  const now = /* @__PURE__ */ new Date();
4379
4403
  const nowIso = now.toISOString();
4380
4404
  const visibility = agent.visibility ?? (agent.authorId ? "private" : null);
4405
+ const metadataJson = agent.metadata ? toPgJson(agent.metadata) : null;
4381
4406
  await this.#db.client.none(`INSERT INTO ${agentsTable} (
4382
4407
  id, status, "authorId", visibility, metadata, "favoriteCount",
4383
4408
  "activeVersionId",
@@ -4387,7 +4412,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4387
4412
  "draft",
4388
4413
  agent.authorId ?? null,
4389
4414
  visibility,
4390
- agent.metadata ? JSON.stringify(agent.metadata) : null,
4415
+ metadataJson,
4391
4416
  0,
4392
4417
  null,
4393
4418
  nowIso,
@@ -4411,7 +4436,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4411
4436
  activeVersionId: void 0,
4412
4437
  authorId: agent.authorId,
4413
4438
  visibility: visibility ?? void 0,
4414
- metadata: agent.metadata,
4439
+ metadata: metadataJson ? JSON.parse(metadataJson) : agent.metadata,
4415
4440
  favoriteCount: 0,
4416
4441
  createdAt: now,
4417
4442
  updatedAt: now
@@ -4469,7 +4494,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4469
4494
  }
4470
4495
  if (metadata !== void 0) {
4471
4496
  setClauses.push(`metadata = $${paramIndex++}`);
4472
- values.push(JSON.stringify(metadata));
4497
+ values.push(toPgJson(metadata));
4473
4498
  }
4474
4499
  const now = (/* @__PURE__ */ new Date()).toISOString();
4475
4500
  setClauses.push(`"updatedAt" = $${paramIndex++}`);
@@ -4563,7 +4588,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4563
4588
  }
4564
4589
  if (metadata && Object.keys(metadata).length > 0) {
4565
4590
  conditions.push(`a.metadata @> $${paramIdx++}::jsonb`);
4566
- queryParams.push(JSON.stringify(metadata));
4591
+ queryParams.push(toPgJson(metadata));
4567
4592
  }
4568
4593
  if (entityIds && entityIds.length > 0) {
4569
4594
  const placeholders = entityIds.map(() => `$${paramIdx++}`).join(", ");
@@ -4629,9 +4654,8 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4629
4654
  indexName: TABLE_AGENT_VERSIONS,
4630
4655
  schemaName: getSchemaName$5(this.#schema)
4631
4656
  });
4632
- const now = /* @__PURE__ */ new Date();
4633
- const nowIso = now.toISOString();
4634
- await this.#db.client.none(`INSERT INTO ${tableName} (
4657
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
4658
+ const row = await this.#db.client.one(`INSERT INTO ${tableName} (
4635
4659
  id, "agentId", "versionNumber",
4636
4660
  name, description, instructions, model, tools,
4637
4661
  "defaultOptions", workflows, agents, "integrationTools", "toolProviders",
@@ -4640,40 +4664,37 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4640
4664
  durable, browser,
4641
4665
  "changedFields", "changeMessage",
4642
4666
  "createdAt", "createdAtZ"
4643
- ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28)`, [
4667
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28) RETURNING *`, [
4644
4668
  input.id,
4645
4669
  input.agentId,
4646
4670
  input.versionNumber,
4647
4671
  input.name,
4648
4672
  input.description ?? null,
4649
4673
  this.serializeInstructions(input.instructions),
4650
- JSON.stringify(input.model),
4651
- input.tools ? JSON.stringify(input.tools) : null,
4652
- input.defaultOptions ? JSON.stringify(input.defaultOptions) : null,
4653
- input.workflows ? JSON.stringify(input.workflows) : null,
4654
- input.agents ? JSON.stringify(input.agents) : null,
4655
- input.integrationTools ? JSON.stringify(input.integrationTools) : null,
4656
- input.toolProviders ? JSON.stringify(input.toolProviders) : null,
4657
- input.inputProcessors ? JSON.stringify(input.inputProcessors) : null,
4658
- input.outputProcessors ? JSON.stringify(input.outputProcessors) : null,
4659
- input.memory ? JSON.stringify(input.memory) : null,
4660
- input.scorers ? JSON.stringify(input.scorers) : null,
4661
- input.mcpClients ? JSON.stringify(input.mcpClients) : null,
4662
- input.requestContextSchema ? JSON.stringify(input.requestContextSchema) : null,
4663
- input.workspace ? JSON.stringify(input.workspace) : null,
4664
- input.skills ? JSON.stringify(input.skills) : null,
4674
+ toPgJson(input.model),
4675
+ input.tools ? toPgJson(input.tools) : null,
4676
+ input.defaultOptions ? toPgJson(input.defaultOptions) : null,
4677
+ input.workflows ? toPgJson(input.workflows) : null,
4678
+ input.agents ? toPgJson(input.agents) : null,
4679
+ input.integrationTools ? toPgJson(input.integrationTools) : null,
4680
+ input.toolProviders ? toPgJson(input.toolProviders) : null,
4681
+ input.inputProcessors ? toPgJson(input.inputProcessors) : null,
4682
+ input.outputProcessors ? toPgJson(input.outputProcessors) : null,
4683
+ input.memory ? toPgJson(input.memory) : null,
4684
+ input.scorers ? toPgJson(input.scorers) : null,
4685
+ input.mcpClients ? toPgJson(input.mcpClients) : null,
4686
+ input.requestContextSchema ? toPgJson(input.requestContextSchema) : null,
4687
+ input.workspace ? toPgJson(input.workspace) : null,
4688
+ input.skills ? toPgJson(input.skills) : null,
4665
4689
  input.skillsFormat ?? null,
4666
- input.durable !== void 0 ? JSON.stringify(input.durable) : null,
4667
- input.browser ? JSON.stringify(input.browser) : null,
4668
- input.changedFields ? JSON.stringify(input.changedFields) : null,
4690
+ input.durable !== void 0 ? toPgJson(input.durable) : null,
4691
+ input.browser ? toPgJson(input.browser) : null,
4692
+ input.changedFields ? toPgJson(input.changedFields) : null,
4669
4693
  input.changeMessage ?? null,
4670
4694
  nowIso,
4671
4695
  nowIso
4672
4696
  ]);
4673
- return {
4674
- ...input,
4675
- createdAt: now
4676
- };
4697
+ return this.parseVersionRow(row);
4677
4698
  } catch (error) {
4678
4699
  if (error instanceof MastraError) throw error;
4679
4700
  throw new MastraError({
@@ -4957,7 +4978,7 @@ function getTableName$4(schemaName) {
4957
4978
  return schemaName ? `${schemaName}.${quoted}` : quoted;
4958
4979
  }
4959
4980
  function serializeJson(v) {
4960
- if (typeof v === "object" && v != null) return JSON.stringify(v);
4981
+ if (typeof v === "object" && v != null) return toPgJson(v);
4961
4982
  return v ?? null;
4962
4983
  }
4963
4984
  function parseJson$2(v) {
@@ -5536,7 +5557,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5536
5557
  installation.agentId,
5537
5558
  installation.status,
5538
5559
  installation.webhookId ?? null,
5539
- JSON.stringify(installation.data),
5560
+ toPgJson(installation.data),
5540
5561
  installation.configHash ?? null,
5541
5562
  installation.error ?? null,
5542
5563
  createdAt,
@@ -5596,7 +5617,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5596
5617
  "updatedAt" = EXCLUDED."updatedAt",
5597
5618
  "updatedAtZ" = EXCLUDED."updatedAtZ"`, [
5598
5619
  config.platform,
5599
- JSON.stringify(config.data),
5620
+ toPgJson(config.data),
5600
5621
  now,
5601
5622
  now
5602
5623
  ]);
@@ -5640,8 +5661,21 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5640
5661
  //#region src/storage/domains/datasets/index.ts
5641
5662
  /** Serialize a value for a jsonb column. Returns null for null/undefined. */
5642
5663
  function jsonbArg(value) {
5643
- return value === void 0 || value === null ? null : JSON.stringify(value);
5664
+ return value === void 0 || value === null ? null : toPgJson(value);
5665
+ }
5666
+ /** Preserve JSON null as data, rather than converting it to an absent SQL value. */
5667
+ function jsonDataArg(value) {
5668
+ return value === void 0 ? null : JSON.stringify(value);
5644
5669
  }
5670
+ const ITEM_SELECT_COLUMNS = [
5671
+ ...Object.keys(DATASET_ITEMS_SCHEMA),
5672
+ "createdAtZ",
5673
+ "updatedAtZ"
5674
+ ].map((column) => [
5675
+ "input",
5676
+ "groundTruth",
5677
+ "expectedTrajectory"
5678
+ ].includes(column) ? `"${column}"::text AS "${column}"` : `"${column}"`).join(", ");
5645
5679
  function parseStoredJSON(value) {
5646
5680
  if (typeof value === "string") try {
5647
5681
  return JSON.parse(value);
@@ -5816,9 +5850,9 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5816
5850
  groundTruthSchema: row.groundTruthSchema ? safelyParseJSON(row.groundTruthSchema) : void 0,
5817
5851
  requestContextSchema: row.requestContextSchema ? safelyParseJSON(row.requestContextSchema) : void 0,
5818
5852
  tags: row.tags ? safelyParseJSON(row.tags) : void 0,
5819
- targetType: row.targetType || null,
5820
- targetIds: row.targetIds || null,
5821
- scorerIds: row.scorerIds || null,
5853
+ targetType: row.targetType || void 0,
5854
+ targetIds: row.targetIds ?? void 0,
5855
+ scorerIds: row.scorerIds ?? void 0,
5822
5856
  organizationId: row.organizationId ?? null,
5823
5857
  projectId: row.projectId ?? null,
5824
5858
  candidateKey: row.candidateKey ?? null,
@@ -5920,9 +5954,9 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5920
5954
  inputSchema: input.inputSchema ?? void 0,
5921
5955
  groundTruthSchema: input.groundTruthSchema ?? void 0,
5922
5956
  requestContextSchema: input.requestContextSchema ?? void 0,
5923
- targetType: input.targetType ?? null,
5924
- targetIds: input.targetIds ?? null,
5925
- scorerIds: input.scorerIds ?? null,
5957
+ targetType: input.targetType ?? void 0,
5958
+ targetIds: input.targetIds ?? void 0,
5959
+ scorerIds: input.scorerIds ?? void 0,
5926
5960
  organizationId: input.organizationId ?? null,
5927
5961
  projectId: input.projectId ?? null,
5928
5962
  candidateKey: input.candidateKey ?? null,
@@ -6008,23 +6042,23 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6008
6042
  }
6009
6043
  if (args.metadata !== void 0) {
6010
6044
  setClauses.push(`"metadata" = $${paramIndex++}`);
6011
- values.push(JSON.stringify(args.metadata));
6045
+ values.push(toPgJson(args.metadata));
6012
6046
  }
6013
6047
  if (args.inputSchema !== void 0) {
6014
6048
  setClauses.push(`"inputSchema" = $${paramIndex++}`);
6015
- values.push(args.inputSchema === null ? null : JSON.stringify(args.inputSchema));
6049
+ values.push(args.inputSchema === null ? null : toPgJson(args.inputSchema));
6016
6050
  }
6017
6051
  if (args.groundTruthSchema !== void 0) {
6018
6052
  setClauses.push(`"groundTruthSchema" = $${paramIndex++}`);
6019
- values.push(args.groundTruthSchema === null ? null : JSON.stringify(args.groundTruthSchema));
6053
+ values.push(args.groundTruthSchema === null ? null : toPgJson(args.groundTruthSchema));
6020
6054
  }
6021
6055
  if (args.requestContextSchema !== void 0) {
6022
6056
  setClauses.push(`"requestContextSchema" = $${paramIndex++}`);
6023
- values.push(args.requestContextSchema === null ? null : JSON.stringify(args.requestContextSchema));
6057
+ values.push(args.requestContextSchema === null ? null : toPgJson(args.requestContextSchema));
6024
6058
  }
6025
6059
  if (args.tags !== void 0) {
6026
6060
  setClauses.push(`"tags" = $${paramIndex++}`);
6027
- values.push(args.tags === null ? null : JSON.stringify(args.tags));
6061
+ values.push(args.tags === null ? null : toPgJson(args.tags));
6028
6062
  }
6029
6063
  if (args.targetType !== void 0) {
6030
6064
  setClauses.push(`"targetType" = $${paramIndex++}`);
@@ -6032,11 +6066,11 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6032
6066
  }
6033
6067
  if (args.targetIds !== void 0) {
6034
6068
  setClauses.push(`"targetIds" = $${paramIndex++}`);
6035
- values.push(args.targetIds === null ? null : JSON.stringify(args.targetIds));
6069
+ values.push(args.targetIds === null ? null : toPgJson(args.targetIds));
6036
6070
  }
6037
6071
  if (args.scorerIds !== void 0) {
6038
6072
  setClauses.push(`"scorerIds" = $${paramIndex++}`);
6039
- values.push(args.scorerIds === null ? null : JSON.stringify(args.scorerIds));
6073
+ values.push(args.scorerIds === null ? null : toPgJson(args.scorerIds));
6040
6074
  }
6041
6075
  values.push(args.id);
6042
6076
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE "id" = $${paramIndex}`, values);
@@ -6049,9 +6083,9 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6049
6083
  groundTruthSchema: (args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema) ?? void 0,
6050
6084
  requestContextSchema: (args.requestContextSchema !== void 0 ? args.requestContextSchema : existing.requestContextSchema) ?? void 0,
6051
6085
  tags: (args.tags !== void 0 ? args.tags : existing.tags) ?? void 0,
6052
- targetType: (args.targetType !== void 0 ? args.targetType : existing.targetType) ?? null,
6053
- targetIds: (args.targetIds !== void 0 ? args.targetIds : existing.targetIds) ?? null,
6054
- scorerIds: (args.scorerIds !== void 0 ? args.scorerIds : existing.scorerIds) ?? null,
6086
+ targetType: (args.targetType !== void 0 ? args.targetType : existing.targetType) ?? void 0,
6087
+ targetIds: (args.targetIds !== void 0 ? args.targetIds : existing.targetIds) ?? void 0,
6088
+ scorerIds: (args.scorerIds !== void 0 ? args.scorerIds : existing.scorerIds) ?? void 0,
6055
6089
  organizationId: existing.organizationId ?? null,
6056
6090
  projectId: existing.projectId ?? null,
6057
6091
  candidateKey: existing.candidateKey ?? null,
@@ -6229,8 +6263,8 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6229
6263
  parentOrganizationId,
6230
6264
  parentProjectId,
6231
6265
  JSON.stringify(args.input),
6232
- jsonbArg(args.groundTruth),
6233
- jsonbArg(args.expectedTrajectory),
6266
+ jsonDataArg(args.groundTruth),
6267
+ jsonDataArg(args.expectedTrajectory),
6234
6268
  jsonbArg(args.toolMocks),
6235
6269
  args.unmockedToolPolicy ?? null,
6236
6270
  jsonbArg(args.scorerIds),
@@ -6346,8 +6380,8 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6346
6380
  parentOrganizationId,
6347
6381
  parentProjectId,
6348
6382
  JSON.stringify(mergedInput),
6349
- jsonbArg(mergedGroundTruth),
6350
- jsonbArg(mergedExpectedTrajectory),
6383
+ jsonDataArg(mergedGroundTruth),
6384
+ jsonDataArg(mergedExpectedTrajectory),
6351
6385
  jsonbArg(mergedToolMocks),
6352
6386
  mergedUnmockedToolPolicy ?? null,
6353
6387
  jsonbArg(mergedScorerIds),
@@ -6436,8 +6470,8 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6436
6470
  parentOrganizationId,
6437
6471
  parentProjectId,
6438
6472
  JSON.stringify(existing.input),
6439
- jsonbArg(existing.groundTruth),
6440
- jsonbArg(existing.expectedTrajectory),
6473
+ jsonDataArg(existing.groundTruth),
6474
+ jsonDataArg(existing.expectedTrajectory),
6441
6475
  jsonbArg(existing.toolMocks),
6442
6476
  existing.unmockedToolPolicy ?? null,
6443
6477
  jsonbArg(existing.scorerIds),
@@ -6484,10 +6518,9 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6484
6518
  indexName: TABLE_EXPERIMENT_RESULTS,
6485
6519
  schemaName: getSchemaName$5(this.#schema)
6486
6520
  });
6487
- const purgedAt = (/* @__PURE__ */ new Date()).toISOString();
6488
- const purgedMetadata = JSON.stringify({
6521
+ const purgedMetadata = toPgJson({
6489
6522
  __purged: true,
6490
- purgedAt
6523
+ purgedAt: (/* @__PURE__ */ new Date()).toISOString()
6491
6524
  });
6492
6525
  await this.#db.client.tx(async (t) => {
6493
6526
  if (!await t.oneOrNone(`SELECT "id" FROM ${datasetsTable} WHERE "id" = $1 FOR UPDATE`, [datasetId])) return;
@@ -6537,7 +6570,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6537
6570
  details: { datasetId: input.datasetId }
6538
6571
  });
6539
6572
  const externalIds = [...new Set(input.items.flatMap((item) => item.externalId ? [item.externalId] : []))];
6540
- const historyRows = externalIds.length ? await t.manyOrNone(`SELECT * FROM ${itemsTable} WHERE "datasetId" = $1 AND "externalId" = ANY($2::text[]) ORDER BY "datasetVersion"`, [input.datasetId, externalIds]) : [];
6573
+ const historyRows = externalIds.length ? await t.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${itemsTable} WHERE "datasetId" = $1 AND "externalId" = ANY($2::text[]) ORDER BY "datasetVersion"`, [input.datasetId, externalIds]) : [];
6541
6574
  const plan = this.planDatasetItemBatch(input.items, historyRows.map((row) => this.transformItemRowFull(row)), () => crypto.randomUUID());
6542
6575
  const resolved = new Map([...plan.existingCurrentItems].map(([id, row]) => [id, this.datasetItemFromRow(row)]));
6543
6576
  if (plan.inserts.length > 0) {
@@ -6554,8 +6587,8 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6554
6587
  dataset.organizationId ?? null,
6555
6588
  dataset.projectId ?? null,
6556
6589
  JSON.stringify(item.input),
6557
- jsonbArg(item.groundTruth),
6558
- jsonbArg(item.expectedTrajectory),
6590
+ jsonDataArg(item.groundTruth),
6591
+ jsonDataArg(item.expectedTrajectory),
6559
6592
  jsonbArg(item.toolMocks),
6560
6593
  item.unmockedToolPolicy ?? null,
6561
6594
  jsonbArg(item.scorerIds),
@@ -6632,7 +6665,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6632
6665
  category: ErrorCategory.USER,
6633
6666
  details: { datasetId: input.datasetId }
6634
6667
  });
6635
- const currentItems = (await t.manyOrNone(`SELECT * FROM ${itemsTable} WHERE "id" = ANY($1::text[]) AND "datasetId" = $2 AND "validTo" IS NULL AND "isDeleted" = false`, [input.itemIds, input.datasetId])).map((row) => this.transformItemRow(row));
6668
+ const currentItems = (await t.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${itemsTable} WHERE "id" = ANY($1::text[]) AND "datasetId" = $2 AND "validTo" IS NULL AND "isDeleted" = false`, [input.itemIds, input.datasetId])).map((row) => this.transformItemRow(row));
6636
6669
  if (currentItems.length === 0) return;
6637
6670
  const parentOrganizationId = dataset.organizationId ?? null;
6638
6671
  const parentProjectId = dataset.projectId ?? null;
@@ -6647,8 +6680,8 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6647
6680
  parentOrganizationId,
6648
6681
  parentProjectId,
6649
6682
  JSON.stringify(item.input),
6650
- jsonbArg(item.groundTruth),
6651
- jsonbArg(item.expectedTrajectory),
6683
+ jsonDataArg(item.groundTruth),
6684
+ jsonDataArg(item.expectedTrajectory),
6652
6685
  jsonbArg(item.toolMocks),
6653
6686
  item.unmockedToolPolicy ?? null,
6654
6687
  jsonbArg(item.scorerIds),
@@ -6688,8 +6721,8 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6688
6721
  schemaName: getSchemaName$5(this.#schema)
6689
6722
  });
6690
6723
  let result;
6691
- if (args.datasetVersion !== void 0) result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $2) AND "isDeleted" = false ORDER BY "datasetVersion" DESC LIMIT 1`, [args.id, args.datasetVersion]);
6692
- else result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`, [args.id]);
6724
+ if (args.datasetVersion !== void 0) result = await client.oneOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $2) AND "isDeleted" = false ORDER BY "datasetVersion" DESC LIMIT 1`, [args.id, args.datasetVersion]);
6725
+ else result = await client.oneOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`, [args.id]);
6693
6726
  return result ? this.transformItemRow(result) : null;
6694
6727
  } catch (error) {
6695
6728
  throw new MastraError({
@@ -6705,7 +6738,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6705
6738
  indexName: TABLE_DATASET_ITEMS,
6706
6739
  schemaName: getSchemaName$5(this.#schema)
6707
6740
  });
6708
- return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC, "id" ASC`, [
6741
+ return (await this.#db.readClient.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC, "id" ASC`, [
6709
6742
  datasetId,
6710
6743
  version,
6711
6744
  version
@@ -6724,7 +6757,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6724
6757
  indexName: TABLE_DATASET_ITEMS,
6725
6758
  schemaName: getSchemaName$5(this.#schema)
6726
6759
  });
6727
- return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6760
+ return (await this.#db.readClient.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6728
6761
  } catch (error) {
6729
6762
  throw new MastraError({
6730
6763
  id: createStorageErrorId("PG", "GET_ITEM_HISTORY", "FAILED"),
@@ -6796,7 +6829,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6796
6829
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
6797
6830
  const limitValue = perPageInput === false ? total : perPage;
6798
6831
  return {
6799
- items: (await client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${orderBy.field}" ${orderBy.direction}, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6832
+ items: (await client.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} ${whereClause} ORDER BY "${orderBy.field}" ${orderBy.direction}, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6800
6833
  ...queryParams,
6801
6834
  limitValue,
6802
6835
  offset
@@ -7287,7 +7320,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7287
7320
  }
7288
7321
  if (input.metadata !== void 0) {
7289
7322
  setClauses.push(`"metadata" = $${paramIndex++}`);
7290
- values.push(JSON.stringify(input.metadata));
7323
+ values.push(toPgJson(input.metadata));
7291
7324
  }
7292
7325
  if (input.status !== void 0) {
7293
7326
  setClauses.push(`"status" = $${paramIndex++}`);
@@ -7518,19 +7551,19 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7518
7551
  input.itemDatasetVersion ?? null,
7519
7552
  input.organizationId ?? null,
7520
7553
  input.projectId ?? null,
7521
- JSON.stringify(purgeMetadata ? null : input.input),
7522
- purgeMetadata || input.output == null ? null : JSON.stringify(input.output),
7523
- purgeMetadata || input.groundTruth == null ? null : JSON.stringify(input.groundTruth),
7524
- JSON.stringify(purgeMetadata ?? input.metadata ?? null),
7525
- purgeMetadata || input.error == null ? null : JSON.stringify(input.error),
7554
+ toPgJson(purgeMetadata ? null : input.input),
7555
+ purgeMetadata || input.output == null ? null : toPgJson(input.output),
7556
+ purgeMetadata || input.groundTruth == null ? null : toPgJson(input.groundTruth),
7557
+ toPgJson(purgeMetadata ?? input.metadata ?? null),
7558
+ purgeMetadata || input.error == null ? null : toPgJson(input.error),
7526
7559
  input.startedAt.toISOString(),
7527
7560
  input.completedAt.toISOString(),
7528
7561
  input.retryCount,
7529
7562
  input.attempt ?? 0,
7530
7563
  input.traceId ?? null,
7531
7564
  input.status ?? null,
7532
- purgeMetadata || input.tags == null ? null : JSON.stringify(input.tags),
7533
- purgeMetadata || input.toolMockReport == null ? null : JSON.stringify(input.toolMockReport),
7565
+ purgeMetadata || input.tags == null ? null : toPgJson(input.tags),
7566
+ purgeMetadata || input.toolMockReport == null ? null : toPgJson(input.toolMockReport),
7534
7567
  nowIso
7535
7568
  ]);
7536
7569
  });
@@ -7576,19 +7609,19 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7576
7609
  input.itemDatasetVersion ?? null,
7577
7610
  input.organizationId ?? null,
7578
7611
  input.projectId ?? null,
7579
- JSON.stringify(purgeMetadata ? null : input.input),
7580
- purgeMetadata || input.output == null ? null : JSON.stringify(input.output),
7581
- purgeMetadata || input.groundTruth == null ? null : JSON.stringify(input.groundTruth),
7582
- JSON.stringify(purgeMetadata ?? input.metadata ?? null),
7583
- purgeMetadata || input.error == null ? null : JSON.stringify(input.error),
7612
+ toPgJson(purgeMetadata ? null : input.input),
7613
+ purgeMetadata || input.output == null ? null : toPgJson(input.output),
7614
+ purgeMetadata || input.groundTruth == null ? null : toPgJson(input.groundTruth),
7615
+ toPgJson(purgeMetadata ?? input.metadata ?? null),
7616
+ purgeMetadata || input.error == null ? null : toPgJson(input.error),
7584
7617
  input.startedAt.toISOString(),
7585
7618
  input.completedAt.toISOString(),
7586
7619
  input.retryCount,
7587
7620
  attempt,
7588
7621
  input.traceId ?? null,
7589
7622
  input.status ?? null,
7590
- purgeMetadata || input.tags == null ? null : JSON.stringify(input.tags),
7591
- purgeMetadata || input.toolMockReport == null ? null : JSON.stringify(input.toolMockReport),
7623
+ purgeMetadata || input.tags == null ? null : toPgJson(input.tags),
7624
+ purgeMetadata || input.toolMockReport == null ? null : toPgJson(input.toolMockReport),
7592
7625
  (/* @__PURE__ */ new Date()).toISOString()
7593
7626
  ]);
7594
7627
  }
@@ -7602,19 +7635,19 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7602
7635
  input.itemDatasetVersion ?? null,
7603
7636
  input.organizationId ?? null,
7604
7637
  input.projectId ?? null,
7605
- JSON.stringify(purgeMetadata ? null : input.input),
7606
- purgeMetadata || input.output == null ? null : JSON.stringify(input.output),
7607
- purgeMetadata || input.groundTruth == null ? null : JSON.stringify(input.groundTruth),
7608
- JSON.stringify(purgeMetadata ?? input.metadata ?? null),
7609
- purgeMetadata || input.error == null ? null : JSON.stringify(input.error),
7638
+ toPgJson(purgeMetadata ? null : input.input),
7639
+ purgeMetadata || input.output == null ? null : toPgJson(input.output),
7640
+ purgeMetadata || input.groundTruth == null ? null : toPgJson(input.groundTruth),
7641
+ toPgJson(purgeMetadata ?? input.metadata ?? null),
7642
+ purgeMetadata || input.error == null ? null : toPgJson(input.error),
7610
7643
  input.startedAt.toISOString(),
7611
7644
  input.completedAt.toISOString(),
7612
7645
  input.retryCount,
7613
7646
  attempt,
7614
7647
  input.traceId ?? null,
7615
7648
  input.status ?? null,
7616
- purgeMetadata || input.tags == null ? null : JSON.stringify(input.tags),
7617
- purgeMetadata || input.toolMockReport == null ? null : JSON.stringify(input.toolMockReport)
7649
+ purgeMetadata || input.tags == null ? null : toPgJson(input.tags),
7650
+ purgeMetadata || input.toolMockReport == null ? null : toPgJson(input.toolMockReport)
7618
7651
  ]);
7619
7652
  });
7620
7653
  return this.transformExperimentResultRow(row);
@@ -7654,7 +7687,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7654
7687
  input.status ?? null,
7655
7688
  Boolean(purgeMetadata),
7656
7689
  input.tags !== void 0,
7657
- input.tags === void 0 ? null : JSON.stringify(input.tags),
7690
+ input.tags === void 0 ? null : toPgJson(input.tags),
7658
7691
  input.comment !== void 0,
7659
7692
  input.comment ?? null,
7660
7693
  ...input.experimentId !== void 0 ? [input.experimentId] : []
@@ -7725,7 +7758,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7725
7758
  }
7726
7759
  for (const tag of args.tags ?? []) {
7727
7760
  conditions.push(`"tags" @> $${paramIndex++}::jsonb`);
7728
- queryParams.push(JSON.stringify([tag]));
7761
+ queryParams.push(toPgJson([tag]));
7729
7762
  }
7730
7763
  if (args.filters) {
7731
7764
  const { organizationId, projectId } = args.filters;
@@ -8652,6 +8685,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8652
8685
  return this.#transaction(async (tx) => {
8653
8686
  const parent = await this.#resolveTerminalNode(tx, nodeReferenceId(input.node));
8654
8687
  if (!parent) throw new KnowledgeNotFoundError("node", nodeReferenceId(input.node));
8688
+ const metadataJson = input.metadata ? toPgJson(input.metadata) : null;
8655
8689
  const record = {
8656
8690
  id: input.id ?? createKnowledgeUlid(),
8657
8691
  node: parent.id,
@@ -8675,13 +8709,16 @@ var KnowledgePG = class extends KnowledgeStorage {
8675
8709
  record.capturedAt.toISOString(),
8676
8710
  record.when?.toISOString() ?? null,
8677
8711
  record.maxScope ?? null,
8678
- record.metadata ? JSON.stringify(record.metadata) : null
8712
+ metadataJson
8679
8713
  ]
8680
8714
  });
8681
8715
  await this.#replaceMentions(tx, "record", record.id, record.text, resolutionScope, defaultScope);
8682
8716
  await this.#activity(tx, "record-created", "record", record.id, scope, record.sourceThreadId);
8683
8717
  await this.#outbox(tx, "record", record.id, "upsert", record.id, scope);
8684
- return record;
8718
+ return metadataJson ? {
8719
+ ...record,
8720
+ metadata: JSON.parse(metadataJson)
8721
+ } : record;
8685
8722
  });
8686
8723
  }
8687
8724
  async getKnowledge(input) {
@@ -9250,6 +9287,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9250
9287
  });
9251
9288
  const now = /* @__PURE__ */ new Date();
9252
9289
  const nowIso = now.toISOString();
9290
+ const metadataJson = mcpClient.metadata ? toPgJson(mcpClient.metadata) : null;
9253
9291
  await this.#db.client.none(`INSERT INTO ${tableName} (
9254
9292
  id, status, "activeVersionId", "authorId", metadata,
9255
9293
  "createdAt", "createdAtZ", "updatedAt", "updatedAtZ"
@@ -9258,7 +9296,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9258
9296
  "draft",
9259
9297
  null,
9260
9298
  mcpClient.authorId ?? null,
9261
- mcpClient.metadata ? JSON.stringify(mcpClient.metadata) : null,
9299
+ metadataJson,
9262
9300
  nowIso,
9263
9301
  nowIso,
9264
9302
  nowIso,
@@ -9279,7 +9317,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9279
9317
  status: "draft",
9280
9318
  activeVersionId: void 0,
9281
9319
  authorId: mcpClient.authorId,
9282
- metadata: mcpClient.metadata,
9320
+ metadata: metadataJson ? JSON.parse(metadataJson) : mcpClient.metadata,
9283
9321
  createdAt: now,
9284
9322
  updatedAt: now
9285
9323
  };
@@ -9337,7 +9375,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9337
9375
  ...metadata
9338
9376
  };
9339
9377
  setClauses.push(`metadata = $${paramIndex++}`);
9340
- values.push(JSON.stringify(mergedMetadata));
9378
+ values.push(toPgJson(mergedMetadata));
9341
9379
  }
9342
9380
  const now = (/* @__PURE__ */ new Date()).toISOString();
9343
9381
  setClauses.push(`"updatedAt" = $${paramIndex++}`);
@@ -9410,7 +9448,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9410
9448
  }
9411
9449
  if (metadata && Object.keys(metadata).length > 0) {
9412
9450
  conditions.push(`metadata @> $${paramIdx++}::jsonb`);
9413
- queryParams.push(JSON.stringify(metadata));
9451
+ queryParams.push(toPgJson(metadata));
9414
9452
  }
9415
9453
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
9416
9454
  const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
@@ -9461,6 +9499,8 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9461
9499
  });
9462
9500
  const now = /* @__PURE__ */ new Date();
9463
9501
  const nowIso = now.toISOString();
9502
+ const serversJson = toPgJson(input.servers);
9503
+ const changedFieldsJson = input.changedFields ? toPgJson(input.changedFields) : null;
9464
9504
  await this.#db.client.none(`INSERT INTO ${tableName} (
9465
9505
  id, "mcpClientId", "versionNumber",
9466
9506
  name, description, servers,
@@ -9472,14 +9512,16 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9472
9512
  input.versionNumber,
9473
9513
  input.name,
9474
9514
  input.description ?? null,
9475
- JSON.stringify(input.servers),
9476
- input.changedFields ? JSON.stringify(input.changedFields) : null,
9515
+ serversJson,
9516
+ changedFieldsJson,
9477
9517
  input.changeMessage ?? null,
9478
9518
  nowIso,
9479
9519
  nowIso
9480
9520
  ]);
9481
9521
  return {
9482
9522
  ...input,
9523
+ servers: JSON.parse(serversJson),
9524
+ changedFields: changedFieldsJson ? JSON.parse(changedFieldsJson) : input.changedFields,
9483
9525
  createdAt: now
9484
9526
  };
9485
9527
  } catch (error) {
@@ -9821,7 +9863,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9821
9863
  "draft",
9822
9864
  null,
9823
9865
  mcpServer.authorId ?? null,
9824
- mcpServer.metadata ? JSON.stringify(mcpServer.metadata) : null,
9866
+ mcpServer.metadata ? toPgJson(mcpServer.metadata) : null,
9825
9867
  nowIso,
9826
9868
  nowIso,
9827
9869
  nowIso,
@@ -9900,7 +9942,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9900
9942
  ...metadata
9901
9943
  };
9902
9944
  setClauses.push(`metadata = $${paramIndex++}`);
9903
- values.push(JSON.stringify(mergedMetadata));
9945
+ values.push(toPgJson(mergedMetadata));
9904
9946
  }
9905
9947
  const now = (/* @__PURE__ */ new Date()).toISOString();
9906
9948
  setClauses.push(`"updatedAt" = $${paramIndex++}`);
@@ -9973,7 +10015,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9973
10015
  }
9974
10016
  if (metadata && Object.keys(metadata).length > 0) {
9975
10017
  conditions.push(`metadata @> $${paramIdx++}::jsonb`);
9976
- queryParams.push(JSON.stringify(metadata));
10018
+ queryParams.push(toPgJson(metadata));
9977
10019
  }
9978
10020
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
9979
10021
  const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
@@ -10039,14 +10081,14 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
10039
10081
  input.version,
10040
10082
  input.description ?? null,
10041
10083
  input.instructions ?? null,
10042
- input.repository ? JSON.stringify(input.repository) : null,
10084
+ input.repository ? toPgJson(input.repository) : null,
10043
10085
  input.releaseDate ?? null,
10044
10086
  input.isLatest ?? null,
10045
10087
  input.packageCanonical ?? null,
10046
- input.tools ? JSON.stringify(input.tools) : null,
10047
- input.agents ? JSON.stringify(input.agents) : null,
10048
- input.workflows ? JSON.stringify(input.workflows) : null,
10049
- input.changedFields ? JSON.stringify(input.changedFields) : null,
10088
+ input.tools ? toPgJson(input.tools) : null,
10089
+ input.agents ? toPgJson(input.agents) : null,
10090
+ input.workflows ? toPgJson(input.workflows) : null,
10091
+ input.changedFields ? toPgJson(input.changedFields) : null,
10050
10092
  input.changeMessage ?? null,
10051
10093
  nowIso,
10052
10094
  nowIso
@@ -10781,7 +10823,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10781
10823
  }
10782
10824
  if (filter?.metadata && Object.keys(filter.metadata).length > 0) for (const [key, value] of Object.entries(filter.metadata)) {
10783
10825
  whereClauses.push(`metadata::jsonb @> $${paramIndex}::jsonb`);
10784
- queryParams.push(JSON.stringify({ [key]: value }));
10826
+ queryParams.push(toPgJson({ [key]: value }));
10785
10827
  paramIndex++;
10786
10828
  }
10787
10829
  const baseQuery = `FROM ${tableName} ${whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : ""}`;
@@ -10840,6 +10882,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10840
10882
  });
10841
10883
  const createdAt = toUtcISOString(thread.createdAt);
10842
10884
  const updatedAt = toUtcISOString(thread.updatedAt);
10885
+ const metadataJson = thread.metadata ? toPgJson(thread.metadata) : null;
10843
10886
  await this.#db.client.none(`INSERT INTO ${tableName} (
10844
10887
  id,
10845
10888
  "resourceId",
@@ -10861,13 +10904,16 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10861
10904
  thread.id,
10862
10905
  thread.resourceId,
10863
10906
  thread.title,
10864
- thread.metadata ? JSON.stringify(thread.metadata) : null,
10907
+ metadataJson,
10865
10908
  createdAt,
10866
10909
  createdAt,
10867
10910
  updatedAt,
10868
10911
  updatedAt
10869
10912
  ]);
10870
- return thread;
10913
+ return {
10914
+ ...thread,
10915
+ metadata: metadataJson ? JSON.parse(metadataJson) : thread.metadata
10916
+ };
10871
10917
  } catch (error) {
10872
10918
  throw new MastraError({
10873
10919
  id: createStorageErrorId("PG", "SAVE_THREAD", "FAILED"),
@@ -11683,16 +11729,20 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11683
11729
  async saveResource({ resource }) {
11684
11730
  const createdAt = toUtcISOString(resource.createdAt);
11685
11731
  const updatedAt = toUtcISOString(resource.updatedAt);
11732
+ const metadataJson = toPgJson(resource.metadata);
11686
11733
  await this.#db.insert({
11687
11734
  tableName: TABLE_RESOURCES,
11688
11735
  record: {
11689
11736
  ...resource,
11690
- metadata: JSON.stringify(resource.metadata),
11737
+ metadata: metadataJson,
11691
11738
  createdAt,
11692
11739
  updatedAt
11693
11740
  }
11694
11741
  });
11695
- return resource;
11742
+ return {
11743
+ ...resource,
11744
+ metadata: metadataJson ? JSON.parse(metadataJson) : resource.metadata
11745
+ };
11696
11746
  }
11697
11747
  async updateResource({ resourceId, workingMemory, metadata }) {
11698
11748
  const existingResource = await this.#getResourceById(this.#db.client, resourceId);
@@ -11727,9 +11777,11 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11727
11777
  values.push(workingMemory);
11728
11778
  paramIndex++;
11729
11779
  }
11780
+ let metadataJson;
11730
11781
  if (metadata) {
11782
+ metadataJson = toPgJson(updatedResource.metadata);
11731
11783
  updates.push(`metadata = $${paramIndex}`);
11732
- values.push(JSON.stringify(updatedResource.metadata));
11784
+ values.push(metadataJson);
11733
11785
  paramIndex++;
11734
11786
  }
11735
11787
  const updatedAtStr = updatedResource.updatedAt.toISOString();
@@ -11739,7 +11791,10 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11739
11791
  values.push(updatedAtStr);
11740
11792
  values.push(resourceId);
11741
11793
  await this.#db.client.none(`UPDATE ${tableName} SET ${updates.join(", ")} WHERE id = $${paramIndex}`, values);
11742
- return updatedResource;
11794
+ return metadataJson ? {
11795
+ ...updatedResource,
11796
+ metadata: JSON.parse(metadataJson)
11797
+ } : updatedResource;
11743
11798
  }
11744
11799
  async copyThread(args) {
11745
11800
  const { sourceThreadId, newThreadId: providedThreadId, resourceId, title, metadata, options } = args;
@@ -11824,7 +11879,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11824
11879
  newThread.id,
11825
11880
  newThread.resourceId,
11826
11881
  newThread.title,
11827
- newThread.metadata ? JSON.stringify(newThread.metadata) : null,
11882
+ newThread.metadata ? toPgJson(newThread.metadata) : null,
11828
11883
  nowStr,
11829
11884
  nowStr,
11830
11885
  nowStr,
@@ -12015,7 +12070,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12015
12070
  "",
12016
12071
  null,
12017
12072
  "initial",
12018
- JSON.stringify(input.config),
12073
+ toPgJson(input.config),
12019
12074
  0,
12020
12075
  null,
12021
12076
  null,
@@ -12078,7 +12133,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12078
12133
  record.activeObservations || "",
12079
12134
  null,
12080
12135
  record.originType || "initial",
12081
- record.config ? JSON.stringify(record.config) : null,
12136
+ record.config ? toPgJson(record.config) : null,
12082
12137
  record.generationCount || 0,
12083
12138
  lastObservedAtStr,
12084
12139
  lastObservedAtStr,
@@ -12087,8 +12142,8 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12087
12142
  record.pendingMessageTokens || 0,
12088
12143
  record.totalTokensObserved || 0,
12089
12144
  record.observationTokenCount || 0,
12090
- record.observedMessageIds ? JSON.stringify(record.observedMessageIds) : null,
12091
- record.bufferedObservationChunks ? JSON.stringify(record.bufferedObservationChunks) : null,
12145
+ record.observedMessageIds ? toPgJson(record.observedMessageIds) : null,
12146
+ record.bufferedObservationChunks ? toPgJson(record.bufferedObservationChunks) : null,
12092
12147
  record.bufferedReflection || null,
12093
12148
  record.bufferedReflectionTokens ?? null,
12094
12149
  record.bufferedReflectionInputTokens ?? null,
@@ -12100,7 +12155,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12100
12155
  record.lastBufferedAtTokens || 0,
12101
12156
  lastBufferedAtTimeStr,
12102
12157
  record.observedTimezone || null,
12103
- record.metadata ? JSON.stringify(record.metadata) : null,
12158
+ record.metadata ? toPgJson(record.metadata) : null,
12104
12159
  record.createdAt.toISOString(),
12105
12160
  record.createdAt.toISOString(),
12106
12161
  record.updatedAt.toISOString(),
@@ -12128,7 +12183,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12128
12183
  });
12129
12184
  const lastObservedAtStr = input.lastObservedAt.toISOString();
12130
12185
  const nowStr = now.toISOString();
12131
- const observedMessageIdsJson = input.observedMessageIds ? JSON.stringify(input.observedMessageIds) : null;
12186
+ const observedMessageIdsJson = input.observedMessageIds ? toPgJson(input.observedMessageIds) : null;
12132
12187
  if ((await this.#db.client.query(`UPDATE ${tableName} SET
12133
12188
  "activeObservations" = $1,
12134
12189
  "lastObservedAt" = $2,
@@ -12217,7 +12272,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12217
12272
  input.reflection,
12218
12273
  null,
12219
12274
  "reflection",
12220
- JSON.stringify(record.config),
12275
+ toPgJson(record.config),
12221
12276
  input.currentRecord.generationCount + 1,
12222
12277
  lastObservedAtStr,
12223
12278
  lastObservedAtStr,
@@ -12233,7 +12288,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12233
12288
  0,
12234
12289
  null,
12235
12290
  record.observedTimezone || null,
12236
- record.metadata ? JSON.stringify(record.metadata) : null,
12291
+ record.metadata ? toPgJson(record.metadata) : null,
12237
12292
  nowStr,
12238
12293
  nowStr,
12239
12294
  nowStr,
@@ -12484,7 +12539,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12484
12539
  const merged = this.deepMergeConfig(existing, input.config);
12485
12540
  const nowStr = (/* @__PURE__ */ new Date()).toISOString();
12486
12541
  await this.#db.client.query(`UPDATE ${tableName} SET config = $1, "updatedAt" = $2, "updatedAtZ" = $3 WHERE id = $4`, [
12487
- JSON.stringify(merged),
12542
+ toPgJson(merged),
12488
12543
  nowStr,
12489
12544
  nowStr,
12490
12545
  input.id
@@ -12535,7 +12590,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12535
12590
  "updatedAt" = $4,
12536
12591
  "updatedAtZ" = $5
12537
12592
  WHERE id = $6`, [
12538
- JSON.stringify([newChunk]),
12593
+ toPgJson([newChunk]),
12539
12594
  input.chunk.cycleId,
12540
12595
  lastBufferedAtTime,
12541
12596
  nowStr,
@@ -12650,7 +12705,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
12650
12705
  activatedContent,
12651
12706
  activatedTokens,
12652
12707
  activatedMessageTokens,
12653
- remainingChunks.length > 0 ? JSON.stringify(remainingChunks) : null,
12708
+ remainingChunks.length > 0 ? toPgJson(remainingChunks) : null,
12654
12709
  lastObservedAtStr,
12655
12710
  lastObservedAtStr,
12656
12711
  nowStr,
@@ -13030,7 +13085,7 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
13030
13085
  });
13031
13086
  const setColumns = entries.map(([key], index) => `"${parseSqlIdentifier(key, "column name")}" = $${index + 1}`);
13032
13087
  const values = entries.map(([key, value]) => {
13033
- if (TABLE_SCHEMAS[TABLE_NOTIFICATIONS][key]?.type === "jsonb" && value !== null) return JSON.stringify(value);
13088
+ if (TABLE_SCHEMAS[TABLE_NOTIFICATIONS][key]?.type === "jsonb" && value !== null) return toPgJson(value);
13034
13089
  return value;
13035
13090
  });
13036
13091
  await this.#db.client.none(`UPDATE ${tableName} SET ${setColumns.join(", ")} WHERE "threadId" = $${values.length + 1} AND "id" = $${values.length + 2}`, [
@@ -13751,15 +13806,15 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13751
13806
  }
13752
13807
  if (filters.scope != null) {
13753
13808
  conditions.push(`r."scope" @> $${paramIndex++}`);
13754
- params.push(JSON.stringify(filters.scope));
13809
+ params.push(toPgJson(filters.scope));
13755
13810
  }
13756
13811
  if (filters.metadata != null) {
13757
13812
  conditions.push(`r."metadata" @> $${paramIndex++}`);
13758
- params.push(JSON.stringify(filters.metadata));
13813
+ params.push(toPgJson(filters.metadata));
13759
13814
  }
13760
13815
  if (filters.tags != null && filters.tags.length > 0) {
13761
13816
  conditions.push(`r."tags" @> $${paramIndex++}`);
13762
- params.push(JSON.stringify(filters.tags));
13817
+ params.push(toPgJson(filters.tags));
13763
13818
  }
13764
13819
  if (filters.status !== void 0) switch (filters.status) {
13765
13820
  case TraceStatus.ERROR:
@@ -15068,7 +15123,7 @@ async function upsertCache(client, schema, cacheKey, values) {
15068
15123
  VALUES ($1, NOW(), $2::jsonb)
15069
15124
  ON CONFLICT ("cacheKey") DO UPDATE SET
15070
15125
  "refreshedAt" = EXCLUDED."refreshedAt",
15071
- "values" = EXCLUDED."values"`, [cacheKey, JSON.stringify(values)]);
15126
+ "values" = EXCLUDED."values"`, [cacheKey, toPgJson(values)]);
15072
15127
  }
15073
15128
  /**
15074
15129
  * Time predicate that bounds a discovery refresh to recent events.
@@ -16022,20 +16077,6 @@ const COMPLEX_GROUP_BY_EXCLUDED = /* @__PURE__ */ new Set([
16022
16077
  "requestContext"
16023
16078
  ]);
16024
16079
  //#endregion
16025
- //#region src/storage/db/sanitize-json.ts
16026
- /**
16027
- * Sanitizes JSON string for PostgreSQL jsonb:
16028
- * - Removes problematic Unicode sequences:
16029
- * - \u0000 (null character) - causes error 22P05 "unsupported Unicode escape sequence"
16030
- * - \uD800-\uDFFF (unpaired surrogates) - causes "Unicode low surrogate must follow a high surrogate"
16031
- * - \\uD800 (escaped-backslash + surrogate, e.g. from JS regex literals like [^\ud800-\udfff]):
16032
- * removing just \uXXXX would leave a dangling backslash that creates a new invalid escape (e.g. \-)
16033
- * - Escapes any remaining invalid JSON escape sequences (e.g. \v, \k, \-)
16034
- */
16035
- function sanitizeJsonForPg(jsonString) {
16036
- return jsonString.replace(/\\\\?u(0000|[Dd][89A-Fa-f][0-9A-Fa-f]{2})/g, "").replace(/(^|[^\\])(\\(?!["\\/bfnrtu]))/g, "$1\\\\");
16037
- }
16038
- //#endregion
16039
16080
  //#region src/storage/domains/observability/v-next/sql.ts
16040
16081
  /**
16041
16082
  * SQL helpers for the v-next Postgres observability domain.
@@ -16057,7 +16098,7 @@ function sanitizeJsonForPg(jsonString) {
16057
16098
  */
16058
16099
  function encodeJsonb(value) {
16059
16100
  if (value === null || value === void 0) return null;
16060
- return sanitizeJsonForPg(JSON.stringify(value));
16101
+ return toPgJson(value);
16061
16102
  }
16062
16103
  /**
16063
16104
  * Build a multi-row INSERT with explicit column types and ON CONFLICT DO NOTHING.
@@ -16458,7 +16499,7 @@ function applyMetricFilters(acc, filters) {
16458
16499
  applySingleOrArrayFilter(acc, "costUnit", filters?.costUnit);
16459
16500
  if (filters?.labels) {
16460
16501
  acc.conditions.push(`"labels" @> $${acc.next++}::jsonb`);
16461
- acc.params.push(JSON.stringify(filters.labels));
16502
+ acc.params.push(toPgJson(filters.labels));
16462
16503
  }
16463
16504
  }
16464
16505
  /** Additional WHERE for metric-name restriction (OLAP queries take a `name` array). */
@@ -16971,7 +17012,7 @@ function applyScoreFilters(acc, filters) {
16971
17012
  }
16972
17013
  if (filters?.metadata && Object.keys(filters.metadata).length > 0) for (const [key, value] of Object.entries(filters.metadata)) {
16973
17014
  acc.conditions.push(`"metadata"->($${acc.next++}::text) = $${acc.next++}::jsonb`);
16974
- acc.params.push(key, JSON.stringify(value ?? null));
17015
+ acc.params.push(key, toPgJson(value ?? null));
16975
17016
  }
16976
17017
  }
16977
17018
  /** OLAP queries take an explicit scorerId / scoreSource pair as identity. */
@@ -17237,16 +17278,21 @@ async function getScorePercentiles(client, schema, args) {
17237
17278
  //#endregion
17238
17279
  //#region src/storage/domains/observability/v-next/trace-query.ts
17239
17280
  const TRACE_STATUS_SQL = `CASE WHEN r."error" IS NOT NULL THEN 'error' ELSE 'success' END`;
17281
+ function durationMsSql(startedAt, endedAt) {
17282
+ return `EXTRACT(EPOCH FROM (${endedAt} - ${startedAt}))::numeric * 1000`;
17283
+ }
17240
17284
  const TRACE_FIELDS = {
17241
17285
  traceId: "r.\"traceId\"",
17242
17286
  threadId: "r.\"threadId\"",
17243
17287
  resourceId: "r.\"resourceId\"",
17244
17288
  startedAt: "r.\"startedAt\"",
17245
17289
  endedAt: "r.\"endedAt\"",
17290
+ durationMs: durationMsSql("r.\"startedAt\"", "r.\"endedAt\""),
17246
17291
  entityName: "r.\"entityName\"",
17247
17292
  entityType: "r.\"entityType\"",
17248
17293
  environment: "r.\"environment\"",
17249
- status: TRACE_STATUS_SQL
17294
+ status: TRACE_STATUS_SQL,
17295
+ tags: "r.\"tags\""
17250
17296
  };
17251
17297
  const SPAN_FIELDS = {
17252
17298
  name: "s.\"name\"",
@@ -17348,6 +17394,19 @@ function compileScalarPredicate(predicate, registry, parameterOffset, allowMetad
17348
17394
  sql: `${field} IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
17349
17395
  values: fieldValues
17350
17396
  };
17397
+ if (predicate.type === "collection") {
17398
+ if (predicate.operator === "includes" || predicate.operator === "notIncludes") {
17399
+ const contains = `${field} @> ARRAY[$${parameterOffset}]::text[]`;
17400
+ return {
17401
+ sql: predicate.operator === "includes" ? contains : `cardinality(${field}) > 0 AND NOT (${contains})`,
17402
+ values: [...fieldValues, predicate.value]
17403
+ };
17404
+ }
17405
+ return {
17406
+ sql: `cardinality(${field}) ${predicate.operator === "empty" ? "=" : ">"} 0`,
17407
+ values: fieldValues
17408
+ };
17409
+ }
17351
17410
  if (predicate.type === "membership") {
17352
17411
  const list = placeholders(predicate.values, parameterOffset);
17353
17412
  if (predicate.operator === "in") return {
@@ -17401,6 +17460,7 @@ function compileFeedbackScalarPredicate(predicate, parameterOffset) {
17401
17460
  };
17402
17461
  }
17403
17462
  if (predicate.field !== "value") return compileScalarPredicate(predicate, FEEDBACK_FIELDS, parameterOffset);
17463
+ if (predicate.type === "collection") throw new Error(`Unsupported trusted trace-query field: ${predicate.field}`);
17404
17464
  if (predicate.type === "presence") {
17405
17465
  const present = `(s."valueString" IS NOT NULL OR s."valueNumber" IS NOT NULL)`;
17406
17466
  return {
@@ -17556,7 +17616,7 @@ function compilePostgresTraceScope(schema, selection, relationCollections, scope
17556
17616
  CASE WHEN s."isPending" THEN NULL ELSE s."endedAt" END AS "endedAt",
17557
17617
  CASE
17558
17618
  WHEN s."isPending" THEN NULL
17559
- ELSE EXTRACT(EPOCH FROM (s."endedAt" - s."startedAt")) * 1000
17619
+ ELSE ${durationMsSql("s.\"startedAt\"", "s.\"endedAt\"")}
17560
17620
  END AS "durationMs",
17561
17621
  CASE WHEN s."error" IS NOT NULL THEN 'error' ELSE 'success' END AS "status",
17562
17622
  s."error",
@@ -17784,22 +17844,23 @@ LIMIT $${values.length}`,
17784
17844
  }
17785
17845
  function compilePostgresTraceQueryValues(schema, plan) {
17786
17846
  const { ctes, values } = compilePostgresTraceScope(schema, plan, discoveryCollections(plan.predicateScope), plan.scope);
17787
- let field;
17788
- if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
17847
+ let extracted;
17848
+ if (plan.predicateScope === "trace" && plan.path === "tags") extracted = `SELECT value FROM (SELECT DISTINCT r."traceId", UNNEST(r."tags") AS value FROM root_scope r) t`;
17849
+ else if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
17789
17850
  const keyParameter = `$${values.length + 1}`;
17790
- field = `COALESCE(
17851
+ extracted = `SELECT COALESCE(
17791
17852
  CASE WHEN jsonb_typeof(r."metadataSearch" -> ${keyParameter}) = 'string' THEN r."metadataSearch" ->> ${keyParameter} END,
17792
17853
  CASE WHEN jsonb_typeof(r."metadataRaw" -> ${keyParameter}) = 'string' THEN NULLIF(btrim(r."metadataRaw" ->> ${keyParameter}), '') END
17793
- )`;
17854
+ )::text AS value FROM root_scope r`;
17794
17855
  values.push(plan.path.slice(9));
17795
- } else field = fieldSql(discoveryRegistry(plan.predicateScope), plan.path);
17856
+ } else extracted = `SELECT ${fieldSql(discoveryRegistry(plan.predicateScope), plan.path)}::text AS value FROM ${discoverySource(plan.predicateScope)}`;
17796
17857
  const searchParameter = values.length + 1;
17797
17858
  const search = plan.search ? `AND strpos(lower(value), lower($${searchParameter})) > 0` : "";
17798
17859
  if (plan.search) values.push(plan.search);
17799
17860
  values.push(plan.limit + 1);
17800
17861
  return {
17801
17862
  text: `WITH ${ctes.join(",\n")}, extracted AS (
17802
- SELECT ${field}::text AS value FROM ${discoverySource(plan.predicateScope)}
17863
+ ${extracted}
17803
17864
  )
17804
17865
  SELECT value, count(*)::bigint AS count
17805
17866
  FROM extracted
@@ -18154,7 +18215,7 @@ function buildListTracesFilters(filters, spanTable, nextParamIdx) {
18154
18215
  }
18155
18216
  if (filters.metadata != null) {
18156
18217
  conditions.push(`r."metadataSearch" @> $${i++}::jsonb`);
18157
- params.push(JSON.stringify(filters.metadata));
18218
+ params.push(toPgJson(filters.metadata));
18158
18219
  }
18159
18220
  if (filters.tags != null && filters.tags.length > 0) {
18160
18221
  conditions.push(`r."tags" @> $${i++}::text[]`);
@@ -18432,7 +18493,7 @@ function buildListBranchesFilters(filters, spanType, spanTable, nextParamIdx) {
18432
18493
  }
18433
18494
  if (filters.metadata != null) {
18434
18495
  conditions.push(`r."metadataSearch" @> $${i++}::jsonb`);
18435
- params.push(JSON.stringify(filters.metadata));
18496
+ params.push(toPgJson(filters.metadata));
18436
18497
  }
18437
18498
  if (filters.tags != null && filters.tags.length > 0) {
18438
18499
  conditions.push(`r."tags" @> $${i++}::text[]`);
@@ -18897,6 +18958,7 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
18897
18958
  "metrics",
18898
18959
  "logs",
18899
18960
  "trace-query",
18961
+ "trace-query-root-duration",
18900
18962
  "trace-query-discovery",
18901
18963
  "thread-query",
18902
18964
  "trace-query-tenant-scope"
@@ -18906,6 +18968,7 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
18906
18968
  "logs",
18907
18969
  "delta-polling",
18908
18970
  "trace-query",
18971
+ "trace-query-root-duration",
18909
18972
  "trace-query-discovery",
18910
18973
  "thread-query",
18911
18974
  "trace-query-tenant-scope"
@@ -19223,7 +19286,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
19223
19286
  "draft",
19224
19287
  null,
19225
19288
  promptBlock.authorId ?? null,
19226
- promptBlock.metadata ? JSON.stringify(promptBlock.metadata) : null,
19289
+ promptBlock.metadata ? toPgJson(promptBlock.metadata) : null,
19227
19290
  nowIso,
19228
19291
  nowIso,
19229
19292
  nowIso,
@@ -19302,7 +19365,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
19302
19365
  ...metadata
19303
19366
  };
19304
19367
  setClauses.push(`metadata = $${paramIndex++}`);
19305
- values.push(JSON.stringify(mergedMetadata));
19368
+ values.push(toPgJson(mergedMetadata));
19306
19369
  }
19307
19370
  const now = (/* @__PURE__ */ new Date()).toISOString();
19308
19371
  setClauses.push(`"updatedAt" = $${paramIndex++}`);
@@ -19377,7 +19440,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
19377
19440
  }
19378
19441
  if (metadata && Object.keys(metadata).length > 0) {
19379
19442
  conditions.push(`metadata @> $${paramIdx++}::jsonb`);
19380
- queryParams.push(JSON.stringify(metadata));
19443
+ queryParams.push(toPgJson(metadata));
19381
19444
  }
19382
19445
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
19383
19446
  const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
@@ -19440,9 +19503,9 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
19440
19503
  input.name,
19441
19504
  input.description ?? null,
19442
19505
  input.content,
19443
- input.rules ? JSON.stringify(input.rules) : null,
19444
- input.requestContextSchema ? JSON.stringify(input.requestContextSchema) : null,
19445
- input.changedFields ? JSON.stringify(input.changedFields) : null,
19506
+ input.rules ? toPgJson(input.rules) : null,
19507
+ input.requestContextSchema ? toPgJson(input.requestContextSchema) : null,
19508
+ input.changedFields ? toPgJson(input.changedFields) : null,
19446
19509
  input.changeMessage ?? null,
19447
19510
  nowIso,
19448
19511
  nowIso
@@ -19949,8 +20012,8 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
19949
20012
  if ("timezone" in patch) push("timezone = ?", patch.timezone ?? null);
19950
20013
  if ("status" in patch && patch.status !== void 0) push("status = ?", patch.status);
19951
20014
  if ("nextFireAt" in patch && patch.nextFireAt !== void 0) push("next_fire_at = ?", patch.nextFireAt);
19952
- if ("target" in patch && patch.target !== void 0) push("target = ?::jsonb", JSON.stringify(patch.target));
19953
- if ("metadata" in patch) push("metadata = ?::jsonb", patch.metadata != null ? JSON.stringify(patch.metadata) : null);
20015
+ if ("target" in patch && patch.target !== void 0) push("target = ?::jsonb", toPgJson(patch.target));
20016
+ if ("metadata" in patch) push("metadata = ?::jsonb", patch.metadata != null ? toPgJson(patch.metadata) : null);
19954
20017
  if ("ownerType" in patch) push("owner_type = ?", patch.ownerType ?? null);
19955
20018
  if ("ownerId" in patch) push("owner_id = ?", patch.ownerId ?? null);
19956
20019
  push("updated_at = ?", Date.now());
@@ -20168,7 +20231,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
20168
20231
  scorerDefinition.authorId ?? null,
20169
20232
  scorerDefinition.organizationId ?? null,
20170
20233
  scorerDefinition.projectId ?? null,
20171
- scorerDefinition.metadata ? JSON.stringify(scorerDefinition.metadata) : null,
20234
+ scorerDefinition.metadata ? toPgJson(scorerDefinition.metadata) : null,
20172
20235
  nowIso,
20173
20236
  nowIso,
20174
20237
  nowIso,
@@ -20249,7 +20312,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
20249
20312
  ...metadata
20250
20313
  };
20251
20314
  setClauses.push(`metadata = $${paramIndex++}`);
20252
- values.push(JSON.stringify(mergedMetadata));
20315
+ values.push(toPgJson(mergedMetadata));
20253
20316
  }
20254
20317
  const now = (/* @__PURE__ */ new Date()).toISOString();
20255
20318
  setClauses.push(`"updatedAt" = $${paramIndex++}`);
@@ -20332,7 +20395,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
20332
20395
  }
20333
20396
  if (metadata && Object.keys(metadata).length > 0) {
20334
20397
  conditions.push(`metadata @> $${paramIdx++}::jsonb`);
20335
- queryParams.push(JSON.stringify(metadata));
20398
+ queryParams.push(toPgJson(metadata));
20336
20399
  }
20337
20400
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
20338
20401
  const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
@@ -20395,12 +20458,12 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
20395
20458
  input.name,
20396
20459
  input.description ?? null,
20397
20460
  input.type,
20398
- input.model ? JSON.stringify(input.model) : null,
20461
+ input.model ? toPgJson(input.model) : null,
20399
20462
  input.instructions ?? null,
20400
- input.scoreRange ? JSON.stringify(input.scoreRange) : null,
20401
- input.presetConfig ? JSON.stringify(input.presetConfig) : null,
20402
- input.defaultSampling ? JSON.stringify(input.defaultSampling) : null,
20403
- input.changedFields ? JSON.stringify(input.changedFields) : null,
20463
+ input.scoreRange ? toPgJson(input.scoreRange) : null,
20464
+ input.presetConfig ? toPgJson(input.presetConfig) : null,
20465
+ input.defaultSampling ? toPgJson(input.defaultSampling) : null,
20466
+ input.changedFields ? toPgJson(input.changedFields) : null,
20404
20467
  input.changeMessage ?? null,
20405
20468
  nowIso,
20406
20469
  nowIso
@@ -20920,15 +20983,15 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
20920
20983
  record: {
20921
20984
  id,
20922
20985
  ...rest,
20923
- input: JSON.stringify(input) || "",
20924
- output: JSON.stringify(output) || "",
20925
- scorer: scorer ? JSON.stringify(scorer) : null,
20926
- preprocessStepResult: preprocessStepResult ? JSON.stringify(preprocessStepResult) : null,
20927
- analyzeStepResult: analyzeStepResult ? JSON.stringify(analyzeStepResult) : null,
20928
- metadata: metadata ? JSON.stringify(metadata) : null,
20929
- additionalContext: additionalContext ? JSON.stringify(additionalContext) : null,
20930
- requestContext: requestContext ? JSON.stringify(requestContext) : null,
20931
- entity: entity ? JSON.stringify(entity) : null,
20986
+ input: toPgJson(input) || "",
20987
+ output: toPgJson(output) || "",
20988
+ scorer: scorer ? toPgJson(scorer) : null,
20989
+ preprocessStepResult: preprocessStepResult ? toPgJson(preprocessStepResult) : null,
20990
+ analyzeStepResult: analyzeStepResult ? toPgJson(analyzeStepResult) : null,
20991
+ metadata: metadata ? toPgJson(metadata) : null,
20992
+ additionalContext: additionalContext ? toPgJson(additionalContext) : null,
20993
+ requestContext: requestContext ? toPgJson(requestContext) : null,
20994
+ entity: entity ? toPgJson(entity) : null,
20932
20995
  createdAt: now.toISOString(),
20933
20996
  updatedAt: now.toISOString()
20934
20997
  }
@@ -21513,15 +21576,15 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
21513
21576
  input.description ?? null,
21514
21577
  input.instructions ?? null,
21515
21578
  input.license ?? null,
21516
- input.compatibility ? JSON.stringify(input.compatibility) : null,
21517
- input.source ? JSON.stringify(input.source) : null,
21518
- input.references ? JSON.stringify(input.references) : null,
21519
- input.scripts ? JSON.stringify(input.scripts) : null,
21520
- input.assets ? JSON.stringify(input.assets) : null,
21521
- input.files ? JSON.stringify(input.files) : null,
21522
- input.metadata ? JSON.stringify(input.metadata) : null,
21523
- input.tree ? JSON.stringify(input.tree) : null,
21524
- input.changedFields ? JSON.stringify(input.changedFields) : null,
21579
+ input.compatibility ? toPgJson(input.compatibility) : null,
21580
+ input.source ? toPgJson(input.source) : null,
21581
+ input.references ? toPgJson(input.references) : null,
21582
+ input.scripts ? toPgJson(input.scripts) : null,
21583
+ input.assets ? toPgJson(input.assets) : null,
21584
+ input.files ? toPgJson(input.files) : null,
21585
+ input.metadata ? toPgJson(input.metadata) : null,
21586
+ input.tree ? toPgJson(input.tree) : null,
21587
+ input.changedFields ? toPgJson(input.changedFields) : null,
21525
21588
  input.changeMessage ?? null,
21526
21589
  nowIso,
21527
21590
  nowIso
@@ -21897,7 +21960,7 @@ var ThreadStatePG = class ThreadStatePG extends ThreadStateStorage {
21897
21960
  }
21898
21961
  async setState({ threadId, type, value }) {
21899
21962
  const now = (/* @__PURE__ */ new Date()).toISOString();
21900
- const serialized = JSON.stringify(value ?? null);
21963
+ const serialized = toPgJson(value ?? null);
21901
21964
  try {
21902
21965
  await this.#db.client.none(`INSERT INTO ${this.#table} ("threadId", "type", "value", "createdAt", "createdAtZ", "updatedAt", "updatedAtZ")
21903
21966
  VALUES ($1, $2, $3::jsonb, $4::timestamp, $5::timestamptz, $4::timestamp, $5::timestamptz)
@@ -22674,7 +22737,7 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
22674
22737
  requestContext
22675
22738
  });
22676
22739
  const now = /* @__PURE__ */ new Date();
22677
- const sanitizedSnapshot = sanitizeJsonForPg(JSON.stringify(snapshot));
22740
+ const sanitizedSnapshot = toPgJson(snapshot);
22678
22741
  await t.none(`INSERT INTO ${tableName}
22679
22742
  (workflow_name, run_id, snapshot, "createdAt", "updatedAt", "createdAtZ", "updatedAtZ")
22680
22743
  VALUES ($1, $2, $3, $4, $5, $6, $7)
@@ -22721,7 +22784,7 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
22721
22784
  ...snapshot,
22722
22785
  ...state
22723
22786
  };
22724
- const sanitizedSnapshot = sanitizeJsonForPg(JSON.stringify(updatedSnapshot));
22787
+ const sanitizedSnapshot = toPgJson(updatedSnapshot);
22725
22788
  const now = /* @__PURE__ */ new Date();
22726
22789
  await t.none(`UPDATE ${tableName}
22727
22790
  SET snapshot = $1, "updatedAt" = $2, "updatedAtZ" = $3
@@ -22751,7 +22814,7 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
22751
22814
  const now = /* @__PURE__ */ new Date();
22752
22815
  const createdAtValue = createdAt ? createdAt : now;
22753
22816
  const updatedAtValue = updatedAt ? updatedAt : now;
22754
- const sanitizedSnapshot = sanitizeJsonForPg(JSON.stringify(snapshot));
22817
+ const sanitizedSnapshot = toPgJson(snapshot);
22755
22818
  await this.#db.client.none(`INSERT INTO ${getTableName({
22756
22819
  indexName: TABLE_WORKFLOW_SNAPSHOT,
22757
22820
  schemaName: getSchemaName(this.#schema)
@@ -23063,7 +23126,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
23063
23126
  "draft",
23064
23127
  null,
23065
23128
  workspace.authorId ?? null,
23066
- workspace.metadata ? JSON.stringify(workspace.metadata) : null,
23129
+ workspace.metadata ? toPgJson(workspace.metadata) : null,
23067
23130
  nowIso,
23068
23131
  nowIso,
23069
23132
  nowIso,
@@ -23138,7 +23201,11 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
23138
23201
  ...latestConfig,
23139
23202
  ...configFields
23140
23203
  };
23141
- const changedFields = SNAPSHOT_FIELDS.filter((field) => field in configFields && JSON.stringify(configFields[field]) !== JSON.stringify(latestConfig[field]));
23204
+ const normalized = (value) => {
23205
+ const json = toPgJson(value);
23206
+ return json === void 0 ? void 0 : JSON.parse(json);
23207
+ };
23208
+ const changedFields = SNAPSHOT_FIELDS.filter((field) => field in configFields && !isDeepStrictEqual(normalized(configFields[field]), normalized(latestConfig[field])));
23142
23209
  if (changedFields.length > 0) {
23143
23210
  versionCreated = true;
23144
23211
  const newVersionId = crypto.randomUUID();
@@ -23172,12 +23239,13 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
23172
23239
  values.push(status);
23173
23240
  }
23174
23241
  if (metadata !== void 0) {
23242
+ const normalizedMetadata = JSON.parse(toPgJson(metadata));
23175
23243
  const mergedMetadata = {
23176
23244
  ...existingWorkspace.metadata || {},
23177
- ...metadata
23245
+ ...normalizedMetadata
23178
23246
  };
23179
23247
  setClauses.push(`metadata = $${paramIndex++}`);
23180
- values.push(JSON.stringify(mergedMetadata));
23248
+ values.push(toPgJson(mergedMetadata));
23181
23249
  }
23182
23250
  const now = (/* @__PURE__ */ new Date()).toISOString();
23183
23251
  setClauses.push(`"updatedAt" = $${paramIndex++}`);
@@ -23248,7 +23316,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
23248
23316
  }
23249
23317
  if (metadata && Object.keys(metadata).length > 0) {
23250
23318
  conditions.push(`metadata @> $${paramIdx++}::jsonb`);
23251
- queryParams.push(JSON.stringify(metadata));
23319
+ queryParams.push(toPgJson(metadata));
23252
23320
  }
23253
23321
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
23254
23322
  const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
@@ -23311,15 +23379,15 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
23311
23379
  input.versionNumber,
23312
23380
  input.name,
23313
23381
  input.description ?? null,
23314
- input.filesystem ? JSON.stringify(input.filesystem) : null,
23315
- input.sandbox ? JSON.stringify(input.sandbox) : null,
23316
- input.mounts ? JSON.stringify(input.mounts) : null,
23317
- input.search ? JSON.stringify(input.search) : null,
23318
- input.skills ? JSON.stringify(input.skills) : null,
23319
- input.tools ? JSON.stringify(input.tools) : null,
23382
+ input.filesystem ? toPgJson(input.filesystem) : null,
23383
+ input.sandbox ? toPgJson(input.sandbox) : null,
23384
+ input.mounts ? toPgJson(input.mounts) : null,
23385
+ input.search ? toPgJson(input.search) : null,
23386
+ input.skills ? toPgJson(input.skills) : null,
23387
+ input.tools ? toPgJson(input.tools) : null,
23320
23388
  input.autoSync ?? false,
23321
23389
  input.operationTimeout ?? null,
23322
- input.changedFields ? JSON.stringify(input.changedFields) : null,
23390
+ input.changedFields ? toPgJson(input.changedFields) : null,
23323
23391
  input.changeMessage ?? null,
23324
23392
  nowIso,
23325
23393
  nowIso
@@ -23611,7 +23679,7 @@ var PgFactoryStorageOps = class {
23611
23679
  switch (spec.type) {
23612
23680
  case "timestamp": return value instanceof Date ? value : new Date(String(value));
23613
23681
  case "boolean": return Boolean(value);
23614
- case "json": return JSON.stringify(value);
23682
+ case "json": return toPgJson(value);
23615
23683
  case "bigint":
23616
23684
  case "integer": return Number(value);
23617
23685
  default: return String(value);