@johpaz/hive-sdk 0.1.4 → 0.1.5

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 (272) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.md +78 -23
  3. package/bunfig.toml +4 -2
  4. package/docs/API-AGENTS.md +78 -27
  5. package/docs/API-CONTEXT-COMPILER.md +31 -34
  6. package/docs/API-TOOLS-SKILLS-CHANNELS.md +58 -22
  7. package/docs/HIVE-HARNESS.md +1 -1
  8. package/docs/INDEX.md +4 -4
  9. package/docs/TEMPLATE-HIVE-APP.md +10 -10
  10. package/package.json +9 -4
  11. package/packages/cli/package.json +2 -2
  12. package/packages/cli/src/commands/create-app.test.ts +36 -7
  13. package/packages/cli/src/commands/init.ts +3 -3
  14. package/packages/cli/src/commands/run.ts +1 -1
  15. package/packages/cli/src/commands/test.ts +37 -25
  16. package/packages/cli/src/commands/trace.ts +30 -28
  17. package/packages/cli/templates/hive-app/.env.example +10 -2
  18. package/packages/cli/templates/hive-app/README.md +103 -0
  19. package/packages/cli/templates/hive-app/hive.config.ts +9 -3
  20. package/packages/cli/templates/hive-app/src/agents/coordinator.ts +8 -1
  21. package/packages/cli/templates/hive-app/src/main.ts +12 -19
  22. package/packages/core/package.json +5 -4
  23. package/packages/core/src/agent/acceptance-checks.ts +166 -0
  24. package/packages/core/src/agent/agent-catalog.ts +348 -0
  25. package/packages/core/src/agent/agent-loop.ts +1373 -0
  26. package/packages/core/src/agent/capability-search.ts +186 -0
  27. package/packages/core/src/agent/catalog-selector.ts +103 -0
  28. package/packages/core/src/agent/{Compaction.ts → compaction.ts} +86 -63
  29. package/packages/core/src/agent/context-compiler.ts +689 -0
  30. package/packages/core/src/agent/conversation-store.ts +381 -0
  31. package/packages/core/src/agent/curator.ts +276 -0
  32. package/packages/core/src/agent/delegation-runtime.ts +241 -0
  33. package/packages/core/src/agent/goal-runner.ts +323 -0
  34. package/packages/core/src/agent/index.ts +17 -12
  35. package/packages/core/src/agent/llm-client.ts +266 -0
  36. package/packages/core/src/agent/llm-providers/anthropic.ts +264 -0
  37. package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
  38. package/packages/core/src/agent/{providers → llm-providers}/gemini.ts +98 -60
  39. package/packages/core/src/agent/llm-providers/groq.ts +5 -0
  40. package/packages/core/src/agent/llm-providers/hiveagents.ts +253 -0
  41. package/packages/core/src/agent/{providers → llm-providers}/interface.ts +73 -13
  42. package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
  43. package/packages/core/src/agent/llm-providers/minimax.ts +13 -0
  44. package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
  45. package/packages/core/src/agent/llm-providers/modelscope.ts +5 -0
  46. package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
  47. package/packages/core/src/agent/{providers → llm-providers}/ollama.ts +31 -5
  48. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +418 -0
  49. package/packages/core/src/agent/llm-providers/openai.ts +5 -0
  50. package/packages/core/src/agent/llm-providers/opencode-go.ts +9 -0
  51. package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
  52. package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
  53. package/packages/core/src/agent/llm-providers/z-ai.ts +5 -0
  54. package/packages/core/src/agent/minimal-loadout.ts +47 -0
  55. package/packages/core/src/agent/playbook-selector.ts +119 -0
  56. package/packages/core/src/agent/{PromptBuilder.ts → prompt-builder.ts} +21 -22
  57. package/packages/core/src/{harness → agent}/proof-packet.ts +16 -21
  58. package/packages/core/src/agent/providers/index.ts +35 -16
  59. package/packages/core/src/agent/reflector.ts +320 -0
  60. package/packages/core/src/agent/routing-intent.ts +22 -0
  61. package/packages/core/src/{harness → agent}/run-epoch.ts +4 -3
  62. package/packages/core/src/{harness → agent}/run-store.ts +142 -81
  63. package/packages/core/src/agent/{Service.ts → service.ts} +37 -26
  64. package/packages/core/src/agent/skill-selector.ts +374 -0
  65. package/packages/core/src/agent/stuck-loop.ts +209 -0
  66. package/packages/core/src/agent/{selectors/ToolSelector.ts → tool-selector.ts} +188 -178
  67. package/packages/core/src/{ace/Tracer.ts → agent/tracer.ts} +37 -27
  68. package/packages/core/src/api/createAgent.test.ts +139 -27
  69. package/packages/core/src/api/createAgent.ts +232 -44
  70. package/packages/core/src/artifacts/store.ts +162 -0
  71. package/packages/core/src/canvas/canvas-manager.ts +161 -0
  72. package/packages/core/src/canvas/canvas.test.ts +8 -4
  73. package/packages/core/src/canvas/emitter.ts +131 -80
  74. package/packages/core/src/canvas/index.ts +1 -3
  75. package/packages/core/src/channels/base.ts +9 -1
  76. package/packages/core/src/channels/discord.ts +5 -4
  77. package/packages/core/src/channels/manager.ts +122 -30
  78. package/packages/core/src/channels/slack.ts +5 -4
  79. package/packages/core/src/channels/telegram.ts +36 -6
  80. package/packages/core/src/channels/webchat.ts +11 -10
  81. package/packages/core/src/channels/whatsapp.ts +23 -7
  82. package/packages/core/src/config/index.ts +13 -2
  83. package/packages/core/src/config/loader.ts +71 -29
  84. package/packages/core/src/ethics/EthicsGuard.test.ts +90 -36
  85. package/packages/core/src/ethics/EthicsGuard.ts +51 -47
  86. package/packages/core/src/events/agent-bus.ts +44 -68
  87. package/packages/core/src/events/channel-narration.ts +150 -0
  88. package/packages/core/src/events/narration.ts +82 -0
  89. package/packages/core/src/events/tool-narration.ts +62 -0
  90. package/packages/core/src/gateway/delegation-groups.ts +258 -0
  91. package/packages/core/src/{harness → gateway}/durable-queue.ts +102 -42
  92. package/packages/core/src/{harness → gateway}/job-store.ts +85 -48
  93. package/packages/core/src/gateway/lane-queue.ts +173 -0
  94. package/packages/core/src/gateway/notification-inbox.ts +57 -0
  95. package/packages/core/src/gateway/server.ts +1 -1
  96. package/packages/core/src/harness/index.ts +46 -27
  97. package/packages/core/src/index.ts +33 -27
  98. package/packages/core/src/mcp/hot-reload.ts +32 -23
  99. package/packages/core/src/mcp/index.ts +6 -3
  100. package/packages/core/src/mcp/singleton.ts +1 -4
  101. package/packages/core/src/mcp/tool-sync.ts +138 -0
  102. package/packages/core/src/memory/Scratchpad.test.ts +39 -20
  103. package/packages/core/src/memory/Scratchpad.ts +27 -34
  104. package/packages/core/src/multimodal/vision-service.ts +44 -38
  105. package/packages/core/src/resilience/retry.ts +95 -0
  106. package/packages/core/src/scheduler/CronScheduler.ts +334 -287
  107. package/packages/core/src/scheduler/index.ts +9 -7
  108. package/packages/core/src/scheduler/integration.ts +46 -26
  109. package/packages/core/src/scheduler/scheduler.test.ts +9 -13
  110. package/packages/core/src/scheduler/types.ts +7 -2
  111. package/packages/core/src/security/Pairing.ts +1 -1
  112. package/packages/core/src/skills/bundled/a2ui/a2ui_dashboard/SKILL.md +176 -0
  113. package/packages/core/src/skills/bundled/a2ui/a2ui_form/SKILL.md +202 -0
  114. package/packages/core/src/skills/bundled/a2ui/a2ui_interactive/SKILL.md +206 -0
  115. package/packages/core/src/skills/bundled/agents/agent_spawner/SKILL.md +173 -0
  116. package/packages/core/src/skills/bundled/agents/memory_manager/SKILL.md +143 -0
  117. package/packages/core/src/skills/bundled/agents/research_and_remember/SKILL.md +139 -0
  118. package/packages/core/src/skills/bundled/agents/task_orchestrator/SKILL.md +98 -0
  119. package/packages/core/src/skills/bundled/api/api_client/SKILL.md +132 -0
  120. package/packages/core/src/skills/bundled/cli/cli_pipeline/SKILL.md +135 -0
  121. package/packages/core/src/skills/bundled/cli/cli_safe_exec/SKILL.md +125 -0
  122. package/packages/core/src/skills/bundled/cli/software_engineering/SKILL.md +23 -0
  123. package/packages/core/src/skills/bundled/cron_manager/SKILL.md +188 -0
  124. package/packages/core/src/skills/bundled/cron_reminder/SKILL.md +112 -0
  125. package/packages/core/src/skills/bundled/filesystem/file_manager/SKILL.md +118 -0
  126. package/packages/core/src/skills/bundled/filesystem/file_read_and_summarize/SKILL.md +109 -0
  127. package/packages/core/src/skills/bundled/filesystem/file_writer/SKILL.md +129 -0
  128. package/packages/core/src/skills/bundled/filesystem/workspace_file_operator/SKILL.md +22 -0
  129. package/packages/core/src/skills/bundled/office/office_document_manager/SKILL.md +262 -0
  130. package/packages/core/src/skills/bundled/search_knowledge/capability_discovery/SKILL.md +75 -0
  131. package/packages/core/src/skills/bundled/web/browser_automate/SKILL.md +120 -0
  132. package/packages/core/src/skills/bundled/web/browser_scrape/SKILL.md +109 -0
  133. package/packages/core/src/skills/bundled/web/web_monitor/SKILL.md +127 -0
  134. package/packages/core/src/skills/bundled/web/web_research/SKILL.md +119 -0
  135. package/packages/core/src/skills/bundled-data.generated.ts +731 -2678
  136. package/packages/core/src/skills/skills.test.ts +52 -11
  137. package/packages/core/src/{harness → storage}/boot-id.ts +5 -2
  138. package/packages/core/src/storage/bootstrap.ts +151 -0
  139. package/packages/core/src/storage/causal-events.ts +84 -0
  140. package/packages/core/src/storage/collections.ts +680 -0
  141. package/packages/core/src/storage/crypto.ts +205 -74
  142. package/packages/core/src/{harness/db-helpers.ts → storage/hive.ts} +63 -7
  143. package/packages/core/src/storage/hivedb.ts +61 -0
  144. package/packages/core/src/storage/index.ts +111 -18
  145. package/packages/core/src/storage/model-id.ts +53 -0
  146. package/packages/core/src/storage/onboarding.ts +540 -972
  147. package/packages/core/src/storage/reconcile.ts +238 -0
  148. package/packages/core/src/storage/seed.ts +572 -406
  149. package/packages/core/src/storage/usage.ts +285 -225
  150. package/packages/core/src/storage/user-email.ts +11 -0
  151. package/packages/core/src/swarm/AgentExecutor.ts +1 -1
  152. package/packages/core/src/swarm/EventBridge.ts +1 -1
  153. package/packages/core/src/swarm/index.ts +12 -9
  154. package/packages/core/src/tool-runtime/index.ts +146 -23
  155. package/packages/core/src/tool-runtime/tool-worker.ts +2 -2
  156. package/packages/core/src/tool-runtime/worker-tools.ts +27 -0
  157. package/packages/core/src/{canvas/a2ui-tools.ts → tools/a2ui/index.ts} +17 -8
  158. package/packages/core/src/tools/agents/get-available-models.ts +36 -54
  159. package/packages/core/src/tools/agents/index.ts +784 -292
  160. package/packages/core/src/tools/api/api-request.test.ts +164 -0
  161. package/packages/core/src/tools/api/api-request.ts +174 -0
  162. package/packages/core/src/tools/api/index.ts +16 -0
  163. package/packages/core/src/tools/cli/index.ts +4 -0
  164. package/packages/core/src/tools/core/index.ts +281 -112
  165. package/packages/core/src/tools/cron/index.ts +121 -124
  166. package/packages/core/src/tools/index.ts +63 -78
  167. package/packages/core/src/tools/office/office-escribir-xlsx.ts +3 -1
  168. package/packages/core/src/tools/types.ts +3 -1
  169. package/packages/core/src/tools/web/artifact-inspect.ts +23 -0
  170. package/packages/core/src/tools/web/browser-screenshot.ts +26 -5
  171. package/packages/core/src/tools/web/browser-service.ts +5 -0
  172. package/packages/core/src/tools/web/browser-type.ts +3 -8
  173. package/packages/core/src/tools/web/index.ts +4 -4
  174. package/packages/core/src/voice/index.ts +89 -63
  175. package/packages/core/src/workers/agent.worker.ts +2 -2
  176. package/packages/core/src/workers/workers.test.ts +3 -10
  177. package/scripts/bump-version.ts +248 -0
  178. package/scripts/generate-skill-bundle.ts +108 -0
  179. package/test/agent-loop-terminal-synthesis.test.ts +32 -0
  180. package/test/catalog-agents-stay-enabled.test.ts +117 -0
  181. package/test/causal-events.test.ts +117 -0
  182. package/test/compaction.test.ts +105 -0
  183. package/test/context-compiler.test.ts +269 -0
  184. package/test/curator.test.ts +130 -0
  185. package/test/durable-queue.test.ts +114 -0
  186. package/test/harness-barrel.test.ts +64 -0
  187. package/test/hive-helpers.test.ts +130 -0
  188. package/test/hivedb-search.test.ts +189 -0
  189. package/test/internal-turns.test.ts +166 -0
  190. package/test/job-idempotency.test.ts +68 -0
  191. package/test/job-retry-backoff.test.ts +184 -0
  192. package/test/job-store.test.ts +381 -0
  193. package/test/llm-retry.test.ts +97 -0
  194. package/test/memory-perf.test.ts +774 -0
  195. package/test/minimal-loadout.test.ts +78 -0
  196. package/test/model-catalog.test.ts +105 -0
  197. package/test/preload.ts +12 -0
  198. package/test/reflector.test.ts +320 -0
  199. package/test/retention-cap.test.ts +91 -0
  200. package/test/retired-capabilities-pruned.test.ts +192 -0
  201. package/test/run-store.test.ts +355 -0
  202. package/test/scratchpad.test.ts +74 -0
  203. package/test/secrets-durability.test.ts +119 -0
  204. package/test/seed-model-reseed.test.ts +155 -0
  205. package/test/setup-agent-seed.test.ts +264 -0
  206. package/test/tool-inventory.test.ts +65 -0
  207. package/test/tool-runtime.test.ts +258 -0
  208. package/test/toon.test.ts +429 -0
  209. package/tsconfig.json +2 -0
  210. package/packages/core/src/ace/Curator.ts +0 -158
  211. package/packages/core/src/ace/Reflector.ts +0 -200
  212. package/packages/core/src/ace/index.ts +0 -4
  213. package/packages/core/src/agent/AgentRunner.ts +0 -711
  214. package/packages/core/src/agent/ContextCompiler.ts +0 -567
  215. package/packages/core/src/agent/ContextGuard.ts +0 -91
  216. package/packages/core/src/agent/ConversationStore.ts +0 -254
  217. package/packages/core/src/agent/Hooks.ts +0 -166
  218. package/packages/core/src/agent/StuckLoop.ts +0 -133
  219. package/packages/core/src/agent/providers/LLMClient.ts +0 -149
  220. package/packages/core/src/agent/providers/anthropic.ts +0 -212
  221. package/packages/core/src/agent/providers/openai-compat.ts +0 -231
  222. package/packages/core/src/agent/selectors/PlaybookSelector.ts +0 -121
  223. package/packages/core/src/agent/selectors/SkillSelector.ts +0 -322
  224. package/packages/core/src/agent/selectors/index.ts +0 -6
  225. package/packages/core/src/auth/auth.ts +0 -121
  226. package/packages/core/src/auth/index.ts +0 -1
  227. package/packages/core/src/canvas/CanvasManager.ts +0 -390
  228. package/packages/core/src/canvas/canvas-tools.ts +0 -448
  229. package/packages/core/src/harness/collections.ts +0 -98
  230. package/packages/core/src/harness/goal-verifier.ts +0 -141
  231. package/packages/core/src/harness/harness.test.ts +0 -236
  232. package/packages/core/src/harness/reconcile.ts +0 -149
  233. package/packages/core/src/mcp/MCPToolAdapter.ts +0 -176
  234. package/packages/core/src/multimodal/VisionService.ts +0 -293
  235. package/packages/core/src/scheduler/dag/AgentExecutor.ts +0 -53
  236. package/packages/core/src/scheduler/dag/DAGScheduler.ts +0 -250
  237. package/packages/core/src/scheduler/dag/EventBridge.ts +0 -122
  238. package/packages/core/src/scheduler/dag/TaskGraph.ts +0 -192
  239. package/packages/core/src/scheduler/dag/TaskNode.ts +0 -97
  240. package/packages/core/src/scheduler/dag/TaskResult.ts +0 -22
  241. package/packages/core/src/scheduler/dag/errors.ts +0 -37
  242. package/packages/core/src/scheduler/dag/index.ts +0 -26
  243. package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +0 -97
  244. package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +0 -21
  245. package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +0 -46
  246. package/packages/core/src/storage/HiveDBStorage.ts +0 -64
  247. package/packages/core/src/storage/SQLiteStorage.ts +0 -414
  248. package/packages/core/src/storage/hiveSeed.ts +0 -308
  249. package/packages/core/src/storage/hiveStorage.test.ts +0 -38
  250. package/packages/core/src/storage/schema.ts +0 -689
  251. package/packages/core/src/storage/storage.test.ts +0 -37
  252. package/packages/core/src/swarm/AgentBus.ts +0 -460
  253. package/packages/core/src/swarm/EventBus.ts +0 -169
  254. package/packages/core/src/swarm/WorkerPool.ts +0 -236
  255. package/packages/core/src/tools/bridge-events.ts +0 -26
  256. package/packages/core/src/tools/canvas/index.ts +0 -375
  257. package/packages/core/src/tools/codebridge/index.ts +0 -342
  258. package/packages/core/src/tools/meeting/index.ts +0 -353
  259. package/packages/core/src/tools/projects/index.ts +0 -37
  260. package/packages/core/src/tools/projects/project-create.ts +0 -94
  261. package/packages/core/src/tools/projects/project-done.ts +0 -66
  262. package/packages/core/src/tools/projects/project-fail.ts +0 -66
  263. package/packages/core/src/tools/projects/project-list.ts +0 -96
  264. package/packages/core/src/tools/projects/project-update.ts +0 -72
  265. package/packages/core/src/tools/projects/task-create.ts +0 -68
  266. package/packages/core/src/tools/projects/task-evaluate.ts +0 -93
  267. package/packages/core/src/tools/projects/task-update.ts +0 -93
  268. package/packages/core/src/tools/voice/index.ts +0 -104
  269. package/packages/core/src/tools/web/api-request.test.ts +0 -170
  270. package/packages/core/src/tools/web/api-request.ts +0 -239
  271. package/test/setup-db.ts +0 -216
  272. /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";