skyloom 1.4.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 (225) hide show
  1. package/.github/workflows/ci.yml +36 -0
  2. package/CONVERSION_PLAN.md +191 -0
  3. package/README.md +67 -0
  4. package/dist/agents/dew.d.ts +15 -0
  5. package/dist/agents/dew.d.ts.map +1 -0
  6. package/dist/agents/dew.js +74 -0
  7. package/dist/agents/dew.js.map +1 -0
  8. package/dist/agents/fair.d.ts +15 -0
  9. package/dist/agents/fair.d.ts.map +1 -0
  10. package/dist/agents/fair.js +106 -0
  11. package/dist/agents/fair.js.map +1 -0
  12. package/dist/agents/fog.d.ts +15 -0
  13. package/dist/agents/fog.d.ts.map +1 -0
  14. package/dist/agents/fog.js +52 -0
  15. package/dist/agents/fog.js.map +1 -0
  16. package/dist/agents/frost.d.ts +15 -0
  17. package/dist/agents/frost.d.ts.map +1 -0
  18. package/dist/agents/frost.js +54 -0
  19. package/dist/agents/frost.js.map +1 -0
  20. package/dist/agents/rain.d.ts +15 -0
  21. package/dist/agents/rain.d.ts.map +1 -0
  22. package/dist/agents/rain.js +54 -0
  23. package/dist/agents/rain.js.map +1 -0
  24. package/dist/agents/snow.d.ts +27 -0
  25. package/dist/agents/snow.d.ts.map +1 -0
  26. package/dist/agents/snow.js +226 -0
  27. package/dist/agents/snow.js.map +1 -0
  28. package/dist/cli/main.d.ts +7 -0
  29. package/dist/cli/main.d.ts.map +1 -0
  30. package/dist/cli/main.js +402 -0
  31. package/dist/cli/main.js.map +1 -0
  32. package/dist/cli/mode.d.ts +17 -0
  33. package/dist/cli/mode.d.ts.map +1 -0
  34. package/dist/cli/mode.js +56 -0
  35. package/dist/cli/mode.js.map +1 -0
  36. package/dist/core/agent.d.ts +174 -0
  37. package/dist/core/agent.d.ts.map +1 -0
  38. package/dist/core/agent.js +1332 -0
  39. package/dist/core/agent.js.map +1 -0
  40. package/dist/core/agent_helpers.d.ts +51 -0
  41. package/dist/core/agent_helpers.d.ts.map +1 -0
  42. package/dist/core/agent_helpers.js +477 -0
  43. package/dist/core/agent_helpers.js.map +1 -0
  44. package/dist/core/bus.d.ts +99 -0
  45. package/dist/core/bus.d.ts.map +1 -0
  46. package/dist/core/bus.js +191 -0
  47. package/dist/core/bus.js.map +1 -0
  48. package/dist/core/cache.d.ts +63 -0
  49. package/dist/core/cache.d.ts.map +1 -0
  50. package/dist/core/cache.js +121 -0
  51. package/dist/core/cache.js.map +1 -0
  52. package/dist/core/checkpoint.d.ts +19 -0
  53. package/dist/core/checkpoint.d.ts.map +1 -0
  54. package/dist/core/checkpoint.js +120 -0
  55. package/dist/core/checkpoint.js.map +1 -0
  56. package/dist/core/circuit_breaker.d.ts +46 -0
  57. package/dist/core/circuit_breaker.d.ts.map +1 -0
  58. package/dist/core/circuit_breaker.js +99 -0
  59. package/dist/core/circuit_breaker.js.map +1 -0
  60. package/dist/core/config.d.ts +97 -0
  61. package/dist/core/config.d.ts.map +1 -0
  62. package/dist/core/config.js +281 -0
  63. package/dist/core/config.js.map +1 -0
  64. package/dist/core/constants.d.ts +78 -0
  65. package/dist/core/constants.d.ts.map +1 -0
  66. package/dist/core/constants.js +84 -0
  67. package/dist/core/constants.js.map +1 -0
  68. package/dist/core/factory.d.ts +63 -0
  69. package/dist/core/factory.d.ts.map +1 -0
  70. package/dist/core/factory.js +537 -0
  71. package/dist/core/factory.js.map +1 -0
  72. package/dist/core/icons.d.ts +28 -0
  73. package/dist/core/icons.d.ts.map +1 -0
  74. package/dist/core/icons.js +86 -0
  75. package/dist/core/icons.js.map +1 -0
  76. package/dist/core/index.d.ts +29 -0
  77. package/dist/core/index.d.ts.map +1 -0
  78. package/dist/core/index.js +54 -0
  79. package/dist/core/index.js.map +1 -0
  80. package/dist/core/llm.d.ts +121 -0
  81. package/dist/core/llm.d.ts.map +1 -0
  82. package/dist/core/llm.js +532 -0
  83. package/dist/core/llm.js.map +1 -0
  84. package/dist/core/logger.d.ts +57 -0
  85. package/dist/core/logger.d.ts.map +1 -0
  86. package/dist/core/logger.js +122 -0
  87. package/dist/core/logger.js.map +1 -0
  88. package/dist/core/mcp.d.ts +190 -0
  89. package/dist/core/mcp.d.ts.map +1 -0
  90. package/dist/core/mcp.js +822 -0
  91. package/dist/core/mcp.js.map +1 -0
  92. package/dist/core/mcp_server.d.ts +26 -0
  93. package/dist/core/mcp_server.d.ts.map +1 -0
  94. package/dist/core/mcp_server.js +211 -0
  95. package/dist/core/mcp_server.js.map +1 -0
  96. package/dist/core/memory.d.ts +190 -0
  97. package/dist/core/memory.d.ts.map +1 -0
  98. package/dist/core/memory.js +988 -0
  99. package/dist/core/memory.js.map +1 -0
  100. package/dist/core/middleware.d.ts +114 -0
  101. package/dist/core/middleware.d.ts.map +1 -0
  102. package/dist/core/middleware.js +248 -0
  103. package/dist/core/middleware.js.map +1 -0
  104. package/dist/core/pipelines.d.ts +87 -0
  105. package/dist/core/pipelines.d.ts.map +1 -0
  106. package/dist/core/pipelines.js +301 -0
  107. package/dist/core/pipelines.js.map +1 -0
  108. package/dist/core/profile.d.ts +23 -0
  109. package/dist/core/profile.d.ts.map +1 -0
  110. package/dist/core/profile.js +289 -0
  111. package/dist/core/profile.js.map +1 -0
  112. package/dist/core/router.d.ts +24 -0
  113. package/dist/core/router.d.ts.map +1 -0
  114. package/dist/core/router.js +111 -0
  115. package/dist/core/router.js.map +1 -0
  116. package/dist/core/schemas.d.ts +82 -0
  117. package/dist/core/schemas.d.ts.map +1 -0
  118. package/dist/core/schemas.js +200 -0
  119. package/dist/core/schemas.js.map +1 -0
  120. package/dist/core/semantic.d.ts +92 -0
  121. package/dist/core/semantic.d.ts.map +1 -0
  122. package/dist/core/semantic.js +175 -0
  123. package/dist/core/semantic.js.map +1 -0
  124. package/dist/core/skill.d.ts +68 -0
  125. package/dist/core/skill.d.ts.map +1 -0
  126. package/dist/core/skill.js +350 -0
  127. package/dist/core/skill.js.map +1 -0
  128. package/dist/core/tool.d.ts +99 -0
  129. package/dist/core/tool.d.ts.map +1 -0
  130. package/dist/core/tool.js +341 -0
  131. package/dist/core/tool.js.map +1 -0
  132. package/dist/core/tool_router.d.ts +29 -0
  133. package/dist/core/tool_router.d.ts.map +1 -0
  134. package/dist/core/tool_router.js +172 -0
  135. package/dist/core/tool_router.js.map +1 -0
  136. package/dist/core/workspace.d.ts +48 -0
  137. package/dist/core/workspace.d.ts.map +1 -0
  138. package/dist/core/workspace.js +179 -0
  139. package/dist/core/workspace.js.map +1 -0
  140. package/dist/plugins/loader.d.ts +17 -0
  141. package/dist/plugins/loader.d.ts.map +1 -0
  142. package/dist/plugins/loader.js +96 -0
  143. package/dist/plugins/loader.js.map +1 -0
  144. package/dist/skills/loader.d.ts +9 -0
  145. package/dist/skills/loader.d.ts.map +1 -0
  146. package/dist/skills/loader.js +78 -0
  147. package/dist/skills/loader.js.map +1 -0
  148. package/dist/tools/builtin.d.ts +10 -0
  149. package/dist/tools/builtin.d.ts.map +1 -0
  150. package/dist/tools/builtin.js +414 -0
  151. package/dist/tools/builtin.js.map +1 -0
  152. package/dist/tools/computer.d.ts +12 -0
  153. package/dist/tools/computer.d.ts.map +1 -0
  154. package/dist/tools/computer.js +326 -0
  155. package/dist/tools/computer.js.map +1 -0
  156. package/dist/tools/delegate.d.ts +10 -0
  157. package/dist/tools/delegate.d.ts.map +1 -0
  158. package/dist/tools/delegate.js +45 -0
  159. package/dist/tools/delegate.js.map +1 -0
  160. package/dist/web/server.d.ts +5 -0
  161. package/dist/web/server.d.ts.map +1 -0
  162. package/dist/web/server.js +647 -0
  163. package/dist/web/server.js.map +1 -0
  164. package/dist/web/tts.d.ts +33 -0
  165. package/dist/web/tts.d.ts.map +1 -0
  166. package/dist/web/tts.js +69 -0
  167. package/dist/web/tts.js.map +1 -0
  168. package/package.json +60 -0
  169. package/scripts/install.js +48 -0
  170. package/scripts/link.js +10 -0
  171. package/setup.bat +79 -0
  172. package/skill-test-ty2fOA/test.md +10 -0
  173. package/src/agents/dew.ts +70 -0
  174. package/src/agents/fair.ts +102 -0
  175. package/src/agents/fog.ts +48 -0
  176. package/src/agents/frost.ts +50 -0
  177. package/src/agents/rain.ts +50 -0
  178. package/src/agents/snow.ts +239 -0
  179. package/src/cli/main.ts +405 -0
  180. package/src/cli/mode.ts +58 -0
  181. package/src/core/agent.ts +1506 -0
  182. package/src/core/agent_helpers.ts +461 -0
  183. package/src/core/bus.ts +221 -0
  184. package/src/core/cache.ts +153 -0
  185. package/src/core/checkpoint.ts +94 -0
  186. package/src/core/circuit_breaker.ts +119 -0
  187. package/src/core/config.ts +341 -0
  188. package/src/core/constants.ts +95 -0
  189. package/src/core/factory.ts +627 -0
  190. package/src/core/icons.ts +53 -0
  191. package/src/core/index.ts +31 -0
  192. package/src/core/llm.ts +724 -0
  193. package/src/core/logger.ts +144 -0
  194. package/src/core/mcp.ts +953 -0
  195. package/src/core/mcp_server.ts +176 -0
  196. package/src/core/memory.ts +1169 -0
  197. package/src/core/middleware.ts +350 -0
  198. package/src/core/pipelines.ts +424 -0
  199. package/src/core/profile.ts +255 -0
  200. package/src/core/router.ts +124 -0
  201. package/src/core/schemas.ts +282 -0
  202. package/src/core/semantic.ts +211 -0
  203. package/src/core/skill.ts +342 -0
  204. package/src/core/tool.ts +427 -0
  205. package/src/core/tool_router.ts +193 -0
  206. package/src/core/workspace.ts +150 -0
  207. package/src/plugins/loader.ts +66 -0
  208. package/src/skills/loader.ts +46 -0
  209. package/src/sql.js.d.ts +29 -0
  210. package/src/tools/builtin.ts +382 -0
  211. package/src/tools/computer.ts +269 -0
  212. package/src/tools/delegate.ts +49 -0
  213. package/src/web/server.ts +634 -0
  214. package/src/web/tts.ts +93 -0
  215. package/tests/bus.test.ts +121 -0
  216. package/tests/icons.test.ts +45 -0
  217. package/tests/router.test.ts +86 -0
  218. package/tests/schemas.test.ts +51 -0
  219. package/tests/semantic.test.ts +83 -0
  220. package/tests/setup.ts +10 -0
  221. package/tests/skill.test.ts +172 -0
  222. package/tests/tool.test.ts +108 -0
  223. package/tests/tool_router.test.ts +71 -0
  224. package/tsconfig.json +37 -0
  225. package/vitest.config.ts +17 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/core/router.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,IAAI,GAAG,QAAQ,GAAG,QAAQ,GAAG,aAAa,CAAC;AAgCvD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAiD3C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAmB7E"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /**
3
+ * Complexity router: classify a user goal into direct / single / orchestrate.
4
+ *
5
+ * Rules-first (no LLM), so classification stays under 1ms. The router exists
6
+ * solely to keep simple goals from triggering Snow's full task-decomposition
7
+ * LLM call when a single agent could answer in one shot.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.classify = classify;
11
+ exports.pickAgentForGoal = pickAgentForGoal;
12
+ const MULTI_STEP_TOKENS = [
13
+ '先', '再', '然后', '接着', '之后', '其次', '最后',
14
+ '第一步', '第二步', '第三步', '步骤', '顺序', '依次', '首先',
15
+ 'step 1', 'step 2', 'first,', 'then,', 'after that', 'finally',
16
+ ];
17
+ const GREETING_TOKENS = [
18
+ '你好', '您好', 'hi', 'hello', 'hey', '在吗', '嗨',
19
+ '早上好', '晚安', '谢谢', 'thanks', 'thank you', '再见', 'bye',
20
+ ];
21
+ const SINGLE_ACTION_HINTS = [
22
+ '解释', '什么是', '为什么', '如何', '怎么', '查询', '搜索',
23
+ '搜一下', '翻译', '总结', 'summarize', 'explain', 'what is', 'why', 'how do',
24
+ ];
25
+ const ACTION_VERBS = [
26
+ '写', '帮我写', '生成', '创建', '实现', '做', '搜', '查',
27
+ '找', '审查', '审计', '翻译', '重构', '修改', '改', '部署',
28
+ '运行', '执行',
29
+ 'write', 'create', 'generate', 'implement', 'search', 'find',
30
+ 'review', 'translate', 'deploy', 'run',
31
+ ];
32
+ const CODE_BLOCK = /```[\s\S]+?```/;
33
+ const URL_PATTERN = /https?:\/\/\S+/;
34
+ const PATH_PATTERN = /(?:[A-Za-z]:[\\/]|[\\/])[\w\-./\\]+/;
35
+ const NUMBERED_LIST = /(?:^|\n)\s*(?:\d+[.)、]|[-*])\s+/gm;
36
+ const INLINE_ENUMERATED = /\b\d+[.)、]\s*\S/g;
37
+ /**
38
+ * Decide the execution mode for a user goal.
39
+ *
40
+ * direct: short greeting / single factual question, no tools needed.
41
+ * single: clear single-purpose task, one agent + tools.
42
+ * orchestrate: multi-step plan worth decomposing into sub-tasks.
43
+ */
44
+ function classify(goal) {
45
+ if (!goal || !goal.trim())
46
+ return 'direct';
47
+ const text = goal.trim();
48
+ const lower = text.toLowerCase();
49
+ const length = text.length;
50
+ const hasCode = CODE_BLOCK.test(text);
51
+ const hasUrl = URL_PATTERN.test(text);
52
+ const hasPath = PATH_PATTERN.test(text);
53
+ const listMatches = (text.match(NUMBERED_LIST) || []).length;
54
+ const inlineEnumHits = (text.match(INLINE_ENUMERATED) || []).length;
55
+ const multiStepHits = MULTI_STEP_TOKENS.filter(t => lower.includes(t)).length;
56
+ const greetingHits = GREETING_TOKENS.filter(t => lower.includes(t)).length;
57
+ const singleHits = SINGLE_ACTION_HINTS.filter(t => lower.includes(t)).length;
58
+ const actionHits = ACTION_VERBS.filter(t => lower.includes(t)).length;
59
+ if (greetingHits >= 1 && length < 30 && multiStepHits === 0 && actionHits === 0) {
60
+ return 'direct';
61
+ }
62
+ if (multiStepHits >= 2 || listMatches >= 2 || inlineEnumHits >= 3) {
63
+ return 'orchestrate';
64
+ }
65
+ if (length > 200 && multiStepHits >= 1) {
66
+ return 'orchestrate';
67
+ }
68
+ if (hasCode && length > 150) {
69
+ return 'orchestrate';
70
+ }
71
+ // Tool-use signals push toward single, not direct
72
+ if (hasPath || hasUrl || actionHits >= 1) {
73
+ return 'single';
74
+ }
75
+ if (length < 50 && !hasCode) {
76
+ if (singleHits >= 1 || text.endsWith('?') || text.endsWith('?')) {
77
+ return 'direct';
78
+ }
79
+ if (multiStepHits === 0) {
80
+ return 'direct';
81
+ }
82
+ }
83
+ return 'single';
84
+ }
85
+ /**
86
+ * Pick a single agent for a non-orchestrate goal, by keyword routing.
87
+ *
88
+ * Returns an agent name guaranteed to be in available, falling back to
89
+ * rain (generation generalist) then to any available agent.
90
+ */
91
+ function pickAgentForGoal(goal, available) {
92
+ const lower = goal.toLowerCase();
93
+ // More specific buckets first
94
+ const buckets = [
95
+ ['frost', ['审查', 'review', '漏洞', '安全', '审计', 'lint', '重构建议', 'code smell']],
96
+ ['dew', ['部署', '运行', '执行命令', 'shell', 'deploy', 'ci', 'cd', '环境变量', '运维']],
97
+ ['fog', ['研究', '调研', '搜一下', '搜索', '查一下', '查资料', 'research', 'search', '调查', '找一下', '找资料']],
98
+ ['rain', ['写', '生成', '实现', 'create', 'generate', '写一段', '写个', '代码', '函数', '实现一个']],
99
+ ['fair', ['陪我', '聊天', '心情', '难过', '开心', '孤独', '倾诉', '你好', 'hi', 'hello', '嗨']],
100
+ ];
101
+ for (const [agent, hints] of buckets) {
102
+ if (!available.has(agent))
103
+ continue;
104
+ if (hints.some(h => lower.includes(h)))
105
+ return agent;
106
+ }
107
+ if (available.has('rain'))
108
+ return 'rain';
109
+ return Array.from(available)[0];
110
+ }
111
+ //# sourceMappingURL=router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/core/router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Lightweight structured output schemas for LLM response validation.
3
+ *
4
+ * Why: LLM JSON output is inherently fragile — models emit markdown fences,
5
+ * trailing commas, unquoted keys, or hallucinated fields. Rather than layering
6
+ * heuristic repair (which silently passes corrupted data), we define typed
7
+ * schemas and validate on ingress. Parsing failures surface immediately so the
8
+ * caller can retry with a corrected prompt instead of propagating garbage.
9
+ *
10
+ * Zero external dependencies: uses only JSON and TypeScript types.
11
+ */
12
+ /**
13
+ * Error raised when an LLM response fails schema validation.
14
+ * Carries both a human-readable message and the raw text so callers
15
+ * can log / retry with full context.
16
+ */
17
+ export declare class SchemaValidationError extends Error {
18
+ raw: string;
19
+ constructor(message: string, raw?: string);
20
+ }
21
+ /**
22
+ * One step in a task plan (mirrors PipelineStep / Task)
23
+ */
24
+ export interface TaskStepSchema {
25
+ id: string | number;
26
+ description: string;
27
+ agent?: string;
28
+ depends_on?: string[];
29
+ priority?: "low" | "medium" | "high";
30
+ }
31
+ /**
32
+ * Full task plan output from Snow's orchestrator
33
+ */
34
+ export interface TaskPlanSchema {
35
+ goal: string;
36
+ steps: TaskStepSchema[];
37
+ }
38
+ /**
39
+ * A single extracted fact for long-term memory
40
+ */
41
+ export interface FactSchema {
42
+ key: string;
43
+ value: string;
44
+ category?: string;
45
+ }
46
+ /**
47
+ * Structured fact-extraction output from the LLM
48
+ */
49
+ export interface ExtractionResultSchema {
50
+ facts: FactSchema[];
51
+ }
52
+ /**
53
+ * Tool call schema for LLM responses
54
+ */
55
+ export interface ToolCallSchema {
56
+ name: string;
57
+ arguments: Record<string, unknown>;
58
+ }
59
+ /**
60
+ * Message schema for agent communication
61
+ */
62
+ export interface MessageSchema {
63
+ role: "user" | "assistant" | "tool";
64
+ content: string;
65
+ tool_calls?: ToolCallSchema[];
66
+ tool_call_id?: string;
67
+ }
68
+ /**
69
+ * Parse a raw LLM response string into a typed JSON object.
70
+ * Handles markdown fences, leading/trailing text, and minor JSON quirks.
71
+ * Raises SchemaValidationError on failure.
72
+ */
73
+ export declare function parseSchema<T extends Record<string, unknown>>(raw: string, schemaType?: new () => T): T;
74
+ /**
75
+ * Validate task plan schema
76
+ */
77
+ export declare function validateTaskPlan(data: unknown): TaskPlanSchema;
78
+ /**
79
+ * Validate extraction result schema
80
+ */
81
+ export declare function validateExtractionResult(data: unknown): ExtractionResultSchema;
82
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/core/schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,GAAG,EAAE,MAAM,CAAC;gBAEA,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAW;CAK9C;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAuFD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,GAAG,EAAE,MAAM,EACX,UAAU,CAAC,EAAE,UAAU,CAAC,GACvB,CAAC,CAuBH;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CA4C9D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,sBAAsB,CA+B9E"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ /**
3
+ * Lightweight structured output schemas for LLM response validation.
4
+ *
5
+ * Why: LLM JSON output is inherently fragile — models emit markdown fences,
6
+ * trailing commas, unquoted keys, or hallucinated fields. Rather than layering
7
+ * heuristic repair (which silently passes corrupted data), we define typed
8
+ * schemas and validate on ingress. Parsing failures surface immediately so the
9
+ * caller can retry with a corrected prompt instead of propagating garbage.
10
+ *
11
+ * Zero external dependencies: uses only JSON and TypeScript types.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.SchemaValidationError = void 0;
15
+ exports.parseSchema = parseSchema;
16
+ exports.validateTaskPlan = validateTaskPlan;
17
+ exports.validateExtractionResult = validateExtractionResult;
18
+ /**
19
+ * Error raised when an LLM response fails schema validation.
20
+ * Carries both a human-readable message and the raw text so callers
21
+ * can log / retry with full context.
22
+ */
23
+ class SchemaValidationError extends Error {
24
+ constructor(message, raw = "") {
25
+ super(message);
26
+ this.name = "SchemaValidationError";
27
+ this.raw = raw;
28
+ }
29
+ }
30
+ exports.SchemaValidationError = SchemaValidationError;
31
+ /**
32
+ * Coerce a value to a target type with best-effort conversion
33
+ */
34
+ function coerceType(value, targetType) {
35
+ if (value === null || value === undefined) {
36
+ return value;
37
+ }
38
+ switch (targetType) {
39
+ case "string":
40
+ return String(value);
41
+ case "number":
42
+ return Number(value);
43
+ case "boolean":
44
+ return Boolean(value);
45
+ case "array":
46
+ return Array.isArray(value) ? value : [];
47
+ case "object":
48
+ return typeof value === "object" ? value : {};
49
+ default:
50
+ return value;
51
+ }
52
+ }
53
+ /**
54
+ * Extract JSON object/array from a potentially malformed string
55
+ */
56
+ function extractJSON(text) {
57
+ let cleaned = text.trim();
58
+ // Strip markdown code fences
59
+ if (cleaned.includes("```")) {
60
+ for (const fence of ["```json", "```"]) {
61
+ if (cleaned.includes(fence)) {
62
+ const after = cleaned.split(fence, 1)[1];
63
+ if (after && after.includes("```")) {
64
+ cleaned = after.split("```")[0].trim();
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ // Find first JSON object or array
71
+ let objStart = -1;
72
+ let depth = 0;
73
+ for (let i = 0; i < cleaned.length; i++) {
74
+ const ch = cleaned[i];
75
+ if (ch === "{") {
76
+ if (objStart < 0)
77
+ objStart = i;
78
+ depth++;
79
+ }
80
+ else if (ch === "}") {
81
+ depth--;
82
+ if (depth === 0 && objStart >= 0) {
83
+ return cleaned.substring(objStart, i + 1);
84
+ }
85
+ }
86
+ }
87
+ // If still not closed, close with extra braces
88
+ if (objStart >= 0) {
89
+ return cleaned.substring(objStart) + "}".repeat(depth);
90
+ }
91
+ throw new SchemaValidationError("No valid JSON found in response", text);
92
+ }
93
+ /**
94
+ * Repair common JSON issues (trailing commas, unquoted keys, etc.)
95
+ */
96
+ function repairJSON(text) {
97
+ let repaired = text;
98
+ // Remove trailing commas
99
+ repaired = repaired.replace(/,\s*([}\]])/g, "$1");
100
+ // Quote unquoted keys
101
+ repaired = repaired.replace(/(?<!["\'\w])(\w[\w\d_]*)(\s*:)/g, '"$1"$2');
102
+ // Normalize quotes
103
+ repaired = repaired.replace(/'/g, '"').replace(/`/g, '"');
104
+ return repaired;
105
+ }
106
+ /**
107
+ * Parse a raw LLM response string into a typed JSON object.
108
+ * Handles markdown fences, leading/trailing text, and minor JSON quirks.
109
+ * Raises SchemaValidationError on failure.
110
+ */
111
+ function parseSchema(raw, schemaType) {
112
+ if (!raw || !raw.trim()) {
113
+ throw new SchemaValidationError("empty response", raw);
114
+ }
115
+ try {
116
+ const extracted = extractJSON(raw);
117
+ let data = JSON.parse(extracted);
118
+ return data;
119
+ }
120
+ catch (error) {
121
+ if (error instanceof SchemaValidationError)
122
+ throw error;
123
+ try {
124
+ const repaired = repairJSON(raw);
125
+ const data = JSON.parse(repaired);
126
+ return data;
127
+ }
128
+ catch (repairError) {
129
+ throw new SchemaValidationError(`JSON parse failed: ${error.message}`, raw);
130
+ }
131
+ }
132
+ }
133
+ /**
134
+ * Validate task plan schema
135
+ */
136
+ function validateTaskPlan(data) {
137
+ if (!data || typeof data !== "object") {
138
+ throw new SchemaValidationError("Invalid task plan: must be an object");
139
+ }
140
+ const plan = data;
141
+ if (typeof plan.goal !== "string") {
142
+ throw new SchemaValidationError("Invalid task plan: goal must be a string");
143
+ }
144
+ if (!Array.isArray(plan.steps)) {
145
+ throw new SchemaValidationError("Invalid task plan: steps must be an array");
146
+ }
147
+ const steps = plan.steps.map((step) => {
148
+ if (!step || typeof step !== "object") {
149
+ throw new SchemaValidationError("Invalid task plan: step must be an object");
150
+ }
151
+ const s = step;
152
+ if (typeof s.id !== "string" && typeof s.id !== "number") {
153
+ throw new SchemaValidationError("Invalid task plan: step.id must be string or number");
154
+ }
155
+ if (typeof s.description !== "string") {
156
+ throw new SchemaValidationError("Invalid task plan: step.description must be a string");
157
+ }
158
+ return {
159
+ id: s.id,
160
+ description: s.description,
161
+ agent: typeof s.agent === "string" ? s.agent : "rain",
162
+ depends_on: Array.isArray(s.depends_on) ? s.depends_on : [],
163
+ priority: (["low", "medium", "high"].includes(s.priority)
164
+ ? s.priority
165
+ : "medium"),
166
+ };
167
+ });
168
+ return {
169
+ goal: plan.goal,
170
+ steps,
171
+ };
172
+ }
173
+ /**
174
+ * Validate extraction result schema
175
+ */
176
+ function validateExtractionResult(data) {
177
+ if (!data || typeof data !== "object") {
178
+ throw new SchemaValidationError("Invalid extraction result: must be an object");
179
+ }
180
+ const result = data;
181
+ if (!Array.isArray(result.facts)) {
182
+ throw new SchemaValidationError("Invalid extraction result: facts must be an array");
183
+ }
184
+ const facts = result.facts.map((fact) => {
185
+ if (!fact || typeof fact !== "object") {
186
+ throw new SchemaValidationError("Invalid extraction result: fact must be an object");
187
+ }
188
+ const f = fact;
189
+ if (typeof f.key !== "string" || typeof f.value !== "string") {
190
+ throw new SchemaValidationError("Invalid extraction result: fact must have key and value strings");
191
+ }
192
+ return {
193
+ key: f.key,
194
+ value: f.value,
195
+ category: typeof f.category === "string" ? f.category : "auto_extracted",
196
+ };
197
+ });
198
+ return { facts };
199
+ }
200
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/core/schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Lightweight semantic retrieval — zero external dependencies.
3
+ *
4
+ * Why: The existing `recall_for_injection` uses SQL LIKE on tokens, which
5
+ * misses semantically related facts that share few literal characters (e.g.
6
+ * query "deploy" vs. stored fact "release_command"). This module provides
7
+ * a character n-gram Jaccard similarity scorer that catches those cross-
8
+ * lingual and synonym relationships without adding PyTorch / sentence-transformers.
9
+ *
10
+ * Design:
11
+ * - Character n-grams (size 2-4) naturally handle CJK, mixed-language, and
12
+ * code identifiers better than word-level tokenization.
13
+ * - Jaccard similarity on n-gram sets is fast (< 10 µs per pair) and
14
+ * well-correlated with human relevance judgments for short text.
15
+ * - Zero dependencies beyond stdlib.
16
+ */
17
+ /**
18
+ * Represents a candidate item for ranking
19
+ */
20
+ export interface Candidate {
21
+ key?: string;
22
+ value?: string | Record<string, unknown>;
23
+ [key: string]: unknown;
24
+ }
25
+ /**
26
+ * Character n-gram semantic similarity scorer.
27
+ *
28
+ * Usage:
29
+ * ```
30
+ * const scorer = new SemanticScorer();
31
+ * const score = scorer.similarity("deploy to prod", "release_command");
32
+ * // score ≈ 0.15 (low but non-zero — catches partial overlap)
33
+ *
34
+ * const ranked = scorer.rank(
35
+ * "search query",
36
+ * [{value: "candidate A"}, {value: "candidate B"}]
37
+ * );
38
+ * // ranked → [[0.85, {value: "candidate A"}], [0.30, {value: "candidate B"}]]
39
+ * ```
40
+ */
41
+ export declare class SemanticScorer {
42
+ private nRange;
43
+ private cache;
44
+ private maxCacheSize;
45
+ /**
46
+ * Initialize scorer with n-gram range.
47
+ * @param nRange - Tuple of [minSize, maxSize] for n-grams (default [2, 4])
48
+ */
49
+ constructor(nRange?: [number, number]);
50
+ /**
51
+ * Generate character n-gram fingerprint (cached).
52
+ * @param text - Input text to fingerprint
53
+ * @returns Set of n-grams for the text
54
+ */
55
+ private fingerprint;
56
+ /**
57
+ * Calculate Jaccard similarity between two texts using character n-grams.
58
+ * @param a - First text
59
+ * @param b - Second text
60
+ * @returns Similarity score between 0 and 1
61
+ */
62
+ similarity(a: string, b: string): number;
63
+ /**
64
+ * Rank candidates by semantic similarity to the query.
65
+ *
66
+ * Each candidate is a dict. The scorer reads `candidate[keyField]`
67
+ * for text to compare. Also scores the "key" field if present.
68
+ * Returns `[score, candidate]` tuples sorted descending, filtered by `minScore`.
69
+ *
70
+ * @param query - Query string to match against
71
+ * @param candidates - Array of candidate objects
72
+ * @param keyField - Field name to extract text from (default "value")
73
+ * @param topK - Maximum number of results to return (default 3)
74
+ * @param minScore - Minimum similarity threshold (default 0.02)
75
+ * @returns Array of [score, candidate] tuples, sorted by score descending
76
+ */
77
+ rank(query: string, candidates: Candidate[], keyField?: string, topK?: number, minScore?: number): Array<[number, Candidate]>;
78
+ /**
79
+ * Clear the fingerprint cache.
80
+ */
81
+ clearCache(): void;
82
+ /**
83
+ * Get current cache size.
84
+ */
85
+ getCacheSize(): number;
86
+ }
87
+ /**
88
+ * Get or create the module-level semantic scorer singleton.
89
+ * @returns SemanticScorer instance
90
+ */
91
+ export declare function getScorer(): SemanticScorer;
92
+ //# sourceMappingURL=semantic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/core/semantic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,KAAK,CAA2B;IACxC,OAAO,CAAC,YAAY,CAAO;IAE3B;;;OAGG;gBACS,MAAM,GAAE,CAAC,MAAM,EAAE,MAAM,CAAU;IAK7C;;;;OAIG;IACH,OAAO,CAAC,WAAW;IA2BnB;;;;;OAKG;IACH,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IA0BxC;;;;;;;;;;;;;OAaG;IACH,IAAI,CACF,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,SAAS,EAAE,EACvB,QAAQ,GAAE,MAAgB,EAC1B,IAAI,GAAE,MAAU,EAChB,QAAQ,GAAE,MAAa,GACtB,KAAK,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAyC7B;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,YAAY,IAAI,MAAM;CAGvB;AAOD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,cAAc,CAK1C"}