@percepta/kaizen 0.9.0 → 0.10.0

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 (81) hide show
  1. package/dist/dashboard/pages/api/langfuse-action.js +9 -2
  2. package/dist/dashboard/pages/api/langfuse-action.js.map +1 -1
  3. package/dist/dashboard/pages/api/langfuse-dataset-item.js +5 -2
  4. package/dist/dashboard/pages/api/langfuse-dataset-item.js.map +1 -1
  5. package/dist/dashboard/pages/api/langfuse-dataset-mutation.js +1 -1
  6. package/dist/dashboard/pages/api/langfuse-dataset-mutation.js.map +1 -1
  7. package/dist/dashboard/pages/api/langfuse-dataset.js.map +1 -1
  8. package/dist/dashboard/pages/api/langfuse-datasets.js.map +1 -1
  9. package/dist/dashboard/pages/api/langfuse-trace-memberships.js +1 -1
  10. package/dist/dashboard/pages/api/langfuse-trace-memberships.js.map +1 -1
  11. package/dist/dashboard/pages/api/langfuse-trace.js.map +1 -1
  12. package/dist/dashboard/pages/api/langfuse-traces.js.map +1 -1
  13. package/dist/dashboard/pages/api/linear-ideas.js.map +1 -1
  14. package/dist/dashboard/pages/api/run-events.js.map +1 -1
  15. package/dist/dashboard/pages/api/run-failures.js.map +1 -1
  16. package/dist/dashboard/pages/api/run-traces.js.map +1 -1
  17. package/dist/dashboard/pages/api/runs.js.map +1 -1
  18. package/dist/dashboard/pages/api/systems.js +1 -1
  19. package/dist/dashboard/pages/api/systems.js.map +1 -1
  20. package/dist/dashboard/pages/api/trace-renderer-version.js +10 -3
  21. package/dist/dashboard/pages/api/trace-renderer-version.js.map +1 -1
  22. package/dist/dashboard/pages/api/trace-renderer.js +12 -26
  23. package/dist/dashboard/pages/api/trace-renderer.js.map +1 -1
  24. package/dist/dashboard/src/lib/bundle-custom-renderer.js +167 -0
  25. package/dist/dashboard/src/lib/bundle-custom-renderer.js.map +1 -0
  26. package/dist/dashboard/src/lib/custom-renderer-files.js.map +1 -1
  27. package/dist/dashboard/src/lib/custom-renderer-metadata.js.map +1 -1
  28. package/dist/dashboard/src/lib/custom-view-paths.js.map +1 -1
  29. package/dist/dashboard/src/lib/dataset-item-labeling.js +20 -0
  30. package/dist/dashboard/src/lib/dataset-item-labeling.js.map +1 -0
  31. package/dist/dashboard/src/lib/env.js.map +1 -1
  32. package/dist/dashboard/src/lib/langfuse-cache.js.map +1 -1
  33. package/dist/dashboard/src/lib/langfuse-creds.js.map +1 -1
  34. package/dist/dashboard/src/lib/langfuse-demo.js.map +1 -1
  35. package/dist/dashboard/src/lib/langfuse-errors.js.map +1 -1
  36. package/dist/dashboard/src/lib/langfuse-helpers.js.map +1 -1
  37. package/dist/dashboard/src/lib/run-api.js.map +1 -1
  38. package/dist/dashboard/src/lib/run-store.js.map +1 -1
  39. package/dist/dashboard/src/lib/types.js.map +1 -1
  40. package/dist/dashboard/src/lib/workspace-env.js.map +1 -1
  41. package/dist/dashboard/src/lib/workspace.js.map +1 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/langfuse.d.ts.map +1 -1
  44. package/dist/langfuse.js.map +1 -1
  45. package/dist/package.js +2 -2
  46. package/dist/shared/env-file.js.map +1 -1
  47. package/dist/shared/linear-ideas.js.map +1 -1
  48. package/dist/shared/linear-issue.js.map +1 -1
  49. package/dist/shared/view-types.d.ts.map +1 -1
  50. package/dist/shared/workspace-paths.js.map +1 -1
  51. package/dist/src/commands/create-view.js.map +1 -1
  52. package/dist/src/commands/guide.js.map +1 -1
  53. package/dist/src/commands/ideas.js.map +1 -1
  54. package/dist/src/commands/init-system.js.map +1 -1
  55. package/dist/src/commands/init.js.map +1 -1
  56. package/dist/src/commands/log.js.map +1 -1
  57. package/dist/src/commands/rebuild.js.map +1 -1
  58. package/dist/src/commands/run.js.map +1 -1
  59. package/dist/src/commands/studio.js.map +1 -1
  60. package/dist/src/lib/bootstrap.js.map +1 -1
  61. package/dist/src/lib/cli.js.map +1 -1
  62. package/dist/src/lib/events.js +2 -0
  63. package/dist/src/lib/events.js.map +1 -1
  64. package/dist/src/lib/fs-utils.js.map +1 -1
  65. package/dist/src/lib/leaderboard.js.map +1 -1
  66. package/dist/src/lib/parse-args.js.map +1 -1
  67. package/dist/src/lib/paths.js.map +1 -1
  68. package/dist/src/lib/promotion.js.map +1 -1
  69. package/dist/src/lib/prompt.js.map +1 -1
  70. package/dist/src/lib/run-dir.js.map +1 -1
  71. package/dist/src/lib/runner.js.map +1 -1
  72. package/dist/src/lib/system.js.map +1 -1
  73. package/dist/studio/client/assets/index-Dc4zGLjQ.css +1 -0
  74. package/dist/studio/client/assets/index-ElL5OoiH.js +9 -0
  75. package/dist/studio/client/index.html +2 -2
  76. package/dist/studio/server.d.ts.map +1 -1
  77. package/dist/studio/server.js.map +1 -1
  78. package/dist/types.d.ts.map +1 -1
  79. package/package.json +3 -3
  80. package/dist/studio/client/assets/index-Bwj0gucs.css +0 -1
  81. package/dist/studio/client/assets/index-DKAiSaYs.js +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"custom-view-paths.js","names":[],"sources":["../../../../dashboard/src/lib/custom-view-paths.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n KAIZEN_DIR,\n KAIZEN_SYSTEMS_DIR,\n} from \"../../../shared/workspace-paths.js\";\nimport type { CustomViewSurface } from \"./custom-renderer-metadata\";\n\nconst VIEW_EXTENSIONS = [\"tsx\", \"ts\", \"jsx\", \"js\"] as const;\nexport type { CustomViewSurface };\n\nexport function findCustomViewPath(\n workspace: string,\n systemId: string,\n surface: CustomViewSurface,\n): string | null {\n const candidates = VIEW_EXTENSIONS.map(\n (ext) =>\n `${KAIZEN_DIR}/${KAIZEN_SYSTEMS_DIR}/${systemId}/${surface}.${ext}`,\n );\n\n for (const candidate of candidates) {\n const fullPath = path.resolve(workspace, candidate);\n if (!isPathInside(workspace, fullPath)) continue;\n if (fs.existsSync(fullPath)) return normalizeSlashes(candidate);\n }\n\n return null;\n}\n\nexport function findCustomTraceRendererPath(\n workspace: string,\n systemId: string,\n): string | null {\n return findCustomViewPath(workspace, systemId, \"trace\");\n}\n\nexport function resolveWorkspaceViewPath(\n workspace: string,\n relativePath: string,\n): string | null {\n const fullPath = path.resolve(workspace, relativePath);\n return isPathInside(workspace, fullPath) ? fullPath : null;\n}\n\nfunction isPathInside(root: string, fullPath: string): boolean {\n const normalizedRoot = path.resolve(root);\n return (\n fullPath === normalizedRoot ||\n fullPath.startsWith(normalizedRoot + path.sep)\n );\n}\n\nfunction normalizeSlashes(value: string): string {\n return value.split(path.sep).join(\"/\");\n}\n"],"mappings":";;;;AAQA,MAAM,kBAAkB;CAAC;CAAO;CAAM;CAAO;CAAK;AAGlD,SAAgB,mBACd,WACA,UACA,SACe;CACf,MAAM,aAAa,gBAAgB,KAChC,QACC,GAAG,WAAW,GAAG,mBAAmB,GAAG,SAAS,GAAG,QAAQ,GAAG,MACjE;AAED,MAAK,MAAM,aAAa,YAAY;EAClC,MAAM,WAAW,KAAK,QAAQ,WAAW,UAAU;AACnD,MAAI,CAAC,aAAa,WAAW,SAAS,CAAE;AACxC,MAAI,GAAG,WAAW,SAAS,CAAE,QAAO,iBAAiB,UAAU;;AAGjE,QAAO;;AAGT,SAAgB,4BACd,WACA,UACe;AACf,QAAO,mBAAmB,WAAW,UAAU,QAAQ;;AAGzD,SAAgB,yBACd,WACA,cACe;CACf,MAAM,WAAW,KAAK,QAAQ,WAAW,aAAa;AACtD,QAAO,aAAa,WAAW,SAAS,GAAG,WAAW;;AAGxD,SAAS,aAAa,MAAc,UAA2B;CAC7D,MAAM,iBAAiB,KAAK,QAAQ,KAAK;AACzC,QACE,aAAa,kBACb,SAAS,WAAW,iBAAiB,KAAK,IAAI;;AAIlD,SAAS,iBAAiB,OAAuB;AAC/C,QAAO,MAAM,MAAM,KAAK,IAAI,CAAC,KAAK,IAAI"}
1
+ {"version":3,"file":"custom-view-paths.js","names":[],"sources":["../../../../dashboard/src/lib/custom-view-paths.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n KAIZEN_DIR,\n KAIZEN_SYSTEMS_DIR,\n} from \"../../../shared/workspace-paths.js\";\nimport type { CustomViewSurface } from \"./custom-renderer-metadata\";\n\nconst VIEW_EXTENSIONS = [\"tsx\", \"ts\", \"jsx\", \"js\"] as const;\nexport type { CustomViewSurface };\n\nexport function findCustomViewPath(\n workspace: string,\n systemId: string,\n surface: CustomViewSurface,\n): string | null {\n const candidates = VIEW_EXTENSIONS.map(\n (ext) =>\n `${KAIZEN_DIR}/${KAIZEN_SYSTEMS_DIR}/${systemId}/${surface}.${ext}`,\n );\n\n for (const candidate of candidates) {\n const fullPath = path.resolve(workspace, candidate);\n if (!isPathInside(workspace, fullPath)) continue;\n if (fs.existsSync(fullPath)) return normalizeSlashes(candidate);\n }\n\n return null;\n}\n\nexport function findCustomTraceRendererPath(\n workspace: string,\n systemId: string,\n): string | null {\n return findCustomViewPath(workspace, systemId, \"trace\");\n}\n\nexport function resolveWorkspaceViewPath(\n workspace: string,\n relativePath: string,\n): string | null {\n const fullPath = path.resolve(workspace, relativePath);\n return isPathInside(workspace, fullPath) ? fullPath : null;\n}\n\nfunction isPathInside(root: string, fullPath: string): boolean {\n const normalizedRoot = path.resolve(root);\n return (\n fullPath === normalizedRoot ||\n fullPath.startsWith(normalizedRoot + path.sep)\n );\n}\n\nfunction normalizeSlashes(value: string): string {\n return value.split(path.sep).join(\"/\");\n}\n"],"mappings":";;;;AAQA,MAAM,kBAAkB;CAAC;CAAO;CAAM;CAAO;AAAI;AAGjD,SAAgB,mBACd,WACA,UACA,SACe;CACf,MAAM,aAAa,gBAAgB,KAChC,QACC,GAAG,WAAW,GAAG,mBAAmB,GAAG,SAAS,GAAG,QAAQ,GAAG,KAClE;CAEA,KAAK,MAAM,aAAa,YAAY;EAClC,MAAM,WAAW,KAAK,QAAQ,WAAW,SAAS;EAClD,IAAI,CAAC,aAAa,WAAW,QAAQ,GAAG;EACxC,IAAI,GAAG,WAAW,QAAQ,GAAG,OAAO,iBAAiB,SAAS;CAChE;CAEA,OAAO;AACT;AAEA,SAAgB,4BACd,WACA,UACe;CACf,OAAO,mBAAmB,WAAW,UAAU,OAAO;AACxD;AAEA,SAAgB,yBACd,WACA,cACe;CACf,MAAM,WAAW,KAAK,QAAQ,WAAW,YAAY;CACrD,OAAO,aAAa,WAAW,QAAQ,IAAI,WAAW;AACxD;AAEA,SAAS,aAAa,MAAc,UAA2B;CAC7D,MAAM,iBAAiB,KAAK,QAAQ,IAAI;CACxC,OACE,aAAa,kBACb,SAAS,WAAW,iBAAiB,KAAK,GAAG;AAEjD;AAEA,SAAS,iBAAiB,OAAuB;CAC/C,OAAO,MAAM,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AACvC"}
@@ -0,0 +1,20 @@
1
+ import { isRecord } from "./langfuse-helpers.js";
2
+ //#region dashboard/src/lib/dataset-item-labeling.ts
3
+ const LABEL_UPDATED_BY = "kaizen-studio";
4
+ function markDatasetItemLabeled(metadata, timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
5
+ const base = metadata ? { ...metadata } : {};
6
+ const kaizen = isRecord(base.kaizen) ? base.kaizen : {};
7
+ return {
8
+ ...base,
9
+ kaizen: {
10
+ ...kaizen,
11
+ isLabeled: true,
12
+ labelUpdatedAt: timestamp,
13
+ labelUpdatedBy: LABEL_UPDATED_BY
14
+ }
15
+ };
16
+ }
17
+ //#endregion
18
+ export { markDatasetItemLabeled };
19
+
20
+ //# sourceMappingURL=dataset-item-labeling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-item-labeling.js","names":[],"sources":["../../../../dashboard/src/lib/dataset-item-labeling.ts"],"sourcesContent":["import { isRecord } from \"./langfuse-helpers\";\n\nconst LABEL_UPDATED_BY = \"kaizen-studio\";\n\nexport function markDatasetItemLabeled(\n metadata: Record<string, unknown> | null | undefined,\n timestamp = new Date().toISOString(),\n): Record<string, unknown> {\n const base = metadata ? { ...metadata } : {};\n const kaizen = isRecord(base.kaizen) ? base.kaizen : {};\n return {\n ...base,\n kaizen: {\n ...kaizen,\n isLabeled: true,\n labelUpdatedAt: timestamp,\n labelUpdatedBy: LABEL_UPDATED_BY,\n },\n };\n}\n"],"mappings":";;AAEA,MAAM,mBAAmB;AAEzB,SAAgB,uBACd,UACA,6BAAY,IAAI,KAAK,GAAE,YAAY,GACV;CACzB,MAAM,OAAO,WAAW,EAAE,GAAG,SAAS,IAAI,CAAC;CAC3C,MAAM,SAAS,SAAS,KAAK,MAAM,IAAI,KAAK,SAAS,CAAC;CACtD,OAAO;EACL,GAAG;EACH,QAAQ;GACN,GAAG;GACH,WAAW;GACX,gBAAgB;GAChB,gBAAgB;EAClB;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","names":[],"sources":["../../../../dashboard/src/lib/env.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport YAML from \"yaml\";\nimport { readEnvFile } from \"../../../shared/env-file.js\";\nimport {\n readSystemEnvFromConfig,\n resolveWorkspacePath as resolveSharedWorkspacePath,\n} from \"../../../shared/env.js\";\nimport { kaizenSystemPath } from \"../../../shared/workspace-paths.js\";\nimport { getWorkspaceRoot } from \"./workspace\";\n\nexport { readEnvFile };\n\nexport function resolveWorkspacePath(value: string): string {\n return resolveSharedWorkspacePath(getWorkspaceRoot(), value);\n}\n\nexport function readSystemMeta(systemId: string): Record<string, unknown> {\n const mdPath = kaizenSystemPath(getWorkspaceRoot(), systemId);\n if (!fs.existsSync(mdPath)) return {};\n const raw = fs.readFileSync(mdPath, \"utf-8\");\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return {};\n const parsed = YAML.parse(match[1]);\n return isRecord(parsed) ? parsed : {};\n}\n\nexport function readSystemEnv(systemId?: string): Record<string, string> {\n const workspaceRoot = getWorkspaceRoot();\n const meta = systemId ? readSystemMeta(systemId) : {};\n return readSystemEnvFromConfig({\n workspaceRoot,\n repo: stringValue(meta.repo),\n runEval: stringValue(meta.run_eval),\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringValue(value: unknown): string | null {\n return typeof value === \"string\" && value ? value : null;\n}\n"],"mappings":";;;;;;;AAgBA,SAAgB,eAAe,UAA2C;CACxE,MAAM,SAAS,iBAAiB,kBAAkB,EAAE,SAAS;AAC7D,KAAI,CAAC,GAAG,WAAW,OAAO,CAAE,QAAO,EAAE;CAErC,MAAM,QADM,GAAG,aAAa,QAAQ,QACnB,CAAC,MAAM,wBAAwB;AAChD,KAAI,CAAC,MAAO,QAAO,EAAE;CACrB,MAAM,SAAS,KAAK,MAAM,MAAM,GAAG;AACnC,QAAO,SAAS,OAAO,GAAG,SAAS,EAAE;;AAavC,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
1
+ {"version":3,"file":"env.js","names":[],"sources":["../../../../dashboard/src/lib/env.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport YAML from \"yaml\";\nimport { readEnvFile } from \"../../../shared/env-file.js\";\nimport {\n readSystemEnvFromConfig,\n resolveWorkspacePath as resolveSharedWorkspacePath,\n} from \"../../../shared/env.js\";\nimport { kaizenSystemPath } from \"../../../shared/workspace-paths.js\";\nimport { getWorkspaceRoot } from \"./workspace\";\n\nexport { readEnvFile };\n\nexport function resolveWorkspacePath(value: string): string {\n return resolveSharedWorkspacePath(getWorkspaceRoot(), value);\n}\n\nexport function readSystemMeta(systemId: string): Record<string, unknown> {\n const mdPath = kaizenSystemPath(getWorkspaceRoot(), systemId);\n if (!fs.existsSync(mdPath)) return {};\n const raw = fs.readFileSync(mdPath, \"utf-8\");\n const match = raw.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!match) return {};\n const parsed = YAML.parse(match[1]);\n return isRecord(parsed) ? parsed : {};\n}\n\nexport function readSystemEnv(systemId?: string): Record<string, string> {\n const workspaceRoot = getWorkspaceRoot();\n const meta = systemId ? readSystemMeta(systemId) : {};\n return readSystemEnvFromConfig({\n workspaceRoot,\n repo: stringValue(meta.repo),\n runEval: stringValue(meta.run_eval),\n });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringValue(value: unknown): string | null {\n return typeof value === \"string\" && value ? value : null;\n}\n"],"mappings":";;;;;;;AAgBA,SAAgB,eAAe,UAA2C;CACxE,MAAM,SAAS,iBAAiB,iBAAiB,GAAG,QAAQ;CAC5D,IAAI,CAAC,GAAG,WAAW,MAAM,GAAG,OAAO,CAAC;CAEpC,MAAM,QADM,GAAG,aAAa,QAAQ,OACpB,EAAE,MAAM,uBAAuB;CAC/C,IAAI,CAAC,OAAO,OAAO,CAAC;CACpB,MAAM,SAAS,KAAK,MAAM,MAAM,EAAE;CAClC,OAAO,SAAS,MAAM,IAAI,SAAS,CAAC;AACtC;AAYA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E"}
@@ -1 +1 @@
1
- {"version":3,"file":"langfuse-cache.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-cache.ts"],"sourcesContent":["/**\n * Lightweight in-process TTL cache for Langfuse API route handlers.\n *\n * Usage:\n * const cache = createTtlCache({ ttlMs: 15_000 });\n * const hit = cache.get(\"key\");\n * cache.set(\"key\", value);\n */\n\ninterface CacheEntry {\n at: number;\n body: unknown;\n}\n\ninterface TtlCacheOptions {\n /** Time-to-live in milliseconds. */\n ttlMs: number;\n /** Hard cap on entries; oldest are evicted when exceeded (default 200). */\n maxSize?: number;\n}\n\nexport interface TtlCache {\n get(key: string): unknown;\n set(key: string, body: unknown): void;\n clear(): void;\n}\n\nexport function createTtlCache(opts: TtlCacheOptions): TtlCache {\n const { ttlMs, maxSize = 200 } = opts;\n const map = new Map<string, CacheEntry>();\n\n function evict(): void {\n const now = Date.now();\n for (const [k, v] of map) {\n if (now - v.at > ttlMs) map.delete(k);\n }\n // Hard cap: if still over maxSize after stale eviction, drop oldest entries\n if (map.size > maxSize) {\n const excess = map.size - maxSize;\n let dropped = 0;\n for (const key of map.keys()) {\n if (dropped >= excess) break;\n map.delete(key);\n dropped++;\n }\n }\n }\n\n return {\n get(key: string): unknown {\n const entry = map.get(key);\n if (!entry) return undefined;\n if (Date.now() - entry.at > ttlMs) {\n map.delete(key);\n return undefined;\n }\n return entry.body;\n },\n set(key: string, body: unknown): void {\n map.set(key, { at: Date.now(), body });\n if (map.size > maxSize) evict();\n },\n clear(): void {\n map.clear();\n },\n };\n}\n"],"mappings":";AA2BA,SAAgB,eAAe,MAAiC;CAC9D,MAAM,EAAE,OAAO,UAAU,QAAQ;CACjC,MAAM,sBAAM,IAAI,KAAyB;CAEzC,SAAS,QAAc;EACrB,MAAM,MAAM,KAAK,KAAK;AACtB,OAAK,MAAM,CAAC,GAAG,MAAM,IACnB,KAAI,MAAM,EAAE,KAAK,MAAO,KAAI,OAAO,EAAE;AAGvC,MAAI,IAAI,OAAO,SAAS;GACtB,MAAM,SAAS,IAAI,OAAO;GAC1B,IAAI,UAAU;AACd,QAAK,MAAM,OAAO,IAAI,MAAM,EAAE;AAC5B,QAAI,WAAW,OAAQ;AACvB,QAAI,OAAO,IAAI;AACf;;;;AAKN,QAAO;EACL,IAAI,KAAsB;GACxB,MAAM,QAAQ,IAAI,IAAI,IAAI;AAC1B,OAAI,CAAC,MAAO,QAAO,KAAA;AACnB,OAAI,KAAK,KAAK,GAAG,MAAM,KAAK,OAAO;AACjC,QAAI,OAAO,IAAI;AACf;;AAEF,UAAO,MAAM;;EAEf,IAAI,KAAa,MAAqB;AACpC,OAAI,IAAI,KAAK;IAAE,IAAI,KAAK,KAAK;IAAE;IAAM,CAAC;AACtC,OAAI,IAAI,OAAO,QAAS,QAAO;;EAEjC,QAAc;AACZ,OAAI,OAAO;;EAEd"}
1
+ {"version":3,"file":"langfuse-cache.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-cache.ts"],"sourcesContent":["/**\n * Lightweight in-process TTL cache for Langfuse API route handlers.\n *\n * Usage:\n * const cache = createTtlCache({ ttlMs: 15_000 });\n * const hit = cache.get(\"key\");\n * cache.set(\"key\", value);\n */\n\ninterface CacheEntry {\n at: number;\n body: unknown;\n}\n\ninterface TtlCacheOptions {\n /** Time-to-live in milliseconds. */\n ttlMs: number;\n /** Hard cap on entries; oldest are evicted when exceeded (default 200). */\n maxSize?: number;\n}\n\nexport interface TtlCache {\n get(key: string): unknown;\n set(key: string, body: unknown): void;\n clear(): void;\n}\n\nexport function createTtlCache(opts: TtlCacheOptions): TtlCache {\n const { ttlMs, maxSize = 200 } = opts;\n const map = new Map<string, CacheEntry>();\n\n function evict(): void {\n const now = Date.now();\n for (const [k, v] of map) {\n if (now - v.at > ttlMs) map.delete(k);\n }\n // Hard cap: if still over maxSize after stale eviction, drop oldest entries\n if (map.size > maxSize) {\n const excess = map.size - maxSize;\n let dropped = 0;\n for (const key of map.keys()) {\n if (dropped >= excess) break;\n map.delete(key);\n dropped++;\n }\n }\n }\n\n return {\n get(key: string): unknown {\n const entry = map.get(key);\n if (!entry) return undefined;\n if (Date.now() - entry.at > ttlMs) {\n map.delete(key);\n return undefined;\n }\n return entry.body;\n },\n set(key: string, body: unknown): void {\n map.set(key, { at: Date.now(), body });\n if (map.size > maxSize) evict();\n },\n clear(): void {\n map.clear();\n },\n };\n}\n"],"mappings":";AA2BA,SAAgB,eAAe,MAAiC;CAC9D,MAAM,EAAE,OAAO,UAAU,QAAQ;CACjC,MAAM,sBAAM,IAAI,IAAwB;CAExC,SAAS,QAAc;EACrB,MAAM,MAAM,KAAK,IAAI;EACrB,KAAK,MAAM,CAAC,GAAG,MAAM,KACnB,IAAI,MAAM,EAAE,KAAK,OAAO,IAAI,OAAO,CAAC;EAGtC,IAAI,IAAI,OAAO,SAAS;GACtB,MAAM,SAAS,IAAI,OAAO;GAC1B,IAAI,UAAU;GACd,KAAK,MAAM,OAAO,IAAI,KAAK,GAAG;IAC5B,IAAI,WAAW,QAAQ;IACvB,IAAI,OAAO,GAAG;IACd;GACF;EACF;CACF;CAEA,OAAO;EACL,IAAI,KAAsB;GACxB,MAAM,QAAQ,IAAI,IAAI,GAAG;GACzB,IAAI,CAAC,OAAO,OAAO,KAAA;GACnB,IAAI,KAAK,IAAI,IAAI,MAAM,KAAK,OAAO;IACjC,IAAI,OAAO,GAAG;IACd;GACF;GACA,OAAO,MAAM;EACf;EACA,IAAI,KAAa,MAAqB;GACpC,IAAI,IAAI,KAAK;IAAE,IAAI,KAAK,IAAI;IAAG;GAAK,CAAC;GACrC,IAAI,IAAI,OAAO,SAAS,MAAM;EAChC;EACA,QAAc;GACZ,IAAI,MAAM;EACZ;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"langfuse-creds.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-creds.ts"],"sourcesContent":["import {\n missingEnvVars,\n readWorkspaceEnvLocal,\n WORKSPACE_ENV_FILE_NAME,\n} from \"./workspace-env\";\n\ninterface LangfuseCreds {\n host: string;\n auth: string; // Base64 encoded public:secret\n connection: LangfuseConnectionStatus;\n}\n\nexport interface LangfuseConnectionStatus {\n state:\n | \"connected\"\n | \"missing_root_env\"\n | \"auth_failed\"\n | \"query_failed\"\n | \"network_error\";\n message: string;\n remediation: string;\n requiredEnvVars: string[];\n expectedEnvFile: string;\n missingEnvVars: string[];\n detail?: string;\n}\n\nconst REQUIRED_LANGFUSE_ENV = [\n \"LANGFUSE_HOST\",\n \"LANGFUSE_PUBLIC_KEY\",\n \"LANGFUSE_SECRET_KEY\",\n];\n\nexport function resolveLangfuseCreds(): LangfuseCreds {\n const env = readWorkspaceEnvLocal();\n const missing = missingEnvVars(env, REQUIRED_LANGFUSE_ENV);\n if (missing.length > 0) {\n return {\n host: \"\",\n auth: \"\",\n connection: langfuseStatus(\"missing_root_env\", {\n missingEnvVars: missing,\n }),\n };\n }\n\n const creds = resolveCredsFromEnv(env);\n return {\n ...creds,\n connection: langfuseStatus(\"connected\"),\n };\n}\n\nfunction resolveCredsFromEnv(\n env: Record<string, string | undefined>,\n): Omit<LangfuseCreds, \"connection\"> {\n const host = env.LANGFUSE_HOST || env.LANGFUSE_BASE_URL || \"\";\n const pub = env.LANGFUSE_PUBLIC_KEY ?? \"\";\n const sec = env.LANGFUSE_SECRET_KEY ?? \"\";\n if (!pub || !sec) {\n return { host, auth: \"\" };\n }\n return {\n host,\n auth: Buffer.from(`${pub}:${sec}`).toString(\"base64\"),\n };\n}\n\nexport function langfuseStatus(\n state: LangfuseConnectionStatus[\"state\"],\n options: { missingEnvVars?: string[]; detail?: string } = {},\n): LangfuseConnectionStatus {\n const common = {\n requiredEnvVars: REQUIRED_LANGFUSE_ENV,\n expectedEnvFile: WORKSPACE_ENV_FILE_NAME,\n missingEnvVars: options.missingEnvVars ?? [],\n detail: options.detail,\n };\n\n if (state === \"connected\") {\n return {\n ...common,\n state,\n message: \"Langfuse is connected.\",\n remediation:\n \"Kaizen is reading Langfuse credentials from the workspace root .env.local file.\",\n };\n }\n if (state === \"missing_root_env\") {\n return {\n ...common,\n state,\n message:\n \"Langfuse credentials are missing from the workspace root .env.local file.\",\n remediation:\n \"Add LANGFUSE_HOST, LANGFUSE_PUBLIC_KEY, and LANGFUSE_SECRET_KEY to the repo root .env.local file, then refresh this view.\",\n };\n }\n if (state === \"auth_failed\") {\n return {\n ...common,\n state,\n message:\n \"Langfuse rejected the credentials in the workspace root .env.local file.\",\n remediation:\n \"Replace the Langfuse values in the repo root .env.local file with valid credentials, then refresh this view.\",\n };\n }\n if (state === \"query_failed\") {\n return {\n ...common,\n state,\n message: \"Kaizen reached Langfuse, but the data query failed.\",\n remediation:\n \"Check the selected dataset or trace in Langfuse, then refresh this view.\",\n };\n }\n return {\n ...common,\n state,\n message: \"Kaizen could not reach Langfuse.\",\n remediation:\n \"Check network access to Langfuse and confirm the repo root .env.local values are correct, then refresh this view.\",\n };\n}\n"],"mappings":";;AA2BA,MAAM,wBAAwB;CAC5B;CACA;CACA;CACD;AAED,SAAgB,uBAAsC;CACpD,MAAM,MAAM,uBAAuB;CACnC,MAAM,UAAU,eAAe,KAAK,sBAAsB;AAC1D,KAAI,QAAQ,SAAS,EACnB,QAAO;EACL,MAAM;EACN,MAAM;EACN,YAAY,eAAe,oBAAoB,EAC7C,gBAAgB,SACjB,CAAC;EACH;AAIH,QAAO;EACL,GAFY,oBAAoB,IAExB;EACR,YAAY,eAAe,YAAY;EACxC;;AAGH,SAAS,oBACP,KACmC;CACnC,MAAM,OAAO,IAAI,iBAAiB,IAAI,qBAAqB;CAC3D,MAAM,MAAM,IAAI,uBAAuB;CACvC,MAAM,MAAM,IAAI,uBAAuB;AACvC,KAAI,CAAC,OAAO,CAAC,IACX,QAAO;EAAE;EAAM,MAAM;EAAI;AAE3B,QAAO;EACL;EACA,MAAM,OAAO,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC,SAAS,SAAS;EACtD;;AAGH,SAAgB,eACd,OACA,UAA0D,EAAE,EAClC;CAC1B,MAAM,SAAS;EACb,iBAAiB;EACjB,iBAAiB;EACjB,gBAAgB,QAAQ,kBAAkB,EAAE;EAC5C,QAAQ,QAAQ;EACjB;AAED,KAAI,UAAU,YACZ,QAAO;EACL,GAAG;EACH;EACA,SAAS;EACT,aACE;EACH;AAEH,KAAI,UAAU,mBACZ,QAAO;EACL,GAAG;EACH;EACA,SACE;EACF,aACE;EACH;AAEH,KAAI,UAAU,cACZ,QAAO;EACL,GAAG;EACH;EACA,SACE;EACF,aACE;EACH;AAEH,KAAI,UAAU,eACZ,QAAO;EACL,GAAG;EACH;EACA,SAAS;EACT,aACE;EACH;AAEH,QAAO;EACL,GAAG;EACH;EACA,SAAS;EACT,aACE;EACH"}
1
+ {"version":3,"file":"langfuse-creds.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-creds.ts"],"sourcesContent":["import {\n missingEnvVars,\n readWorkspaceEnvLocal,\n WORKSPACE_ENV_FILE_NAME,\n} from \"./workspace-env\";\n\ninterface LangfuseCreds {\n host: string;\n auth: string; // Base64 encoded public:secret\n connection: LangfuseConnectionStatus;\n}\n\nexport interface LangfuseConnectionStatus {\n state:\n | \"connected\"\n | \"missing_root_env\"\n | \"auth_failed\"\n | \"query_failed\"\n | \"network_error\";\n message: string;\n remediation: string;\n requiredEnvVars: string[];\n expectedEnvFile: string;\n missingEnvVars: string[];\n detail?: string;\n}\n\nconst REQUIRED_LANGFUSE_ENV = [\n \"LANGFUSE_HOST\",\n \"LANGFUSE_PUBLIC_KEY\",\n \"LANGFUSE_SECRET_KEY\",\n];\n\nexport function resolveLangfuseCreds(): LangfuseCreds {\n const env = readWorkspaceEnvLocal();\n const missing = missingEnvVars(env, REQUIRED_LANGFUSE_ENV);\n if (missing.length > 0) {\n return {\n host: \"\",\n auth: \"\",\n connection: langfuseStatus(\"missing_root_env\", {\n missingEnvVars: missing,\n }),\n };\n }\n\n const creds = resolveCredsFromEnv(env);\n return {\n ...creds,\n connection: langfuseStatus(\"connected\"),\n };\n}\n\nfunction resolveCredsFromEnv(\n env: Record<string, string | undefined>,\n): Omit<LangfuseCreds, \"connection\"> {\n const host = env.LANGFUSE_HOST || env.LANGFUSE_BASE_URL || \"\";\n const pub = env.LANGFUSE_PUBLIC_KEY ?? \"\";\n const sec = env.LANGFUSE_SECRET_KEY ?? \"\";\n if (!pub || !sec) {\n return { host, auth: \"\" };\n }\n return {\n host,\n auth: Buffer.from(`${pub}:${sec}`).toString(\"base64\"),\n };\n}\n\nexport function langfuseStatus(\n state: LangfuseConnectionStatus[\"state\"],\n options: { missingEnvVars?: string[]; detail?: string } = {},\n): LangfuseConnectionStatus {\n const common = {\n requiredEnvVars: REQUIRED_LANGFUSE_ENV,\n expectedEnvFile: WORKSPACE_ENV_FILE_NAME,\n missingEnvVars: options.missingEnvVars ?? [],\n detail: options.detail,\n };\n\n if (state === \"connected\") {\n return {\n ...common,\n state,\n message: \"Langfuse is connected.\",\n remediation:\n \"Kaizen is reading Langfuse credentials from the workspace root .env.local file.\",\n };\n }\n if (state === \"missing_root_env\") {\n return {\n ...common,\n state,\n message:\n \"Langfuse credentials are missing from the workspace root .env.local file.\",\n remediation:\n \"Add LANGFUSE_HOST, LANGFUSE_PUBLIC_KEY, and LANGFUSE_SECRET_KEY to the repo root .env.local file, then refresh this view.\",\n };\n }\n if (state === \"auth_failed\") {\n return {\n ...common,\n state,\n message:\n \"Langfuse rejected the credentials in the workspace root .env.local file.\",\n remediation:\n \"Replace the Langfuse values in the repo root .env.local file with valid credentials, then refresh this view.\",\n };\n }\n if (state === \"query_failed\") {\n return {\n ...common,\n state,\n message: \"Kaizen reached Langfuse, but the data query failed.\",\n remediation:\n \"Check the selected dataset or trace in Langfuse, then refresh this view.\",\n };\n }\n return {\n ...common,\n state,\n message: \"Kaizen could not reach Langfuse.\",\n remediation:\n \"Check network access to Langfuse and confirm the repo root .env.local values are correct, then refresh this view.\",\n };\n}\n"],"mappings":";;AA2BA,MAAM,wBAAwB;CAC5B;CACA;CACA;AACF;AAEA,SAAgB,uBAAsC;CACpD,MAAM,MAAM,sBAAsB;CAClC,MAAM,UAAU,eAAe,KAAK,qBAAqB;CACzD,IAAI,QAAQ,SAAS,GACnB,OAAO;EACL,MAAM;EACN,MAAM;EACN,YAAY,eAAe,oBAAoB,EAC7C,gBAAgB,QAClB,CAAC;CACH;CAIF,OAAO;EACL,GAFY,oBAAoB,GAEzB;EACP,YAAY,eAAe,WAAW;CACxC;AACF;AAEA,SAAS,oBACP,KACmC;CACnC,MAAM,OAAO,IAAI,iBAAiB,IAAI,qBAAqB;CAC3D,MAAM,MAAM,IAAI,uBAAuB;CACvC,MAAM,MAAM,IAAI,uBAAuB;CACvC,IAAI,CAAC,OAAO,CAAC,KACX,OAAO;EAAE;EAAM,MAAM;CAAG;CAE1B,OAAO;EACL;EACA,MAAM,OAAO,KAAK,GAAG,IAAI,GAAG,KAAK,EAAE,SAAS,QAAQ;CACtD;AACF;AAEA,SAAgB,eACd,OACA,UAA0D,CAAC,GACjC;CAC1B,MAAM,SAAS;EACb,iBAAiB;EACjB,iBAAiB;EACjB,gBAAgB,QAAQ,kBAAkB,CAAC;EAC3C,QAAQ,QAAQ;CAClB;CAEA,IAAI,UAAU,aACZ,OAAO;EACL,GAAG;EACH;EACA,SAAS;EACT,aACE;CACJ;CAEF,IAAI,UAAU,oBACZ,OAAO;EACL,GAAG;EACH;EACA,SACE;EACF,aACE;CACJ;CAEF,IAAI,UAAU,eACZ,OAAO;EACL,GAAG;EACH;EACA,SACE;EACF,aACE;CACJ;CAEF,IAAI,UAAU,gBACZ,OAAO;EACL,GAAG;EACH;EACA,SAAS;EACT,aACE;CACJ;CAEF,OAAO;EACL,GAAG;EACH;EACA,SAAS;EACT,aACE;CACJ;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"langfuse-demo.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-demo.ts"],"sourcesContent":["/**\n * Demo/mock data for testing the Kaizen data management UI without a live\n * Langfuse connection. Enabled by setting KAIZEN_DEMO_MODE=1 in .env.local.\n *\n * All mock state lives in-memory on the server process so mutations\n * (create, delete, rename) persist across requests until the dev server\n * restarts.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RunStatus } from \"./types\";\nimport { getKaizenStateDir } from \"./workspace\";\n\nexport function isDemoMode(): boolean {\n return process.env.KAIZEN_DEMO_MODE === \"1\";\n}\n\n/* ────────────────────────── Mock Datasets ────────────────────────── */\n\ninterface MockDataset {\n id: string;\n name: string;\n description: string | null;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface MockDatasetItem {\n id: string;\n datasetName: string;\n status: string;\n sourceTraceId: string | null;\n input: unknown;\n expectedOutput: unknown;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface MockTrace {\n id: string;\n name: string;\n tags: string[];\n timestamp: string;\n input: unknown;\n output: unknown;\n metadata: Record<string, unknown> | null;\n}\n\nexport interface DemoRunTraceItem {\n id: string;\n score: number;\n traceId: string | null;\n breakdown?: Record<string, number>;\n}\n\nconst DEMO_TRACES_FILE = path.join(\"dist\", \"demo-traces.json\");\n\nconst now = new Date().toISOString();\nconst yesterday = new Date(Date.now() - 86_400_000).toISOString();\nconst twoDaysAgo = new Date(Date.now() - 172_800_000).toISOString();\n\nlet mockDatasets: MockDataset[] = [\n {\n id: \"ds-001\",\n name: \"golden-eval-set\",\n description: \"Primary evaluation dataset with curated examples\",\n metadata: null,\n createdAt: twoDaysAgo,\n updatedAt: yesterday,\n },\n {\n id: \"ds-002\",\n name: \"regression-tests\",\n description: \"Regression test cases from production issues\",\n metadata: null,\n createdAt: twoDaysAgo,\n updatedAt: twoDaysAgo,\n },\n {\n id: \"ds-003\",\n name: \"edge-cases\",\n description: null,\n metadata: null,\n createdAt: yesterday,\n updatedAt: yesterday,\n },\n];\n\nlet mockDatasetItems: MockDatasetItem[] = [\n {\n id: \"dsi-001\",\n datasetName: \"golden-eval-set\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-001\",\n input: { query: \"What is the capital of France?\", context: \"geography\" },\n expectedOutput: { answer: \"Paris\" },\n metadata: {\n callSummary: \"Geography question\",\n kaizen: { notes: \"Clean example\" },\n },\n createdAt: twoDaysAgo,\n updatedAt: yesterday,\n },\n {\n id: \"dsi-002\",\n datasetName: \"golden-eval-set\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-002\",\n input: { query: \"Summarize this document\", document: \"Lorem ipsum...\" },\n expectedOutput: { summary: \"A brief summary of the document.\" },\n metadata: {\n callSummary: \"Summarization task\",\n kaizen: { notes: \"Standard summarization\" },\n },\n createdAt: twoDaysAgo,\n updatedAt: twoDaysAgo,\n },\n {\n id: \"dsi-003\",\n datasetName: \"golden-eval-set\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-003\",\n input: { query: \"Translate to Spanish: Hello world\" },\n expectedOutput: { translation: \"Hola mundo\" },\n metadata: { callSummary: \"Translation request\" },\n createdAt: yesterday,\n updatedAt: yesterday,\n },\n {\n id: \"dsi-004\",\n datasetName: \"regression-tests\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-004\",\n input: { query: \"Calculate 2+2\", mode: \"math\" },\n expectedOutput: { result: 4 },\n metadata: {\n callSummary: \"Math calculation\",\n kaizen: { notes: \"Regression from v1.2\" },\n },\n createdAt: twoDaysAgo,\n updatedAt: twoDaysAgo,\n },\n {\n id: \"dsi-005\",\n datasetName: \"regression-tests\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-005\",\n input: { query: \"Parse this date: 2024-01-15\" },\n expectedOutput: { year: 2024, month: 1, day: 15 },\n metadata: { callSummary: \"Date parsing\" },\n createdAt: yesterday,\n updatedAt: yesterday,\n },\n];\n\nconst mockTraces: MockTrace[] = [\n {\n id: \"trace-001\",\n name: \"geography-qa\",\n tags: [\"eval\", \"geography\", \"qa\"],\n timestamp: twoDaysAgo,\n input: { query: \"What is the capital of France?\" },\n output: { answer: \"Paris\", confidence: 0.98 },\n metadata: { model: \"gpt-4\", latencyMs: 320 },\n },\n {\n id: \"trace-002\",\n name: \"document-summarize\",\n tags: [\"eval\", \"summarization\"],\n timestamp: twoDaysAgo,\n input: { query: \"Summarize this document\", document: \"Lorem ipsum...\" },\n output: { summary: \"A brief summary of the document.\" },\n metadata: { model: \"gpt-4\", latencyMs: 1240 },\n },\n {\n id: \"trace-003\",\n name: \"translate-en-es\",\n tags: [\"eval\", \"translation\", \"spanish\"],\n timestamp: yesterday,\n input: { query: \"Translate to Spanish: Hello world\" },\n output: { translation: \"Hola mundo\" },\n metadata: { model: \"gpt-3.5-turbo\", latencyMs: 180 },\n },\n {\n id: \"trace-004\",\n name: \"math-calc\",\n tags: [\"regression\", \"math\"],\n timestamp: twoDaysAgo,\n input: { query: \"Calculate 2+2\", mode: \"math\" },\n output: { result: 4, workShown: \"2 + 2 = 4\" },\n metadata: { model: \"gpt-4\", latencyMs: 95 },\n },\n {\n id: \"trace-005\",\n name: \"date-parser\",\n tags: [\"regression\", \"parsing\"],\n timestamp: yesterday,\n input: { query: \"Parse this date: 2024-01-15\" },\n output: { year: 2024, month: 1, day: 15 },\n metadata: { model: \"gpt-3.5-turbo\", latencyMs: 110 },\n },\n {\n id: \"trace-006\",\n name: \"sentiment-analysis\",\n tags: [\"analysis\", \"sentiment\"],\n timestamp: now,\n input: { text: \"I love this product! It's amazing.\" },\n output: { sentiment: \"positive\", score: 0.95 },\n metadata: { model: \"gpt-4\", latencyMs: 200 },\n },\n {\n id: \"trace-007\",\n name: \"code-review\",\n tags: [\"code\", \"review\"],\n timestamp: now,\n input: {\n code: \"function add(a, b) { return a + b; }\",\n language: \"javascript\",\n },\n output: {\n review: \"Clean implementation. Consider adding type annotations.\",\n },\n metadata: { model: \"gpt-4\", latencyMs: 850 },\n },\n {\n id: \"trace-008\",\n name: \"email-draft\",\n tags: [\"generation\", \"email\"],\n timestamp: now,\n input: { subject: \"Meeting follow-up\", tone: \"professional\" },\n output: { draft: \"Dear team, Thank you for attending today's meeting...\" },\n metadata: { model: \"gpt-4\", latencyMs: 520 },\n },\n];\n\nconst demoRuns = [\n {\n runId: \"demo-baseline\",\n runName: \"baseline-prompt\",\n parentId: null,\n dataset: \"golden-eval-set\",\n startedAt: \"2026-05-08T15:00:00.000Z\",\n updatedAt: \"2026-05-08T15:08:20.000Z\",\n score: 0.62,\n chartNotes: 0.6,\n followUp: 0.64,\n cost: 0.0082,\n latency: 9.4,\n traceIds: [\"trace-001\", \"trace-002\", \"trace-003\"],\n branch: \"kaizen/demo/baseline-prompt\",\n linearIssue: \"KZN-101\",\n },\n {\n runId: \"demo-structured-output\",\n runName: \"structured-output-sections\",\n parentId: \"demo-baseline\",\n dataset: \"golden-eval-set\",\n startedAt: \"2026-05-08T16:00:00.000Z\",\n updatedAt: \"2026-05-08T16:09:04.000Z\",\n score: 0.71,\n chartNotes: 0.74,\n followUp: 0.66,\n cost: 0.0088,\n latency: 9.8,\n traceIds: [\"trace-001\", \"trace-002\", \"trace-003\"],\n branch: \"kaizen/demo/structured-output-sections\",\n linearIssue: \"KZN-102\",\n },\n {\n runId: \"demo-grounded-follow-up\",\n runName: \"grounded-follow-up\",\n parentId: \"demo-structured-output\",\n dataset: \"golden-eval-set\",\n startedAt: \"2026-05-08T17:00:00.000Z\",\n updatedAt: \"2026-05-08T17:10:12.000Z\",\n score: 0.78,\n chartNotes: 0.75,\n followUp: 0.82,\n cost: 0.0095,\n latency: 10.6,\n traceIds: [\"trace-001\", \"trace-002\", \"trace-003\"],\n branch: \"kaizen/demo/grounded-follow-up\",\n linearIssue: \"KZN-103\",\n },\n {\n runId: \"demo-regression-baseline\",\n runName: \"regression-baseline\",\n parentId: null,\n dataset: \"regression-tests\",\n startedAt: \"2026-05-09T15:00:00.000Z\",\n updatedAt: \"2026-05-09T15:07:30.000Z\",\n score: 0.68,\n chartNotes: 0.7,\n followUp: 0.64,\n cost: 0.0065,\n latency: 8.1,\n traceIds: [\"trace-004\", \"trace-005\"],\n branch: \"kaizen/demo/regression-baseline\",\n linearIssue: \"KZN-104\",\n },\n {\n runId: \"demo-parser-repair\",\n runName: \"parser-repair\",\n parentId: \"demo-regression-baseline\",\n dataset: \"regression-tests\",\n startedAt: \"2026-05-09T16:00:00.000Z\",\n updatedAt: \"2026-05-09T16:06:45.000Z\",\n score: 0.84,\n chartNotes: 0.82,\n followUp: 0.86,\n cost: 0.0068,\n latency: 8.4,\n traceIds: [\"trace-004\", \"trace-005\"],\n branch: \"kaizen/demo/parser-repair\",\n linearIssue: \"KZN-105\",\n },\n] as const;\n\nlet nextItemId = 100;\n\n/* ────────────────────────── Public API ────────────────────────── */\n\nexport function getDemoDatasets(): MockDataset[] {\n return [...mockDatasets];\n}\n\nexport function getDemoDatasetItems(datasetName: string): MockDatasetItem[] {\n return mockDatasetItems.filter((i) => i.datasetName === datasetName);\n}\n\nexport function getDemoTraces(\n page: number,\n limit: number,\n tags?: string[],\n fromTimestamp?: string,\n toTimestamp?: string,\n): {\n data: MockTrace[];\n meta: { page: number; totalPages: number; totalItems: number };\n} {\n let filtered = getAllDemoTraces();\n if (tags && tags.length > 0) {\n filtered = filtered.filter((t) => tags.some((tag) => t.tags.includes(tag)));\n }\n const fromMs = parseTimestampMs(fromTimestamp);\n const toMs = parseTimestampMs(toTimestamp);\n if (fromMs !== null || toMs !== null) {\n filtered = filtered.filter((trace) => {\n const traceMs = parseTimestampMs(trace.timestamp);\n if (traceMs === null) return false;\n return (\n (fromMs === null || traceMs >= fromMs) &&\n (toMs === null || traceMs <= toMs)\n );\n });\n }\n const totalItems = filtered.length;\n const totalPages = Math.max(1, Math.ceil(totalItems / limit));\n const start = (page - 1) * limit;\n return {\n data: filtered.slice(start, start + limit),\n meta: { page, totalPages, totalItems },\n };\n}\n\nexport function getDemoTrace(traceId: string): MockTrace | null {\n return getAllDemoTraces().find((t) => t.id === traceId) ?? null;\n}\n\nexport function getDemoRunStatuses(): RunStatus[] {\n return demoRuns\n .map((run) => ({\n runId: run.runId,\n runName: run.runName,\n status: \"complete\" as const,\n worktreeBranch: run.branch,\n parentId: run.parentId,\n system: \"demo-system\",\n metrics: demoRunMetrics(run),\n totalItems: run.traceIds.length,\n linearIssue: {\n id: run.linearIssue,\n url: `https://linear.app/aitco/issue/${run.linearIssue}`,\n },\n evalConfig: {\n dataset: run.dataset,\n evalVersion: 1,\n datasetItemCount: run.traceIds.length,\n },\n startedAt: run.startedAt,\n updatedAt: run.updatedAt,\n }))\n .sort((a, b) => (b.startedAt < a.startedAt ? -1 : 1));\n}\n\nexport function getDemoRunTraceItems(runId: string): DemoRunTraceItem[] | null {\n const run = demoRuns.find((candidate) => candidate.runId === runId);\n if (!run) return null;\n return run.traceIds.map((traceId, index) => {\n const wobble = ((index % 3) - 1) * 0.018;\n const score = clampScore(run.score + wobble);\n return {\n id: `${run.dataset}-item-${index + 1}`,\n score,\n traceId,\n breakdown: {\n judge_quality: score,\n judge_quality_chartNotes: clampScore(run.chartNotes + wobble / 2),\n judge_quality_followUp: clampScore(run.followUp - wobble / 2),\n cost_per_item: Number((run.cost + index * 0.0002).toFixed(4)),\n avg_latency_s: Number((run.latency + index * 0.18).toFixed(2)),\n },\n };\n });\n}\n\nexport function createDemoDataset(\n name: string,\n description?: string,\n): MockDataset {\n const existing = mockDatasets.find((d) => d.name === name);\n if (existing) return existing;\n const ds: MockDataset = {\n id: `ds-${Date.now()}`,\n name,\n description: description ?? null,\n metadata: null,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n mockDatasets.push(ds);\n return ds;\n}\n\nexport function renameDemoDataset(oldName: string, newName: string): void {\n const ds = mockDatasets.find((d) => d.name === oldName);\n if (ds) {\n ds.name = newName;\n ds.updatedAt = new Date().toISOString();\n }\n for (const item of mockDatasetItems) {\n if (item.datasetName === oldName) {\n item.datasetName = newName;\n }\n }\n}\n\nexport function deleteDemoDatasetItems(datasetName: string): void {\n mockDatasetItems = mockDatasetItems.filter(\n (i) => i.datasetName !== datasetName,\n );\n // Also remove the dataset itself from the list so it disappears\n mockDatasets = mockDatasets.filter((d) => d.name !== datasetName);\n}\n\nexport function deleteDemoDatasetItem(itemId: string): void {\n mockDatasetItems = mockDatasetItems.filter((i) => i.id !== itemId);\n}\n\nexport function addDemoDatasetItemFromTrace(\n datasetName: string,\n traceId: string,\n options: {\n expectedOutput?: unknown;\n notes?: string;\n source?: string;\n } = {},\n): MockDatasetItem {\n const trace = getAllDemoTraces().find((t) => t.id === traceId);\n const nowIso = new Date().toISOString();\n const sourceUrl = options.source?.startsWith(\"http\") ? options.source : null;\n const baseMetadata: Record<string, unknown> = trace\n ? { ...trace.metadata, callSummary: trace.name }\n : {};\n const existingKaizen = isRecord(baseMetadata.kaizen)\n ? baseMetadata.kaizen\n : {};\n const metadata: Record<string, unknown> = {\n ...baseMetadata,\n sourceTraceId: traceId,\n kaizen: {\n ...existingKaizen,\n notes: options.notes ?? \"\",\n ...(sourceUrl ? { sourceUrl } : {}),\n lastEditedAt: nowIso,\n lastEditedBy: \"kaizen-studio\",\n lastAction: \"added\",\n ...(trace?.output === undefined || trace.output === null\n ? {}\n : { sourceOutput: trace.output }),\n },\n };\n const item: MockDatasetItem = {\n id: `dsi-auto-${nextItemId++}`,\n datasetName,\n status: \"ACTIVE\",\n sourceTraceId: traceId,\n input: trace?.input ?? {},\n expectedOutput:\n options.expectedOutput === undefined ? {} : options.expectedOutput,\n metadata,\n createdAt: nowIso,\n updatedAt: nowIso,\n };\n mockDatasetItems.push(item);\n return item;\n}\n\nexport function copyDemoDatasetItem(\n datasetName: string,\n item: {\n input: unknown;\n expectedOutput: unknown;\n metadata: Record<string, unknown> | null;\n sourceTraceId: string | null;\n status: string | null;\n },\n): MockDatasetItem {\n const nowIso = new Date().toISOString();\n const metadata = item.metadata\n ? {\n ...item.metadata,\n kaizen: {\n ...(isRecord(item.metadata.kaizen) ? item.metadata.kaizen : {}),\n lastEditedAt: nowIso,\n lastEditedBy: \"kaizen-studio\",\n lastAction: \"copied\",\n },\n }\n : null;\n const copied: MockDatasetItem = {\n id: `dsi-auto-${nextItemId++}`,\n datasetName,\n status: item.status ?? \"ACTIVE\",\n sourceTraceId: item.sourceTraceId,\n input: item.input,\n expectedOutput: item.expectedOutput,\n metadata,\n createdAt: nowIso,\n updatedAt: nowIso,\n };\n mockDatasetItems.push(copied);\n return copied;\n}\n\nfunction parseTimestampMs(value: string | undefined): number | null {\n if (!value) return null;\n const parsed = new Date(value).getTime();\n return Number.isNaN(parsed) ? null : parsed;\n}\n\nfunction getAllDemoTraces(): MockTrace[] {\n const generated = readGeneratedDemoTraces();\n if (generated.length === 0) return [...mockTraces];\n\n const byId = new Map<string, MockTrace>();\n for (const trace of generated) byId.set(trace.id, trace);\n for (const trace of mockTraces) {\n if (!byId.has(trace.id)) byId.set(trace.id, trace);\n }\n return [...byId.values()].sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(),\n );\n}\n\nfunction readGeneratedDemoTraces(): MockTrace[] {\n const filePath = path.join(getKaizenStateDir(), DEMO_TRACES_FILE);\n if (!fs.existsSync(filePath)) return [];\n\n try {\n const parsed = JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n if (!Array.isArray(parsed)) return [];\n return parsed.map(parseMockTrace).filter((t): t is MockTrace => t !== null);\n } catch {\n return [];\n }\n}\n\nfunction parseMockTrace(value: unknown): MockTrace | null {\n if (!isRecord(value)) return null;\n const id = stringValue(value.id);\n const name = stringValue(value.name);\n const timestamp = stringValue(value.timestamp);\n if (!id || !name || !timestamp) return null;\n\n return {\n id,\n name,\n tags: Array.isArray(value.tags)\n ? value.tags.filter((tag): tag is string => typeof tag === \"string\")\n : [],\n timestamp,\n input: value.input ?? null,\n output: value.output ?? null,\n metadata: isRecord(value.metadata) ? value.metadata : null,\n };\n}\n\nfunction demoRunMetrics(\n run: (typeof demoRuns)[number],\n): Record<string, number> {\n return {\n score: run.score,\n judge_quality: run.score,\n judge_quality_chartNotes: run.chartNotes,\n judge_quality_followUp: run.followUp,\n cost_per_item: run.cost,\n avg_latency_s: run.latency,\n };\n}\n\nfunction clampScore(value: number): number {\n return Number(Math.max(0, Math.min(1, value)).toFixed(3));\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringValue(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value : null;\n}\n\nexport const DEMO_CONNECTION = {\n state: \"connected\" as const,\n message: \"Demo mode — using mock data.\",\n remediation: \"Set KAIZEN_DEMO_MODE=1 in .env.local to enable demo mode.\",\n requiredEnvVars: [] as string[],\n expectedEnvFile: \".env.local\",\n missingEnvVars: [] as string[],\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"langfuse-demo.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-demo.ts"],"sourcesContent":["/**\n * Demo/mock data for testing the Kaizen data management UI without a live\n * Langfuse connection. Enabled by setting KAIZEN_DEMO_MODE=1 in .env.local.\n *\n * All mock state lives in-memory on the server process so mutations\n * (create, delete, rename) persist across requests until the dev server\n * restarts.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { RunStatus } from \"./types\";\nimport { getKaizenStateDir } from \"./workspace\";\n\nexport function isDemoMode(): boolean {\n return process.env.KAIZEN_DEMO_MODE === \"1\";\n}\n\n/* ────────────────────────── Mock Datasets ────────────────────────── */\n\ninterface MockDataset {\n id: string;\n name: string;\n description: string | null;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface MockDatasetItem {\n id: string;\n datasetName: string;\n status: string;\n sourceTraceId: string | null;\n input: unknown;\n expectedOutput: unknown;\n metadata: Record<string, unknown> | null;\n createdAt: string;\n updatedAt: string;\n}\n\ninterface MockTrace {\n id: string;\n name: string;\n tags: string[];\n timestamp: string;\n input: unknown;\n output: unknown;\n metadata: Record<string, unknown> | null;\n}\n\nexport interface DemoRunTraceItem {\n id: string;\n score: number;\n traceId: string | null;\n breakdown?: Record<string, number>;\n}\n\nconst DEMO_TRACES_FILE = path.join(\"dist\", \"demo-traces.json\");\n\nconst now = new Date().toISOString();\nconst yesterday = new Date(Date.now() - 86_400_000).toISOString();\nconst twoDaysAgo = new Date(Date.now() - 172_800_000).toISOString();\n\nlet mockDatasets: MockDataset[] = [\n {\n id: \"ds-001\",\n name: \"golden-eval-set\",\n description: \"Primary evaluation dataset with curated examples\",\n metadata: null,\n createdAt: twoDaysAgo,\n updatedAt: yesterday,\n },\n {\n id: \"ds-002\",\n name: \"regression-tests\",\n description: \"Regression test cases from production issues\",\n metadata: null,\n createdAt: twoDaysAgo,\n updatedAt: twoDaysAgo,\n },\n {\n id: \"ds-003\",\n name: \"edge-cases\",\n description: null,\n metadata: null,\n createdAt: yesterday,\n updatedAt: yesterday,\n },\n];\n\nlet mockDatasetItems: MockDatasetItem[] = [\n {\n id: \"dsi-001\",\n datasetName: \"golden-eval-set\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-001\",\n input: { query: \"What is the capital of France?\", context: \"geography\" },\n expectedOutput: { answer: \"Paris\" },\n metadata: {\n callSummary: \"Geography question\",\n kaizen: { notes: \"Clean example\" },\n },\n createdAt: twoDaysAgo,\n updatedAt: yesterday,\n },\n {\n id: \"dsi-002\",\n datasetName: \"golden-eval-set\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-002\",\n input: { query: \"Summarize this document\", document: \"Lorem ipsum...\" },\n expectedOutput: { summary: \"A brief summary of the document.\" },\n metadata: {\n callSummary: \"Summarization task\",\n kaizen: { notes: \"Standard summarization\" },\n },\n createdAt: twoDaysAgo,\n updatedAt: twoDaysAgo,\n },\n {\n id: \"dsi-003\",\n datasetName: \"golden-eval-set\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-003\",\n input: { query: \"Translate to Spanish: Hello world\" },\n expectedOutput: { translation: \"Hola mundo\" },\n metadata: { callSummary: \"Translation request\" },\n createdAt: yesterday,\n updatedAt: yesterday,\n },\n {\n id: \"dsi-004\",\n datasetName: \"regression-tests\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-004\",\n input: { query: \"Calculate 2+2\", mode: \"math\" },\n expectedOutput: { result: 4 },\n metadata: {\n callSummary: \"Math calculation\",\n kaizen: { notes: \"Regression from v1.2\" },\n },\n createdAt: twoDaysAgo,\n updatedAt: twoDaysAgo,\n },\n {\n id: \"dsi-005\",\n datasetName: \"regression-tests\",\n status: \"ACTIVE\",\n sourceTraceId: \"trace-005\",\n input: { query: \"Parse this date: 2024-01-15\" },\n expectedOutput: { year: 2024, month: 1, day: 15 },\n metadata: { callSummary: \"Date parsing\" },\n createdAt: yesterday,\n updatedAt: yesterday,\n },\n];\n\nconst mockTraces: MockTrace[] = [\n {\n id: \"trace-001\",\n name: \"geography-qa\",\n tags: [\"eval\", \"geography\", \"qa\"],\n timestamp: twoDaysAgo,\n input: { query: \"What is the capital of France?\" },\n output: { answer: \"Paris\", confidence: 0.98 },\n metadata: { model: \"gpt-4\", latencyMs: 320 },\n },\n {\n id: \"trace-002\",\n name: \"document-summarize\",\n tags: [\"eval\", \"summarization\"],\n timestamp: twoDaysAgo,\n input: { query: \"Summarize this document\", document: \"Lorem ipsum...\" },\n output: { summary: \"A brief summary of the document.\" },\n metadata: { model: \"gpt-4\", latencyMs: 1240 },\n },\n {\n id: \"trace-003\",\n name: \"translate-en-es\",\n tags: [\"eval\", \"translation\", \"spanish\"],\n timestamp: yesterday,\n input: { query: \"Translate to Spanish: Hello world\" },\n output: { translation: \"Hola mundo\" },\n metadata: { model: \"gpt-3.5-turbo\", latencyMs: 180 },\n },\n {\n id: \"trace-004\",\n name: \"math-calc\",\n tags: [\"regression\", \"math\"],\n timestamp: twoDaysAgo,\n input: { query: \"Calculate 2+2\", mode: \"math\" },\n output: { result: 4, workShown: \"2 + 2 = 4\" },\n metadata: { model: \"gpt-4\", latencyMs: 95 },\n },\n {\n id: \"trace-005\",\n name: \"date-parser\",\n tags: [\"regression\", \"parsing\"],\n timestamp: yesterday,\n input: { query: \"Parse this date: 2024-01-15\" },\n output: { year: 2024, month: 1, day: 15 },\n metadata: { model: \"gpt-3.5-turbo\", latencyMs: 110 },\n },\n {\n id: \"trace-006\",\n name: \"sentiment-analysis\",\n tags: [\"analysis\", \"sentiment\"],\n timestamp: now,\n input: { text: \"I love this product! It's amazing.\" },\n output: { sentiment: \"positive\", score: 0.95 },\n metadata: { model: \"gpt-4\", latencyMs: 200 },\n },\n {\n id: \"trace-007\",\n name: \"code-review\",\n tags: [\"code\", \"review\"],\n timestamp: now,\n input: {\n code: \"function add(a, b) { return a + b; }\",\n language: \"javascript\",\n },\n output: {\n review: \"Clean implementation. Consider adding type annotations.\",\n },\n metadata: { model: \"gpt-4\", latencyMs: 850 },\n },\n {\n id: \"trace-008\",\n name: \"email-draft\",\n tags: [\"generation\", \"email\"],\n timestamp: now,\n input: { subject: \"Meeting follow-up\", tone: \"professional\" },\n output: { draft: \"Dear team, Thank you for attending today's meeting...\" },\n metadata: { model: \"gpt-4\", latencyMs: 520 },\n },\n];\n\nconst demoRuns = [\n {\n runId: \"demo-baseline\",\n runName: \"baseline-prompt\",\n parentId: null,\n dataset: \"golden-eval-set\",\n startedAt: \"2026-05-08T15:00:00.000Z\",\n updatedAt: \"2026-05-08T15:08:20.000Z\",\n score: 0.62,\n chartNotes: 0.6,\n followUp: 0.64,\n cost: 0.0082,\n latency: 9.4,\n traceIds: [\"trace-001\", \"trace-002\", \"trace-003\"],\n branch: \"kaizen/demo/baseline-prompt\",\n linearIssue: \"KZN-101\",\n },\n {\n runId: \"demo-structured-output\",\n runName: \"structured-output-sections\",\n parentId: \"demo-baseline\",\n dataset: \"golden-eval-set\",\n startedAt: \"2026-05-08T16:00:00.000Z\",\n updatedAt: \"2026-05-08T16:09:04.000Z\",\n score: 0.71,\n chartNotes: 0.74,\n followUp: 0.66,\n cost: 0.0088,\n latency: 9.8,\n traceIds: [\"trace-001\", \"trace-002\", \"trace-003\"],\n branch: \"kaizen/demo/structured-output-sections\",\n linearIssue: \"KZN-102\",\n },\n {\n runId: \"demo-grounded-follow-up\",\n runName: \"grounded-follow-up\",\n parentId: \"demo-structured-output\",\n dataset: \"golden-eval-set\",\n startedAt: \"2026-05-08T17:00:00.000Z\",\n updatedAt: \"2026-05-08T17:10:12.000Z\",\n score: 0.78,\n chartNotes: 0.75,\n followUp: 0.82,\n cost: 0.0095,\n latency: 10.6,\n traceIds: [\"trace-001\", \"trace-002\", \"trace-003\"],\n branch: \"kaizen/demo/grounded-follow-up\",\n linearIssue: \"KZN-103\",\n },\n {\n runId: \"demo-regression-baseline\",\n runName: \"regression-baseline\",\n parentId: null,\n dataset: \"regression-tests\",\n startedAt: \"2026-05-09T15:00:00.000Z\",\n updatedAt: \"2026-05-09T15:07:30.000Z\",\n score: 0.68,\n chartNotes: 0.7,\n followUp: 0.64,\n cost: 0.0065,\n latency: 8.1,\n traceIds: [\"trace-004\", \"trace-005\"],\n branch: \"kaizen/demo/regression-baseline\",\n linearIssue: \"KZN-104\",\n },\n {\n runId: \"demo-parser-repair\",\n runName: \"parser-repair\",\n parentId: \"demo-regression-baseline\",\n dataset: \"regression-tests\",\n startedAt: \"2026-05-09T16:00:00.000Z\",\n updatedAt: \"2026-05-09T16:06:45.000Z\",\n score: 0.84,\n chartNotes: 0.82,\n followUp: 0.86,\n cost: 0.0068,\n latency: 8.4,\n traceIds: [\"trace-004\", \"trace-005\"],\n branch: \"kaizen/demo/parser-repair\",\n linearIssue: \"KZN-105\",\n },\n] as const;\n\nlet nextItemId = 100;\n\n/* ────────────────────────── Public API ────────────────────────── */\n\nexport function getDemoDatasets(): MockDataset[] {\n return [...mockDatasets];\n}\n\nexport function getDemoDatasetItems(datasetName: string): MockDatasetItem[] {\n return mockDatasetItems.filter((i) => i.datasetName === datasetName);\n}\n\nexport function getDemoTraces(\n page: number,\n limit: number,\n tags?: string[],\n fromTimestamp?: string,\n toTimestamp?: string,\n): {\n data: MockTrace[];\n meta: { page: number; totalPages: number; totalItems: number };\n} {\n let filtered = getAllDemoTraces();\n if (tags && tags.length > 0) {\n filtered = filtered.filter((t) => tags.some((tag) => t.tags.includes(tag)));\n }\n const fromMs = parseTimestampMs(fromTimestamp);\n const toMs = parseTimestampMs(toTimestamp);\n if (fromMs !== null || toMs !== null) {\n filtered = filtered.filter((trace) => {\n const traceMs = parseTimestampMs(trace.timestamp);\n if (traceMs === null) return false;\n return (\n (fromMs === null || traceMs >= fromMs) &&\n (toMs === null || traceMs <= toMs)\n );\n });\n }\n const totalItems = filtered.length;\n const totalPages = Math.max(1, Math.ceil(totalItems / limit));\n const start = (page - 1) * limit;\n return {\n data: filtered.slice(start, start + limit),\n meta: { page, totalPages, totalItems },\n };\n}\n\nexport function getDemoTrace(traceId: string): MockTrace | null {\n return getAllDemoTraces().find((t) => t.id === traceId) ?? null;\n}\n\nexport function getDemoRunStatuses(): RunStatus[] {\n return demoRuns\n .map((run) => ({\n runId: run.runId,\n runName: run.runName,\n status: \"complete\" as const,\n worktreeBranch: run.branch,\n parentId: run.parentId,\n system: \"demo-system\",\n metrics: demoRunMetrics(run),\n totalItems: run.traceIds.length,\n linearIssue: {\n id: run.linearIssue,\n url: `https://linear.app/aitco/issue/${run.linearIssue}`,\n },\n evalConfig: {\n dataset: run.dataset,\n evalVersion: 1,\n datasetItemCount: run.traceIds.length,\n },\n startedAt: run.startedAt,\n updatedAt: run.updatedAt,\n }))\n .sort((a, b) => (b.startedAt < a.startedAt ? -1 : 1));\n}\n\nexport function getDemoRunTraceItems(runId: string): DemoRunTraceItem[] | null {\n const run = demoRuns.find((candidate) => candidate.runId === runId);\n if (!run) return null;\n return run.traceIds.map((traceId, index) => {\n const wobble = ((index % 3) - 1) * 0.018;\n const score = clampScore(run.score + wobble);\n return {\n id: `${run.dataset}-item-${index + 1}`,\n score,\n traceId,\n breakdown: {\n judge_quality: score,\n judge_quality_chartNotes: clampScore(run.chartNotes + wobble / 2),\n judge_quality_followUp: clampScore(run.followUp - wobble / 2),\n cost_per_item: Number((run.cost + index * 0.0002).toFixed(4)),\n avg_latency_s: Number((run.latency + index * 0.18).toFixed(2)),\n },\n };\n });\n}\n\nexport function createDemoDataset(\n name: string,\n description?: string,\n): MockDataset {\n const existing = mockDatasets.find((d) => d.name === name);\n if (existing) return existing;\n const ds: MockDataset = {\n id: `ds-${Date.now()}`,\n name,\n description: description ?? null,\n metadata: null,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n mockDatasets.push(ds);\n return ds;\n}\n\nexport function renameDemoDataset(oldName: string, newName: string): void {\n const ds = mockDatasets.find((d) => d.name === oldName);\n if (ds) {\n ds.name = newName;\n ds.updatedAt = new Date().toISOString();\n }\n for (const item of mockDatasetItems) {\n if (item.datasetName === oldName) {\n item.datasetName = newName;\n }\n }\n}\n\nexport function deleteDemoDatasetItems(datasetName: string): void {\n mockDatasetItems = mockDatasetItems.filter(\n (i) => i.datasetName !== datasetName,\n );\n // Also remove the dataset itself from the list so it disappears\n mockDatasets = mockDatasets.filter((d) => d.name !== datasetName);\n}\n\nexport function deleteDemoDatasetItem(itemId: string): void {\n mockDatasetItems = mockDatasetItems.filter((i) => i.id !== itemId);\n}\n\nexport function addDemoDatasetItemFromTrace(\n datasetName: string,\n traceId: string,\n options: {\n expectedOutput?: unknown;\n notes?: string;\n source?: string;\n } = {},\n): MockDatasetItem {\n const trace = getAllDemoTraces().find((t) => t.id === traceId);\n const nowIso = new Date().toISOString();\n const sourceUrl = options.source?.startsWith(\"http\") ? options.source : null;\n const baseMetadata: Record<string, unknown> = trace\n ? { ...trace.metadata, callSummary: trace.name }\n : {};\n const existingKaizen = isRecord(baseMetadata.kaizen)\n ? baseMetadata.kaizen\n : {};\n const metadata: Record<string, unknown> = {\n ...baseMetadata,\n sourceTraceId: traceId,\n kaizen: {\n ...existingKaizen,\n notes: options.notes ?? \"\",\n ...(sourceUrl ? { sourceUrl } : {}),\n lastEditedAt: nowIso,\n lastEditedBy: \"kaizen-studio\",\n lastAction: \"added\",\n ...(trace?.output === undefined || trace.output === null\n ? {}\n : { sourceOutput: trace.output }),\n },\n };\n const item: MockDatasetItem = {\n id: `dsi-auto-${nextItemId++}`,\n datasetName,\n status: \"ACTIVE\",\n sourceTraceId: traceId,\n input: trace?.input ?? {},\n expectedOutput:\n options.expectedOutput === undefined ? {} : options.expectedOutput,\n metadata,\n createdAt: nowIso,\n updatedAt: nowIso,\n };\n mockDatasetItems.push(item);\n return item;\n}\n\nexport function copyDemoDatasetItem(\n datasetName: string,\n item: {\n input: unknown;\n expectedOutput: unknown;\n metadata: Record<string, unknown> | null;\n sourceTraceId: string | null;\n status: string | null;\n },\n): MockDatasetItem {\n const nowIso = new Date().toISOString();\n const metadata = item.metadata\n ? {\n ...item.metadata,\n kaizen: {\n ...(isRecord(item.metadata.kaizen) ? item.metadata.kaizen : {}),\n lastEditedAt: nowIso,\n lastEditedBy: \"kaizen-studio\",\n lastAction: \"copied\",\n },\n }\n : null;\n const copied: MockDatasetItem = {\n id: `dsi-auto-${nextItemId++}`,\n datasetName,\n status: item.status ?? \"ACTIVE\",\n sourceTraceId: item.sourceTraceId,\n input: item.input,\n expectedOutput: item.expectedOutput,\n metadata,\n createdAt: nowIso,\n updatedAt: nowIso,\n };\n mockDatasetItems.push(copied);\n return copied;\n}\n\nfunction parseTimestampMs(value: string | undefined): number | null {\n if (!value) return null;\n const parsed = new Date(value).getTime();\n return Number.isNaN(parsed) ? null : parsed;\n}\n\nfunction getAllDemoTraces(): MockTrace[] {\n const generated = readGeneratedDemoTraces();\n if (generated.length === 0) return [...mockTraces];\n\n const byId = new Map<string, MockTrace>();\n for (const trace of generated) byId.set(trace.id, trace);\n for (const trace of mockTraces) {\n if (!byId.has(trace.id)) byId.set(trace.id, trace);\n }\n return [...byId.values()].sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(),\n );\n}\n\nfunction readGeneratedDemoTraces(): MockTrace[] {\n const filePath = path.join(getKaizenStateDir(), DEMO_TRACES_FILE);\n if (!fs.existsSync(filePath)) return [];\n\n try {\n const parsed = JSON.parse(fs.readFileSync(filePath, \"utf-8\"));\n if (!Array.isArray(parsed)) return [];\n return parsed.map(parseMockTrace).filter((t): t is MockTrace => t !== null);\n } catch {\n return [];\n }\n}\n\nfunction parseMockTrace(value: unknown): MockTrace | null {\n if (!isRecord(value)) return null;\n const id = stringValue(value.id);\n const name = stringValue(value.name);\n const timestamp = stringValue(value.timestamp);\n if (!id || !name || !timestamp) return null;\n\n return {\n id,\n name,\n tags: Array.isArray(value.tags)\n ? value.tags.filter((tag): tag is string => typeof tag === \"string\")\n : [],\n timestamp,\n input: value.input ?? null,\n output: value.output ?? null,\n metadata: isRecord(value.metadata) ? value.metadata : null,\n };\n}\n\nfunction demoRunMetrics(\n run: (typeof demoRuns)[number],\n): Record<string, number> {\n return {\n score: run.score,\n judge_quality: run.score,\n judge_quality_chartNotes: run.chartNotes,\n judge_quality_followUp: run.followUp,\n cost_per_item: run.cost,\n avg_latency_s: run.latency,\n };\n}\n\nfunction clampScore(value: number): number {\n return Number(Math.max(0, Math.min(1, value)).toFixed(3));\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringValue(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value : null;\n}\n\nexport const DEMO_CONNECTION = {\n state: \"connected\" as const,\n message: \"Demo mode — using mock data.\",\n remediation: \"Set KAIZEN_DEMO_MODE=1 in .env.local to enable demo mode.\",\n requiredEnvVars: [] as string[],\n expectedEnvFile: \".env.local\",\n missingEnvVars: [] as string[],\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"langfuse-errors.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-errors.ts"],"sourcesContent":["export async function formatLangfuseHttpError(\n res: Response,\n resource: string,\n): Promise<string> {\n const detail = await extractReadableDetail(res);\n const status = `Langfuse returned ${res.status}${\n res.statusText ? ` ${res.statusText}` : \"\"\n }.`;\n\n const remediation =\n res.status === 401 || res.status === 403\n ? \"Check that the Langfuse host and API keys are for the right workspace and have access to this data.\"\n : res.status === 404\n ? \"Confirm the selected dataset or trace still exists in Langfuse.\"\n : res.status >= 500\n ? \"Langfuse may be temporarily unavailable. Try refreshing in a moment.\"\n : \"Check the Langfuse connection and try refreshing.\";\n\n return [\n `Kaizen could not load ${resource} from Langfuse.`,\n status,\n remediation,\n detail ? `Detail: ${detail}` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n}\n\nexport function formatLangfuseRequestError(err: unknown): string {\n if (err instanceof Error && err.name === \"AbortError\") {\n return \"Kaizen could not load Langfuse data because Langfuse did not respond in time. Check your connection and try refreshing.\";\n }\n\n const detail =\n err instanceof Error && err.message.trim()\n ? ` Detail: ${truncate(err.message.trim())}`\n : \"\";\n return `Kaizen could not reach Langfuse. Check your network or VPN, confirm the Langfuse host is reachable, then refresh.${detail}`;\n}\n\nasync function extractReadableDetail(res: Response): Promise<string | null> {\n const text = await res.text().catch(() => \"\");\n if (!text.trim() || looksLikeHtml(text)) return null;\n\n try {\n const parsed = JSON.parse(text) as unknown;\n const message = extractJsonMessage(parsed);\n if (message) return truncate(message);\n } catch {\n // Plain text responses are handled below.\n }\n\n return truncate(text.replace(/\\s+/g, \" \").trim());\n}\n\nfunction extractJsonMessage(value: unknown): string | null {\n if (!isRecord(value)) return null;\n for (const key of [\"message\", \"error\", \"detail\"]) {\n const candidate = value[key];\n if (typeof candidate === \"string\" && candidate.trim()) {\n return candidate.trim();\n }\n }\n return null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction looksLikeHtml(text: string): boolean {\n const trimmed = text.trim().toLowerCase();\n return (\n trimmed.startsWith(\"<!doctype html\") ||\n trimmed.startsWith(\"<html\") ||\n /<body[\\s>]/.test(trimmed)\n );\n}\n\nfunction truncate(text: string): string {\n return text.length > 180 ? `${text.slice(0, 177)}...` : text;\n}\n"],"mappings":";AAAA,eAAsB,wBACpB,KACA,UACiB;CACjB,MAAM,SAAS,MAAM,sBAAsB,IAAI;CAC/C,MAAM,SAAS,qBAAqB,IAAI,SACtC,IAAI,aAAa,IAAI,IAAI,eAAe,GACzC;CAED,MAAM,cACJ,IAAI,WAAW,OAAO,IAAI,WAAW,MACjC,wGACA,IAAI,WAAW,MACb,oEACA,IAAI,UAAU,MACZ,yEACA;AAEV,QAAO;EACL,yBAAyB,SAAS;EAClC;EACA;EACA,SAAS,WAAW,WAAW;EAChC,CACE,OAAO,QAAQ,CACf,KAAK,IAAI;;AAGd,SAAgB,2BAA2B,KAAsB;AAC/D,KAAI,eAAe,SAAS,IAAI,SAAS,aACvC,QAAO;AAOT,QAAO,oHAHL,eAAe,SAAS,IAAI,QAAQ,MAAM,GACtC,YAAY,SAAS,IAAI,QAAQ,MAAM,CAAC,KACxC;;AAIR,eAAe,sBAAsB,KAAuC;CAC1E,MAAM,OAAO,MAAM,IAAI,MAAM,CAAC,YAAY,GAAG;AAC7C,KAAI,CAAC,KAAK,MAAM,IAAI,cAAc,KAAK,CAAE,QAAO;AAEhD,KAAI;EAEF,MAAM,UAAU,mBADD,KAAK,MAAM,KACe,CAAC;AAC1C,MAAI,QAAS,QAAO,SAAS,QAAQ;SAC/B;AAIR,QAAO,SAAS,KAAK,QAAQ,QAAQ,IAAI,CAAC,MAAM,CAAC;;AAGnD,SAAS,mBAAmB,OAA+B;AACzD,KAAI,CAAC,SAAS,MAAM,CAAE,QAAO;AAC7B,MAAK,MAAM,OAAO;EAAC;EAAW;EAAS;EAAS,EAAE;EAChD,MAAM,YAAY,MAAM;AACxB,MAAI,OAAO,cAAc,YAAY,UAAU,MAAM,CACnD,QAAO,UAAU,MAAM;;AAG3B,QAAO;;AAGT,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;AAG7E,SAAS,cAAc,MAAuB;CAC5C,MAAM,UAAU,KAAK,MAAM,CAAC,aAAa;AACzC,QACE,QAAQ,WAAW,iBAAiB,IACpC,QAAQ,WAAW,QAAQ,IAC3B,aAAa,KAAK,QAAQ;;AAI9B,SAAS,SAAS,MAAsB;AACtC,QAAO,KAAK,SAAS,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO"}
1
+ {"version":3,"file":"langfuse-errors.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-errors.ts"],"sourcesContent":["export async function formatLangfuseHttpError(\n res: Response,\n resource: string,\n): Promise<string> {\n const detail = await extractReadableDetail(res);\n const status = `Langfuse returned ${res.status}${\n res.statusText ? ` ${res.statusText}` : \"\"\n }.`;\n\n const remediation =\n res.status === 401 || res.status === 403\n ? \"Check that the Langfuse host and API keys are for the right workspace and have access to this data.\"\n : res.status === 404\n ? \"Confirm the selected dataset or trace still exists in Langfuse.\"\n : res.status >= 500\n ? \"Langfuse may be temporarily unavailable. Try refreshing in a moment.\"\n : \"Check the Langfuse connection and try refreshing.\";\n\n return [\n `Kaizen could not load ${resource} from Langfuse.`,\n status,\n remediation,\n detail ? `Detail: ${detail}` : null,\n ]\n .filter(Boolean)\n .join(\" \");\n}\n\nexport function formatLangfuseRequestError(err: unknown): string {\n if (err instanceof Error && err.name === \"AbortError\") {\n return \"Kaizen could not load Langfuse data because Langfuse did not respond in time. Check your connection and try refreshing.\";\n }\n\n const detail =\n err instanceof Error && err.message.trim()\n ? ` Detail: ${truncate(err.message.trim())}`\n : \"\";\n return `Kaizen could not reach Langfuse. Check your network or VPN, confirm the Langfuse host is reachable, then refresh.${detail}`;\n}\n\nasync function extractReadableDetail(res: Response): Promise<string | null> {\n const text = await res.text().catch(() => \"\");\n if (!text.trim() || looksLikeHtml(text)) return null;\n\n try {\n const parsed = JSON.parse(text) as unknown;\n const message = extractJsonMessage(parsed);\n if (message) return truncate(message);\n } catch {\n // Plain text responses are handled below.\n }\n\n return truncate(text.replace(/\\s+/g, \" \").trim());\n}\n\nfunction extractJsonMessage(value: unknown): string | null {\n if (!isRecord(value)) return null;\n for (const key of [\"message\", \"error\", \"detail\"]) {\n const candidate = value[key];\n if (typeof candidate === \"string\" && candidate.trim()) {\n return candidate.trim();\n }\n }\n return null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction looksLikeHtml(text: string): boolean {\n const trimmed = text.trim().toLowerCase();\n return (\n trimmed.startsWith(\"<!doctype html\") ||\n trimmed.startsWith(\"<html\") ||\n /<body[\\s>]/.test(trimmed)\n );\n}\n\nfunction truncate(text: string): string {\n return text.length > 180 ? `${text.slice(0, 177)}...` : text;\n}\n"],"mappings":";AAAA,eAAsB,wBACpB,KACA,UACiB;CACjB,MAAM,SAAS,MAAM,sBAAsB,GAAG;CAC9C,MAAM,SAAS,qBAAqB,IAAI,SACtC,IAAI,aAAa,IAAI,IAAI,eAAe,GACzC;CAED,MAAM,cACJ,IAAI,WAAW,OAAO,IAAI,WAAW,MACjC,wGACA,IAAI,WAAW,MACb,oEACA,IAAI,UAAU,MACZ,yEACA;CAEV,OAAO;EACL,yBAAyB,SAAS;EAClC;EACA;EACA,SAAS,WAAW,WAAW;CACjC,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACb;AAEA,SAAgB,2BAA2B,KAAsB;CAC/D,IAAI,eAAe,SAAS,IAAI,SAAS,cACvC,OAAO;CAOT,OAAO,oHAHL,eAAe,SAAS,IAAI,QAAQ,KAAK,IACrC,YAAY,SAAS,IAAI,QAAQ,KAAK,CAAC,MACvC;AAER;AAEA,eAAe,sBAAsB,KAAuC;CAC1E,MAAM,OAAO,MAAM,IAAI,KAAK,EAAE,YAAY,EAAE;CAC5C,IAAI,CAAC,KAAK,KAAK,KAAK,cAAc,IAAI,GAAG,OAAO;CAEhD,IAAI;EAEF,MAAM,UAAU,mBADD,KAAK,MAAM,IACc,CAAC;EACzC,IAAI,SAAS,OAAO,SAAS,OAAO;CACtC,QAAQ,CAER;CAEA,OAAO,SAAS,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK,CAAC;AAClD;AAEA,SAAS,mBAAmB,OAA+B;CACzD,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;CAC7B,KAAK,MAAM,OAAO;EAAC;EAAW;EAAS;CAAQ,GAAG;EAChD,MAAM,YAAY,MAAM;EACxB,IAAI,OAAO,cAAc,YAAY,UAAU,KAAK,GAClD,OAAO,UAAU,KAAK;CAE1B;CACA,OAAO;AACT;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,cAAc,MAAuB;CAC5C,MAAM,UAAU,KAAK,KAAK,EAAE,YAAY;CACxC,OACE,QAAQ,WAAW,gBAAgB,KACnC,QAAQ,WAAW,OAAO,KAC1B,aAAa,KAAK,OAAO;AAE7B;AAEA,SAAS,SAAS,MAAsB;CACtC,OAAO,KAAK,SAAS,MAAM,GAAG,KAAK,MAAM,GAAG,GAAG,EAAE,OAAO;AAC1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"langfuse-helpers.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-helpers.ts"],"sourcesContent":["/**\n * Shared helpers for Langfuse API route handlers.\n */\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Extract source trace ID from a dataset item, falling back to metadata\n * fields that some Langfuse deployments use instead of the top-level field.\n */\nexport function getSourceTraceId(item: unknown): string | null {\n if (!isRecord(item)) return null;\n if (typeof item.sourceTraceId === \"string\" && item.sourceTraceId) {\n return item.sourceTraceId;\n }\n const metadata = item.metadata;\n if (isRecord(metadata)) {\n const maybeTrace = metadata.sourceTraceId ?? metadata.traceId;\n if (typeof maybeTrace === \"string\" && maybeTrace) return maybeTrace;\n }\n return null;\n}\n"],"mappings":";;;;AAIA,SAAgB,SAAS,OAAkD;AACzE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM;;;;;;AAO7E,SAAgB,iBAAiB,MAA8B;AAC7D,KAAI,CAAC,SAAS,KAAK,CAAE,QAAO;AAC5B,KAAI,OAAO,KAAK,kBAAkB,YAAY,KAAK,cACjD,QAAO,KAAK;CAEd,MAAM,WAAW,KAAK;AACtB,KAAI,SAAS,SAAS,EAAE;EACtB,MAAM,aAAa,SAAS,iBAAiB,SAAS;AACtD,MAAI,OAAO,eAAe,YAAY,WAAY,QAAO;;AAE3D,QAAO"}
1
+ {"version":3,"file":"langfuse-helpers.js","names":[],"sources":["../../../../dashboard/src/lib/langfuse-helpers.ts"],"sourcesContent":["/**\n * Shared helpers for Langfuse API route handlers.\n */\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Extract source trace ID from a dataset item, falling back to metadata\n * fields that some Langfuse deployments use instead of the top-level field.\n */\nexport function getSourceTraceId(item: unknown): string | null {\n if (!isRecord(item)) return null;\n if (typeof item.sourceTraceId === \"string\" && item.sourceTraceId) {\n return item.sourceTraceId;\n }\n const metadata = item.metadata;\n if (isRecord(metadata)) {\n const maybeTrace = metadata.sourceTraceId ?? metadata.traceId;\n if (typeof maybeTrace === \"string\" && maybeTrace) return maybeTrace;\n }\n return null;\n}\n"],"mappings":";;;;AAIA,SAAgB,SAAS,OAAkD;CACzE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;;;AAMA,SAAgB,iBAAiB,MAA8B;CAC7D,IAAI,CAAC,SAAS,IAAI,GAAG,OAAO;CAC5B,IAAI,OAAO,KAAK,kBAAkB,YAAY,KAAK,eACjD,OAAO,KAAK;CAEd,MAAM,WAAW,KAAK;CACtB,IAAI,SAAS,QAAQ,GAAG;EACtB,MAAM,aAAa,SAAS,iBAAiB,SAAS;EACtD,IAAI,OAAO,eAAe,YAAY,YAAY,OAAO;CAC3D;CACA,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-api.js","names":[],"sources":["../../../../dashboard/src/lib/run-api.ts"],"sourcesContent":["export function isSafeRunPathSegment(value: string): boolean {\n return (\n value.length > 0 &&\n !value.includes(\"..\") &&\n !value.includes(\"/\") &&\n !value.includes(\"\\\\\")\n );\n}\n"],"mappings":";AAAA,SAAgB,qBAAqB,OAAwB;AAC3D,QACE,MAAM,SAAS,KACf,CAAC,MAAM,SAAS,KAAK,IACrB,CAAC,MAAM,SAAS,IAAI,IACpB,CAAC,MAAM,SAAS,KAAK"}
1
+ {"version":3,"file":"run-api.js","names":[],"sources":["../../../../dashboard/src/lib/run-api.ts"],"sourcesContent":["export function isSafeRunPathSegment(value: string): boolean {\n return (\n value.length > 0 &&\n !value.includes(\"..\") &&\n !value.includes(\"/\") &&\n !value.includes(\"\\\\\")\n );\n}\n"],"mappings":";AAAA,SAAgB,qBAAqB,OAAwB;CAC3D,OACE,MAAM,SAAS,KACf,CAAC,MAAM,SAAS,IAAI,KACpB,CAAC,MAAM,SAAS,GAAG,KACnB,CAAC,MAAM,SAAS,IAAI;AAExB"}
@@ -1 +1 @@
1
- {"version":3,"file":"run-store.js","names":[],"sources":["../../../../dashboard/src/lib/run-store.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { normalizeLinearIssue } from \"../../../shared/linear-issue.js\";\nimport type { RunStatus } from \"./types\";\nimport { getKaizenStateDir } from \"./workspace\";\n\nexport interface RunManifest {\n run_id: string;\n system: string;\n variant: string;\n parent_id: string | null;\n hypothesis: string;\n eval_version: number;\n dataset_version: string;\n started_at: string;\n git_sha?: string | null;\n git_branch?: string | null;\n linear_issue_id?: string | null;\n linear_issue_url?: string | null;\n}\n\nexport interface RunState {\n run_id: string;\n status: \"complete\" | \"crashed\" | \"aborted\" | \"running\";\n score: number | null;\n n_total?: number | null;\n n_done?: number;\n promoted?: boolean | null;\n ended_at?: string | null;\n updated_at?: string;\n}\n\nexport interface RunRecord {\n manifest: RunManifest;\n state: RunState;\n dir: string;\n eventsPath: string;\n failuresPath: string;\n}\n\nexport function listRunRecords(systemId?: string): RunRecord[] {\n const stateDir = getKaizenStateDir();\n const runsRoot = path.join(stateDir, \"runs\");\n if (!fs.existsSync(runsRoot)) return [];\n\n const systemIds = systemId ? [systemId] : safeDirs(runsRoot);\n const out: RunRecord[] = [];\n\n for (const system of systemIds) {\n const systemDir = path.join(runsRoot, system);\n for (const runId of safeDirs(systemDir)) {\n const dir = path.join(systemDir, runId);\n const manifest = parseRunManifest(\n readJson(path.join(dir, \"manifest.json\")),\n );\n if (!manifest) continue;\n const state = parseRunState(readJson(path.join(dir, \"state.json\"))) ?? {\n run_id: manifest.run_id,\n status: \"running\",\n score: null,\n };\n out.push({\n manifest,\n state,\n dir,\n eventsPath: path.join(dir, \"events.jsonl\"),\n failuresPath: path.join(dir, \"failures.jsonl\"),\n });\n }\n }\n\n out.sort((a, b) => (b.manifest.started_at < a.manifest.started_at ? -1 : 1));\n return out;\n}\n\nexport function toRunStatus(run: RunRecord): RunStatus {\n const { manifest, state } = run;\n const metrics = readCompleteMetrics(run.eventsPath);\n if (state.score !== null) metrics.score = state.score;\n\n return {\n runId: manifest.run_id,\n runName: manifest.variant,\n status: state.status,\n worktreeBranch: manifest.git_branch ?? \"\",\n parentId: manifest.parent_id,\n system: manifest.system,\n progress: getProgress(manifest, state),\n metrics,\n totalItems: state.n_total ?? null,\n linearIssue:\n normalizeLinearIssue(\n manifest.linear_issue_url ?? manifest.linear_issue_id,\n ) ?? undefined,\n evalConfig: {\n dataset: manifest.dataset_version,\n evalVersion: manifest.eval_version,\n datasetItemCount: state.n_total ?? 0,\n },\n startedAt: manifest.started_at,\n updatedAt: state.ended_at ?? state.updated_at ?? manifest.started_at,\n };\n}\n\nfunction getProgress(\n manifest: RunManifest,\n state: RunState,\n): RunStatus[\"progress\"] {\n if (state.status === \"running\") {\n return {\n completed: state.n_done ?? 0,\n total: state.n_total ?? 0,\n lastHeartbeat: state.updated_at ?? manifest.started_at,\n };\n }\n\n if (\n (state.status === \"crashed\" || state.status === \"aborted\") &&\n typeof state.n_done === \"number\" &&\n typeof state.n_total === \"number\"\n ) {\n return {\n completed: state.n_done,\n total: state.n_total,\n lastHeartbeat: state.updated_at ?? state.ended_at ?? manifest.started_at,\n };\n }\n\n return undefined;\n}\n\nexport function readFailures(systemId: string, runId: string): unknown[] {\n const file = path.join(\n getKaizenStateDir(),\n \"runs\",\n systemId,\n runId,\n \"failures.jsonl\",\n );\n return readNdjson(file);\n}\n\nexport function readEvents(systemId: string, runId: string): unknown[] {\n const file = path.join(\n getKaizenStateDir(),\n \"runs\",\n systemId,\n runId,\n \"events.jsonl\",\n );\n return readNdjson(file);\n}\n\nfunction safeDirs(dir: string): string[] {\n try {\n return fs\n .readdirSync(dir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n } catch {\n return [];\n }\n}\n\nfunction readJson(file: string): unknown {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\nfunction readNdjson(file: string): unknown[] {\n try {\n return fs\n .readFileSync(file, \"utf-8\")\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => JSON.parse(line));\n } catch {\n return [];\n }\n}\n\nfunction readCompleteMetrics(eventsPath: string): Record<string, number> {\n const metrics: Record<string, number> = {};\n for (const event of readNdjson(eventsPath)) {\n if (!isRecord(event) || event.type !== \"complete\") continue;\n if (typeof event.score === \"number\") metrics.score = event.score;\n if (\n event.breakdown &&\n typeof event.breakdown === \"object\" &&\n !Array.isArray(event.breakdown)\n ) {\n for (const [key, value] of Object.entries(event.breakdown)) {\n if (typeof value === \"number\") metrics[key] = value;\n }\n }\n }\n return metrics;\n}\n\nfunction parseRunManifest(value: unknown): RunManifest | null {\n if (!isRecord(value)) return null;\n const runId = stringValue(value.run_id);\n const system = stringValue(value.system);\n const variant = stringValue(value.variant);\n const hypothesis = stringValue(value.hypothesis);\n const datasetVersion = stringValue(value.dataset_version);\n const startedAt = stringValue(value.started_at);\n const evalVersion = numberValue(value.eval_version);\n if (\n !runId ||\n !system ||\n !variant ||\n hypothesis === null ||\n !datasetVersion ||\n !startedAt ||\n evalVersion === null\n ) {\n return null;\n }\n\n return {\n run_id: runId,\n system,\n variant,\n parent_id: nullableStringValue(value.parent_id),\n hypothesis,\n eval_version: evalVersion,\n dataset_version: datasetVersion,\n started_at: startedAt,\n git_sha: nullableStringValue(value.git_sha),\n git_branch: nullableStringValue(value.git_branch),\n linear_issue_id:\n nullableStringValue(value.linear_issue_id) ??\n nullableStringValue(value.linear_issue),\n linear_issue_url: nullableStringValue(value.linear_issue_url),\n };\n}\n\nfunction parseRunState(value: unknown): RunState | null {\n if (!isRecord(value)) return null;\n const runId = stringValue(value.run_id);\n const status = runStatusValue(value.status);\n if (!runId || !status) return null;\n return {\n run_id: runId,\n status,\n score: nullableNumberValue(value.score),\n n_total: nullableNumberValue(value.n_total),\n n_done: numberValue(value.n_done) ?? undefined,\n promoted: nullableBooleanValue(value.promoted),\n ended_at: nullableStringValue(value.ended_at),\n updated_at: stringValue(value.updated_at) ?? undefined,\n };\n}\n\nfunction runStatusValue(value: unknown): RunState[\"status\"] | null {\n return value === \"complete\" ||\n value === \"crashed\" ||\n value === \"aborted\" ||\n value === \"running\"\n ? value\n : null;\n}\n\nfunction stringValue(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\nfunction nullableStringValue(value: unknown): string | null {\n return value === null || value === undefined ? null : stringValue(value);\n}\n\nfunction numberValue(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction nullableNumberValue(value: unknown): number | null {\n return value === null || value === undefined ? null : numberValue(value);\n}\n\nfunction nullableBooleanValue(value: unknown): boolean | null {\n return value === null || value === undefined || typeof value !== \"boolean\"\n ? null\n : value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"run-store.js","names":[],"sources":["../../../../dashboard/src/lib/run-store.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { normalizeLinearIssue } from \"../../../shared/linear-issue.js\";\nimport type { RunStatus } from \"./types\";\nimport { getKaizenStateDir } from \"./workspace\";\n\nexport interface RunManifest {\n run_id: string;\n system: string;\n variant: string;\n parent_id: string | null;\n hypothesis: string;\n eval_version: number;\n dataset_version: string;\n started_at: string;\n git_sha?: string | null;\n git_branch?: string | null;\n linear_issue_id?: string | null;\n linear_issue_url?: string | null;\n}\n\nexport interface RunState {\n run_id: string;\n status: \"complete\" | \"crashed\" | \"aborted\" | \"running\";\n score: number | null;\n n_total?: number | null;\n n_done?: number;\n promoted?: boolean | null;\n ended_at?: string | null;\n updated_at?: string;\n}\n\nexport interface RunRecord {\n manifest: RunManifest;\n state: RunState;\n dir: string;\n eventsPath: string;\n failuresPath: string;\n}\n\nexport function listRunRecords(systemId?: string): RunRecord[] {\n const stateDir = getKaizenStateDir();\n const runsRoot = path.join(stateDir, \"runs\");\n if (!fs.existsSync(runsRoot)) return [];\n\n const systemIds = systemId ? [systemId] : safeDirs(runsRoot);\n const out: RunRecord[] = [];\n\n for (const system of systemIds) {\n const systemDir = path.join(runsRoot, system);\n for (const runId of safeDirs(systemDir)) {\n const dir = path.join(systemDir, runId);\n const manifest = parseRunManifest(\n readJson(path.join(dir, \"manifest.json\")),\n );\n if (!manifest) continue;\n const state = parseRunState(readJson(path.join(dir, \"state.json\"))) ?? {\n run_id: manifest.run_id,\n status: \"running\",\n score: null,\n };\n out.push({\n manifest,\n state,\n dir,\n eventsPath: path.join(dir, \"events.jsonl\"),\n failuresPath: path.join(dir, \"failures.jsonl\"),\n });\n }\n }\n\n out.sort((a, b) => (b.manifest.started_at < a.manifest.started_at ? -1 : 1));\n return out;\n}\n\nexport function toRunStatus(run: RunRecord): RunStatus {\n const { manifest, state } = run;\n const metrics = readCompleteMetrics(run.eventsPath);\n if (state.score !== null) metrics.score = state.score;\n\n return {\n runId: manifest.run_id,\n runName: manifest.variant,\n status: state.status,\n worktreeBranch: manifest.git_branch ?? \"\",\n parentId: manifest.parent_id,\n system: manifest.system,\n progress: getProgress(manifest, state),\n metrics,\n totalItems: state.n_total ?? null,\n linearIssue:\n normalizeLinearIssue(\n manifest.linear_issue_url ?? manifest.linear_issue_id,\n ) ?? undefined,\n evalConfig: {\n dataset: manifest.dataset_version,\n evalVersion: manifest.eval_version,\n datasetItemCount: state.n_total ?? 0,\n },\n startedAt: manifest.started_at,\n updatedAt: state.ended_at ?? state.updated_at ?? manifest.started_at,\n };\n}\n\nfunction getProgress(\n manifest: RunManifest,\n state: RunState,\n): RunStatus[\"progress\"] {\n if (state.status === \"running\") {\n return {\n completed: state.n_done ?? 0,\n total: state.n_total ?? 0,\n lastHeartbeat: state.updated_at ?? manifest.started_at,\n };\n }\n\n if (\n (state.status === \"crashed\" || state.status === \"aborted\") &&\n typeof state.n_done === \"number\" &&\n typeof state.n_total === \"number\"\n ) {\n return {\n completed: state.n_done,\n total: state.n_total,\n lastHeartbeat: state.updated_at ?? state.ended_at ?? manifest.started_at,\n };\n }\n\n return undefined;\n}\n\nexport function readFailures(systemId: string, runId: string): unknown[] {\n const file = path.join(\n getKaizenStateDir(),\n \"runs\",\n systemId,\n runId,\n \"failures.jsonl\",\n );\n return readNdjson(file);\n}\n\nexport function readEvents(systemId: string, runId: string): unknown[] {\n const file = path.join(\n getKaizenStateDir(),\n \"runs\",\n systemId,\n runId,\n \"events.jsonl\",\n );\n return readNdjson(file);\n}\n\nfunction safeDirs(dir: string): string[] {\n try {\n return fs\n .readdirSync(dir, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => entry.name);\n } catch {\n return [];\n }\n}\n\nfunction readJson(file: string): unknown {\n try {\n return JSON.parse(fs.readFileSync(file, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\nfunction readNdjson(file: string): unknown[] {\n try {\n return fs\n .readFileSync(file, \"utf-8\")\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => JSON.parse(line));\n } catch {\n return [];\n }\n}\n\nfunction readCompleteMetrics(eventsPath: string): Record<string, number> {\n const metrics: Record<string, number> = {};\n for (const event of readNdjson(eventsPath)) {\n if (!isRecord(event) || event.type !== \"complete\") continue;\n if (typeof event.score === \"number\") metrics.score = event.score;\n if (\n event.breakdown &&\n typeof event.breakdown === \"object\" &&\n !Array.isArray(event.breakdown)\n ) {\n for (const [key, value] of Object.entries(event.breakdown)) {\n if (typeof value === \"number\") metrics[key] = value;\n }\n }\n }\n return metrics;\n}\n\nfunction parseRunManifest(value: unknown): RunManifest | null {\n if (!isRecord(value)) return null;\n const runId = stringValue(value.run_id);\n const system = stringValue(value.system);\n const variant = stringValue(value.variant);\n const hypothesis = stringValue(value.hypothesis);\n const datasetVersion = stringValue(value.dataset_version);\n const startedAt = stringValue(value.started_at);\n const evalVersion = numberValue(value.eval_version);\n if (\n !runId ||\n !system ||\n !variant ||\n hypothesis === null ||\n !datasetVersion ||\n !startedAt ||\n evalVersion === null\n ) {\n return null;\n }\n\n return {\n run_id: runId,\n system,\n variant,\n parent_id: nullableStringValue(value.parent_id),\n hypothesis,\n eval_version: evalVersion,\n dataset_version: datasetVersion,\n started_at: startedAt,\n git_sha: nullableStringValue(value.git_sha),\n git_branch: nullableStringValue(value.git_branch),\n linear_issue_id:\n nullableStringValue(value.linear_issue_id) ??\n nullableStringValue(value.linear_issue),\n linear_issue_url: nullableStringValue(value.linear_issue_url),\n };\n}\n\nfunction parseRunState(value: unknown): RunState | null {\n if (!isRecord(value)) return null;\n const runId = stringValue(value.run_id);\n const status = runStatusValue(value.status);\n if (!runId || !status) return null;\n return {\n run_id: runId,\n status,\n score: nullableNumberValue(value.score),\n n_total: nullableNumberValue(value.n_total),\n n_done: numberValue(value.n_done) ?? undefined,\n promoted: nullableBooleanValue(value.promoted),\n ended_at: nullableStringValue(value.ended_at),\n updated_at: stringValue(value.updated_at) ?? undefined,\n };\n}\n\nfunction runStatusValue(value: unknown): RunState[\"status\"] | null {\n return value === \"complete\" ||\n value === \"crashed\" ||\n value === \"aborted\" ||\n value === \"running\"\n ? value\n : null;\n}\n\nfunction stringValue(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\nfunction nullableStringValue(value: unknown): string | null {\n return value === null || value === undefined ? null : stringValue(value);\n}\n\nfunction numberValue(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nfunction nullableNumberValue(value: unknown): number | null {\n return value === null || value === undefined ? null : numberValue(value);\n}\n\nfunction nullableBooleanValue(value: unknown): boolean | null {\n return value === null || value === undefined || typeof value !== \"boolean\"\n ? null\n : value;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../../dashboard/src/lib/types.ts"],"sourcesContent":["// --- Run record projected from kaizen/.kaizen/runs for Studio ---\n\nexport interface RunStatus {\n runId: string;\n runName: string;\n status: \"running\" | \"complete\" | \"crashed\" | \"aborted\";\n worktreeBranch: string;\n parentId: string | null;\n system: string;\n progress?: {\n completed: number;\n total: number;\n lastHeartbeat: string;\n };\n metrics: Record<string, number>;\n totalItems: number | null;\n langfuseRunId?: string;\n linearIssue?: {\n id: string;\n url: string;\n };\n evalConfig?: {\n dataset: string;\n evalVersion?: number;\n datasetItemCount: number;\n judge?: {\n rubric: string;\n rubricHash: string;\n model: string;\n temperature: number;\n };\n };\n startedAt: string;\n updatedAt: string;\n}\n\n// --- Metric helpers ---\n\ninterface MetricMeta {\n label: string;\n /** \"percent\" = multiply by 100 and append %. \"raw\" = display with 2 decimals. \"integer\" = display as whole number. */\n format: \"percent\" | \"raw\" | \"integer\";\n}\n\nconst METRIC_META: Record<string, MetricMeta> = {\n actionAccuracy: { label: \"Action Accuracy\", format: \"percent\" },\n parameterExtraction: { label: \"Param Extraction\", format: \"percent\" },\n clarificationAppropriateness: { label: \"Clarification\", format: \"percent\" },\n multiActionDetection: { label: \"Multi-Action\", format: \"percent\" },\n f1: { label: \"F1\", format: \"percent\" },\n f2: { label: \"F2\", format: \"percent\" },\n precision: { label: \"Precision\", format: \"percent\" },\n recall: { label: \"Recall\", format: \"percent\" },\n cost_per_item: { label: \"Cost / Item\", format: \"raw\" },\n avg_latency_s: { label: \"Avg Latency (s)\", format: \"raw\" },\n true_positives: { label: \"TP\", format: \"integer\" },\n false_positives: { label: \"FP\", format: \"integer\" },\n false_negatives: { label: \"FN\", format: \"integer\" },\n total_clis_scored: { label: \"CLIs Scored\", format: \"integer\" },\n items_with_metrics: { label: \"Items w/ Metrics\", format: \"integer\" },\n timeouts: { label: \"Timeouts\", format: \"integer\" },\n judge_quality: { label: \"Judge Quality\", format: \"percent\" },\n judge_quality_chartNotes: {\n label: \"Quality: Chart Notes\",\n format: \"percent\",\n },\n judge_quality_followUp: { label: \"Quality: Follow-Up\", format: \"percent\" },\n};\n\nexport const KNOWN_METRIC_KEYS = Object.keys(METRIC_META);\n\nexport function getMetricLabel(key: string): string {\n return (\n METRIC_META[key]?.label ??\n key\n .replace(/[_-]+/g, \" \")\n .replace(/([A-Z])/g, \" $1\")\n .replace(/^./, (s) => s.toUpperCase())\n .trim()\n );\n}\n\nexport function formatMetricValue(key: string, val: number): string {\n const meta = METRIC_META[key];\n if (meta?.format === \"integer\") return Math.round(val).toLocaleString();\n if (meta?.format === \"raw\") return val.toFixed(2);\n if (meta?.format === \"percent\") return (val * 100).toFixed(1) + \"%\";\n // Unknown metrics: if value > 1, it's likely a count; otherwise treat as percent.\n if (val > 1) return Math.round(val).toLocaleString();\n return (val * 100).toFixed(1) + \"%\";\n}\n\nexport function computeF2(precision: number, recall: number): number {\n if (precision + recall === 0) return 0;\n return (5 * precision * recall) / (4 * precision + recall);\n}\n\nexport function getPrimaryMetricValue(\n status: RunStatus,\n primaryMetric: string | null | undefined,\n): number | null {\n if (!primaryMetric) return null;\n\n if (primaryMetric in status.metrics) return status.metrics[primaryMetric];\n\n if (\n primaryMetric === \"f2\" &&\n \"precision\" in status.metrics &&\n \"recall\" in status.metrics\n ) {\n return computeF2(status.metrics.precision, status.metrics.recall);\n }\n\n return null;\n}\n\nexport function getPrimaryMetricLabel(\n primaryMetric: string | null | undefined,\n): string {\n if (!primaryMetric) return \"Score\";\n return getMetricLabel(primaryMetric);\n}\n"],"mappings":";AA4FA,SAAgB,UAAU,WAAmB,QAAwB;AACnE,KAAI,YAAY,WAAW,EAAG,QAAO;AACrC,QAAQ,IAAI,YAAY,UAAW,IAAI,YAAY;;AAGrD,SAAgB,sBACd,QACA,eACe;AACf,KAAI,CAAC,cAAe,QAAO;AAE3B,KAAI,iBAAiB,OAAO,QAAS,QAAO,OAAO,QAAQ;AAE3D,KACE,kBAAkB,QAClB,eAAe,OAAO,WACtB,YAAY,OAAO,QAEnB,QAAO,UAAU,OAAO,QAAQ,WAAW,OAAO,QAAQ,OAAO;AAGnE,QAAO"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../../dashboard/src/lib/types.ts"],"sourcesContent":["// --- Run record projected from kaizen/.kaizen/runs for Studio ---\n\nexport interface RunStatus {\n runId: string;\n runName: string;\n status: \"running\" | \"complete\" | \"crashed\" | \"aborted\";\n worktreeBranch: string;\n parentId: string | null;\n system: string;\n progress?: {\n completed: number;\n total: number;\n lastHeartbeat: string;\n };\n metrics: Record<string, number>;\n totalItems: number | null;\n langfuseRunId?: string;\n linearIssue?: {\n id: string;\n url: string;\n };\n evalConfig?: {\n dataset: string;\n evalVersion?: number;\n datasetItemCount: number;\n judge?: {\n rubric: string;\n rubricHash: string;\n model: string;\n temperature: number;\n };\n };\n startedAt: string;\n updatedAt: string;\n}\n\n// --- Metric helpers ---\n\ninterface MetricMeta {\n label: string;\n /** \"percent\" = multiply by 100 and append %. \"raw\" = display with 2 decimals. \"integer\" = display as whole number. */\n format: \"percent\" | \"raw\" | \"integer\";\n}\n\nconst METRIC_META: Record<string, MetricMeta> = {\n actionAccuracy: { label: \"Action Accuracy\", format: \"percent\" },\n parameterExtraction: { label: \"Param Extraction\", format: \"percent\" },\n clarificationAppropriateness: { label: \"Clarification\", format: \"percent\" },\n multiActionDetection: { label: \"Multi-Action\", format: \"percent\" },\n f1: { label: \"F1\", format: \"percent\" },\n f2: { label: \"F2\", format: \"percent\" },\n precision: { label: \"Precision\", format: \"percent\" },\n recall: { label: \"Recall\", format: \"percent\" },\n cost_per_item: { label: \"Cost / Item\", format: \"raw\" },\n avg_latency_s: { label: \"Avg Latency (s)\", format: \"raw\" },\n true_positives: { label: \"TP\", format: \"integer\" },\n false_positives: { label: \"FP\", format: \"integer\" },\n false_negatives: { label: \"FN\", format: \"integer\" },\n total_clis_scored: { label: \"CLIs Scored\", format: \"integer\" },\n items_with_metrics: { label: \"Items w/ Metrics\", format: \"integer\" },\n timeouts: { label: \"Timeouts\", format: \"integer\" },\n judge_quality: { label: \"Judge Quality\", format: \"percent\" },\n judge_quality_chartNotes: {\n label: \"Quality: Chart Notes\",\n format: \"percent\",\n },\n judge_quality_followUp: { label: \"Quality: Follow-Up\", format: \"percent\" },\n};\n\nexport const KNOWN_METRIC_KEYS = Object.keys(METRIC_META);\n\nexport function getMetricLabel(key: string): string {\n return (\n METRIC_META[key]?.label ??\n key\n .replace(/[_-]+/g, \" \")\n .replace(/([A-Z])/g, \" $1\")\n .replace(/^./, (s) => s.toUpperCase())\n .trim()\n );\n}\n\nexport function formatMetricValue(key: string, val: number): string {\n const meta = METRIC_META[key];\n if (meta?.format === \"integer\") return Math.round(val).toLocaleString();\n if (meta?.format === \"raw\") return val.toFixed(2);\n if (meta?.format === \"percent\") return (val * 100).toFixed(1) + \"%\";\n // Unknown metrics: if value > 1, it's likely a count; otherwise treat as percent.\n if (val > 1) return Math.round(val).toLocaleString();\n return (val * 100).toFixed(1) + \"%\";\n}\n\nexport function computeF2(precision: number, recall: number): number {\n if (precision + recall === 0) return 0;\n return (5 * precision * recall) / (4 * precision + recall);\n}\n\nexport function getPrimaryMetricValue(\n status: RunStatus,\n primaryMetric: string | null | undefined,\n): number | null {\n if (!primaryMetric) return null;\n\n if (primaryMetric in status.metrics) return status.metrics[primaryMetric];\n\n if (\n primaryMetric === \"f2\" &&\n \"precision\" in status.metrics &&\n \"recall\" in status.metrics\n ) {\n return computeF2(status.metrics.precision, status.metrics.recall);\n }\n\n return null;\n}\n\nexport function getPrimaryMetricLabel(\n primaryMetric: string | null | undefined,\n): string {\n if (!primaryMetric) return \"Score\";\n return getMetricLabel(primaryMetric);\n}\n"],"mappings":";AA4FA,SAAgB,UAAU,WAAmB,QAAwB;CACnE,IAAI,YAAY,WAAW,GAAG,OAAO;CACrC,OAAQ,IAAI,YAAY,UAAW,IAAI,YAAY;AACrD;AAEA,SAAgB,sBACd,QACA,eACe;CACf,IAAI,CAAC,eAAe,OAAO;CAE3B,IAAI,iBAAiB,OAAO,SAAS,OAAO,OAAO,QAAQ;CAE3D,IACE,kBAAkB,QAClB,eAAe,OAAO,WACtB,YAAY,OAAO,SAEnB,OAAO,UAAU,OAAO,QAAQ,WAAW,OAAO,QAAQ,MAAM;CAGlE,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-env.js","names":[],"sources":["../../../../dashboard/src/lib/workspace-env.ts"],"sourcesContent":["import path from \"node:path\";\nimport { readEnvFile } from \"../../../shared/env-file.js\";\nimport { getWorkspaceRoot } from \"./workspace\";\n\nexport const WORKSPACE_ENV_FILE_NAME = \".env.local\";\n\nexport function getWorkspaceEnvPath(): string {\n return path.join(getWorkspaceRoot(), WORKSPACE_ENV_FILE_NAME);\n}\n\nexport function readWorkspaceEnvLocal(): Record<string, string> {\n return readEnvFile(getWorkspaceEnvPath());\n}\n\nexport function missingEnvVars(\n env: Record<string, string | undefined>,\n required: string[],\n): string[] {\n return required.filter((key) => !env[key]?.trim());\n}\n"],"mappings":";;;;AAIA,MAAa,0BAA0B;AAEvC,SAAgB,sBAA8B;AAC5C,QAAO,KAAK,KAAK,kBAAkB,EAAE,wBAAwB;;AAG/D,SAAgB,wBAAgD;AAC9D,QAAO,YAAY,qBAAqB,CAAC;;AAG3C,SAAgB,eACd,KACA,UACU;AACV,QAAO,SAAS,QAAQ,QAAQ,CAAC,IAAI,MAAM,MAAM,CAAC"}
1
+ {"version":3,"file":"workspace-env.js","names":[],"sources":["../../../../dashboard/src/lib/workspace-env.ts"],"sourcesContent":["import path from \"node:path\";\nimport { readEnvFile } from \"../../../shared/env-file.js\";\nimport { getWorkspaceRoot } from \"./workspace\";\n\nexport const WORKSPACE_ENV_FILE_NAME = \".env.local\";\n\nexport function getWorkspaceEnvPath(): string {\n return path.join(getWorkspaceRoot(), WORKSPACE_ENV_FILE_NAME);\n}\n\nexport function readWorkspaceEnvLocal(): Record<string, string> {\n return readEnvFile(getWorkspaceEnvPath());\n}\n\nexport function missingEnvVars(\n env: Record<string, string | undefined>,\n required: string[],\n): string[] {\n return required.filter((key) => !env[key]?.trim());\n}\n"],"mappings":";;;;AAIA,MAAa,0BAA0B;AAEvC,SAAgB,sBAA8B;CAC5C,OAAO,KAAK,KAAK,iBAAiB,GAAG,uBAAuB;AAC9D;AAEA,SAAgB,wBAAgD;CAC9D,OAAO,YAAY,oBAAoB,CAAC;AAC1C;AAEA,SAAgB,eACd,KACA,UACU;CACV,OAAO,SAAS,QAAQ,QAAQ,CAAC,IAAI,MAAM,KAAK,CAAC;AACnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.js","names":[],"sources":["../../../../dashboard/src/lib/workspace.ts"],"sourcesContent":["import path from \"node:path\";\nimport { resolveKaizenStateDir } from \"../../../shared/workspace-paths.js\";\n\nexport function getWorkspaceRoot(): string {\n const raw = process.env.KAIZEN_WORKSPACE;\n return raw ? path.resolve(raw) : process.cwd();\n}\n\nexport function getKaizenStateDir(): string {\n return resolveKaizenStateDir(getWorkspaceRoot());\n}\n"],"mappings":";;;AAGA,SAAgB,mBAA2B;CACzC,MAAM,MAAM,QAAQ,IAAI;AACxB,QAAO,MAAM,KAAK,QAAQ,IAAI,GAAG,QAAQ,KAAK;;AAGhD,SAAgB,oBAA4B;AAC1C,QAAO,sBAAsB,kBAAkB,CAAC"}
1
+ {"version":3,"file":"workspace.js","names":[],"sources":["../../../../dashboard/src/lib/workspace.ts"],"sourcesContent":["import path from \"node:path\";\nimport { resolveKaizenStateDir } from \"../../../shared/workspace-paths.js\";\n\nexport function getWorkspaceRoot(): string {\n const raw = process.env.KAIZEN_WORKSPACE;\n return raw ? path.resolve(raw) : process.cwd();\n}\n\nexport function getKaizenStateDir(): string {\n return resolveKaizenStateDir(getWorkspaceRoot());\n}\n"],"mappings":";;;AAGA,SAAgB,mBAA2B;CACzC,MAAM,MAAM,QAAQ,IAAI;CACxB,OAAO,MAAM,KAAK,QAAQ,GAAG,IAAI,QAAQ,IAAI;AAC/C;AAEA,SAAgB,oBAA4B;CAC1C,OAAO,sBAAsB,iBAAiB,CAAC;AACjD"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { runCreateView } from \"./commands/create-view.js\";\nimport { runGuide } from \"./commands/guide.js\";\nimport { runIdeas } from \"./commands/ideas.js\";\nimport { runInitSystem } from \"./commands/init-system.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runLog } from \"./commands/log.js\";\nimport { runRebuild } from \"./commands/rebuild.js\";\nimport { runRun } from \"./commands/run.js\";\nimport { runStudio } from \"./commands/studio.js\";\n\nconst HELP = `kaizen — automated AI researcher\n\nworkspace:\n kaizen init scaffold a Kaizen workspace (run once per repo)\n kaizen guide [topic] print package-owned agent instructions\n topics: overview, evals, views,\n variant-builder, claude-command, all\n kaizen create system [name] add a system definition + starter eval\n [--eval-language py|ts]\n kaizen create view <system> add kaizen/systems/<system>/<type>.tsx\n --type trace|dataset-item\n kaizen studio [--port 6789]\n open the local Kaizen dashboard against this workspace\n kaizen ideas --system <s> [--json] [--limit <n>]\n list Linear issues labeled Kaizen for a system\n\nagent-facing (the inner loop):\n kaizen run --system <s> --variant <v> [--parent <id>] [--hypothesis \"...\"]\n [--idea <KZN-123>] [--diagnostic] [--no-auto-promote]\n record one run; emits score on stdout\n kaizen log [--system <s>] [-n <count>] [--json]\n promoted baseline + chronological run history\n\nrecovery (rare):\n kaizen rebuild [--system <s>]\n re-derive state.json from events.jsonl\n\n kaizen --version print version\n`;\n\nasync function main(argv: string[]): Promise<number> {\n const [cmd, sub, ...rest] = argv;\n\n if (!cmd || cmd === \"--help\" || cmd === \"-h\" || cmd === \"help\") {\n process.stdout.write(HELP);\n return 0;\n }\n if (cmd === \"--version\" || cmd === \"-v\") {\n const pkg = await import(\"../package.json\", { with: { type: \"json\" } });\n process.stdout.write(`${pkg.default.version}\\n`);\n return 0;\n }\n\n switch (cmd) {\n case \"create\":\n if (sub === \"system\") {\n return runInitSystem(rest);\n }\n if (sub === \"view\") {\n return runCreateView(rest);\n }\n process.stderr.write(`unknown create target: ${sub ?? \"\"}\\n\\n${HELP}`);\n return 1;\n case \"init\":\n return runInit([sub, ...rest].filter(Boolean));\n case \"guide\":\n return runGuide([sub, ...rest].filter(Boolean));\n case \"run\":\n return runRun([sub, ...rest].filter(Boolean));\n case \"log\":\n return runLog([sub, ...rest].filter(Boolean));\n case \"rebuild\":\n return runRebuild([sub, ...rest].filter(Boolean));\n case \"studio\":\n return runStudio([sub, ...rest].filter(Boolean));\n case \"ideas\":\n return runIdeas([sub, ...rest].filter(Boolean));\n default:\n process.stderr.write(`unknown command: ${cmd}\\n\\n${HELP}`);\n return 1;\n }\n}\n\nmain(process.argv.slice(2)).then(\n (code) => process.exit(code),\n (err) => {\n process.stderr.write(`error: ${err?.message ?? err}\\n`);\n if (process.env.KAIZEN_DEBUG) process.stderr.write(`${err?.stack}\\n`);\n process.exit(1);\n },\n);\n"],"mappings":";;;;;;;;;;AAUA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8Bb,eAAe,KAAK,MAAiC;CACnD,MAAM,CAAC,KAAK,KAAK,GAAG,QAAQ;AAE5B,KAAI,CAAC,OAAO,QAAQ,YAAY,QAAQ,QAAQ,QAAQ,QAAQ;AAC9D,UAAQ,OAAO,MAAM,KAAK;AAC1B,SAAO;;AAET,KAAI,QAAQ,eAAe,QAAQ,MAAM;EACvC,MAAM,MAAM,MAAM,OAAO,mBAAmB,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE;AACtE,UAAQ,OAAO,MAAM,GAAG,IAAI,QAAQ,QAAQ,IAAI;AAChD,SAAO;;AAGT,SAAQ,KAAR;EACE,KAAK;AACH,OAAI,QAAQ,SACV,QAAO,cAAc,KAAK;AAE5B,OAAI,QAAQ,OACV,QAAO,cAAc,KAAK;AAE5B,WAAQ,OAAO,MAAM,0BAA0B,OAAO,GAAG,MAAM,OAAO;AACtE,UAAO;EACT,KAAK,OACH,QAAO,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,QAAQ,CAAC;EAChD,KAAK,QACH,QAAO,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,QAAQ,CAAC;EACjD,KAAK,MACH,QAAO,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,QAAQ,CAAC;EAC/C,KAAK,MACH,QAAO,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,QAAQ,CAAC;EAC/C,KAAK,UACH,QAAO,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,QAAQ,CAAC;EACnD,KAAK,SACH,QAAO,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,QAAQ,CAAC;EAClD,KAAK,QACH,QAAO,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC,OAAO,QAAQ,CAAC;EACjD;AACE,WAAQ,OAAO,MAAM,oBAAoB,IAAI,MAAM,OAAO;AAC1D,UAAO;;;AAIb,KAAK,QAAQ,KAAK,MAAM,EAAE,CAAC,CAAC,MACzB,SAAS,QAAQ,KAAK,KAAK,GAC3B,QAAQ;AACP,SAAQ,OAAO,MAAM,UAAU,KAAK,WAAW,IAAI,IAAI;AACvD,KAAI,QAAQ,IAAI,aAAc,SAAQ,OAAO,MAAM,GAAG,KAAK,MAAM,IAAI;AACrE,SAAQ,KAAK,EAAE;EAElB"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { runCreateView } from \"./commands/create-view.js\";\nimport { runGuide } from \"./commands/guide.js\";\nimport { runIdeas } from \"./commands/ideas.js\";\nimport { runInitSystem } from \"./commands/init-system.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runLog } from \"./commands/log.js\";\nimport { runRebuild } from \"./commands/rebuild.js\";\nimport { runRun } from \"./commands/run.js\";\nimport { runStudio } from \"./commands/studio.js\";\n\nconst HELP = `kaizen — automated AI researcher\n\nworkspace:\n kaizen init scaffold a Kaizen workspace (run once per repo)\n kaizen guide [topic] print package-owned agent instructions\n topics: overview, evals, views,\n variant-builder, claude-command, all\n kaizen create system [name] add a system definition + starter eval\n [--eval-language py|ts]\n kaizen create view <system> add kaizen/systems/<system>/<type>.tsx\n --type trace|dataset-item\n kaizen studio [--port 6789]\n open the local Kaizen dashboard against this workspace\n kaizen ideas --system <s> [--json] [--limit <n>]\n list Linear issues labeled Kaizen for a system\n\nagent-facing (the inner loop):\n kaizen run --system <s> --variant <v> [--parent <id>] [--hypothesis \"...\"]\n [--idea <KZN-123>] [--diagnostic] [--no-auto-promote]\n record one run; emits score on stdout\n kaizen log [--system <s>] [-n <count>] [--json]\n promoted baseline + chronological run history\n\nrecovery (rare):\n kaizen rebuild [--system <s>]\n re-derive state.json from events.jsonl\n\n kaizen --version print version\n`;\n\nasync function main(argv: string[]): Promise<number> {\n const [cmd, sub, ...rest] = argv;\n\n if (!cmd || cmd === \"--help\" || cmd === \"-h\" || cmd === \"help\") {\n process.stdout.write(HELP);\n return 0;\n }\n if (cmd === \"--version\" || cmd === \"-v\") {\n const pkg = await import(\"../package.json\", { with: { type: \"json\" } });\n process.stdout.write(`${pkg.default.version}\\n`);\n return 0;\n }\n\n switch (cmd) {\n case \"create\":\n if (sub === \"system\") {\n return runInitSystem(rest);\n }\n if (sub === \"view\") {\n return runCreateView(rest);\n }\n process.stderr.write(`unknown create target: ${sub ?? \"\"}\\n\\n${HELP}`);\n return 1;\n case \"init\":\n return runInit([sub, ...rest].filter(Boolean));\n case \"guide\":\n return runGuide([sub, ...rest].filter(Boolean));\n case \"run\":\n return runRun([sub, ...rest].filter(Boolean));\n case \"log\":\n return runLog([sub, ...rest].filter(Boolean));\n case \"rebuild\":\n return runRebuild([sub, ...rest].filter(Boolean));\n case \"studio\":\n return runStudio([sub, ...rest].filter(Boolean));\n case \"ideas\":\n return runIdeas([sub, ...rest].filter(Boolean));\n default:\n process.stderr.write(`unknown command: ${cmd}\\n\\n${HELP}`);\n return 1;\n }\n}\n\nmain(process.argv.slice(2)).then(\n (code) => process.exit(code),\n (err) => {\n process.stderr.write(`error: ${err?.message ?? err}\\n`);\n if (process.env.KAIZEN_DEBUG) process.stderr.write(`${err?.stack}\\n`);\n process.exit(1);\n },\n);\n"],"mappings":";;;;;;;;;;AAUA,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8Bb,eAAe,KAAK,MAAiC;CACnD,MAAM,CAAC,KAAK,KAAK,GAAG,QAAQ;CAE5B,IAAI,CAAC,OAAO,QAAQ,YAAY,QAAQ,QAAQ,QAAQ,QAAQ;EAC9D,QAAQ,OAAO,MAAM,IAAI;EACzB,OAAO;CACT;CACA,IAAI,QAAQ,eAAe,QAAQ,MAAM;EACvC,MAAM,MAAM,MAAM,OAAO,mBAAmB,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE;EACrE,QAAQ,OAAO,MAAM,GAAG,IAAI,QAAQ,QAAQ,GAAG;EAC/C,OAAO;CACT;CAEA,QAAQ,KAAR;EACE,KAAK;GACH,IAAI,QAAQ,UACV,OAAO,cAAc,IAAI;GAE3B,IAAI,QAAQ,QACV,OAAO,cAAc,IAAI;GAE3B,QAAQ,OAAO,MAAM,0BAA0B,OAAO,GAAG,MAAM,MAAM;GACrE,OAAO;EACT,KAAK,QACH,OAAO,QAAQ,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC;EAC/C,KAAK,SACH,OAAO,SAAS,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC;EAChD,KAAK,OACH,OAAO,OAAO,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC;EAC9C,KAAK,OACH,OAAO,OAAO,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC;EAC9C,KAAK,WACH,OAAO,WAAW,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC;EAClD,KAAK,UACH,OAAO,UAAU,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC;EACjD,KAAK,SACH,OAAO,SAAS,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,OAAO,CAAC;EAChD;GACE,QAAQ,OAAO,MAAM,oBAAoB,IAAI,MAAM,MAAM;GACzD,OAAO;CACX;AACF;AAEA,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC,EAAE,MACzB,SAAS,QAAQ,KAAK,IAAI,IAC1B,QAAQ;CACP,QAAQ,OAAO,MAAM,UAAU,KAAK,WAAW,IAAI,GAAG;CACtD,IAAI,QAAQ,IAAI,cAAc,QAAQ,OAAO,MAAM,GAAG,KAAK,MAAM,GAAG;CACpE,QAAQ,KAAK,CAAC;AAChB,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"langfuse.d.ts","names":[],"sources":["../src/langfuse.ts"],"mappings":";UAAiB,cAAA;EACf,IAAA;EACA,SAAA;EACA,SAAA;AAAA;AAAA,UAGe,mBAAA;EACf,EAAA;EACA,KAAA;EACA,cAAA;EACA,QAAA,GAAW,MAAA;EAAA,CACV,GAAA;AAAA;AAAA,UAGc,aAAA;EACf,EAAA;EACA,IAAA;EACA,KAAA;EACA,MAAA;EACA,QAAA,GAAW,MAAA;EAAA,CACV,GAAA;AAAA;AAAA,UAGc,kBAAA;EACf,OAAA;EACA,IAAA;EACA,KAAA;EACA,OAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,UAGI,2BAAA;EACf,aAAA;EACA,OAAA;EACA,OAAA;EACA,cAAA;EACA,QAAA,GAAW,MAAA;AAAA;AAAA,iBAGG,qBAAA,CACd,GAAA,GAAK,MAAA,CAAO,UAAA,GACX,cAAA;AAAA,cAyBU,iBAAA;EAAA,iBACM,IAAA;EAAA,iBACA,IAAA;cAEE,MAAA,EAAQ,cAAA;EAOd,gBAAA,CACX,WAAA,UACA,IAAA;IAAQ,KAAA;EAAA,IACP,OAAA,CAAQ,mBAAA;EAgBE,QAAA,CAAS,OAAA,WAAkB,OAAA,CAAQ,aAAA;EAMnC,WAAA,CAAY,KAAA,EAAO,kBAAA,GAAqB,OAAA;EAUxC,oBAAA,CACX,KAAA,EAAO,2BAAA,GACN,OAAA;EAAA,QAUW,GAAA;EAAA,QAIA,IAAA;EAAA,QAQA,OAAA;AAAA;AAAA,iBAsBA,oBAAA,CACd,MAAA,GAAQ,cAAA,GACP,iBAAA"}
1
+ {"version":3,"file":"langfuse.d.ts","names":[],"sources":["../src/langfuse.ts"],"mappings":";UAAiB,cAAA;EACf,IAAA;EACA,SAAA;EACA,SAAA;AAAA;AAAA,UAGe,mBAAA;EACf,EAAA;EACA,KAAA;EACA,cAAA;EACA,QAAA,GAAW,MAAM;EAAA,CAChB,GAAA;AAAA;AAAA,UAGc,aAAA;EACf,EAAA;EACA,IAAA;EACA,KAAA;EACA,MAAA;EACA,QAAA,GAAW,MAAM;EAAA,CAChB,GAAA;AAAA;AAAA,UAGc,kBAAA;EACf,OAAA;EACA,IAAA;EACA,KAAA;EACA,OAAA;EACA,QAAA,GAAW,MAAM;AAAA;AAAA,UAGF,2BAAA;EACf,aAAA;EACA,OAAA;EACA,OAAA;EACA,cAAA;EACA,QAAA,GAAW,MAAM;AAAA;AAAA,iBAGH,qBAAA,CACd,GAAA,GAAK,MAAA,CAAO,UAAA,GACX,cAAc;AAAA,cAyBJ,iBAAA;EAAA,iBACM,IAAA;EAAA,iBACA,IAAA;cAEE,MAAA,EAAQ,cAAA;EAOd,gBAAA,CACX,WAAA,UACA,IAAA;IAAQ,KAAA;EAAA,IACP,OAAA,CAAQ,mBAAA;EAgBE,QAAA,CAAS,OAAA,WAAkB,OAAA,CAAQ,aAAA;EAMnC,WAAA,CAAY,KAAA,EAAO,kBAAA,GAAqB,OAAA;EAUxC,oBAAA,CACX,KAAA,EAAO,2BAAA,GACN,OAAA;EAAA,QAUW,GAAA;EAAA,QAIA,IAAA;EAAA,QAQA,OAAA;AAAA;AAAA,iBAsBA,oBAAA,CACd,MAAA,GAAQ,cAAA,GACP,iBAAiB"}
@@ -1 +1 @@
1
- {"version":3,"file":"langfuse.js","names":[],"sources":["../src/langfuse.ts"],"sourcesContent":["export interface LangfuseConfig {\n host: string;\n publicKey: string;\n secretKey: string;\n}\n\nexport interface LangfuseDatasetItem {\n id: string;\n input?: unknown;\n expectedOutput?: unknown;\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface LangfuseTrace {\n id: string;\n name?: string;\n input?: unknown;\n output?: unknown;\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface LangfuseScoreInput {\n traceId: string;\n name: string;\n value: number | string | boolean;\n comment?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface LangfuseDatasetRunItemInput {\n datasetItemId: string;\n traceId: string;\n runName: string;\n runDescription?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport function langfuseConfigFromEnv(\n env: NodeJS.ProcessEnv = process.env,\n): LangfuseConfig {\n const host = env.LANGFUSE_HOST ?? env.LANGFUSE_BASE_URL;\n const publicKey = env.LANGFUSE_PUBLIC_KEY;\n const secretKey = env.LANGFUSE_SECRET_KEY;\n const missing = [\n [\"LANGFUSE_HOST\", host],\n [\"LANGFUSE_PUBLIC_KEY\", publicKey],\n [\"LANGFUSE_SECRET_KEY\", secretKey],\n ]\n .filter(([, value]) => !value)\n .map(([name]) => name);\n\n if (missing.length > 0) {\n throw new Error(\n `missing Langfuse environment variables: ${missing.join(\", \")}`,\n );\n }\n\n return {\n host: host!.replace(/\\/$/, \"\"),\n publicKey: publicKey!,\n secretKey: secretKey!,\n };\n}\n\nexport class LangfuseApiClient {\n private readonly host: string;\n private readonly auth: string;\n\n public constructor(config: LangfuseConfig) {\n this.host = config.host.replace(/\\/$/, \"\");\n this.auth = Buffer.from(`${config.publicKey}:${config.secretKey}`).toString(\n \"base64\",\n );\n }\n\n public async listDatasetItems(\n datasetName: string,\n opts: { limit?: number } = {},\n ): Promise<LangfuseDatasetItem[]> {\n const limit = clampDatasetItemLimit(opts.limit);\n const out: LangfuseDatasetItem[] = [];\n let page = 1;\n\n while (true) {\n const data = await this.get<{ data?: LangfuseDatasetItem[] }>(\n `/api/public/dataset-items?datasetName=${encodeURIComponent(datasetName)}&limit=${limit}&page=${page}`,\n );\n const items = data.data ?? [];\n out.push(...items);\n if (items.length < limit) return out;\n page++;\n }\n }\n\n public async getTrace(traceId: string): Promise<LangfuseTrace> {\n return this.get<LangfuseTrace>(\n `/api/public/traces/${encodeURIComponent(traceId)}`,\n );\n }\n\n public async createScore(input: LangfuseScoreInput): Promise<unknown> {\n return this.post(\"/api/public/scores\", {\n traceId: input.traceId,\n name: input.name,\n value: input.value,\n comment: input.comment,\n metadata: input.metadata,\n });\n }\n\n public async createDatasetRunItem(\n input: LangfuseDatasetRunItemInput,\n ): Promise<unknown> {\n return this.post(\"/api/public/dataset-run-items\", {\n datasetItemId: input.datasetItemId,\n traceId: input.traceId,\n runName: input.runName,\n runDescription: input.runDescription,\n metadata: input.metadata,\n });\n }\n\n private async get<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: \"GET\" });\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(path, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n }\n\n private async request<T>(path: string, init: RequestInit): Promise<T> {\n const res = await fetch(`${this.host}${path}`, {\n ...init,\n headers: {\n Authorization: `Basic ${this.auth}`,\n // eslint-disable-next-line typescript/no-misused-spread\n ...init.headers,\n },\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Langfuse ${res.status}: ${text.slice(0, 500)}`);\n }\n return res.json() as Promise<T>;\n }\n}\n\nfunction clampDatasetItemLimit(limit: number | undefined): number {\n if (!limit || !Number.isFinite(limit)) return 100;\n return Math.max(1, Math.min(100, Math.floor(limit)));\n}\n\nexport function createLangfuseClient(\n config: LangfuseConfig = langfuseConfigFromEnv(),\n): LangfuseApiClient {\n return new LangfuseApiClient(config);\n}\n"],"mappings":";AAuCA,SAAgB,sBACd,MAAyB,QAAQ,KACjB;CAChB,MAAM,OAAO,IAAI,iBAAiB,IAAI;CACtC,MAAM,YAAY,IAAI;CACtB,MAAM,YAAY,IAAI;CACtB,MAAM,UAAU;EACd,CAAC,iBAAiB,KAAK;EACvB,CAAC,uBAAuB,UAAU;EAClC,CAAC,uBAAuB,UAAU;EACnC,CACE,QAAQ,GAAG,WAAW,CAAC,MAAM,CAC7B,KAAK,CAAC,UAAU,KAAK;AAExB,KAAI,QAAQ,SAAS,EACnB,OAAM,IAAI,MACR,2CAA2C,QAAQ,KAAK,KAAK,GAC9D;AAGH,QAAO;EACL,MAAM,KAAM,QAAQ,OAAO,GAAG;EACnB;EACA;EACZ;;AAGH,IAAa,oBAAb,MAA+B;CAC7B;CACA;CAEA,YAAmB,QAAwB;AACzC,OAAK,OAAO,OAAO,KAAK,QAAQ,OAAO,GAAG;AAC1C,OAAK,OAAO,OAAO,KAAK,GAAG,OAAO,UAAU,GAAG,OAAO,YAAY,CAAC,SACjE,SACD;;CAGH,MAAa,iBACX,aACA,OAA2B,EAAE,EACG;EAChC,MAAM,QAAQ,sBAAsB,KAAK,MAAM;EAC/C,MAAM,MAA6B,EAAE;EACrC,IAAI,OAAO;AAEX,SAAO,MAAM;GAIX,MAAM,SAAQ,MAHK,KAAK,IACtB,yCAAyC,mBAAmB,YAAY,CAAC,SAAS,MAAM,QAAQ,OACjG,EACkB,QAAQ,EAAE;AAC7B,OAAI,KAAK,GAAG,MAAM;AAClB,OAAI,MAAM,SAAS,MAAO,QAAO;AACjC;;;CAIJ,MAAa,SAAS,SAAyC;AAC7D,SAAO,KAAK,IACV,sBAAsB,mBAAmB,QAAQ,GAClD;;CAGH,MAAa,YAAY,OAA6C;AACpE,SAAO,KAAK,KAAK,sBAAsB;GACrC,SAAS,MAAM;GACf,MAAM,MAAM;GACZ,OAAO,MAAM;GACb,SAAS,MAAM;GACf,UAAU,MAAM;GACjB,CAAC;;CAGJ,MAAa,qBACX,OACkB;AAClB,SAAO,KAAK,KAAK,iCAAiC;GAChD,eAAe,MAAM;GACrB,SAAS,MAAM;GACf,SAAS,MAAM;GACf,gBAAgB,MAAM;GACtB,UAAU,MAAM;GACjB,CAAC;;CAGJ,MAAc,IAAO,MAA0B;AAC7C,SAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,OAAO,CAAC;;CAGjD,MAAc,KAAQ,MAAc,MAA2B;AAC7D,SAAO,KAAK,QAAW,MAAM;GAC3B,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAC/C,MAAM,KAAK,UAAU,KAAK;GAC3B,CAAC;;CAGJ,MAAc,QAAW,MAAc,MAA+B;EACpE,MAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,QAAQ;GAC7C,GAAG;GACH,SAAS;IACP,eAAe,SAAS,KAAK;IAE7B,GAAG,KAAK;IACT;GACF,CAAC;AACF,MAAI,CAAC,IAAI,IAAI;GACX,MAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,SAAM,IAAI,MAAM,YAAY,IAAI,OAAO,IAAI,KAAK,MAAM,GAAG,IAAI,GAAG;;AAElE,SAAO,IAAI,MAAM;;;AAIrB,SAAS,sBAAsB,OAAmC;AAChE,KAAI,CAAC,SAAS,CAAC,OAAO,SAAS,MAAM,CAAE,QAAO;AAC9C,QAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,MAAM,CAAC,CAAC;;AAGtD,SAAgB,qBACd,SAAyB,uBAAuB,EAC7B;AACnB,QAAO,IAAI,kBAAkB,OAAO"}
1
+ {"version":3,"file":"langfuse.js","names":[],"sources":["../src/langfuse.ts"],"sourcesContent":["export interface LangfuseConfig {\n host: string;\n publicKey: string;\n secretKey: string;\n}\n\nexport interface LangfuseDatasetItem {\n id: string;\n input?: unknown;\n expectedOutput?: unknown;\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface LangfuseTrace {\n id: string;\n name?: string;\n input?: unknown;\n output?: unknown;\n metadata?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface LangfuseScoreInput {\n traceId: string;\n name: string;\n value: number | string | boolean;\n comment?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface LangfuseDatasetRunItemInput {\n datasetItemId: string;\n traceId: string;\n runName: string;\n runDescription?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport function langfuseConfigFromEnv(\n env: NodeJS.ProcessEnv = process.env,\n): LangfuseConfig {\n const host = env.LANGFUSE_HOST ?? env.LANGFUSE_BASE_URL;\n const publicKey = env.LANGFUSE_PUBLIC_KEY;\n const secretKey = env.LANGFUSE_SECRET_KEY;\n const missing = [\n [\"LANGFUSE_HOST\", host],\n [\"LANGFUSE_PUBLIC_KEY\", publicKey],\n [\"LANGFUSE_SECRET_KEY\", secretKey],\n ]\n .filter(([, value]) => !value)\n .map(([name]) => name);\n\n if (missing.length > 0) {\n throw new Error(\n `missing Langfuse environment variables: ${missing.join(\", \")}`,\n );\n }\n\n return {\n host: host!.replace(/\\/$/, \"\"),\n publicKey: publicKey!,\n secretKey: secretKey!,\n };\n}\n\nexport class LangfuseApiClient {\n private readonly host: string;\n private readonly auth: string;\n\n public constructor(config: LangfuseConfig) {\n this.host = config.host.replace(/\\/$/, \"\");\n this.auth = Buffer.from(`${config.publicKey}:${config.secretKey}`).toString(\n \"base64\",\n );\n }\n\n public async listDatasetItems(\n datasetName: string,\n opts: { limit?: number } = {},\n ): Promise<LangfuseDatasetItem[]> {\n const limit = clampDatasetItemLimit(opts.limit);\n const out: LangfuseDatasetItem[] = [];\n let page = 1;\n\n while (true) {\n const data = await this.get<{ data?: LangfuseDatasetItem[] }>(\n `/api/public/dataset-items?datasetName=${encodeURIComponent(datasetName)}&limit=${limit}&page=${page}`,\n );\n const items = data.data ?? [];\n out.push(...items);\n if (items.length < limit) return out;\n page++;\n }\n }\n\n public async getTrace(traceId: string): Promise<LangfuseTrace> {\n return this.get<LangfuseTrace>(\n `/api/public/traces/${encodeURIComponent(traceId)}`,\n );\n }\n\n public async createScore(input: LangfuseScoreInput): Promise<unknown> {\n return this.post(\"/api/public/scores\", {\n traceId: input.traceId,\n name: input.name,\n value: input.value,\n comment: input.comment,\n metadata: input.metadata,\n });\n }\n\n public async createDatasetRunItem(\n input: LangfuseDatasetRunItemInput,\n ): Promise<unknown> {\n return this.post(\"/api/public/dataset-run-items\", {\n datasetItemId: input.datasetItemId,\n traceId: input.traceId,\n runName: input.runName,\n runDescription: input.runDescription,\n metadata: input.metadata,\n });\n }\n\n private async get<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: \"GET\" });\n }\n\n private async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(path, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n }\n\n private async request<T>(path: string, init: RequestInit): Promise<T> {\n const res = await fetch(`${this.host}${path}`, {\n ...init,\n headers: {\n Authorization: `Basic ${this.auth}`,\n // eslint-disable-next-line typescript/no-misused-spread\n ...init.headers,\n },\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Langfuse ${res.status}: ${text.slice(0, 500)}`);\n }\n return res.json() as Promise<T>;\n }\n}\n\nfunction clampDatasetItemLimit(limit: number | undefined): number {\n if (!limit || !Number.isFinite(limit)) return 100;\n return Math.max(1, Math.min(100, Math.floor(limit)));\n}\n\nexport function createLangfuseClient(\n config: LangfuseConfig = langfuseConfigFromEnv(),\n): LangfuseApiClient {\n return new LangfuseApiClient(config);\n}\n"],"mappings":";AAuCA,SAAgB,sBACd,MAAyB,QAAQ,KACjB;CAChB,MAAM,OAAO,IAAI,iBAAiB,IAAI;CACtC,MAAM,YAAY,IAAI;CACtB,MAAM,YAAY,IAAI;CACtB,MAAM,UAAU;EACd,CAAC,iBAAiB,IAAI;EACtB,CAAC,uBAAuB,SAAS;EACjC,CAAC,uBAAuB,SAAS;CACnC,EACG,QAAQ,GAAG,WAAW,CAAC,KAAK,EAC5B,KAAK,CAAC,UAAU,IAAI;CAEvB,IAAI,QAAQ,SAAS,GACnB,MAAM,IAAI,MACR,2CAA2C,QAAQ,KAAK,IAAI,GAC9D;CAGF,OAAO;EACL,MAAM,KAAM,QAAQ,OAAO,EAAE;EAClB;EACA;CACb;AACF;AAEA,IAAa,oBAAb,MAA+B;CAC7B;CACA;CAEA,YAAmB,QAAwB;EACzC,KAAK,OAAO,OAAO,KAAK,QAAQ,OAAO,EAAE;EACzC,KAAK,OAAO,OAAO,KAAK,GAAG,OAAO,UAAU,GAAG,OAAO,WAAW,EAAE,SACjE,QACF;CACF;CAEA,MAAa,iBACX,aACA,OAA2B,CAAC,GACI;EAChC,MAAM,QAAQ,sBAAsB,KAAK,KAAK;EAC9C,MAAM,MAA6B,CAAC;EACpC,IAAI,OAAO;EAEX,OAAO,MAAM;GAIX,MAAM,SAAQ,MAHK,KAAK,IACtB,yCAAyC,mBAAmB,WAAW,EAAE,SAAS,MAAM,QAAQ,MAClG,GACmB,QAAQ,CAAC;GAC5B,IAAI,KAAK,GAAG,KAAK;GACjB,IAAI,MAAM,SAAS,OAAO,OAAO;GACjC;EACF;CACF;CAEA,MAAa,SAAS,SAAyC;EAC7D,OAAO,KAAK,IACV,sBAAsB,mBAAmB,OAAO,GAClD;CACF;CAEA,MAAa,YAAY,OAA6C;EACpE,OAAO,KAAK,KAAK,sBAAsB;GACrC,SAAS,MAAM;GACf,MAAM,MAAM;GACZ,OAAO,MAAM;GACb,SAAS,MAAM;GACf,UAAU,MAAM;EAClB,CAAC;CACH;CAEA,MAAa,qBACX,OACkB;EAClB,OAAO,KAAK,KAAK,iCAAiC;GAChD,eAAe,MAAM;GACrB,SAAS,MAAM;GACf,SAAS,MAAM;GACf,gBAAgB,MAAM;GACtB,UAAU,MAAM;EAClB,CAAC;CACH;CAEA,MAAc,IAAO,MAA0B;EAC7C,OAAO,KAAK,QAAW,MAAM,EAAE,QAAQ,MAAM,CAAC;CAChD;CAEA,MAAc,KAAQ,MAAc,MAA2B;EAC7D,OAAO,KAAK,QAAW,MAAM;GAC3B,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU,IAAI;EAC3B,CAAC;CACH;CAEA,MAAc,QAAW,MAAc,MAA+B;EACpE,MAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,QAAQ;GAC7C,GAAG;GACH,SAAS;IACP,eAAe,SAAS,KAAK;IAE7B,GAAG,KAAK;GACV;EACF,CAAC;EACD,IAAI,CAAC,IAAI,IAAI;GACX,MAAM,OAAO,MAAM,IAAI,KAAK;GAC5B,MAAM,IAAI,MAAM,YAAY,IAAI,OAAO,IAAI,KAAK,MAAM,GAAG,GAAG,GAAG;EACjE;EACA,OAAO,IAAI,KAAK;CAClB;AACF;AAEA,SAAS,sBAAsB,OAAmC;CAChE,IAAI,CAAC,SAAS,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO;CAC9C,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,KAAK,CAAC,CAAC;AACrD;AAEA,SAAgB,qBACd,SAAyB,sBAAsB,GAC5B;CACnB,OAAO,IAAI,kBAAkB,MAAM;AACrC"}
package/dist/package.js CHANGED
@@ -1,7 +1,7 @@
1
1
  //#region package.json
2
2
  var package_default = {
3
3
  name: "@percepta/kaizen",
4
- version: "0.9.0",
4
+ version: "0.10.0",
5
5
  description: "Automated AI researcher that improves AI systems",
6
6
  keywords: [
7
7
  "ai",
@@ -55,7 +55,7 @@ var package_default = {
55
55
  "yaml": "^2.8.4"
56
56
  },
57
57
  devDependencies: {
58
- "@percepta/build": "workspace:*",
58
+ "@percepta/build": "^1.2.1",
59
59
  "@types/d3-hierarchy": "^3.1.7",
60
60
  "@types/node": "^25.6.2",
61
61
  "@types/react": "^19.2.14",
@@ -1 +1 @@
1
- {"version":3,"file":"env-file.js","names":[],"sources":["../../shared/env-file.js"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\n\nexport function readEnvFile(envPath) {\n if (!existsSync(envPath)) return {};\n const vars = {};\n for (const line of readFileSync(envPath, \"utf-8\").split(\"\\n\")) {\n let trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n if (trimmed.startsWith(\"export \")) trimmed = trimmed.slice(7).trim();\n const eq = trimmed.indexOf(\"=\");\n if (eq < 0) continue;\n const key = trimmed.slice(0, eq).trim();\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) continue;\n let val = trimmed.slice(eq + 1);\n if (\n (val.startsWith('\"') && val.endsWith('\"')) ||\n (val.startsWith(\"'\") && val.endsWith(\"'\"))\n ) {\n val = val.slice(1, -1);\n }\n vars[key] = val;\n }\n return vars;\n}\n"],"mappings":";;AAEA,SAAgB,YAAY,SAAS;AACnC,KAAI,CAAC,WAAW,QAAQ,CAAE,QAAO,EAAE;CACnC,MAAM,OAAO,EAAE;AACf,MAAK,MAAM,QAAQ,aAAa,SAAS,QAAQ,CAAC,MAAM,KAAK,EAAE;EAC7D,IAAI,UAAU,KAAK,MAAM;AACzB,MAAI,CAAC,WAAW,QAAQ,WAAW,IAAI,CAAE;AACzC,MAAI,QAAQ,WAAW,UAAU,CAAE,WAAU,QAAQ,MAAM,EAAE,CAAC,MAAM;EACpE,MAAM,KAAK,QAAQ,QAAQ,IAAI;AAC/B,MAAI,KAAK,EAAG;EACZ,MAAM,MAAM,QAAQ,MAAM,GAAG,GAAG,CAAC,MAAM;AACvC,MAAI,CAAC,2BAA2B,KAAK,IAAI,CAAE;EAC3C,IAAI,MAAM,QAAQ,MAAM,KAAK,EAAE;AAC/B,MACG,IAAI,WAAW,KAAI,IAAI,IAAI,SAAS,KAAI,IACxC,IAAI,WAAW,IAAI,IAAI,IAAI,SAAS,IAAI,CAEzC,OAAM,IAAI,MAAM,GAAG,GAAG;AAExB,OAAK,OAAO;;AAEd,QAAO"}
1
+ {"version":3,"file":"env-file.js","names":[],"sources":["../../shared/env-file.js"],"sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\n\nexport function readEnvFile(envPath) {\n if (!existsSync(envPath)) return {};\n const vars = {};\n for (const line of readFileSync(envPath, \"utf-8\").split(\"\\n\")) {\n let trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n if (trimmed.startsWith(\"export \")) trimmed = trimmed.slice(7).trim();\n const eq = trimmed.indexOf(\"=\");\n if (eq < 0) continue;\n const key = trimmed.slice(0, eq).trim();\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) continue;\n let val = trimmed.slice(eq + 1);\n if (\n (val.startsWith('\"') && val.endsWith('\"')) ||\n (val.startsWith(\"'\") && val.endsWith(\"'\"))\n ) {\n val = val.slice(1, -1);\n }\n vars[key] = val;\n }\n return vars;\n}\n"],"mappings":";;AAEA,SAAgB,YAAY,SAAS;CACnC,IAAI,CAAC,WAAW,OAAO,GAAG,OAAO,CAAC;CAClC,MAAM,OAAO,CAAC;CACd,KAAK,MAAM,QAAQ,aAAa,SAAS,OAAO,EAAE,MAAM,IAAI,GAAG;EAC7D,IAAI,UAAU,KAAK,KAAK;EACxB,IAAI,CAAC,WAAW,QAAQ,WAAW,GAAG,GAAG;EACzC,IAAI,QAAQ,WAAW,SAAS,GAAG,UAAU,QAAQ,MAAM,CAAC,EAAE,KAAK;EACnE,MAAM,KAAK,QAAQ,QAAQ,GAAG;EAC9B,IAAI,KAAK,GAAG;EACZ,MAAM,MAAM,QAAQ,MAAM,GAAG,EAAE,EAAE,KAAK;EACtC,IAAI,CAAC,2BAA2B,KAAK,GAAG,GAAG;EAC3C,IAAI,MAAM,QAAQ,MAAM,KAAK,CAAC;EAC9B,IACG,IAAI,WAAW,IAAG,KAAK,IAAI,SAAS,IAAG,KACvC,IAAI,WAAW,GAAG,KAAK,IAAI,SAAS,GAAG,GAExC,MAAM,IAAI,MAAM,GAAG,EAAE;EAEvB,KAAK,OAAO;CACd;CACA,OAAO;AACT"}