pulseed 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +9 -62
  2. package/dist/cli/commands/config.d.ts.map +1 -1
  3. package/dist/cli/commands/config.js +2 -1
  4. package/dist/cli/commands/config.js.map +1 -1
  5. package/dist/cli/commands/goal-utils.d.ts.map +1 -1
  6. package/dist/cli/commands/goal-utils.js +18 -6
  7. package/dist/cli/commands/goal-utils.js.map +1 -1
  8. package/dist/cli/commands/goal-write.d.ts.map +1 -1
  9. package/dist/cli/commands/goal-write.js +34 -1
  10. package/dist/cli/commands/goal-write.js.map +1 -1
  11. package/dist/cli/commands/setup.d.ts.map +1 -1
  12. package/dist/cli/commands/setup.js +18 -0
  13. package/dist/cli/commands/setup.js.map +1 -1
  14. package/dist/cli/commands/suggest-normalizer.d.ts.map +1 -1
  15. package/dist/cli/commands/suggest-normalizer.js +5 -0
  16. package/dist/cli/commands/suggest-normalizer.js.map +1 -1
  17. package/dist/cli/commands/suggest.d.ts.map +1 -1
  18. package/dist/cli/commands/suggest.js +13 -3
  19. package/dist/cli/commands/suggest.js.map +1 -1
  20. package/dist/cli/commands/task-read 2.d.ts +4 -0
  21. package/dist/cli/commands/task-read 2.d.ts.map +1 -0
  22. package/dist/cli/commands/task-read 2.js +195 -0
  23. package/dist/cli/commands/task-read 2.js.map +1 -0
  24. package/dist/cli/commands/task-read.d.ts +4 -0
  25. package/dist/cli/commands/task-read.d.ts.map +1 -0
  26. package/dist/cli/commands/task-read.js +195 -0
  27. package/dist/cli/commands/task-read.js.map +1 -0
  28. package/dist/cli/setup.d.ts.map +1 -1
  29. package/dist/cli/setup.js +4 -2
  30. package/dist/cli/setup.js.map +1 -1
  31. package/dist/cli-runner.d.ts.map +1 -1
  32. package/dist/cli-runner.js +19 -0
  33. package/dist/cli-runner.js.map +1 -1
  34. package/dist/core-loop.d.ts.map +1 -1
  35. package/dist/core-loop.js +1 -0
  36. package/dist/core-loop.js.map +1 -1
  37. package/dist/drive/progress-predictor.d.ts +24 -0
  38. package/dist/drive/progress-predictor.d.ts.map +1 -0
  39. package/dist/drive/progress-predictor.js +93 -0
  40. package/dist/drive/progress-predictor.js.map +1 -0
  41. package/dist/drive/stall-detector.d.ts +8 -1
  42. package/dist/drive/stall-detector.d.ts.map +1 -1
  43. package/dist/drive/stall-detector.js +42 -2
  44. package/dist/drive/stall-detector.js.map +1 -1
  45. package/dist/execution/reflection-generator.d.ts +1 -1
  46. package/dist/execution/reflection-generator.d.ts.map +1 -1
  47. package/dist/execution/reflection-generator.js +3 -3
  48. package/dist/execution/reflection-generator.js.map +1 -1
  49. package/dist/execution/task-executor.d.ts.map +1 -1
  50. package/dist/execution/task-executor.js +1 -0
  51. package/dist/execution/task-executor.js.map +1 -1
  52. package/dist/execution/task-generation.js +1 -1
  53. package/dist/execution/task-generation.js.map +1 -1
  54. package/dist/execution/task-lifecycle.js +1 -1
  55. package/dist/execution/task-lifecycle.js.map +1 -1
  56. package/dist/execution/task-verifier.d.ts.map +1 -1
  57. package/dist/execution/task-verifier.js +11 -2
  58. package/dist/execution/task-verifier.js.map +1 -1
  59. package/dist/goal/goal-dependency-graph.d.ts +6 -1
  60. package/dist/goal/goal-dependency-graph.d.ts.map +1 -1
  61. package/dist/goal/goal-dependency-graph.js +6 -3
  62. package/dist/goal/goal-dependency-graph.js.map +1 -1
  63. package/dist/goal/goal-negotiator.d.ts.map +1 -1
  64. package/dist/goal/goal-negotiator.js +36 -14
  65. package/dist/goal/goal-negotiator.js.map +1 -1
  66. package/dist/goal/goal-refiner.d.ts.map +1 -1
  67. package/dist/goal/goal-refiner.js +6 -8
  68. package/dist/goal/goal-refiner.js.map +1 -1
  69. package/dist/goal/goal-suggest.d.ts +9 -2
  70. package/dist/goal/goal-suggest.d.ts.map +1 -1
  71. package/dist/goal/goal-suggest.js +74 -17
  72. package/dist/goal/goal-suggest.js.map +1 -1
  73. package/dist/goal/goal-tree-manager.d.ts.map +1 -1
  74. package/dist/goal/goal-tree-manager.js +8 -10
  75. package/dist/goal/goal-tree-manager.js.map +1 -1
  76. package/dist/goal/negotiator-steps.d.ts.map +1 -1
  77. package/dist/goal/negotiator-steps.js +1 -3
  78. package/dist/goal/negotiator-steps.js.map +1 -1
  79. package/dist/goal/refiner-prompts.d.ts +1 -17
  80. package/dist/goal/refiner-prompts.d.ts.map +1 -1
  81. package/dist/goal/refiner-prompts.js +1 -65
  82. package/dist/goal/refiner-prompts.js.map +1 -1
  83. package/dist/goal/subgoal-curriculum.d.ts +30 -0
  84. package/dist/goal/subgoal-curriculum.d.ts.map +1 -0
  85. package/dist/goal/subgoal-curriculum.js +53 -0
  86. package/dist/goal/subgoal-curriculum.js.map +1 -0
  87. package/dist/goal/tree-loop-orchestrator.d.ts.map +1 -1
  88. package/dist/goal/tree-loop-orchestrator.js +3 -2
  89. package/dist/goal/tree-loop-orchestrator.js.map +1 -1
  90. package/dist/llm/base-llm-client.d.ts +38 -6
  91. package/dist/llm/base-llm-client.d.ts.map +1 -1
  92. package/dist/llm/base-llm-client.js +120 -14
  93. package/dist/llm/base-llm-client.js.map +1 -1
  94. package/dist/llm/json-sanitizer.d.ts +34 -0
  95. package/dist/llm/json-sanitizer.d.ts.map +1 -0
  96. package/dist/llm/json-sanitizer.js +110 -0
  97. package/dist/llm/json-sanitizer.js.map +1 -0
  98. package/dist/llm/llm-client.d.ts +10 -2
  99. package/dist/llm/llm-client.d.ts.map +1 -1
  100. package/dist/llm/llm-client.js +19 -2
  101. package/dist/llm/llm-client.js.map +1 -1
  102. package/dist/llm/provider-factory.js +1 -1
  103. package/dist/llm/provider-factory.js.map +1 -1
  104. package/dist/loop/core-loop-phases-b.d.ts.map +1 -1
  105. package/dist/loop/core-loop-phases-b.js +6 -0
  106. package/dist/loop/core-loop-phases-b.js.map +1 -1
  107. package/dist/observation/capability-detector.d.ts.map +1 -1
  108. package/dist/observation/capability-detector.js +2 -1
  109. package/dist/observation/capability-detector.js.map +1 -1
  110. package/dist/observation/observation-llm.d.ts.map +1 -1
  111. package/dist/observation/observation-llm.js +3 -1
  112. package/dist/observation/observation-llm.js.map +1 -1
  113. package/dist/runtime/daemon-runner.d.ts.map +1 -1
  114. package/dist/runtime/daemon-runner.js +8 -4
  115. package/dist/runtime/daemon-runner.js.map +1 -1
  116. package/dist/tui/entry.d.ts.map +1 -1
  117. package/dist/tui/entry.js +4 -2
  118. package/dist/tui/entry.js.map +1 -1
  119. package/dist/types/core.d.ts +1 -1
  120. package/dist/types/core.d.ts.map +1 -1
  121. package/dist/types/core.js +2 -0
  122. package/dist/types/core.js.map +1 -1
  123. package/dist/types/stall.d.ts +3 -3
  124. package/dist/types/task-group.d.ts +15 -0
  125. package/dist/types/task-group.d.ts.map +1 -1
  126. package/dist/types/task.d.ts +9 -0
  127. package/dist/types/task.d.ts.map +1 -1
  128. package/dist/types/task.js +4 -0
  129. package/dist/types/task.js.map +1 -1
  130. package/package.json +2 -2
@@ -1,21 +1,5 @@
1
1
  import type { Goal } from "../types/goal.js";
2
- /**
3
- * Sanitizes LLM-returned threshold_type strings to valid enum values.
4
- * Handles the union of all known non-standard values from both
5
- * GoalRefiner (leaf test) and GoalTreeManager (subgoal decomposition).
6
- *
7
- * Uses regex replacement so it works on raw JSON strings before parsing.
8
- */
9
- export declare function sanitizeThresholdTypes(raw: string): string;
10
- /**
11
- * Sanitizes LLM-returned threshold_value when threshold_type is "present".
12
- * When the LLM returns an object (e.g. `{"type":"present"}`) as the value for
13
- * a present threshold, replace it with null so downstream Zod schemas accept it.
14
- *
15
- * Operates on the raw JSON string before parsing to avoid any type-safety issues
16
- * with the un-parsed LLM output.
17
- */
18
- export declare function sanitizeThresholdValues(raw: string): string;
2
+ export { sanitizeThresholdTypes, sanitizeThresholdValues } from "../llm/json-sanitizer.js";
19
3
  /**
20
4
  * Builds the leaf test prompt for the GoalRefiner.
21
5
  *
@@ -1 +1 @@
1
- {"version":3,"file":"refiner-prompts.d.ts","sourceRoot":"","sources":["../../src/goal/refiner-prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAe7C;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAS1D;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY3D;AAqBD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,EACV,oBAAoB,EAAE,MAAM,EAAE,GAC7B,MAAM,CAkDR"}
1
+ {"version":3,"file":"refiner-prompts.d.ts","sourceRoot":"","sources":["../../src/goal/refiner-prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAE3F;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,EACV,oBAAoB,EAAE,MAAM,EAAE,GAC7B,MAAM,CAkDR"}
@@ -1,68 +1,4 @@
1
- // ─── Threshold type sanitizer ───
2
- const THRESHOLD_TYPE_MAP = {
3
- exact: "match",
4
- scale: "min",
5
- qualitative: "min",
6
- boolean: "present",
7
- percentage: "min",
8
- count: "min",
9
- };
10
- const VALID_THRESHOLD_TYPES = new Set(["min", "max", "range", "present", "match"]);
11
- /**
12
- * Sanitizes LLM-returned threshold_type strings to valid enum values.
13
- * Handles the union of all known non-standard values from both
14
- * GoalRefiner (leaf test) and GoalTreeManager (subgoal decomposition).
15
- *
16
- * Uses regex replacement so it works on raw JSON strings before parsing.
17
- */
18
- export function sanitizeThresholdTypes(raw) {
19
- return raw.replace(/"threshold_type"\s*:\s*"([^"]+)"/g, (_match, val) => {
20
- if (VALID_THRESHOLD_TYPES.has(val))
21
- return `"threshold_type": "${val}"`;
22
- const mapped = THRESHOLD_TYPE_MAP[val] ?? "min";
23
- return `"threshold_type": "${mapped}"`;
24
- });
25
- }
26
- /**
27
- * Sanitizes LLM-returned threshold_value when threshold_type is "present".
28
- * When the LLM returns an object (e.g. `{"type":"present"}`) as the value for
29
- * a present threshold, replace it with null so downstream Zod schemas accept it.
30
- *
31
- * Operates on the raw JSON string before parsing to avoid any type-safety issues
32
- * with the un-parsed LLM output.
33
- */
34
- export function sanitizeThresholdValues(raw) {
35
- // Find any "threshold_value": <object> that immediately follows a "present" threshold_type.
36
- // Strategy: parse and re-serialize only the threshold_value fields for present dimensions.
37
- // We use a two-pass approach on the raw string to avoid fragile regex on nested JSON.
38
- try {
39
- const parsed = JSON.parse(raw);
40
- const sanitized = sanitizePresentThresholdValues(parsed);
41
- return JSON.stringify(sanitized);
42
- }
43
- catch {
44
- // If JSON parsing fails, return as-is and let downstream parsers handle it.
45
- return raw;
46
- }
47
- }
48
- function sanitizePresentThresholdValues(value) {
49
- if (Array.isArray(value)) {
50
- return value.map(sanitizePresentThresholdValues);
51
- }
52
- if (value !== null && typeof value === "object") {
53
- const record = value;
54
- const result = {};
55
- for (const [k, v] of Object.entries(record)) {
56
- result[k] = sanitizePresentThresholdValues(v);
57
- }
58
- // If this object has threshold_type === "present" and threshold_value is an object, null it out.
59
- if (result["threshold_type"] === "present" && typeof result["threshold_value"] === "object" && result["threshold_value"] !== null) {
60
- result["threshold_value"] = null;
61
- }
62
- return result;
63
- }
64
- return value;
65
- }
1
+ export { sanitizeThresholdTypes, sanitizeThresholdValues } from "../llm/json-sanitizer.js";
66
2
  /**
67
3
  * Builds the leaf test prompt for the GoalRefiner.
68
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"refiner-prompts.js","sourceRoot":"","sources":["../../src/goal/refiner-prompts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"refiner-prompts.js","sourceRoot":"","sources":["../../src/goal/refiner-prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAU,EACV,oBAA8B;IAE9B,MAAM,kBAAkB,GACtB,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QACzB,CAAC,CAAC,gBAAgB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QAC/C,CAAC,CAAC,mBAAmB,CAAC;IAE1B,MAAM,kBAAkB,GACtB,oBAAoB,CAAC,MAAM,GAAG,CAAC;QAC7B,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;QACjC,CAAC,CAAC,uBAAuB,CAAC;IAE9B,OAAO;;SAEA,IAAI,CAAC,WAAW;EACvB,kBAAkB;0BACM,kBAAkB;SACnC,IAAI,CAAC,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oEAiCmC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Difficulty-based curriculum ordering for subgoal selection.
3
+ * Prioritizes medium-complexity (0.3-0.7) subgoals using gap × (1 - confidence).
4
+ */
5
+ import type { Goal } from "../types/goal.js";
6
+ /** Preferred difficulty band for curriculum-based selection. */
7
+ export declare const MEDIUM_BAND: {
8
+ min: number;
9
+ max: number;
10
+ };
11
+ /** Goals with aggregated gap below this threshold are treated as medium difficulty to avoid starvation. */
12
+ export declare const NEAR_COMPLETE_GAP_THRESHOLD = 0.1;
13
+ /**
14
+ * Estimate difficulty for a single goal.
15
+ * difficulty = aggregatedGap × (1 - minConfidence), clamped to [0, 1].
16
+ * Uses calculateDimensionGap for consistent gap computation, aggregateGaps for aggregation.
17
+ * Returns 0.5 (medium) when dimensions is empty or goal is near-complete.
18
+ */
19
+ export declare function estimateDifficulty(goal: Goal): number;
20
+ /**
21
+ * Sort subgoal entries in-place using center-biased curriculum ordering.
22
+ * Primary: |difficulty - 0.5| ascending (closest to medium first).
23
+ * Tiebreaker: depth descending (deeper first).
24
+ */
25
+ export declare function curriculumSort(entries: Array<{
26
+ id: string;
27
+ depth: number;
28
+ difficulty: number;
29
+ }>): void;
30
+ //# sourceMappingURL=subgoal-curriculum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subgoal-curriculum.d.ts","sourceRoot":"","sources":["../../src/goal/subgoal-curriculum.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAM7C,gEAAgE;AAChE,eAAO,MAAM,WAAW;;;CAAyB,CAAC;AAElD,2GAA2G;AAC3G,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CA8BrD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,GAChE,IAAI,CAON"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Difficulty-based curriculum ordering for subgoal selection.
3
+ * Prioritizes medium-complexity (0.3-0.7) subgoals using gap × (1 - confidence).
4
+ */
5
+ import { calculateDimensionGap, aggregateGaps, } from "../drive/gap-calculator.js";
6
+ /** Preferred difficulty band for curriculum-based selection. */
7
+ export const MEDIUM_BAND = { min: 0.3, max: 0.7 };
8
+ /** Goals with aggregated gap below this threshold are treated as medium difficulty to avoid starvation. */
9
+ export const NEAR_COMPLETE_GAP_THRESHOLD = 0.1;
10
+ /**
11
+ * Estimate difficulty for a single goal.
12
+ * difficulty = aggregatedGap × (1 - minConfidence), clamped to [0, 1].
13
+ * Uses calculateDimensionGap for consistent gap computation, aggregateGaps for aggregation.
14
+ * Returns 0.5 (medium) when dimensions is empty or goal is near-complete.
15
+ */
16
+ export function estimateDifficulty(goal) {
17
+ const dims = goal.dimensions;
18
+ if (dims.length === 0)
19
+ return 0.5;
20
+ const weightedGaps = dims.map((d) => calculateDimensionGap({
21
+ name: d.name,
22
+ current_value: d.current_value,
23
+ threshold: d.threshold,
24
+ confidence: d.confidence,
25
+ uncertainty_weight: d.uncertainty_weight,
26
+ }, goal.uncertainty_weight));
27
+ // Use normalized_gap (pre-uncertainty-weighting) so the confidence multiplier
28
+ // below applies uniformly, including for null current_value (which yields 1.0).
29
+ const gapValues = weightedGaps.map((wg) => wg.normalized_gap);
30
+ const weights = dims.map((d) => d.weight ?? 1.0);
31
+ const minConfidence = Math.min(...dims.map((d) => d.confidence));
32
+ const aggregatedGap = aggregateGaps(gapValues, goal.gap_aggregation, weights);
33
+ // Near-complete goals (gap < threshold) should not be starved — treat as medium difficulty
34
+ if (aggregatedGap < NEAR_COMPLETE_GAP_THRESHOLD)
35
+ return 0.5;
36
+ const difficulty = aggregatedGap * (1 - minConfidence);
37
+ return Math.min(1, Math.max(0, difficulty));
38
+ }
39
+ /**
40
+ * Sort subgoal entries in-place using center-biased curriculum ordering.
41
+ * Primary: |difficulty - 0.5| ascending (closest to medium first).
42
+ * Tiebreaker: depth descending (deeper first).
43
+ */
44
+ export function curriculumSort(entries) {
45
+ entries.sort((a, b) => {
46
+ const aDist = Math.abs(a.difficulty - 0.5);
47
+ const bDist = Math.abs(b.difficulty - 0.5);
48
+ if (aDist !== bDist)
49
+ return aDist - bDist;
50
+ return b.depth - a.depth;
51
+ });
52
+ }
53
+ //# sourceMappingURL=subgoal-curriculum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subgoal-curriculum.js","sourceRoot":"","sources":["../../src/goal/subgoal-curriculum.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,qBAAqB,EACrB,aAAa,GACd,MAAM,4BAA4B,CAAC;AAEpC,gEAAgE;AAChE,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAElD,2GAA2G;AAC3G,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAU;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;IAC7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IAElC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAClC,qBAAqB,CACnB;QACE,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,aAAa,EAAE,CAAC,CAAC,aAAa;QAC9B,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,kBAAkB,EAAE,CAAC,CAAC,kBAAkB;KACzC,EACD,IAAI,CAAC,kBAAkB,CACxB,CACF,CAAC;IAEF,8EAA8E;IAC9E,gFAAgF;IAChF,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IAEjE,MAAM,aAAa,GAAG,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAE9E,2FAA2F;IAC3F,IAAI,aAAa,GAAG,2BAA2B;QAAE,OAAO,GAAG,CAAC;IAE5D,MAAM,UAAU,GAAG,aAAa,GAAG,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAiE;IAEjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;QAC3C,IAAI,KAAK,KAAK,KAAK;YAAE,OAAO,KAAK,GAAG,KAAK,CAAC;QAC1C,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"tree-loop-orchestrator.d.ts","sourceRoot":"","sources":["../../src/goal/tree-loop-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAGrE;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAoB;IAa7B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAhB/B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAKZ;gBAGiB,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EAChC,eAAe,EAAE,eAAe,EAChC,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,CAAC,EAAE,WAAW,YAAA;IAK5C;;;;;OAKG;IACG,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC;IAwBhB;;;;;;OAMG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCtD;;;;;;;;;;;;;OAaG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA4B5D;;;;OAIG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlD;;;;OAIG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAanD;;;;;;;;OAQG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCpD;;OAEG;YACW,wBAAwB;IAWtC;;;OAGG;YACW,qBAAqB;IAqBnC;;OAEG;YACW,uBAAuB;CAatC"}
1
+ {"version":3,"file":"tree-loop-orchestrator.d.ts","sourceRoot":"","sources":["../../src/goal/tree-loop-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAIrE;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAoB;IAa7B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;IAhB/B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAKZ;gBAGiB,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EAChC,eAAe,EAAE,eAAe,EAChC,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,CAAC,EAAE,WAAW,YAAA;IAK5C;;;;;OAKG;IACG,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC;IAwBhB;;;;;;OAMG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCtD;;;;;;;;;;;;;OAaG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA4B5D;;;;OAIG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlD;;;;OAIG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAanD;;;;;;;;OAQG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCpD;;OAEG;YACW,wBAAwB;IAWtC;;;OAGG;YACW,qBAAqB;IAqBnC;;OAEG;YACW,uBAAuB;CAatC"}
@@ -1,4 +1,5 @@
1
1
  import { hasValidatedDimensions } from "./goal-refiner.js";
2
+ import { estimateDifficulty, curriculumSort } from "./subgoal-curriculum.js";
2
3
  /**
3
4
  * TreeLoopOrchestrator manages the execution of independent loops across
4
5
  * all nodes in a goal tree.
@@ -239,13 +240,13 @@ export class TreeLoopOrchestrator {
239
240
  if (goal.loop_status === "running" || goal.loop_status === "paused")
240
241
  continue;
241
242
  if (goal.node_type === "leaf") {
242
- eligibleLeaves.push({ id, depth: goal.decomposition_depth ?? 0 });
243
+ eligibleLeaves.push({ id, depth: goal.decomposition_depth ?? 0, difficulty: estimateDifficulty(goal) });
243
244
  }
244
245
  else {
245
246
  eligibleNonLeaves.push(id);
246
247
  }
247
248
  }
248
- eligibleLeaves.sort((a, b) => b.depth - a.depth);
249
+ curriculumSort(eligibleLeaves);
249
250
  return eligibleLeaves[0]?.id ?? eligibleNonLeaves[0] ?? null;
250
251
  }
251
252
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tree-loop-orchestrator.js","sourceRoot":"","sources":["../../src/goal/tree-loop-orchestrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tree-loop-orchestrator.js","sourceRoot":"","sources":["../../src/goal/tree-loop-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -9,10 +9,27 @@ export declare const MAX_RETRY_ATTEMPTS = 3;
9
9
  /** Exponential backoff delays in milliseconds: 1s, 2s, 4s */
10
10
  export declare const RETRY_DELAYS_MS: number[];
11
11
  /**
12
- * Extract JSON from a string that may contain markdown code blocks.
13
- * Tries ```json ... ``` first, then ``` ... ```, then bare JSON.
12
+ * Extract JSON from a string that may contain markdown code blocks or prose.
13
+ *
14
+ * Strategies (first match wins):
15
+ * 1. Fast path — already valid JSON, return as-is
16
+ * 2. Code fence extraction — ```json ... ``` or ``` ... ```
17
+ * 3. Brace matching — find first { or [ and last matching } or ]
14
18
  */
15
19
  export declare function extractJSON(text: string): string;
20
+ export interface ParseJSONMessage {
21
+ role: string;
22
+ content: string;
23
+ }
24
+ /** Options for parseJSON(). Pass `retry` to enable a single re-prompt on failure. */
25
+ export interface ParseJSONOptions {
26
+ retry?: {
27
+ /** Original messages used to produce the first LLM response. */
28
+ messages: ParseJSONMessage[];
29
+ /** Optional system prompt for the retry call. */
30
+ systemPrompt?: string;
31
+ };
32
+ }
16
33
  /**
17
34
  * Abstract base for all LLM clients.
18
35
  * Provides a shared parseJSON() implementation with safeParse-based validation,
@@ -29,10 +46,25 @@ export declare abstract class BaseLLMClient {
29
46
  */
30
47
  protected resolveEffectiveModel(defaultModel: string, tier?: ModelTier): string;
31
48
  /**
32
- * Extract JSON from LLM response text (handles markdown code blocks)
33
- * and validate against the given Zod schema.
34
- * Throws on parse failure or schema validation failure with detailed messages.
35
- */
49
+ * Send messages to the LLM and return the response text.
50
+ * Used internally by parseJSON retry logic.
51
+ * Subclasses that support retry must override this method.
52
+ */
53
+ protected callLLMRaw(_messages: ParseJSONMessage[], _systemPrompt?: string): Promise<string>;
54
+ /**
55
+ * Attempt to parse and validate a single content string against the schema.
56
+ * Returns the parsed value on success, or throws LLMError on failure.
57
+ */
58
+ private attemptParse;
59
+ /**
60
+ * Extract JSON from LLM response text (handles markdown code blocks)
61
+ * and validate against the given Zod schema.
62
+ * Throws on parse failure or schema validation failure with detailed messages.
63
+ *
64
+ * When `options.retry` is provided, a single retry is attempted on first failure:
65
+ * the original messages are re-sent with an error feedback message appended.
66
+ */
67
+ parseJSON<T>(content: string, schema: ZodSchema<T>, options?: ParseJSONOptions): Promise<T>;
36
68
  parseJSON<T>(content: string, schema: ZodSchema<T>): T;
37
69
  }
38
70
  //# sourceMappingURL=base-llm-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-llm-client.d.ts","sourceRoot":"","sources":["../../src/llm/base-llm-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAKrC,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAIzC,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,kDAAkD;AAClD,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C,2DAA2D;AAC3D,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,6DAA6D;AAC7D,eAAO,MAAM,eAAe,UAAqB,CAAC;AAIlD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUhD;AAID;;;;GAIG;AACH,8BAAsB,aAAa;IACjC,iFAAiF;IACjF,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;OAKG;IACH,SAAS,CAAC,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM;IAO/E;;;;MAIE;IACF,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;CAmBvD"}
1
+ {"version":3,"file":"base-llm-client.d.ts","sourceRoot":"","sources":["../../src/llm/base-llm-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAMrC,2EAA2E;AAC3E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAIzC,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,kDAAkD;AAClD,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C,2DAA2D;AAC3D,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC,6DAA6D;AAC7D,eAAO,MAAM,eAAe,UAAqB,CAAC;AAIlD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA2DhD;AAID,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE;QACN,gEAAgE;QAChE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;QAC7B,iDAAiD;QACjD,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAID;;;;GAIG;AACH,8BAAsB,aAAa;IACjC,iFAAiF;IACjF,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;OAKG;IACH,SAAS,CAAC,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM;IAO/E;;;;OAIG;cAEa,UAAU,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlG;;;OAGG;IACH,OAAO,CAAC,YAAY;IAoBpB;;;;;;;OAOG;IACG,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,CAAC;IACjG,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;CAmCvD"}
@@ -1,4 +1,5 @@
1
1
  import { LLMError } from "../utils/errors.js";
2
+ import { sanitizeLLMJson } from "./json-sanitizer.js";
2
3
  // ─── Shared constants ───
3
4
  export const DEFAULT_MAX_TOKENS = 4096;
4
5
  /** Default LLM request timeout in milliseconds */
@@ -9,19 +10,81 @@ export const MAX_RETRY_ATTEMPTS = 3;
9
10
  export const RETRY_DELAYS_MS = [1000, 2000, 4000];
10
11
  // ─── JSON extraction utility ───
11
12
  /**
12
- * Extract JSON from a string that may contain markdown code blocks.
13
- * Tries ```json ... ``` first, then ``` ... ```, then bare JSON.
13
+ * Extract JSON from a string that may contain markdown code blocks or prose.
14
+ *
15
+ * Strategies (first match wins):
16
+ * 1. Fast path — already valid JSON, return as-is
17
+ * 2. Code fence extraction — ```json ... ``` or ``` ... ```
18
+ * 3. Brace matching — find first { or [ and last matching } or ]
14
19
  */
15
20
  export function extractJSON(text) {
16
- const jsonBlock = text.match(/```json\s*([\s\S]*?)```/);
21
+ const trimmed = text.trim();
22
+ // 1. Fast path: already valid JSON
23
+ try {
24
+ JSON.parse(trimmed);
25
+ return trimmed;
26
+ }
27
+ catch {
28
+ // not bare JSON, continue
29
+ }
30
+ // 2. Code fence extraction
31
+ const jsonBlock = trimmed.match(/```json\s*([\s\S]*?)```/);
17
32
  if (jsonBlock) {
18
33
  return jsonBlock[1].trim();
19
34
  }
20
- const genericBlock = text.match(/```\s*([\s\S]*?)```/);
35
+ const genericBlock = trimmed.match(/```\s*([\s\S]*?)```/);
21
36
  if (genericBlock) {
22
37
  return genericBlock[1].trim();
23
38
  }
24
- return text.trim();
39
+ // 3. Depth-aware brace matching: scan from first { or [ to its matching close
40
+ const firstBrace = trimmed.indexOf("{");
41
+ const firstBracket = trimmed.indexOf("[");
42
+ let start = -1;
43
+ let openChar;
44
+ let closeChar;
45
+ if (firstBrace === -1 && firstBracket === -1) {
46
+ return trimmed;
47
+ }
48
+ else if (firstBrace === -1 || (firstBracket !== -1 && firstBracket < firstBrace)) {
49
+ start = firstBracket;
50
+ openChar = "[";
51
+ closeChar = "]";
52
+ }
53
+ else {
54
+ start = firstBrace;
55
+ openChar = "{";
56
+ closeChar = "}";
57
+ }
58
+ let depth = 0;
59
+ let inString = false;
60
+ let escape = false;
61
+ for (let i = start; i < trimmed.length; i++) {
62
+ const ch = trimmed[i];
63
+ if (escape) {
64
+ escape = false;
65
+ continue;
66
+ }
67
+ if (ch === "\\" && inString) {
68
+ escape = true;
69
+ continue;
70
+ }
71
+ if (ch === '"') {
72
+ inString = !inString;
73
+ continue;
74
+ }
75
+ if (inString)
76
+ continue;
77
+ if (ch === openChar) {
78
+ depth++;
79
+ }
80
+ else if (ch === closeChar) {
81
+ depth--;
82
+ if (depth === 0) {
83
+ return trimmed.slice(start, i + 1);
84
+ }
85
+ }
86
+ }
87
+ return trimmed;
25
88
  }
26
89
  // ─── BaseLLMClient ───
27
90
  /**
@@ -45,25 +108,68 @@ export class BaseLLMClient {
45
108
  return effectiveModel;
46
109
  }
47
110
  /**
48
- * Extract JSON from LLM response text (handles markdown code blocks)
49
- * and validate against the given Zod schema.
50
- * Throws on parse failure or schema validation failure with detailed messages.
51
- */
52
- parseJSON(content, schema) {
53
- const jsonText = extractJSON(content);
111
+ * Send messages to the LLM and return the response text.
112
+ * Used internally by parseJSON retry logic.
113
+ * Subclasses that support retry must override this method.
114
+ */
115
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
116
+ async callLLMRaw(_messages, _systemPrompt) {
117
+ throw new LLMError("callLLMRaw not implemented — override in subclass to enable parseJSON retry");
118
+ }
119
+ /**
120
+ * Attempt to parse and validate a single content string against the schema.
121
+ * Returns the parsed value on success, or throws LLMError on failure.
122
+ */
123
+ attemptParse(content, schema) {
124
+ const jsonText = sanitizeLLMJson(extractJSON(content));
54
125
  let raw;
55
126
  try {
56
127
  raw = JSON.parse(jsonText);
57
128
  }
58
129
  catch (err) {
59
- throw new LLMError(`LLM response JSON parse failed — ${String(err)}\nContent: ${content}`);
130
+ const msg = `LLM response JSON parse failed — ${String(err)}`;
131
+ console.warn(`[parseJSON] ${msg} | raw(200): ${content.slice(0, 200)}`);
132
+ throw new LLMError(`${msg}\nContent: ${content}`);
60
133
  }
61
134
  const result = schema.safeParse(raw);
62
135
  if (!result.success) {
63
- throw new LLMError(`LLM response validation failed: ${result.error.issues.map((i) => i.message).join(", ")}. ` +
64
- `Raw: ${JSON.stringify(raw).slice(0, 200)}`);
136
+ const issues = result.error.issues.map((i) => i.message).join(", ");
137
+ const msg = `LLM response validation failed: ${issues}`;
138
+ console.warn(`[parseJSON] ${msg} | raw(200): ${JSON.stringify(raw).slice(0, 200)}`);
139
+ throw new LLMError(`${msg}. Raw: ${JSON.stringify(raw).slice(0, 200)}`);
65
140
  }
66
141
  return result.data;
67
142
  }
143
+ parseJSON(content, schema, options) {
144
+ if (!options?.retry) {
145
+ return this.attemptParse(content, schema);
146
+ }
147
+ // Async path: retry enabled
148
+ return (async () => {
149
+ let firstError;
150
+ try {
151
+ return this.attemptParse(content, schema);
152
+ }
153
+ catch (err) {
154
+ firstError = err;
155
+ }
156
+ console.warn(`[parseJSON] first attempt failed, retrying... Error: ${firstError.message}`);
157
+ const retryMessages = [
158
+ ...options.retry.messages,
159
+ {
160
+ role: "user",
161
+ content: `Your previous response was not valid JSON. Error: ${firstError.message}. Please respond with ONLY valid JSON matching the required schema, no other text.`,
162
+ },
163
+ ];
164
+ const retryContent = await this.callLLMRaw(retryMessages, options.retry.systemPrompt);
165
+ try {
166
+ return this.attemptParse(retryContent, schema);
167
+ }
168
+ catch (err) {
169
+ console.warn(`[parseJSON] retry also failed`);
170
+ throw err;
171
+ }
172
+ })();
173
+ }
68
174
  }
69
175
  //# sourceMappingURL=base-llm-client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-llm-client.js","sourceRoot":"","sources":["../../src/llm/base-llm-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAO9C,2BAA2B;AAE3B,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,kDAAkD;AAClD,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAE7C,2DAA2D;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC,6DAA6D;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAElD,kCAAkC;AAElC;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACxD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IACD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACvD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED,wBAAwB;AAExB;;;;GAIG;AACH,MAAM,OAAgB,aAAa;IACjC,iFAAiF;IACvE,UAAU,CAAU;IAE9B;;;;;OAKG;IACO,qBAAqB,CAAC,YAAoB,EAAE,IAAgB;QACpE,MAAM,cAAc,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC;YAC1D,CAAC,CAAC,IAAI,CAAC,UAAU;YACjB,CAAC,CAAC,YAAY,CAAC;QACjB,OAAO,cAAc,CAAC;IACxB,CAAC;IAED;;;;MAIE;IACF,SAAS,CAAI,OAAe,EAAE,MAAoB;QAChD,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,QAAQ,CAChB,oCAAoC,MAAM,CAAC,GAAG,CAAC,cAAc,OAAO,EAAE,CACvE,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,QAAQ,CAChB,mCAAmC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBACzF,QAAQ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC9C,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;CACF"}
1
+ {"version":3,"file":"base-llm-client.js","sourceRoot":"","sources":["../../src/llm/base-llm-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAOtD,2BAA2B;AAE3B,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,kDAAkD;AAClD,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAE7C,2DAA2D;AAC3D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC,6DAA6D;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAElD,kCAAkC;AAElC;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAE5B,mCAAmC;IACnC,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpB,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IAED,2BAA2B;IAC3B,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC3D,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IACD,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC1D,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,CAAC;IAED,8EAA8E;IAC9E,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;IACf,IAAI,QAAmB,CAAC;IACxB,IAAI,SAAoB,CAAC;IAEzB,IAAI,UAAU,KAAK,CAAC,CAAC,IAAI,YAAY,KAAK,CAAC,CAAC,EAAE,CAAC;QAC7C,OAAO,OAAO,CAAC;IACjB,CAAC;SAAM,IAAI,UAAU,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,CAAC,IAAI,YAAY,GAAG,UAAU,CAAC,EAAE,CAAC;QACnF,KAAK,GAAG,YAAY,CAAC;QACrB,QAAQ,GAAG,GAAG,CAAC;QACf,SAAS,GAAG,GAAG,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,UAAU,CAAC;QACnB,QAAQ,GAAG,GAAG,CAAC;QACf,SAAS,GAAG,GAAG,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,MAAM,EAAE,CAAC;YAAC,MAAM,GAAG,KAAK,CAAC;YAAC,SAAS;QAAC,CAAC;QACzC,IAAI,EAAE,KAAK,IAAI,IAAI,QAAQ,EAAE,CAAC;YAAC,MAAM,GAAG,IAAI,CAAC;YAAC,SAAS;QAAC,CAAC;QACzD,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAAC,QAAQ,GAAG,CAAC,QAAQ,CAAC;YAAC,SAAS;QAAC,CAAC;QACnD,IAAI,QAAQ;YAAE,SAAS;QACvB,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;YAAC,KAAK,EAAE,CAAC;QAAC,CAAC;aAC5B,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YAC1B,KAAK,EAAE,CAAC;YACR,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAmBD,wBAAwB;AAExB;;;;GAIG;AACH,MAAM,OAAgB,aAAa;IACjC,iFAAiF;IACvE,UAAU,CAAU;IAE9B;;;;;OAKG;IACO,qBAAqB,CAAC,YAAoB,EAAE,IAAgB;QACpE,MAAM,cAAc,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC;YAC1D,CAAC,CAAC,IAAI,CAAC,UAAU;YACjB,CAAC,CAAC,YAAY,CAAC;QACjB,OAAO,cAAc,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,6DAA6D;IACnD,KAAK,CAAC,UAAU,CAAC,SAA6B,EAAE,aAAsB;QAC9E,MAAM,IAAI,QAAQ,CAAC,6EAA6E,CAAC,CAAC;IACpG,CAAC;IAED;;;OAGG;IACK,YAAY,CAAI,OAAe,EAAE,MAAoB;QAC3D,MAAM,QAAQ,GAAG,eAAe,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,IAAI,GAAY,CAAC;QACjB,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAG,oCAAoC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9D,OAAO,CAAC,IAAI,CAAC,eAAe,GAAG,gBAAgB,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACxE,MAAM,IAAI,QAAQ,CAAC,GAAG,GAAG,cAAc,OAAO,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpE,MAAM,GAAG,GAAG,mCAAmC,MAAM,EAAE,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,eAAe,GAAG,gBAAgB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACpF,MAAM,IAAI,QAAQ,CAAC,GAAG,GAAG,UAAU,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAYD,SAAS,CAAI,OAAe,EAAE,MAAoB,EAAE,OAA0B;QAC5E,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QAED,4BAA4B;QAC5B,OAAO,CAAC,KAAK,IAAI,EAAE;YACjB,IAAI,UAAoB,CAAC;YACzB,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,UAAU,GAAG,GAAe,CAAC;YAC/B,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,wDAAwD,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YAE3F,MAAM,aAAa,GAAuB;gBACxC,GAAG,OAAO,CAAC,KAAM,CAAC,QAAQ;gBAC1B;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,qDAAqD,UAAU,CAAC,OAAO,oFAAoF;iBACrK;aACF,CAAC;YAEF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,OAAO,CAAC,KAAM,CAAC,YAAY,CAAC,CAAC;YAEvF,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;gBAC9C,MAAM,GAAe,CAAC;YACxB,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;CACF"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * json-sanitizer.ts — Shared LLM JSON response sanitization utilities.
3
+ *
4
+ * Centralizes all sanitization logic so it can be applied consistently
5
+ * before JSON.parse() and Zod validation.
6
+ */
7
+ /**
8
+ * Sanitizes LLM-returned threshold_type strings to valid enum values.
9
+ * Handles the union of all known non-standard values from both
10
+ * GoalRefiner (leaf test) and GoalTreeManager (subgoal decomposition).
11
+ *
12
+ * Uses regex replacement so it works on raw JSON strings before parsing.
13
+ */
14
+ export declare function sanitizeThresholdTypes(raw: string): string;
15
+ /**
16
+ * Sanitizes LLM-returned threshold_value when threshold_type is "present".
17
+ * When the LLM returns an object (e.g. `{"type":"present"}`) as the value for
18
+ * a present threshold, replace it with null so downstream Zod schemas accept it.
19
+ *
20
+ * Operates on the raw JSON string before parsing to avoid any type-safety issues
21
+ * with the un-parsed LLM output.
22
+ */
23
+ export declare function sanitizeThresholdValues(raw: string): string;
24
+ /**
25
+ * Applies all LLM JSON sanitizers in sequence.
26
+ *
27
+ * Order:
28
+ * 1. Remove trailing commas (syntactic fix — must come before JSON.parse attempts)
29
+ * 2. Replace NaN/Infinity with null (syntactic fix)
30
+ * 3. Sanitize threshold_type enum values (domain-specific string replacement)
31
+ * 4. Sanitize threshold_value for "present" thresholds (requires parse+reserialize)
32
+ */
33
+ export declare function sanitizeLLMJson(raw: string): string;
34
+ //# sourceMappingURL=json-sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-sanitizer.d.ts","sourceRoot":"","sources":["../../src/llm/json-sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAS1D;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY3D;AAgDD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOnD"}