@jellyos/agent 0.1.3 → 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.
Files changed (59) hide show
  1. package/README.md +9 -9
  2. package/dist/api/Registry.js +3 -1
  3. package/dist/api/Registry.js.map +1 -1
  4. package/dist/cli.js +10 -1
  5. package/dist/cli.js.map +1 -1
  6. package/dist/index.d.ts +10 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +7 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/models/CostTracker.d.ts +66 -0
  11. package/dist/models/CostTracker.d.ts.map +1 -0
  12. package/dist/models/CostTracker.js +148 -0
  13. package/dist/models/CostTracker.js.map +1 -0
  14. package/dist/models/ModelRegistry.d.ts +146 -0
  15. package/dist/models/ModelRegistry.d.ts.map +1 -0
  16. package/dist/models/ModelRegistry.js +400 -0
  17. package/dist/models/ModelRegistry.js.map +1 -0
  18. package/dist/models/index.d.ts +5 -0
  19. package/dist/models/index.d.ts.map +1 -0
  20. package/dist/models/index.js +3 -0
  21. package/dist/models/index.js.map +1 -0
  22. package/dist/runner/AgentRunner.d.ts +5 -1
  23. package/dist/runner/AgentRunner.d.ts.map +1 -1
  24. package/dist/runner/AgentRunner.js +18 -8
  25. package/dist/runner/AgentRunner.js.map +1 -1
  26. package/dist/runner/ModelClient.d.ts +16 -5
  27. package/dist/runner/ModelClient.d.ts.map +1 -1
  28. package/dist/runner/ModelClient.js +69 -23
  29. package/dist/runner/ModelClient.js.map +1 -1
  30. package/dist/runner/SwarmRouter.d.ts +4 -1
  31. package/dist/runner/SwarmRouter.d.ts.map +1 -1
  32. package/dist/runner/SwarmRouter.js +15 -7
  33. package/dist/runner/SwarmRouter.js.map +1 -1
  34. package/dist/session/SessionManager.d.ts +2 -2
  35. package/dist/session/SessionManager.js +3 -3
  36. package/dist/session/SessionManager.js.map +1 -1
  37. package/dist/tools/NewsSentiment.d.ts +67 -0
  38. package/dist/tools/NewsSentiment.d.ts.map +1 -0
  39. package/dist/tools/NewsSentiment.js +199 -0
  40. package/dist/tools/NewsSentiment.js.map +1 -0
  41. package/dist/tools/PriceFeed.d.ts +103 -0
  42. package/dist/tools/PriceFeed.d.ts.map +1 -0
  43. package/dist/tools/PriceFeed.js +230 -0
  44. package/dist/tools/PriceFeed.js.map +1 -0
  45. package/dist/tools/TechnicalAnalysis.d.ts +73 -0
  46. package/dist/tools/TechnicalAnalysis.d.ts.map +1 -0
  47. package/dist/tools/TechnicalAnalysis.js +272 -0
  48. package/dist/tools/TechnicalAnalysis.js.map +1 -0
  49. package/dist/tools/index.d.ts +7 -0
  50. package/dist/tools/index.d.ts.map +1 -0
  51. package/dist/tools/index.js +4 -0
  52. package/dist/tools/index.js.map +1 -0
  53. package/dist/tui/App.d.ts +7 -5
  54. package/dist/tui/App.d.ts.map +1 -1
  55. package/dist/tui/App.js +178 -56
  56. package/dist/tui/App.js.map +1 -1
  57. package/dist/tui/StatusBar.js +1 -1
  58. package/dist/tui/StatusBar.js.map +1 -1
  59. package/package.json +2 -2
@@ -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, providing seamless fallback.
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 ~/.jellyos/.env");
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
- constructor(cfg) {
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
- * On HTTP error the generator yields a single { type: "error", status, error }
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
- try {
137
- res = await fetch(`${this.cfg.baseUrl}/chat/completions`, {
138
- method: "POST",
139
- headers,
140
- body: JSON.stringify(body),
141
- signal: AbortSignal.timeout(120_000),
142
- });
143
- }
144
- catch (e) {
145
- yield { type: "error", error: `Network error: ${e.message}`, status: 0 };
146
- return;
147
- }
148
- if (!res.ok) {
149
- const err = await res.text().catch(() => res.statusText);
150
- yield { type: "error", error: `Model API ${res.status}: ${err}`, status: res.status };
151
- return;
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;;;;;;;;;;GAUG;AAoCH,iFAAiF;AAEjF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,GAAO,OAAO,CAAC,GAAG,CAAC;IAC5B,MAAM,MAAM,GAAI,QAAQ,CAAC,GAAG,CAAC,UAAU,IAAM,MAAM,CAAC,CAAC;IACrD,MAAM,IAAI,GAAM,UAAU,CAAC,GAAG,CAAC,WAAW,IAAI,KAAK,CAAC,CAAC;IAErD,2EAA2E;IAC3E,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,IAAI,EAAE;YAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,4EAA4E;IAC5E,IAAI,GAAG,CAAC,kBAAkB,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAO,8BAA8B,CAAC;QAChD,MAAM,GAAG,GAAQ,GAAG,CAAC,kBAAkB,CAAC;QACxC,MAAM,OAAO,GAAI,GAAG,CAAC,mBAAmB,IAAK,wBAAwB,CAAC;QACtE,MAAM,QAAQ,GAAG,GAAG,CAAC,oBAAoB,IAAI,SAAS,CAAC;QACvD,MAAM,EAAE,GAAG,CAAC,KAAa,EAAe,EAAE,CAAC,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI;YACvE,OAAO,EAAE,QAAQ;SAClB,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG;YACf,GAAG,CAAC,aAAa,IAAI,6BAA6B;YAClD,0BAA0B;YAC1B,oBAAoB;YACpB,yBAAyB;YACzB,qCAAqC;SACtC,CAAC;QACF,+EAA+E;QAC/E,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7F,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,4EAA4E;IAC5E,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,8BAA8B,CAAC;QAC5C,MAAM,GAAG,GAAI,GAAG,CAAC,iBAAiB,CAAC;QACnC,MAAM,EAAE,GAAG,CAAC,KAAa,EAAe,EAAE,CAAC,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI;SACxE,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG;YACf,GAAG,CAAC,aAAa,IAAI,4BAA4B;YACjD,yBAAyB;YACzB,2BAA2B;SAC5B,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7F,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,4EAA4E;IAC5E,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,IAAI,2BAA2B,CAAC;QAChE,MAAM,GAAG,GAAI,GAAG,CAAC,cAAc,CAAC;QAChC,MAAM,EAAE,GAAG,CAAC,KAAa,EAAe,EAAE,CAAC,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI;SACxE,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG;YACf,GAAG,CAAC,aAAa,IAAI,QAAQ;YAC7B,aAAa;YACb,eAAe;SAChB,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7F,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED,2EAA2E;IAC3E,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;QACxB,OAAO,CAAC;gBACN,OAAO,EAAM,GAAG,CAAC,eAAe;gBAChC,MAAM,EAAO,GAAG,CAAC,cAAc,IAAI,OAAO;gBAC1C,KAAK,EAAQ,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,aAAa,IAAI,QAAQ;gBAC3D,SAAS,EAAI,MAAM;gBACnB,WAAW,EAAE,IAAI;aAClB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,KAAK,CACb,mGAAmG,CACpG,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,kBAAkB;IAChC,OAAO,iBAAiB,EAAE,CAAC,CAAC,CAAE,CAAC;AACjC,CAAC;AAED,iFAAiF;AAEjF,MAAM,OAAO,WAAW;IACF;IAApB,YAAoB,GAAgB;QAAhB,QAAG,GAAH,GAAG,CAAa;IAAG,CAAC;IAExC;;;;OAIG;IACH,KAAK,CAAC,CAAC,MAAM,CACX,QAAmB,EACnB,KAAyG;QAEzG,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAG,kBAAkB;YACnC,eAAe,EAAE,UAAU,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;YAC5C,YAAY,EAAK,aAAa;SAC/B,CAAC;QACF,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO;YAAG,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;QAClE,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ;YAAE,OAAO,CAAC,SAAS,CAAC,GAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;QAEnE,MAAM,IAAI,GAA4B;YACpC,KAAK,EAAQ,IAAI,CAAC,GAAG,CAAC,KAAK;YAC3B,QAAQ;YACR,UAAU,EAAG,IAAI,CAAC,GAAG,CAAC,SAAS;YAC/B,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW;YACjC,MAAM,EAAO,IAAI;SAClB,CAAC;QACF,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,GAAS,KAAK,CAAC;YACzB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;QAC5B,CAAC;QAED,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,mBAAmB,EAAE;gBACxD,MAAM,EAAG,MAAM;gBACf,OAAO;gBACP,IAAI,EAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC7B,MAAM,EAAG,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;aACtC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;YACzE,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACzD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;YACtF,OAAO;QACT,CAAC;QAED,+DAA+D;QAC/D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAsD,CAAC;QAClF,MAAM,MAAM,GAAI,GAAG,CAAC,IAAK,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,IAAM,GAAG,GAAO,EAAE,CAAC;QAEnB,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAChB,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAE/C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9B,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;YAExB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,cAAc;oBAAE,SAAS;gBACrD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBAE5C,IAAI,KAAU,CAAC;gBACf,IAAI,CAAC;oBAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC;oBAAC,SAAS;gBAAC,CAAC;gBAEjE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;gBACxC,IAAI,CAAC,KAAK;oBAAE,SAAS;gBAErB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC/C,CAAC;gBAED,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBACrB,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;wBAClC,MAAM,GAAG,GAAQ,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC;wBAC/B,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;wBACxE,IAAI,EAAE,CAAC,EAAE;4BAAmB,QAAQ,CAAC,EAAE,IAAM,EAAE,CAAC,EAAE,CAAC;wBACnD,IAAI,EAAE,CAAC,QAAQ,EAAE,IAAI;4BAAO,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;wBAC9D,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS;4BAAE,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;wBACnE,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;oBACjC,CAAC;gBACH,CAAC;gBAED,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC;gBACjD,IAAI,MAAM,KAAK,YAAY,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;oBACjD,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;wBACzB,MAAM,UAAU,GAAe,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;4BAClE,EAAE,EAAQ,EAAE,CAAC,EAAE,IAAM,QAAQ,IAAI,CAAC,GAAG,EAAE,EAAE;4BACzC,IAAI,EAAM,UAAmB;4BAC7B,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE;yBAChD,CAAC,CAAC,CAAC;wBACJ,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;wBACxC,WAAW,CAAC,KAAK,EAAE,CAAC;oBACtB,CAAC;oBACD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;gBAChD,CAAC;YACH,CAAC;QACH,CAAC;QAED,uEAAuE;QACvE,IAAI,WAAW,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,UAAU,GAAe,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBAClE,EAAE,EAAQ,EAAE,CAAC,EAAE,IAAM,QAAQ,IAAI,CAAC,GAAG,EAAE,EAAE;gBACzC,IAAI,EAAM,UAAmB;gBAC7B,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE;aAChD,CAAC,CAAC,CAAC;YACJ,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;QAC1C,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC;IAC/C,CAAC;CACF"}
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
- constructor(cfg?: SwarmConfig);
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;AAKH,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;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;AAqCD,qBAAa,WAAW;IACtB,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,mBAAmB,CAAS;gBAExB,GAAG,GAAE,WAAgB;IAMjC,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;CAoD/D"}
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, results, systemPrompt) {
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
- constructor(cfg = {}) {
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":"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"}
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 MAX_TOKENS worth of rough char count,
5
- * it compacts by summarizing the oldest messages (keeps system + last N turns).
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 MAX_TOKENS worth of rough char count,
5
- * it compacts by summarizing the oldest messages (keeps system + last N turns).
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
- // Keep the last KEEP_RECENT messages, drop the rest
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,oDAAoD;QACpD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;CACF"}
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"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * NewsSentiment — fetches RSS feeds, runs headline sentiment scoring
3
+ * with a cheap model, and surfaces trending narratives.
4
+ */
5
+ import { Type } from "@sinclair/typebox";
6
+ // ── RSS sources ───────────────────────────────────────────────────────────────
7
+ const FEEDS = [
8
+ { name: "CoinDesk", url: "https://www.coindesk.com/arc/outboundfeeds/rss/" },
9
+ { name: "CoinTelegraph", url: "https://cointelegraph.com/rss" },
10
+ { name: "The Block", url: "https://www.theblock.co/rss" },
11
+ ];
12
+ // ── Simple keyword-based sentiment (no model required) ────────────────────────
13
+ const BULLISH_WORDS = [
14
+ "surge", "soar", "rally", "bull", "breakout", "moon", "pump", "record high",
15
+ "all-time high", "ath", "accumulate", "institutional", "adoption", "approval",
16
+ "etf approved", "launch", "partnership", "upgrade", "mainnet", "listing",
17
+ "airdrop", "halving", "buyback", "burn", "yield", "staking",
18
+ ];
19
+ const BEARISH_WORDS = [
20
+ "crash", "plunge", "dump", "bear", "downturn", "correction", "liquidate",
21
+ "hack", "exploit", "rug", "scam", "sec", "lawsuit", "regulation", "ban",
22
+ "crackdown", "fine", "penalty", "delist", "suspend", "halt", "freeze",
23
+ "insolvent", "bankrupt", "depeg", "exploit",
24
+ ];
25
+ export function scoreSentiment(text) {
26
+ const lower = text.toLowerCase();
27
+ let score = 0;
28
+ let hits = 0;
29
+ for (const w of BULLISH_WORDS) {
30
+ if (lower.includes(w)) {
31
+ score++;
32
+ hits++;
33
+ }
34
+ }
35
+ for (const w of BEARISH_WORDS) {
36
+ if (lower.includes(w)) {
37
+ score--;
38
+ hits++;
39
+ }
40
+ }
41
+ return hits === 0 ? 0 : Math.max(-1, Math.min(1, score / hits));
42
+ }
43
+ // ── Fetch & parse ────────────────────────────────────────────────────────────
44
+ async function fetchRSS(url, source) {
45
+ try {
46
+ const res = await fetch(url, {
47
+ signal: AbortSignal.timeout(10_000),
48
+ headers: { "User-Agent": "JellyOS/1.0", "Accept": "application/rss+xml, application/xml, text/xml" },
49
+ });
50
+ if (!res.ok)
51
+ return [];
52
+ const text = await res.text();
53
+ // Parse RSS items with regex (no XML parser dependency)
54
+ const items = [];
55
+ const itemMatches = text.match(/<item[\s\S]*?<\/item>/gi) ?? [];
56
+ for (const item of itemMatches) {
57
+ const titleMatch = item.match(/<title[^>]*><!\[CDATA\[(.*?)\]\]><\/title>|<title[^>]*>(.*?)<\/title>/i);
58
+ const linkMatch = item.match(/<link[^>]*>(.*?)<\/link>/i);
59
+ const dateMatch = item.match(/<pubDate[^>]*>(.*?)<\/pubDate>/i);
60
+ const title = titleMatch?.[1] ?? titleMatch?.[2] ?? "";
61
+ if (!title.trim())
62
+ continue;
63
+ items.push({
64
+ title,
65
+ source,
66
+ url: linkMatch?.[1] ?? "",
67
+ published: dateMatch ? new Date(dateMatch[1]).getTime() : Date.now(),
68
+ sentiment: scoreSentiment(title),
69
+ });
70
+ }
71
+ return items.slice(0, 20);
72
+ }
73
+ catch {
74
+ return [];
75
+ }
76
+ }
77
+ // ── Keyword extraction ────────────────────────────────────────────────────────
78
+ function extractKeywords(items, topN = 10) {
79
+ const wordFreq = new Map();
80
+ const stopWords = new Set(["the", "a", "an", "in", "on", "at", "to", "for", "of", "and", "is", "are", "was", "were", "will", "has", "have", "it", "its", "with", "from", "by", "as", "be", "that", "this", "but", "or", "not", "can", "may"]);
81
+ for (const item of items) {
82
+ const words = item.title.toLowerCase().replace(/[^a-z0-9 ]/g, "").split(/\s+/);
83
+ for (const w of words) {
84
+ if (w.length < 3 || stopWords.has(w))
85
+ continue;
86
+ wordFreq.set(w, (wordFreq.get(w) ?? 0) + 1);
87
+ }
88
+ }
89
+ return [...wordFreq.entries()]
90
+ .sort((a, b) => b[1] - a[1])
91
+ .slice(0, topN)
92
+ .map(([w]) => w);
93
+ }
94
+ // ── NewsFeed class ────────────────────────────────────────────────────────────
95
+ export class NewsFeed {
96
+ lastReport = null;
97
+ pollInterval;
98
+ timer;
99
+ constructor(pollIntervalMs = 600_000) {
100
+ this.pollInterval = pollIntervalMs;
101
+ }
102
+ start() {
103
+ this.fetch();
104
+ this.timer = setInterval(() => this.fetch(), this.pollInterval);
105
+ }
106
+ stop() {
107
+ if (this.timer) {
108
+ clearInterval(this.timer);
109
+ this.timer = undefined;
110
+ }
111
+ }
112
+ async fetch() {
113
+ const allItems = [];
114
+ for (const feed of FEEDS) {
115
+ const items = await fetchRSS(feed.url, feed.name);
116
+ allItems.push(...items);
117
+ }
118
+ allItems.sort((a, b) => b.published - a.published);
119
+ const scored = allItems.filter(i => i.sentiment !== undefined && i.sentiment !== 0);
120
+ const avgSent = scored.length > 0 ? scored.reduce((s, i) => s + (i.sentiment ?? 0), 0) / scored.length : 0;
121
+ const positive = allItems.filter(i => (i.sentiment ?? 0) > 0.1).length;
122
+ const negative = allItems.filter(i => (i.sentiment ?? 0) < -0.1).length;
123
+ const neutral = allItems.length - positive - negative;
124
+ const topKeywords = extractKeywords(allItems);
125
+ this.lastReport = {
126
+ items: allItems,
127
+ avgSentiment: Math.round(avgSent * 1000) / 1000,
128
+ positive,
129
+ negative,
130
+ neutral,
131
+ updatedAt: Date.now(),
132
+ topKeywords,
133
+ };
134
+ }
135
+ getLatest() {
136
+ return this.lastReport;
137
+ }
138
+ summary() {
139
+ if (!this.lastReport)
140
+ return "No news data available.";
141
+ const r = this.lastReport;
142
+ const score = r.avgSentiment;
143
+ const mood = score > 0.2 ? "🟢 Bullish" : score < -0.2 ? "🔴 Bearish" : "🟡 Neutral";
144
+ return [
145
+ `News Sentiment: ${mood} (score: ${score >= 0 ? "+" : ""}${score.toFixed(3)})`,
146
+ ` ${r.positive} positive · ${r.negative} negative · ${r.neutral} neutral (${r.items.length} articles)`,
147
+ ` Trending: ${r.topKeywords.slice(0, 8).join(", ")}`,
148
+ ` Latest:`,
149
+ ...r.items.slice(0, 5).map(i => {
150
+ const s = (i.sentiment ?? 0) >= 0.1 ? "🟢" : (i.sentiment ?? 0) <= -0.1 ? "🔴" : " ";
151
+ return ` ${s} [${i.source}] ${i.title.slice(0, 80)}`;
152
+ }),
153
+ ].join("\n");
154
+ }
155
+ /** Compact sentiment badge for status bar. */
156
+ statusBadge() {
157
+ if (!this.lastReport)
158
+ return "📰 ?";
159
+ const s = this.lastReport.avgSentiment;
160
+ const emoji = s > 0.3 ? "🟢" : s > 0 ? "🟡" : "🔴";
161
+ return `📰 ${emoji} ${(s * 100).toFixed(0)}%`;
162
+ }
163
+ }
164
+ // ── Singleton ─────────────────────────────────────────────────────────────────
165
+ export const newsFeed = new NewsFeed();
166
+ // ── Tool: get_news ────────────────────────────────────────────────────────────
167
+ export const getNewsParams = Type.Object({
168
+ limit: Type.Optional(Type.Number({ default: 10, description: "Number of articles to show" })),
169
+ });
170
+ export async function getNewsTool(_id, params) {
171
+ const report = newsFeed.getLatest();
172
+ if (!report) {
173
+ return {
174
+ content: [{ type: "text", text: "News data not yet available. Please wait for the first fetch." }],
175
+ details: {},
176
+ };
177
+ }
178
+ const items = report.items.slice(0, params.limit ?? 10)
179
+ .map(i => {
180
+ const s = (i.sentiment ?? 0) >= 0.1 ? "+" : (i.sentiment ?? 0) <= -0.1 ? "-" : " ";
181
+ return `${s} [${i.source}] ${i.title}`;
182
+ })
183
+ .join("\n");
184
+ return {
185
+ content: [{
186
+ type: "text",
187
+ text: `News Sentiment: ${report.avgSentiment >= 0 ? "+" : ""}${(report.avgSentiment * 100).toFixed(0)}% sentiment · ${report.positive}p/${report.negative}n/${report.neutral}·\nTrending: ${report.topKeywords.join(", ")}\n\n${items}`,
188
+ }],
189
+ details: {
190
+ avgSentiment: report.avgSentiment,
191
+ positive: report.positive,
192
+ negative: report.negative,
193
+ neutral: report.neutral,
194
+ articleCount: report.items.length,
195
+ topKeywords: report.topKeywords,
196
+ },
197
+ };
198
+ }
199
+ //# sourceMappingURL=NewsSentiment.js.map