cmdr-agent 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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +238 -0
  3. package/dist/bin/cmdr.d.ts +9 -0
  4. package/dist/bin/cmdr.d.ts.map +1 -0
  5. package/dist/bin/cmdr.js +49 -0
  6. package/dist/bin/cmdr.js.map +1 -0
  7. package/dist/src/cli/args.d.ts +19 -0
  8. package/dist/src/cli/args.d.ts.map +1 -0
  9. package/dist/src/cli/args.js +89 -0
  10. package/dist/src/cli/args.js.map +1 -0
  11. package/dist/src/cli/commands.d.ts +12 -0
  12. package/dist/src/cli/commands.d.ts.map +1 -0
  13. package/dist/src/cli/commands.js +400 -0
  14. package/dist/src/cli/commands.js.map +1 -0
  15. package/dist/src/cli/renderer.d.ts +8 -0
  16. package/dist/src/cli/renderer.d.ts.map +1 -0
  17. package/dist/src/cli/renderer.js +47 -0
  18. package/dist/src/cli/renderer.js.map +1 -0
  19. package/dist/src/cli/repl.d.ts +18 -0
  20. package/dist/src/cli/repl.d.ts.map +1 -0
  21. package/dist/src/cli/repl.js +751 -0
  22. package/dist/src/cli/repl.js.map +1 -0
  23. package/dist/src/cli/spinner.d.ts +16 -0
  24. package/dist/src/cli/spinner.d.ts.map +1 -0
  25. package/dist/src/cli/spinner.js +233 -0
  26. package/dist/src/cli/spinner.js.map +1 -0
  27. package/dist/src/cli/theme.d.ts +95 -0
  28. package/dist/src/cli/theme.d.ts.map +1 -0
  29. package/dist/src/cli/theme.js +178 -0
  30. package/dist/src/cli/theme.js.map +1 -0
  31. package/dist/src/communication/message-bus.d.ts +35 -0
  32. package/dist/src/communication/message-bus.d.ts.map +1 -0
  33. package/dist/src/communication/message-bus.js +60 -0
  34. package/dist/src/communication/message-bus.js.map +1 -0
  35. package/dist/src/communication/shared-memory.d.ts +19 -0
  36. package/dist/src/communication/shared-memory.d.ts.map +1 -0
  37. package/dist/src/communication/shared-memory.js +37 -0
  38. package/dist/src/communication/shared-memory.js.map +1 -0
  39. package/dist/src/communication/task-queue.d.ts +50 -0
  40. package/dist/src/communication/task-queue.d.ts.map +1 -0
  41. package/dist/src/communication/task-queue.js +158 -0
  42. package/dist/src/communication/task-queue.js.map +1 -0
  43. package/dist/src/config/config-loader.d.ts +23 -0
  44. package/dist/src/config/config-loader.d.ts.map +1 -0
  45. package/dist/src/config/config-loader.js +91 -0
  46. package/dist/src/config/config-loader.js.map +1 -0
  47. package/dist/src/config/defaults.d.ts +6 -0
  48. package/dist/src/config/defaults.d.ts.map +1 -0
  49. package/dist/src/config/defaults.js +21 -0
  50. package/dist/src/config/defaults.js.map +1 -0
  51. package/dist/src/config/schema.d.ts +135 -0
  52. package/dist/src/config/schema.d.ts.map +1 -0
  53. package/dist/src/config/schema.js +35 -0
  54. package/dist/src/config/schema.js.map +1 -0
  55. package/dist/src/config/telemetry.d.ts +41 -0
  56. package/dist/src/config/telemetry.d.ts.map +1 -0
  57. package/dist/src/config/telemetry.js +57 -0
  58. package/dist/src/config/telemetry.js.map +1 -0
  59. package/dist/src/core/agent-pool.d.ts +40 -0
  60. package/dist/src/core/agent-pool.d.ts.map +1 -0
  61. package/dist/src/core/agent-pool.js +66 -0
  62. package/dist/src/core/agent-pool.js.map +1 -0
  63. package/dist/src/core/agent-runner.d.ts +51 -0
  64. package/dist/src/core/agent-runner.d.ts.map +1 -0
  65. package/dist/src/core/agent-runner.js +251 -0
  66. package/dist/src/core/agent-runner.js.map +1 -0
  67. package/dist/src/core/agent.d.ts +34 -0
  68. package/dist/src/core/agent.d.ts.map +1 -0
  69. package/dist/src/core/agent.js +143 -0
  70. package/dist/src/core/agent.js.map +1 -0
  71. package/dist/src/core/intent.d.ts +33 -0
  72. package/dist/src/core/intent.d.ts.map +1 -0
  73. package/dist/src/core/intent.js +91 -0
  74. package/dist/src/core/intent.js.map +1 -0
  75. package/dist/src/core/orchestrator.d.ts +43 -0
  76. package/dist/src/core/orchestrator.d.ts.map +1 -0
  77. package/dist/src/core/orchestrator.js +115 -0
  78. package/dist/src/core/orchestrator.js.map +1 -0
  79. package/dist/src/core/permissions.d.ts +36 -0
  80. package/dist/src/core/permissions.d.ts.map +1 -0
  81. package/dist/src/core/permissions.js +129 -0
  82. package/dist/src/core/permissions.js.map +1 -0
  83. package/dist/src/core/presets.d.ts +12 -0
  84. package/dist/src/core/presets.d.ts.map +1 -0
  85. package/dist/src/core/presets.js +148 -0
  86. package/dist/src/core/presets.js.map +1 -0
  87. package/dist/src/core/team.d.ts +44 -0
  88. package/dist/src/core/team.d.ts.map +1 -0
  89. package/dist/src/core/team.js +156 -0
  90. package/dist/src/core/team.js.map +1 -0
  91. package/dist/src/core/types.d.ts +257 -0
  92. package/dist/src/core/types.d.ts.map +1 -0
  93. package/dist/src/core/types.js +7 -0
  94. package/dist/src/core/types.js.map +1 -0
  95. package/dist/src/index.d.ts +44 -0
  96. package/dist/src/index.d.ts.map +1 -0
  97. package/dist/src/index.js +45 -0
  98. package/dist/src/index.js.map +1 -0
  99. package/dist/src/llm/adapter.d.ts +5 -0
  100. package/dist/src/llm/adapter.d.ts.map +1 -0
  101. package/dist/src/llm/adapter.js +5 -0
  102. package/dist/src/llm/adapter.js.map +1 -0
  103. package/dist/src/llm/model-registry.d.ts +14 -0
  104. package/dist/src/llm/model-registry.d.ts.map +1 -0
  105. package/dist/src/llm/model-registry.js +30 -0
  106. package/dist/src/llm/model-registry.js.map +1 -0
  107. package/dist/src/llm/ollama.d.ts +26 -0
  108. package/dist/src/llm/ollama.d.ts.map +1 -0
  109. package/dist/src/llm/ollama.js +375 -0
  110. package/dist/src/llm/ollama.js.map +1 -0
  111. package/dist/src/llm/token-counter.d.ts +11 -0
  112. package/dist/src/llm/token-counter.d.ts.map +1 -0
  113. package/dist/src/llm/token-counter.js +35 -0
  114. package/dist/src/llm/token-counter.js.map +1 -0
  115. package/dist/src/plugins/mcp-client.d.ts +38 -0
  116. package/dist/src/plugins/mcp-client.d.ts.map +1 -0
  117. package/dist/src/plugins/mcp-client.js +113 -0
  118. package/dist/src/plugins/mcp-client.js.map +1 -0
  119. package/dist/src/plugins/plugin-manager.d.ts +37 -0
  120. package/dist/src/plugins/plugin-manager.d.ts.map +1 -0
  121. package/dist/src/plugins/plugin-manager.js +146 -0
  122. package/dist/src/plugins/plugin-manager.js.map +1 -0
  123. package/dist/src/scheduling/semaphore.d.ts +20 -0
  124. package/dist/src/scheduling/semaphore.d.ts.map +1 -0
  125. package/dist/src/scheduling/semaphore.js +52 -0
  126. package/dist/src/scheduling/semaphore.js.map +1 -0
  127. package/dist/src/scheduling/strategies.d.ts +39 -0
  128. package/dist/src/scheduling/strategies.d.ts.map +1 -0
  129. package/dist/src/scheduling/strategies.js +88 -0
  130. package/dist/src/scheduling/strategies.js.map +1 -0
  131. package/dist/src/session/compaction.d.ts +32 -0
  132. package/dist/src/session/compaction.d.ts.map +1 -0
  133. package/dist/src/session/compaction.js +172 -0
  134. package/dist/src/session/compaction.js.map +1 -0
  135. package/dist/src/session/cost-tracker.d.ts +41 -0
  136. package/dist/src/session/cost-tracker.d.ts.map +1 -0
  137. package/dist/src/session/cost-tracker.js +76 -0
  138. package/dist/src/session/cost-tracker.js.map +1 -0
  139. package/dist/src/session/project-context.d.ts +6 -0
  140. package/dist/src/session/project-context.d.ts.map +1 -0
  141. package/dist/src/session/project-context.js +147 -0
  142. package/dist/src/session/project-context.js.map +1 -0
  143. package/dist/src/session/prompt-builder.d.ts +11 -0
  144. package/dist/src/session/prompt-builder.d.ts.map +1 -0
  145. package/dist/src/session/prompt-builder.js +30 -0
  146. package/dist/src/session/prompt-builder.js.map +1 -0
  147. package/dist/src/session/session-manager.d.ts +32 -0
  148. package/dist/src/session/session-manager.d.ts.map +1 -0
  149. package/dist/src/session/session-manager.js +84 -0
  150. package/dist/src/session/session-manager.js.map +1 -0
  151. package/dist/src/session/session-persistence.d.ts +44 -0
  152. package/dist/src/session/session-persistence.d.ts.map +1 -0
  153. package/dist/src/session/session-persistence.js +150 -0
  154. package/dist/src/session/session-persistence.js.map +1 -0
  155. package/dist/src/session/undo-manager.d.ts +35 -0
  156. package/dist/src/session/undo-manager.d.ts.map +1 -0
  157. package/dist/src/session/undo-manager.js +79 -0
  158. package/dist/src/session/undo-manager.js.map +1 -0
  159. package/dist/src/tools/built-in/ask-user.d.ts +7 -0
  160. package/dist/src/tools/built-in/ask-user.d.ts.map +1 -0
  161. package/dist/src/tools/built-in/ask-user.js +28 -0
  162. package/dist/src/tools/built-in/ask-user.js.map +1 -0
  163. package/dist/src/tools/built-in/bash.d.ts +9 -0
  164. package/dist/src/tools/built-in/bash.d.ts.map +1 -0
  165. package/dist/src/tools/built-in/bash.js +67 -0
  166. package/dist/src/tools/built-in/bash.js.map +1 -0
  167. package/dist/src/tools/built-in/file-edit.d.ts +9 -0
  168. package/dist/src/tools/built-in/file-edit.d.ts.map +1 -0
  169. package/dist/src/tools/built-in/file-edit.js +39 -0
  170. package/dist/src/tools/built-in/file-edit.js.map +1 -0
  171. package/dist/src/tools/built-in/file-read.d.ts +9 -0
  172. package/dist/src/tools/built-in/file-read.d.ts.map +1 -0
  173. package/dist/src/tools/built-in/file-read.js +41 -0
  174. package/dist/src/tools/built-in/file-read.js.map +1 -0
  175. package/dist/src/tools/built-in/file-write.d.ts +8 -0
  176. package/dist/src/tools/built-in/file-write.d.ts.map +1 -0
  177. package/dist/src/tools/built-in/file-write.js +29 -0
  178. package/dist/src/tools/built-in/file-write.js.map +1 -0
  179. package/dist/src/tools/built-in/git-commit.d.ts +12 -0
  180. package/dist/src/tools/built-in/git-commit.d.ts.map +1 -0
  181. package/dist/src/tools/built-in/git-commit.js +96 -0
  182. package/dist/src/tools/built-in/git-commit.js.map +1 -0
  183. package/dist/src/tools/built-in/git-diff.d.ts +8 -0
  184. package/dist/src/tools/built-in/git-diff.d.ts.map +1 -0
  185. package/dist/src/tools/built-in/git-diff.js +43 -0
  186. package/dist/src/tools/built-in/git-diff.js.map +1 -0
  187. package/dist/src/tools/built-in/git-log.d.ts +8 -0
  188. package/dist/src/tools/built-in/git-log.d.ts.map +1 -0
  189. package/dist/src/tools/built-in/git-log.js +39 -0
  190. package/dist/src/tools/built-in/git-log.js.map +1 -0
  191. package/dist/src/tools/built-in/glob.d.ts +8 -0
  192. package/dist/src/tools/built-in/glob.d.ts.map +1 -0
  193. package/dist/src/tools/built-in/glob.js +60 -0
  194. package/dist/src/tools/built-in/glob.js.map +1 -0
  195. package/dist/src/tools/built-in/grep.d.ts +9 -0
  196. package/dist/src/tools/built-in/grep.d.ts.map +1 -0
  197. package/dist/src/tools/built-in/grep.js +115 -0
  198. package/dist/src/tools/built-in/grep.js.map +1 -0
  199. package/dist/src/tools/built-in/index.d.ts +21 -0
  200. package/dist/src/tools/built-in/index.d.ts.map +1 -0
  201. package/dist/src/tools/built-in/index.js +30 -0
  202. package/dist/src/tools/built-in/index.js.map +1 -0
  203. package/dist/src/tools/built-in/think.d.ts +7 -0
  204. package/dist/src/tools/built-in/think.d.ts.map +1 -0
  205. package/dist/src/tools/built-in/think.js +18 -0
  206. package/dist/src/tools/built-in/think.js.map +1 -0
  207. package/dist/src/tools/built-in/web-fetch.d.ts +11 -0
  208. package/dist/src/tools/built-in/web-fetch.d.ts.map +1 -0
  209. package/dist/src/tools/built-in/web-fetch.js +70 -0
  210. package/dist/src/tools/built-in/web-fetch.js.map +1 -0
  211. package/dist/src/tools/executor.d.ts +25 -0
  212. package/dist/src/tools/executor.d.ts.map +1 -0
  213. package/dist/src/tools/executor.js +61 -0
  214. package/dist/src/tools/executor.js.map +1 -0
  215. package/dist/src/tools/registry.d.ts +25 -0
  216. package/dist/src/tools/registry.d.ts.map +1 -0
  217. package/dist/src/tools/registry.js +135 -0
  218. package/dist/src/tools/registry.js.map +1 -0
  219. package/package.json +63 -0
@@ -0,0 +1,26 @@
1
+ /**
2
+ * OllamaAdapter — primary LLM backend for cmdr.
3
+ *
4
+ * Uses Ollama's /api/chat endpoint with native tool calling support.
5
+ * Falls back to prompt-based tool injection for models without tool support.
6
+ */
7
+ import type { LLMAdapter, LLMMessage, LLMChatOptions, LLMStreamOptions, LLMResponse, StreamEvent } from '../core/types.js';
8
+ export declare class OllamaAdapter implements LLMAdapter {
9
+ readonly name = "ollama";
10
+ private readonly baseUrl;
11
+ private toolCapabilityCache;
12
+ constructor(baseUrl?: string);
13
+ /** Check if Ollama is running and reachable. */
14
+ healthCheck(): Promise<boolean>;
15
+ /** List available models. */
16
+ listModels(): Promise<string[]>;
17
+ /** Check if a specific model supports native tool calling. */
18
+ supportsTools(model: string): Promise<boolean>;
19
+ chat(messages: LLMMessage[], options: LLMChatOptions): Promise<LLMResponse>;
20
+ stream(messages: LLMMessage[], options: LLMStreamOptions): AsyncIterable<StreamEvent>;
21
+ private convertMessages;
22
+ private convertToolDef;
23
+ private buildToolPromptSuffix;
24
+ private parsePromptBasedToolCalls;
25
+ }
26
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../src/llm/ollama.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,gBAAgB,EACxD,WAAW,EAAE,WAAW,EAEzB,MAAM,kBAAkB,CAAA;AAgDzB,qBAAa,aAAc,YAAW,UAAU;IAC9C,QAAQ,CAAC,IAAI,YAAW;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,mBAAmB,CAA6B;gBAE5C,OAAO,SAA2B;IAI9C,gDAAgD;IAC1C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IASrC,6BAA6B;IACvB,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAOrC,8DAA8D;IACxD,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsC9C,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IA4E1E,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAAC,WAAW,CAAC;IA0H5F,OAAO,CAAC,eAAe;IAoEvB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,yBAAyB;CA4ClC"}
@@ -0,0 +1,375 @@
1
+ /**
2
+ * OllamaAdapter — primary LLM backend for cmdr.
3
+ *
4
+ * Uses Ollama's /api/chat endpoint with native tool calling support.
5
+ * Falls back to prompt-based tool injection for models without tool support.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Models known to support native tool calling via Ollama
9
+ // ---------------------------------------------------------------------------
10
+ const TOOL_CAPABLE_FAMILIES = new Set([
11
+ 'qwen2', 'qwen2.5', 'qwen3', 'qwen3moe',
12
+ 'llama3.1', 'llama3.2', 'llama3.3', 'llama4',
13
+ 'mistral', 'mistral-nemo', 'command-r', 'firefunction',
14
+ 'granite', 'nemotron', 'hermes3',
15
+ ]);
16
+ // ---------------------------------------------------------------------------
17
+ // OllamaAdapter
18
+ // ---------------------------------------------------------------------------
19
+ export class OllamaAdapter {
20
+ name = 'ollama';
21
+ baseUrl;
22
+ toolCapabilityCache = new Map();
23
+ constructor(baseUrl = 'http://localhost:11434') {
24
+ this.baseUrl = baseUrl.replace(/\/$/, '');
25
+ }
26
+ /** Check if Ollama is running and reachable. */
27
+ async healthCheck() {
28
+ try {
29
+ const res = await fetch(`${this.baseUrl}/api/tags`);
30
+ return res.ok;
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ /** List available models. */
37
+ async listModels() {
38
+ const res = await fetch(`${this.baseUrl}/api/tags`);
39
+ if (!res.ok)
40
+ throw new Error(`Ollama /api/tags failed: ${res.status}`);
41
+ const data = await res.json();
42
+ return data.models.map(m => m.name);
43
+ }
44
+ /** Check if a specific model supports native tool calling. */
45
+ async supportsTools(model) {
46
+ const cached = this.toolCapabilityCache.get(model);
47
+ if (cached !== undefined)
48
+ return cached;
49
+ try {
50
+ const res = await fetch(`${this.baseUrl}/api/show`, {
51
+ method: 'POST',
52
+ headers: { 'Content-Type': 'application/json' },
53
+ body: JSON.stringify({ name: model }),
54
+ });
55
+ if (!res.ok) {
56
+ this.toolCapabilityCache.set(model, false);
57
+ return false;
58
+ }
59
+ const info = await res.json();
60
+ const family = info.details?.family?.toLowerCase() ?? '';
61
+ const supports = TOOL_CAPABLE_FAMILIES.has(family) ||
62
+ family.includes('qwen') ||
63
+ family.includes('llama3') ||
64
+ family.includes('llama4') ||
65
+ family.includes('mistral') ||
66
+ family.includes('gemma');
67
+ this.toolCapabilityCache.set(model, supports);
68
+ return supports;
69
+ }
70
+ catch {
71
+ this.toolCapabilityCache.set(model, false);
72
+ return false;
73
+ }
74
+ }
75
+ // -----------------------------------------------------------------------
76
+ // LLMAdapter.chat
77
+ // -----------------------------------------------------------------------
78
+ async chat(messages, options) {
79
+ const hasTools = options.tools && options.tools.length > 0;
80
+ const supportsNativeTools = hasTools ? await this.supportsTools(options.model) : false;
81
+ const body = {
82
+ model: options.model,
83
+ messages: this.convertMessages(messages, options.systemPrompt, !supportsNativeTools && hasTools ? options.tools : undefined),
84
+ stream: false,
85
+ options: {
86
+ ...(options.temperature !== undefined ? { temperature: options.temperature } : {}),
87
+ ...(options.maxTokens !== undefined ? { num_predict: options.maxTokens } : {}),
88
+ },
89
+ };
90
+ if (supportsNativeTools && options.tools) {
91
+ body.tools = options.tools.map(t => this.convertToolDef(t));
92
+ }
93
+ const res = await fetch(`${this.baseUrl}/api/chat`, {
94
+ method: 'POST',
95
+ headers: { 'Content-Type': 'application/json' },
96
+ body: JSON.stringify(body),
97
+ signal: options.abortSignal,
98
+ });
99
+ if (!res.ok) {
100
+ const text = await res.text();
101
+ throw new Error(`Ollama /api/chat failed (${res.status}): ${text}`);
102
+ }
103
+ const data = await res.json();
104
+ // Parse response - handle both native tool calls and prompt-based tool calls
105
+ const content = [];
106
+ if (data.message.tool_calls && data.message.tool_calls.length > 0) {
107
+ // Native tool calling response
108
+ if (data.message.content) {
109
+ content.push({ type: 'text', text: data.message.content });
110
+ }
111
+ for (const tc of data.message.tool_calls) {
112
+ content.push({
113
+ type: 'tool_use',
114
+ id: `tool_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
115
+ name: tc.function.name,
116
+ input: tc.function.arguments,
117
+ });
118
+ }
119
+ }
120
+ else if (hasTools && !supportsNativeTools && data.message.content) {
121
+ // Parse prompt-based tool calls from text
122
+ const parsed = this.parsePromptBasedToolCalls(data.message.content);
123
+ content.push(...parsed);
124
+ }
125
+ else {
126
+ content.push({ type: 'text', text: data.message.content || '' });
127
+ }
128
+ const usage = {
129
+ input_tokens: data.prompt_eval_count ?? 0,
130
+ output_tokens: data.eval_count ?? 0,
131
+ };
132
+ const hasToolUse = content.some(b => b.type === 'tool_use');
133
+ return {
134
+ id: `ollama_${Date.now()}`,
135
+ content,
136
+ model: data.model,
137
+ stop_reason: hasToolUse ? 'tool_use' : 'end_turn',
138
+ usage,
139
+ };
140
+ }
141
+ // -----------------------------------------------------------------------
142
+ // LLMAdapter.stream
143
+ // -----------------------------------------------------------------------
144
+ async *stream(messages, options) {
145
+ const hasTools = options.tools && options.tools.length > 0;
146
+ const supportsNativeTools = hasTools ? await this.supportsTools(options.model) : false;
147
+ const body = {
148
+ model: options.model,
149
+ messages: this.convertMessages(messages, options.systemPrompt, !supportsNativeTools && hasTools ? options.tools : undefined),
150
+ stream: true,
151
+ options: {
152
+ ...(options.temperature !== undefined ? { temperature: options.temperature } : {}),
153
+ ...(options.maxTokens !== undefined ? { num_predict: options.maxTokens } : {}),
154
+ },
155
+ };
156
+ if (supportsNativeTools && options.tools) {
157
+ body.tools = options.tools.map(t => this.convertToolDef(t));
158
+ }
159
+ const res = await fetch(`${this.baseUrl}/api/chat`, {
160
+ method: 'POST',
161
+ headers: { 'Content-Type': 'application/json' },
162
+ body: JSON.stringify(body),
163
+ signal: options.abortSignal,
164
+ });
165
+ if (!res.ok) {
166
+ const text = await res.text();
167
+ yield { type: 'error', data: new Error(`Ollama stream failed (${res.status}): ${text}`) };
168
+ return;
169
+ }
170
+ const reader = res.body?.getReader();
171
+ if (!reader) {
172
+ yield { type: 'error', data: new Error('No response body from Ollama') };
173
+ return;
174
+ }
175
+ const decoder = new TextDecoder();
176
+ let buffer = '';
177
+ let fullText = '';
178
+ let totalInputTokens = 0;
179
+ let totalOutputTokens = 0;
180
+ let model = options.model;
181
+ try {
182
+ while (true) {
183
+ const { done, value } = await reader.read();
184
+ if (done)
185
+ break;
186
+ buffer += decoder.decode(value, { stream: true });
187
+ const lines = buffer.split('\n');
188
+ buffer = lines.pop() || '';
189
+ for (const line of lines) {
190
+ if (!line.trim())
191
+ continue;
192
+ let chunk;
193
+ try {
194
+ chunk = JSON.parse(line);
195
+ }
196
+ catch {
197
+ continue;
198
+ }
199
+ model = chunk.model;
200
+ if (chunk.message?.content) {
201
+ fullText += chunk.message.content;
202
+ yield { type: 'text', data: chunk.message.content };
203
+ }
204
+ if (chunk.message?.tool_calls) {
205
+ for (const tc of chunk.message.tool_calls) {
206
+ yield {
207
+ type: 'tool_use',
208
+ data: {
209
+ type: 'tool_use',
210
+ id: `tool_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
211
+ name: tc.function.name,
212
+ input: tc.function.arguments,
213
+ },
214
+ };
215
+ }
216
+ }
217
+ if (chunk.done) {
218
+ totalInputTokens = chunk.prompt_eval_count ?? 0;
219
+ totalOutputTokens = chunk.eval_count ?? 0;
220
+ }
221
+ }
222
+ }
223
+ }
224
+ finally {
225
+ reader.releaseLock();
226
+ }
227
+ // Check for prompt-based tool calls if model doesn't support native tools
228
+ if (hasTools && !supportsNativeTools && fullText) {
229
+ const parsed = this.parsePromptBasedToolCalls(fullText);
230
+ const toolBlocks = parsed.filter(b => b.type === 'tool_use');
231
+ for (const block of toolBlocks) {
232
+ yield { type: 'tool_use', data: block };
233
+ }
234
+ }
235
+ const finalContent = fullText
236
+ ? [{ type: 'text', text: fullText }]
237
+ : [];
238
+ const response = {
239
+ id: `ollama_${Date.now()}`,
240
+ content: finalContent,
241
+ model,
242
+ stop_reason: 'end_turn',
243
+ usage: { input_tokens: totalInputTokens, output_tokens: totalOutputTokens },
244
+ };
245
+ yield { type: 'done', data: response };
246
+ }
247
+ // -----------------------------------------------------------------------
248
+ // Private helpers
249
+ // -----------------------------------------------------------------------
250
+ convertMessages(messages, systemPrompt, fallbackTools) {
251
+ const result = [];
252
+ // System prompt
253
+ let sysContent = systemPrompt || '';
254
+ if (fallbackTools && fallbackTools.length > 0) {
255
+ sysContent += this.buildToolPromptSuffix(fallbackTools);
256
+ }
257
+ if (sysContent) {
258
+ result.push({ role: 'system', content: sysContent });
259
+ }
260
+ // Conversation messages
261
+ for (const msg of messages) {
262
+ if (msg.role === 'user') {
263
+ const textParts = [];
264
+ const toolResults = [];
265
+ for (const block of msg.content) {
266
+ if (block.type === 'text') {
267
+ textParts.push(block.text);
268
+ }
269
+ else if (block.type === 'tool_result') {
270
+ toolResults.push({
271
+ type: 'tool_result',
272
+ tool_use_id: block.tool_use_id,
273
+ content: block.content,
274
+ });
275
+ }
276
+ }
277
+ if (toolResults.length > 0) {
278
+ // Ollama expects tool results as separate messages with role 'tool'
279
+ for (const tr of toolResults) {
280
+ result.push({ role: 'tool', content: tr.content });
281
+ }
282
+ }
283
+ else {
284
+ result.push({ role: 'user', content: textParts.join('\n') });
285
+ }
286
+ }
287
+ else if (msg.role === 'assistant') {
288
+ const text = msg.content
289
+ .filter((b) => b.type === 'text')
290
+ .map(b => b.text)
291
+ .join('');
292
+ const toolCalls = msg.content
293
+ .filter((b) => b.type === 'tool_use')
294
+ .map(b => ({
295
+ function: { name: b.name, arguments: b.input },
296
+ }));
297
+ const assistantMsg = {
298
+ role: 'assistant',
299
+ content: text,
300
+ };
301
+ if (toolCalls.length > 0) {
302
+ assistantMsg.tool_calls = toolCalls;
303
+ }
304
+ result.push(assistantMsg);
305
+ }
306
+ }
307
+ return result;
308
+ }
309
+ convertToolDef(tool) {
310
+ return {
311
+ type: 'function',
312
+ function: {
313
+ name: tool.name,
314
+ description: tool.description,
315
+ parameters: tool.inputSchema,
316
+ },
317
+ };
318
+ }
319
+ buildToolPromptSuffix(tools) {
320
+ const toolDescs = tools.map(t => `- ${t.name}: ${t.description}\n Input: ${JSON.stringify(t.inputSchema)}`).join('\n');
321
+ return `\n\nYou have access to the following tools. To use a tool, respond with a JSON block:
322
+
323
+ \`\`\`tool_call
324
+ {"name": "tool_name", "arguments": {"arg1": "value1"}}
325
+ \`\`\`
326
+
327
+ Available tools:
328
+ ${toolDescs}
329
+
330
+ Always use tools when you need to interact with the filesystem or run commands.
331
+ After receiving a tool result, continue your analysis.`;
332
+ }
333
+ parsePromptBasedToolCalls(text) {
334
+ const content = [];
335
+ const toolCallRegex = /```tool_call\s*\n([\s\S]*?)\n```/g;
336
+ let lastIndex = 0;
337
+ let match;
338
+ while ((match = toolCallRegex.exec(text)) !== null) {
339
+ // Add text before the tool call
340
+ if (match.index > lastIndex) {
341
+ const before = text.slice(lastIndex, match.index).trim();
342
+ if (before)
343
+ content.push({ type: 'text', text: before });
344
+ }
345
+ try {
346
+ const parsed = JSON.parse(match[1]);
347
+ if (parsed.name && parsed.arguments) {
348
+ content.push({
349
+ type: 'tool_use',
350
+ id: `tool_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
351
+ name: parsed.name,
352
+ input: parsed.arguments,
353
+ });
354
+ }
355
+ }
356
+ catch {
357
+ // Malformed JSON — keep as text
358
+ content.push({ type: 'text', text: match[0] });
359
+ }
360
+ lastIndex = match.index + match[0].length;
361
+ }
362
+ // Add remaining text
363
+ if (lastIndex < text.length) {
364
+ const remainder = text.slice(lastIndex).trim();
365
+ if (remainder)
366
+ content.push({ type: 'text', text: remainder });
367
+ }
368
+ // If no tool calls found, return as pure text
369
+ if (content.length === 0 && text) {
370
+ content.push({ type: 'text', text });
371
+ }
372
+ return content;
373
+ }
374
+ }
375
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../src/llm/ollama.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Approximate token counter for context management.
3
+ *
4
+ * Uses a simple heuristic: ~4 characters per token for English text.
5
+ * Good enough for context budget tracking; not for billing.
6
+ */
7
+ export declare function countTokens(text: string): number;
8
+ export declare function countMessageTokens(messages: Array<{
9
+ content: unknown;
10
+ }>): number;
11
+ //# sourceMappingURL=token-counter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-counter.d.ts","sourceRoot":"","sources":["../../../src/llm/token-counter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,MAAM,CAoBhF"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Approximate token counter for context management.
3
+ *
4
+ * Uses a simple heuristic: ~4 characters per token for English text.
5
+ * Good enough for context budget tracking; not for billing.
6
+ */
7
+ const CHARS_PER_TOKEN = 4;
8
+ export function countTokens(text) {
9
+ return Math.ceil(text.length / CHARS_PER_TOKEN);
10
+ }
11
+ export function countMessageTokens(messages) {
12
+ let total = 0;
13
+ for (const msg of messages) {
14
+ if (typeof msg.content === 'string') {
15
+ total += countTokens(msg.content);
16
+ }
17
+ else if (Array.isArray(msg.content)) {
18
+ for (const block of msg.content) {
19
+ if (typeof block === 'object' && block !== null) {
20
+ if ('text' in block && typeof block.text === 'string') {
21
+ total += countTokens(block.text);
22
+ }
23
+ else if ('content' in block && typeof block.content === 'string') {
24
+ total += countTokens(block.content);
25
+ }
26
+ else {
27
+ total += countTokens(JSON.stringify(block));
28
+ }
29
+ }
30
+ }
31
+ }
32
+ }
33
+ return total;
34
+ }
35
+ //# sourceMappingURL=token-counter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-counter.js","sourceRoot":"","sources":["../../../src/llm/token-counter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,eAAe,GAAG,CAAC,CAAA;AAEzB,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAqC;IACtE,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACpC,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACnC,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;oBAChD,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBACtD,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;oBAClC,CAAC;yBAAM,IAAI,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;wBACnE,KAAK,IAAI,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;oBACrC,CAAC;yBAAM,CAAC;wBACN,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;oBAC7C,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * MCP Client — connects to external Model Context Protocol servers for tool expansion.
3
+ *
4
+ * MCP servers expose tools over HTTP (SSE or REST).
5
+ * This client registers remote tools as local tool definitions.
6
+ */
7
+ import type { McpServerConfig, ToolResult } from '../core/types.js';
8
+ import type { ToolRegistry } from '../tools/registry.js';
9
+ interface McpTool {
10
+ name: string;
11
+ description: string;
12
+ inputSchema: Record<string, unknown>;
13
+ }
14
+ export declare class McpClient {
15
+ private connections;
16
+ /** Connect to an MCP server and discover its tools. */
17
+ connect(config: McpServerConfig): Promise<McpTool[]>;
18
+ /** Disconnect from an MCP server. */
19
+ disconnect(name: string): boolean;
20
+ /** List connected MCP servers. */
21
+ listConnections(): Array<{
22
+ name: string;
23
+ url: string;
24
+ tools: number;
25
+ connected: boolean;
26
+ }>;
27
+ /** Call a tool on an MCP server. */
28
+ callTool(serverName: string, toolName: string, input: Record<string, unknown>): Promise<ToolResult>;
29
+ /**
30
+ * Register all tools from connected MCP servers into a ToolRegistry.
31
+ * Tools are prefixed with `mcp_{serverName}_` to avoid collisions.
32
+ */
33
+ registerTools(registry: ToolRegistry): number;
34
+ /** Check if any servers are connected. */
35
+ get hasConnections(): boolean;
36
+ }
37
+ export {};
38
+ //# sourceMappingURL=mcp-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../../src/plugins/mcp-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAkB,UAAU,EAAkB,MAAM,kBAAkB,CAAA;AACnG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAGxD,UAAU,OAAO;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACrC;AAQD,qBAAa,SAAS;IACpB,OAAO,CAAC,WAAW,CAAmC;IAEtD,uDAAuD;IACjD,OAAO,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IA8B1D,qCAAqC;IACrC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,kCAAkC;IAClC,eAAe,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAS1F,oCAAoC;IAC9B,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,UAAU,CAAC;IAmCtB;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM;IAyB7C,0CAA0C;IAC1C,IAAI,cAAc,IAAI,OAAO,CAE5B;CACF"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * MCP Client — connects to external Model Context Protocol servers for tool expansion.
3
+ *
4
+ * MCP servers expose tools over HTTP (SSE or REST).
5
+ * This client registers remote tools as local tool definitions.
6
+ */
7
+ import { z } from 'zod';
8
+ export class McpClient {
9
+ connections = new Map();
10
+ /** Connect to an MCP server and discover its tools. */
11
+ async connect(config) {
12
+ const url = config.url.replace(/\/$/, '');
13
+ const headers = {
14
+ 'Content-Type': 'application/json',
15
+ };
16
+ if (config.apiKey) {
17
+ headers['Authorization'] = `Bearer ${config.apiKey}`;
18
+ }
19
+ try {
20
+ const response = await fetch(`${url}/tools`, { headers });
21
+ if (!response.ok) {
22
+ throw new Error(`MCP server returned ${response.status}: ${response.statusText}`);
23
+ }
24
+ const data = await response.json();
25
+ const tools = data.tools ?? [];
26
+ this.connections.set(config.name, {
27
+ config,
28
+ tools,
29
+ connected: true,
30
+ });
31
+ return tools;
32
+ }
33
+ catch (err) {
34
+ const msg = err instanceof Error ? err.message : String(err);
35
+ throw new Error(`Failed to connect to MCP server "${config.name}" at ${config.url}: ${msg}`);
36
+ }
37
+ }
38
+ /** Disconnect from an MCP server. */
39
+ disconnect(name) {
40
+ return this.connections.delete(name);
41
+ }
42
+ /** List connected MCP servers. */
43
+ listConnections() {
44
+ return Array.from(this.connections.values()).map(c => ({
45
+ name: c.config.name,
46
+ url: c.config.url,
47
+ tools: c.tools.length,
48
+ connected: c.connected,
49
+ }));
50
+ }
51
+ /** Call a tool on an MCP server. */
52
+ async callTool(serverName, toolName, input) {
53
+ const conn = this.connections.get(serverName);
54
+ if (!conn)
55
+ throw new Error(`Not connected to MCP server "${serverName}"`);
56
+ const url = conn.config.url.replace(/\/$/, '');
57
+ const headers = {
58
+ 'Content-Type': 'application/json',
59
+ };
60
+ if (conn.config.apiKey) {
61
+ headers['Authorization'] = `Bearer ${conn.config.apiKey}`;
62
+ }
63
+ try {
64
+ const response = await fetch(`${url}/tools/${toolName}`, {
65
+ method: 'POST',
66
+ headers,
67
+ body: JSON.stringify({ input }),
68
+ });
69
+ if (!response.ok) {
70
+ const text = await response.text();
71
+ return { data: `MCP tool error (${response.status}): ${text}`, isError: true };
72
+ }
73
+ const data = await response.json();
74
+ if (data.error) {
75
+ return { data: data.error, isError: true };
76
+ }
77
+ return { data: data.result ?? JSON.stringify(data) };
78
+ }
79
+ catch (err) {
80
+ const msg = err instanceof Error ? err.message : String(err);
81
+ return { data: `MCP call failed: ${msg}`, isError: true };
82
+ }
83
+ }
84
+ /**
85
+ * Register all tools from connected MCP servers into a ToolRegistry.
86
+ * Tools are prefixed with `mcp_{serverName}_` to avoid collisions.
87
+ */
88
+ registerTools(registry) {
89
+ let count = 0;
90
+ for (const [serverName, conn] of this.connections) {
91
+ for (const mcpTool of conn.tools) {
92
+ const toolName = `mcp_${serverName}_${mcpTool.name}`;
93
+ const client = this;
94
+ const tool = {
95
+ name: toolName,
96
+ description: `[MCP:${serverName}] ${mcpTool.description}`,
97
+ inputSchema: z.record(z.unknown()),
98
+ async execute(input, _context) {
99
+ return client.callTool(serverName, mcpTool.name, input);
100
+ },
101
+ };
102
+ registry.register(tool);
103
+ count++;
104
+ }
105
+ }
106
+ return count;
107
+ }
108
+ /** Check if any servers are connected. */
109
+ get hasConnections() {
110
+ return this.connections.size > 0;
111
+ }
112
+ }
113
+ //# sourceMappingURL=mcp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.js","sourceRoot":"","sources":["../../../src/plugins/mcp-client.ts"],"names":[],"mappings":"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"}