glirastes 0.2.1 → 0.3.1

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 (319) hide show
  1. package/CHANGELOG.md +96 -0
  2. package/CODE_OF_CONDUCT.md +85 -0
  3. package/CONTRIBUTING.md +87 -0
  4. package/README.md +268 -23
  5. package/SECURITY.md +46 -0
  6. package/codegen/package.json +5 -0
  7. package/dist/cjs/codegen/asset-sync.d.ts +20 -0
  8. package/dist/cjs/codegen/asset-sync.js +28 -0
  9. package/dist/cjs/codegen/coverage.d.ts +66 -0
  10. package/dist/cjs/codegen/coverage.js +408 -0
  11. package/dist/cjs/codegen/endpoint-scanner.d.ts +16 -0
  12. package/dist/cjs/codegen/endpoint-scanner.js +197 -0
  13. package/dist/cjs/codegen/format.d.ts +17 -0
  14. package/dist/cjs/codegen/format.js +34 -0
  15. package/dist/cjs/codegen/fs-utils.d.ts +45 -0
  16. package/dist/cjs/codegen/fs-utils.js +165 -0
  17. package/dist/cjs/codegen/index.d.ts +13 -0
  18. package/dist/cjs/codegen/index.js +33 -0
  19. package/dist/cjs/codegen/mcp-generator.d.ts +50 -0
  20. package/dist/cjs/codegen/mcp-generator.js +803 -0
  21. package/dist/cjs/codegen/module-generator.d.ts +11 -0
  22. package/dist/cjs/codegen/module-generator.js +353 -0
  23. package/dist/cjs/codegen/nestjs-scanner.d.ts +43 -0
  24. package/dist/cjs/codegen/nestjs-scanner.js +241 -0
  25. package/dist/cjs/codegen/output-recommender.d.ts +23 -0
  26. package/dist/cjs/codegen/output-recommender.js +33 -0
  27. package/dist/cjs/codegen/scaffolder.d.ts +36 -0
  28. package/dist/cjs/codegen/scaffolder.js +262 -0
  29. package/dist/cjs/codegen/skill-generator.d.ts +49 -0
  30. package/dist/cjs/codegen/skill-generator.js +967 -0
  31. package/dist/cjs/codegen/types.d.ts +52 -0
  32. package/dist/cjs/codegen/types.js +16 -0
  33. package/dist/cjs/codegen/ui-scanner.d.ts +24 -0
  34. package/dist/cjs/codegen/ui-scanner.js +202 -0
  35. package/dist/cjs/codegen/validator.d.ts +35 -0
  36. package/dist/cjs/codegen/validator.js +292 -0
  37. package/dist/cjs/index.d.ts +1 -0
  38. package/dist/cjs/index.js +23 -0
  39. package/dist/cjs/openapi/index.d.ts +78 -0
  40. package/dist/cjs/openapi/index.js +347 -0
  41. package/dist/cjs/package.json +1 -0
  42. package/dist/cjs/react/audio-worklet-processor.d.ts +16 -0
  43. package/dist/cjs/react/audio-worklet-processor.js +27 -0
  44. package/dist/cjs/react/bridges/rest-session-bridge.d.ts +113 -0
  45. package/dist/cjs/react/bridges/rest-session-bridge.js +209 -0
  46. package/dist/cjs/react/components/ai-chat-panel.d.ts +12 -0
  47. package/dist/cjs/react/components/ai-chat-panel.js +67 -0
  48. package/dist/cjs/react/components/ai-trigger-button.d.ts +2 -0
  49. package/dist/cjs/react/components/ai-trigger-button.js +239 -0
  50. package/dist/cjs/react/components/approval-card.d.ts +9 -0
  51. package/dist/cjs/react/components/approval-card.js +24 -0
  52. package/dist/cjs/react/components/bulk-approval-card.d.ts +9 -0
  53. package/dist/cjs/react/components/bulk-approval-card.js +36 -0
  54. package/dist/cjs/react/components/chat-input.d.ts +10 -0
  55. package/dist/cjs/react/components/chat-input.js +60 -0
  56. package/dist/cjs/react/components/chat-window.d.ts +2 -0
  57. package/dist/cjs/react/components/chat-window.js +134 -0
  58. package/dist/cjs/react/components/confirm-dialog.d.ts +32 -0
  59. package/dist/cjs/react/components/confirm-dialog.js +48 -0
  60. package/dist/cjs/react/components/floating-chat-ui.d.ts +90 -0
  61. package/dist/cjs/react/components/floating-chat-ui.js +163 -0
  62. package/dist/cjs/react/components/mention-chip.d.ts +16 -0
  63. package/dist/cjs/react/components/mention-chip.js +42 -0
  64. package/dist/cjs/react/components/mention-input.d.ts +8 -0
  65. package/dist/cjs/react/components/mention-input.js +117 -0
  66. package/dist/cjs/react/components/message-bubble.d.ts +11 -0
  67. package/dist/cjs/react/components/message-bubble.js +171 -0
  68. package/dist/cjs/react/components/message-list.d.ts +8 -0
  69. package/dist/cjs/react/components/message-list.js +52 -0
  70. package/dist/cjs/react/components/pipeline-timeline.d.ts +7 -0
  71. package/dist/cjs/react/components/pipeline-timeline.js +72 -0
  72. package/dist/cjs/react/components/recording-bar.d.ts +2 -0
  73. package/dist/cjs/react/components/recording-bar.js +81 -0
  74. package/dist/cjs/react/components/recording-controls.d.ts +18 -0
  75. package/dist/cjs/react/components/recording-controls.js +38 -0
  76. package/dist/cjs/react/components/rich-mention-input.d.ts +2 -0
  77. package/dist/cjs/react/components/rich-mention-input.js +571 -0
  78. package/dist/cjs/react/components/session-switcher.d.ts +14 -0
  79. package/dist/cjs/react/components/session-switcher.js +133 -0
  80. package/dist/cjs/react/components/suggestion-bar.d.ts +9 -0
  81. package/dist/cjs/react/components/suggestion-bar.js +47 -0
  82. package/dist/cjs/react/components/suggestion-chip.d.ts +9 -0
  83. package/dist/cjs/react/components/suggestion-chip.js +14 -0
  84. package/dist/cjs/react/components/voice-input-addon.d.ts +13 -0
  85. package/dist/cjs/react/components/voice-input-addon.js +31 -0
  86. package/dist/cjs/react/components/voice-input-button.d.ts +2 -0
  87. package/dist/cjs/react/components/voice-input-button.js +55 -0
  88. package/dist/cjs/react/components/wavesurfer-loader.d.ts +5 -0
  89. package/dist/cjs/react/components/wavesurfer-loader.js +36 -0
  90. package/dist/cjs/react/hooks/use-ai-chat.d.ts +22 -0
  91. package/dist/cjs/react/hooks/use-ai-chat.js +51 -0
  92. package/dist/cjs/react/hooks/use-approvals.d.ts +23 -0
  93. package/dist/cjs/react/hooks/use-approvals.js +63 -0
  94. package/dist/cjs/react/hooks/use-deepgram-transcription.d.ts +2 -0
  95. package/dist/cjs/react/hooks/use-deepgram-transcription.js +329 -0
  96. package/dist/cjs/react/hooks/use-drag-resize-panel.d.ts +48 -0
  97. package/dist/cjs/react/hooks/use-drag-resize-panel.js +308 -0
  98. package/dist/cjs/react/hooks/use-draggable-position.d.ts +25 -0
  99. package/dist/cjs/react/hooks/use-draggable-position.js +134 -0
  100. package/dist/cjs/react/hooks/use-keyboard-shortcut.d.ts +20 -0
  101. package/dist/cjs/react/hooks/use-keyboard-shortcut.js +93 -0
  102. package/dist/cjs/react/hooks/use-mentions.d.ts +23 -0
  103. package/dist/cjs/react/hooks/use-mentions.js +42 -0
  104. package/dist/cjs/react/hooks/use-suggestions.d.ts +22 -0
  105. package/dist/cjs/react/hooks/use-suggestions.js +39 -0
  106. package/dist/cjs/react/index.d.ts +43 -0
  107. package/dist/cjs/react/index.js +111 -0
  108. package/dist/cjs/react/provider/ai-chat-provider.d.ts +45 -0
  109. package/dist/cjs/react/provider/ai-chat-provider.js +1024 -0
  110. package/dist/cjs/react/provider/chat-context.d.ts +84 -0
  111. package/dist/cjs/react/provider/chat-context.js +13 -0
  112. package/dist/cjs/react/template.d.ts +84 -0
  113. package/dist/cjs/react/template.js +90 -0
  114. package/dist/cjs/react/themes.d.ts +24 -0
  115. package/dist/cjs/react/themes.js +273 -0
  116. package/dist/cjs/react/transports/langgraph/index.d.ts +2 -0
  117. package/dist/cjs/react/transports/langgraph/index.js +8 -0
  118. package/dist/cjs/react/transports/langgraph/langgraph-ai-chat.d.ts +62 -0
  119. package/dist/cjs/react/transports/langgraph/langgraph-ai-chat.js +94 -0
  120. package/dist/cjs/react/transports/langgraph.d.ts +71 -0
  121. package/dist/cjs/react/transports/langgraph.js +369 -0
  122. package/dist/cjs/react/transports/vercel/index.d.ts +2 -0
  123. package/dist/cjs/react/transports/vercel/index.js +8 -0
  124. package/dist/cjs/react/transports/vercel/vercel-ai-chat.d.ts +49 -0
  125. package/dist/cjs/react/transports/vercel/vercel-ai-chat.js +81 -0
  126. package/dist/cjs/react/transports/vercel.d.ts +30 -0
  127. package/dist/cjs/react/transports/vercel.js +69 -0
  128. package/dist/cjs/react/types.d.ts +760 -0
  129. package/dist/cjs/react/types.js +2 -0
  130. package/dist/cjs/react/ui.d.ts +73 -0
  131. package/dist/cjs/react/ui.js +183 -0
  132. package/dist/cjs/react/utils/create-approval-description.d.ts +53 -0
  133. package/dist/cjs/react/utils/create-approval-description.js +122 -0
  134. package/dist/cjs/react/utils/create-tool-result-handler.d.ts +90 -0
  135. package/dist/cjs/react/utils/create-tool-result-handler.js +168 -0
  136. package/dist/cjs/react/utils/mention-markup.d.ts +13 -0
  137. package/dist/cjs/react/utils/mention-markup.js +117 -0
  138. package/dist/cjs/react/utils/merge-pipeline-steps.d.ts +19 -0
  139. package/dist/cjs/react/utils/merge-pipeline-steps.js +81 -0
  140. package/dist/cjs/react/utils/sanitize-stored-messages.d.ts +23 -0
  141. package/dist/cjs/react/utils/sanitize-stored-messages.js +52 -0
  142. package/dist/cjs/server/adapters/nestjs/chat/ai-chat-auth.guard.d.ts +10 -0
  143. package/dist/cjs/server/adapters/nestjs/chat/ai-chat-auth.guard.js +42 -0
  144. package/dist/cjs/server/adapters/nestjs/chat/ai-chat-module-options.interface.d.ts +32 -0
  145. package/dist/cjs/server/adapters/nestjs/chat/ai-chat-module-options.interface.js +4 -0
  146. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.controller.d.ts +11 -0
  147. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.controller.js +80 -0
  148. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.module.d.ts +9 -0
  149. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.module.js +119 -0
  150. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.service.d.ts +13 -0
  151. package/dist/cjs/server/adapters/nestjs/chat/ai-chat.service.js +131 -0
  152. package/dist/cjs/server/adapters/nestjs/chat/dto/ai-chat-request.dto.d.ts +7 -0
  153. package/dist/cjs/server/adapters/nestjs/chat/dto/ai-chat-request.dto.js +52 -0
  154. package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message-part.dto.d.ts +19 -0
  155. package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message-part.dto.js +108 -0
  156. package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message.dto.d.ts +8 -0
  157. package/dist/cjs/server/adapters/nestjs/chat/dto/chat-message.dto.js +59 -0
  158. package/dist/cjs/server/adapters/nestjs/chat/dto/index.d.ts +3 -0
  159. package/dist/cjs/server/adapters/nestjs/chat/dto/index.js +9 -0
  160. package/dist/cjs/server/adapters/nestjs/chat/index.d.ts +3 -0
  161. package/dist/cjs/server/adapters/nestjs/chat/index.js +9 -0
  162. package/dist/cjs/server/adapters/nestjs/chat/speech-stream.gateway.d.ts +4 -0
  163. package/dist/cjs/server/adapters/nestjs/chat/speech-stream.gateway.js +73 -0
  164. package/dist/cjs/server/adapters/nestjs/chat/ws-loader.d.ts +5 -0
  165. package/dist/cjs/server/adapters/nestjs/chat/ws-loader.js +72 -0
  166. package/dist/cjs/server/adapters/nestjs/decorators/ai-module.decorator.d.ts +6 -0
  167. package/dist/cjs/server/adapters/nestjs/decorators/ai-module.decorator.js +13 -0
  168. package/dist/cjs/server/adapters/nestjs/decorators/ai-param.decorator.d.ts +5 -0
  169. package/dist/cjs/server/adapters/nestjs/decorators/ai-param.decorator.js +15 -0
  170. package/dist/cjs/server/adapters/nestjs/decorators/ai-tool.decorator.d.ts +6 -0
  171. package/dist/cjs/server/adapters/nestjs/decorators/ai-tool.decorator.js +22 -0
  172. package/dist/cjs/server/adapters/nestjs/decorators/constants.d.ts +4 -0
  173. package/dist/cjs/server/adapters/nestjs/decorators/constants.js +7 -0
  174. package/dist/cjs/server/adapters/nestjs/index.d.ts +14 -0
  175. package/dist/cjs/server/adapters/nestjs/index.js +42 -0
  176. package/dist/cjs/server/adapters/nestjs/metadata.d.ts +39 -0
  177. package/dist/cjs/server/adapters/nestjs/metadata.js +36 -0
  178. package/dist/cjs/server/adapters/nestjs/module/ai-tools-explorer.service.d.ts +36 -0
  179. package/dist/cjs/server/adapters/nestjs/module/ai-tools-explorer.service.js +159 -0
  180. package/dist/cjs/server/adapters/nestjs/module/ai-tools.module.d.ts +37 -0
  181. package/dist/cjs/server/adapters/nestjs/module/ai-tools.module.js +44 -0
  182. package/dist/cjs/server/adapters/nestjs/module/ai-tools.service.d.ts +28 -0
  183. package/dist/cjs/server/adapters/nestjs/module/ai-tools.service.js +41 -0
  184. package/dist/cjs/server/adapters/nestjs/scanner/nestjs-scanner.d.ts +16 -0
  185. package/dist/cjs/server/adapters/nestjs/scanner/nestjs-scanner.js +117 -0
  186. package/dist/cjs/server/adapters/nestjs/scanner/schema-builder.d.ts +26 -0
  187. package/dist/cjs/server/adapters/nestjs/scanner/schema-builder.js +259 -0
  188. package/dist/cjs/server/adapters/nestjs/swagger.d.ts +7 -0
  189. package/dist/cjs/server/adapters/nestjs/swagger.js +39 -0
  190. package/dist/cjs/server/adapters/nextjs/context-helpers.d.ts +22 -0
  191. package/dist/cjs/server/adapters/nextjs/context-helpers.js +60 -0
  192. package/dist/cjs/server/adapters/nextjs/create-ai-chat-handler.d.ts +94 -0
  193. package/dist/cjs/server/adapters/nextjs/create-ai-chat-handler.js +965 -0
  194. package/dist/cjs/server/adapters/nextjs/filter-fallback-error.d.ts +11 -0
  195. package/dist/cjs/server/adapters/nextjs/filter-fallback-error.js +41 -0
  196. package/dist/cjs/server/adapters/nextjs/index.d.ts +8 -0
  197. package/dist/cjs/server/adapters/nextjs/index.js +22 -0
  198. package/dist/cjs/server/adapters/nextjs/prepare-model-messages.d.ts +58 -0
  199. package/dist/cjs/server/adapters/nextjs/prepare-model-messages.js +114 -0
  200. package/dist/cjs/server/adapters/nextjs/sanitize-model-messages.d.ts +64 -0
  201. package/dist/cjs/server/adapters/nextjs/sanitize-model-messages.js +489 -0
  202. package/dist/cjs/server/adapters/nextjs/server-action-helper.d.ts +7 -0
  203. package/dist/cjs/server/adapters/nextjs/server-action-helper.js +40 -0
  204. package/dist/cjs/server/adapters/nextjs/types.d.ts +246 -0
  205. package/dist/cjs/server/adapters/nextjs/types.js +2 -0
  206. package/dist/cjs/server/adapters/nextjs/with-ai-tool.d.ts +9 -0
  207. package/dist/cjs/server/adapters/nextjs/with-ai-tool.js +12 -0
  208. package/dist/cjs/server/core/followup-tool.d.ts +9 -0
  209. package/dist/cjs/server/core/followup-tool.js +82 -0
  210. package/dist/cjs/server/core/index.d.ts +139 -0
  211. package/dist/cjs/server/core/index.js +818 -0
  212. package/dist/cjs/server/core/intent-classifier.d.ts +94 -0
  213. package/dist/cjs/server/core/intent-classifier.js +324 -0
  214. package/dist/cjs/server/core/model-selector.d.ts +12 -0
  215. package/dist/cjs/server/core/model-selector.js +48 -0
  216. package/dist/cjs/server/core/module-router.d.ts +14 -0
  217. package/dist/cjs/server/core/module-router.js +110 -0
  218. package/dist/cjs/server/core/zod-compact.d.ts +18 -0
  219. package/dist/cjs/server/core/zod-compact.js +129 -0
  220. package/dist/cjs/server/index.d.ts +6 -0
  221. package/dist/cjs/server/index.js +28 -0
  222. package/dist/cjs/server/lancer/cache.d.ts +9 -0
  223. package/dist/cjs/server/lancer/cache.js +33 -0
  224. package/dist/cjs/server/lancer/client.d.ts +2 -0
  225. package/dist/cjs/server/lancer/client.js +279 -0
  226. package/dist/cjs/server/lancer/errors.d.ts +13 -0
  227. package/dist/cjs/server/lancer/errors.js +21 -0
  228. package/dist/cjs/server/lancer/index.d.ts +3 -0
  229. package/dist/cjs/server/lancer/index.js +7 -0
  230. package/dist/cjs/server/lancer/telemetry-buffer.d.ts +15 -0
  231. package/dist/cjs/server/lancer/telemetry-buffer.js +64 -0
  232. package/dist/cjs/server/lancer/types.d.ts +201 -0
  233. package/dist/cjs/server/lancer/types.js +5 -0
  234. package/dist/cjs/server/pii-shield/aegis-detector.d.ts +26 -0
  235. package/dist/cjs/server/pii-shield/aegis-detector.js +26 -0
  236. package/dist/cjs/server/pii-shield/create-pii-shield.d.ts +2 -0
  237. package/dist/cjs/server/pii-shield/create-pii-shield.js +191 -0
  238. package/dist/cjs/server/pii-shield/deep-walk.d.ts +1 -0
  239. package/dist/cjs/server/pii-shield/deep-walk.js +19 -0
  240. package/dist/cjs/server/pii-shield/fake-data.d.ts +5 -0
  241. package/dist/cjs/server/pii-shield/fake-data.js +170 -0
  242. package/dist/cjs/server/pii-shield/index.d.ts +4 -0
  243. package/dist/cjs/server/pii-shield/index.js +9 -0
  244. package/dist/cjs/server/pii-shield/leakage.d.ts +1 -0
  245. package/dist/cjs/server/pii-shield/leakage.js +15 -0
  246. package/dist/cjs/server/pii-shield/session-mapping.d.ts +12 -0
  247. package/dist/cjs/server/pii-shield/session-mapping.js +70 -0
  248. package/dist/cjs/server/pipeline.d.ts +26 -0
  249. package/dist/cjs/server/pipeline.js +127 -0
  250. package/dist/cjs/server/testing/approvals.d.ts +11 -0
  251. package/dist/cjs/server/testing/approvals.js +41 -0
  252. package/dist/cjs/server/testing/combination.d.ts +3 -0
  253. package/dist/cjs/server/testing/combination.js +83 -0
  254. package/dist/cjs/server/testing/create-test-suite.d.ts +29 -0
  255. package/dist/cjs/server/testing/create-test-suite.js +81 -0
  256. package/dist/cjs/server/testing/edge-cases.d.ts +8 -0
  257. package/dist/cjs/server/testing/edge-cases.js +277 -0
  258. package/dist/cjs/server/testing/guardrails.d.ts +14 -0
  259. package/dist/cjs/server/testing/guardrails.js +152 -0
  260. package/dist/cjs/server/testing/helpers.d.ts +14 -0
  261. package/dist/cjs/server/testing/helpers.js +119 -0
  262. package/dist/cjs/server/testing/index.d.ts +12 -0
  263. package/dist/cjs/server/testing/index.js +37 -0
  264. package/dist/cjs/server/testing/mock-executor.d.ts +8 -0
  265. package/dist/cjs/server/testing/mock-executor.js +40 -0
  266. package/dist/cjs/server/testing/regression.d.ts +7 -0
  267. package/dist/cjs/server/testing/regression.js +27 -0
  268. package/dist/cjs/server/testing/routing.d.ts +12 -0
  269. package/dist/cjs/server/testing/routing.js +63 -0
  270. package/dist/cjs/server/testing/schema-consistency.d.ts +6 -0
  271. package/dist/cjs/server/testing/schema-consistency.js +56 -0
  272. package/dist/cjs/server/testing/smoke.d.ts +11 -0
  273. package/dist/cjs/server/testing/smoke.js +64 -0
  274. package/dist/cjs/server/testing/types.d.ts +156 -0
  275. package/dist/cjs/server/testing/types.js +2 -0
  276. package/dist/cjs/types.d.ts +696 -0
  277. package/dist/cjs/types.js +91 -0
  278. package/dist/cli/commands/install-skills.d.ts +17 -0
  279. package/dist/cli/commands/install-skills.js +185 -0
  280. package/dist/cli/commands/install-skills.js.map +1 -0
  281. package/dist/cli/index.js +25 -0
  282. package/dist/cli/index.js.map +1 -1
  283. package/dist/react/components/ai-trigger-button.js +4 -6
  284. package/dist/react/components/ai-trigger-button.js.map +1 -1
  285. package/dist/react/components/recording-bar.js +4 -6
  286. package/dist/react/components/recording-bar.js.map +1 -1
  287. package/dist/react/components/wavesurfer-loader.d.ts +5 -0
  288. package/dist/react/components/wavesurfer-loader.js +34 -0
  289. package/dist/react/components/wavesurfer-loader.js.map +1 -0
  290. package/dist/server/adapters/nestjs/chat/ai-chat.module.d.ts +1 -1
  291. package/dist/server/adapters/nestjs/chat/ai-chat.module.js +3 -2
  292. package/dist/server/adapters/nestjs/chat/ai-chat.module.js.map +1 -1
  293. package/dist/server/adapters/nestjs/chat/speech-stream.gateway.d.ts +1 -1
  294. package/dist/server/adapters/nestjs/chat/speech-stream.gateway.js +10 -8
  295. package/dist/server/adapters/nestjs/chat/speech-stream.gateway.js.map +1 -1
  296. package/dist/server/adapters/nestjs/chat/ws-loader.d.ts +5 -0
  297. package/dist/server/adapters/nestjs/chat/ws-loader.js +37 -0
  298. package/dist/server/adapters/nestjs/chat/ws-loader.js.map +1 -0
  299. package/dist/server/adapters/nextjs/create-ai-chat-handler.d.ts +16 -0
  300. package/dist/server/adapters/nextjs/create-ai-chat-handler.js +14 -3
  301. package/dist/server/adapters/nextjs/create-ai-chat-handler.js.map +1 -1
  302. package/dist/server/adapters/nextjs/filter-fallback-error.d.ts +11 -0
  303. package/dist/server/adapters/nextjs/filter-fallback-error.js +38 -0
  304. package/dist/server/adapters/nextjs/filter-fallback-error.js.map +1 -0
  305. package/openapi/package.json +5 -0
  306. package/package.json +66 -21
  307. package/react/langgraph/package.json +5 -0
  308. package/react/package.json +5 -0
  309. package/react/vercel/package.json +5 -0
  310. package/server/nestjs/package.json +5 -0
  311. package/server/nextjs/package.json +5 -0
  312. package/server/package.json +5 -0
  313. package/server/testing/package.json +5 -0
  314. package/skills/README.md +107 -0
  315. package/skills/building-glirastes-chat-ui/SKILL.md +378 -0
  316. package/skills/integrating-glirastes-nestjs/SKILL.md +346 -0
  317. package/skills/integrating-glirastes-nextjs/SKILL.md +306 -0
  318. package/skills/integrating-glirastes-nextjs-with-nestjs-backend/SKILL.md +359 -0
  319. package/skills/maintaining-glirastes-tools/SKILL.md +463 -0
@@ -0,0 +1,94 @@
1
+ import type { IntentClassifier, IntentClassifierConfig, IntentClassification, ModuleDefinition, ConversationMessage } from '../../types.js';
2
+ import { type Stemmer } from 'snowball-stemmers';
3
+ /**
4
+ * Configuration for the local intent classifier.
5
+ *
6
+ * Extends IntentClassifierConfig with a `generateText` callback so
7
+ * consumers can pass in their AI SDK `generateText` function without
8
+ * the server-core package needing a hard dependency on `ai`.
9
+ */
10
+ export interface LocalClassifierConfig extends IntentClassifierConfig {
11
+ /**
12
+ * Optional generateText callback (from Vercel AI SDK or compatible).
13
+ * When provided, the classifier uses LLM classification with a
14
+ * Jaccard heuristic fallback. Without it, only heuristics are used.
15
+ *
16
+ * Expected signature:
17
+ * ```ts
18
+ * (options: { model: unknown; prompt: string; }) => Promise<{ text: string }>
19
+ * ```
20
+ */
21
+ generateText?: (options: {
22
+ model: unknown;
23
+ prompt: string;
24
+ abortSignal?: AbortSignal;
25
+ }) => Promise<{
26
+ text: string;
27
+ }>;
28
+ }
29
+ /** Resolve a BCP-47 locale (e.g. "de-DE") to a Snowball Stemmer, or null */
30
+ export declare function stemmerForLocale(locale?: string): Stemmer | null;
31
+ /**
32
+ * Tokenize text into lowercase tokens (3+ chars).
33
+ * Strips punctuation and splits on whitespace.
34
+ */
35
+ export declare function tokenize(text: string): Set<string>;
36
+ /** Character trigrams for fuzzy matching */
37
+ export declare function charTrigrams(text: string): Set<string>;
38
+ /**
39
+ * Compute Jaccard similarity between two token sets.
40
+ * Returns 0 when either set is empty.
41
+ */
42
+ export declare function jaccardSimilarity(a: Set<string>, b: Set<string>): number;
43
+ /** Count token pairs sharing a prefix of at least `minLen` chars */
44
+ export declare function prefixOverlap(a: Set<string>, b: Set<string>, minLen?: number): number;
45
+ /**
46
+ * Classify user input against modules using multi-signal similarity:
47
+ * 1. Snowball-stemmed Jaccard (language-aware inflection handling)
48
+ * 2. Prefix overlap (morphological variants)
49
+ * 3. Character trigrams (typos, fuzzy matches)
50
+ *
51
+ * Maps raw scores to confidence buckets:
52
+ * - >= 0.5 → 0.93 (high confidence)
53
+ * - >= 0.4 → 0.86 (medium-high)
54
+ * - >= 0.15 → 0.72 (medium)
55
+ * - < 0.15 → ambiguous
56
+ */
57
+ export declare function classifyWithHeuristics(message: string, modules: ModuleDefinition[], locale?: string): IntentClassification;
58
+ /**
59
+ * Build the classification prompt for LLM-based intent classification.
60
+ */
61
+ export declare function buildClassificationPrompt(message: string, modules: ModuleDefinition[], history?: ConversationMessage[]): string;
62
+ /**
63
+ * Parse a JSON response from the LLM, tolerating markdown code blocks
64
+ * and other wrapper text.
65
+ */
66
+ export declare function parseJsonResponse(text: string): {
67
+ moduleId: string;
68
+ confidence: number;
69
+ } | null;
70
+ /**
71
+ * Create a local intent classifier that uses the user's own model for
72
+ * LLM classification, falling back to a multi-signal heuristic when
73
+ * the LLM is unavailable or fails.
74
+ *
75
+ * Heuristics use Snowball stemming (24 languages), prefix overlap, and
76
+ * character trigrams for language-agnostic fuzzy matching.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * import { generateText } from 'ai';
81
+ * import { openai } from '@ai-sdk/openai';
82
+ *
83
+ * const classifier = createIntentClassifier({
84
+ * modules: [taskModule, calendarModule],
85
+ * model: openai('gpt-4o-mini'),
86
+ * generateText,
87
+ * locale: 'de',
88
+ * });
89
+ *
90
+ * const result = await classifier.classify('create a new task');
91
+ * // { intent: 'tasks', confidence: 0.95 }
92
+ * ```
93
+ */
94
+ export declare function createIntentClassifier(config: LocalClassifierConfig): IntentClassifier;
@@ -0,0 +1,324 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stemmerForLocale = stemmerForLocale;
4
+ exports.tokenize = tokenize;
5
+ exports.charTrigrams = charTrigrams;
6
+ exports.jaccardSimilarity = jaccardSimilarity;
7
+ exports.prefixOverlap = prefixOverlap;
8
+ exports.classifyWithHeuristics = classifyWithHeuristics;
9
+ exports.buildClassificationPrompt = buildClassificationPrompt;
10
+ exports.parseJsonResponse = parseJsonResponse;
11
+ exports.createIntentClassifier = createIntentClassifier;
12
+ const snowball_stemmers_1 = require("snowball-stemmers");
13
+ // ============================================================================
14
+ // Locale → Snowball Stemmer
15
+ // ============================================================================
16
+ const AVAILABLE_ALGOS = new Set((0, snowball_stemmers_1.algorithms)());
17
+ const LOCALE_MAP = {
18
+ ar: 'arabic', am: 'armenian', eu: 'basque', ca: 'catalan', cs: 'czech',
19
+ da: 'danish', nl: 'dutch', en: 'english', fi: 'finnish', fr: 'french',
20
+ de: 'german', hu: 'hungarian', it: 'italian', ga: 'irish', nb: 'norwegian',
21
+ nn: 'norwegian', no: 'norwegian', pt: 'portuguese', ro: 'romanian',
22
+ ru: 'russian', es: 'spanish', sl: 'slovene', sv: 'swedish', ta: 'tamil',
23
+ tr: 'turkish',
24
+ };
25
+ /** Resolve a BCP-47 locale (e.g. "de-DE") to a Snowball Stemmer, or null */
26
+ function stemmerForLocale(locale) {
27
+ if (!locale)
28
+ return null;
29
+ const lang = locale.split(/[-_]/)[0].toLowerCase();
30
+ const algo = LOCALE_MAP[lang];
31
+ if (algo && AVAILABLE_ALGOS.has(algo))
32
+ return (0, snowball_stemmers_1.newStemmer)(algo);
33
+ return null;
34
+ }
35
+ // ============================================================================
36
+ // Tokenization & Similarity
37
+ // ============================================================================
38
+ /**
39
+ * Tokenize text into lowercase tokens (3+ chars).
40
+ * Strips punctuation and splits on whitespace.
41
+ */
42
+ function tokenize(text) {
43
+ return new Set(text
44
+ .toLowerCase()
45
+ .replace(/[^\p{L}\p{N}\s]+/gu, ' ')
46
+ .split(/\s+/)
47
+ .map((t) => t.trim())
48
+ .filter((t) => t.length >= 3));
49
+ }
50
+ function rawTokenize(text) {
51
+ return text
52
+ .toLowerCase()
53
+ .replace(/[^\p{L}\p{N}\s]+/gu, ' ')
54
+ .split(/\s+/)
55
+ .map((t) => t.trim())
56
+ .filter((t) => t.length >= 3);
57
+ }
58
+ function toSet(tokens) {
59
+ return new Set(tokens);
60
+ }
61
+ function stemTokens(tokens, stemmer) {
62
+ if (!stemmer)
63
+ return toSet(tokens);
64
+ return toSet(tokens.map((t) => stemmer.stem(t)));
65
+ }
66
+ /** Character trigrams for fuzzy matching */
67
+ function charTrigrams(text) {
68
+ const clean = text.toLowerCase().replace(/[^\p{L}\p{N}]/gu, '');
69
+ const grams = new Set();
70
+ for (let i = 0; i <= clean.length - 3; i++) {
71
+ grams.add(clean.slice(i, i + 3));
72
+ }
73
+ return grams;
74
+ }
75
+ /**
76
+ * Compute Jaccard similarity between two token sets.
77
+ * Returns 0 when either set is empty.
78
+ */
79
+ function jaccardSimilarity(a, b) {
80
+ if (a.size === 0 || b.size === 0)
81
+ return 0;
82
+ let intersection = 0;
83
+ const [small, large] = a.size <= b.size ? [a, b] : [b, a];
84
+ for (const token of small) {
85
+ if (large.has(token))
86
+ intersection++;
87
+ }
88
+ const union = a.size + b.size - intersection;
89
+ return union === 0 ? 0 : intersection / union;
90
+ }
91
+ /** Count token pairs sharing a prefix of at least `minLen` chars */
92
+ function prefixOverlap(a, b, minLen = 4) {
93
+ if (a.size === 0 || b.size === 0)
94
+ return 0;
95
+ const bArr = [...b];
96
+ let matches = 0;
97
+ const used = new Set();
98
+ for (const tokA of a) {
99
+ if (tokA.length < minLen)
100
+ continue;
101
+ const pre = tokA.slice(0, minLen);
102
+ for (let j = 0; j < bArr.length; j++) {
103
+ if (used.has(j) || bArr[j].length < minLen)
104
+ continue;
105
+ if (bArr[j].startsWith(pre)) {
106
+ matches++;
107
+ used.add(j);
108
+ break;
109
+ }
110
+ }
111
+ }
112
+ const union = a.size + b.size - matches;
113
+ return union === 0 ? 0 : matches / union;
114
+ }
115
+ // ============================================================================
116
+ // Multi-Signal Heuristic Classifier
117
+ // ============================================================================
118
+ function scoreModule(inputTokens, inputStems, inputTrigrams, m, stemmer) {
119
+ const descRaw = rawTokenize(m.description);
120
+ const descTokens = toSet(descRaw);
121
+ const descStems = stemTokens(descRaw, stemmer);
122
+ const descTrigrams = charTrigrams(m.description);
123
+ const examples = m.classification?.examples ?? [];
124
+ // --- Signal 1: Stemmed Jaccard (handles inflection via Snowball) ---
125
+ let bestStemEx = 0;
126
+ for (const ex of examples) {
127
+ const exRaw = rawTokenize(ex);
128
+ bestStemEx = Math.max(bestStemEx, jaccardSimilarity(inputStems, stemTokens(exRaw, stemmer)));
129
+ }
130
+ const stemmedScore = Math.max(bestStemEx, jaccardSimilarity(inputStems, descStems) * 0.8);
131
+ // --- Signal 2: Prefix overlap (morphological variants beyond stemmer) ---
132
+ let bestPrefixEx = 0;
133
+ for (const ex of examples) {
134
+ bestPrefixEx = Math.max(bestPrefixEx, prefixOverlap(inputTokens, toSet(rawTokenize(ex))));
135
+ }
136
+ const prefixScore = Math.max(bestPrefixEx, prefixOverlap(inputTokens, descTokens) * 0.8);
137
+ // --- Signal 3: Character trigrams (typos, partial matches) ---
138
+ let bestTrigramEx = 0;
139
+ for (const ex of examples) {
140
+ bestTrigramEx = Math.max(bestTrigramEx, jaccardSimilarity(inputTrigrams, charTrigrams(ex)));
141
+ }
142
+ const trigramScore = Math.max(bestTrigramEx, jaccardSimilarity(inputTrigrams, descTrigrams) * 0.8);
143
+ // Best signal wins (slight discount on fuzzier methods)
144
+ return Math.max(stemmedScore, prefixScore * 0.95, trigramScore * 0.85);
145
+ }
146
+ /**
147
+ * Classify user input against modules using multi-signal similarity:
148
+ * 1. Snowball-stemmed Jaccard (language-aware inflection handling)
149
+ * 2. Prefix overlap (morphological variants)
150
+ * 3. Character trigrams (typos, fuzzy matches)
151
+ *
152
+ * Maps raw scores to confidence buckets:
153
+ * - >= 0.5 → 0.93 (high confidence)
154
+ * - >= 0.4 → 0.86 (medium-high)
155
+ * - >= 0.15 → 0.72 (medium)
156
+ * - < 0.15 → ambiguous
157
+ */
158
+ function classifyWithHeuristics(message, modules, locale) {
159
+ const stemmer = stemmerForLocale(locale);
160
+ const raw = rawTokenize(message);
161
+ const inputTokens = toSet(raw);
162
+ const inputStems = stemTokens(raw, stemmer);
163
+ const inputTrigrams = charTrigrams(message);
164
+ if (inputTokens.size === 0 || modules.length === 0) {
165
+ return { intent: 'ambiguous', confidence: 0 };
166
+ }
167
+ const scored = modules.map((m) => ({
168
+ moduleId: m.id,
169
+ score: scoreModule(inputTokens, inputStems, inputTrigrams, m, stemmer),
170
+ }));
171
+ scored.sort((a, b) => b.score - a.score);
172
+ const best = scored[0];
173
+ if (!best || best.score < 0.15) {
174
+ return { intent: 'ambiguous', confidence: 0 };
175
+ }
176
+ // Map raw Jaccard score to confidence buckets
177
+ const confidence = best.score >= 0.5 ? 0.93 : best.score >= 0.4 ? 0.86 : 0.72;
178
+ return { intent: best.moduleId, confidence };
179
+ }
180
+ // ============================================================================
181
+ // LLM Classification
182
+ // ============================================================================
183
+ /**
184
+ * Build the classification prompt for LLM-based intent classification.
185
+ */
186
+ function buildClassificationPrompt(message, modules, history) {
187
+ const moduleDescriptions = modules
188
+ .map((m) => {
189
+ const examples = m.classification?.examples ?? [];
190
+ const examplesStr = examples.length > 0
191
+ ? ` Examples: ${examples.map((e) => `"${e}"`).join(', ')}`
192
+ : '';
193
+ return `- ${m.id}: ${m.description}.${examplesStr}`;
194
+ })
195
+ .join('\n');
196
+ const historyContext = history && history.length > 0
197
+ ? `\nConversation history:\n${history.map((h) => `${h.role}: ${h.content}`).join('\n')}\n`
198
+ : '';
199
+ return `You are an intent classifier. Given a user message, determine which module best handles it.
200
+
201
+ Available modules:
202
+ ${moduleDescriptions}
203
+
204
+ Respond with JSON only: { "moduleId": "<module_id>", "confidence": <0.0-1.0> }
205
+ If no module matches well, use confidence < 0.3.
206
+ ${historyContext}
207
+ User message: "${message}"`;
208
+ }
209
+ /**
210
+ * Parse a JSON response from the LLM, tolerating markdown code blocks
211
+ * and other wrapper text.
212
+ */
213
+ function parseJsonResponse(text) {
214
+ const validate = (obj) => {
215
+ if (typeof obj === 'object' && obj !== null &&
216
+ typeof obj.moduleId === 'string' &&
217
+ typeof obj.confidence === 'number') {
218
+ return obj;
219
+ }
220
+ return null;
221
+ };
222
+ // Strip markdown fences before attempting parse
223
+ const cleaned = text.replace(/```(?:json)?\s*/g, '').replace(/```/g, '').trim();
224
+ try {
225
+ return validate(JSON.parse(cleaned));
226
+ }
227
+ catch {
228
+ // Try extracting any JSON object containing both required fields
229
+ const jsonMatch = cleaned.match(/\{[^}]*"(?:moduleId|confidence)"[^}]*\}/);
230
+ if (jsonMatch) {
231
+ try {
232
+ return validate(JSON.parse(jsonMatch[0]));
233
+ }
234
+ catch {
235
+ // Give up
236
+ }
237
+ }
238
+ }
239
+ return null;
240
+ }
241
+ // ============================================================================
242
+ // Factory
243
+ // ============================================================================
244
+ /**
245
+ * Create a local intent classifier that uses the user's own model for
246
+ * LLM classification, falling back to a multi-signal heuristic when
247
+ * the LLM is unavailable or fails.
248
+ *
249
+ * Heuristics use Snowball stemming (24 languages), prefix overlap, and
250
+ * character trigrams for language-agnostic fuzzy matching.
251
+ *
252
+ * @example
253
+ * ```ts
254
+ * import { generateText } from 'ai';
255
+ * import { openai } from '@ai-sdk/openai';
256
+ *
257
+ * const classifier = createIntentClassifier({
258
+ * modules: [taskModule, calendarModule],
259
+ * model: openai('gpt-4o-mini'),
260
+ * generateText,
261
+ * locale: 'de',
262
+ * });
263
+ *
264
+ * const result = await classifier.classify('create a new task');
265
+ * // { intent: 'tasks', confidence: 0.95 }
266
+ * ```
267
+ */
268
+ function createIntentClassifier(config) {
269
+ const { modules, model, generateText, timeoutMs = 2000, confidenceThreshold = 0.5, minTokens = 2, locale, } = config;
270
+ return {
271
+ async classify(input, _context, conversationHistory) {
272
+ // Short-circuit: not enough tokens to classify meaningfully
273
+ const tokens = tokenize(input);
274
+ if (tokens.size < minTokens || modules.length === 0) {
275
+ return { intent: 'ambiguous', confidence: 0 };
276
+ }
277
+ // Try LLM classification when both model and generateText are available
278
+ if (model && generateText) {
279
+ try {
280
+ const result = await classifyWithLlm(input, modules, model, generateText, timeoutMs, conversationHistory);
281
+ if (result.confidence >= confidenceThreshold) {
282
+ return result;
283
+ }
284
+ // LLM returned low confidence — fall through to heuristics
285
+ }
286
+ catch {
287
+ // LLM failed — fall through to heuristics
288
+ }
289
+ }
290
+ return classifyWithHeuristics(input, modules, locale);
291
+ },
292
+ };
293
+ }
294
+ // ============================================================================
295
+ // Internal LLM Classification
296
+ // ============================================================================
297
+ async function classifyWithLlm(input, modules, model, generateText, timeoutMs, conversationHistory) {
298
+ const prompt = buildClassificationPrompt(input, modules, conversationHistory);
299
+ const controller = new AbortController();
300
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
301
+ let result;
302
+ try {
303
+ result = await generateText({ model, prompt, abortSignal: controller.signal });
304
+ }
305
+ finally {
306
+ clearTimeout(timer);
307
+ }
308
+ const parsed = parseJsonResponse(result.text);
309
+ if (!parsed) {
310
+ throw new Error('Failed to parse LLM JSON response');
311
+ }
312
+ // Validate moduleId exists in configured modules
313
+ const matchedModule = modules.find((m) => m.id === parsed.moduleId);
314
+ if (!matchedModule) {
315
+ return {
316
+ intent: 'ambiguous',
317
+ confidence: Math.max(0, Math.min(1, parsed.confidence)),
318
+ };
319
+ }
320
+ return {
321
+ intent: parsed.moduleId,
322
+ confidence: Math.max(0, Math.min(1, parsed.confidence)),
323
+ };
324
+ }
@@ -0,0 +1,12 @@
1
+ import type { ModelSelectorConfig, ModelSelector, ModuleDefinition } from '../../types.js';
2
+ /**
3
+ * Create a model selector from a flat tier→modelId map.
4
+ * The consuming app provides an `instanceFactory` that turns a modelId
5
+ * string into a ready-to-use LanguageModel instance.
6
+ */
7
+ export declare function createModelSelectorFromMap(models: Record<string, string>, instanceFactory: (modelId: string) => unknown, modules?: ModuleDefinition[]): ModelSelector;
8
+ /**
9
+ * Create a model selector that picks the appropriate model based on
10
+ * intent classification and module configuration.
11
+ */
12
+ export declare function createModelSelector(tiers: ModelSelectorConfig, modules?: ModuleDefinition[]): ModelSelector;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createModelSelectorFromMap = createModelSelectorFromMap;
4
+ exports.createModelSelector = createModelSelector;
5
+ // ============================================================================
6
+ // Flat-map Factory
7
+ // ============================================================================
8
+ /**
9
+ * Create a model selector from a flat tier→modelId map.
10
+ * The consuming app provides an `instanceFactory` that turns a modelId
11
+ * string into a ready-to-use LanguageModel instance.
12
+ */
13
+ function createModelSelectorFromMap(models, instanceFactory, modules) {
14
+ const resolve = (tier) => models[tier] ?? models.standard ?? 'default';
15
+ const tiers = {
16
+ fast: { modelId: resolve('fast'), instance: instanceFactory(resolve('fast')) },
17
+ standard: { modelId: resolve('standard'), instance: instanceFactory(resolve('standard')) },
18
+ premium: { modelId: resolve('powerful'), instance: instanceFactory(resolve('powerful')) },
19
+ };
20
+ return createModelSelector(tiers, modules);
21
+ }
22
+ // ============================================================================
23
+ // Factory
24
+ // ============================================================================
25
+ /**
26
+ * Create a model selector that picks the appropriate model based on
27
+ * intent classification and module configuration.
28
+ */
29
+ function createModelSelector(tiers, modules) {
30
+ const moduleMap = modules
31
+ ? new Map(modules.map((m) => [m.id, m]))
32
+ : new Map();
33
+ return {
34
+ select(intent, _context) {
35
+ const module = moduleMap.get(intent.intent);
36
+ const tier = module?.executionDefaults?.modelTier ?? 'standard';
37
+ switch (tier) {
38
+ case 'fast':
39
+ return tiers.fast;
40
+ case 'powerful':
41
+ return tiers.premium;
42
+ case 'standard':
43
+ default:
44
+ return tiers.standard;
45
+ }
46
+ },
47
+ };
48
+ }
@@ -0,0 +1,14 @@
1
+ import type { ModuleDefinition, AiRouterConfig, AiRouter } from '../../types.js';
2
+ /**
3
+ * Define a module for intent-based tool routing.
4
+ */
5
+ export declare function defineModule(config: ModuleDefinition): ModuleDefinition;
6
+ /**
7
+ * Create an AI router that selects tools based on classified intent.
8
+ *
9
+ * The router uses confidence-based expansion:
10
+ * - High confidence (>= 0.85): Only primary module's own tools
11
+ * - Medium confidence (0.7-0.85): Primary module tools + shared tools from all modules
12
+ * - Low confidence (< 0.7): All tools (ambiguous fallback)
13
+ */
14
+ export declare function createAiRouter(config: AiRouterConfig): AiRouter;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defineModule = defineModule;
4
+ exports.createAiRouter = createAiRouter;
5
+ // ============================================================================
6
+ // Default Confidence Thresholds
7
+ // ============================================================================
8
+ const DEFAULT_THRESHOLDS = {
9
+ high: 0.85,
10
+ medium: 0.7,
11
+ };
12
+ // ============================================================================
13
+ // Helpers
14
+ // ============================================================================
15
+ function getExpansionStrategy(confidence, thresholds) {
16
+ if (confidence >= thresholds.high)
17
+ return 'single';
18
+ if (confidence >= thresholds.medium)
19
+ return 'expanded';
20
+ return 'all';
21
+ }
22
+ function getAllTools(modules) {
23
+ const all = new Set();
24
+ for (const mod of modules) {
25
+ for (const tool of mod.tools)
26
+ all.add(tool);
27
+ if (mod.sharedTools) {
28
+ for (const tool of mod.sharedTools)
29
+ all.add(tool);
30
+ }
31
+ }
32
+ return [...all];
33
+ }
34
+ function unique(tools) {
35
+ return [...new Set(tools)];
36
+ }
37
+ // ============================================================================
38
+ // Module Definition Helper
39
+ // ============================================================================
40
+ /**
41
+ * Define a module for intent-based tool routing.
42
+ */
43
+ function defineModule(config) {
44
+ return config;
45
+ }
46
+ // ============================================================================
47
+ // Router Factory
48
+ // ============================================================================
49
+ /**
50
+ * Create an AI router that selects tools based on classified intent.
51
+ *
52
+ * The router uses confidence-based expansion:
53
+ * - High confidence (>= 0.85): Only primary module's own tools
54
+ * - Medium confidence (0.7-0.85): Primary module tools + shared tools from all modules
55
+ * - Low confidence (< 0.7): All tools (ambiguous fallback)
56
+ */
57
+ function createAiRouter(config) {
58
+ const { modules, relatedModules = {}, confidenceThresholds = {}, } = config;
59
+ const thresholds = {
60
+ high: confidenceThresholds.high ?? DEFAULT_THRESHOLDS.high,
61
+ medium: confidenceThresholds.medium ?? DEFAULT_THRESHOLDS.medium,
62
+ };
63
+ const moduleMap = new Map(modules.map((m) => [m.id, m]));
64
+ const allToolNames = getAllTools(modules);
65
+ return {
66
+ route(intent, _allToolNames) {
67
+ // Ambiguous: use all tools
68
+ if (intent.intent === 'ambiguous') {
69
+ return {
70
+ tools: unique(allToolNames),
71
+ module: null,
72
+ strategy: 'all',
73
+ };
74
+ }
75
+ const primaryModule = moduleMap.get(intent.intent);
76
+ if (!primaryModule) {
77
+ return {
78
+ tools: unique(allToolNames),
79
+ module: null,
80
+ strategy: 'all',
81
+ };
82
+ }
83
+ const strategy = getExpansionStrategy(intent.confidence, thresholds);
84
+ switch (strategy) {
85
+ case 'single': {
86
+ return {
87
+ tools: unique([...primaryModule.tools]),
88
+ module: primaryModule,
89
+ strategy: 'single',
90
+ };
91
+ }
92
+ case 'expanded': {
93
+ const sharedFromAll = modules.flatMap((m) => m.sharedTools ?? []);
94
+ return {
95
+ tools: unique([...primaryModule.tools, ...sharedFromAll]),
96
+ module: primaryModule,
97
+ strategy: 'expanded',
98
+ };
99
+ }
100
+ case 'all':
101
+ default:
102
+ return {
103
+ tools: unique(allToolNames),
104
+ module: null,
105
+ strategy: 'all',
106
+ };
107
+ }
108
+ },
109
+ };
110
+ }
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Convert a Zod schema to a compact TypeScript-like description string.
4
+ *
5
+ * Used to auto-generate "Returns: ..." suffixes for AI tool descriptions,
6
+ * so the LLM knows the response shape without bloating the system prompt.
7
+ *
8
+ * @example
9
+ * zodToCompactDescription(z.object({
10
+ * tasks: z.array(z.object({ id: z.string(), title: z.string() })),
11
+ * total: z.number(),
12
+ * }))
13
+ * // → '{ tasks: Array<{ id: string, title: string }>, total: number }'
14
+ *
15
+ * @param schema - Any Zod schema
16
+ * @param maxDepth - Maximum nesting depth before collapsing to "..." (default: 3)
17
+ */
18
+ export declare function zodToCompactDescription(schema: z.ZodTypeAny, maxDepth?: number): string;