@johpaz/hive-sdk 0.1.4 → 0.1.6

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 (278) hide show
  1. package/CHANGELOG.md +129 -0
  2. package/README.md +78 -23
  3. package/bun.lock +55 -29
  4. package/bunfig.toml +4 -2
  5. package/docs/API-AGENTS.md +78 -27
  6. package/docs/API-CONTEXT-COMPILER.md +31 -34
  7. package/docs/API-TOOLS-SKILLS-CHANNELS.md +58 -22
  8. package/docs/HIVE-HARNESS.md +1 -1
  9. package/docs/INDEX.md +4 -4
  10. package/docs/TEMPLATE-HIVE-APP.md +10 -10
  11. package/package.json +17 -12
  12. package/packages/cli/package.json +2 -2
  13. package/packages/cli/src/commands/create-app.test.ts +36 -7
  14. package/packages/cli/src/commands/init.ts +3 -3
  15. package/packages/cli/src/commands/run.ts +1 -1
  16. package/packages/cli/src/commands/test.ts +37 -25
  17. package/packages/cli/src/commands/trace.ts +30 -28
  18. package/packages/cli/templates/hive-app/.env.example +10 -2
  19. package/packages/cli/templates/hive-app/README.md +103 -0
  20. package/packages/cli/templates/hive-app/hive.config.ts +9 -3
  21. package/packages/cli/templates/hive-app/src/agents/coordinator.ts +8 -1
  22. package/packages/cli/templates/hive-app/src/main.ts +12 -19
  23. package/packages/core/package.json +13 -12
  24. package/packages/core/src/agent/acceptance-checks.ts +172 -0
  25. package/packages/core/src/agent/agent-catalog.ts +348 -0
  26. package/packages/core/src/agent/agent-loop.ts +1373 -0
  27. package/packages/core/src/agent/capability-search.ts +186 -0
  28. package/packages/core/src/agent/catalog-selector.ts +103 -0
  29. package/packages/core/src/agent/{Compaction.ts → compaction.ts} +86 -63
  30. package/packages/core/src/agent/context-compiler.ts +689 -0
  31. package/packages/core/src/agent/conversation-store.ts +381 -0
  32. package/packages/core/src/agent/curator.ts +276 -0
  33. package/packages/core/src/agent/delegation-runtime.ts +241 -0
  34. package/packages/core/src/agent/goal-runner.ts +323 -0
  35. package/packages/core/src/agent/index.ts +17 -12
  36. package/packages/core/src/agent/llm-client.ts +266 -0
  37. package/packages/core/src/agent/llm-providers/anthropic.ts +264 -0
  38. package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
  39. package/packages/core/src/agent/{providers → llm-providers}/gemini.ts +98 -60
  40. package/packages/core/src/agent/llm-providers/groq.ts +5 -0
  41. package/packages/core/src/agent/llm-providers/hiveagents.ts +253 -0
  42. package/packages/core/src/agent/{providers → llm-providers}/interface.ts +73 -13
  43. package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
  44. package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
  45. package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
  46. package/packages/core/src/agent/llm-providers/modelscope.ts +5 -0
  47. package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
  48. package/packages/core/src/agent/{providers → llm-providers}/ollama.ts +31 -5
  49. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +418 -0
  50. package/packages/core/src/agent/llm-providers/openai.ts +5 -0
  51. package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
  52. package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
  53. package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
  54. package/packages/core/src/agent/llm-providers/z-ai.ts +5 -0
  55. package/packages/core/src/agent/minimal-loadout.ts +47 -0
  56. package/packages/core/src/agent/playbook-selector.ts +119 -0
  57. package/packages/core/src/agent/{PromptBuilder.ts → prompt-builder.ts} +21 -22
  58. package/packages/core/src/{harness → agent}/proof-packet.ts +16 -21
  59. package/packages/core/src/agent/providers/index.ts +35 -16
  60. package/packages/core/src/agent/reflector.ts +320 -0
  61. package/packages/core/src/agent/routing-intent.ts +22 -0
  62. package/packages/core/src/{harness → agent}/run-epoch.ts +4 -3
  63. package/packages/core/src/{harness → agent}/run-store.ts +142 -81
  64. package/packages/core/src/agent/{Service.ts → service.ts} +37 -26
  65. package/packages/core/src/agent/skill-selector.ts +374 -0
  66. package/packages/core/src/agent/stuck-loop.ts +209 -0
  67. package/packages/core/src/agent/{selectors/ToolSelector.ts → tool-selector.ts} +188 -178
  68. package/packages/core/src/{ace/Tracer.ts → agent/tracer.ts} +37 -27
  69. package/packages/core/src/api/createAgent.test.ts +139 -27
  70. package/packages/core/src/api/createAgent.ts +232 -44
  71. package/packages/core/src/artifacts/store.ts +162 -0
  72. package/packages/core/src/canvas/canvas-manager.ts +161 -0
  73. package/packages/core/src/canvas/canvas.test.ts +8 -4
  74. package/packages/core/src/canvas/emitter.ts +131 -80
  75. package/packages/core/src/canvas/index.ts +1 -3
  76. package/packages/core/src/channels/base.ts +9 -1
  77. package/packages/core/src/channels/discord.ts +5 -4
  78. package/packages/core/src/channels/manager.ts +122 -30
  79. package/packages/core/src/channels/slack.ts +5 -4
  80. package/packages/core/src/channels/telegram.ts +36 -6
  81. package/packages/core/src/channels/webchat.ts +11 -10
  82. package/packages/core/src/channels/whatsapp.ts +23 -7
  83. package/packages/core/src/config/index.ts +13 -2
  84. package/packages/core/src/config/loader.ts +76 -29
  85. package/packages/core/src/ethics/EthicsGuard.test.ts +90 -36
  86. package/packages/core/src/ethics/EthicsGuard.ts +51 -47
  87. package/packages/core/src/events/agent-bus.ts +44 -68
  88. package/packages/core/src/events/channel-narration.ts +150 -0
  89. package/packages/core/src/events/narration.ts +82 -0
  90. package/packages/core/src/events/tool-narration.ts +62 -0
  91. package/packages/core/src/gateway/delegation-groups.ts +258 -0
  92. package/packages/core/src/{harness → gateway}/durable-queue.ts +102 -42
  93. package/packages/core/src/{harness → gateway}/job-store.ts +85 -48
  94. package/packages/core/src/gateway/lane-queue.ts +173 -0
  95. package/packages/core/src/gateway/notification-inbox.ts +57 -0
  96. package/packages/core/src/gateway/server.ts +1 -1
  97. package/packages/core/src/harness/index.ts +46 -27
  98. package/packages/core/src/index.ts +33 -27
  99. package/packages/core/src/mcp/hot-reload.ts +32 -23
  100. package/packages/core/src/mcp/index.ts +6 -3
  101. package/packages/core/src/mcp/singleton.ts +1 -4
  102. package/packages/core/src/mcp/tool-sync.ts +138 -0
  103. package/packages/core/src/memory/Scratchpad.test.ts +39 -20
  104. package/packages/core/src/memory/Scratchpad.ts +27 -34
  105. package/packages/core/src/multimodal/vision-service.ts +44 -38
  106. package/packages/core/src/resilience/retry.ts +95 -0
  107. package/packages/core/src/scheduler/CronScheduler.ts +334 -287
  108. package/packages/core/src/scheduler/index.ts +9 -7
  109. package/packages/core/src/scheduler/integration.ts +46 -26
  110. package/packages/core/src/scheduler/scheduler.test.ts +9 -13
  111. package/packages/core/src/scheduler/types.ts +7 -2
  112. package/packages/core/src/security/Pairing.ts +1 -1
  113. package/packages/core/src/skills/bundled/a2ui/a2ui_dashboard/SKILL.md +176 -0
  114. package/packages/core/src/skills/bundled/a2ui/a2ui_form/SKILL.md +202 -0
  115. package/packages/core/src/skills/bundled/a2ui/a2ui_interactive/SKILL.md +206 -0
  116. package/packages/core/src/skills/bundled/agents/agent_spawner/SKILL.md +173 -0
  117. package/packages/core/src/skills/bundled/agents/memory_manager/SKILL.md +143 -0
  118. package/packages/core/src/skills/bundled/agents/research_and_remember/SKILL.md +139 -0
  119. package/packages/core/src/skills/bundled/agents/task_orchestrator/SKILL.md +98 -0
  120. package/packages/core/src/skills/bundled/api/api_client/SKILL.md +132 -0
  121. package/packages/core/src/skills/bundled/cli/cli_pipeline/SKILL.md +135 -0
  122. package/packages/core/src/skills/bundled/cli/cli_safe_exec/SKILL.md +125 -0
  123. package/packages/core/src/skills/bundled/cli/software_engineering/SKILL.md +23 -0
  124. package/packages/core/src/skills/bundled/cron_manager/SKILL.md +188 -0
  125. package/packages/core/src/skills/bundled/cron_reminder/SKILL.md +112 -0
  126. package/packages/core/src/skills/bundled/filesystem/file_manager/SKILL.md +118 -0
  127. package/packages/core/src/skills/bundled/filesystem/file_read_and_summarize/SKILL.md +109 -0
  128. package/packages/core/src/skills/bundled/filesystem/file_writer/SKILL.md +129 -0
  129. package/packages/core/src/skills/bundled/filesystem/workspace_file_operator/SKILL.md +22 -0
  130. package/packages/core/src/skills/bundled/office/office_document_manager/SKILL.md +262 -0
  131. package/packages/core/src/skills/bundled/search_knowledge/capability_discovery/SKILL.md +75 -0
  132. package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +120 -0
  133. package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +109 -0
  134. package/packages/core/src/skills/bundled/web/web_monitor/SKILL.md +127 -0
  135. package/packages/core/src/skills/bundled/web/web_research/SKILL.md +119 -0
  136. package/packages/core/src/skills/bundled-data.generated.ts +731 -2678
  137. package/packages/core/src/skills/skills.test.ts +52 -11
  138. package/packages/core/src/{harness → storage}/boot-id.ts +5 -2
  139. package/packages/core/src/storage/bootstrap.ts +151 -0
  140. package/packages/core/src/storage/causal-events.ts +84 -0
  141. package/packages/core/src/storage/collections.ts +680 -0
  142. package/packages/core/src/storage/crypto.ts +205 -74
  143. package/packages/core/src/{harness/db-helpers.ts → storage/hive.ts} +63 -7
  144. package/packages/core/src/storage/hivedb.ts +61 -0
  145. package/packages/core/src/storage/index.ts +111 -18
  146. package/packages/core/src/storage/model-id.ts +53 -0
  147. package/packages/core/src/storage/onboarding.ts +540 -972
  148. package/packages/core/src/storage/reconcile.ts +238 -0
  149. package/packages/core/src/storage/seed.ts +572 -406
  150. package/packages/core/src/storage/usage.ts +285 -225
  151. package/packages/core/src/storage/user-email.ts +11 -0
  152. package/packages/core/src/swarm/AgentExecutor.ts +1 -1
  153. package/packages/core/src/swarm/EventBridge.ts +1 -1
  154. package/packages/core/src/swarm/index.ts +12 -9
  155. package/packages/core/src/tool-runtime/index.ts +146 -23
  156. package/packages/core/src/tool-runtime/tool-worker.ts +2 -2
  157. package/packages/core/src/tool-runtime/worker-tools.ts +27 -0
  158. package/packages/core/src/{canvas/a2ui-tools.ts → tools/a2ui/index.ts} +17 -8
  159. package/packages/core/src/tools/agents/get-available-models.ts +36 -54
  160. package/packages/core/src/tools/agents/index.ts +784 -292
  161. package/packages/core/src/tools/api/api-request.test.ts +164 -0
  162. package/packages/core/src/tools/api/api-request.ts +174 -0
  163. package/packages/core/src/tools/api/index.ts +16 -0
  164. package/packages/core/src/tools/cli/index.ts +4 -0
  165. package/packages/core/src/tools/core/index.ts +281 -112
  166. package/packages/core/src/tools/cron/index.ts +121 -124
  167. package/packages/core/src/tools/index.ts +63 -78
  168. package/packages/core/src/tools/office/office-escribir-xlsx.ts +3 -1
  169. package/packages/core/src/tools/types.ts +3 -1
  170. package/packages/core/src/tools/web/artifact-inspect.ts +23 -0
  171. package/packages/core/src/tools/web/browser-backend.ts +129 -0
  172. package/packages/core/src/tools/web/browser-screenshot.ts +26 -5
  173. package/packages/core/src/tools/web/browser-service.ts +80 -35
  174. package/packages/core/src/tools/web/browser-type.ts +3 -8
  175. package/packages/core/src/tools/web/index.ts +4 -4
  176. package/packages/core/src/tools/web/webview-backend.ts +412 -0
  177. package/packages/core/src/voice/index.ts +89 -63
  178. package/packages/core/src/workers/agent.worker.ts +2 -2
  179. package/packages/core/src/workers/workers.test.ts +3 -10
  180. package/scripts/bump-version.ts +248 -0
  181. package/scripts/generate-skill-bundle.ts +108 -0
  182. package/test/acceptance-checks.test.ts +403 -0
  183. package/test/agent-loop-terminal-synthesis.test.ts +32 -0
  184. package/test/browser-backend.test.ts +308 -0
  185. package/test/catalog-agents-stay-enabled.test.ts +117 -0
  186. package/test/causal-events.test.ts +117 -0
  187. package/test/compaction.test.ts +105 -0
  188. package/test/context-compiler.test.ts +269 -0
  189. package/test/curator.test.ts +130 -0
  190. package/test/durable-queue.test.ts +114 -0
  191. package/test/harness-barrel.test.ts +64 -0
  192. package/test/hive-helpers.test.ts +130 -0
  193. package/test/hivedb-search.test.ts +189 -0
  194. package/test/internal-turns.test.ts +166 -0
  195. package/test/job-idempotency.test.ts +68 -0
  196. package/test/job-retry-backoff.test.ts +184 -0
  197. package/test/job-store.test.ts +381 -0
  198. package/test/llm-retry.test.ts +97 -0
  199. package/test/memory-perf.test.ts +774 -0
  200. package/test/minimal-loadout.test.ts +78 -0
  201. package/test/model-catalog.test.ts +105 -0
  202. package/test/preload.ts +12 -0
  203. package/test/reflector.test.ts +320 -0
  204. package/test/retention-cap.test.ts +91 -0
  205. package/test/retired-capabilities-pruned.test.ts +192 -0
  206. package/test/run-store.test.ts +355 -0
  207. package/test/scratchpad.test.ts +74 -0
  208. package/test/secrets-durability.test.ts +119 -0
  209. package/test/seed-model-reseed.test.ts +155 -0
  210. package/test/setup-agent-seed.test.ts +264 -0
  211. package/test/tool-inventory.test.ts +65 -0
  212. package/test/tool-runtime.test.ts +258 -0
  213. package/test/tool-selector-runtime-tools.test.ts +117 -0
  214. package/test/toon.test.ts +429 -0
  215. package/tsconfig.json +2 -0
  216. package/packages/core/src/ace/Curator.ts +0 -158
  217. package/packages/core/src/ace/Reflector.ts +0 -200
  218. package/packages/core/src/ace/index.ts +0 -4
  219. package/packages/core/src/agent/AgentRunner.ts +0 -711
  220. package/packages/core/src/agent/ContextCompiler.ts +0 -567
  221. package/packages/core/src/agent/ContextGuard.ts +0 -91
  222. package/packages/core/src/agent/ConversationStore.ts +0 -254
  223. package/packages/core/src/agent/Hooks.ts +0 -166
  224. package/packages/core/src/agent/StuckLoop.ts +0 -133
  225. package/packages/core/src/agent/providers/LLMClient.ts +0 -149
  226. package/packages/core/src/agent/providers/anthropic.ts +0 -212
  227. package/packages/core/src/agent/providers/openai-compat.ts +0 -231
  228. package/packages/core/src/agent/selectors/PlaybookSelector.ts +0 -121
  229. package/packages/core/src/agent/selectors/SkillSelector.ts +0 -322
  230. package/packages/core/src/agent/selectors/index.ts +0 -6
  231. package/packages/core/src/auth/auth.ts +0 -121
  232. package/packages/core/src/auth/index.ts +0 -1
  233. package/packages/core/src/canvas/CanvasManager.ts +0 -390
  234. package/packages/core/src/canvas/canvas-tools.ts +0 -448
  235. package/packages/core/src/harness/collections.ts +0 -98
  236. package/packages/core/src/harness/goal-verifier.ts +0 -141
  237. package/packages/core/src/harness/harness.test.ts +0 -236
  238. package/packages/core/src/harness/reconcile.ts +0 -149
  239. package/packages/core/src/mcp/MCPToolAdapter.ts +0 -176
  240. package/packages/core/src/multimodal/VisionService.ts +0 -293
  241. package/packages/core/src/scheduler/dag/AgentExecutor.ts +0 -53
  242. package/packages/core/src/scheduler/dag/DAGScheduler.ts +0 -250
  243. package/packages/core/src/scheduler/dag/EventBridge.ts +0 -122
  244. package/packages/core/src/scheduler/dag/TaskGraph.ts +0 -192
  245. package/packages/core/src/scheduler/dag/TaskNode.ts +0 -97
  246. package/packages/core/src/scheduler/dag/TaskResult.ts +0 -22
  247. package/packages/core/src/scheduler/dag/errors.ts +0 -37
  248. package/packages/core/src/scheduler/dag/index.ts +0 -26
  249. package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +0 -97
  250. package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +0 -21
  251. package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +0 -46
  252. package/packages/core/src/storage/HiveDBStorage.ts +0 -64
  253. package/packages/core/src/storage/SQLiteStorage.ts +0 -414
  254. package/packages/core/src/storage/hiveSeed.ts +0 -308
  255. package/packages/core/src/storage/hiveStorage.test.ts +0 -38
  256. package/packages/core/src/storage/schema.ts +0 -689
  257. package/packages/core/src/storage/storage.test.ts +0 -37
  258. package/packages/core/src/swarm/AgentBus.ts +0 -460
  259. package/packages/core/src/swarm/EventBus.ts +0 -169
  260. package/packages/core/src/swarm/WorkerPool.ts +0 -236
  261. package/packages/core/src/tools/bridge-events.ts +0 -26
  262. package/packages/core/src/tools/canvas/index.ts +0 -375
  263. package/packages/core/src/tools/codebridge/index.ts +0 -342
  264. package/packages/core/src/tools/meeting/index.ts +0 -353
  265. package/packages/core/src/tools/projects/index.ts +0 -37
  266. package/packages/core/src/tools/projects/project-create.ts +0 -94
  267. package/packages/core/src/tools/projects/project-done.ts +0 -66
  268. package/packages/core/src/tools/projects/project-fail.ts +0 -66
  269. package/packages/core/src/tools/projects/project-list.ts +0 -96
  270. package/packages/core/src/tools/projects/project-update.ts +0 -72
  271. package/packages/core/src/tools/projects/task-create.ts +0 -68
  272. package/packages/core/src/tools/projects/task-evaluate.ts +0 -93
  273. package/packages/core/src/tools/projects/task-update.ts +0 -93
  274. package/packages/core/src/tools/voice/index.ts +0 -104
  275. package/packages/core/src/tools/web/api-request.test.ts +0 -170
  276. package/packages/core/src/tools/web/api-request.ts +0 -239
  277. package/test/setup-db.ts +0 -216
  278. /package/packages/core/src/agent/{NativeTools.ts → native-tools.ts} +0 -0
@@ -1,322 +0,0 @@
1
- /**
2
- * HiveDB-based Dynamic Skill Selector Module
3
- *
4
- * Context Compiler Level 4 - Intelligent Skill Selection
5
- *
6
- * Uses HiveDB hybrid search (BM25 + optional vector) over the skills index.
7
- */
8
-
9
- import { getHiveDB } from "../../storage/HiveDBStorage.ts"
10
- import { logger } from "../../utils/logger.ts"
11
- import type { HiveSkillDoc } from "../../storage/hiveSeed.ts"
12
- import type { IndexDoc } from "@johpaz/hive-db"
13
-
14
- const log = logger.child("skill-selector")
15
-
16
- // ─── Minimal Skill Set ─────────────────────────────────────────────────────────
17
-
18
- export const MINIMAL_SKILL_NAMES = new Set([
19
- "memory_manager",
20
- "canvas_report",
21
- "task_orchestrator",
22
- ])
23
-
24
- // ─── Types ───────────────────────────────────────────────────────────────────────
25
-
26
- export interface SkillDescriptor {
27
- id: string
28
- name: string
29
- description: string
30
- category: string
31
- tools: string
32
- triggers: string
33
- preferred_agents: string
34
- body: string
35
- version: string
36
- version_num: number
37
- active: number
38
- }
39
-
40
- export interface SelectedSkill {
41
- id: string
42
- name: string
43
- score: number
44
- category: string
45
- description: string
46
- body: string
47
- }
48
-
49
- export interface SkillSelectorResult {
50
- skills: SkillDescriptor[]
51
- selected: SelectedSkill[]
52
- reasoning: string
53
- timingMs: number
54
- }
55
-
56
- // ─── Configuration ─────────────────────────────────────────────────────────
57
-
58
- const MAX_SKILLS_PER_TURN = 4
59
-
60
- const MIN_RELEVANCE_THRESHOLD = 0.5
61
-
62
- const STOPWORDS = new Set([
63
- "que", "con", "para", "por", "una", "uno", "los", "las", "del",
64
- "como", "esta", "esto", "ese", "eso", "the", "and", "for",
65
- "with", "this", "that", "have", "will", "also", "de", "en",
66
- "el", "la", "se", "su", "sus", "al", "es", "son", "pero",
67
- "más", "mas", "ya", "yo", "tu", "te", "ti", "mi", "me",
68
- "hola", "hi", "hello", "hey", "gracias", "thank", "please",
69
- "ok", "okay", "yes", "si", "no", "bien", "good", "great",
70
- "puedes", "necesito", "quiero", "podés", "necesitás", "querés",
71
- ])
72
-
73
- const CONVERSATIONAL_PATTERNS = [
74
- /^(hola|hi|hello|hey|buenos? días?|buenas? noches?|qué tal|howdy)/i,
75
- /^(gracias|thank you|thanks|muchas gracias|muchas thanks)/i,
76
- /^(cómo estás?|how are you?|qué流水|you doing|qué cuentas)/i,
77
- /^(sí|yes|ok|okay|de acuerdo|perfecto|claro|por supuesto)/i,
78
- /^(adiós|bye|nos vemos|see you|later|chau)/i,
79
- /^(entiendo|understand|i see|ya veo|got it)/i,
80
- /^(bien|good|great|excelente|awesome|perfect)/i,
81
- /^(?:\?|¿)$/,
82
- ]
83
-
84
- // ─── Helper Functions ───────────────────────────────────────────────────────
85
-
86
- function isConversational(message: string): boolean {
87
- const trimmed = message.trim()
88
- if (trimmed.length < 2) return true
89
- for (const pattern of CONVERSATIONAL_PATTERNS) {
90
- if (pattern.test(trimmed)) {
91
- log.debug(`[skill-selector] Message matched conversational pattern: ${pattern}`)
92
- return true
93
- }
94
- }
95
- const words = trimmed.toLowerCase().split(/\s+/)
96
- const meaningfulWords = words.filter(w => w.length > 2 && !STOPWORDS.has(w))
97
- if (meaningfulWords.length === 0) {
98
- log.debug(`[skill-selector] All words are stopwords - conversational`)
99
- return true
100
- }
101
- return false
102
- }
103
-
104
- function buildFTSQuery(message: string): string {
105
- const words = message
106
- .toLowerCase()
107
- .replace(/[^\p{L}\p{N}\s]/gu, " ")
108
- .split(/\s+/)
109
- .filter((w) => w.length > 2 && !STOPWORDS.has(w))
110
- .slice(0, 8)
111
-
112
- if (words.length === 0) return ""
113
- return words.join(" ")
114
- }
115
-
116
- function matchTriggers(message: string, triggers: string[]): boolean {
117
- if (!triggers || triggers.length === 0) return false
118
- const lowerMessage = message.toLowerCase()
119
- return triggers.some(trigger =>
120
- lowerMessage.includes(trigger.toLowerCase())
121
- )
122
- }
123
-
124
- function toSkillDescriptor(doc: HiveSkillDoc): SkillDescriptor {
125
- return {
126
- id: doc.id,
127
- name: doc.name,
128
- description: doc.description,
129
- category: doc.category,
130
- tools: Array.isArray(doc.tools) ? doc.tools.join(",") : String(doc.tools ?? ""),
131
- triggers: Array.isArray(doc.triggers) ? doc.triggers.join(",") : String(doc.triggers ?? ""),
132
- preferred_agents: Array.isArray(doc.preferredAgents) ? doc.preferredAgents.join(",") : String(doc.preferredAgents ?? ""),
133
- body: doc.body,
134
- version: doc.version,
135
- version_num: doc.versionNum,
136
- active: doc.active ? 1 : 0,
137
- }
138
- }
139
-
140
- // ─── Main Selection Function ─────────────────────────────────────────────────
141
-
142
- export async function selectSkills(userMessage: string): Promise<SkillDescriptor[]> {
143
- const startTime = performance.now()
144
-
145
- log.debug(`[skill-selector] Processing user message: "${userMessage.substring(0, 100)}"`)
146
-
147
- if (isConversational(userMessage)) {
148
- log.debug(`[skill-selector] Conversational message, returning empty array`)
149
- return []
150
- }
151
-
152
- const db = await getHiveDB()
153
- const skillsCol = db.collection<HiveSkillDoc>("skills")
154
- const entries = await skillsCol.scan()
155
- const allSkills = entries.map(e => e.doc).filter(s => s.active)
156
-
157
- for (const skill of allSkills) {
158
- if (matchTriggers(userMessage, skill.triggers)) {
159
- log.info(`[skill-selector] Trigger match found: ${skill.name}`)
160
- return [toSkillDescriptor(skill)]
161
- }
162
- }
163
-
164
- const ftsQuery = buildFTSQuery(userMessage)
165
- if (!ftsQuery) {
166
- log.debug(`[skill-selector] No valid query terms, returning empty array`)
167
- return []
168
- }
169
-
170
- log.debug(`[skill-selector] Search query: "${ftsQuery}"`)
171
-
172
- const hits = await db.queryHybrid({
173
- text: ftsQuery,
174
- k: 20,
175
- boosts: { name: 4.0, body: 5.0, tags: 3.0 },
176
- })
177
-
178
- if (hits.length === 0) {
179
- log.debug(`[skill-selector] No index matches, returning empty array`)
180
- return []
181
- }
182
-
183
- log.info(`[skill-selector] Raw scores: ${hits.slice(0, 10).map(r => `id=${r.id}, score=${r.score.toFixed(2)}`).join(", ")}`)
184
-
185
- const relevantResults = hits.filter(r => r.score >= MIN_RELEVANCE_THRESHOLD)
186
- if (relevantResults.length === 0) {
187
- log.debug(`[skill-selector] All results below threshold ${MIN_RELEVANCE_THRESHOLD}, returning empty`)
188
- return []
189
- }
190
-
191
- const skillMap = new Map(allSkills.map(s => [s.id, s]))
192
- const scoredSkills: SelectedSkill[] = []
193
-
194
- for (const hit of relevantResults) {
195
- const skill = skillMap.get(hit.id)
196
- if (skill) {
197
- scoredSkills.push({
198
- id: skill.id,
199
- name: skill.name,
200
- score: hit.score,
201
- category: skill.category,
202
- description: skill.description || "",
203
- body: skill.body,
204
- })
205
- }
206
- }
207
-
208
- const topSkills = scoredSkills.slice(0, MAX_SKILLS_PER_TURN)
209
- const result = topSkills.map(t => toSkillDescriptor(skillMap.get(t.id)!)).filter(Boolean)
210
-
211
- const timing = performance.now() - startTime
212
-
213
- if (result.length > 0) {
214
- log.info(`[skill-selector] Selected ${result.length} skills in ${timing.toFixed(2)}ms:`,
215
- result.map(s => ({ name: s.name, category: s.category })))
216
- } else {
217
- log.debug(`[skill-selector] No skills selected, returning empty array in ${timing.toFixed(2)}ms`)
218
- }
219
-
220
- return result
221
- }
222
-
223
- // ─── Minimal Skills Loader ───────────────────────────────────────────────────
224
-
225
- export async function getMinimalSkills(): Promise<SkillDescriptor[]> {
226
- try {
227
- const db = await getHiveDB()
228
- const skillsCol = db.collection<HiveSkillDoc>("skills")
229
- const entries = await skillsCol.scan()
230
- const skills = entries
231
- .map(e => e.doc)
232
- .filter(s => s.active && MINIMAL_SKILL_NAMES.has(s.name))
233
- .map(toSkillDescriptor)
234
-
235
- log.info(`[skill-selector] Loaded ${skills.length} minimal skills: ${skills.map(s => s.name).join(", ")}`)
236
- return skills
237
- } catch (err) {
238
- log.error(`[skill-selector] Failed to load minimal skills:`, err)
239
- return []
240
- }
241
- }
242
-
243
- // ─── Sync Skills to Index ───────────────────────────────────────────────────
244
-
245
- export async function syncSkillsToFTS(): Promise<void> {
246
- const db = await getHiveDB()
247
-
248
- try {
249
- const skillsCol = db.collection<HiveSkillDoc>("skills")
250
- const entries = await skillsCol.scan()
251
- const dbSkills = entries.map(e => e.doc).filter(s => s.active)
252
-
253
- if (dbSkills.length === 0) {
254
- log.debug(`[skill-selector] No skills found in DB to sync`)
255
- return
256
- }
257
-
258
- const docs: IndexDoc[] = dbSkills.map(skill => ({
259
- id: skill.id,
260
- name: skill.name,
261
- body: `${skill.description || ""} ${skill.body || ""}`,
262
- tags: [skill.category, ...skill.tools, ...skill.triggers].join(" "),
263
- filters: [{ field: "type", value: "skill" }],
264
- }))
265
-
266
- await db.upsertBatch(docs)
267
-
268
- log.info(`[skill-selector] Atomic sync complete: ${dbSkills.length} skills indexed in HiveDB`)
269
-
270
- } catch (err) {
271
- log.error(`[skill-selector] Transactional sync failed:`, err)
272
- throw err
273
- }
274
- }
275
-
276
- // ─── Initialization ───────────────────────────────────────────────────────
277
-
278
- export function initializeSkillSelector(): void {
279
- log.info(`[skill-selector] Initializing skill selector (deprecated - sync is done in seed)`)
280
- }
281
-
282
- // ─── Debug/Test Helpers ─────────────────────────────────────────────────────
283
-
284
- export async function getAllSkillsFromDB(): Promise<SkillDescriptor[]> {
285
- try {
286
- const db = await getHiveDB()
287
- const skillsCol = db.collection<HiveSkillDoc>("skills")
288
- const entries = await skillsCol.scan()
289
- return entries.map(e => toSkillDescriptor(e.doc)).filter(s => s.active)
290
- } catch (err) {
291
- log.error(`[skill-selector] Failed to fetch skills:`, err)
292
- return []
293
- }
294
- }
295
-
296
- export async function getSkillByName(name: string): Promise<SkillDescriptor | undefined> {
297
- try {
298
- const db = await getHiveDB()
299
- const skillsCol = db.collection<HiveSkillDoc>("skills")
300
- const entries = await skillsCol.scan()
301
- const skill = entries.map(e => e.doc).find(s => s.name === name && s.active)
302
- return skill ? toSkillDescriptor(skill) : undefined
303
- } catch (err) {
304
- log.error(`[skill-selector] Failed to fetch skill by name:`, err)
305
- return undefined
306
- }
307
- }
308
-
309
- export async function getSkillsByCategory(category: string): Promise<SkillDescriptor[]> {
310
- try {
311
- const db = await getHiveDB()
312
- const skillsCol = db.collection<HiveSkillDoc>("skills")
313
- const entries = await skillsCol.scan()
314
- return entries
315
- .map(e => e.doc)
316
- .filter(s => s.active && s.category === category)
317
- .map(toSkillDescriptor)
318
- } catch (err) {
319
- log.error(`[skill-selector] Failed to fetch skills by category:`, err)
320
- return []
321
- }
322
- }
@@ -1,6 +0,0 @@
1
- export type { ToolDescriptor, SelectedTool, ToolSelectorResult } from "./ToolSelector.ts";
2
- export { MIN_RELEVANCE_THRESHOLD, CORE_TOOL_CATALOG, selectTools, syncToolCatalogToFTS, mcpToolFullName, initializeToolSelector, getAllTools, getToolByName, getToolsByCategory } from "./ToolSelector.ts";
3
- export type { SkillDescriptor, SelectedSkill, SkillSelectorResult } from "./SkillSelector.ts";
4
- export { MINIMAL_SKILL_NAMES, selectSkills, getMinimalSkills, syncSkillsToFTS, initializeSkillSelector, getAllSkillsFromDB, getSkillByName, getSkillsByCategory } from "./SkillSelector.ts";
5
- export type { PlaybookRule } from "./PlaybookSelector.ts";
6
- export { selectPlaybookRules, syncPlaybookToFTS } from "./PlaybookSelector.ts";
@@ -1,121 +0,0 @@
1
- import jwt from "jsonwebtoken";
2
- import { hashString } from "../utils/crypto.ts";
3
- import { getHiveDB } from "../storage/HiveDBStorage.ts";
4
-
5
- const JWT_SECRET = process.env.JWT_SECRET || "hive-default-jwt-secret-change-in-production";
6
- const ACCESS_TOKEN_EXPIRY = "15m";
7
- const REFRESH_TOKEN_EXPIRY = "7d";
8
- const REFRESH_TOKEN_EXPIRY_SECONDS = 7 * 24 * 60 * 60;
9
-
10
- interface AuthTokens {
11
- accessToken: string;
12
- refreshToken: string;
13
- expiresIn: number;
14
- tokenType: "Bearer";
15
- }
16
-
17
- interface JwtPayload {
18
- userId: string;
19
- type: "access" | "refresh";
20
- }
21
-
22
- interface RefreshTokenDoc {
23
- userId: string;
24
- tokenHash: string;
25
- expiresAt: number;
26
- revoked: boolean;
27
- }
28
-
29
- function tokensCollection() {
30
- return getHiveDB().then(db => db.collection<RefreshTokenDoc>("refresh_tokens"));
31
- }
32
-
33
- export async function generateTokens(userId: string): Promise<AuthTokens> {
34
- const accessToken = jwt.sign({ userId, type: "access" } satisfies JwtPayload, JWT_SECRET, {
35
- expiresIn: ACCESS_TOKEN_EXPIRY,
36
- });
37
-
38
- const refreshToken = jwt.sign({ userId, type: "refresh" } satisfies JwtPayload, JWT_SECRET, {
39
- expiresIn: REFRESH_TOKEN_EXPIRY,
40
- });
41
-
42
- const refreshTokenHash = hashString(refreshToken);
43
- const expiresAt = Math.floor(Date.now() / 1000) + REFRESH_TOKEN_EXPIRY_SECONDS;
44
-
45
- const col = await tokensCollection();
46
- await col.put(refreshTokenHash, { userId, tokenHash: refreshTokenHash, expiresAt, revoked: false });
47
-
48
- return {
49
- accessToken,
50
- refreshToken,
51
- expiresIn: 15 * 60,
52
- tokenType: "Bearer",
53
- };
54
- }
55
-
56
- export async function refreshAccessToken(refreshToken: string): Promise<AuthTokens> {
57
- let payload: JwtPayload;
58
- try {
59
- payload = jwt.verify(refreshToken, JWT_SECRET) as JwtPayload;
60
- } catch {
61
- throw new Error("Invalid or expired refresh token");
62
- }
63
-
64
- if (payload.type !== "refresh") {
65
- throw new Error("Invalid token type");
66
- }
67
-
68
- const refreshTokenHash = hashString(refreshToken);
69
- const col = await tokensCollection();
70
- const entry = await col.get(refreshTokenHash);
71
-
72
- if (!entry) {
73
- throw new Error("Refresh token not found");
74
- }
75
-
76
- const tokenRow = entry.doc;
77
-
78
- if (tokenRow.revoked) {
79
- throw new Error("Refresh token has been revoked");
80
- }
81
-
82
- if (tokenRow.expiresAt < Math.floor(Date.now() / 1000)) {
83
- await col.delete(refreshTokenHash);
84
- throw new Error("Refresh token has expired");
85
- }
86
-
87
- await col.delete(refreshTokenHash);
88
-
89
- return generateTokens(payload.userId);
90
- }
91
-
92
- export async function validateAccessToken(token: string): Promise<{ userId: string } | null> {
93
- try {
94
- const payload = jwt.verify(token, JWT_SECRET) as JwtPayload;
95
- if (payload.type !== "access") {
96
- return null;
97
- }
98
- return { userId: payload.userId };
99
- } catch {
100
- return null;
101
- }
102
- }
103
-
104
- export async function revokeRefreshToken(refreshToken: string): Promise<void> {
105
- const refreshTokenHash = hashString(refreshToken);
106
- const col = await tokensCollection();
107
- const entry = await col.get(refreshTokenHash);
108
- if (entry) {
109
- await col.put(refreshTokenHash, { ...entry.doc, revoked: true });
110
- }
111
- }
112
-
113
- export async function revokeAllUserTokens(userId: string): Promise<void> {
114
- const col = await tokensCollection();
115
- const entries = await col.scan();
116
- for (const e of entries) {
117
- if (e.doc.userId === userId && !e.doc.revoked) {
118
- await col.put(e.id, { ...e.doc, revoked: true });
119
- }
120
- }
121
- }
@@ -1 +0,0 @@
1
- export * from "./auth.ts";