cmdr-agent 2.1.2 → 2.3.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.
- package/dist/bin/cmdr.js +4 -0
- package/dist/bin/cmdr.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/src/cli/args.d.ts +4 -0
- package/dist/src/cli/args.d.ts.map +1 -1
- package/dist/src/cli/args.js +15 -0
- package/dist/src/cli/args.js.map +1 -1
- package/dist/src/cli/commands.js +21 -1
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/ink/App.d.ts +2 -0
- package/dist/src/cli/ink/App.d.ts.map +1 -1
- package/dist/src/cli/ink/App.js +71 -7
- package/dist/src/cli/ink/App.js.map +1 -1
- package/dist/src/cli/repl.d.ts +4 -0
- package/dist/src/cli/repl.d.ts.map +1 -1
- package/dist/src/cli/repl.js +83 -20
- package/dist/src/cli/repl.js.map +1 -1
- package/dist/src/config/mcp-registry.d.ts +45 -0
- package/dist/src/config/mcp-registry.d.ts.map +1 -0
- package/dist/src/config/mcp-registry.js +156 -0
- package/dist/src/config/mcp-registry.js.map +1 -0
- package/dist/src/config/schema.d.ts +8 -8
- package/dist/src/core/agent-runner.d.ts +5 -0
- package/dist/src/core/agent-runner.d.ts.map +1 -1
- package/dist/src/core/agent-runner.js +34 -2
- package/dist/src/core/agent-runner.js.map +1 -1
- package/dist/src/core/agent.d.ts +2 -1
- package/dist/src/core/agent.d.ts.map +1 -1
- package/dist/src/core/agent.js +5 -1
- package/dist/src/core/agent.js.map +1 -1
- package/dist/src/core/content-replacement.d.ts +44 -0
- package/dist/src/core/content-replacement.d.ts.map +1 -0
- package/dist/src/core/content-replacement.js +67 -0
- package/dist/src/core/content-replacement.js.map +1 -0
- package/dist/src/core/event-bus.d.ts +129 -0
- package/dist/src/core/event-bus.d.ts.map +1 -0
- package/dist/src/core/event-bus.js +103 -0
- package/dist/src/core/event-bus.js.map +1 -0
- package/dist/src/core/hooks.d.ts +61 -0
- package/dist/src/core/hooks.d.ts.map +1 -0
- package/dist/src/core/hooks.js +140 -0
- package/dist/src/core/hooks.js.map +1 -0
- package/dist/src/core/orchestrator.d.ts +17 -1
- package/dist/src/core/orchestrator.d.ts.map +1 -1
- package/dist/src/core/orchestrator.js +95 -1
- package/dist/src/core/orchestrator.js.map +1 -1
- package/dist/src/core/permissions.d.ts +74 -3
- package/dist/src/core/permissions.d.ts.map +1 -1
- package/dist/src/core/permissions.js +230 -11
- package/dist/src/core/permissions.js.map +1 -1
- package/dist/src/core/presets.d.ts.map +1 -1
- package/dist/src/core/presets.js +1 -0
- package/dist/src/core/presets.js.map +1 -1
- package/dist/src/core/types.d.ts +22 -1
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/llm/anthropic.d.ts +27 -0
- package/dist/src/llm/anthropic.d.ts.map +1 -0
- package/dist/src/llm/anthropic.js +269 -0
- package/dist/src/llm/anthropic.js.map +1 -0
- package/dist/src/llm/ollama.d.ts.map +1 -1
- package/dist/src/llm/ollama.js +16 -4
- package/dist/src/llm/ollama.js.map +1 -1
- package/dist/src/llm/openai.d.ts +25 -0
- package/dist/src/llm/openai.d.ts.map +1 -0
- package/dist/src/llm/openai.js +299 -0
- package/dist/src/llm/openai.js.map +1 -0
- package/dist/src/llm/provider-factory.d.ts +35 -0
- package/dist/src/llm/provider-factory.d.ts.map +1 -0
- package/dist/src/llm/provider-factory.js +73 -0
- package/dist/src/llm/provider-factory.js.map +1 -0
- package/dist/src/memory/consolidation.d.ts +37 -0
- package/dist/src/memory/consolidation.d.ts.map +1 -0
- package/dist/src/memory/consolidation.js +148 -0
- package/dist/src/memory/consolidation.js.map +1 -0
- package/dist/src/memory/memory-manager.d.ts +39 -0
- package/dist/src/memory/memory-manager.d.ts.map +1 -0
- package/dist/src/memory/memory-manager.js +96 -0
- package/dist/src/memory/memory-manager.js.map +1 -0
- package/dist/src/plugins/mcp-client.d.ts +14 -5
- package/dist/src/plugins/mcp-client.d.ts.map +1 -1
- package/dist/src/plugins/mcp-client.js +197 -43
- package/dist/src/plugins/mcp-client.js.map +1 -1
- package/dist/src/scheduling/task-scheduler.d.ts +51 -0
- package/dist/src/scheduling/task-scheduler.d.ts.map +1 -0
- package/dist/src/scheduling/task-scheduler.js +127 -0
- package/dist/src/scheduling/task-scheduler.js.map +1 -0
- package/dist/src/session/prompt-builder.d.ts +6 -0
- package/dist/src/session/prompt-builder.d.ts.map +1 -1
- package/dist/src/session/prompt-builder.js +21 -2
- package/dist/src/session/prompt-builder.js.map +1 -1
- package/dist/src/session/prompt-cache.d.ts +33 -0
- package/dist/src/session/prompt-cache.d.ts.map +1 -0
- package/dist/src/session/prompt-cache.js +54 -0
- package/dist/src/session/prompt-cache.js.map +1 -0
- package/dist/src/tools/built-in/cron-tools.d.ts +19 -0
- package/dist/src/tools/built-in/cron-tools.d.ts.map +1 -0
- package/dist/src/tools/built-in/cron-tools.js +86 -0
- package/dist/src/tools/built-in/cron-tools.js.map +1 -0
- package/dist/src/tools/built-in/diagnostics.d.ts +12 -0
- package/dist/src/tools/built-in/diagnostics.d.ts.map +1 -0
- package/dist/src/tools/built-in/diagnostics.js +119 -0
- package/dist/src/tools/built-in/diagnostics.js.map +1 -0
- package/dist/src/tools/built-in/git-worktree.d.ts +13 -0
- package/dist/src/tools/built-in/git-worktree.d.ts.map +1 -0
- package/dist/src/tools/built-in/git-worktree.js +75 -0
- package/dist/src/tools/built-in/git-worktree.js.map +1 -0
- package/dist/src/tools/built-in/index.d.ts +11 -1
- package/dist/src/tools/built-in/index.d.ts.map +1 -1
- package/dist/src/tools/built-in/index.js +19 -2
- package/dist/src/tools/built-in/index.js.map +1 -1
- package/dist/src/tools/built-in/mcp-resource-tools.d.ts +16 -0
- package/dist/src/tools/built-in/mcp-resource-tools.d.ts.map +1 -0
- package/dist/src/tools/built-in/mcp-resource-tools.js +73 -0
- package/dist/src/tools/built-in/mcp-resource-tools.js.map +1 -0
- package/dist/src/tools/built-in/memory.d.ts +15 -0
- package/dist/src/tools/built-in/memory.d.ts.map +1 -0
- package/dist/src/tools/built-in/memory.js +58 -0
- package/dist/src/tools/built-in/memory.js.map +1 -0
- package/dist/src/tools/built-in/notebook.d.ts +22 -0
- package/dist/src/tools/built-in/notebook.d.ts.map +1 -0
- package/dist/src/tools/built-in/notebook.js +207 -0
- package/dist/src/tools/built-in/notebook.js.map +1 -0
- package/dist/src/tools/built-in/plan-tools.d.ts +13 -0
- package/dist/src/tools/built-in/plan-tools.d.ts.map +1 -0
- package/dist/src/tools/built-in/plan-tools.js +42 -0
- package/dist/src/tools/built-in/plan-tools.js.map +1 -0
- package/dist/src/tools/built-in/task-tools.d.ts +22 -0
- package/dist/src/tools/built-in/task-tools.d.ts.map +1 -0
- package/dist/src/tools/built-in/task-tools.js +113 -0
- package/dist/src/tools/built-in/task-tools.js.map +1 -0
- package/dist/src/tools/built-in/todo-tool.d.ts +21 -0
- package/dist/src/tools/built-in/todo-tool.d.ts.map +1 -0
- package/dist/src/tools/built-in/todo-tool.js +52 -0
- package/dist/src/tools/built-in/todo-tool.js.map +1 -0
- package/dist/src/tools/built-in/web-search.d.ts +9 -0
- package/dist/src/tools/built-in/web-search.d.ts.map +1 -0
- package/dist/src/tools/built-in/web-search.js +89 -0
- package/dist/src/tools/built-in/web-search.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible LLM adapter for cmdr.
|
|
3
|
+
*
|
|
4
|
+
* Works with: OpenAI API, Groq, Together, OpenRouter, and any OpenAI-API-compatible provider.
|
|
5
|
+
* Uses the standard /v1/chat/completions endpoint.
|
|
6
|
+
*/
|
|
7
|
+
export class OpenAIAdapter {
|
|
8
|
+
name;
|
|
9
|
+
baseUrl;
|
|
10
|
+
apiKey;
|
|
11
|
+
defaultHeaders;
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this.apiKey = options.apiKey;
|
|
14
|
+
this.baseUrl = (options.baseUrl ?? 'https://api.openai.com/v1').replace(/\/$/, '');
|
|
15
|
+
this.name = options.name ?? 'openai';
|
|
16
|
+
this.defaultHeaders = options.headers ?? {};
|
|
17
|
+
}
|
|
18
|
+
// -----------------------------------------------------------------------
|
|
19
|
+
// LLMAdapter.chat
|
|
20
|
+
// -----------------------------------------------------------------------
|
|
21
|
+
async chat(messages, options) {
|
|
22
|
+
const body = {
|
|
23
|
+
model: options.model,
|
|
24
|
+
messages: this.convertMessages(messages, options.systemPrompt),
|
|
25
|
+
stream: false,
|
|
26
|
+
...(options.temperature !== undefined ? { temperature: options.temperature } : {}),
|
|
27
|
+
...(options.maxTokens !== undefined ? { max_tokens: options.maxTokens } : {}),
|
|
28
|
+
};
|
|
29
|
+
if (options.tools && options.tools.length > 0) {
|
|
30
|
+
body.tools = options.tools.map(t => this.convertToolDef(t));
|
|
31
|
+
}
|
|
32
|
+
const res = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
37
|
+
...this.defaultHeaders,
|
|
38
|
+
},
|
|
39
|
+
body: JSON.stringify(body),
|
|
40
|
+
signal: options.abortSignal,
|
|
41
|
+
});
|
|
42
|
+
if (!res.ok) {
|
|
43
|
+
const text = await res.text();
|
|
44
|
+
throw new Error(`OpenAI API error (${res.status}): ${text.slice(0, 300)}`);
|
|
45
|
+
}
|
|
46
|
+
const data = await res.json();
|
|
47
|
+
const choice = data.choices[0];
|
|
48
|
+
if (!choice)
|
|
49
|
+
throw new Error('No choices in OpenAI response');
|
|
50
|
+
const content = this.parseAssistantMessage(choice.message);
|
|
51
|
+
const hasToolUse = content.some(b => b.type === 'tool_use');
|
|
52
|
+
const usage = {
|
|
53
|
+
input_tokens: data.usage?.prompt_tokens ?? 0,
|
|
54
|
+
output_tokens: data.usage?.completion_tokens ?? 0,
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
id: data.id,
|
|
58
|
+
content,
|
|
59
|
+
model: data.model,
|
|
60
|
+
stop_reason: hasToolUse ? 'tool_use' : 'end_turn',
|
|
61
|
+
usage,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// -----------------------------------------------------------------------
|
|
65
|
+
// LLMAdapter.stream
|
|
66
|
+
// -----------------------------------------------------------------------
|
|
67
|
+
async *stream(messages, options) {
|
|
68
|
+
const body = {
|
|
69
|
+
model: options.model,
|
|
70
|
+
messages: this.convertMessages(messages, options.systemPrompt),
|
|
71
|
+
stream: true,
|
|
72
|
+
stream_options: { include_usage: true },
|
|
73
|
+
...(options.temperature !== undefined ? { temperature: options.temperature } : {}),
|
|
74
|
+
...(options.maxTokens !== undefined ? { max_tokens: options.maxTokens } : {}),
|
|
75
|
+
};
|
|
76
|
+
if (options.tools && options.tools.length > 0) {
|
|
77
|
+
body.tools = options.tools.map(t => this.convertToolDef(t));
|
|
78
|
+
}
|
|
79
|
+
let res;
|
|
80
|
+
try {
|
|
81
|
+
res = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
headers: {
|
|
84
|
+
'Content-Type': 'application/json',
|
|
85
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
86
|
+
...this.defaultHeaders,
|
|
87
|
+
},
|
|
88
|
+
body: JSON.stringify(body),
|
|
89
|
+
signal: options.abortSignal,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
yield { type: 'error', data: err instanceof Error ? err : new Error(String(err)) };
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (!res.ok) {
|
|
97
|
+
const text = await res.text();
|
|
98
|
+
yield { type: 'error', data: new Error(`OpenAI API error (${res.status}): ${text.slice(0, 300)}`) };
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const reader = res.body?.getReader();
|
|
102
|
+
if (!reader) {
|
|
103
|
+
yield { type: 'error', data: new Error('No response body') };
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const decoder = new TextDecoder();
|
|
107
|
+
let buffer = '';
|
|
108
|
+
let fullText = '';
|
|
109
|
+
let totalUsage = { input_tokens: 0, output_tokens: 0 };
|
|
110
|
+
let model = options.model;
|
|
111
|
+
// Accumulate tool call deltas
|
|
112
|
+
const toolCallAccumulator = new Map();
|
|
113
|
+
try {
|
|
114
|
+
while (true) {
|
|
115
|
+
const { done, value } = await reader.read();
|
|
116
|
+
if (done)
|
|
117
|
+
break;
|
|
118
|
+
buffer += decoder.decode(value, { stream: true });
|
|
119
|
+
const lines = buffer.split('\n');
|
|
120
|
+
buffer = lines.pop() ?? '';
|
|
121
|
+
for (const line of lines) {
|
|
122
|
+
const trimmed = line.trim();
|
|
123
|
+
if (!trimmed || !trimmed.startsWith('data: '))
|
|
124
|
+
continue;
|
|
125
|
+
const payload = trimmed.slice(6);
|
|
126
|
+
if (payload === '[DONE]')
|
|
127
|
+
continue;
|
|
128
|
+
let chunk;
|
|
129
|
+
try {
|
|
130
|
+
chunk = JSON.parse(payload);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
model = chunk.model || model;
|
|
136
|
+
if (chunk.usage) {
|
|
137
|
+
totalUsage = {
|
|
138
|
+
input_tokens: chunk.usage.prompt_tokens ?? 0,
|
|
139
|
+
output_tokens: chunk.usage.completion_tokens ?? 0,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const choice = chunk.choices?.[0];
|
|
143
|
+
if (!choice)
|
|
144
|
+
continue;
|
|
145
|
+
// Text content
|
|
146
|
+
if (choice.delta.content) {
|
|
147
|
+
fullText += choice.delta.content;
|
|
148
|
+
yield { type: 'text', data: choice.delta.content };
|
|
149
|
+
}
|
|
150
|
+
// Tool call deltas
|
|
151
|
+
if (choice.delta.tool_calls) {
|
|
152
|
+
for (const tc of choice.delta.tool_calls) {
|
|
153
|
+
const existing = toolCallAccumulator.get(tc.index);
|
|
154
|
+
if (existing) {
|
|
155
|
+
if (tc.function?.arguments)
|
|
156
|
+
existing.arguments += tc.function.arguments;
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
toolCallAccumulator.set(tc.index, {
|
|
160
|
+
id: tc.id ?? `call_${Date.now()}_${tc.index}`,
|
|
161
|
+
name: tc.function?.name ?? '',
|
|
162
|
+
arguments: tc.function?.arguments ?? '',
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
reader.releaseLock();
|
|
172
|
+
}
|
|
173
|
+
// Emit accumulated tool calls
|
|
174
|
+
for (const [, tc] of toolCallAccumulator) {
|
|
175
|
+
let args = {};
|
|
176
|
+
try {
|
|
177
|
+
args = JSON.parse(tc.arguments);
|
|
178
|
+
}
|
|
179
|
+
catch { /* malformed args */ }
|
|
180
|
+
const toolUseBlock = {
|
|
181
|
+
type: 'tool_use',
|
|
182
|
+
id: tc.id,
|
|
183
|
+
name: tc.name,
|
|
184
|
+
input: args,
|
|
185
|
+
};
|
|
186
|
+
yield { type: 'tool_use', data: toolUseBlock };
|
|
187
|
+
}
|
|
188
|
+
// Done event
|
|
189
|
+
const content = [];
|
|
190
|
+
if (fullText)
|
|
191
|
+
content.push({ type: 'text', text: fullText });
|
|
192
|
+
for (const [, tc] of toolCallAccumulator) {
|
|
193
|
+
let args = {};
|
|
194
|
+
try {
|
|
195
|
+
args = JSON.parse(tc.arguments);
|
|
196
|
+
}
|
|
197
|
+
catch { /* */ }
|
|
198
|
+
content.push({ type: 'tool_use', id: tc.id, name: tc.name, input: args });
|
|
199
|
+
}
|
|
200
|
+
yield {
|
|
201
|
+
type: 'done',
|
|
202
|
+
data: {
|
|
203
|
+
id: `openai_${Date.now()}`,
|
|
204
|
+
content,
|
|
205
|
+
model,
|
|
206
|
+
stop_reason: toolCallAccumulator.size > 0 ? 'tool_use' : 'end_turn',
|
|
207
|
+
usage: totalUsage,
|
|
208
|
+
},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
// -----------------------------------------------------------------------
|
|
212
|
+
// Message conversion
|
|
213
|
+
// -----------------------------------------------------------------------
|
|
214
|
+
convertMessages(messages, systemPrompt) {
|
|
215
|
+
const result = [];
|
|
216
|
+
if (systemPrompt) {
|
|
217
|
+
result.push({ role: 'system', content: systemPrompt });
|
|
218
|
+
}
|
|
219
|
+
for (const msg of messages) {
|
|
220
|
+
if (msg.role === 'user') {
|
|
221
|
+
// Check if this is a tool result message
|
|
222
|
+
const toolResults = msg.content.filter((b) => b.type === 'tool_result');
|
|
223
|
+
if (toolResults.length > 0) {
|
|
224
|
+
for (const tr of toolResults) {
|
|
225
|
+
result.push({
|
|
226
|
+
role: 'tool',
|
|
227
|
+
tool_call_id: tr.tool_use_id,
|
|
228
|
+
content: tr.content,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
const text = msg.content
|
|
234
|
+
.filter((b) => b.type === 'text')
|
|
235
|
+
.map(b => b.text)
|
|
236
|
+
.join('');
|
|
237
|
+
if (text)
|
|
238
|
+
result.push({ role: 'user', content: text });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else if (msg.role === 'assistant') {
|
|
242
|
+
const text = msg.content
|
|
243
|
+
.filter((b) => b.type === 'text')
|
|
244
|
+
.map(b => b.text)
|
|
245
|
+
.join('');
|
|
246
|
+
const toolCalls = msg.content
|
|
247
|
+
.filter((b) => b.type === 'tool_use')
|
|
248
|
+
.map(tc => ({
|
|
249
|
+
id: tc.id,
|
|
250
|
+
type: 'function',
|
|
251
|
+
function: {
|
|
252
|
+
name: tc.name,
|
|
253
|
+
arguments: JSON.stringify(tc.input),
|
|
254
|
+
},
|
|
255
|
+
}));
|
|
256
|
+
const chatMsg = {
|
|
257
|
+
role: 'assistant',
|
|
258
|
+
...(text ? { content: text } : { content: null }),
|
|
259
|
+
...(toolCalls.length > 0 ? { tool_calls: toolCalls } : {}),
|
|
260
|
+
};
|
|
261
|
+
result.push(chatMsg);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
parseAssistantMessage(msg) {
|
|
267
|
+
const content = [];
|
|
268
|
+
if (msg.content) {
|
|
269
|
+
content.push({ type: 'text', text: msg.content });
|
|
270
|
+
}
|
|
271
|
+
if (msg.tool_calls) {
|
|
272
|
+
for (const tc of msg.tool_calls) {
|
|
273
|
+
let args = {};
|
|
274
|
+
try {
|
|
275
|
+
args = JSON.parse(tc.function.arguments);
|
|
276
|
+
}
|
|
277
|
+
catch { /* */ }
|
|
278
|
+
content.push({
|
|
279
|
+
type: 'tool_use',
|
|
280
|
+
id: tc.id,
|
|
281
|
+
name: tc.function.name,
|
|
282
|
+
input: args,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return content;
|
|
287
|
+
}
|
|
288
|
+
convertToolDef(tool) {
|
|
289
|
+
return {
|
|
290
|
+
type: 'function',
|
|
291
|
+
function: {
|
|
292
|
+
name: tool.name,
|
|
293
|
+
description: tool.description,
|
|
294
|
+
parameters: tool.inputSchema,
|
|
295
|
+
},
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/llm/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider factory — creates the appropriate LLM adapter based on configuration.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - ollama: Local inference via Ollama (default)
|
|
6
|
+
* - openai: OpenAI API (also works with Groq, Together, OpenRouter)
|
|
7
|
+
* - anthropic: Anthropic Claude API
|
|
8
|
+
*
|
|
9
|
+
* API keys are read from environment variables:
|
|
10
|
+
* - OPENAI_API_KEY (or CMDR_OPENAI_API_KEY)
|
|
11
|
+
* - ANTHROPIC_API_KEY (or CMDR_ANTHROPIC_API_KEY)
|
|
12
|
+
*
|
|
13
|
+
* Custom base URLs:
|
|
14
|
+
* - OPENAI_BASE_URL (e.g. https://openrouter.ai/api/v1)
|
|
15
|
+
* - ANTHROPIC_BASE_URL
|
|
16
|
+
*/
|
|
17
|
+
import type { LLMAdapter } from '../core/types.js';
|
|
18
|
+
export type ProviderName = 'ollama' | 'openai' | 'anthropic';
|
|
19
|
+
export interface ProviderOptions {
|
|
20
|
+
provider: ProviderName;
|
|
21
|
+
ollamaUrl?: string;
|
|
22
|
+
apiKey?: string;
|
|
23
|
+
baseUrl?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create an LLM adapter for the given provider.
|
|
27
|
+
* Throws if required configuration (e.g. API key) is missing.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createAdapter(options: ProviderOptions): LLMAdapter;
|
|
30
|
+
/**
|
|
31
|
+
* Detect provider from model name pattern.
|
|
32
|
+
* Returns undefined if can't determine — falls back to config default.
|
|
33
|
+
*/
|
|
34
|
+
export declare function detectProviderFromModel(model: string): ProviderName | undefined;
|
|
35
|
+
//# sourceMappingURL=provider-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-factory.d.ts","sourceRoot":"","sources":["../../../src/llm/provider-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAKlD,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAA;AAE5D,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,UAAU,CAuClE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAS/E"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider factory — creates the appropriate LLM adapter based on configuration.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - ollama: Local inference via Ollama (default)
|
|
6
|
+
* - openai: OpenAI API (also works with Groq, Together, OpenRouter)
|
|
7
|
+
* - anthropic: Anthropic Claude API
|
|
8
|
+
*
|
|
9
|
+
* API keys are read from environment variables:
|
|
10
|
+
* - OPENAI_API_KEY (or CMDR_OPENAI_API_KEY)
|
|
11
|
+
* - ANTHROPIC_API_KEY (or CMDR_ANTHROPIC_API_KEY)
|
|
12
|
+
*
|
|
13
|
+
* Custom base URLs:
|
|
14
|
+
* - OPENAI_BASE_URL (e.g. https://openrouter.ai/api/v1)
|
|
15
|
+
* - ANTHROPIC_BASE_URL
|
|
16
|
+
*/
|
|
17
|
+
import { OllamaAdapter } from './ollama.js';
|
|
18
|
+
import { OpenAIAdapter } from './openai.js';
|
|
19
|
+
import { AnthropicAdapter } from './anthropic.js';
|
|
20
|
+
/**
|
|
21
|
+
* Create an LLM adapter for the given provider.
|
|
22
|
+
* Throws if required configuration (e.g. API key) is missing.
|
|
23
|
+
*/
|
|
24
|
+
export function createAdapter(options) {
|
|
25
|
+
switch (options.provider) {
|
|
26
|
+
case 'ollama':
|
|
27
|
+
return new OllamaAdapter(options.ollamaUrl ?? 'http://localhost:11434');
|
|
28
|
+
case 'openai': {
|
|
29
|
+
const apiKey = options.apiKey
|
|
30
|
+
?? process.env.CMDR_OPENAI_API_KEY
|
|
31
|
+
?? process.env.OPENAI_API_KEY;
|
|
32
|
+
if (!apiKey) {
|
|
33
|
+
throw new Error('OpenAI API key required. Set OPENAI_API_KEY or CMDR_OPENAI_API_KEY environment variable.');
|
|
34
|
+
}
|
|
35
|
+
return new OpenAIAdapter({
|
|
36
|
+
apiKey,
|
|
37
|
+
baseUrl: options.baseUrl ?? process.env.OPENAI_BASE_URL,
|
|
38
|
+
name: 'openai',
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
case 'anthropic': {
|
|
42
|
+
const apiKey = options.apiKey
|
|
43
|
+
?? process.env.CMDR_ANTHROPIC_API_KEY
|
|
44
|
+
?? process.env.ANTHROPIC_API_KEY;
|
|
45
|
+
if (!apiKey) {
|
|
46
|
+
throw new Error('Anthropic API key required. Set ANTHROPIC_API_KEY or CMDR_ANTHROPIC_API_KEY environment variable.');
|
|
47
|
+
}
|
|
48
|
+
return new AnthropicAdapter({
|
|
49
|
+
apiKey,
|
|
50
|
+
baseUrl: options.baseUrl ?? process.env.ANTHROPIC_BASE_URL,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
default:
|
|
54
|
+
throw new Error(`Unknown provider: ${options.provider}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Detect provider from model name pattern.
|
|
59
|
+
* Returns undefined if can't determine — falls back to config default.
|
|
60
|
+
*/
|
|
61
|
+
export function detectProviderFromModel(model) {
|
|
62
|
+
// Claude models → Anthropic
|
|
63
|
+
if (/^claude-/i.test(model))
|
|
64
|
+
return 'anthropic';
|
|
65
|
+
// GPT/o1/o3 models → OpenAI
|
|
66
|
+
if (/^(gpt-|o1|o3|chatgpt)/i.test(model))
|
|
67
|
+
return 'openai';
|
|
68
|
+
// Models with colons are typically Ollama tags (e.g. qwen2.5-coder:14b)
|
|
69
|
+
if (model.includes(':'))
|
|
70
|
+
return 'ollama';
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=provider-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-factory.js","sourceRoot":"","sources":["../../../src/llm/provider-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAWjD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAwB;IACpD,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,SAAS,IAAI,wBAAwB,CAAC,CAAA;QAEzE,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;mBACxB,OAAO,CAAC,GAAG,CAAC,mBAAmB;mBAC/B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;YAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,0FAA0F,CAC3F,CAAA;YACH,CAAC;YACD,OAAO,IAAI,aAAa,CAAC;gBACvB,MAAM;gBACN,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;gBACvD,IAAI,EAAE,QAAQ;aACf,CAAC,CAAA;QACJ,CAAC;QAED,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;mBACxB,OAAO,CAAC,GAAG,CAAC,sBAAsB;mBAClC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAA;YAClC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,KAAK,CACb,mGAAmG,CACpG,CAAA;YACH,CAAC;YACD,OAAO,IAAI,gBAAgB,CAAC;gBAC1B,MAAM;gBACN,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB;aAC3D,CAAC,CAAA;QACJ,CAAC;QAED;YACE,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,4BAA4B;IAC5B,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,WAAW,CAAA;IAC/C,4BAA4B;IAC5B,IAAI,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAA;IACzD,wEAAwE;IACxE,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAA;IAExC,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Consolidation — the "auto-dream" system for cmdr.
|
|
3
|
+
*
|
|
4
|
+
* After a session ends, consolidation reviews the conversation to extract
|
|
5
|
+
* learnings and update MEMORY.md files. This follows a 4-stage pipeline:
|
|
6
|
+
*
|
|
7
|
+
* 1. Orient — Identify what the session was about (project, topic, scope)
|
|
8
|
+
* 2. Gather — Extract actionable learnings from the conversation
|
|
9
|
+
* 3. Consolidate — Merge new learnings with existing memory, dedup
|
|
10
|
+
* 4. Prune — Remove stale or contradicted entries, enforce size budget
|
|
11
|
+
*
|
|
12
|
+
* Triggered automatically at session end or via /compact command.
|
|
13
|
+
*/
|
|
14
|
+
import type { LLMAdapter, LLMMessage } from '../core/types.js';
|
|
15
|
+
import type { MemoryManager } from './memory-manager.js';
|
|
16
|
+
interface ConsolidationResult {
|
|
17
|
+
learningsFound: number;
|
|
18
|
+
memoryUpdated: boolean;
|
|
19
|
+
scope: 'project' | 'user';
|
|
20
|
+
}
|
|
21
|
+
export declare class MemoryConsolidator {
|
|
22
|
+
private readonly memoryManager;
|
|
23
|
+
private readonly adapter;
|
|
24
|
+
private readonly model;
|
|
25
|
+
constructor(memoryManager: MemoryManager, adapter: LLMAdapter, model: string);
|
|
26
|
+
/**
|
|
27
|
+
* Run the full consolidation pipeline on a completed session's messages.
|
|
28
|
+
* Returns info about what was updated.
|
|
29
|
+
*/
|
|
30
|
+
consolidate(messages: LLMMessage[], scope?: 'project' | 'user'): Promise<ConsolidationResult>;
|
|
31
|
+
/** Stage 2: Extract learnings from conversation messages. */
|
|
32
|
+
private gatherLearnings;
|
|
33
|
+
/** Stage 3 & 4: Merge new learnings with existing memory. */
|
|
34
|
+
private consolidateMemory;
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=consolidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidation.d.ts","sourceRoot":"","sources":["../../../src/memory/consolidation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAA6B,MAAM,kBAAkB,CAAA;AACzF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AA+BxD,UAAU,mBAAmB;IAC3B,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,OAAO,CAAA;IACtB,KAAK,EAAE,SAAS,GAAG,MAAM,CAAA;CAC1B;AAED,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAFL,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,MAAM;IAGhC;;;OAGG;IACG,WAAW,CACf,QAAQ,EAAE,UAAU,EAAE,EACtB,KAAK,GAAE,SAAS,GAAG,MAAkB,GACpC,OAAO,CAAC,mBAAmB,CAAC;IAgC/B,6DAA6D;YAC/C,eAAe;IAyC7B,6DAA6D;YAC/C,iBAAiB;CA+BhC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memory Consolidation — the "auto-dream" system for cmdr.
|
|
3
|
+
*
|
|
4
|
+
* After a session ends, consolidation reviews the conversation to extract
|
|
5
|
+
* learnings and update MEMORY.md files. This follows a 4-stage pipeline:
|
|
6
|
+
*
|
|
7
|
+
* 1. Orient — Identify what the session was about (project, topic, scope)
|
|
8
|
+
* 2. Gather — Extract actionable learnings from the conversation
|
|
9
|
+
* 3. Consolidate — Merge new learnings with existing memory, dedup
|
|
10
|
+
* 4. Prune — Remove stale or contradicted entries, enforce size budget
|
|
11
|
+
*
|
|
12
|
+
* Triggered automatically at session end or via /compact command.
|
|
13
|
+
*/
|
|
14
|
+
const GATHER_PROMPT = `You are a memory consolidation agent. Analyze this conversation and extract key learnings.
|
|
15
|
+
|
|
16
|
+
Focus on:
|
|
17
|
+
- Project conventions discovered (naming, structure, patterns)
|
|
18
|
+
- User preferences observed (style, tools, workflow)
|
|
19
|
+
- Technical decisions made and their rationale
|
|
20
|
+
- Bugs found and solutions applied
|
|
21
|
+
- Common patterns that should be remembered
|
|
22
|
+
|
|
23
|
+
Output a bulleted list of concise, actionable learnings. Each item should be self-contained.
|
|
24
|
+
Do NOT include conversation-specific details that won't be useful in future sessions.
|
|
25
|
+
Do NOT include transient information (file paths of temporary files, specific error messages that were fixed).
|
|
26
|
+
|
|
27
|
+
If there are no meaningful learnings to extract, output exactly: NO_LEARNINGS`;
|
|
28
|
+
const CONSOLIDATE_PROMPT = `You are a memory manager. Given existing memory and new learnings, produce a consolidated MEMORY.md.
|
|
29
|
+
|
|
30
|
+
Rules:
|
|
31
|
+
- Merge duplicates: if a new learning matches an existing entry, keep the more specific/recent one
|
|
32
|
+
- Remove contradictions: if a new learning contradicts an old one, keep the new one
|
|
33
|
+
- Group by topic: use ## headers (preferences, conventions, patterns, decisions)
|
|
34
|
+
- Keep each entry as a concise bullet point
|
|
35
|
+
- Stay under {MAX_LINES} lines total
|
|
36
|
+
- Preserve date annotations where useful
|
|
37
|
+
|
|
38
|
+
Output the final consolidated markdown content. No preamble, just the content.`;
|
|
39
|
+
const MAX_MEMORY_LINES = 150;
|
|
40
|
+
export class MemoryConsolidator {
|
|
41
|
+
memoryManager;
|
|
42
|
+
adapter;
|
|
43
|
+
model;
|
|
44
|
+
constructor(memoryManager, adapter, model) {
|
|
45
|
+
this.memoryManager = memoryManager;
|
|
46
|
+
this.adapter = adapter;
|
|
47
|
+
this.model = model;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Run the full consolidation pipeline on a completed session's messages.
|
|
51
|
+
* Returns info about what was updated.
|
|
52
|
+
*/
|
|
53
|
+
async consolidate(messages, scope = 'project') {
|
|
54
|
+
// Skip tiny sessions — not enough to learn from
|
|
55
|
+
if (messages.length < 4) {
|
|
56
|
+
return { learningsFound: 0, memoryUpdated: false, scope };
|
|
57
|
+
}
|
|
58
|
+
// Stage 1 & 2: Gather learnings from conversation
|
|
59
|
+
const learnings = await this.gatherLearnings(messages);
|
|
60
|
+
if (!learnings || learnings === 'NO_LEARNINGS') {
|
|
61
|
+
return { learningsFound: 0, memoryUpdated: false, scope };
|
|
62
|
+
}
|
|
63
|
+
const learningsList = learnings.split('\n').filter(l => l.trim().startsWith('-') || l.trim().startsWith('*'));
|
|
64
|
+
if (learningsList.length === 0) {
|
|
65
|
+
return { learningsFound: 0, memoryUpdated: false, scope };
|
|
66
|
+
}
|
|
67
|
+
// Stage 3 & 4: Consolidate with existing memory
|
|
68
|
+
const existingMemory = await this.memoryManager.read(scope);
|
|
69
|
+
const consolidated = await this.consolidateMemory(existingMemory, learnings);
|
|
70
|
+
if (consolidated && consolidated.trim()) {
|
|
71
|
+
await this.memoryManager.write(scope, consolidated);
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
learningsFound: learningsList.length,
|
|
75
|
+
memoryUpdated: true,
|
|
76
|
+
scope,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** Stage 2: Extract learnings from conversation messages. */
|
|
80
|
+
async gatherLearnings(messages) {
|
|
81
|
+
// Build a condensed transcript for the LLM
|
|
82
|
+
const transcript = messages
|
|
83
|
+
.filter(m => !m.isMeta && !m.isVisibleInTranscriptOnly)
|
|
84
|
+
.map(m => {
|
|
85
|
+
const texts = m.content
|
|
86
|
+
.filter((b) => b.type === 'text')
|
|
87
|
+
.map(b => b.text)
|
|
88
|
+
.join('');
|
|
89
|
+
return `[${m.role}]: ${texts.slice(0, 2000)}`;
|
|
90
|
+
})
|
|
91
|
+
.join('\n\n');
|
|
92
|
+
// Limit transcript size for the LLM call
|
|
93
|
+
const truncated = transcript.length > 12_000
|
|
94
|
+
? transcript.slice(0, 6000) + '\n\n...(middle omitted)...\n\n' + transcript.slice(-6000)
|
|
95
|
+
: transcript;
|
|
96
|
+
const chatMessages = [
|
|
97
|
+
{ role: 'user', content: [{ type: 'text', text: `Here is the conversation to analyze:\n\n${truncated}` }] },
|
|
98
|
+
];
|
|
99
|
+
const options = {
|
|
100
|
+
model: this.model,
|
|
101
|
+
systemPrompt: GATHER_PROMPT,
|
|
102
|
+
maxTokens: 1024,
|
|
103
|
+
temperature: 0.3,
|
|
104
|
+
};
|
|
105
|
+
try {
|
|
106
|
+
const response = await this.adapter.chat(chatMessages, options);
|
|
107
|
+
const text = response.content
|
|
108
|
+
.filter((b) => b.type === 'text')
|
|
109
|
+
.map(b => b.text)
|
|
110
|
+
.join('');
|
|
111
|
+
return text.trim();
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/** Stage 3 & 4: Merge new learnings with existing memory. */
|
|
118
|
+
async consolidateMemory(existing, newLearnings) {
|
|
119
|
+
const prompt = CONSOLIDATE_PROMPT.replace('{MAX_LINES}', String(MAX_MEMORY_LINES));
|
|
120
|
+
const chatMessages = [
|
|
121
|
+
{
|
|
122
|
+
role: 'user',
|
|
123
|
+
content: [{
|
|
124
|
+
type: 'text',
|
|
125
|
+
text: `## Existing Memory\n\n${existing || '(empty — first session)'}\n\n## New Learnings\n\n${newLearnings}`,
|
|
126
|
+
}],
|
|
127
|
+
},
|
|
128
|
+
];
|
|
129
|
+
const options = {
|
|
130
|
+
model: this.model,
|
|
131
|
+
systemPrompt: prompt,
|
|
132
|
+
maxTokens: 2048,
|
|
133
|
+
temperature: 0.2,
|
|
134
|
+
};
|
|
135
|
+
try {
|
|
136
|
+
const response = await this.adapter.chat(chatMessages, options);
|
|
137
|
+
const text = response.content
|
|
138
|
+
.filter((b) => b.type === 'text')
|
|
139
|
+
.map(b => b.text)
|
|
140
|
+
.join('');
|
|
141
|
+
return text.trim();
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=consolidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidation.js","sourceRoot":"","sources":["../../../src/memory/consolidation.ts"],"names":[],"mappings":"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"}
|