myaiforone 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/README.md +113 -0
  2. package/agents/_template/CLAUDE.md +18 -0
  3. package/agents/_template/agent.json +7 -0
  4. package/agents/platform/agentcreator/CLAUDE.md +300 -0
  5. package/agents/platform/appcreator/CLAUDE.md +158 -0
  6. package/agents/platform/gym/CLAUDE.md +486 -0
  7. package/agents/platform/gym/agent.json +40 -0
  8. package/agents/platform/gym/programs/agent-building/program.json +160 -0
  9. package/agents/platform/gym/programs/automations-mastery/program.json +129 -0
  10. package/agents/platform/gym/programs/getting-started/program.json +124 -0
  11. package/agents/platform/gym/programs/mcp-integrations/program.json +116 -0
  12. package/agents/platform/gym/programs/multi-model-strategy/program.json +115 -0
  13. package/agents/platform/gym/programs/prompt-engineering/program.json +136 -0
  14. package/agents/platform/gym/souls/alex.md +12 -0
  15. package/agents/platform/gym/souls/jordan.md +12 -0
  16. package/agents/platform/gym/souls/morgan.md +12 -0
  17. package/agents/platform/gym/souls/riley.md +12 -0
  18. package/agents/platform/gym/souls/sam.md +12 -0
  19. package/agents/platform/hub/CLAUDE.md +372 -0
  20. package/agents/platform/promptcreator/CLAUDE.md +130 -0
  21. package/agents/platform/skillcreator/CLAUDE.md +163 -0
  22. package/bin/cli.js +566 -0
  23. package/config.example.json +310 -0
  24. package/dist/agent-registry.d.ts +32 -0
  25. package/dist/agent-registry.d.ts.map +1 -0
  26. package/dist/agent-registry.js +144 -0
  27. package/dist/agent-registry.js.map +1 -0
  28. package/dist/channels/discord.d.ts +17 -0
  29. package/dist/channels/discord.d.ts.map +1 -0
  30. package/dist/channels/discord.js +114 -0
  31. package/dist/channels/discord.js.map +1 -0
  32. package/dist/channels/imessage.d.ts +23 -0
  33. package/dist/channels/imessage.d.ts.map +1 -0
  34. package/dist/channels/imessage.js +214 -0
  35. package/dist/channels/imessage.js.map +1 -0
  36. package/dist/channels/slack.d.ts +19 -0
  37. package/dist/channels/slack.d.ts.map +1 -0
  38. package/dist/channels/slack.js +167 -0
  39. package/dist/channels/slack.js.map +1 -0
  40. package/dist/channels/telegram.d.ts +19 -0
  41. package/dist/channels/telegram.d.ts.map +1 -0
  42. package/dist/channels/telegram.js +274 -0
  43. package/dist/channels/telegram.js.map +1 -0
  44. package/dist/channels/types.d.ts +44 -0
  45. package/dist/channels/types.d.ts.map +1 -0
  46. package/dist/channels/types.js +18 -0
  47. package/dist/channels/types.js.map +1 -0
  48. package/dist/channels/whatsapp.d.ts +23 -0
  49. package/dist/channels/whatsapp.d.ts.map +1 -0
  50. package/dist/channels/whatsapp.js +189 -0
  51. package/dist/channels/whatsapp.js.map +1 -0
  52. package/dist/config.d.ts +134 -0
  53. package/dist/config.d.ts.map +1 -0
  54. package/dist/config.js +127 -0
  55. package/dist/config.js.map +1 -0
  56. package/dist/cron.d.ts +8 -0
  57. package/dist/cron.d.ts.map +1 -0
  58. package/dist/cron.js +35 -0
  59. package/dist/cron.js.map +1 -0
  60. package/dist/decrypt-keys.d.ts +7 -0
  61. package/dist/decrypt-keys.d.ts.map +1 -0
  62. package/dist/decrypt-keys.js +53 -0
  63. package/dist/decrypt-keys.js.map +1 -0
  64. package/dist/encrypt-keys.d.ts +8 -0
  65. package/dist/encrypt-keys.d.ts.map +1 -0
  66. package/dist/encrypt-keys.js +62 -0
  67. package/dist/encrypt-keys.js.map +1 -0
  68. package/dist/executor.d.ts +31 -0
  69. package/dist/executor.d.ts.map +1 -0
  70. package/dist/executor.js +2009 -0
  71. package/dist/executor.js.map +1 -0
  72. package/dist/gemini-executor.d.ts +27 -0
  73. package/dist/gemini-executor.d.ts.map +1 -0
  74. package/dist/gemini-executor.js +160 -0
  75. package/dist/gemini-executor.js.map +1 -0
  76. package/dist/goals.d.ts +24 -0
  77. package/dist/goals.d.ts.map +1 -0
  78. package/dist/goals.js +189 -0
  79. package/dist/goals.js.map +1 -0
  80. package/dist/gym/activity-digest.d.ts +30 -0
  81. package/dist/gym/activity-digest.d.ts.map +1 -0
  82. package/dist/gym/activity-digest.js +506 -0
  83. package/dist/gym/activity-digest.js.map +1 -0
  84. package/dist/gym/dimension-scorer.d.ts +76 -0
  85. package/dist/gym/dimension-scorer.d.ts.map +1 -0
  86. package/dist/gym/dimension-scorer.js +236 -0
  87. package/dist/gym/dimension-scorer.js.map +1 -0
  88. package/dist/gym/gym-router.d.ts +7 -0
  89. package/dist/gym/gym-router.d.ts.map +1 -0
  90. package/dist/gym/gym-router.js +718 -0
  91. package/dist/gym/gym-router.js.map +1 -0
  92. package/dist/gym/index.d.ts +11 -0
  93. package/dist/gym/index.d.ts.map +1 -0
  94. package/dist/gym/index.js +11 -0
  95. package/dist/gym/index.js.map +1 -0
  96. package/dist/heartbeat.d.ts +21 -0
  97. package/dist/heartbeat.d.ts.map +1 -0
  98. package/dist/heartbeat.js +163 -0
  99. package/dist/heartbeat.js.map +1 -0
  100. package/dist/index.d.ts +2 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +254 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/keystore.d.ts +22 -0
  105. package/dist/keystore.d.ts.map +1 -0
  106. package/dist/keystore.js +178 -0
  107. package/dist/keystore.js.map +1 -0
  108. package/dist/logger.d.ts +9 -0
  109. package/dist/logger.d.ts.map +1 -0
  110. package/dist/logger.js +45 -0
  111. package/dist/logger.js.map +1 -0
  112. package/dist/memory/daily.d.ts +22 -0
  113. package/dist/memory/daily.d.ts.map +1 -0
  114. package/dist/memory/daily.js +82 -0
  115. package/dist/memory/daily.js.map +1 -0
  116. package/dist/memory/embeddings.d.ts +15 -0
  117. package/dist/memory/embeddings.d.ts.map +1 -0
  118. package/dist/memory/embeddings.js +154 -0
  119. package/dist/memory/embeddings.js.map +1 -0
  120. package/dist/memory/index.d.ts +32 -0
  121. package/dist/memory/index.d.ts.map +1 -0
  122. package/dist/memory/index.js +159 -0
  123. package/dist/memory/index.js.map +1 -0
  124. package/dist/memory/search.d.ts +21 -0
  125. package/dist/memory/search.d.ts.map +1 -0
  126. package/dist/memory/search.js +77 -0
  127. package/dist/memory/search.js.map +1 -0
  128. package/dist/memory/store.d.ts +23 -0
  129. package/dist/memory/store.d.ts.map +1 -0
  130. package/dist/memory/store.js +144 -0
  131. package/dist/memory/store.js.map +1 -0
  132. package/dist/ollama-executor.d.ts +17 -0
  133. package/dist/ollama-executor.d.ts.map +1 -0
  134. package/dist/ollama-executor.js +112 -0
  135. package/dist/ollama-executor.js.map +1 -0
  136. package/dist/openai-executor.d.ts +38 -0
  137. package/dist/openai-executor.d.ts.map +1 -0
  138. package/dist/openai-executor.js +197 -0
  139. package/dist/openai-executor.js.map +1 -0
  140. package/dist/router.d.ts +11 -0
  141. package/dist/router.d.ts.map +1 -0
  142. package/dist/router.js +185 -0
  143. package/dist/router.js.map +1 -0
  144. package/dist/test-message.d.ts +2 -0
  145. package/dist/test-message.d.ts.map +1 -0
  146. package/dist/test-message.js +60 -0
  147. package/dist/test-message.js.map +1 -0
  148. package/dist/utils/imsg-db-reader.d.ts +24 -0
  149. package/dist/utils/imsg-db-reader.d.ts.map +1 -0
  150. package/dist/utils/imsg-db-reader.js +92 -0
  151. package/dist/utils/imsg-db-reader.js.map +1 -0
  152. package/dist/utils/imsg-rpc.d.ts +25 -0
  153. package/dist/utils/imsg-rpc.d.ts.map +1 -0
  154. package/dist/utils/imsg-rpc.js +149 -0
  155. package/dist/utils/imsg-rpc.js.map +1 -0
  156. package/dist/utils/message-formatter.d.ts +3 -0
  157. package/dist/utils/message-formatter.d.ts.map +1 -0
  158. package/dist/utils/message-formatter.js +69 -0
  159. package/dist/utils/message-formatter.js.map +1 -0
  160. package/dist/web-ui.d.ts +12 -0
  161. package/dist/web-ui.d.ts.map +1 -0
  162. package/dist/web-ui.js +5784 -0
  163. package/dist/web-ui.js.map +1 -0
  164. package/dist/whatsapp-chats.d.ts +2 -0
  165. package/dist/whatsapp-chats.d.ts.map +1 -0
  166. package/dist/whatsapp-chats.js +76 -0
  167. package/dist/whatsapp-chats.js.map +1 -0
  168. package/dist/whatsapp-login.d.ts +2 -0
  169. package/dist/whatsapp-login.d.ts.map +1 -0
  170. package/dist/whatsapp-login.js +90 -0
  171. package/dist/whatsapp-login.js.map +1 -0
  172. package/dist/wiki-sync.d.ts +21 -0
  173. package/dist/wiki-sync.d.ts.map +1 -0
  174. package/dist/wiki-sync.js +147 -0
  175. package/dist/wiki-sync.js.map +1 -0
  176. package/docs/AddNewAgentGuide.md +100 -0
  177. package/docs/AddNewMcpGuide.md +72 -0
  178. package/docs/Architecture.md +795 -0
  179. package/docs/CLAUDE-AI-SETUP.md +166 -0
  180. package/docs/Setup.md +297 -0
  181. package/docs/ai-gym-architecture.md +1040 -0
  182. package/docs/ai-gym-build-plan.md +343 -0
  183. package/docs/ai-gym-onboarding.md +122 -0
  184. package/docs/appcreator_plan.md +348 -0
  185. package/docs/platform-mcp-audit.md +320 -0
  186. package/docs/server-deployment-plan.md +503 -0
  187. package/docs/superpowers/plans/2026-03-25-marketplace.md +1281 -0
  188. package/docs/superpowers/specs/2026-03-25-marketplace-design.md +287 -0
  189. package/docs/user-guide.md +2016 -0
  190. package/mcp-catalog.json +628 -0
  191. package/package.json +63 -0
  192. package/public/MyAIforOne-logomark-512.svg +16 -0
  193. package/public/MyAIforOne-logomark-transparent.svg +15 -0
  194. package/public/activity.html +314 -0
  195. package/public/admin.html +1674 -0
  196. package/public/agent-dashboard.html +670 -0
  197. package/public/api-docs.html +1106 -0
  198. package/public/automations.html +722 -0
  199. package/public/canvas.css +223 -0
  200. package/public/canvas.js +588 -0
  201. package/public/changelog.html +231 -0
  202. package/public/gym.html +2766 -0
  203. package/public/home.html +1930 -0
  204. package/public/index.html +2809 -0
  205. package/public/lab.html +1643 -0
  206. package/public/library.html +1442 -0
  207. package/public/marketplace.html +1101 -0
  208. package/public/mcp-docs.html +441 -0
  209. package/public/mini.html +390 -0
  210. package/public/monitor.html +584 -0
  211. package/public/org.html +4304 -0
  212. package/public/projects.html +734 -0
  213. package/public/settings.html +645 -0
  214. package/public/tasks.html +932 -0
  215. package/public/trainers/alex.svg +12 -0
  216. package/public/trainers/jordan.svg +12 -0
  217. package/public/trainers/morgan.svg +12 -0
  218. package/public/trainers/riley.svg +12 -0
  219. package/public/trainers/sam.svg +12 -0
  220. package/public/user-guide.html +218 -0
  221. package/registry/agents.json +3 -0
  222. package/registry/apps.json +20 -0
  223. package/registry/installed-drafts.json +3 -0
  224. package/registry/mcps.json +1084 -0
  225. package/registry/prompts/personal/mcp-test-prompt.md +6 -0
  226. package/registry/prompts/personal/memory-recall.md +6 -0
  227. package/registry/prompts/platform/brainstorm.md +15 -0
  228. package/registry/prompts/platform/code-review.md +16 -0
  229. package/registry/prompts/platform/explain.md +16 -0
  230. package/registry/prompts.json +58 -0
  231. package/registry/skills/external/brainstorming.md +5 -0
  232. package/registry/skills/external/code-review.md +40 -0
  233. package/registry/skills/external/frontend-patterns.md +642 -0
  234. package/registry/skills/external/frontend-slides.md +184 -0
  235. package/registry/skills/external/systematic-debugging.md +5 -0
  236. package/registry/skills/external/tdd.md +328 -0
  237. package/registry/skills/external/verification-before-completion.md +5 -0
  238. package/registry/skills/external/writing-plans.md +5 -0
  239. package/registry/skills/platform/ai41_app_build.md +930 -0
  240. package/registry/skills/platform/ai41_app_deploy.md +168 -0
  241. package/registry/skills/platform/ai41_app_orchestrator.md +239 -0
  242. package/registry/skills/platform/ai41_app_patterns.md +359 -0
  243. package/registry/skills/platform/ai41_app_register.md +85 -0
  244. package/registry/skills/platform/ai41_app_scaffold.md +421 -0
  245. package/registry/skills/platform/ai41_app_verify.md +107 -0
  246. package/registry/skills/platform/opProjectCreate.md +239 -0
  247. package/registry/skills/platform/op_devbrowser.md +136 -0
  248. package/registry/skills/platform/sop_brandguidelines.md +103 -0
  249. package/registry/skills/platform/sop_docx.md +117 -0
  250. package/registry/skills/platform/sop_frontenddesign.md +44 -0
  251. package/registry/skills/platform/sop_frontenddesign_v2.md +659 -0
  252. package/registry/skills/platform/sop_mcpbuilder.md +133 -0
  253. package/registry/skills/platform/sop_pdf.md +172 -0
  254. package/registry/skills/platform/sop_pptx.md +133 -0
  255. package/registry/skills/platform/sop_skillcreator.md +104 -0
  256. package/registry/skills/platform/sop_themefactory.md +128 -0
  257. package/registry/skills/platform/sop_webapptesting.md +75 -0
  258. package/registry/skills/platform/sop_webartifactsbuilder.md +97 -0
  259. package/registry/skills/platform/sop_xlsx.md +134 -0
  260. package/registry/skills.json +1055 -0
  261. package/scripts/discover-chats.sh +11 -0
  262. package/scripts/install-service-windows.ps1 +87 -0
  263. package/scripts/install-service.sh +52 -0
  264. package/scripts/seed-registry.ts +195 -0
  265. package/scripts/test-send.sh +5 -0
  266. package/scripts/tray-indicator.ps1 +35 -0
  267. package/scripts/uninstall-service-windows.ps1 +23 -0
  268. package/scripts/uninstall-service.sh +15 -0
  269. package/scripts/xbar-myagent.5s.sh +32 -0
  270. package/server/mcp-server/dist/index.d.ts +11 -0
  271. package/server/mcp-server/dist/index.js +1332 -0
  272. package/server/mcp-server/dist/lib/api-client.d.ts +165 -0
  273. package/server/mcp-server/dist/lib/api-client.js +241 -0
  274. package/server/mcp-server/index.ts +1545 -0
  275. package/server/mcp-server/lib/api-client.ts +366 -0
  276. package/server/mcp-server/tsconfig.json +14 -0
  277. package/src/agent-registry.ts +180 -0
  278. package/src/channels/discord.ts +129 -0
  279. package/src/channels/imessage.ts +261 -0
  280. package/src/channels/slack.ts +208 -0
  281. package/src/channels/telegram.ts +307 -0
  282. package/src/channels/types.ts +62 -0
  283. package/src/channels/whatsapp.ts +227 -0
  284. package/src/config.ts +281 -0
  285. package/src/cron.ts +43 -0
  286. package/src/decrypt-keys.ts +60 -0
  287. package/src/encrypt-keys.ts +70 -0
  288. package/src/executor.ts +2190 -0
  289. package/src/gemini-executor.ts +212 -0
  290. package/src/goals.ts +240 -0
  291. package/src/gym/activity-digest.ts +546 -0
  292. package/src/gym/dimension-scorer.ts +297 -0
  293. package/src/gym/gym-router.ts +801 -0
  294. package/src/gym/index.ts +19 -0
  295. package/src/heartbeat.ts +220 -0
  296. package/src/index.ts +275 -0
  297. package/src/keystore.ts +190 -0
  298. package/src/logger.ts +51 -0
  299. package/src/memory/daily.ts +101 -0
  300. package/src/memory/embeddings.ts +185 -0
  301. package/src/memory/index.ts +218 -0
  302. package/src/memory/search.ts +124 -0
  303. package/src/memory/store.ts +189 -0
  304. package/src/ollama-executor.ts +126 -0
  305. package/src/openai-executor.ts +259 -0
  306. package/src/router.ts +230 -0
  307. package/src/test-message.ts +72 -0
  308. package/src/utils/imsg-db-reader.ts +109 -0
  309. package/src/utils/imsg-rpc.ts +178 -0
  310. package/src/utils/message-formatter.ts +90 -0
  311. package/src/web-ui.ts +5778 -0
  312. package/src/whatsapp-chats.ts +91 -0
  313. package/src/whatsapp-login.ts +110 -0
  314. package/src/wiki-sync.ts +199 -0
  315. package/tsconfig.json +19 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * MemoryManager — orchestrates advanced memory for agents.
3
+ * - Semantic search over stored memories
4
+ * - Daily memory logging
5
+ * - Auto-compaction (prompts agent to save before context grows too large)
6
+ * - Indexes context.md, daily logs, and conversation exchanges
7
+ */
8
+ import { randomUUID } from "node:crypto";
9
+ import { readFileSync, existsSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { getEmbeddingProvider, buildVocab } from "./embeddings.js";
12
+ import { createStore } from "./store.js";
13
+ import { hybridSearch, formatSearchResults } from "./search.js";
14
+ import { appendDailyEntry, loadRecentDaily, listDailyFiles } from "./daily.js";
15
+ import { log } from "../logger.js";
16
+ // ─── Chunk text into ~400 token pieces ───────────────────────────────
17
+ function chunkText(text, maxChars = 1200) {
18
+ const paragraphs = text.split(/\n\n+/);
19
+ const chunks = [];
20
+ let current = "";
21
+ for (const para of paragraphs) {
22
+ if (current.length + para.length > maxChars && current.length > 0) {
23
+ chunks.push(current.trim());
24
+ current = "";
25
+ }
26
+ current += para + "\n\n";
27
+ }
28
+ if (current.trim()) {
29
+ chunks.push(current.trim());
30
+ }
31
+ return chunks.length > 0 ? chunks : [text];
32
+ }
33
+ // ─── Auto-compaction thresholds ──────────────────────────────────────
34
+ const COMPACTION_WARN_MESSAGES = 20; // suggest compaction after 20 messages
35
+ const COMPACTION_FORCE_MESSAGES = 40; // strongly suggest after 40
36
+ // ─── Create MemoryManager ────────────────────────────────────────────
37
+ export async function createMemoryManager(memoryDir) {
38
+ const embedder = getEmbeddingProvider();
39
+ const store = await createStore(memoryDir);
40
+ const contextPath = join(memoryDir, "context.md");
41
+ // Initial index if store is empty
42
+ const count = await store.count();
43
+ if (count === 0) {
44
+ log.info(`Memory: empty store, indexing existing files...`);
45
+ await indexExistingFiles(memoryDir, contextPath, embedder, store);
46
+ }
47
+ return {
48
+ async search(query, topK = 5) {
49
+ const queryVector = await embedder.embed(query);
50
+ const allChunks = await store.getAll();
51
+ return hybridSearch(queryVector, query, allChunks, { topK });
52
+ },
53
+ async searchFormatted(query, topK = 5) {
54
+ const queryVector = await embedder.embed(query);
55
+ const allChunks = await store.getAll();
56
+ const results = hybridSearch(queryVector, query, allChunks, { topK });
57
+ return formatSearchResults(results);
58
+ },
59
+ async index(text, source, metadata) {
60
+ const chunks = chunkText(text);
61
+ const vectors = await embedder.embedBatch(chunks);
62
+ const memoryChunks = chunks.map((text, i) => ({
63
+ id: `${source}-${randomUUID().slice(0, 8)}`,
64
+ text,
65
+ vector: vectors[i],
66
+ source,
67
+ timestamp: new Date().toISOString(),
68
+ metadata,
69
+ }));
70
+ await store.addBatch(memoryChunks);
71
+ },
72
+ async indexExchange(userMessage, agentResponse, sender) {
73
+ // Log to daily file
74
+ appendDailyEntry(memoryDir, sender, userMessage, agentResponse);
75
+ // Index the exchange as a memory chunk
76
+ const summary = `User (${sender}): ${userMessage.slice(0, 200)}\nAgent: ${agentResponse.slice(0, 400)}`;
77
+ const vector = await embedder.embed(summary);
78
+ await store.add({
79
+ id: `conv-${Date.now()}`,
80
+ text: summary,
81
+ vector,
82
+ source: "conversation",
83
+ timestamp: new Date().toISOString(),
84
+ metadata: { sender },
85
+ });
86
+ },
87
+ loadDailyContext() {
88
+ return loadRecentDaily(memoryDir);
89
+ },
90
+ async reindex() {
91
+ await store.clear();
92
+ await indexExistingFiles(memoryDir, contextPath, embedder, store);
93
+ log.info(`Memory: reindexed`);
94
+ },
95
+ getCompactionPrompt(messageCount) {
96
+ if (messageCount >= COMPACTION_FORCE_MESSAGES) {
97
+ return `[SYSTEM: Your conversation has reached ${messageCount} messages. Before the context gets compressed, save any important decisions, facts, or context to ${contextPath} using the Write tool. Focus on: key decisions made, user preferences learned, project state, and anything you'd need to know if starting fresh. Merge with existing content — don't overwrite.]`;
98
+ }
99
+ if (messageCount >= COMPACTION_WARN_MESSAGES) {
100
+ return `[SYSTEM: You're at ${messageCount} messages. Consider using /opcompact to save important context soon, or I'll remind you again at ${COMPACTION_FORCE_MESSAGES} messages.]`;
101
+ }
102
+ return null;
103
+ },
104
+ async stats() {
105
+ return {
106
+ chunks: await store.count(),
107
+ store: store.name,
108
+ embeddings: embedder.name,
109
+ };
110
+ },
111
+ };
112
+ }
113
+ // ─── Index existing files into the store ─────────────────────────────
114
+ async function indexExistingFiles(memoryDir, contextPath, embedder, store) {
115
+ const allTexts = [];
116
+ // Index context.md
117
+ if (existsSync(contextPath)) {
118
+ try {
119
+ const content = readFileSync(contextPath, "utf-8").trim();
120
+ if (content) {
121
+ const chunks = chunkText(content);
122
+ for (const chunk of chunks) {
123
+ allTexts.push({ text: chunk, source: "context", timestamp: new Date().toISOString() });
124
+ }
125
+ }
126
+ }
127
+ catch { /* ignore */ }
128
+ }
129
+ // Index daily files
130
+ const dailyFiles = listDailyFiles(memoryDir);
131
+ for (const { path, date } of dailyFiles) {
132
+ try {
133
+ const content = readFileSync(path, "utf-8").trim();
134
+ if (content) {
135
+ const chunks = chunkText(content);
136
+ for (const chunk of chunks) {
137
+ allTexts.push({ text: chunk, source: "daily", timestamp: `${date}T00:00:00.000Z` });
138
+ }
139
+ }
140
+ }
141
+ catch { /* ignore */ }
142
+ }
143
+ if (allTexts.length === 0)
144
+ return;
145
+ // Build vocab for TF-IDF (if using local embeddings)
146
+ buildVocab(allTexts.map(t => t.text));
147
+ // Embed all at once
148
+ const vectors = await embedder.embedBatch(allTexts.map(t => t.text));
149
+ const memoryChunks = allTexts.map((t, i) => ({
150
+ id: `${t.source}-${randomUUID().slice(0, 8)}`,
151
+ text: t.text,
152
+ vector: vectors[i],
153
+ source: t.source,
154
+ timestamp: t.timestamp,
155
+ }));
156
+ await store.addBatch(memoryChunks);
157
+ log.info(`Memory: indexed ${memoryChunks.length} chunks from ${dailyFiles.length} daily files + context.md`);
158
+ }
159
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Hybrid semantic search: cosine similarity + BM25 keyword + temporal decay.
3
+ */
4
+ import type { MemoryChunk } from "./store.js";
5
+ export interface SearchResult {
6
+ chunk: MemoryChunk;
7
+ score: number;
8
+ vectorScore: number;
9
+ keywordScore: number;
10
+ decayFactor: number;
11
+ }
12
+ export interface SearchOptions {
13
+ topK?: number;
14
+ vectorWeight?: number;
15
+ keywordWeight?: number;
16
+ decayWeight?: number;
17
+ minScore?: number;
18
+ }
19
+ export declare function hybridSearch(queryVector: number[], queryText: string, chunks: MemoryChunk[], options?: SearchOptions): SearchResult[];
20
+ export declare function formatSearchResults(results: SearchResult[]): string;
21
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/memory/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAmDD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EAAE,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,GAAE,aAAkB,GAC1B,YAAY,EAAE,CA+BhB;AAID,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAWnE"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Hybrid semantic search: cosine similarity + BM25 keyword + temporal decay.
3
+ */
4
+ import { cosineSimilarity } from "./embeddings.js";
5
+ // ─── BM25 keyword scoring ────────────────────────────────────────────
6
+ const BM25_K1 = 1.2;
7
+ const BM25_B = 0.75;
8
+ function tokenize(text) {
9
+ return text.toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter(t => t.length > 1);
10
+ }
11
+ function bm25Score(query, document, avgDocLen) {
12
+ const queryTokens = tokenize(query);
13
+ const docTokens = tokenize(document);
14
+ if (queryTokens.length === 0 || docTokens.length === 0)
15
+ return 0;
16
+ const docLen = docTokens.length;
17
+ const tf = new Map();
18
+ for (const t of docTokens) {
19
+ tf.set(t, (tf.get(t) || 0) + 1);
20
+ }
21
+ let score = 0;
22
+ for (const qt of queryTokens) {
23
+ const freq = tf.get(qt) || 0;
24
+ if (freq === 0)
25
+ continue;
26
+ const numerator = freq * (BM25_K1 + 1);
27
+ const denominator = freq + BM25_K1 * (1 - BM25_B + BM25_B * (docLen / avgDocLen));
28
+ score += numerator / denominator;
29
+ }
30
+ // Normalize to 0-1 range (approximate)
31
+ return Math.min(score / queryTokens.length, 1);
32
+ }
33
+ // ─── Temporal decay ──────────────────────────────────────────────────
34
+ const HALF_LIFE_DAYS = 30;
35
+ const DECAY_LAMBDA = Math.LN2 / HALF_LIFE_DAYS;
36
+ function temporalDecay(timestamp, source) {
37
+ // context.md and manual entries never decay
38
+ if (source === "context" || source === "manual")
39
+ return 1.0;
40
+ const ageMs = Date.now() - new Date(timestamp).getTime();
41
+ const ageDays = ageMs / (1000 * 60 * 60 * 24);
42
+ return Math.exp(-DECAY_LAMBDA * ageDays);
43
+ }
44
+ export function hybridSearch(queryVector, queryText, chunks, options = {}) {
45
+ const { topK = 5, vectorWeight = 0.6, keywordWeight = 0.3, decayWeight = 0.1, minScore = 0.1, } = options;
46
+ if (chunks.length === 0)
47
+ return [];
48
+ // Average document length for BM25
49
+ const avgDocLen = chunks.reduce((sum, c) => sum + tokenize(c.text).length, 0) / chunks.length;
50
+ const results = chunks.map(chunk => {
51
+ const vectorScore = cosineSimilarity(queryVector, chunk.vector);
52
+ const keywordScore = bm25Score(queryText, chunk.text, avgDocLen);
53
+ const decayFactor = temporalDecay(chunk.timestamp, chunk.source);
54
+ const score = vectorWeight * vectorScore +
55
+ keywordWeight * keywordScore +
56
+ decayWeight * decayFactor;
57
+ return { chunk, score, vectorScore, keywordScore, decayFactor };
58
+ });
59
+ return results
60
+ .filter(r => r.score >= minScore)
61
+ .sort((a, b) => b.score - a.score)
62
+ .slice(0, topK);
63
+ }
64
+ // ─── Format search results for prompt injection ──────────────────────
65
+ export function formatSearchResults(results) {
66
+ if (results.length === 0)
67
+ return "";
68
+ const lines = ["[Relevant Memories]"];
69
+ for (const r of results) {
70
+ const date = r.chunk.timestamp.split("T")[0];
71
+ const source = r.chunk.source;
72
+ lines.push(`- [${date}/${source}] ${r.chunk.text}`);
73
+ }
74
+ lines.push("[/Relevant Memories]");
75
+ return lines.join("\n");
76
+ }
77
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/memory/search.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAWnD,wEAAwE;AAExE,MAAM,OAAO,GAAG,GAAG,CAAC;AACpB,MAAM,MAAM,GAAG,IAAI,CAAC;AAEpB,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAChG,CAAC;AAED,SAAS,SAAS,CAAC,KAAa,EAAE,QAAgB,EAAE,SAAiB;IACnE,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAEjE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;IAChC,MAAM,EAAE,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,IAAI,KAAK,CAAC;YAAE,SAAS;QACzB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QACvC,MAAM,WAAW,GAAG,IAAI,GAAG,OAAO,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;QAClF,KAAK,IAAI,SAAS,GAAG,WAAW,CAAC;IACnC,CAAC;IAED,uCAAuC;IACvC,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,wEAAwE;AAExE,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,GAAG,cAAc,CAAC;AAE/C,SAAS,aAAa,CAAC,SAAiB,EAAE,MAAc;IACtD,4CAA4C;IAC5C,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAE5D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;IACzD,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,GAAG,OAAO,CAAC,CAAC;AAC3C,CAAC;AAYD,MAAM,UAAU,YAAY,CAC1B,WAAqB,EACrB,SAAiB,EACjB,MAAqB,EACrB,UAAyB,EAAE;IAE3B,MAAM,EACJ,IAAI,GAAG,CAAC,EACR,YAAY,GAAG,GAAG,EAClB,aAAa,GAAG,GAAG,EACnB,WAAW,GAAG,GAAG,EACjB,QAAQ,GAAG,GAAG,GACf,GAAG,OAAO,CAAC;IAEZ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,mCAAmC;IACnC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IAE9F,MAAM,OAAO,GAAmB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QACjD,MAAM,WAAW,GAAG,gBAAgB,CAAC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAChE,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACjE,MAAM,WAAW,GAAG,aAAa,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAEjE,MAAM,KAAK,GACT,YAAY,GAAG,WAAW;YAC1B,aAAa,GAAG,YAAY;YAC5B,WAAW,GAAG,WAAW,CAAC;QAE5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC;SAChC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACpB,CAAC;AAED,wEAAwE;AAExE,MAAM,UAAU,mBAAmB,CAAC,OAAuB;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,KAAK,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,MAAM,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Vector store — JSON default, auto-upgrades to SQLite if better-sqlite3 is available.
3
+ * Stores text chunks with their embedding vectors for semantic search.
4
+ */
5
+ export interface MemoryChunk {
6
+ id: string;
7
+ text: string;
8
+ vector: number[];
9
+ source: string;
10
+ timestamp: string;
11
+ metadata?: Record<string, string>;
12
+ }
13
+ export interface VectorStore {
14
+ name: string;
15
+ add(chunk: MemoryChunk): Promise<void>;
16
+ addBatch(chunks: MemoryChunk[]): Promise<void>;
17
+ getAll(): Promise<MemoryChunk[]>;
18
+ remove(id: string): Promise<void>;
19
+ clear(): Promise<void>;
20
+ count(): Promise<number>;
21
+ }
22
+ export declare function createStore(memoryDir: string): Promise<VectorStore>;
23
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1B;AA0JD,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAQzE"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Vector store — JSON default, auto-upgrades to SQLite if better-sqlite3 is available.
3
+ * Stores text chunks with their embedding vectors for semantic search.
4
+ */
5
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
6
+ import { join } from "node:path";
7
+ import { log } from "../logger.js";
8
+ // ─── JSON Store (default) ────────────────────────────────────────────
9
+ class JSONStore {
10
+ name = "json";
11
+ filePath;
12
+ chunks = [];
13
+ loaded = false;
14
+ constructor(memoryDir) {
15
+ mkdirSync(memoryDir, { recursive: true });
16
+ this.filePath = join(memoryDir, "vectors.json");
17
+ }
18
+ load() {
19
+ if (this.loaded)
20
+ return;
21
+ if (existsSync(this.filePath)) {
22
+ try {
23
+ this.chunks = JSON.parse(readFileSync(this.filePath, "utf-8"));
24
+ }
25
+ catch {
26
+ this.chunks = [];
27
+ }
28
+ }
29
+ this.loaded = true;
30
+ }
31
+ save() {
32
+ writeFileSync(this.filePath, JSON.stringify(this.chunks));
33
+ }
34
+ async add(chunk) {
35
+ this.load();
36
+ // Replace if same ID exists
37
+ this.chunks = this.chunks.filter(c => c.id !== chunk.id);
38
+ this.chunks.push(chunk);
39
+ this.save();
40
+ }
41
+ async addBatch(chunks) {
42
+ this.load();
43
+ const newIds = new Set(chunks.map(c => c.id));
44
+ this.chunks = this.chunks.filter(c => !newIds.has(c.id));
45
+ this.chunks.push(...chunks);
46
+ this.save();
47
+ }
48
+ async getAll() {
49
+ this.load();
50
+ return [...this.chunks];
51
+ }
52
+ async remove(id) {
53
+ this.load();
54
+ this.chunks = this.chunks.filter(c => c.id !== id);
55
+ this.save();
56
+ }
57
+ async clear() {
58
+ this.chunks = [];
59
+ this.loaded = true;
60
+ this.save();
61
+ }
62
+ async count() {
63
+ this.load();
64
+ return this.chunks.length;
65
+ }
66
+ }
67
+ // ─── SQLite Store (auto-upgrade if available) ────────────────────────
68
+ async function trySQLiteStore(memoryDir) {
69
+ try {
70
+ // Dynamic import — only works if better-sqlite3 is installed
71
+ // Use createRequire to avoid TypeScript module resolution errors
72
+ const { createRequire } = await import("node:module");
73
+ const require = createRequire(import.meta.url);
74
+ const Database = require("better-sqlite3");
75
+ const dbPath = join(memoryDir, "vectors.sqlite");
76
+ const db = new Database(dbPath);
77
+ // Create table
78
+ db.exec(`
79
+ CREATE TABLE IF NOT EXISTS chunks (
80
+ id TEXT PRIMARY KEY,
81
+ text TEXT NOT NULL,
82
+ vector TEXT NOT NULL,
83
+ source TEXT NOT NULL,
84
+ timestamp TEXT NOT NULL,
85
+ metadata TEXT
86
+ )
87
+ `);
88
+ const store = {
89
+ name: "sqlite",
90
+ async add(chunk) {
91
+ db.prepare(`
92
+ INSERT OR REPLACE INTO chunks (id, text, vector, source, timestamp, metadata)
93
+ VALUES (?, ?, ?, ?, ?, ?)
94
+ `).run(chunk.id, chunk.text, JSON.stringify(chunk.vector), chunk.source, chunk.timestamp, chunk.metadata ? JSON.stringify(chunk.metadata) : null);
95
+ },
96
+ async addBatch(chunks) {
97
+ const stmt = db.prepare(`
98
+ INSERT OR REPLACE INTO chunks (id, text, vector, source, timestamp, metadata)
99
+ VALUES (?, ?, ?, ?, ?, ?)
100
+ `);
101
+ const tx = db.transaction((items) => {
102
+ for (const c of items) {
103
+ stmt.run(c.id, c.text, JSON.stringify(c.vector), c.source, c.timestamp, c.metadata ? JSON.stringify(c.metadata) : null);
104
+ }
105
+ });
106
+ tx(chunks);
107
+ },
108
+ async getAll() {
109
+ const rows = db.prepare("SELECT * FROM chunks").all();
110
+ return rows.map(r => ({
111
+ id: r.id, text: r.text, vector: JSON.parse(r.vector),
112
+ source: r.source, timestamp: r.timestamp,
113
+ metadata: r.metadata ? JSON.parse(r.metadata) : undefined,
114
+ }));
115
+ },
116
+ async remove(id) {
117
+ db.prepare("DELETE FROM chunks WHERE id = ?").run(id);
118
+ },
119
+ async clear() {
120
+ db.exec("DELETE FROM chunks");
121
+ },
122
+ async count() {
123
+ const row = db.prepare("SELECT COUNT(*) as cnt FROM chunks").get();
124
+ return row.cnt;
125
+ },
126
+ };
127
+ log.info("Memory store: SQLite (better-sqlite3)");
128
+ return store;
129
+ }
130
+ catch {
131
+ return null;
132
+ }
133
+ }
134
+ // ─── Store factory ───────────────────────────────────────────────────
135
+ export async function createStore(memoryDir) {
136
+ // Try SQLite first
137
+ const sqlite = await trySQLiteStore(memoryDir);
138
+ if (sqlite)
139
+ return sqlite;
140
+ // Fall back to JSON
141
+ log.info("Memory store: JSON (install better-sqlite3 for faster search at scale)");
142
+ return new JSONStore(memoryDir);
143
+ }
144
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/memory/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface OllamaOptions {
2
+ model: string;
3
+ systemPrompt: string;
4
+ message: string;
5
+ baseUrl?: string;
6
+ timeout?: number;
7
+ }
8
+ export declare function executeOllama(opts: OllamaOptions): Promise<string>;
9
+ export declare function streamOllama(opts: OllamaOptions): AsyncGenerator<string>;
10
+ /**
11
+ * Check if Ollama is running and the model is available
12
+ */
13
+ export declare function checkOllamaHealth(baseUrl?: string, model?: string): Promise<{
14
+ ok: boolean;
15
+ error?: string;
16
+ }>;
17
+ //# sourceMappingURL=ollama-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama-executor.d.ts","sourceRoot":"","sources":["../src/ollama-executor.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAyCxE;AAED,wBAAuB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,CAmD/E;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBlH"}
@@ -0,0 +1,112 @@
1
+ import { log } from "./logger.js";
2
+ export async function executeOllama(opts) {
3
+ const baseUrl = opts.baseUrl || "http://localhost:11434";
4
+ const timeout = opts.timeout || 300_000;
5
+ log.info(`[Ollama] Executing ${opts.model}: ${opts.message.slice(0, 200)}`);
6
+ const controller = new AbortController();
7
+ const timer = setTimeout(() => controller.abort(), timeout);
8
+ try {
9
+ const res = await fetch(`${baseUrl}/api/chat`, {
10
+ method: "POST",
11
+ headers: { "Content-Type": "application/json" },
12
+ body: JSON.stringify({
13
+ model: opts.model,
14
+ messages: [
15
+ { role: "system", content: opts.systemPrompt },
16
+ { role: "user", content: opts.message },
17
+ ],
18
+ stream: false,
19
+ }),
20
+ signal: controller.signal,
21
+ });
22
+ if (!res.ok) {
23
+ const errText = await res.text();
24
+ log.error(`[Ollama] Error ${res.status}: ${errText}`);
25
+ throw new Error(`Ollama API error ${res.status}: ${errText}`);
26
+ }
27
+ const data = await res.json();
28
+ if (data.error) {
29
+ throw new Error(`Ollama error: ${data.error}`);
30
+ }
31
+ const response = data.message?.content || "";
32
+ log.info(`[Ollama] Response from ${opts.model}: ${response.slice(0, 200)}`);
33
+ return response;
34
+ }
35
+ finally {
36
+ clearTimeout(timer);
37
+ }
38
+ }
39
+ export async function* streamOllama(opts) {
40
+ const baseUrl = opts.baseUrl || "http://localhost:11434";
41
+ const timeout = opts.timeout || 300_000;
42
+ log.info(`[Ollama] Streaming ${opts.model}: ${opts.message.slice(0, 200)}`);
43
+ const controller = new AbortController();
44
+ const timer = setTimeout(() => controller.abort(), timeout);
45
+ try {
46
+ const res = await fetch(`${baseUrl}/api/chat`, {
47
+ method: "POST",
48
+ headers: { "Content-Type": "application/json" },
49
+ body: JSON.stringify({
50
+ model: opts.model,
51
+ messages: [
52
+ { role: "system", content: opts.systemPrompt },
53
+ { role: "user", content: opts.message },
54
+ ],
55
+ stream: true,
56
+ }),
57
+ signal: controller.signal,
58
+ });
59
+ if (!res.ok) {
60
+ const errText = await res.text();
61
+ throw new Error(`Ollama API error ${res.status}: ${errText}`);
62
+ }
63
+ const reader = res.body?.getReader();
64
+ if (!reader)
65
+ throw new Error("No response body");
66
+ const decoder = new TextDecoder();
67
+ while (true) {
68
+ const { done, value } = await reader.read();
69
+ if (done)
70
+ break;
71
+ const chunk = decoder.decode(value, { stream: true });
72
+ // Ollama streams newline-delimited JSON
73
+ for (const line of chunk.split("\n")) {
74
+ if (!line.trim())
75
+ continue;
76
+ try {
77
+ const parsed = JSON.parse(line);
78
+ if (parsed.message?.content) {
79
+ yield parsed.message.content;
80
+ }
81
+ }
82
+ catch { /* skip unparseable lines */ }
83
+ }
84
+ }
85
+ }
86
+ finally {
87
+ clearTimeout(timer);
88
+ }
89
+ }
90
+ /**
91
+ * Check if Ollama is running and the model is available
92
+ */
93
+ export async function checkOllamaHealth(baseUrl, model) {
94
+ const url = baseUrl || "http://localhost:11434";
95
+ try {
96
+ const res = await fetch(`${url}/api/tags`);
97
+ if (!res.ok)
98
+ return { ok: false, error: `Ollama not responding (${res.status})` };
99
+ if (model) {
100
+ const data = await res.json();
101
+ const models = data.models?.map(m => m.name.replace(/:latest$/, "")) || [];
102
+ if (!models.some(m => m === model || m.startsWith(model + ":"))) {
103
+ return { ok: false, error: `Model "${model}" not found. Available: ${models.join(", ")}` };
104
+ }
105
+ }
106
+ return { ok: true };
107
+ }
108
+ catch (err) {
109
+ return { ok: false, error: `Ollama not running at ${url}: ${err}` };
110
+ }
111
+ }
112
+ //# sourceMappingURL=ollama-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama-executor.js","sourceRoot":"","sources":["../src/ollama-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * OpenAI-compatible executor — handles OpenAI, xAI (Grok), Groq, Together, Mistral,
3
+ * and any other provider that implements the OpenAI Chat Completions API.
4
+ *
5
+ * Executor format: "openai:gpt-4o", "grok:grok-3", "groq:llama-3.3-70b-versatile",
6
+ * "together:meta-llama/Llama-3.3-70B-Instruct", "mistral:mistral-large-latest"
7
+ */
8
+ export interface ProviderConfig {
9
+ name: string;
10
+ baseUrl: string;
11
+ keyField: string;
12
+ modelsEndpoint?: string;
13
+ }
14
+ export declare const PROVIDERS: Record<string, ProviderConfig>;
15
+ export interface OpenAICompatOptions {
16
+ provider: string;
17
+ model: string;
18
+ apiKey: string;
19
+ systemPrompt: string;
20
+ message: string;
21
+ baseUrl?: string;
22
+ timeout?: number;
23
+ temperature?: number;
24
+ maxTokens?: number;
25
+ }
26
+ export declare function executeOpenAICompat(opts: OpenAICompatOptions): Promise<string>;
27
+ export declare function streamOpenAICompat(opts: OpenAICompatOptions): AsyncGenerator<string>;
28
+ export declare function checkOpenAICompatHealth(provider: string, apiKey: string, baseUrl?: string): Promise<{
29
+ ok: boolean;
30
+ error?: string;
31
+ models?: string[];
32
+ }>;
33
+ /**
34
+ * Resolve provider prefix to config.
35
+ * Returns null if the prefix is not an OpenAI-compatible provider.
36
+ */
37
+ export declare function resolveProvider(prefix: string): ProviderConfig | null;
38
+ //# sourceMappingURL=openai-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-executor.d.ts","sourceRoot":"","sources":["../src/openai-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CA0BpD,CAAC;AAGF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqBD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAiEpF;AAGD,wBAAuB,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,GAAG,cAAc,CAAC,MAAM,CAAC,CAsE3F;AAGD,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA2B7D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAErE"}