@plumbus/core 0.2.8 → 0.3.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 (205) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ai/__tests__/ai-service.test.js +704 -1
  3. package/dist/ai/__tests__/ai-service.test.js.map +1 -1
  4. package/dist/ai/__tests__/chunking.test.js +34 -0
  5. package/dist/ai/__tests__/chunking.test.js.map +1 -1
  6. package/dist/ai/__tests__/provider.test.d.ts.map +1 -1
  7. package/dist/ai/__tests__/provider.test.js +482 -4
  8. package/dist/ai/__tests__/provider.test.js.map +1 -1
  9. package/dist/ai/__tests__/validation.test.js +238 -1
  10. package/dist/ai/__tests__/validation.test.js.map +1 -1
  11. package/dist/ai/__tests__/zod-to-provider-schema.test.d.ts +2 -0
  12. package/dist/ai/__tests__/zod-to-provider-schema.test.d.ts.map +1 -0
  13. package/dist/ai/__tests__/zod-to-provider-schema.test.js +60 -0
  14. package/dist/ai/__tests__/zod-to-provider-schema.test.js.map +1 -0
  15. package/dist/ai/ai-service.d.ts +19 -2
  16. package/dist/ai/ai-service.d.ts.map +1 -1
  17. package/dist/ai/ai-service.js +565 -90
  18. package/dist/ai/ai-service.js.map +1 -1
  19. package/dist/ai/cost-tracker.d.ts +26 -1
  20. package/dist/ai/cost-tracker.d.ts.map +1 -1
  21. package/dist/ai/cost-tracker.js +1 -0
  22. package/dist/ai/cost-tracker.js.map +1 -1
  23. package/dist/ai/index.d.ts +5 -3
  24. package/dist/ai/index.d.ts.map +1 -1
  25. package/dist/ai/index.js +5 -1
  26. package/dist/ai/index.js.map +1 -1
  27. package/dist/ai/provider.d.ts +59 -1
  28. package/dist/ai/provider.d.ts.map +1 -1
  29. package/dist/ai/provider.js +388 -90
  30. package/dist/ai/provider.js.map +1 -1
  31. package/dist/ai/rag/chunking.js +53 -3
  32. package/dist/ai/rag/chunking.js.map +1 -1
  33. package/dist/ai/refusal.d.ts +28 -0
  34. package/dist/ai/refusal.d.ts.map +1 -0
  35. package/dist/ai/refusal.js +36 -0
  36. package/dist/ai/refusal.js.map +1 -0
  37. package/dist/ai/validation.d.ts +40 -8
  38. package/dist/ai/validation.d.ts.map +1 -1
  39. package/dist/ai/validation.js +212 -6
  40. package/dist/ai/validation.js.map +1 -1
  41. package/dist/ai/zod-to-provider-schema.d.ts +15 -0
  42. package/dist/ai/zod-to-provider-schema.d.ts.map +1 -0
  43. package/dist/ai/zod-to-provider-schema.js +200 -0
  44. package/dist/ai/zod-to-provider-schema.js.map +1 -0
  45. package/dist/api/__tests__/route-generator.test.js +3 -0
  46. package/dist/api/__tests__/route-generator.test.js.map +1 -1
  47. package/dist/api/route-generator.d.ts +4 -0
  48. package/dist/api/route-generator.d.ts.map +1 -1
  49. package/dist/api/route-generator.js +1 -0
  50. package/dist/api/route-generator.js.map +1 -1
  51. package/dist/cli/__tests__/doctor.test.js +104 -2
  52. package/dist/cli/__tests__/doctor.test.js.map +1 -1
  53. package/dist/cli/__tests__/init.test.js +127 -7
  54. package/dist/cli/__tests__/init.test.js.map +1 -1
  55. package/dist/cli/__tests__/migrate.test.js +159 -2
  56. package/dist/cli/__tests__/migrate.test.js.map +1 -1
  57. package/dist/cli/commands/__tests__/commands.test.js +5 -0
  58. package/dist/cli/commands/__tests__/commands.test.js.map +1 -1
  59. package/dist/cli/commands/dev.d.ts.map +1 -1
  60. package/dist/cli/commands/dev.js +22 -1
  61. package/dist/cli/commands/dev.js.map +1 -1
  62. package/dist/cli/commands/doctor.d.ts +2 -0
  63. package/dist/cli/commands/doctor.d.ts.map +1 -1
  64. package/dist/cli/commands/doctor.js +78 -0
  65. package/dist/cli/commands/doctor.js.map +1 -1
  66. package/dist/cli/commands/generate.d.ts.map +1 -1
  67. package/dist/cli/commands/generate.js +8 -3
  68. package/dist/cli/commands/generate.js.map +1 -1
  69. package/dist/cli/commands/init.d.ts +16 -2
  70. package/dist/cli/commands/init.d.ts.map +1 -1
  71. package/dist/cli/commands/init.js +226 -25
  72. package/dist/cli/commands/init.js.map +1 -1
  73. package/dist/cli/commands/migrate.d.ts.map +1 -1
  74. package/dist/cli/commands/migrate.js +258 -8
  75. package/dist/cli/commands/migrate.js.map +1 -1
  76. package/dist/cli/commands/start.d.ts.map +1 -1
  77. package/dist/cli/commands/start.js +22 -1
  78. package/dist/cli/commands/start.js.map +1 -1
  79. package/dist/config/loader.d.ts.map +1 -1
  80. package/dist/config/loader.js +3 -0
  81. package/dist/config/loader.js.map +1 -1
  82. package/dist/data/__tests__/drift-inspector.test.d.ts +2 -0
  83. package/dist/data/__tests__/drift-inspector.test.d.ts.map +1 -0
  84. package/dist/data/__tests__/drift-inspector.test.js +170 -0
  85. package/dist/data/__tests__/drift-inspector.test.js.map +1 -0
  86. package/dist/data/__tests__/framework-migration-rewriter.test.d.ts +2 -0
  87. package/dist/data/__tests__/framework-migration-rewriter.test.d.ts.map +1 -0
  88. package/dist/data/__tests__/framework-migration-rewriter.test.js +329 -0
  89. package/dist/data/__tests__/framework-migration-rewriter.test.js.map +1 -0
  90. package/dist/data/__tests__/migration.test.d.ts +2 -0
  91. package/dist/data/__tests__/migration.test.d.ts.map +1 -0
  92. package/dist/data/__tests__/migration.test.js +143 -0
  93. package/dist/data/__tests__/migration.test.js.map +1 -0
  94. package/dist/data/__tests__/repository.test.js +126 -0
  95. package/dist/data/__tests__/repository.test.js.map +1 -1
  96. package/dist/data/drift-inspector.d.ts +41 -0
  97. package/dist/data/drift-inspector.d.ts.map +1 -0
  98. package/dist/data/drift-inspector.js +197 -0
  99. package/dist/data/drift-inspector.js.map +1 -0
  100. package/dist/data/framework-migration-rewriter.d.ts +61 -0
  101. package/dist/data/framework-migration-rewriter.d.ts.map +1 -0
  102. package/dist/data/framework-migration-rewriter.js +357 -0
  103. package/dist/data/framework-migration-rewriter.js.map +1 -0
  104. package/dist/data/index.d.ts +2 -1
  105. package/dist/data/index.d.ts.map +1 -1
  106. package/dist/data/index.js +2 -1
  107. package/dist/data/index.js.map +1 -1
  108. package/dist/data/migration.d.ts +31 -1
  109. package/dist/data/migration.d.ts.map +1 -1
  110. package/dist/data/migration.js +127 -3
  111. package/dist/data/migration.js.map +1 -1
  112. package/dist/data/repository.d.ts.map +1 -1
  113. package/dist/data/repository.js +21 -0
  114. package/dist/data/repository.js.map +1 -1
  115. package/dist/define/__tests__/definePrompt.test.js +37 -0
  116. package/dist/define/__tests__/definePrompt.test.js.map +1 -1
  117. package/dist/define/definePrompt.d.ts +13 -0
  118. package/dist/define/definePrompt.d.ts.map +1 -1
  119. package/dist/define/definePrompt.js +3 -0
  120. package/dist/define/definePrompt.js.map +1 -1
  121. package/dist/errors/__tests__/http.test.js +3 -0
  122. package/dist/errors/__tests__/http.test.js.map +1 -1
  123. package/dist/errors/http.d.ts.map +1 -1
  124. package/dist/errors/http.js +14 -0
  125. package/dist/errors/http.js.map +1 -1
  126. package/dist/errors/index.d.ts +12 -0
  127. package/dist/errors/index.d.ts.map +1 -1
  128. package/dist/errors/index.js +21 -0
  129. package/dist/errors/index.js.map +1 -1
  130. package/dist/events/__tests__/event-emitter.test.js +72 -0
  131. package/dist/events/__tests__/event-emitter.test.js.map +1 -1
  132. package/dist/events/emitter.d.ts.map +1 -1
  133. package/dist/events/emitter.js +51 -0
  134. package/dist/events/emitter.js.map +1 -1
  135. package/dist/execution/__tests__/capability-executor.test.js +28 -0
  136. package/dist/execution/__tests__/capability-executor.test.js.map +1 -1
  137. package/dist/execution/__tests__/context-factory.test.js +1 -0
  138. package/dist/execution/__tests__/context-factory.test.js.map +1 -1
  139. package/dist/execution/capability-executor.d.ts.map +1 -1
  140. package/dist/execution/capability-executor.js +21 -0
  141. package/dist/execution/capability-executor.js.map +1 -1
  142. package/dist/execution/context-factory.d.ts.map +1 -1
  143. package/dist/execution/context-factory.js +2 -0
  144. package/dist/execution/context-factory.js.map +1 -1
  145. package/dist/flows/__tests__/flow-engine.test.js +535 -3
  146. package/dist/flows/__tests__/flow-engine.test.js.map +1 -1
  147. package/dist/flows/__tests__/flow-service.test.js +8 -0
  148. package/dist/flows/__tests__/flow-service.test.js.map +1 -1
  149. package/dist/flows/__tests__/step-executor.test.js +14 -4
  150. package/dist/flows/__tests__/step-executor.test.js.map +1 -1
  151. package/dist/flows/engine.d.ts +53 -1
  152. package/dist/flows/engine.d.ts.map +1 -1
  153. package/dist/flows/engine.js +462 -25
  154. package/dist/flows/engine.js.map +1 -1
  155. package/dist/flows/flow-service.d.ts.map +1 -1
  156. package/dist/flows/flow-service.js +4 -0
  157. package/dist/flows/flow-service.js.map +1 -1
  158. package/dist/flows/index.d.ts +1 -1
  159. package/dist/flows/index.d.ts.map +1 -1
  160. package/dist/flows/index.js +1 -1
  161. package/dist/flows/index.js.map +1 -1
  162. package/dist/flows/schema.d.ts +34 -0
  163. package/dist/flows/schema.d.ts.map +1 -1
  164. package/dist/flows/schema.js +3 -0
  165. package/dist/flows/schema.js.map +1 -1
  166. package/dist/flows/step-executor.d.ts +2 -0
  167. package/dist/flows/step-executor.d.ts.map +1 -1
  168. package/dist/flows/step-executor.js +6 -6
  169. package/dist/flows/step-executor.js.map +1 -1
  170. package/dist/index.d.ts +4 -4
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js +3 -3
  173. package/dist/index.js.map +1 -1
  174. package/dist/server/__tests__/bootstrap.test.js +37 -0
  175. package/dist/server/__tests__/bootstrap.test.js.map +1 -1
  176. package/dist/server/bootstrap.d.ts +19 -0
  177. package/dist/server/bootstrap.d.ts.map +1 -1
  178. package/dist/server/bootstrap.js +48 -4
  179. package/dist/server/bootstrap.js.map +1 -1
  180. package/dist/testing/__tests__/simulate-flow.test.js +24 -2
  181. package/dist/testing/__tests__/simulate-flow.test.js.map +1 -1
  182. package/dist/testing/context.d.ts.map +1 -1
  183. package/dist/testing/context.js +37 -1
  184. package/dist/testing/context.js.map +1 -1
  185. package/dist/testing/simulate-flow.d.ts.map +1 -1
  186. package/dist/testing/simulate-flow.js +25 -1
  187. package/dist/testing/simulate-flow.js.map +1 -1
  188. package/dist/types/context.d.ts +118 -0
  189. package/dist/types/context.d.ts.map +1 -1
  190. package/dist/types/enums.d.ts +2 -0
  191. package/dist/types/enums.d.ts.map +1 -1
  192. package/dist/types/enums.js +2 -0
  193. package/dist/types/enums.js.map +1 -1
  194. package/dist/types/prompt.d.ts +64 -0
  195. package/dist/types/prompt.d.ts.map +1 -1
  196. package/dist/worker/__tests__/bootstrap.test.js +36 -2
  197. package/dist/worker/__tests__/bootstrap.test.js.map +1 -1
  198. package/dist/worker/bootstrap.d.ts +7 -0
  199. package/dist/worker/bootstrap.d.ts.map +1 -1
  200. package/dist/worker/bootstrap.js +164 -14
  201. package/dist/worker/bootstrap.js.map +1 -1
  202. package/instructions/framework.md +7 -0
  203. package/instructions/guardrails.md +39 -0
  204. package/instructions/patterns.md +10 -0
  205. package/package.json +3 -2
@@ -10,6 +10,35 @@ export function chunkDocument(text, config) {
10
10
  }
11
11
  return chunkBySize(text, config);
12
12
  }
13
+ /**
14
+ * Find the best sentence-boundary cut point by scanning backwards from `pos`.
15
+ * Looks for `.` / `?` / `!` followed by whitespace, or `\n`.
16
+ * Returns the index *after* the boundary char (i.e. the start of the next sentence).
17
+ * Falls back to the nearest whitespace, then to `pos` itself if nothing found.
18
+ */
19
+ function snapToSentenceBoundary(text, pos, minPos) {
20
+ // Scan backwards up to 20% of the distance from minPos
21
+ const lookback = Math.floor((pos - minPos) * 0.2);
22
+ const limit = Math.max(minPos, pos - lookback);
23
+ for (let i = pos - 1; i >= limit; i--) {
24
+ const ch = text[i];
25
+ if (ch === '\n')
26
+ return i + 1;
27
+ if ((ch === '.' || ch === '?' || ch === '!') && i + 1 < text.length) {
28
+ const next = text[i + 1];
29
+ if (next === ' ' || next === '\n' || next === '\r' || next === '\t') {
30
+ return i + 1;
31
+ }
32
+ }
33
+ }
34
+ // Fallback: nearest whitespace boundary (avoid mid-word cuts)
35
+ for (let i = pos - 1; i >= limit; i--) {
36
+ const ch = text[i];
37
+ if (ch === ' ' || ch === '\t')
38
+ return i + 1;
39
+ }
40
+ return pos;
41
+ }
13
42
  function chunkBySize(text, config) {
14
43
  const maxSize = config?.maxChunkSize ?? 1000;
15
44
  const overlap = config?.overlap ?? 200;
@@ -20,12 +49,33 @@ function chunkBySize(text, config) {
20
49
  let start = 0;
21
50
  let idx = 0;
22
51
  while (start < text.length) {
23
- const end = Math.min(start + maxSize, text.length);
52
+ let end = Math.min(start + maxSize, text.length);
53
+ if (end < text.length) {
54
+ end = snapToSentenceBoundary(text, end, start);
55
+ }
24
56
  chunks.push({ content: text.slice(start, end), index: idx });
25
57
  idx++;
26
- if (end === text.length)
58
+ if (end >= text.length)
27
59
  break;
28
- start = end - overlap;
60
+ // Overlap: step back, then snap forward to nearest sentence start
61
+ let nextStart = end - overlap;
62
+ if (nextStart <= start) {
63
+ nextStart = end;
64
+ }
65
+ else {
66
+ // Snap forward to the start of a sentence for clean overlap
67
+ for (let i = nextStart; i < end; i++) {
68
+ const ch = text[i];
69
+ if (ch === '\n' || ch === '.' || ch === '?' || ch === '!') {
70
+ const boundary = ch === '\n' ? i + 1 : i + 2;
71
+ if (boundary <= end) {
72
+ nextStart = boundary;
73
+ break;
74
+ }
75
+ }
76
+ }
77
+ }
78
+ start = nextStart;
29
79
  // Avoid tiny trailing chunks
30
80
  if (text.length - start <= overlap) {
31
81
  chunks.push({ content: text.slice(start), index: idx });
@@ -1 +1 @@
1
- {"version":3,"file":"chunking.js","sourceRoot":"","sources":["../../../src/ai/rag/chunking.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chunking.js","sourceRoot":"","sources":["../../../src/ai/rag/chunking.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,0DAA0D;AAiB1D;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAoB;IAC9D,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,MAAM,CAAC;IAE5C,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7B,OAAO,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,IAAY,EAAE,GAAW,EAAE,MAAc;IACvE,uDAAuD;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,QAAQ,CAAC,CAAC;IAE/C,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,EAAE,KAAK,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACpE,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACzB,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBACpE,OAAO,CAAC,GAAG,CAAC,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,KAAK,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,MAAoB;IACrD,MAAM,OAAO,GAAG,MAAM,EAAE,YAAY,IAAI,IAAI,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,IAAI,GAAG,CAAC;IACvC,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC;QAC3B,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,OAAO,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC3B,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAEjD,IAAI,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YACtB,GAAG,GAAG,sBAAsB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7D,GAAG,EAAE,CAAC;QACN,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM;QAE9B,kEAAkE;QAClE,IAAI,SAAS,GAAG,GAAG,GAAG,OAAO,CAAC;QAC9B,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YACvB,SAAS,GAAG,GAAG,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,4DAA4D;YAC5D,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBACnB,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;oBAC1D,MAAM,QAAQ,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBAC7C,IAAI,QAAQ,IAAI,GAAG,EAAE,CAAC;wBACpB,SAAS,GAAG,QAAQ,CAAC;wBACrB,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK,GAAG,SAAS,CAAC;QAElB,6BAA6B;QAC7B,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,IAAI,OAAO,EAAE,CAAC;YACnC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACxD,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,MAAoB;IAC1D,MAAM,OAAO,GAAG,MAAM,EAAE,YAAY,IAAI,IAAI,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,GAAG,GAAG,CAAC,CAAC;IAEZ,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrE,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACrD,GAAG,EAAE,CAAC;YACN,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { TokenUsage } from './provider.js';
2
+ export declare class AIRefusalError extends Error {
3
+ readonly provider: string;
4
+ readonly model: string;
5
+ readonly refusalText: string;
6
+ readonly usage: TokenUsage;
7
+ constructor(args: {
8
+ provider: string;
9
+ model: string;
10
+ refusalText: string;
11
+ usage?: TokenUsage;
12
+ });
13
+ }
14
+ export declare class AIIncompleteOutputError extends Error {
15
+ readonly provider: string;
16
+ readonly model: string;
17
+ readonly partialText: string;
18
+ readonly usage: TokenUsage;
19
+ readonly finishReason: string;
20
+ constructor(args: {
21
+ provider: string;
22
+ model: string;
23
+ partialText: string;
24
+ usage?: TokenUsage;
25
+ finishReason: string;
26
+ });
27
+ }
28
+ //# sourceMappingURL=refusal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refusal.d.ts","sourceRoot":"","sources":["../../src/ai/refusal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAQhD,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;gBAEf,IAAI,EAAE;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,UAAU,CAAC;KACpB;CAQF;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,IAAI,EAAE;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;KACtB;CASF"}
@@ -0,0 +1,36 @@
1
+ const zeroUsage = Object.freeze({
2
+ inputTokens: 0,
3
+ outputTokens: 0,
4
+ totalTokens: 0,
5
+ });
6
+ export class AIRefusalError extends Error {
7
+ provider;
8
+ model;
9
+ refusalText;
10
+ usage;
11
+ constructor(args) {
12
+ super(`AI provider refused the request: ${args.refusalText}`);
13
+ this.name = 'AIRefusalError';
14
+ this.provider = args.provider;
15
+ this.model = args.model;
16
+ this.refusalText = args.refusalText;
17
+ this.usage = args.usage ?? zeroUsage;
18
+ }
19
+ }
20
+ export class AIIncompleteOutputError extends Error {
21
+ provider;
22
+ model;
23
+ partialText;
24
+ usage;
25
+ finishReason;
26
+ constructor(args) {
27
+ super(`AI provider stopped before completing structured output: ${args.finishReason}`);
28
+ this.name = 'AIIncompleteOutputError';
29
+ this.provider = args.provider;
30
+ this.model = args.model;
31
+ this.partialText = args.partialText;
32
+ this.usage = args.usage ?? zeroUsage;
33
+ this.finishReason = args.finishReason;
34
+ }
35
+ }
36
+ //# sourceMappingURL=refusal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refusal.js","sourceRoot":"","sources":["../../src/ai/refusal.ts"],"names":[],"mappings":"AAEA,MAAM,SAAS,GAAe,MAAM,CAAC,MAAM,CAAC;IAC1C,WAAW,EAAE,CAAC;IACd,YAAY,EAAE,CAAC;IACf,WAAW,EAAE,CAAC;CACf,CAAC,CAAC;AAEH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,QAAQ,CAAS;IACjB,KAAK,CAAS;IACd,WAAW,CAAS;IACpB,KAAK,CAAa;IAE3B,YAAY,IAKX;QACC,KAAK,CAAC,oCAAoC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACvC,QAAQ,CAAS;IACjB,KAAK,CAAS;IACd,WAAW,CAAS;IACpB,KAAK,CAAa;IAClB,YAAY,CAAS;IAE9B,YAAY,IAMX;QACC,KAAK,CAAC,4DAA4D,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QACvF,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACtC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC;QACrC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;IACxC,CAAC;CACF"}
@@ -1,10 +1,7 @@
1
- import type { z } from 'zod';
2
- import type { AIProviderAdapter, ProviderRequest } from './provider.js';
3
- export interface ValidationRetryConfig {
4
- /** Max retries on validation failure (default 2) */
5
- maxRetries?: number;
6
- /** Whether to append validation error to retry prompt */
7
- feedbackOnError?: boolean;
1
+ import { z } from 'zod';
2
+ import type { AIValidationOptions } from '../types/context.js';
3
+ import type { AIProviderAdapter, ProviderRequest, TokenUsage } from './provider.js';
4
+ export interface ValidationRetryConfig extends AIValidationOptions {
8
5
  }
9
6
  export interface ValidatedResponse<T> {
10
7
  data: T;
@@ -16,5 +13,40 @@ export interface ValidatedResponse<T> {
16
13
  totalTokens: number;
17
14
  };
18
15
  }
19
- export declare function generateWithValidation<T>(provider: AIProviderAdapter, request: ProviderRequest, schema: z.ZodType<T>, config?: ValidationRetryConfig): Promise<ValidatedResponse<T>>;
16
+ export declare class AIValidationError extends Error {
17
+ readonly attempts: number;
18
+ readonly rawOutput: string | null;
19
+ readonly validationMessage: string | null;
20
+ /**
21
+ * Accumulated token usage across all retry attempts the provider actually
22
+ * ran before this error was thrown. Present when the caller threaded
23
+ * provider metadata through `generateWithValidation`; otherwise a zero
24
+ * record (kept non-optional so failure-path cost recording does not need
25
+ * null-checks).
26
+ */
27
+ readonly usage: TokenUsage;
28
+ /** Resolved model name when the error was thrown (empty string if unknown). */
29
+ readonly model: string;
30
+ /** Resolved provider name when the error was thrown (empty string if unknown). */
31
+ readonly provider: string;
32
+ constructor(input: {
33
+ attempts: number;
34
+ rawOutput: string | null;
35
+ lastError: Error | null;
36
+ usage?: TokenUsage;
37
+ model?: string;
38
+ provider?: string;
39
+ });
40
+ }
41
+ export declare function generateWithValidation<T>(provider: AIProviderAdapter, request: ProviderRequest, schema: z.ZodType<T>, config?: ValidationRetryConfig & {
42
+ /**
43
+ * Optional resolved model + provider metadata attached to any
44
+ * `AIValidationError` thrown from this call. Used by the AI service
45
+ * failure-path cost recorder so it can bill the sunk spend against the
46
+ * right model. Omitted = error is thrown with empty strings (still
47
+ * compiles and still carries `usage`).
48
+ */
49
+ model?: string;
50
+ provider?: string;
51
+ }): Promise<ValidatedResponse<T>>;
20
52
  //# sourceMappingURL=validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/ai/validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EAGhB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,qBAAqB;IACpC,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,IAAI,EAAE,CAAC,CAAC;IACR,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AAED,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,CAAC,EAAE,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAoD/B"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/ai/validation.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EAEf,UAAU,EACX,MAAM,eAAe,CAAC;AAGvB,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;CAAG;AAErE,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,IAAI,EAAE,CAAC,CAAC;IACR,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AAED,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,KAAK,EAAE;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,SAAS,EAAE,KAAK,GAAG,IAAI,CAAC;QACxB,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;CAYF;AAiLD,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,CAAC,EAAE,qBAAqB,GAAG;IAC/B;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAgF/B"}
@@ -1,23 +1,222 @@
1
1
  // ── Output Validation with Retry ──
2
2
  // Validates AI responses against Zod schemas, retries on mismatch
3
+ import { parse as parseJsonc } from 'jsonc-parser';
4
+ import { z } from 'zod';
5
+ import { AIIncompleteOutputError } from './refusal.js';
6
+ export class AIValidationError extends Error {
7
+ attempts;
8
+ rawOutput;
9
+ validationMessage;
10
+ /**
11
+ * Accumulated token usage across all retry attempts the provider actually
12
+ * ran before this error was thrown. Present when the caller threaded
13
+ * provider metadata through `generateWithValidation`; otherwise a zero
14
+ * record (kept non-optional so failure-path cost recording does not need
15
+ * null-checks).
16
+ */
17
+ usage;
18
+ /** Resolved model name when the error was thrown (empty string if unknown). */
19
+ model;
20
+ /** Resolved provider name when the error was thrown (empty string if unknown). */
21
+ provider;
22
+ constructor(input) {
23
+ super(`AI output validation failed after ${input.attempts} attempts: ${input.lastError?.message}`);
24
+ this.name = 'AIValidationError';
25
+ this.attempts = input.attempts;
26
+ this.rawOutput = input.rawOutput;
27
+ this.validationMessage = input.lastError?.message ?? null;
28
+ this.usage = input.usage ?? { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
29
+ this.model = input.model ?? '';
30
+ this.provider = input.provider ?? '';
31
+ }
32
+ }
33
+ function stripMarkdownCodeFence(content) {
34
+ const trimmed = content.trim();
35
+ const fenced = trimmed.match(/^```(?:json)?\s*\n?([\s\S]*?)\n?```$/i);
36
+ return fenced?.[1]?.trim() ?? trimmed;
37
+ }
38
+ function extractJsonCandidate(content) {
39
+ const stripped = stripMarkdownCodeFence(content);
40
+ if (stripped.startsWith('{') || stripped.startsWith('[')) {
41
+ return stripped;
42
+ }
43
+ const firstObjectStart = stripped.indexOf('{');
44
+ const lastObjectEnd = stripped.lastIndexOf('}');
45
+ if (firstObjectStart >= 0 && lastObjectEnd > firstObjectStart) {
46
+ return stripped.slice(firstObjectStart, lastObjectEnd + 1);
47
+ }
48
+ const firstArrayStart = stripped.indexOf('[');
49
+ const lastArrayEnd = stripped.lastIndexOf(']');
50
+ if (firstArrayStart >= 0 && lastArrayEnd > firstArrayStart) {
51
+ return stripped.slice(firstArrayStart, lastArrayEnd + 1);
52
+ }
53
+ return stripped;
54
+ }
55
+ function escapeControlCharactersInsideStrings(content) {
56
+ let result = '';
57
+ let inString = false;
58
+ let escaped = false;
59
+ for (const character of content) {
60
+ if (escaped) {
61
+ result += character;
62
+ escaped = false;
63
+ continue;
64
+ }
65
+ if (character === '\\') {
66
+ result += character;
67
+ escaped = true;
68
+ continue;
69
+ }
70
+ if (character === '"') {
71
+ result += character;
72
+ inString = !inString;
73
+ continue;
74
+ }
75
+ if (inString) {
76
+ if (character === '\n') {
77
+ result += '\\n';
78
+ continue;
79
+ }
80
+ if (character === '\r') {
81
+ result += '\\r';
82
+ continue;
83
+ }
84
+ if (character === '\t') {
85
+ result += '\\t';
86
+ continue;
87
+ }
88
+ }
89
+ result += character;
90
+ }
91
+ return result;
92
+ }
93
+ function parseJsonCandidate(candidate) {
94
+ const errors = [];
95
+ const parsed = parseJsonc(candidate, errors, {
96
+ allowTrailingComma: true,
97
+ disallowComments: false,
98
+ });
99
+ if (errors.length > 0) {
100
+ const firstError = errors[0];
101
+ if (firstError) {
102
+ throw new SyntaxError(`JSONC parse failed with code ${firstError.error} at offset ${firstError.offset}`);
103
+ }
104
+ throw new SyntaxError('JSONC parse failed');
105
+ }
106
+ return parsed;
107
+ }
108
+ /**
109
+ * Detects whether an output schema accepts a raw string at the top level.
110
+ *
111
+ * When the prompt author declares `output: z.string()` (or a trivially
112
+ * wrapped variant like `z.string().optional()` / `.nullable()`), the intent
113
+ * is to let the AI return raw text — typically a custom line-delimited
114
+ * format parsed by the capability. In that case we MUST NOT force the
115
+ * provider into JSON mode (OpenAI `response_format: json_object`), because
116
+ * the model will wrap the text into a JSON object and downstream
117
+ * `schema.parse(<object>)` will blow up with "Expected string, received
118
+ * object".
119
+ *
120
+ * Unwrapping `.optional()` / `.nullable()` is safe: they still pass a raw
121
+ * string through unchanged.
122
+ */
123
+ function isStringOutputSchema(schema) {
124
+ let current = schema;
125
+ // Unwrap one level of optional/nullable/default at a time, capping the
126
+ // loop so a bad schema can never hang the process.
127
+ for (let depth = 0; depth < 5; depth += 1) {
128
+ if (current instanceof z.ZodString) {
129
+ return true;
130
+ }
131
+ if (current instanceof z.ZodOptional || current instanceof z.ZodNullable) {
132
+ current = current._def.innerType;
133
+ continue;
134
+ }
135
+ if (current instanceof z.ZodDefault) {
136
+ current = current._def.innerType;
137
+ continue;
138
+ }
139
+ return false;
140
+ }
141
+ return false;
142
+ }
143
+ function parseStructuredResponse(content) {
144
+ try {
145
+ return JSON.parse(content);
146
+ }
147
+ catch (originalError) {
148
+ let lastError = originalError instanceof Error ? originalError : new Error(String(originalError));
149
+ const extracted = extractJsonCandidate(content);
150
+ if (extracted !== content) {
151
+ try {
152
+ return JSON.parse(extracted);
153
+ }
154
+ catch (extractedError) {
155
+ lastError =
156
+ extractedError instanceof Error ? extractedError : new Error(String(extractedError));
157
+ }
158
+ }
159
+ const sanitized = escapeControlCharactersInsideStrings(extracted);
160
+ if (sanitized !== extracted) {
161
+ try {
162
+ return JSON.parse(sanitized);
163
+ }
164
+ catch (sanitizedError) {
165
+ lastError =
166
+ sanitizedError instanceof Error ? sanitizedError : new Error(String(sanitizedError));
167
+ }
168
+ }
169
+ const completeJsonLikeObject = (sanitized.startsWith('{') && sanitized.includes('}')) ||
170
+ (sanitized.startsWith('[') && sanitized.includes(']'));
171
+ if (completeJsonLikeObject) {
172
+ try {
173
+ return parseJsonCandidate(sanitized);
174
+ }
175
+ catch (jsoncError) {
176
+ lastError = jsoncError instanceof Error ? jsoncError : new Error(String(jsoncError));
177
+ }
178
+ }
179
+ throw lastError;
180
+ }
181
+ }
3
182
  export async function generateWithValidation(provider, request, schema, config) {
4
183
  const maxRetries = config?.maxRetries ?? 2;
5
184
  const feedbackOnError = config?.feedbackOnError ?? true;
185
+ // Prompts with `output: z.string()` want raw text (e.g. a pipe-separated
186
+ // line format parsed by the capability). Forcing JSON mode on those
187
+ // would make the model wrap the text in a JSON object and shatter
188
+ // schema validation, so we switch to text mode and skip JSON parsing.
189
+ const textOutput = isStringOutputSchema(schema);
6
190
  let totalUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
7
191
  let lastError = null;
192
+ let lastRawOutput = null;
8
193
  let currentPrompt = request.prompt;
9
194
  for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {
10
- // OpenAI requires the word "json" in the prompt when using json_object response format.
11
- // Auto-inject a JSON instruction if the prompt doesn't already mention it.
12
195
  let promptForRequest = currentPrompt;
13
- if (!currentPrompt.toLowerCase().includes('json')) {
196
+ if (!textOutput && !request.responseSchema && !currentPrompt.toLowerCase().includes('json')) {
197
+ // OpenAI requires the word "json" in the prompt when using
198
+ // json_object response format. Only inject the hint for JSON-mode
199
+ // prompts without a provider schema — text-mode prompts never go into
200
+ // json_object, and json_schema requests should not need a prose JSON
201
+ // instruction as a substitute for constrained decoding.
14
202
  promptForRequest = `${currentPrompt}\n\nRespond with a valid JSON object.`;
15
203
  }
16
204
  const response = await provider.complete({
17
205
  ...request,
18
206
  prompt: promptForRequest,
19
- responseFormat: 'json',
207
+ responseFormat: textOutput ? 'text' : 'json',
20
208
  });
209
+ lastRawOutput = response.content;
210
+ if (!textOutput &&
211
+ (response.finishReason === 'length' || response.finishReason === 'max_tokens')) {
212
+ throw new AIIncompleteOutputError({
213
+ provider: config?.provider ?? provider.name,
214
+ model: config?.model ?? response.model,
215
+ partialText: response.content,
216
+ usage: response.usage,
217
+ finishReason: response.finishReason,
218
+ });
219
+ }
21
220
  totalUsage = {
22
221
  inputTokens: totalUsage.inputTokens + response.usage.inputTokens,
23
222
  outputTokens: totalUsage.outputTokens + response.usage.outputTokens,
@@ -26,7 +225,7 @@ export async function generateWithValidation(provider, request, schema, config)
26
225
  cacheWriteTokens: (totalUsage.cacheWriteTokens ?? 0) + (response.usage.cacheWriteTokens ?? 0),
27
226
  };
28
227
  try {
29
- const parsed = JSON.parse(response.content);
228
+ const parsed = textOutput ? response.content : parseStructuredResponse(response.content);
30
229
  const result = schema.parse(parsed);
31
230
  return {
32
231
  data: result,
@@ -42,6 +241,13 @@ export async function generateWithValidation(provider, request, schema, config)
42
241
  }
43
242
  }
44
243
  }
45
- throw new Error(`AI output validation failed after ${maxRetries + 1} attempts: ${lastError?.message}`);
244
+ throw new AIValidationError({
245
+ attempts: maxRetries + 1,
246
+ rawOutput: lastRawOutput,
247
+ lastError,
248
+ usage: totalUsage,
249
+ model: config?.model ?? '',
250
+ provider: config?.provider ?? provider.name,
251
+ });
46
252
  }
47
253
  //# sourceMappingURL=validation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/ai/validation.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,kEAAkE;AAwBlE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAA2B,EAC3B,OAAwB,EACxB,MAAoB,EACpB,MAA8B;IAE9B,MAAM,UAAU,GAAG,MAAM,EAAE,UAAU,IAAI,CAAC,CAAC;IAC3C,MAAM,eAAe,GAAG,MAAM,EAAE,eAAe,IAAI,IAAI,CAAC;IAExD,IAAI,UAAU,GAAe,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;IACjF,IAAI,SAAS,GAAiB,IAAI,CAAC;IACnC,IAAI,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAEnC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3D,wFAAwF;QACxF,2EAA2E;QAC3E,IAAI,gBAAgB,GAAG,aAAa,CAAC;QACrC,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAClD,gBAAgB,GAAG,GAAG,aAAa,uCAAuC,CAAC;QAC7E,CAAC;QAED,MAAM,QAAQ,GAAqB,MAAM,QAAQ,CAAC,QAAQ,CAAC;YACzD,GAAG,OAAO;YACV,MAAM,EAAE,gBAAgB;YACxB,cAAc,EAAE,MAAM;SACvB,CAAC,CAAC;QAEH,UAAU,GAAG;YACX,WAAW,EAAE,UAAU,CAAC,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW;YAChE,YAAY,EAAE,UAAU,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY;YACnE,WAAW,EAAE,UAAU,CAAC,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW;YAChE,iBAAiB,EACf,CAAC,UAAU,CAAC,iBAAiB,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,CAAC;YAC/E,gBAAgB,EAAE,CAAC,UAAU,CAAC,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC;SAC9F,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACpC,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,QAAQ,CAAC,OAAO;gBACrB,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,UAAU;aAClB,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAEhE,IAAI,OAAO,IAAI,UAAU,IAAI,eAAe,EAAE,CAAC;gBAC7C,aAAa,GAAG,GAAG,OAAO,CAAC,MAAM,kDAAkD,SAAS,CAAC,OAAO,uDAAuD,CAAC;YAC9J,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,qCAAqC,UAAU,GAAG,CAAC,cAAc,SAAS,EAAE,OAAO,EAAE,CACtF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/ai/validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { z } from 'zod';
2
+ export interface ProviderJsonSchemaResult {
3
+ schema: Record<string, unknown>;
4
+ optionalParameterCount: number;
5
+ unionParameterCount: number;
6
+ }
7
+ export interface ProviderJsonSchemaOptions {
8
+ promptName?: string;
9
+ }
10
+ export declare class ProviderJsonSchemaError extends Error {
11
+ readonly promptName?: string;
12
+ constructor(message: string, promptName?: string);
13
+ }
14
+ export declare function zodToProviderJsonSchema(zodSchema: z.ZodTypeAny, options?: ProviderJsonSchemaOptions): ProviderJsonSchemaResult;
15
+ //# sourceMappingURL=zod-to-provider-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-to-provider-schema.d.ts","sourceRoot":"","sources":["../../src/ai/zod-to-provider-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgB7B,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAKjD;AA2MD,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,CAAC,CAAC,UAAU,EACvB,OAAO,GAAE,yBAA8B,GACtC,wBAAwB,CAkC1B"}