musonda 1.0.8 → 1.0.9
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/README.md +44 -5
- package/dist/agent/chatCompletionsClient.d.ts +56 -0
- package/dist/agent/chatCompletionsClient.js +345 -0
- package/dist/agent/chatCompletionsClient.js.map +1 -0
- package/dist/agent/harness.d.ts +6 -3
- package/dist/agent/harness.js +93 -20
- package/dist/agent/harness.js.map +1 -1
- package/dist/agent/modelFactory.d.ts +13 -0
- package/dist/agent/modelFactory.js +65 -0
- package/dist/agent/modelFactory.js.map +1 -0
- package/dist/agent/modelTypes.d.ts +46 -0
- package/dist/agent/modelTypes.js +2 -0
- package/dist/agent/modelTypes.js.map +1 -0
- package/dist/agent/openaiResponsesClient.d.ts +7 -11
- package/dist/agent/openaiResponsesClient.js +48 -0
- package/dist/agent/openaiResponsesClient.js.map +1 -1
- package/dist/agent/systemPrompt.js +1 -1
- package/dist/agent/systemPrompt.js.map +1 -1
- package/dist/cli/commands/connect.d.ts +1 -0
- package/dist/cli/commands/connect.js +17 -2
- package/dist/cli/commands/connect.js.map +1 -1
- package/dist/cli/commands/doctor.js +45 -5
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/help.js +73 -2
- package/dist/cli/commands/help.js.map +1 -1
- package/dist/cli/commands/langfuse.d.ts +18 -0
- package/dist/cli/commands/langfuse.js +139 -0
- package/dist/cli/commands/langfuse.js.map +1 -0
- package/dist/cli/commands/model.d.ts +38 -0
- package/dist/cli/commands/model.js +446 -0
- package/dist/cli/commands/model.js.map +1 -0
- package/dist/cli/commands/status.js +6 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/interactiveMenu.js +18 -4
- package/dist/cli/interactiveMenu.js.map +1 -1
- package/dist/cli/musondaCli.d.ts +9 -0
- package/dist/cli/musondaCli.js +124 -1
- package/dist/cli/musondaCli.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/config/loader.js +89 -15
- package/dist/config/loader.js.map +1 -1
- package/dist/config/types.d.ts +35 -4
- package/dist/config/types.js +26 -3
- package/dist/config/types.js.map +1 -1
- package/dist/gateway/channels/cli.js +3 -2
- package/dist/gateway/channels/cli.js.map +1 -1
- package/dist/gateway/channels/discord.js +4 -0
- package/dist/gateway/channels/discord.js.map +1 -1
- package/dist/gateway/channels/slack.js +39 -17
- package/dist/gateway/channels/slack.js.map +1 -1
- package/dist/gateway/channels/telegram.js +4 -0
- package/dist/gateway/channels/telegram.js.map +1 -1
- package/dist/gateway/http.js +20 -7
- package/dist/gateway/http.js.map +1 -1
- package/dist/gateway/server.d.ts +2 -2
- package/dist/gateway/server.js +24 -3
- package/dist/gateway/server.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/observability/langfuse.d.ts +91 -0
- package/dist/observability/langfuse.js +247 -0
- package/dist/observability/langfuse.js.map +1 -0
- package/dist/tools/registry.d.ts +2 -0
- package/dist/tools/registry.js +4 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/wizard/onboarding.d.ts +1 -1
- package/dist/wizard/onboarding.js +92 -20
- package/dist/wizard/onboarding.js.map +1 -1
- package/package.json +12 -5
package/README.md
CHANGED
|
@@ -50,8 +50,11 @@ or a companion you message on Discord.
|
|
|
50
50
|
|
|
51
51
|
## Getting started
|
|
52
52
|
|
|
53
|
-
You need [Node.js](https://nodejs.org/) 20 or newer and
|
|
54
|
-
|
|
53
|
+
You need [Node.js](https://nodejs.org/) 20 or newer and a model API key.
|
|
54
|
+
Musonda is model-agnostic: use OpenAI, Ollama (local, no key), LM Studio,
|
|
55
|
+
OpenRouter, Anthropic, Google, Groq, Mistral, DeepSeek, Together, or any
|
|
56
|
+
OpenAI-compatible endpoint. Discord and Slack are optional—you can start
|
|
57
|
+
entirely in your terminal.
|
|
55
58
|
|
|
56
59
|
### Quick install (npm)
|
|
57
60
|
|
|
@@ -154,7 +157,26 @@ Musonda includes a production multi-stage Dockerfile and Docker Compose configur
|
|
|
154
157
|
cp .env.example .env
|
|
155
158
|
```
|
|
156
159
|
|
|
157
|
-
2. Add your
|
|
160
|
+
2. Add your model credentials to `.env` (generic or provider-specific):
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
# Hosted (OpenAI example)
|
|
164
|
+
MODEL_PROVIDER=openai
|
|
165
|
+
MODEL_NAME=gpt-4o-mini
|
|
166
|
+
MODEL_API_KEY=sk-...
|
|
167
|
+
|
|
168
|
+
# Local (Ollama example — no key needed)
|
|
169
|
+
MODEL_PROVIDER=ollama
|
|
170
|
+
MODEL_NAME=llama3.1
|
|
171
|
+
MODEL_BASE_URL=http://localhost:11434/v1
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Or configure interactively at any time:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
musonda model setup
|
|
178
|
+
musonda model use ollama/llama3.1
|
|
179
|
+
```
|
|
158
180
|
|
|
159
181
|
3. Launch the container:
|
|
160
182
|
|
|
@@ -199,7 +221,16 @@ conversation.
|
|
|
199
221
|
|---|---|
|
|
200
222
|
| `musonda` | Opens the interactive dashboard and menu |
|
|
201
223
|
| `musonda setup` | Runs the personal onboarding and channel setup wizard |
|
|
224
|
+
| `musonda model` | Shows current AI model provider and model |
|
|
225
|
+
| `musonda model setup` | Configures AI model provider without onboarding |
|
|
226
|
+
| `musonda model use <provider>/<model>` | Switches provider + model (e.g. `ollama/llama3.1`) |
|
|
227
|
+
| `musonda connect model` | Alias for `musonda model setup` |
|
|
228
|
+
| `musonda connect <provider>` | Sets up a model provider's key (e.g. `deepseek`, `openai`, `ollama`) |
|
|
229
|
+
| `musonda change model <provider>[/<model>]` | Switches active model (provider must be set up first) |
|
|
202
230
|
| `musonda connect <channel>` | Connects a channel (telegram\|discord\|slack) without onboarding |
|
|
231
|
+
| `musonda connect langfuse` | Connects Langfuse tracing (agent observability) |
|
|
232
|
+
| `musonda disconnect langfuse` | Disables Langfuse tracing (keys are kept) |
|
|
233
|
+
| `musonda langfuse status` | Shows Langfuse tracing status |
|
|
203
234
|
| `musonda disconnect <channel>` | Disables a connected channel (tokens are kept) |
|
|
204
235
|
| `musonda channels` | Shows channel connection status |
|
|
205
236
|
| `musonda cli` | Starts an interactive terminal conversation |
|
|
@@ -225,8 +256,16 @@ You can also supply environment variables in a `.env` file in your working direc
|
|
|
225
256
|
|
|
226
257
|
| Environment Variable | Description | Default |
|
|
227
258
|
|---|---|---|
|
|
228
|
-
| `
|
|
229
|
-
| `
|
|
259
|
+
| `MODEL_PROVIDER` | Model provider (`openai`, `ollama`, `lmstudio`, `openrouter`, `anthropic`, `google`, `groq`, `mistral`, `deepseek`, `together`, custom) | `openai` |
|
|
260
|
+
| `MODEL_NAME` | Target language model (any provider model name) | `gpt-5.6-luna` |
|
|
261
|
+
| `MODEL_API_KEY` | Provider API key (not needed for `ollama`/`lmstudio`) | |
|
|
262
|
+
| `MODEL_BASE_URL` | Custom OpenAI-compatible base URL | provider default |
|
|
263
|
+
| `MODEL_API` | API dialect: `auto` / `chat` (universal) / `responses` (OpenAI-only) | `auto` |
|
|
264
|
+
| `OPENAI_API_KEY` / `OPENAI_MODEL` / `OPENAI_BASE_URL` | Legacy fallbacks (still supported) | |
|
|
265
|
+
| `ANTHROPIC_API_KEY` / `GOOGLE_API_KEY` / `OPENROUTER_API_KEY` / `GROQ_API_KEY` | Provider-specific keys (auto-detected) | |
|
|
266
|
+
| `LANGFUSE_SECRET_KEY` / `LANGFUSE_PUBLIC_KEY` | Langfuse tracing keys (or use `musonda connect langfuse`) | |
|
|
267
|
+
| `LANGFUSE_BASE_URL` | Langfuse server (Cloud EU default) | `https://cloud.langfuse.com` |
|
|
268
|
+
| `LANGFUSE_ENABLED` | Enable Langfuse tracing (`true`/`1`) | `false` |
|
|
230
269
|
| `PORT` or `GATEWAY_PORT` | HTTP Gateway listening port | `4141` |
|
|
231
270
|
| `HOST` or `GATEWAY_HOST` | HTTP Gateway binding address | `127.0.0.1` |
|
|
232
271
|
| `DISCORD_BOT_TOKEN` | Discord Bot token (optional) | |
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ModelConfig } from '../config/types.js';
|
|
2
|
+
import { OpenAIFunctionToolSchema } from '../tools/types.js';
|
|
3
|
+
import { ModelResponseResult } from './modelTypes.js';
|
|
4
|
+
/**
|
|
5
|
+
* Generic OpenAI-compatible Chat Completions client.
|
|
6
|
+
*
|
|
7
|
+
* Speaks the `/chat/completions` dialect understood by OpenAI itself
|
|
8
|
+
* plus Ollama, LM Studio, vLLM, OpenRouter, Groq, Mistral, DeepSeek,
|
|
9
|
+
* Together, Azure OpenAI, and any other OpenAI-compatible endpoint.
|
|
10
|
+
* This is what makes Musonda model-agnostic: point `baseUrl` at any
|
|
11
|
+
* compatible server and set `model` to any hosted model name.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ChatCompletionsClient {
|
|
14
|
+
private client;
|
|
15
|
+
private model;
|
|
16
|
+
private provider;
|
|
17
|
+
private temperature?;
|
|
18
|
+
private maxOutputTokens;
|
|
19
|
+
private readinessCache;
|
|
20
|
+
constructor(config: ModelConfig);
|
|
21
|
+
getModelName(): string;
|
|
22
|
+
getProviderName(): string;
|
|
23
|
+
private withRetry;
|
|
24
|
+
checkReadiness(cacheMs?: number): Promise<{
|
|
25
|
+
ready: boolean;
|
|
26
|
+
reason?: string;
|
|
27
|
+
}>;
|
|
28
|
+
generateImage(params: {
|
|
29
|
+
prompt: string;
|
|
30
|
+
size?: string;
|
|
31
|
+
model?: string;
|
|
32
|
+
quality?: 'standard' | 'hd';
|
|
33
|
+
style?: 'vivid' | 'natural';
|
|
34
|
+
}): Promise<{
|
|
35
|
+
b64_json?: string;
|
|
36
|
+
url?: string;
|
|
37
|
+
revised_prompt?: string;
|
|
38
|
+
}>;
|
|
39
|
+
private supportsTemperature;
|
|
40
|
+
/** Convert Responses-style input items + instructions into Chat Completions messages. */
|
|
41
|
+
private toChatMessages;
|
|
42
|
+
/** Convert Responses content parts (input_text/input_image) to Chat content parts. */
|
|
43
|
+
private toChatContent;
|
|
44
|
+
private toChatTools;
|
|
45
|
+
generate(params: {
|
|
46
|
+
instructions: string;
|
|
47
|
+
input: any[];
|
|
48
|
+
tools?: OpenAIFunctionToolSchema[];
|
|
49
|
+
onDelta?: (delta: string) => void | Promise<void>;
|
|
50
|
+
onReasoningSummaryDelta?: (delta: string) => void | Promise<void>;
|
|
51
|
+
}): Promise<ModelResponseResult>;
|
|
52
|
+
private summarizeInput;
|
|
53
|
+
private doGenerate;
|
|
54
|
+
private isTempError;
|
|
55
|
+
private toProviderError;
|
|
56
|
+
}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
import { langfuseTracer } from '../observability/langfuse.js';
|
|
4
|
+
/**
|
|
5
|
+
* Generic OpenAI-compatible Chat Completions client.
|
|
6
|
+
*
|
|
7
|
+
* Speaks the `/chat/completions` dialect understood by OpenAI itself
|
|
8
|
+
* plus Ollama, LM Studio, vLLM, OpenRouter, Groq, Mistral, DeepSeek,
|
|
9
|
+
* Together, Azure OpenAI, and any other OpenAI-compatible endpoint.
|
|
10
|
+
* This is what makes Musonda model-agnostic: point `baseUrl` at any
|
|
11
|
+
* compatible server and set `model` to any hosted model name.
|
|
12
|
+
*/
|
|
13
|
+
export class ChatCompletionsClient {
|
|
14
|
+
client;
|
|
15
|
+
model;
|
|
16
|
+
provider;
|
|
17
|
+
temperature;
|
|
18
|
+
maxOutputTokens;
|
|
19
|
+
readinessCache = null;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.model = config.model || 'gpt-4o-mini';
|
|
22
|
+
this.provider = config.provider || 'openai-compatible';
|
|
23
|
+
this.temperature = config.temperature;
|
|
24
|
+
this.maxOutputTokens = config.maxOutputTokens ?? 4096;
|
|
25
|
+
this.client = new OpenAI({
|
|
26
|
+
// Local runtimes (Ollama / LM Studio) typically need no key.
|
|
27
|
+
apiKey: config.apiKey || 'not-needed',
|
|
28
|
+
baseURL: config.baseUrl || undefined,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
getModelName() {
|
|
32
|
+
return this.model;
|
|
33
|
+
}
|
|
34
|
+
getProviderName() {
|
|
35
|
+
return this.provider;
|
|
36
|
+
}
|
|
37
|
+
async withRetry(fn, opts) {
|
|
38
|
+
const tries = opts?.tries ?? 3;
|
|
39
|
+
let lastErr;
|
|
40
|
+
for (let attempt = 1; attempt <= tries; attempt++) {
|
|
41
|
+
try {
|
|
42
|
+
return await fn();
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
lastErr = err;
|
|
46
|
+
const status = err?.status;
|
|
47
|
+
const retryable = status === 429 || (typeof status === 'number' && status >= 500) || status === undefined;
|
|
48
|
+
if (!retryable || attempt === tries)
|
|
49
|
+
throw err;
|
|
50
|
+
const retryAfter = Number(err?.headers?.['retry-after']);
|
|
51
|
+
const base = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1000 : 1000 * 2 ** (attempt - 1);
|
|
52
|
+
const delay = Math.min(base + Math.floor(Math.random() * 500), 10000);
|
|
53
|
+
logger.debug(`Model ${opts?.label || 'request'} transient failure (attempt ${attempt}/${tries}, status ${status}). Retrying in ${delay}ms...`);
|
|
54
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
throw lastErr;
|
|
58
|
+
}
|
|
59
|
+
async checkReadiness(cacheMs = 30000) {
|
|
60
|
+
const now = Date.now();
|
|
61
|
+
if (this.readinessCache && now - this.readinessCache.checkedAt < cacheMs) {
|
|
62
|
+
return { ready: this.readinessCache.ready, reason: this.readinessCache.reason };
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
await this.client.models.retrieve(this.model, { timeout: 4000, maxRetries: 0 });
|
|
66
|
+
this.readinessCache = { checkedAt: now, ready: true };
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
// Local providers (Ollama/LM Studio) often lack a /models/:id endpoint.
|
|
70
|
+
// Fall back to listing models and checking reachability.
|
|
71
|
+
try {
|
|
72
|
+
await this.client.models.list({ timeout: 4000, maxRetries: 0 });
|
|
73
|
+
this.readinessCache = { checkedAt: now, ready: true };
|
|
74
|
+
}
|
|
75
|
+
catch (inner) {
|
|
76
|
+
const reason = inner?.status === 401 || inner?.status === 403
|
|
77
|
+
? 'credentials_rejected'
|
|
78
|
+
: inner?.status === 404
|
|
79
|
+
? 'model_unavailable'
|
|
80
|
+
: 'provider_unreachable';
|
|
81
|
+
this.readinessCache = { checkedAt: now, ready: false, reason };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return { ready: this.readinessCache.ready, reason: this.readinessCache.reason };
|
|
85
|
+
}
|
|
86
|
+
async generateImage(params) {
|
|
87
|
+
try {
|
|
88
|
+
const response = await this.client.images.generate({
|
|
89
|
+
model: params.model || 'dall-e-3',
|
|
90
|
+
prompt: params.prompt,
|
|
91
|
+
n: 1,
|
|
92
|
+
size: params.size || '1024x1024',
|
|
93
|
+
response_format: 'b64_json',
|
|
94
|
+
quality: params.quality,
|
|
95
|
+
style: params.style,
|
|
96
|
+
});
|
|
97
|
+
const item = response.data?.[0];
|
|
98
|
+
return { b64_json: item?.b64_json, url: item?.url, revised_prompt: item?.revised_prompt };
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
logger.debug(`Image generation unavailable on provider "${this.provider}" (${this.model}):`, err.message || err);
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
supportsTemperature(model) {
|
|
106
|
+
const m = model.toLowerCase();
|
|
107
|
+
if (m.startsWith('gpt-5') || m.startsWith('o1') || m.startsWith('o3') || m.startsWith('o4'))
|
|
108
|
+
return false;
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
/** Convert Responses-style input items + instructions into Chat Completions messages. */
|
|
112
|
+
toChatMessages(instructions, input) {
|
|
113
|
+
const messages = [{ role: 'system', content: instructions }];
|
|
114
|
+
for (const item of input || []) {
|
|
115
|
+
if (!item || typeof item !== 'object')
|
|
116
|
+
continue;
|
|
117
|
+
if (item.type === 'function_call') {
|
|
118
|
+
messages.push({
|
|
119
|
+
role: 'assistant',
|
|
120
|
+
content: null,
|
|
121
|
+
tool_calls: [
|
|
122
|
+
{
|
|
123
|
+
id: item.call_id || item.callId,
|
|
124
|
+
type: 'function',
|
|
125
|
+
function: {
|
|
126
|
+
name: item.name,
|
|
127
|
+
arguments: typeof item.arguments === 'string' ? item.arguments : JSON.stringify(item.arguments || {}),
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
});
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (item.type === 'function_call_output') {
|
|
135
|
+
messages.push({
|
|
136
|
+
role: 'tool',
|
|
137
|
+
tool_call_id: item.call_id || item.callId,
|
|
138
|
+
content: typeof item.output === 'string' ? item.output : JSON.stringify(item.output ?? ''),
|
|
139
|
+
});
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const role = item.role === 'assistant' || item.role === 'user' || item.role === 'system' ? item.role : 'user';
|
|
143
|
+
messages.push({ role, content: this.toChatContent(item.content) });
|
|
144
|
+
}
|
|
145
|
+
return messages;
|
|
146
|
+
}
|
|
147
|
+
/** Convert Responses content parts (input_text/input_image) to Chat content parts. */
|
|
148
|
+
toChatContent(content) {
|
|
149
|
+
if (typeof content === 'string' || content === null || content === undefined)
|
|
150
|
+
return content ?? '';
|
|
151
|
+
if (!Array.isArray(content))
|
|
152
|
+
return content;
|
|
153
|
+
return content.map((part) => {
|
|
154
|
+
if (!part || typeof part !== 'object')
|
|
155
|
+
return { type: 'text', text: String(part) };
|
|
156
|
+
if (part.type === 'input_text')
|
|
157
|
+
return { type: 'text', text: part.text ?? '' };
|
|
158
|
+
if (part.type === 'input_image') {
|
|
159
|
+
const url = typeof part.image_url === 'string' ? part.image_url : part.image_url?.url || part.url;
|
|
160
|
+
return { type: 'image_url', image_url: { url } };
|
|
161
|
+
}
|
|
162
|
+
if (part.type === 'text' || part.type === 'image_url')
|
|
163
|
+
return part;
|
|
164
|
+
return part;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
toChatTools(tools) {
|
|
168
|
+
if (!tools || tools.length === 0)
|
|
169
|
+
return undefined;
|
|
170
|
+
return tools.map((t) => ({
|
|
171
|
+
type: 'function',
|
|
172
|
+
function: {
|
|
173
|
+
name: t.name || t.function?.name,
|
|
174
|
+
description: t.description || t.function?.description || '',
|
|
175
|
+
parameters: t.parameters || t.function?.parameters || { type: 'object', properties: {} },
|
|
176
|
+
},
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
async generate(params) {
|
|
180
|
+
const genSpan = langfuseTracer.startGeneration('musonda-llm-generation', {
|
|
181
|
+
model: this.model,
|
|
182
|
+
input: this.summarizeInput(params.instructions, params.input, params.tools),
|
|
183
|
+
metadata: { provider: this.provider, model: this.model, inputItems: params.input?.length || 0, tools: params.tools?.length || 0 },
|
|
184
|
+
});
|
|
185
|
+
const startedAt = Date.now();
|
|
186
|
+
try {
|
|
187
|
+
const result = await this.doGenerate(params);
|
|
188
|
+
langfuseTracer.endSpan(genSpan, {
|
|
189
|
+
output: { text: result.text?.slice(0, 4000), toolCalls: result.toolCalls?.length || 0 },
|
|
190
|
+
metadata: { provider: this.provider, model: this.model, latencyMs: Date.now() - startedAt, toolCalls: result.toolCalls?.length || 0 },
|
|
191
|
+
});
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
langfuseTracer.endSpan(genSpan, {
|
|
196
|
+
metadata: { provider: this.provider, model: this.model, latencyMs: Date.now() - startedAt, error: err?.message || String(err) },
|
|
197
|
+
});
|
|
198
|
+
throw err;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
summarizeInput(instructions, input, tools) {
|
|
202
|
+
try {
|
|
203
|
+
const last = input?.slice(-6).map((item) => {
|
|
204
|
+
if (typeof item === 'string')
|
|
205
|
+
return item.slice(0, 500);
|
|
206
|
+
const content = typeof item?.content === 'string'
|
|
207
|
+
? item.content.slice(0, 500)
|
|
208
|
+
: JSON.stringify(item?.content ?? item).slice(0, 500);
|
|
209
|
+
return { type: item?.type || item?.role, name: item?.name, content };
|
|
210
|
+
});
|
|
211
|
+
return {
|
|
212
|
+
instructions: instructions?.slice(0, 2000),
|
|
213
|
+
recentInput: last,
|
|
214
|
+
toolNames: (tools || []).map((t) => t?.name || t?.function?.name).filter(Boolean),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return { instructions: instructions?.slice(0, 500), inputItems: input?.length || 0 };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async doGenerate(params) {
|
|
222
|
+
logger.debug(`Calling Chat Completions (provider "${this.provider}") with model "${this.model}", ${params.input.length} input items...`);
|
|
223
|
+
const messages = this.toChatMessages(params.instructions, params.input);
|
|
224
|
+
const tools = this.toChatTools(params.tools);
|
|
225
|
+
const basePayload = {
|
|
226
|
+
model: this.model,
|
|
227
|
+
messages,
|
|
228
|
+
max_tokens: this.maxOutputTokens,
|
|
229
|
+
};
|
|
230
|
+
if (this.temperature !== undefined && this.supportsTemperature(this.model)) {
|
|
231
|
+
basePayload.temperature = this.temperature;
|
|
232
|
+
}
|
|
233
|
+
if (tools)
|
|
234
|
+
basePayload.tools = tools;
|
|
235
|
+
// Streaming path
|
|
236
|
+
if (params.onDelta) {
|
|
237
|
+
let stream;
|
|
238
|
+
try {
|
|
239
|
+
stream = await this.withRetry(() => this.client.chat.completions.create({ ...basePayload, stream: true }), { label: 'chat.stream' });
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
if (this.isTempError(err) && basePayload.temperature !== undefined) {
|
|
243
|
+
delete basePayload.temperature;
|
|
244
|
+
stream = await this.withRetry(() => this.client.chat.completions.create({ ...basePayload, stream: true }), { label: 'chat.stream' });
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
throw this.toProviderError(err);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
let accumulatedText = '';
|
|
251
|
+
const toolCallMap = new Map();
|
|
252
|
+
const orderedIds = [];
|
|
253
|
+
for await (const chunk of stream) {
|
|
254
|
+
const choice = chunk?.choices?.[0];
|
|
255
|
+
const delta = choice?.delta;
|
|
256
|
+
if (!delta)
|
|
257
|
+
continue;
|
|
258
|
+
const textDelta = delta.content || '';
|
|
259
|
+
if (textDelta) {
|
|
260
|
+
accumulatedText += textDelta;
|
|
261
|
+
try {
|
|
262
|
+
await params.onDelta(textDelta);
|
|
263
|
+
}
|
|
264
|
+
catch (cbErr) {
|
|
265
|
+
logger.debug('Error in onDelta streaming callback:', cbErr);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const deltaToolCalls = delta.tool_calls;
|
|
269
|
+
if (Array.isArray(deltaToolCalls)) {
|
|
270
|
+
for (const tc of deltaToolCalls) {
|
|
271
|
+
const idx = typeof tc.index === 'number' ? tc.index : 0;
|
|
272
|
+
const key = `idx:${idx}`;
|
|
273
|
+
let entry = toolCallMap.get(key);
|
|
274
|
+
if (!entry) {
|
|
275
|
+
entry = { id: tc.id || '', name: tc.function?.name || '', args: '' };
|
|
276
|
+
toolCallMap.set(key, entry);
|
|
277
|
+
orderedIds.push(key);
|
|
278
|
+
}
|
|
279
|
+
if (tc.id)
|
|
280
|
+
entry.id = tc.id;
|
|
281
|
+
if (tc.function?.name)
|
|
282
|
+
entry.name = tc.function.name;
|
|
283
|
+
if (tc.function?.arguments)
|
|
284
|
+
entry.args += tc.function.arguments;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const toolCalls = [];
|
|
289
|
+
for (const key of orderedIds) {
|
|
290
|
+
const entry = toolCallMap.get(key);
|
|
291
|
+
if (!entry.name)
|
|
292
|
+
continue;
|
|
293
|
+
toolCalls.push({
|
|
294
|
+
callId: entry.id || `call_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`,
|
|
295
|
+
name: entry.name,
|
|
296
|
+
arguments: entry.args || '{}',
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
return { text: accumulatedText.trim(), toolCalls, rawOutput: [] };
|
|
300
|
+
}
|
|
301
|
+
// Non-streaming path
|
|
302
|
+
let response;
|
|
303
|
+
try {
|
|
304
|
+
response = await this.withRetry(() => this.client.chat.completions.create(basePayload), {
|
|
305
|
+
label: 'chat.create',
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
if (this.isTempError(err) && basePayload.temperature !== undefined) {
|
|
310
|
+
delete basePayload.temperature;
|
|
311
|
+
response = await this.withRetry(() => this.client.chat.completions.create(basePayload), {
|
|
312
|
+
label: 'chat.create',
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
throw this.toProviderError(err);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
const message = response?.choices?.[0]?.message;
|
|
320
|
+
const text = typeof message?.content === 'string' ? message.content : '';
|
|
321
|
+
const toolCalls = [];
|
|
322
|
+
if (Array.isArray(message?.tool_calls)) {
|
|
323
|
+
for (const tc of message.tool_calls) {
|
|
324
|
+
toolCalls.push({
|
|
325
|
+
callId: tc.id || `call_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`,
|
|
326
|
+
name: tc.function?.name,
|
|
327
|
+
arguments: typeof tc.function?.arguments === 'string' ? tc.function.arguments : JSON.stringify(tc.function?.arguments || {}),
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return { text: (text || '').trim(), toolCalls, rawOutput: [] };
|
|
332
|
+
}
|
|
333
|
+
isTempError(err) {
|
|
334
|
+
return (err?.status === 400 &&
|
|
335
|
+
(err?.message?.includes('temperature') || err?.param === 'temperature' || err?.error?.param === 'temperature'));
|
|
336
|
+
}
|
|
337
|
+
toProviderError(err) {
|
|
338
|
+
logger.error(`Chat Completions error (provider "${this.provider}", model "${this.model}"):`, err.message || err);
|
|
339
|
+
if (err.status === 401 || (err.message && err.message.includes('API key'))) {
|
|
340
|
+
return new Error(`Model Authentication Error [${this.provider}]: API key is invalid or missing for model "${this.model}". Run 'musonda setup' or 'musonda model setup' to configure credentials.`);
|
|
341
|
+
}
|
|
342
|
+
return err;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=chatCompletionsClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatCompletionsClient.js","sourceRoot":"","sources":["../../src/agent/chatCompletionsClient.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/harness.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MusondaConfig } from '../config/types.js';
|
|
2
2
|
import { MemoryManager } from '../memory/memoryManager.js';
|
|
3
3
|
import { ToolRegistry } from '../tools/registry.js';
|
|
4
|
-
import {
|
|
4
|
+
import { ModelClient } from './modelTypes.js';
|
|
5
5
|
import { AgentRunInput, AgentRunResult } from './types.js';
|
|
6
6
|
import { FileRunLedger } from './runLedger.js';
|
|
7
7
|
import { MediaManager } from '../media/mediaManager.js';
|
|
@@ -16,7 +16,7 @@ export declare class AgentHarness {
|
|
|
16
16
|
private gateway?;
|
|
17
17
|
private mediaManager?;
|
|
18
18
|
private runLedger?;
|
|
19
|
-
constructor(config: MusondaConfig, memory: MemoryManager, tools: ToolRegistry, client:
|
|
19
|
+
constructor(config: MusondaConfig, memory: MemoryManager, tools: ToolRegistry, client: ModelClient, scheduler?: any, pluginManager?: any, gateway?: any, mediaManager?: MediaManager);
|
|
20
20
|
setMediaManager(mediaManager: MediaManager): void;
|
|
21
21
|
getMediaManager(): MediaManager | undefined;
|
|
22
22
|
setGateway(gateway: any): void;
|
|
@@ -27,7 +27,9 @@ export declare class AgentHarness {
|
|
|
27
27
|
getPluginManager(): any;
|
|
28
28
|
getMemoryManager(): MemoryManager;
|
|
29
29
|
getToolRegistry(): ToolRegistry;
|
|
30
|
-
getClient():
|
|
30
|
+
getClient(): ModelClient;
|
|
31
|
+
/** Swap the model client at runtime (e.g. after `musonda model` changes). */
|
|
32
|
+
setClient(client: ModelClient): void;
|
|
31
33
|
/** Inject a file-backed run ledger (durable journal). Optional — harness works without it. */
|
|
32
34
|
setRunLedger(ledger: FileRunLedger): void;
|
|
33
35
|
getRunLedger(): FileRunLedger | undefined;
|
|
@@ -38,4 +40,5 @@ export declare class AgentHarness {
|
|
|
38
40
|
private formatToolStatus;
|
|
39
41
|
private formatToolReviewStatus;
|
|
40
42
|
processMessage(input: AgentRunInput): Promise<AgentRunResult>;
|
|
43
|
+
private doProcessMessage;
|
|
41
44
|
}
|