@mcoda/codali 0.1.66

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 (241) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/LICENSE +21 -0
  3. package/README.md +111 -0
  4. package/dist/agents/AgentProtocol.d.ts +287 -0
  5. package/dist/agents/AgentProtocol.d.ts.map +1 -0
  6. package/dist/agents/AgentProtocol.js +365 -0
  7. package/dist/agents/AgentResolver.d.ts +23 -0
  8. package/dist/agents/AgentResolver.d.ts.map +1 -0
  9. package/dist/agents/AgentResolver.js +77 -0
  10. package/dist/agents/PhaseAgentSelector.d.ts +23 -0
  11. package/dist/agents/PhaseAgentSelector.d.ts.map +1 -0
  12. package/dist/agents/PhaseAgentSelector.js +287 -0
  13. package/dist/cli/EvalCommand.d.ts +37 -0
  14. package/dist/cli/EvalCommand.d.ts.map +1 -0
  15. package/dist/cli/EvalCommand.js +333 -0
  16. package/dist/cli/FeedbackCommand.d.ts +22 -0
  17. package/dist/cli/FeedbackCommand.d.ts.map +1 -0
  18. package/dist/cli/FeedbackCommand.js +163 -0
  19. package/dist/cli/RunCommand.d.ts +78 -0
  20. package/dist/cli/RunCommand.d.ts.map +1 -0
  21. package/dist/cli/RunCommand.js +2261 -0
  22. package/dist/cli.d.ts +3 -0
  23. package/dist/cli.d.ts.map +1 -0
  24. package/dist/cli.js +109 -0
  25. package/dist/cognitive/ArchitectPlanner.d.ts +107 -0
  26. package/dist/cognitive/ArchitectPlanner.d.ts.map +1 -0
  27. package/dist/cognitive/ArchitectPlanner.js +1726 -0
  28. package/dist/cognitive/BuilderOutputParser.d.ts +25 -0
  29. package/dist/cognitive/BuilderOutputParser.d.ts.map +1 -0
  30. package/dist/cognitive/BuilderOutputParser.js +164 -0
  31. package/dist/cognitive/BuilderRunner.d.ts +76 -0
  32. package/dist/cognitive/BuilderRunner.d.ts.map +1 -0
  33. package/dist/cognitive/BuilderRunner.js +1159 -0
  34. package/dist/cognitive/ContextAssembler.d.ts +91 -0
  35. package/dist/cognitive/ContextAssembler.d.ts.map +1 -0
  36. package/dist/cognitive/ContextAssembler.js +4547 -0
  37. package/dist/cognitive/ContextBudget.d.ts +19 -0
  38. package/dist/cognitive/ContextBudget.d.ts.map +1 -0
  39. package/dist/cognitive/ContextBudget.js +35 -0
  40. package/dist/cognitive/ContextFileLoader.d.ts +30 -0
  41. package/dist/cognitive/ContextFileLoader.d.ts.map +1 -0
  42. package/dist/cognitive/ContextFileLoader.js +307 -0
  43. package/dist/cognitive/ContextManager.d.ts +47 -0
  44. package/dist/cognitive/ContextManager.d.ts.map +1 -0
  45. package/dist/cognitive/ContextManager.js +272 -0
  46. package/dist/cognitive/ContextRedactor.d.ts +18 -0
  47. package/dist/cognitive/ContextRedactor.d.ts.map +1 -0
  48. package/dist/cognitive/ContextRedactor.js +53 -0
  49. package/dist/cognitive/ContextSelector.d.ts +22 -0
  50. package/dist/cognitive/ContextSelector.d.ts.map +1 -0
  51. package/dist/cognitive/ContextSelector.js +431 -0
  52. package/dist/cognitive/ContextSerializer.d.ts +8 -0
  53. package/dist/cognitive/ContextSerializer.d.ts.map +1 -0
  54. package/dist/cognitive/ContextSerializer.js +882 -0
  55. package/dist/cognitive/ContextStore.d.ts +27 -0
  56. package/dist/cognitive/ContextStore.d.ts.map +1 -0
  57. package/dist/cognitive/ContextStore.js +79 -0
  58. package/dist/cognitive/ContextSummarizer.d.ts +16 -0
  59. package/dist/cognitive/ContextSummarizer.d.ts.map +1 -0
  60. package/dist/cognitive/ContextSummarizer.js +45 -0
  61. package/dist/cognitive/CostEstimator.d.ts +31 -0
  62. package/dist/cognitive/CostEstimator.d.ts.map +1 -0
  63. package/dist/cognitive/CostEstimator.js +66 -0
  64. package/dist/cognitive/CriticEvaluator.d.ts +32 -0
  65. package/dist/cognitive/CriticEvaluator.d.ts.map +1 -0
  66. package/dist/cognitive/CriticEvaluator.js +297 -0
  67. package/dist/cognitive/EvidenceGate.d.ts +9 -0
  68. package/dist/cognitive/EvidenceGate.d.ts.map +1 -0
  69. package/dist/cognitive/EvidenceGate.js +75 -0
  70. package/dist/cognitive/GoldenExampleIndexer.d.ts +12 -0
  71. package/dist/cognitive/GoldenExampleIndexer.d.ts.map +1 -0
  72. package/dist/cognitive/GoldenExampleIndexer.js +34 -0
  73. package/dist/cognitive/GoldenSetStore.d.ts +33 -0
  74. package/dist/cognitive/GoldenSetStore.d.ts.map +1 -0
  75. package/dist/cognitive/GoldenSetStore.js +159 -0
  76. package/dist/cognitive/IntentSignals.d.ts +7 -0
  77. package/dist/cognitive/IntentSignals.d.ts.map +1 -0
  78. package/dist/cognitive/IntentSignals.js +285 -0
  79. package/dist/cognitive/LearningGovernance.d.ts +100 -0
  80. package/dist/cognitive/LearningGovernance.d.ts.map +1 -0
  81. package/dist/cognitive/LearningGovernance.js +276 -0
  82. package/dist/cognitive/MemoryWriteback.d.ts +64 -0
  83. package/dist/cognitive/MemoryWriteback.d.ts.map +1 -0
  84. package/dist/cognitive/MemoryWriteback.js +287 -0
  85. package/dist/cognitive/PatchApplier.d.ts +49 -0
  86. package/dist/cognitive/PatchApplier.d.ts.map +1 -0
  87. package/dist/cognitive/PatchApplier.js +199 -0
  88. package/dist/cognitive/PatchInterpreter.d.ts +35 -0
  89. package/dist/cognitive/PatchInterpreter.d.ts.map +1 -0
  90. package/dist/cognitive/PatchInterpreter.js +100 -0
  91. package/dist/cognitive/PatchOutputNormalizer.d.ts +7 -0
  92. package/dist/cognitive/PatchOutputNormalizer.d.ts.map +1 -0
  93. package/dist/cognitive/PatchOutputNormalizer.js +59 -0
  94. package/dist/cognitive/PostMortemAnalyzer.d.ts +17 -0
  95. package/dist/cognitive/PostMortemAnalyzer.d.ts.map +1 -0
  96. package/dist/cognitive/PostMortemAnalyzer.js +131 -0
  97. package/dist/cognitive/PreferenceExtraction.d.ts +3 -0
  98. package/dist/cognitive/PreferenceExtraction.d.ts.map +1 -0
  99. package/dist/cognitive/PreferenceExtraction.js +85 -0
  100. package/dist/cognitive/Prompts.d.ts +15 -0
  101. package/dist/cognitive/Prompts.d.ts.map +1 -0
  102. package/dist/cognitive/Prompts.js +326 -0
  103. package/dist/cognitive/ProviderRouting.d.ts +16 -0
  104. package/dist/cognitive/ProviderRouting.d.ts.map +1 -0
  105. package/dist/cognitive/ProviderRouting.js +24 -0
  106. package/dist/cognitive/QueryExtraction.d.ts +12 -0
  107. package/dist/cognitive/QueryExtraction.d.ts.map +1 -0
  108. package/dist/cognitive/QueryExtraction.js +262 -0
  109. package/dist/cognitive/RunHistoryIndexer.d.ts +13 -0
  110. package/dist/cognitive/RunHistoryIndexer.d.ts.map +1 -0
  111. package/dist/cognitive/RunHistoryIndexer.js +125 -0
  112. package/dist/cognitive/SmartPipeline.d.ts +92 -0
  113. package/dist/cognitive/SmartPipeline.d.ts.map +1 -0
  114. package/dist/cognitive/SmartPipeline.js +4804 -0
  115. package/dist/cognitive/Types.d.ts +474 -0
  116. package/dist/cognitive/Types.d.ts.map +1 -0
  117. package/dist/cognitive/Types.js +7 -0
  118. package/dist/cognitive/ValidationRunner.d.ts +57 -0
  119. package/dist/cognitive/ValidationRunner.d.ts.map +1 -0
  120. package/dist/cognitive/ValidationRunner.js +515 -0
  121. package/dist/config/Config.d.ts +249 -0
  122. package/dist/config/Config.d.ts.map +1 -0
  123. package/dist/config/Config.js +200 -0
  124. package/dist/config/ConfigLoader.d.ts +56 -0
  125. package/dist/config/ConfigLoader.d.ts.map +1 -0
  126. package/dist/config/ConfigLoader.js +1246 -0
  127. package/dist/docdex/DocdexClient.d.ts +159 -0
  128. package/dist/docdex/DocdexClient.d.ts.map +1 -0
  129. package/dist/docdex/DocdexClient.js +838 -0
  130. package/dist/eval/EvalRunner.d.ts +35 -0
  131. package/dist/eval/EvalRunner.d.ts.map +1 -0
  132. package/dist/eval/EvalRunner.js +38 -0
  133. package/dist/eval/EvalTaskExecutor.d.ts +81 -0
  134. package/dist/eval/EvalTaskExecutor.d.ts.map +1 -0
  135. package/dist/eval/EvalTaskExecutor.js +371 -0
  136. package/dist/eval/GateEvaluator.d.ts +31 -0
  137. package/dist/eval/GateEvaluator.d.ts.map +1 -0
  138. package/dist/eval/GateEvaluator.js +134 -0
  139. package/dist/eval/MetricTypes.d.ts +28 -0
  140. package/dist/eval/MetricTypes.d.ts.map +1 -0
  141. package/dist/eval/MetricTypes.js +1 -0
  142. package/dist/eval/MetricsAggregator.d.ts +4 -0
  143. package/dist/eval/MetricsAggregator.d.ts.map +1 -0
  144. package/dist/eval/MetricsAggregator.js +97 -0
  145. package/dist/eval/RegressionComparator.d.ts +29 -0
  146. package/dist/eval/RegressionComparator.d.ts.map +1 -0
  147. package/dist/eval/RegressionComparator.js +155 -0
  148. package/dist/eval/ReportInputAdapter.d.ts +52 -0
  149. package/dist/eval/ReportInputAdapter.d.ts.map +1 -0
  150. package/dist/eval/ReportInputAdapter.js +229 -0
  151. package/dist/eval/ReportSerializer.d.ts +32 -0
  152. package/dist/eval/ReportSerializer.d.ts.map +1 -0
  153. package/dist/eval/ReportSerializer.js +33 -0
  154. package/dist/eval/ReportStore.d.ts +18 -0
  155. package/dist/eval/ReportStore.d.ts.map +1 -0
  156. package/dist/eval/ReportStore.js +96 -0
  157. package/dist/eval/SuiteLoader.d.ts +12 -0
  158. package/dist/eval/SuiteLoader.d.ts.map +1 -0
  159. package/dist/eval/SuiteLoader.js +51 -0
  160. package/dist/eval/SuiteSchema.d.ts +56 -0
  161. package/dist/eval/SuiteSchema.d.ts.map +1 -0
  162. package/dist/eval/SuiteSchema.js +357 -0
  163. package/dist/index.d.ts +11 -0
  164. package/dist/index.d.ts.map +1 -0
  165. package/dist/index.js +5 -0
  166. package/dist/providers/CodexCliProvider.d.ts +8 -0
  167. package/dist/providers/CodexCliProvider.d.ts.map +1 -0
  168. package/dist/providers/CodexCliProvider.js +282 -0
  169. package/dist/providers/OllamaRemoteProvider.d.ts +8 -0
  170. package/dist/providers/OllamaRemoteProvider.d.ts.map +1 -0
  171. package/dist/providers/OllamaRemoteProvider.js +300 -0
  172. package/dist/providers/OpenAiCompatibleProvider.d.ts +8 -0
  173. package/dist/providers/OpenAiCompatibleProvider.d.ts.map +1 -0
  174. package/dist/providers/OpenAiCompatibleProvider.js +192 -0
  175. package/dist/providers/ProviderRegistry.d.ts +12 -0
  176. package/dist/providers/ProviderRegistry.d.ts.map +1 -0
  177. package/dist/providers/ProviderRegistry.js +28 -0
  178. package/dist/providers/ProviderTypes.d.ts +81 -0
  179. package/dist/providers/ProviderTypes.d.ts.map +1 -0
  180. package/dist/providers/ProviderTypes.js +1 -0
  181. package/dist/runtime/CodaliRuntime.d.ts +189 -0
  182. package/dist/runtime/CodaliRuntime.d.ts.map +1 -0
  183. package/dist/runtime/CodaliRuntime.js +1435 -0
  184. package/dist/runtime/DeepInvestigationErrors.d.ts +39 -0
  185. package/dist/runtime/DeepInvestigationErrors.d.ts.map +1 -0
  186. package/dist/runtime/DeepInvestigationErrors.js +57 -0
  187. package/dist/runtime/RunContext.d.ts +27 -0
  188. package/dist/runtime/RunContext.d.ts.map +1 -0
  189. package/dist/runtime/RunContext.js +51 -0
  190. package/dist/runtime/RunLogQuery.d.ts +48 -0
  191. package/dist/runtime/RunLogQuery.d.ts.map +1 -0
  192. package/dist/runtime/RunLogQuery.js +36 -0
  193. package/dist/runtime/RunLogReader.d.ts +19 -0
  194. package/dist/runtime/RunLogReader.d.ts.map +1 -0
  195. package/dist/runtime/RunLogReader.js +361 -0
  196. package/dist/runtime/RunLogger.d.ts +71 -0
  197. package/dist/runtime/RunLogger.d.ts.map +1 -0
  198. package/dist/runtime/RunLogger.js +100 -0
  199. package/dist/runtime/RunTelemetryTypes.d.ts +117 -0
  200. package/dist/runtime/RunTelemetryTypes.d.ts.map +1 -0
  201. package/dist/runtime/RunTelemetryTypes.js +299 -0
  202. package/dist/runtime/Runner.d.ts +66 -0
  203. package/dist/runtime/Runner.d.ts.map +1 -0
  204. package/dist/runtime/Runner.js +215 -0
  205. package/dist/runtime/StoragePaths.d.ts +3 -0
  206. package/dist/runtime/StoragePaths.d.ts.map +1 -0
  207. package/dist/runtime/StoragePaths.js +19 -0
  208. package/dist/runtime/WorkspaceLock.d.ts +30 -0
  209. package/dist/runtime/WorkspaceLock.d.ts.map +1 -0
  210. package/dist/runtime/WorkspaceLock.js +141 -0
  211. package/dist/session/InstructionLoader.d.ts +14 -0
  212. package/dist/session/InstructionLoader.d.ts.map +1 -0
  213. package/dist/session/InstructionLoader.js +107 -0
  214. package/dist/session/SessionStore.d.ts +81 -0
  215. package/dist/session/SessionStore.d.ts.map +1 -0
  216. package/dist/session/SessionStore.js +244 -0
  217. package/dist/subagents/SubagentOrchestrator.d.ts +68 -0
  218. package/dist/subagents/SubagentOrchestrator.d.ts.map +1 -0
  219. package/dist/subagents/SubagentOrchestrator.js +150 -0
  220. package/dist/tools/ToolRegistry.d.ts +9 -0
  221. package/dist/tools/ToolRegistry.d.ts.map +1 -0
  222. package/dist/tools/ToolRegistry.js +293 -0
  223. package/dist/tools/ToolTypes.d.ts +66 -0
  224. package/dist/tools/ToolTypes.d.ts.map +1 -0
  225. package/dist/tools/ToolTypes.js +40 -0
  226. package/dist/tools/diff/DiffTool.d.ts +3 -0
  227. package/dist/tools/diff/DiffTool.d.ts.map +1 -0
  228. package/dist/tools/diff/DiffTool.js +34 -0
  229. package/dist/tools/docdex/DocdexTools.d.ts +4 -0
  230. package/dist/tools/docdex/DocdexTools.d.ts.map +1 -0
  231. package/dist/tools/docdex/DocdexTools.js +490 -0
  232. package/dist/tools/filesystem/FileTools.d.ts +3 -0
  233. package/dist/tools/filesystem/FileTools.d.ts.map +1 -0
  234. package/dist/tools/filesystem/FileTools.js +141 -0
  235. package/dist/tools/search/SearchTool.d.ts +3 -0
  236. package/dist/tools/search/SearchTool.d.ts.map +1 -0
  237. package/dist/tools/search/SearchTool.js +46 -0
  238. package/dist/tools/shell/ShellTool.d.ts +3 -0
  239. package/dist/tools/shell/ShellTool.d.ts.map +1 -0
  240. package/dist/tools/shell/ShellTool.js +104 -0
  241. package/package.json +44 -0
@@ -0,0 +1,300 @@
1
+ const parseToolArgs = (raw) => {
2
+ if (typeof raw !== "string")
3
+ return raw;
4
+ try {
5
+ return JSON.parse(raw);
6
+ }
7
+ catch {
8
+ return raw;
9
+ }
10
+ };
11
+ const isObject = (value) => {
12
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13
+ };
14
+ const toToolCalls = (value) => {
15
+ if (!value)
16
+ return [];
17
+ if (Array.isArray(value)) {
18
+ return value.flatMap((entry) => toToolCalls(entry));
19
+ }
20
+ if (!isObject(value))
21
+ return [];
22
+ if (Array.isArray(value.tool_calls)) {
23
+ return toToolCalls(value.tool_calls);
24
+ }
25
+ const functionPayload = isObject(value.function) ? value.function : undefined;
26
+ if (functionPayload && typeof functionPayload.name === "string") {
27
+ const rawArgs = functionPayload.arguments ?? functionPayload.args ?? {};
28
+ return [
29
+ {
30
+ id: `call_1`,
31
+ name: functionPayload.name,
32
+ args: parseToolArgs(rawArgs),
33
+ },
34
+ ];
35
+ }
36
+ const name = (typeof value.tool === "string" && value.tool) ||
37
+ (typeof value.name === "string" && value.name) ||
38
+ (typeof value.tool_name === "string" && value.tool_name);
39
+ if (!name)
40
+ return [];
41
+ const rawArgs = (value.args ?? value.arguments ?? value.params ?? value.parameters ?? {});
42
+ return [
43
+ {
44
+ id: `call_1`,
45
+ name,
46
+ args: parseToolArgs(rawArgs),
47
+ },
48
+ ];
49
+ };
50
+ const extractToolCallsFromContent = (content) => {
51
+ if (!content)
52
+ return [];
53
+ const trimmed = content.trim();
54
+ const jsonBlocks = [];
55
+ const fenceRegex = /```(?:json)?\s*([\s\S]*?)```/gi;
56
+ let match;
57
+ while ((match = fenceRegex.exec(content)) !== null) {
58
+ const block = match[1]?.trim();
59
+ if (block)
60
+ jsonBlocks.push(block);
61
+ }
62
+ if (jsonBlocks.length === 0 && (trimmed.startsWith("{") || trimmed.startsWith("["))) {
63
+ jsonBlocks.push(trimmed);
64
+ }
65
+ for (const block of jsonBlocks) {
66
+ try {
67
+ const parsed = JSON.parse(block);
68
+ const calls = toToolCalls(parsed);
69
+ if (calls.length) {
70
+ return calls.map((call, index) => ({ ...call, id: `call_${index + 1}` }));
71
+ }
72
+ }
73
+ catch {
74
+ // ignore parsing errors
75
+ }
76
+ }
77
+ return [];
78
+ };
79
+ const normalizeBaseUrl = (baseUrl) => {
80
+ const root = baseUrl ?? "http://127.0.0.1:11434";
81
+ return root.endsWith("/") ? root : `${root}/`;
82
+ };
83
+ const parseModelNotFound = (errorBody) => {
84
+ const match = errorBody.match(/model ['"]?([^'"]+)['"]? not found/i);
85
+ return match?.[1];
86
+ };
87
+ const fetchModelTags = async (baseUrl) => {
88
+ const url = new URL("api/tags", baseUrl).toString();
89
+ const resp = await fetch(url, { method: "GET" });
90
+ if (!resp.ok) {
91
+ return [];
92
+ }
93
+ try {
94
+ const data = (await resp.json());
95
+ return (data.models ?? []).map((entry) => entry.name).filter((name) => Boolean(name));
96
+ }
97
+ catch {
98
+ return [];
99
+ }
100
+ };
101
+ const pickFallbackModel = (requested, available) => {
102
+ if (!available.length)
103
+ return undefined;
104
+ const normalized = requested.toLowerCase();
105
+ const exact = available.find((name) => name.toLowerCase() === normalized);
106
+ if (exact)
107
+ return undefined;
108
+ const base = requested.split(":")[0]?.toLowerCase();
109
+ if (!base)
110
+ return undefined;
111
+ const candidates = available.filter((name) => name.toLowerCase() === base || name.toLowerCase().startsWith(`${base}:`));
112
+ if (!candidates.length)
113
+ return undefined;
114
+ const latest = candidates.find((name) => name.toLowerCase() === `${base}:latest`);
115
+ return latest ?? candidates[0];
116
+ };
117
+ const applyResponseFormat = (body, format) => {
118
+ if (!format)
119
+ return;
120
+ if (format.type === "json") {
121
+ body.format = "json";
122
+ return;
123
+ }
124
+ if (format.type === "json_schema") {
125
+ body.format = format.schema ?? "json";
126
+ return;
127
+ }
128
+ if (format.type === "gbnf" && format.grammar) {
129
+ body.grammar = format.grammar;
130
+ }
131
+ };
132
+ export class OllamaRemoteProvider {
133
+ constructor(config) {
134
+ this.config = config;
135
+ this.name = "ollama-remote";
136
+ }
137
+ async generate(request) {
138
+ const baseUrl = normalizeBaseUrl(this.config.baseUrl);
139
+ const url = new URL("api/chat", baseUrl).toString();
140
+ let resolvedModel = this.config.model;
141
+ const emitToken = (token) => {
142
+ if (request.onEvent) {
143
+ request.onEvent({ type: "token", content: token });
144
+ return;
145
+ }
146
+ request.onToken?.(token);
147
+ };
148
+ const buildBody = (model) => {
149
+ const body = {
150
+ model,
151
+ messages: request.messages.map((message) => ({
152
+ role: message.role,
153
+ content: message.content,
154
+ name: message.name,
155
+ })),
156
+ tools: request.tools?.map((tool) => ({
157
+ type: "function",
158
+ function: {
159
+ name: tool.name,
160
+ description: tool.description,
161
+ parameters: tool.inputSchema ?? {},
162
+ },
163
+ })),
164
+ stream: request.stream ?? false,
165
+ };
166
+ if (request.temperature !== undefined) {
167
+ body.options = { temperature: request.temperature };
168
+ }
169
+ applyResponseFormat(body, request.responseFormat);
170
+ return body;
171
+ };
172
+ const execute = async (model) => {
173
+ const response = await fetch(url, {
174
+ method: "POST",
175
+ headers: {
176
+ "content-type": "application/json",
177
+ },
178
+ body: JSON.stringify(buildBody(model)),
179
+ });
180
+ if (!response.ok) {
181
+ const errorBody = await response.text();
182
+ return { response, errorBody };
183
+ }
184
+ return { response };
185
+ };
186
+ let { response, errorBody } = await execute(resolvedModel);
187
+ if (!response.ok) {
188
+ const missingModel = errorBody ? parseModelNotFound(errorBody) : undefined;
189
+ if (response.status === 404 && missingModel) {
190
+ const available = await fetchModelTags(baseUrl);
191
+ const fallback = pickFallbackModel(resolvedModel, available);
192
+ if (fallback) {
193
+ resolvedModel = fallback;
194
+ const retry = await execute(resolvedModel);
195
+ response = retry.response;
196
+ errorBody = retry.errorBody;
197
+ }
198
+ }
199
+ if (!response.ok) {
200
+ throw new Error(`Ollama error ${response.status}: ${errorBody ?? ""}`.trim());
201
+ }
202
+ }
203
+ if (request.stream) {
204
+ if (!response.body) {
205
+ throw new Error("Ollama streaming response missing body");
206
+ }
207
+ const reader = response.body.getReader();
208
+ const decoder = new TextDecoder();
209
+ let buffer = "";
210
+ let content = "";
211
+ let toolCalls;
212
+ const rawChunks = [];
213
+ while (true) {
214
+ const { value, done } = await reader.read();
215
+ if (done)
216
+ break;
217
+ buffer += decoder.decode(value, { stream: true });
218
+ const lines = buffer.split("\n");
219
+ buffer = lines.pop() ?? "";
220
+ for (const line of lines) {
221
+ const trimmed = line.trim();
222
+ if (!trimmed)
223
+ continue;
224
+ try {
225
+ const chunk = JSON.parse(trimmed);
226
+ rawChunks.push(chunk);
227
+ const message = chunk.message ?? {};
228
+ if (message.content) {
229
+ content += message.content;
230
+ emitToken(message.content);
231
+ }
232
+ if (message.tool_calls && message.tool_calls.length > 0) {
233
+ toolCalls = message.tool_calls.map((call, index) => ({
234
+ id: call.id ?? `call_${index + 1}`,
235
+ name: call.function.name,
236
+ args: parseToolArgs(call.function.arguments),
237
+ }));
238
+ }
239
+ }
240
+ catch {
241
+ // ignore malformed chunks
242
+ }
243
+ }
244
+ }
245
+ if (buffer.trim()) {
246
+ try {
247
+ const chunk = JSON.parse(buffer);
248
+ rawChunks.push(chunk);
249
+ const message = chunk.message ?? {};
250
+ if (message.content) {
251
+ content += message.content;
252
+ emitToken(message.content);
253
+ }
254
+ if (message.tool_calls && message.tool_calls.length > 0) {
255
+ toolCalls = message.tool_calls.map((call, index) => ({
256
+ id: call.id ?? `call_${index + 1}`,
257
+ name: call.function.name,
258
+ args: parseToolArgs(call.function.arguments),
259
+ }));
260
+ }
261
+ }
262
+ catch {
263
+ // ignore trailing parse errors
264
+ }
265
+ }
266
+ if (!toolCalls || toolCalls.length === 0) {
267
+ const fallback = extractToolCallsFromContent(content);
268
+ if (fallback.length) {
269
+ toolCalls = fallback;
270
+ }
271
+ }
272
+ return {
273
+ message: { role: "assistant", content },
274
+ toolCalls,
275
+ raw: rawChunks,
276
+ };
277
+ }
278
+ const raw = (await response.json());
279
+ const message = raw.message ?? {};
280
+ let toolCalls = message.tool_calls?.map((call, index) => ({
281
+ id: call.id ?? `call_${index + 1}`,
282
+ name: call.function.name,
283
+ args: parseToolArgs(call.function.arguments),
284
+ }));
285
+ if (!toolCalls || toolCalls.length === 0) {
286
+ const fallback = extractToolCallsFromContent(message.content);
287
+ if (fallback.length) {
288
+ toolCalls = fallback;
289
+ }
290
+ }
291
+ return {
292
+ message: {
293
+ role: "assistant",
294
+ content: message.content ?? "",
295
+ },
296
+ toolCalls,
297
+ raw,
298
+ };
299
+ }
300
+ }
@@ -0,0 +1,8 @@
1
+ import type { Provider, ProviderConfig, ProviderRequest, ProviderResponse } from "./ProviderTypes.js";
2
+ export declare class OpenAiCompatibleProvider implements Provider {
3
+ private config;
4
+ name: string;
5
+ constructor(config: ProviderConfig);
6
+ generate(request: ProviderRequest): Promise<ProviderResponse>;
7
+ }
8
+ //# sourceMappingURL=OpenAiCompatibleProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpenAiCompatibleProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OpenAiCompatibleProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EACd,eAAe,EACf,gBAAgB,EAGjB,MAAM,oBAAoB,CAAC;AAuD5B,qBAAa,wBAAyB,YAAW,QAAQ;IAG3C,OAAO,CAAC,MAAM;IAF1B,IAAI,SAAuB;gBAEP,MAAM,EAAE,cAAc;IAEpC,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA2KpE"}
@@ -0,0 +1,192 @@
1
+ const parseToolArgs = (raw) => {
2
+ try {
3
+ return JSON.parse(raw);
4
+ }
5
+ catch {
6
+ return raw;
7
+ }
8
+ };
9
+ const normalizeBaseUrl = (baseUrl) => {
10
+ const root = baseUrl ?? "https://api.openai.com/v1";
11
+ return root.endsWith("/") ? root : `${root}/`;
12
+ };
13
+ const toResponseFormat = (format) => {
14
+ if (!format)
15
+ return undefined;
16
+ if (format.type === "json") {
17
+ return { type: "json_object" };
18
+ }
19
+ if (format.type === "json_schema") {
20
+ return { type: "json_schema", json_schema: format.schema ?? {} };
21
+ }
22
+ if (format.type === "text") {
23
+ return { type: "text" };
24
+ }
25
+ return undefined;
26
+ };
27
+ export class OpenAiCompatibleProvider {
28
+ constructor(config) {
29
+ this.config = config;
30
+ this.name = "openai-compatible";
31
+ }
32
+ async generate(request) {
33
+ const baseUrl = normalizeBaseUrl(this.config.baseUrl);
34
+ const url = new URL("chat/completions", baseUrl).toString();
35
+ const emitToken = (token) => {
36
+ if (request.onEvent) {
37
+ request.onEvent({ type: "token", content: token });
38
+ return;
39
+ }
40
+ request.onToken?.(token);
41
+ };
42
+ const headers = {
43
+ "content-type": "application/json",
44
+ };
45
+ if (this.config.apiKey) {
46
+ headers.authorization = `Bearer ${this.config.apiKey}`;
47
+ }
48
+ const body = {
49
+ model: this.config.model,
50
+ messages: request.messages.map((message) => ({
51
+ role: message.role,
52
+ content: message.content,
53
+ name: message.name,
54
+ tool_call_id: message.toolCallId,
55
+ })),
56
+ tools: request.tools?.map((tool) => ({
57
+ type: "function",
58
+ function: {
59
+ name: tool.name,
60
+ description: tool.description,
61
+ parameters: tool.inputSchema ?? {},
62
+ },
63
+ })),
64
+ tool_choice: request.toolChoice,
65
+ max_tokens: request.maxTokens,
66
+ temperature: request.temperature,
67
+ response_format: toResponseFormat(request.responseFormat),
68
+ stream: request.stream ?? false,
69
+ stream_options: request.stream ? { include_usage: true } : undefined,
70
+ };
71
+ const controller = new AbortController();
72
+ const timeoutMs = this.config.timeoutMs ?? 60000;
73
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
74
+ try {
75
+ const response = await fetch(url, {
76
+ method: "POST",
77
+ headers,
78
+ body: JSON.stringify(body),
79
+ signal: controller.signal,
80
+ });
81
+ if (!response.ok) {
82
+ const errorBody = await response.text();
83
+ throw new Error(`OpenAI-compatible error ${response.status}: ${errorBody}`);
84
+ }
85
+ if (request.stream) {
86
+ if (!response.body) {
87
+ throw new Error("OpenAI-compatible streaming response missing body");
88
+ }
89
+ const reader = response.body.getReader();
90
+ const decoder = new TextDecoder();
91
+ let buffer = "";
92
+ let content = "";
93
+ const toolCallMap = new Map();
94
+ let usage;
95
+ while (true) {
96
+ const { value, done } = await reader.read();
97
+ if (done)
98
+ break;
99
+ buffer += decoder.decode(value, { stream: true });
100
+ const lines = buffer.split("\n");
101
+ buffer = lines.pop() ?? "";
102
+ for (const line of lines) {
103
+ const trimmed = line.trim();
104
+ if (!trimmed.startsWith("data:"))
105
+ continue;
106
+ const data = trimmed.slice(5).trim();
107
+ if (!data || data === "[DONE]")
108
+ continue;
109
+ try {
110
+ const chunk = JSON.parse(data);
111
+ const delta = chunk.choices?.[0]?.delta;
112
+ if (delta?.content) {
113
+ content += delta.content;
114
+ emitToken(delta.content);
115
+ }
116
+ if (Array.isArray(delta?.tool_calls)) {
117
+ for (const call of delta.tool_calls) {
118
+ const index = call.index ?? 0;
119
+ const existing = toolCallMap.get(index) ?? {
120
+ id: call.id ?? `call_${index + 1}`,
121
+ name: "",
122
+ args: "",
123
+ };
124
+ if (call.function?.name) {
125
+ existing.name = call.function.name;
126
+ }
127
+ if (typeof call.function?.arguments === "string") {
128
+ existing.args += call.function.arguments;
129
+ }
130
+ toolCallMap.set(index, existing);
131
+ }
132
+ }
133
+ if (chunk.usage) {
134
+ usage = chunk.usage;
135
+ }
136
+ }
137
+ catch {
138
+ // ignore malformed chunks
139
+ }
140
+ }
141
+ }
142
+ const toolCalls = toolCallMap.size > 0
143
+ ? Array.from(toolCallMap.entries()).map(([index, call]) => ({
144
+ id: call.id ?? `call_${index + 1}`,
145
+ name: call.name,
146
+ args: parseToolArgs(call.args),
147
+ }))
148
+ : undefined;
149
+ return {
150
+ message: { role: "assistant", content },
151
+ toolCalls,
152
+ usage: usage
153
+ ? {
154
+ inputTokens: usage.prompt_tokens,
155
+ outputTokens: usage.completion_tokens,
156
+ totalTokens: usage.total_tokens,
157
+ }
158
+ : undefined,
159
+ raw: { stream: true },
160
+ };
161
+ }
162
+ const raw = (await response.json());
163
+ const choice = raw.choices[0]?.message;
164
+ if (!choice) {
165
+ throw new Error("OpenAI-compatible response missing choices");
166
+ }
167
+ const toolCalls = choice.tool_calls?.map((call) => ({
168
+ id: call.id,
169
+ name: call.function.name,
170
+ args: parseToolArgs(call.function.arguments),
171
+ }));
172
+ return {
173
+ message: {
174
+ role: "assistant",
175
+ content: choice.content ?? "",
176
+ },
177
+ toolCalls,
178
+ usage: raw.usage
179
+ ? {
180
+ inputTokens: raw.usage.prompt_tokens,
181
+ outputTokens: raw.usage.completion_tokens,
182
+ totalTokens: raw.usage.total_tokens,
183
+ }
184
+ : undefined,
185
+ raw,
186
+ };
187
+ }
188
+ finally {
189
+ clearTimeout(timeout);
190
+ }
191
+ }
192
+ }
@@ -0,0 +1,12 @@
1
+ import type { Provider, ProviderConfig } from "./ProviderTypes.js";
2
+ export type ProviderFactory = (config: ProviderConfig) => Provider;
3
+ export declare class ProviderRegistry {
4
+ private factories;
5
+ register(name: string, factory: ProviderFactory): void;
6
+ create(name: string, config: ProviderConfig): Provider;
7
+ list(): string[];
8
+ }
9
+ export declare const defaultProviderRegistry: ProviderRegistry;
10
+ export declare const registerProvider: (name: string, factory: ProviderFactory) => void;
11
+ export declare const createProvider: (name: string, config: ProviderConfig) => Provider;
12
+ //# sourceMappingURL=ProviderRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProviderRegistry.d.ts","sourceRoot":"","sources":["../../src/providers/ProviderRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,QAAQ,CAAC;AAEnE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAsC;IAEvD,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI;IAOtD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,QAAQ;IAQtD,IAAI,IAAI,MAAM,EAAE;CAGjB;AAED,eAAO,MAAM,uBAAuB,kBAAyB,CAAC;AAE9D,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,SAAS,eAAe,KAAG,IAEzE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,EAAE,QAAQ,cAAc,KAAG,QAErE,CAAC"}
@@ -0,0 +1,28 @@
1
+ export class ProviderRegistry {
2
+ constructor() {
3
+ this.factories = new Map();
4
+ }
5
+ register(name, factory) {
6
+ if (this.factories.has(name)) {
7
+ throw new Error(`Provider already registered: ${name}`);
8
+ }
9
+ this.factories.set(name, factory);
10
+ }
11
+ create(name, config) {
12
+ const factory = this.factories.get(name);
13
+ if (!factory) {
14
+ throw new Error(`Unknown provider: ${name}`);
15
+ }
16
+ return factory(config);
17
+ }
18
+ list() {
19
+ return Array.from(this.factories.keys());
20
+ }
21
+ }
22
+ export const defaultProviderRegistry = new ProviderRegistry();
23
+ export const registerProvider = (name, factory) => {
24
+ defaultProviderRegistry.register(name, factory);
25
+ };
26
+ export const createProvider = (name, config) => {
27
+ return defaultProviderRegistry.create(name, config);
28
+ };
@@ -0,0 +1,81 @@
1
+ export type ProviderRole = "system" | "user" | "assistant" | "tool";
2
+ export interface ProviderToolDefinition {
3
+ name: string;
4
+ description?: string;
5
+ inputSchema?: Record<string, unknown>;
6
+ }
7
+ export interface ProviderToolCall {
8
+ id: string;
9
+ name: string;
10
+ args: unknown;
11
+ }
12
+ export type AgentStatusPhase = "thinking" | "executing" | "patching" | "done";
13
+ export type AgentEvent = {
14
+ type: "token";
15
+ content: string;
16
+ } | {
17
+ type: "tool_call";
18
+ name: string;
19
+ args: unknown;
20
+ } | {
21
+ type: "tool_result";
22
+ name: string;
23
+ output: string;
24
+ ok?: boolean;
25
+ errorCode?: string;
26
+ retryable?: boolean;
27
+ } | {
28
+ type: "status";
29
+ phase: AgentStatusPhase;
30
+ message?: string;
31
+ } | {
32
+ type: "error";
33
+ message: string;
34
+ };
35
+ export interface ProviderResponseFormat {
36
+ type: "json" | "json_schema" | "text" | "gbnf";
37
+ schema?: Record<string, unknown>;
38
+ grammar?: string;
39
+ }
40
+ export interface ProviderMessage {
41
+ role: ProviderRole;
42
+ content: string;
43
+ name?: string;
44
+ toolCallId?: string;
45
+ }
46
+ export interface ProviderUsage {
47
+ inputTokens?: number;
48
+ outputTokens?: number;
49
+ totalTokens?: number;
50
+ }
51
+ export interface ProviderRequest {
52
+ messages: ProviderMessage[];
53
+ tools?: ProviderToolDefinition[];
54
+ toolChoice?: "auto" | "none" | {
55
+ name: string;
56
+ };
57
+ maxTokens?: number;
58
+ temperature?: number;
59
+ responseFormat?: ProviderResponseFormat;
60
+ stream?: boolean;
61
+ onEvent?: (event: AgentEvent) => void;
62
+ onToken?: (token: string) => void;
63
+ streamFlushMs?: number;
64
+ }
65
+ export interface ProviderResponse {
66
+ message: ProviderMessage;
67
+ toolCalls?: ProviderToolCall[];
68
+ usage?: ProviderUsage;
69
+ raw?: unknown;
70
+ }
71
+ export interface ProviderConfig {
72
+ model: string;
73
+ apiKey?: string;
74
+ baseUrl?: string;
75
+ timeoutMs?: number;
76
+ }
77
+ export interface Provider {
78
+ name: string;
79
+ generate(request: ProviderRequest): Promise<ProviderResponse>;
80
+ }
81
+ //# sourceMappingURL=ProviderTypes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProviderTypes.d.ts","sourceRoot":"","sources":["../../src/providers/ProviderTypes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};