@jellyos/agent 0.1.2 → 0.1.4
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 +9 -9
- package/dist/api/Registry.js +3 -1
- package/dist/api/Registry.js.map +1 -1
- package/dist/cli.js +11 -24
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +1 -25
- package/dist/loader.js.map +1 -1
- package/dist/models/CostTracker.d.ts +66 -0
- package/dist/models/CostTracker.d.ts.map +1 -0
- package/dist/models/CostTracker.js +148 -0
- package/dist/models/CostTracker.js.map +1 -0
- package/dist/models/ModelRegistry.d.ts +146 -0
- package/dist/models/ModelRegistry.d.ts.map +1 -0
- package/dist/models/ModelRegistry.js +400 -0
- package/dist/models/ModelRegistry.js.map +1 -0
- package/dist/models/index.d.ts +5 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/models/index.js +3 -0
- package/dist/models/index.js.map +1 -0
- package/dist/runner/AgentRunner.d.ts +5 -1
- package/dist/runner/AgentRunner.d.ts.map +1 -1
- package/dist/runner/AgentRunner.js +18 -8
- package/dist/runner/AgentRunner.js.map +1 -1
- package/dist/runner/ModelClient.d.ts +16 -5
- package/dist/runner/ModelClient.d.ts.map +1 -1
- package/dist/runner/ModelClient.js +69 -23
- package/dist/runner/ModelClient.js.map +1 -1
- package/dist/runner/SwarmRouter.d.ts +4 -1
- package/dist/runner/SwarmRouter.d.ts.map +1 -1
- package/dist/runner/SwarmRouter.js +15 -7
- package/dist/runner/SwarmRouter.js.map +1 -1
- package/dist/session/SessionManager.d.ts +2 -2
- package/dist/session/SessionManager.js +3 -3
- package/dist/session/SessionManager.js.map +1 -1
- package/dist/tools/NewsSentiment.d.ts +67 -0
- package/dist/tools/NewsSentiment.d.ts.map +1 -0
- package/dist/tools/NewsSentiment.js +199 -0
- package/dist/tools/NewsSentiment.js.map +1 -0
- package/dist/tools/PriceFeed.d.ts +103 -0
- package/dist/tools/PriceFeed.d.ts.map +1 -0
- package/dist/tools/PriceFeed.js +230 -0
- package/dist/tools/PriceFeed.js.map +1 -0
- package/dist/tools/TechnicalAnalysis.d.ts +73 -0
- package/dist/tools/TechnicalAnalysis.d.ts.map +1 -0
- package/dist/tools/TechnicalAnalysis.js +272 -0
- package/dist/tools/TechnicalAnalysis.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tui/App.d.ts +7 -5
- package/dist/tui/App.d.ts.map +1 -1
- package/dist/tui/App.js +178 -61
- package/dist/tui/App.js.map +1 -1
- package/dist/tui/StatusBar.js +1 -1
- package/dist/tui/StatusBar.js.map +1 -1
- package/package.json +2 -2
- package/dist/util/safeLog.d.ts +0 -39
- package/dist/util/safeLog.d.ts.map +0 -1
- package/dist/util/safeLog.js +0 -59
- package/dist/util/safeLog.js.map +0 -1
|
@@ -26,19 +26,23 @@ export class AgentRunner {
|
|
|
26
26
|
modelChain;
|
|
27
27
|
dispatcher;
|
|
28
28
|
swarmRouter;
|
|
29
|
-
|
|
29
|
+
modelRegistry;
|
|
30
|
+
costTracker;
|
|
31
|
+
constructor(registry, session, onEvent, sessionCtx, effectLevel = "normal", modelReg, costTracker) {
|
|
30
32
|
this.registry = registry;
|
|
31
33
|
this.session = session;
|
|
32
34
|
this.onEvent = onEvent;
|
|
33
35
|
this.sessionCtx = sessionCtx;
|
|
34
36
|
this.effectLevel = effectLevel;
|
|
35
|
-
this.
|
|
37
|
+
this.modelRegistry = modelReg;
|
|
38
|
+
this.costTracker = costTracker;
|
|
39
|
+
this.modelChain = resolveModelChain(modelReg);
|
|
36
40
|
this.dispatcher = new ToolDispatcher(registry);
|
|
37
41
|
const sc = EFFECT_SWARM[effectLevel] ?? EFFECT_SWARM["normal"];
|
|
38
42
|
this.swarmRouter = new SwarmRouter({
|
|
39
43
|
maxAgents: sc.maxAgents,
|
|
40
44
|
complexityThreshold: sc.threshold,
|
|
41
|
-
});
|
|
45
|
+
}, modelReg);
|
|
42
46
|
}
|
|
43
47
|
/**
|
|
44
48
|
* Live reconfigure effect level without recreating the runner.
|
|
@@ -47,13 +51,12 @@ export class AgentRunner {
|
|
|
47
51
|
*/
|
|
48
52
|
setEffectLevel(level) {
|
|
49
53
|
this.effectLevel = level;
|
|
50
|
-
|
|
51
|
-
this.modelChain = resolveModelChain();
|
|
54
|
+
this.modelChain = resolveModelChain(this.modelRegistry);
|
|
52
55
|
const sc = EFFECT_SWARM[level] ?? EFFECT_SWARM["normal"];
|
|
53
56
|
this.swarmRouter = new SwarmRouter({
|
|
54
57
|
maxAgents: sc.maxAgents,
|
|
55
58
|
complexityThreshold: sc.threshold,
|
|
56
|
-
});
|
|
59
|
+
}, this.modelRegistry);
|
|
57
60
|
}
|
|
58
61
|
/** Run one user turn — may invoke multiple tool rounds and model fallbacks internally */
|
|
59
62
|
async run(userMessage) {
|
|
@@ -106,7 +109,7 @@ export class AgentRunner {
|
|
|
106
109
|
// Try model chain — rotate on 429/5xx
|
|
107
110
|
for (let mi = 0; mi < this.modelChain.length; mi++) {
|
|
108
111
|
const cfg = this.modelChain[mi];
|
|
109
|
-
const client = new ModelClient(cfg);
|
|
112
|
+
const client = new ModelClient(cfg, this.modelRegistry);
|
|
110
113
|
assistantText = "";
|
|
111
114
|
pendingToolCalls = [];
|
|
112
115
|
modelError = null;
|
|
@@ -133,6 +136,10 @@ export class AgentRunner {
|
|
|
133
136
|
break; // success — use this model's output
|
|
134
137
|
// Rotate to next model on rate-limit or server errors
|
|
135
138
|
const nextCfg = this.modelChain[mi + 1];
|
|
139
|
+
// Save any partial text the user already saw before rotating
|
|
140
|
+
if (assistantText.trim()) {
|
|
141
|
+
this.session.addMessage({ role: "assistant", content: assistantText + "\n\n[connection interrupted — retrying with fallback model]" });
|
|
142
|
+
}
|
|
136
143
|
if (nextCfg && isRateLimit) {
|
|
137
144
|
this.onEvent({
|
|
138
145
|
type: "model_fallback",
|
|
@@ -142,7 +149,10 @@ export class AgentRunner {
|
|
|
142
149
|
});
|
|
143
150
|
continue;
|
|
144
151
|
}
|
|
145
|
-
// Non-recoverable error or no more fallbacks
|
|
152
|
+
// Non-recoverable error or no more fallbacks — commit partial text if any
|
|
153
|
+
if (assistantText.trim()) {
|
|
154
|
+
this.session.addMessage({ role: "assistant", content: assistantText });
|
|
155
|
+
}
|
|
146
156
|
this.onEvent({ type: "error", message: modelError ?? "Model error" });
|
|
147
157
|
return;
|
|
148
158
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentRunner.js","sourceRoot":"","sources":["../../src/runner/AgentRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,WAAW,EACX,iBAAiB,GAIlB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAO,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAU,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"AgentRunner.js","sourceRoot":"","sources":["../../src/runner/AgentRunner.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
* OpenRouter > Anthropic compat > OpenAI > local (ollama/lm-studio)
|
|
6
6
|
*
|
|
7
7
|
* Model rotation: resolveModelChain() returns up to 5 configs — the AgentRunner
|
|
8
|
-
* walks the chain on 429 (rate limit) or 5xx errors,
|
|
8
|
+
* walks the chain on 429 (rate limit) or 5xx errors, with exponential backoff
|
|
9
|
+
* (up to 2 retries per model) before falling through.
|
|
10
|
+
*
|
|
11
|
+
* When a ModelRegistry is available, chains are dynamically built from the
|
|
12
|
+
* tiered pool, with per-model performance tracking and cost estimation.
|
|
9
13
|
*
|
|
10
14
|
* All outbound, all local — no inbound ports, no server.
|
|
11
15
|
*/
|
|
16
|
+
import type { ModelRegistry } from "../models/ModelRegistry.js";
|
|
12
17
|
export interface Message {
|
|
13
18
|
role: "system" | "user" | "assistant" | "tool";
|
|
14
19
|
content: string | null;
|
|
@@ -45,6 +50,9 @@ export interface ModelConfig {
|
|
|
45
50
|
/**
|
|
46
51
|
* Build the ordered model fallback chain.
|
|
47
52
|
*
|
|
53
|
+
* If a ModelRegistry is provided, builds from the tiered pool dynamically.
|
|
54
|
+
* Falls back to static env-var parsing otherwise.
|
|
55
|
+
*
|
|
48
56
|
* User-configurable pool: JELLY_MODEL_1 … JELLY_MODEL_5
|
|
49
57
|
* If any JELLY_MODEL_N vars are set they take priority; up to 5 are used in
|
|
50
58
|
* order. Unset slots are filled with provider-appropriate defaults.
|
|
@@ -54,16 +62,19 @@ export interface ModelConfig {
|
|
|
54
62
|
* JELLY_MODEL_2=openai/gpt-4o
|
|
55
63
|
* JELLY_MODEL_3=google/gemini-2.5-pro
|
|
56
64
|
*/
|
|
57
|
-
export declare function resolveModelChain(): ModelConfig[];
|
|
65
|
+
export declare function resolveModelChain(modelReg?: ModelRegistry): ModelConfig[];
|
|
58
66
|
/** Convenience: returns just the primary (first) model config */
|
|
59
|
-
export declare function resolveModelConfig(): ModelConfig;
|
|
67
|
+
export declare function resolveModelConfig(modelReg?: ModelRegistry): ModelConfig;
|
|
60
68
|
export declare class ModelClient {
|
|
61
69
|
private cfg;
|
|
62
|
-
|
|
70
|
+
private modelRegistry?;
|
|
71
|
+
constructor(cfg: ModelConfig, modelReg?: ModelRegistry);
|
|
63
72
|
/**
|
|
64
73
|
* Stream a chat completion. Yields ChatChunk objects.
|
|
65
|
-
*
|
|
74
|
+
* Retries up to 2 times on 429 / 5xx with exponential backoff (1s, 2s).
|
|
75
|
+
* On persistent HTTP error the generator yields a single { type: "error", status, error }
|
|
66
76
|
* chunk and returns — the caller (AgentRunner) decides whether to rotate.
|
|
77
|
+
* Also reports success/failure to the ModelRegistry for tiering and cooldown.
|
|
67
78
|
*/
|
|
68
79
|
stream(messages: Message[], tools?: Array<{
|
|
69
80
|
type: "function";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelClient.d.ts","sourceRoot":"","sources":["../../src/runner/ModelClient.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ModelClient.d.ts","sourceRoot":"","sources":["../../src/runner/ModelClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,WAAW,OAAO;IACtB,IAAI,EAAW,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACxD,OAAO,EAAQ,MAAM,GAAG,IAAI,CAAC;IAC7B,IAAI,CAAC,EAAU,MAAM,CAAC;IACtB,UAAU,CAAC,EAAI,QAAQ,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAQ,MAAM,CAAC;IACjB,IAAI,EAAM,UAAU,CAAC;IACrB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAY,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;IACzD,IAAI,CAAC,EAAW,MAAM,CAAC;IACvB,UAAU,CAAC,EAAK,QAAQ,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAU,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,MAAM,CAAC,EAAS,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAM,MAAM,CAAC;IACpB,MAAM,EAAO,MAAM,CAAC;IACpB,KAAK,EAAQ,MAAM,CAAC;IACpB,SAAS,EAAI,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAK,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAI,MAAM,CAAC;CACrB;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,WAAW,EAAE,CAuFzE;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,WAAW,CAExE;AAID,qBAAa,WAAW;IAIpB,OAAO,CAAC,GAAG;IAHb,OAAO,CAAC,aAAa,CAAC,CAAgB;gBAG5B,GAAG,EAAE,WAAW,EACxB,QAAQ,CAAC,EAAE,aAAa;IAK1B;;;;;;OAMG;IACI,MAAM,CACX,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC,GACxG,cAAc,CAAC,SAAS,CAAC;CA2I7B"}
|
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
* OpenRouter > Anthropic compat > OpenAI > local (ollama/lm-studio)
|
|
6
6
|
*
|
|
7
7
|
* Model rotation: resolveModelChain() returns up to 5 configs — the AgentRunner
|
|
8
|
-
* walks the chain on 429 (rate limit) or 5xx errors,
|
|
8
|
+
* walks the chain on 429 (rate limit) or 5xx errors, with exponential backoff
|
|
9
|
+
* (up to 2 retries per model) before falling through.
|
|
10
|
+
*
|
|
11
|
+
* When a ModelRegistry is available, chains are dynamically built from the
|
|
12
|
+
* tiered pool, with per-model performance tracking and cost estimation.
|
|
9
13
|
*
|
|
10
14
|
* All outbound, all local — no inbound ports, no server.
|
|
11
15
|
*/
|
|
@@ -13,6 +17,9 @@
|
|
|
13
17
|
/**
|
|
14
18
|
* Build the ordered model fallback chain.
|
|
15
19
|
*
|
|
20
|
+
* If a ModelRegistry is provided, builds from the tiered pool dynamically.
|
|
21
|
+
* Falls back to static env-var parsing otherwise.
|
|
22
|
+
*
|
|
16
23
|
* User-configurable pool: JELLY_MODEL_1 … JELLY_MODEL_5
|
|
17
24
|
* If any JELLY_MODEL_N vars are set they take priority; up to 5 are used in
|
|
18
25
|
* order. Unset slots are filled with provider-appropriate defaults.
|
|
@@ -22,7 +29,7 @@
|
|
|
22
29
|
* JELLY_MODEL_2=openai/gpt-4o
|
|
23
30
|
* JELLY_MODEL_3=google/gemini-2.5-pro
|
|
24
31
|
*/
|
|
25
|
-
export function resolveModelChain() {
|
|
32
|
+
export function resolveModelChain(modelReg) {
|
|
26
33
|
const env = process.env;
|
|
27
34
|
const tokens = parseInt(env.MAX_TOKENS ?? "8192");
|
|
28
35
|
const temp = parseFloat(env.TEMPERATURE ?? "0.7");
|
|
@@ -33,6 +40,11 @@ export function resolveModelChain() {
|
|
|
33
40
|
if (m?.trim())
|
|
34
41
|
userModels.push(m.trim());
|
|
35
42
|
}
|
|
43
|
+
// ── Use ModelRegistry dynamic pool if available ──────────────────────────
|
|
44
|
+
if (modelReg) {
|
|
45
|
+
return modelReg.buildModelChain(userModels);
|
|
46
|
+
}
|
|
47
|
+
// ── Static fallback (used when ModelRegistry cannot be initialised) ───────
|
|
36
48
|
// ── OpenRouter — supports all providers via a single key ─────────────────
|
|
37
49
|
if (env.OPENROUTER_API_KEY) {
|
|
38
50
|
const base = "https://openrouter.ai/api/v1";
|
|
@@ -94,24 +106,30 @@ export function resolveModelChain() {
|
|
|
94
106
|
temperature: temp,
|
|
95
107
|
}];
|
|
96
108
|
}
|
|
97
|
-
throw new Error("No API key found. Set OPENROUTER_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY in ~/.
|
|
109
|
+
throw new Error("No API key found. Set OPENROUTER_API_KEY, ANTHROPIC_API_KEY, or OPENAI_API_KEY in ~/.jelly/.env");
|
|
98
110
|
}
|
|
99
111
|
/** Convenience: returns just the primary (first) model config */
|
|
100
|
-
export function resolveModelConfig() {
|
|
101
|
-
return resolveModelChain()[0];
|
|
112
|
+
export function resolveModelConfig(modelReg) {
|
|
113
|
+
return resolveModelChain(modelReg)[0];
|
|
102
114
|
}
|
|
103
115
|
// ── ModelClient ───────────────────────────────────────────────────────────────
|
|
104
116
|
export class ModelClient {
|
|
105
117
|
cfg;
|
|
106
|
-
|
|
118
|
+
modelRegistry;
|
|
119
|
+
constructor(cfg, modelReg) {
|
|
107
120
|
this.cfg = cfg;
|
|
121
|
+
this.modelRegistry = modelReg;
|
|
108
122
|
}
|
|
109
123
|
/**
|
|
110
124
|
* Stream a chat completion. Yields ChatChunk objects.
|
|
111
|
-
*
|
|
125
|
+
* Retries up to 2 times on 429 / 5xx with exponential backoff (1s, 2s).
|
|
126
|
+
* On persistent HTTP error the generator yields a single { type: "error", status, error }
|
|
112
127
|
* chunk and returns — the caller (AgentRunner) decides whether to rotate.
|
|
128
|
+
* Also reports success/failure to the ModelRegistry for tiering and cooldown.
|
|
113
129
|
*/
|
|
114
130
|
async *stream(messages, tools) {
|
|
131
|
+
const t0 = Date.now();
|
|
132
|
+
let hadError = false;
|
|
115
133
|
const headers = {
|
|
116
134
|
"Content-Type": "application/json",
|
|
117
135
|
"Authorization": `Bearer ${this.cfg.apiKey}`,
|
|
@@ -132,23 +150,48 @@ export class ModelClient {
|
|
|
132
150
|
body.tools = tools;
|
|
133
151
|
body.tool_choice = "auto";
|
|
134
152
|
}
|
|
153
|
+
const MAX_RETRIES = 2;
|
|
154
|
+
const RETRY_STATUSES = new Set([429, 500, 502, 503, 504]);
|
|
135
155
|
let res;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
156
|
+
let lastError = "";
|
|
157
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
158
|
+
try {
|
|
159
|
+
res = await fetch(`${this.cfg.baseUrl}/chat/completions`, {
|
|
160
|
+
method: "POST",
|
|
161
|
+
headers,
|
|
162
|
+
body: JSON.stringify(body),
|
|
163
|
+
signal: AbortSignal.timeout(120_000),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
hadError = true;
|
|
168
|
+
lastError = `Network error: ${e.message}`;
|
|
169
|
+
if (attempt < MAX_RETRIES) {
|
|
170
|
+
await new Promise(r => setTimeout(r, 1000 * (attempt + 1)));
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
this.modelRegistry?.recordFailure(this.cfg.model);
|
|
174
|
+
yield { type: "error", error: lastError, status: 0 };
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (!res.ok && RETRY_STATUSES.has(res.status) && attempt < MAX_RETRIES) {
|
|
178
|
+
hadError = true;
|
|
179
|
+
lastError = await res.text().catch(() => res.statusText);
|
|
180
|
+
await new Promise(r => setTimeout(r, 1000 * (attempt + 1)));
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (!res.ok) {
|
|
184
|
+
hadError = true;
|
|
185
|
+
const err = await res.text().catch(() => res.statusText);
|
|
186
|
+
// 404 → model removed, mark permanently deprecated
|
|
187
|
+
if (res.status === 404)
|
|
188
|
+
this.modelRegistry?.markDeprecated(this.cfg.model);
|
|
189
|
+
else
|
|
190
|
+
this.modelRegistry?.recordFailure(this.cfg.model);
|
|
191
|
+
yield { type: "error", error: `Model API ${res.status}: ${err}`, status: res.status };
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
break; // success — got an ok response
|
|
152
195
|
}
|
|
153
196
|
// Accumulate tool calls across chunks (they arrive fragmented)
|
|
154
197
|
const toolCallMap = new Map();
|
|
@@ -219,6 +262,9 @@ export class ModelClient {
|
|
|
219
262
|
yield { type: "tool_call", tool_calls };
|
|
220
263
|
}
|
|
221
264
|
yield { type: "done", finish_reason: "end" };
|
|
265
|
+
// Report success to model registry
|
|
266
|
+
if (!hadError)
|
|
267
|
+
this.modelRegistry?.recordSuccess(this.cfg.model, Date.now() - t0);
|
|
222
268
|
}
|
|
223
269
|
}
|
|
224
270
|
//# sourceMappingURL=ModelClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelClient.js","sourceRoot":"","sources":["../../src/runner/ModelClient.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ModelClient.js","sourceRoot":"","sources":["../../src/runner/ModelClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* Sub-task execution is sequential inside each worker slot to avoid hammering
|
|
9
9
|
* the provider; concurrency is capped at Math.min(maxAgents, os.cpus().length).
|
|
10
10
|
*/
|
|
11
|
+
import type { ModelRegistry } from "../models/ModelRegistry.js";
|
|
11
12
|
export interface SwarmConfig {
|
|
12
13
|
/** Maximum parallel workers (hard cap: 5). Default: min(cpuCount, 3). */
|
|
13
14
|
maxAgents?: number;
|
|
@@ -19,6 +20,7 @@ export interface SubTaskResult {
|
|
|
19
20
|
result: string;
|
|
20
21
|
model: string;
|
|
21
22
|
ms: number;
|
|
23
|
+
error?: string;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
26
|
* Returns a score 0–100 reflecting prompt complexity.
|
|
@@ -33,7 +35,8 @@ export declare function decompose(prompt: string, maxTasks: number): string[];
|
|
|
33
35
|
export declare class SwarmRouter {
|
|
34
36
|
private maxAgents;
|
|
35
37
|
private complexityThreshold;
|
|
36
|
-
|
|
38
|
+
private modelRegistry?;
|
|
39
|
+
constructor(cfg?: SwarmConfig, modelReg?: ModelRegistry);
|
|
37
40
|
/** True when the prompt is complex enough to warrant swarm execution. */
|
|
38
41
|
shouldSwarm(prompt: string): boolean;
|
|
39
42
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SwarmRouter.d.ts","sourceRoot":"","sources":["../../src/runner/SwarmRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"SwarmRouter.d.ts","sourceRoot":"","sources":["../../src/runner/SwarmRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAI,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAG,MAAM,CAAC;IACf,EAAE,EAAM,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AASD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAetD;AAID;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBpE;AAyCD,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,aAAa,CAAC,CAAqB;gBAE/B,GAAG,GAAE,WAAgB,EAAE,QAAQ,CAAC,EAAE,aAAa;IAO3D,yEAAyE;IACzE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIpC;;;;;;;;;;;;;OAaG;IACG,GAAG,CACP,MAAM,EAAQ,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAI,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,GAC/D,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,aAAa,EAAE,CAAA;KAAE,CAAC;CAuD/D"}
|
|
@@ -55,10 +55,12 @@ export function decompose(prompt, maxTasks) {
|
|
|
55
55
|
return [prompt];
|
|
56
56
|
}
|
|
57
57
|
// ── Reviewer synthesis ───────────────────────────────────────────────────────
|
|
58
|
-
async function reviewerSynthesize(originalPrompt,
|
|
59
|
-
const chain = resolveModelChain();
|
|
58
|
+
async function reviewerSynthesize(originalPrompt, allResults, systemPrompt, modelReg) {
|
|
59
|
+
const chain = resolveModelChain(modelReg);
|
|
60
60
|
const cfg = chain[0];
|
|
61
|
-
const client = new ModelClient(cfg);
|
|
61
|
+
const client = new ModelClient(cfg, modelReg);
|
|
62
|
+
// Filter out sub-tasks that errored — don't feed garbage into the reviewer
|
|
63
|
+
const results = allResults.filter(r => !r.error);
|
|
62
64
|
const context = results
|
|
63
65
|
.map((r, i) => `### Sub-task ${i + 1}: ${r.task}\n${r.result}`)
|
|
64
66
|
.join("\n\n");
|
|
@@ -82,10 +84,12 @@ async function reviewerSynthesize(originalPrompt, results, systemPrompt) {
|
|
|
82
84
|
export class SwarmRouter {
|
|
83
85
|
maxAgents;
|
|
84
86
|
complexityThreshold;
|
|
85
|
-
|
|
87
|
+
modelRegistry;
|
|
88
|
+
constructor(cfg = {}, modelReg) {
|
|
86
89
|
const cpus = os.cpus().length;
|
|
87
90
|
this.maxAgents = Math.min(cfg.maxAgents ?? Math.min(cpus, 3), 5);
|
|
88
91
|
this.complexityThreshold = cfg.complexityThreshold ?? 40;
|
|
92
|
+
this.modelRegistry = modelReg;
|
|
89
93
|
}
|
|
90
94
|
/** True when the prompt is complex enough to warrant swarm execution. */
|
|
91
95
|
shouldSwarm(prompt) {
|
|
@@ -118,22 +122,26 @@ export class SwarmRouter {
|
|
|
118
122
|
let modelIdx = 1; // reserve chain[0] for reviewer
|
|
119
123
|
const runOne = async (task, mIdx, remaining) => {
|
|
120
124
|
const cfg = chain[mIdx % chain.length] ?? chain[0];
|
|
121
|
-
const client = new ModelClient(cfg);
|
|
125
|
+
const client = new ModelClient(cfg, this.modelRegistry);
|
|
122
126
|
const msgs = [
|
|
123
127
|
{ role: "system", content: systemPrompt },
|
|
124
128
|
{ role: "user", content: task },
|
|
125
129
|
];
|
|
126
130
|
const t0 = Date.now();
|
|
127
131
|
let out = "";
|
|
132
|
+
let error;
|
|
128
133
|
for await (const chunk of client.stream(msgs, [])) {
|
|
129
134
|
if (chunk.type === "delta" && chunk.text)
|
|
130
135
|
out += chunk.text;
|
|
136
|
+
if (chunk.type === "error")
|
|
137
|
+
error = chunk.error ?? "Sub-task model error";
|
|
131
138
|
}
|
|
132
139
|
const r = {
|
|
133
140
|
task,
|
|
134
|
-
result: out || "(no output)",
|
|
141
|
+
result: out || (error ? `(error: ${error})` : "(no output)"),
|
|
135
142
|
model: cfg.model,
|
|
136
143
|
ms: Date.now() - t0,
|
|
144
|
+
error,
|
|
137
145
|
};
|
|
138
146
|
subResults.push(r);
|
|
139
147
|
onProgress(r, remaining);
|
|
@@ -146,7 +154,7 @@ export class SwarmRouter {
|
|
|
146
154
|
return runOne(task, modelIdx++, remaining);
|
|
147
155
|
}));
|
|
148
156
|
}
|
|
149
|
-
const synthesis = await reviewerSynthesize(prompt, subResults, systemPrompt);
|
|
157
|
+
const synthesis = await reviewerSynthesize(prompt, subResults, systemPrompt, this.modelRegistry);
|
|
150
158
|
return { synthesis, subResults };
|
|
151
159
|
}
|
|
152
160
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SwarmRouter.js","sourceRoot":"","sources":["../../src/runner/SwarmRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAgB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"SwarmRouter.js","sourceRoot":"","sources":["../../src/runner/SwarmRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SessionManager — manages conversation history, compaction, and persistence.
|
|
3
3
|
*
|
|
4
|
-
* History is kept in memory. If it exceeds
|
|
5
|
-
*
|
|
4
|
+
* History is kept in memory. If it exceeds MAX_HISTORY_CHARS worth of rough char count,
|
|
5
|
+
* older messages are dropped, keeping only the most recent N turns.
|
|
6
6
|
*/
|
|
7
7
|
import type { Message } from "../runner/ModelClient.js";
|
|
8
8
|
export declare class SessionManager {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SessionManager — manages conversation history, compaction, and persistence.
|
|
3
3
|
*
|
|
4
|
-
* History is kept in memory. If it exceeds
|
|
5
|
-
*
|
|
4
|
+
* History is kept in memory. If it exceeds MAX_HISTORY_CHARS worth of rough char count,
|
|
5
|
+
* older messages are dropped, keeping only the most recent N turns.
|
|
6
6
|
*/
|
|
7
7
|
const MAX_HISTORY_CHARS = 80_000; // ~20k tokens rough estimate
|
|
8
8
|
const KEEP_RECENT = 20; // always keep last N messages after compaction
|
|
@@ -43,7 +43,7 @@ export class SessionManager {
|
|
|
43
43
|
const totalChars = this.history.reduce((n, m) => n + (typeof m.content === "string" ? m.content.length : 0), 0);
|
|
44
44
|
if (totalChars <= MAX_HISTORY_CHARS)
|
|
45
45
|
return;
|
|
46
|
-
//
|
|
46
|
+
// Drop oldest messages; keep only the most recent KEEP_RECENT
|
|
47
47
|
this.history = this.history.slice(-KEEP_RECENT);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,iBAAiB,GAAG,MAAM,CAAC,CAAG,6BAA6B;AACjE,MAAM,WAAW,GAAS,EAAE,CAAC,CAAQ,+CAA+C;AAEpF,MAAM,OAAO,cAAc;IACjB,OAAO,GAAc,EAAE,CAAC;IACxB,YAAY,GAAS,EAAE,CAAC;IAEhC,eAAe,CAAC,MAAc;QAC5B,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;IAC7B,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,GAAY;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,WAAW,CAAC,IAAe;QACzB,KAAK,MAAM,CAAC,IAAI,IAAI;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,4EAA4E;IAC5E,WAAW;QACT,MAAM,GAAG,GAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;QAC5E,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,mCAAmC;IACnC,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;IAEO,kBAAkB;QACxB,OAAO,IAAI,CAAC,YAAY,IAAI,uCAAuC,CAAC;IACtE,CAAC;IAEO,YAAY;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EACpE,CAAC,CACF,CAAC;QACF,IAAI,UAAU,IAAI,iBAAiB;YAAE,OAAO;QAE5C,
|
|
1
|
+
{"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../src/session/SessionManager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,iBAAiB,GAAG,MAAM,CAAC,CAAG,6BAA6B;AACjE,MAAM,WAAW,GAAS,EAAE,CAAC,CAAQ,+CAA+C;AAEpF,MAAM,OAAO,cAAc;IACjB,OAAO,GAAc,EAAE,CAAC;IACxB,YAAY,GAAS,EAAE,CAAC;IAEhC,eAAe,CAAC,MAAc;QAC5B,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;IAC7B,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,GAAY;QACrB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,WAAW,CAAC,IAAe;QACzB,KAAK,MAAM,CAAC,IAAI,IAAI;YAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED,4EAA4E;IAC5E,WAAW;QACT,MAAM,GAAG,GAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;QAC5E,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,mCAAmC;IACnC,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;IAEO,kBAAkB;QACxB,OAAO,IAAI,CAAC,YAAY,IAAI,uCAAuC,CAAC;IACtE,CAAC;IAEO,YAAY;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CACpC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EACpE,CAAC,CACF,CAAC;QACF,IAAI,UAAU,IAAI,iBAAiB;YAAE,OAAO;QAE5C,8DAA8D;QAC9D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;CACF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NewsSentiment — fetches RSS feeds, runs headline sentiment scoring
|
|
3
|
+
* with a cheap model, and surfaces trending narratives.
|
|
4
|
+
*/
|
|
5
|
+
import { type Static } from "@sinclair/typebox";
|
|
6
|
+
export interface NewsItem {
|
|
7
|
+
title: string;
|
|
8
|
+
source: string;
|
|
9
|
+
url: string;
|
|
10
|
+
published: number;
|
|
11
|
+
sentiment?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface SentimentReport {
|
|
14
|
+
items: NewsItem[];
|
|
15
|
+
avgSentiment: number;
|
|
16
|
+
positive: number;
|
|
17
|
+
negative: number;
|
|
18
|
+
neutral: number;
|
|
19
|
+
updatedAt: number;
|
|
20
|
+
topKeywords: string[];
|
|
21
|
+
}
|
|
22
|
+
export declare function scoreSentiment(text: string): number;
|
|
23
|
+
export declare class NewsFeed {
|
|
24
|
+
private lastReport;
|
|
25
|
+
private pollInterval;
|
|
26
|
+
private timer?;
|
|
27
|
+
constructor(pollIntervalMs?: number);
|
|
28
|
+
start(): void;
|
|
29
|
+
stop(): void;
|
|
30
|
+
fetch(): Promise<void>;
|
|
31
|
+
getLatest(): SentimentReport | null;
|
|
32
|
+
summary(): string;
|
|
33
|
+
/** Compact sentiment badge for status bar. */
|
|
34
|
+
statusBadge(): string;
|
|
35
|
+
}
|
|
36
|
+
export declare const newsFeed: NewsFeed;
|
|
37
|
+
export declare const getNewsParams: import("@sinclair/typebox").TObject<{
|
|
38
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
39
|
+
}>;
|
|
40
|
+
export declare function getNewsTool(_id: string, params: Static<typeof getNewsParams>): Promise<{
|
|
41
|
+
content: {
|
|
42
|
+
type: "text";
|
|
43
|
+
text: string;
|
|
44
|
+
}[];
|
|
45
|
+
details: {
|
|
46
|
+
avgSentiment?: undefined;
|
|
47
|
+
positive?: undefined;
|
|
48
|
+
negative?: undefined;
|
|
49
|
+
neutral?: undefined;
|
|
50
|
+
articleCount?: undefined;
|
|
51
|
+
topKeywords?: undefined;
|
|
52
|
+
};
|
|
53
|
+
} | {
|
|
54
|
+
content: {
|
|
55
|
+
type: "text";
|
|
56
|
+
text: string;
|
|
57
|
+
}[];
|
|
58
|
+
details: {
|
|
59
|
+
avgSentiment: number;
|
|
60
|
+
positive: number;
|
|
61
|
+
negative: number;
|
|
62
|
+
neutral: number;
|
|
63
|
+
articleCount: number;
|
|
64
|
+
topKeywords: string[];
|
|
65
|
+
};
|
|
66
|
+
}>;
|
|
67
|
+
//# sourceMappingURL=NewsSentiment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NewsSentiment.d.ts","sourceRoot":"","sources":["../../src/tools/NewsSentiment.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAItD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAM,MAAM,CAAC;IAClB,MAAM,EAAK,MAAM,CAAC;IAClB,GAAG,EAAQ,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAO,QAAQ,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAI,MAAM,CAAC;IACnB,QAAQ,EAAI,MAAM,CAAC;IACnB,OAAO,EAAK,MAAM,CAAC;IACnB,SAAS,EAAG,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AA0BD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAanD;AA8DD,qBAAa,QAAQ;IACnB,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAC,CAAiC;gBAEnC,cAAc,SAAU;IAIpC,KAAK,IAAI,IAAI;IAKb,IAAI,IAAI,IAAI;IAIN,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B5B,SAAS,IAAI,eAAe,GAAG,IAAI;IAInC,OAAO,IAAI,MAAM;IAkBjB,8CAA8C;IAC9C,WAAW,IAAI,MAAM;CAMtB;AAID,eAAO,MAAM,QAAQ,UAAiB,CAAC;AAIvC,eAAO,MAAM,aAAa;;EAExB,CAAC;AAEH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BlF"}
|