@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.
- package/README.md +9 -9
- package/dist/api/Registry.js +3 -1
- package/dist/api/Registry.js.map +1 -1
- package/dist/cli.js +10 -1
- 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/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 -56
- 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/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Your machine
|
|
|
39
39
|
│ ├── VaultManager ← AES-256-GCM encrypted profit vault
|
|
40
40
|
│ └── DashboardServer ← optional local WebSocket dashboard
|
|
41
41
|
│
|
|
42
|
-
├── ~/.
|
|
42
|
+
├── ~/.jelly/
|
|
43
43
|
│ ├── .env ← your API keys
|
|
44
44
|
│ ├── wallets/ ← local keypairs (never synced)
|
|
45
45
|
│ ├── vault/ ← encrypted vault file
|
|
@@ -68,8 +68,8 @@ npm install -g @jellyos/agent
|
|
|
68
68
|
|
|
69
69
|
```bash
|
|
70
70
|
# 1. Create config directory and set your API key
|
|
71
|
-
mkdir -p ~/.
|
|
72
|
-
echo "OPENROUTER_API_KEY=sk-or-..." > ~/.
|
|
71
|
+
mkdir -p ~/.jelly
|
|
72
|
+
echo "OPENROUTER_API_KEY=sk-or-..." > ~/.jelly/.env
|
|
73
73
|
|
|
74
74
|
# 2. Launch
|
|
75
75
|
jellyos
|
|
@@ -91,7 +91,7 @@ cd JellyOS
|
|
|
91
91
|
# Install dependencies
|
|
92
92
|
npm install
|
|
93
93
|
|
|
94
|
-
# Run one-command setup (generates wallets, vault ceremony, writes ~/.
|
|
94
|
+
# Run one-command setup (generates wallets, vault ceremony, writes ~/.jelly/.env)
|
|
95
95
|
bash setup.sh # macOS / Linux
|
|
96
96
|
# or
|
|
97
97
|
powershell -ExecutionPolicy Bypass -File setup.ps1 # Windows
|
|
@@ -104,11 +104,11 @@ jellyos
|
|
|
104
104
|
|
|
105
105
|
## Configuration
|
|
106
106
|
|
|
107
|
-
All config lives in `~/.
|
|
107
|
+
All config lives in `~/.jelly/.env`. The setup wizard creates this for you, or create it manually:
|
|
108
108
|
|
|
109
109
|
```bash
|
|
110
|
-
cp .env.example ~/.
|
|
111
|
-
nano ~/.
|
|
110
|
+
cp .env.example ~/.jelly/.env
|
|
111
|
+
nano ~/.jelly/.env
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
### AI Model Provider (pick one)
|
|
@@ -362,11 +362,11 @@ jellyos setup # run the setup wizard
|
|
|
362
362
|
|
|
363
363
|
## Security
|
|
364
364
|
|
|
365
|
-
- **Keys stay local** — API keys are read from `~/.
|
|
365
|
+
- **Keys stay local** — API keys are read from `~/.jelly/.env` at startup and never logged or transmitted beyond outbound API calls
|
|
366
366
|
- **Private keys never leave the process** — signing happens in memory; only the resulting signature is returned
|
|
367
367
|
- **Vault encryption** — AES-256-GCM with a key derived from your passphrase using scrypt (memory-hard KDF) + random per-vault salt; the key itself is never persisted
|
|
368
368
|
- **Auto-lock** — vault locks automatically on `/panic` and on process exit
|
|
369
|
-
- **Wallet storage** — keypairs are written to `~/.
|
|
369
|
+
- **Wallet storage** — keypairs are written to `~/.jelly/wallets/` which is in `.gitignore` and never included in any sync or backup by the agent
|
|
370
370
|
|
|
371
371
|
---
|
|
372
372
|
|
package/dist/api/Registry.js
CHANGED
|
@@ -83,7 +83,9 @@ export class Registry {
|
|
|
83
83
|
await h(undefined, ctx); // (_event, ctx) => {...} — Pi convention
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
-
catch {
|
|
86
|
+
catch (e) {
|
|
87
|
+
console.error(`[Registry] hook "${event}" threw:`, e);
|
|
88
|
+
}
|
|
87
89
|
}
|
|
88
90
|
}
|
|
89
91
|
// ── OpenAI tool schema ───────────────────────────────────────────────────
|
package/dist/api/Registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Registry.js","sourceRoot":"","sources":["../../src/api/Registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,MAAM,OAAO,QAAQ;IACX,QAAQ,GAAG,IAAI,GAAG,EAAsB,CAAC;IACzC,KAAK,GAAM,IAAI,GAAG,EAA4B,CAAC;IAC/C,MAAM,GAAgB,EAAE,CAAC;IAEzB,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAErC,aAAa,GAAG,EAAE,CAAC;IAE3B,2EAA2E;IAE3E,UAAU,CAAC,IAAY,EAAE,GAAe;QACtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,GAAG,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,CAAoB,GAAe;QACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAAkC,CAAC,CAAC;IAC/D,CAAC;IAED,QAAQ,CAAC,GAAa;QACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,KAAmB,EAAE,OAA0C;QACrE,oDAAoD;QACpD,MAAM,GAAG,GAAG,KAAK,KAAK,kBAAkB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;QACjE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,OAAkB,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,eAAe,CAAC,MAAc;QAC5B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;IAC9B,CAAC;IAED,4EAA4E;IAE5E,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,YAAY;QACV,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACtC,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,QAAQ,CAAC,KAAa,EAAE,GAAmB;QAC/C,MAAM,GAAG,GAAQ,KAAK,KAAK,kBAAkB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;QACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACnB,MAAM,CAAC,EAAE,CAAC,CAAgB,cAAc;gBAC1C,CAAC;qBAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,CAAC,GAAU,CAAC,CAAC,CAAM,iBAAiB;gBAC7C,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAE,0CAA0C;gBACtE,CAAC;YACH,CAAC;YAAC,
|
|
1
|
+
{"version":3,"file":"Registry.js","sourceRoot":"","sources":["../../src/api/Registry.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -12,6 +12,8 @@ import { Registry } from "./api/Registry.js";
|
|
|
12
12
|
import { loadExtension } from "./loader.js";
|
|
13
13
|
import { App } from "./tui/App.js";
|
|
14
14
|
import { T } from "./tui/theme.js";
|
|
15
|
+
import { modelRegistry } from "./models/ModelRegistry.js";
|
|
16
|
+
import { CostTracker } from "./models/CostTracker.js";
|
|
15
17
|
// ── Load env vars from ~/.jelly/.env ─────────────────────────────────────────
|
|
16
18
|
const JELLY_HOME = process.env.JELLYOS_HOME ?? join(homedir(), ".jelly");
|
|
17
19
|
const envPath = join(JELLY_HOME, ".env");
|
|
@@ -33,7 +35,7 @@ if (subcmd === "config") {
|
|
|
33
35
|
const m = line.match(/^([A-Z_]+)=(.*)$/);
|
|
34
36
|
if (!m)
|
|
35
37
|
continue;
|
|
36
|
-
const masked = m[2].length >
|
|
38
|
+
const masked = m[2].length > 12 ? m[2].slice(0, 6) + "********" : "********";
|
|
37
39
|
console.log(` ${m[1].padEnd(28)} ${masked}`);
|
|
38
40
|
}
|
|
39
41
|
}
|
|
@@ -120,6 +122,11 @@ function loadContext() {
|
|
|
120
122
|
if (!process.env.OPENROUTER_API_KEY && !process.env.ANTHROPIC_API_KEY && !process.env.OPENAI_API_KEY) {
|
|
121
123
|
console.log(T.warn(" No API key found. Set OPENROUTER_API_KEY in ~/.jelly/.env\n"));
|
|
122
124
|
}
|
|
125
|
+
// ── Initialise model registry & cost tracker ─────────────────────────────
|
|
126
|
+
const costTracker = new CostTracker(modelRegistry);
|
|
127
|
+
console.log(T.muted(" Discovering available models via OpenRouter…"));
|
|
128
|
+
await modelRegistry.initialise();
|
|
129
|
+
console.log(T.success(` ✓ ${modelRegistry.modelCount} models available \n`));
|
|
123
130
|
await new Promise(r => setTimeout(r, 500));
|
|
124
131
|
console.clear();
|
|
125
132
|
render(React.createElement(App, {
|
|
@@ -127,6 +134,8 @@ function loadContext() {
|
|
|
127
134
|
systemPrompt,
|
|
128
135
|
effectLevel,
|
|
129
136
|
chain,
|
|
137
|
+
modelReg: modelRegistry,
|
|
138
|
+
costTracker,
|
|
130
139
|
onNotifyReady: (fn) => { _notifyFn = fn; },
|
|
131
140
|
onStatusReady: (fn) => { _setStatusFn = fn; },
|
|
132
141
|
}), { exitOnCtrlC: false });
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAiB,WAAW,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAuB,SAAS,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAwB,KAAK,CAAC;AAC/C,OAAO,KAAK,MAA6B,OAAO,CAAC;AACjD,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAU,QAAQ,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAsB,mBAAmB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAiB,aAAa,CAAC;AACvD,OAAO,EAAE,GAAG,EAAE,MAA2B,cAAc,CAAC;AACxD,OAAO,EAAE,CAAC,EAAE,MAA6B,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,4 +15,14 @@ export { ToolDispatcher } from "./runner/ToolDispatcher.js";
|
|
|
15
15
|
export { SessionManager } from "./session/SessionManager.js";
|
|
16
16
|
export { loadExtension } from "./loader.js";
|
|
17
17
|
export { makeTheme, T, JELLY_COLORS } from "./tui/theme.js";
|
|
18
|
+
export { ModelRegistry, modelRegistry, classifyModel } from "./models/ModelRegistry.js";
|
|
19
|
+
export { CostTracker } from "./models/CostTracker.js";
|
|
20
|
+
export type { OpenRouterModel, TieredModel, TieredPool, ModelTier } from "./models/ModelRegistry.js";
|
|
21
|
+
export type { UsageEntry, SessionUsage, LifetimeUsage } from "./models/CostTracker.js";
|
|
22
|
+
export { fullAnalysis, rsi, macd, ema, sma, bollingerBands, atr } from "./tools/TechnicalAnalysis.js";
|
|
23
|
+
export { PriceFeed, priceFeed, getPricesTool, topMoversTool, marketOverviewTool } from "./tools/PriceFeed.js";
|
|
24
|
+
export { NewsFeed, newsFeed, getNewsTool, scoreSentiment } from "./tools/NewsSentiment.js";
|
|
25
|
+
export type { OHLCV, AnalysisResult } from "./tools/TechnicalAnalysis.js";
|
|
26
|
+
export type { PriceTick } from "./tools/PriceFeed.js";
|
|
27
|
+
export type { NewsItem, SentimentReport } from "./tools/NewsSentiment.js";
|
|
18
28
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGtD,YAAY,EACV,YAAY,EACZ,eAAe,EACf,UAAU,EACV,cAAc,EACd,SAAS,EACT,YAAY,EACZ,OAAO,EACP,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,cAAc,GACf,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAG7C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,OAAO,EAAE,WAAW,EAAE,MAAS,yBAAyB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGtD,YAAY,EACV,YAAY,EACZ,eAAe,EACf,UAAU,EACV,cAAc,EACd,SAAS,EACT,YAAY,EACZ,OAAO,EACP,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,cAAc,GACf,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAG7C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,OAAO,EAAE,WAAW,EAAE,MAAS,yBAAyB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACrG,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAGvF,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAC;AACtG,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC9G,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC3F,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC1E,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -21,4 +21,11 @@ export { SessionManager } from "./session/SessionManager.js";
|
|
|
21
21
|
export { loadExtension } from "./loader.js";
|
|
22
22
|
// Theme
|
|
23
23
|
export { makeTheme, T, JELLY_COLORS } from "./tui/theme.js";
|
|
24
|
+
// Model intelligence
|
|
25
|
+
export { ModelRegistry, modelRegistry, classifyModel } from "./models/ModelRegistry.js";
|
|
26
|
+
export { CostTracker } from "./models/CostTracker.js";
|
|
27
|
+
// Tools
|
|
28
|
+
export { fullAnalysis, rsi, macd, ema, sma, bollingerBands, atr } from "./tools/TechnicalAnalysis.js";
|
|
29
|
+
export { PriceFeed, priceFeed, getPricesTool, topMoversTool, marketOverviewTool } from "./tools/PriceFeed.js";
|
|
30
|
+
export { NewsFeed, newsFeed, getNewsTool, scoreSentiment } from "./tools/NewsSentiment.js";
|
|
24
31
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,0EAA0E;AAC1E,OAAO,EAAE,IAAI,EAAe,MAAM,mBAAmB,CAAC;AAiBtD,2CAA2C;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,wCAAwC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,oBAAoB;AACpB,OAAO,EAAE,WAAW,EAAE,MAAS,yBAAyB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,UAAU;AACV,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,kDAAkD;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,0EAA0E;AAC1E,OAAO,EAAE,IAAI,EAAe,MAAM,mBAAmB,CAAC;AAiBtD,2CAA2C;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C,wCAAwC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,oBAAoB;AACpB,OAAO,EAAE,WAAW,EAAE,MAAS,yBAAyB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,UAAU;AACV,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,kDAAkD;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,QAAQ;AACR,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE5D,qBAAqB;AACrB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAItD,QAAQ;AACR,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,8BAA8B,CAAC;AACtG,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC9G,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostTracker — tracks per-session and lifetime token usage and cost.
|
|
3
|
+
*
|
|
4
|
+
* Uses OpenRouter response headers (x-credit-used) when available,
|
|
5
|
+
* otherwise estimates from the model registry's pricing data.
|
|
6
|
+
* Emits budget warnings and provides cost reports via tool/command.
|
|
7
|
+
*/
|
|
8
|
+
import type { ModelRegistry } from "./ModelRegistry.js";
|
|
9
|
+
export interface UsageEntry {
|
|
10
|
+
model: string;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
promptTokens: number;
|
|
13
|
+
completionTokens: number;
|
|
14
|
+
/** Estimated cost in nano-dollars (billionths of a dollar) */
|
|
15
|
+
estimatedCost: number;
|
|
16
|
+
/** Duration in ms */
|
|
17
|
+
duration: number;
|
|
18
|
+
}
|
|
19
|
+
export interface SessionUsage {
|
|
20
|
+
promptTokens: number;
|
|
21
|
+
completionTokens: number;
|
|
22
|
+
estimatedCost: number;
|
|
23
|
+
calls: number;
|
|
24
|
+
errors: number;
|
|
25
|
+
}
|
|
26
|
+
export interface LifetimeUsage {
|
|
27
|
+
promptTokens: number;
|
|
28
|
+
completionTokens: number;
|
|
29
|
+
estimatedCost: number;
|
|
30
|
+
calls: number;
|
|
31
|
+
modelsUsed: Set<string>;
|
|
32
|
+
}
|
|
33
|
+
export declare class CostTracker {
|
|
34
|
+
private modelReg;
|
|
35
|
+
private session;
|
|
36
|
+
private lifetime;
|
|
37
|
+
private budgetSession;
|
|
38
|
+
private budgetLifetime;
|
|
39
|
+
private budgetWarned;
|
|
40
|
+
constructor(modelReg: ModelRegistry);
|
|
41
|
+
record(modelId: string, promptTokens: number, completionTokens: number, duration: number): void;
|
|
42
|
+
recordError(): void;
|
|
43
|
+
private maybeWarnBudget;
|
|
44
|
+
getBudgetStatus(): {
|
|
45
|
+
session: SessionUsage;
|
|
46
|
+
lifetime: LifetimeUsage;
|
|
47
|
+
warnings: string[];
|
|
48
|
+
};
|
|
49
|
+
/** True if the next call would exceed the session budget. */
|
|
50
|
+
wouldExceed(estimatedCallCost: number): boolean;
|
|
51
|
+
private loadLifetime;
|
|
52
|
+
saveLifetime(): void;
|
|
53
|
+
private formatNano;
|
|
54
|
+
statusLine(): string;
|
|
55
|
+
report(): string;
|
|
56
|
+
readonly costReportParams: import("@sinclair/typebox").TObject<{}>;
|
|
57
|
+
costReportTool(): Promise<{
|
|
58
|
+
content: Array<{
|
|
59
|
+
type: "text";
|
|
60
|
+
text: string;
|
|
61
|
+
}>;
|
|
62
|
+
details: Record<string, unknown>;
|
|
63
|
+
}>;
|
|
64
|
+
resetSession(): void;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=CostTracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CostTracker.d.ts","sourceRoot":"","sources":["../../src/models/CostTracker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAQxD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAQ,MAAM,CAAC;IACpB,SAAS,EAAI,MAAM,CAAC;IACpB,YAAY,EAAI,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB;IACrB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAO,MAAM,CAAC;IAC1B,gBAAgB,EAAI,MAAM,CAAC;IAC3B,aAAa,EAAO,MAAM,CAAC;IAC3B,KAAK,EAAe,MAAM,CAAC;IAC3B,MAAM,EAAc,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAO,MAAM,CAAC;IAC1B,gBAAgB,EAAI,MAAM,CAAC;IAC3B,aAAa,EAAO,MAAM,CAAC;IAC3B,KAAK,EAAe,MAAM,CAAC;IAC3B,UAAU,EAAU,GAAG,CAAC,MAAM,CAAC,CAAC;CACjC;AAOD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,OAAO,CAAyG;IACxH,OAAO,CAAC,QAAQ,CAAoH;IACpI,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,YAAY,CAAY;gBAEpB,QAAQ,EAAE,aAAa;IASnC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAuB/F,WAAW,IAAI,IAAI;IAOnB,OAAO,CAAC,eAAe;IAOvB,eAAe,IAAI;QAAE,OAAO,EAAE,YAAY,CAAC;QAAC,QAAQ,EAAE,aAAa,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE;IAazF,6DAA6D;IAC7D,WAAW,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO;IAM/C,OAAO,CAAC,YAAY;IAYpB,YAAY,IAAI,IAAI;IAepB,OAAO,CAAC,UAAU;IAIlB,UAAU,IAAI,MAAM;IAIpB,MAAM,IAAI,MAAM;IAahB,QAAQ,CAAC,gBAAgB,0CAAmB;IAEtC,cAAc,IAAI,OAAO,CAAC;QAC9B,OAAO,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC/C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,CAAC;IAqBF,YAAY,IAAI,IAAI;CAIrB"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostTracker — tracks per-session and lifetime token usage and cost.
|
|
3
|
+
*
|
|
4
|
+
* Uses OpenRouter response headers (x-credit-used) when available,
|
|
5
|
+
* otherwise estimates from the model registry's pricing data.
|
|
6
|
+
* Emits budget warnings and provides cost reports via tool/command.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { Type } from "@sinclair/typebox";
|
|
12
|
+
const JELLY_HOME = process.env.JELLYOS_HOME ?? join(homedir(), ".jelly");
|
|
13
|
+
const COST_FILE = join(JELLY_HOME, "usage.json");
|
|
14
|
+
// ── CostTracker class ─────────────────────────────────────────────────────────
|
|
15
|
+
const DEFAULT_BUDGET_PER_SESSION = 1_000_000_000_000; // $1.00 in nano-dollars
|
|
16
|
+
const DEFAULT_BUDGET_LIFETIME = 25_000_000_000_000; // $25.00
|
|
17
|
+
export class CostTracker {
|
|
18
|
+
modelReg;
|
|
19
|
+
session = { promptTokens: 0, completionTokens: 0, estimatedCost: 0, calls: 0, errors: 0 };
|
|
20
|
+
lifetime = { promptTokens: 0, completionTokens: 0, estimatedCost: 0, calls: 0, modelsUsed: new Set() };
|
|
21
|
+
budgetSession;
|
|
22
|
+
budgetLifetime;
|
|
23
|
+
budgetWarned = false;
|
|
24
|
+
constructor(modelReg) {
|
|
25
|
+
this.modelReg = modelReg;
|
|
26
|
+
this.budgetSession = parseInt(process.env.JELLY_BUDGET_SESSION ?? String(DEFAULT_BUDGET_PER_SESSION));
|
|
27
|
+
this.budgetLifetime = parseInt(process.env.JELLY_BUDGET_LIFETIME ?? String(DEFAULT_BUDGET_LIFETIME));
|
|
28
|
+
this.loadLifetime();
|
|
29
|
+
}
|
|
30
|
+
// ── Recording ─────────────────────────────────────────────────────────────
|
|
31
|
+
record(modelId, promptTokens, completionTokens, duration) {
|
|
32
|
+
const tm = this.modelReg["modelMap"]?.get(modelId);
|
|
33
|
+
const costPer1K = tm?.costPer1K ?? 50_000; // fallback: 50 nano-dollars/1K (=$0.00005/1K)
|
|
34
|
+
const estimatedCost = Math.round(costPer1K * (promptTokens + completionTokens) / 1000);
|
|
35
|
+
const entry = { model: modelId, timestamp: Date.now(), promptTokens, completionTokens, estimatedCost, duration };
|
|
36
|
+
// Session
|
|
37
|
+
this.session.promptTokens += promptTokens;
|
|
38
|
+
this.session.completionTokens += completionTokens;
|
|
39
|
+
this.session.estimatedCost += estimatedCost;
|
|
40
|
+
this.session.calls++;
|
|
41
|
+
// Lifetime
|
|
42
|
+
this.lifetime.promptTokens += promptTokens;
|
|
43
|
+
this.lifetime.completionTokens += completionTokens;
|
|
44
|
+
this.lifetime.estimatedCost += estimatedCost;
|
|
45
|
+
this.lifetime.calls++;
|
|
46
|
+
this.lifetime.modelsUsed.add(modelId);
|
|
47
|
+
this.maybeWarnBudget();
|
|
48
|
+
}
|
|
49
|
+
recordError() {
|
|
50
|
+
this.session.errors++;
|
|
51
|
+
this.lifetime.calls++;
|
|
52
|
+
}
|
|
53
|
+
// ── Budget ────────────────────────────────────────────────────────────────
|
|
54
|
+
maybeWarnBudget() {
|
|
55
|
+
if (this.session.estimatedCost > this.budgetSession * 0.8 && !this.budgetWarned) {
|
|
56
|
+
this.budgetWarned = true;
|
|
57
|
+
// Budget warning is surfaced via getBudgetStatus() — callers can check
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
getBudgetStatus() {
|
|
61
|
+
const warnings = [];
|
|
62
|
+
const pctSession = this.session.estimatedCost / this.budgetSession * 100;
|
|
63
|
+
const pctLifetime = this.lifetime.estimatedCost / this.budgetLifetime * 100;
|
|
64
|
+
if (pctSession >= 90)
|
|
65
|
+
warnings.push(`⚠ Session budget at ${pctSession.toFixed(0)}% — near limit`);
|
|
66
|
+
else if (pctSession >= 75)
|
|
67
|
+
warnings.push(`⚡ Session budget at ${pctSession.toFixed(0)}%`);
|
|
68
|
+
if (pctLifetime >= 90)
|
|
69
|
+
warnings.push(`⚠ Lifetime budget at ${pctLifetime.toFixed(0)}% — near limit`);
|
|
70
|
+
else if (pctLifetime >= 75)
|
|
71
|
+
warnings.push(`⚡ Lifetime budget at ${pctLifetime.toFixed(0)}%`);
|
|
72
|
+
return { session: { ...this.session }, lifetime: { ...this.lifetime, modelsUsed: new Set(this.lifetime.modelsUsed) }, warnings };
|
|
73
|
+
}
|
|
74
|
+
/** True if the next call would exceed the session budget. */
|
|
75
|
+
wouldExceed(estimatedCallCost) {
|
|
76
|
+
return this.session.estimatedCost + estimatedCallCost > this.budgetSession;
|
|
77
|
+
}
|
|
78
|
+
// ── Persistence ────────────────────────────────────────────────────────────
|
|
79
|
+
loadLifetime() {
|
|
80
|
+
try {
|
|
81
|
+
if (!existsSync(COST_FILE))
|
|
82
|
+
return;
|
|
83
|
+
const raw = JSON.parse(readFileSync(COST_FILE, "utf-8"));
|
|
84
|
+
this.lifetime.promptTokens = raw.promptTokens ?? 0;
|
|
85
|
+
this.lifetime.completionTokens = raw.completionTokens ?? 0;
|
|
86
|
+
this.lifetime.estimatedCost = raw.estimatedCost ?? 0;
|
|
87
|
+
this.lifetime.calls = raw.calls ?? 0;
|
|
88
|
+
this.lifetime.modelsUsed = new Set(raw.modelsUsed ?? []);
|
|
89
|
+
}
|
|
90
|
+
catch { /* best effort */ }
|
|
91
|
+
}
|
|
92
|
+
saveLifetime() {
|
|
93
|
+
try {
|
|
94
|
+
mkdirSync(JELLY_HOME, { recursive: true });
|
|
95
|
+
writeFileSync(COST_FILE, JSON.stringify({
|
|
96
|
+
promptTokens: this.lifetime.promptTokens,
|
|
97
|
+
completionTokens: this.lifetime.completionTokens,
|
|
98
|
+
estimatedCost: this.lifetime.estimatedCost,
|
|
99
|
+
calls: this.lifetime.calls,
|
|
100
|
+
modelsUsed: [...this.lifetime.modelsUsed],
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
catch { /* best effort */ }
|
|
104
|
+
}
|
|
105
|
+
// ── Formatting ─────────────────────────────────────────────────────────────
|
|
106
|
+
formatNano(cost) {
|
|
107
|
+
return `$${(cost / 1_000_000_000).toFixed(4)}`;
|
|
108
|
+
}
|
|
109
|
+
statusLine() {
|
|
110
|
+
return `${this.formatNano(this.session.estimatedCost)} · ${this.session.calls}calls`;
|
|
111
|
+
}
|
|
112
|
+
report() {
|
|
113
|
+
const s = this.session;
|
|
114
|
+
return [
|
|
115
|
+
`Session: ${s.calls} calls · ${s.errors} errors · ${this.formatNano(s.estimatedCost)}`,
|
|
116
|
+
` Prompt: ${s.promptTokens.toLocaleString()} tokens`,
|
|
117
|
+
` Completion: ${s.completionTokens.toLocaleString()} tokens`,
|
|
118
|
+
`Lifetime: ${this.lifetime.calls} calls · ${this.formatNano(this.lifetime.estimatedCost)}`,
|
|
119
|
+
` Models used: ${this.lifetime.modelsUsed.size}`,
|
|
120
|
+
].join("\n");
|
|
121
|
+
}
|
|
122
|
+
// ── Tool: cost_report ──────────────────────────────────────────────────────
|
|
123
|
+
costReportParams = Type.Object({});
|
|
124
|
+
async costReportTool() {
|
|
125
|
+
const status = this.getBudgetStatus();
|
|
126
|
+
let text = this.report();
|
|
127
|
+
if (status.warnings.length > 0) {
|
|
128
|
+
text += "\n\n" + status.warnings.join("\n");
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
content: [{ type: "text", text }],
|
|
132
|
+
details: {
|
|
133
|
+
session_cost_nano: status.session.estimatedCost,
|
|
134
|
+
lifetime_cost_nano: status.lifetime.estimatedCost,
|
|
135
|
+
session_calls: status.session.calls,
|
|
136
|
+
lifetime_calls: status.lifetime.calls,
|
|
137
|
+
models_used: status.lifetime.modelsUsed.size,
|
|
138
|
+
warnings: status.warnings,
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
// ── Reset ──────────────────────────────────────────────────────────────────
|
|
143
|
+
resetSession() {
|
|
144
|
+
this.session = { promptTokens: 0, completionTokens: 0, estimatedCost: 0, calls: 0, errors: 0 };
|
|
145
|
+
this.budgetWarned = false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=CostTracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CostTracker.js","sourceRoot":"","sources":["../../src/models/CostTracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModelRegistry — dynamic model discovery, tiering, and routing.
|
|
3
|
+
*
|
|
4
|
+
* Queries OpenRouter's /models endpoint at startup to build a local registry
|
|
5
|
+
* of all available models. Classifies them into tiers (orchestrator / analyst /
|
|
6
|
+
* worker / free), tracks performance, handles deprecation, and exposes
|
|
7
|
+
* model selection as both a tool and a REPL command.
|
|
8
|
+
*
|
|
9
|
+
* Also supports direct provider routing (Anthropic/OpenAI/Google keys) for
|
|
10
|
+
* models that can be reached cheaper outside OpenRouter.
|
|
11
|
+
*/
|
|
12
|
+
import type { ModelConfig } from "../runner/ModelClient.js";
|
|
13
|
+
import { type Static } from "@sinclair/typebox";
|
|
14
|
+
export interface OpenRouterModel {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
created: number;
|
|
18
|
+
description: string;
|
|
19
|
+
context_length: number;
|
|
20
|
+
architecture: {
|
|
21
|
+
modality: string;
|
|
22
|
+
tokenizer: string;
|
|
23
|
+
instruct_type: string | null;
|
|
24
|
+
};
|
|
25
|
+
pricing: {
|
|
26
|
+
prompt: string;
|
|
27
|
+
completion: string;
|
|
28
|
+
image?: string;
|
|
29
|
+
request?: string;
|
|
30
|
+
input_cache_read?: string;
|
|
31
|
+
input_cache_write?: string;
|
|
32
|
+
};
|
|
33
|
+
top_provider: {
|
|
34
|
+
context_length: number;
|
|
35
|
+
max_completion_tokens: number | null;
|
|
36
|
+
is_moderated: boolean;
|
|
37
|
+
};
|
|
38
|
+
per_request_limits?: Record<string, string>;
|
|
39
|
+
}
|
|
40
|
+
export type ModelTier = "orchestrator" | "analyst" | "worker" | "free";
|
|
41
|
+
export interface TieredModel {
|
|
42
|
+
tier: ModelTier;
|
|
43
|
+
model: OpenRouterModel;
|
|
44
|
+
/** Nano-dollars per 1K prompt tokens (for cost comparison) */
|
|
45
|
+
costPer1K: number;
|
|
46
|
+
/** Whether this model is currently available (not deprecated / rate-limited) */
|
|
47
|
+
available: boolean;
|
|
48
|
+
/** Consecutive failures — if >= 3, mark unavailable temporarily */
|
|
49
|
+
failures: number;
|
|
50
|
+
/** Timestamp of last failure (ms) */
|
|
51
|
+
lastFailure: number;
|
|
52
|
+
/** Average stream latency in ms */
|
|
53
|
+
avgLatency: number;
|
|
54
|
+
/** Number of times used */
|
|
55
|
+
uses: number;
|
|
56
|
+
}
|
|
57
|
+
export interface TieredPool {
|
|
58
|
+
orchestrator: TieredModel[];
|
|
59
|
+
analyst: TieredModel[];
|
|
60
|
+
worker: TieredModel[];
|
|
61
|
+
free: TieredModel[];
|
|
62
|
+
}
|
|
63
|
+
export declare function classifyModel(model: OpenRouterModel): ModelTier;
|
|
64
|
+
export declare class ModelRegistry {
|
|
65
|
+
private allModels;
|
|
66
|
+
private tieredPool;
|
|
67
|
+
private modelMap;
|
|
68
|
+
private loaded;
|
|
69
|
+
private lastFetch;
|
|
70
|
+
/** Query OpenRouter /models and build the tiered pool. Called once at startup. */
|
|
71
|
+
initialise(apiKey?: string): Promise<void>;
|
|
72
|
+
/** Rebuild tier classifications (call after cache load or fetch). */
|
|
73
|
+
private rebuildTiers;
|
|
74
|
+
private saveCache;
|
|
75
|
+
private loadFromCache;
|
|
76
|
+
/** True if cache is stale and we should re-fetch on next opportunity. */
|
|
77
|
+
get cacheStale(): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Pick the best available model for a given tier.
|
|
80
|
+
* Favours lower cost among available models, excluding those with >= 3
|
|
81
|
+
* consecutive failures (which get a 5-minute cooldown).
|
|
82
|
+
*/
|
|
83
|
+
pick(tier: ModelTier): OpenRouterModel | null;
|
|
84
|
+
/**
|
|
85
|
+
* Build a full ModelConfig chain from the tiered pool.
|
|
86
|
+
* Uses user-configured models from env first, then fills with tiered picks.
|
|
87
|
+
*/
|
|
88
|
+
buildModelChain(userModels: string[]): ModelConfig[];
|
|
89
|
+
/** Build a single ModelConfig, preferring direct provider when possible. */
|
|
90
|
+
buildConfig(modelId: string, maxTokens: number, temperature: number): ModelConfig | null;
|
|
91
|
+
recordFailure(modelId: string): void;
|
|
92
|
+
recordSuccess(modelId: string, latencyMs: number): void;
|
|
93
|
+
/** Mark a model as permanently deprecated (404, model removed). */
|
|
94
|
+
markDeprecated(modelId: string): void;
|
|
95
|
+
getTier(modelId: string): ModelTier;
|
|
96
|
+
get modelCount(): number;
|
|
97
|
+
/** Search / filter models by keyword (case-insensitive). */
|
|
98
|
+
search(query: string, maxResults?: number): TieredModel[];
|
|
99
|
+
/** Get all models for a tier. */
|
|
100
|
+
getPool(tier: ModelTier): TieredModel[];
|
|
101
|
+
/** Human-readable summary of the current pool. */
|
|
102
|
+
summary(): string;
|
|
103
|
+
/**
|
|
104
|
+
* Find the cheapest model meeting minimum requirements.
|
|
105
|
+
* @param tier - Required tier (or "any")
|
|
106
|
+
* @param minContext - Minimum context length
|
|
107
|
+
* @param maxCost - Maximum cost in nano-dollars per 1K prompt
|
|
108
|
+
*/
|
|
109
|
+
findCheapest(tier: ModelTier | "any", minContext?: number, maxCost?: number): TieredModel | null;
|
|
110
|
+
readonly listModelsParams: import("@sinclair/typebox").TObject<{
|
|
111
|
+
query: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
112
|
+
tier: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
113
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
114
|
+
available_only: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
115
|
+
}>;
|
|
116
|
+
listModelsTool(_id: string, params: Static<typeof this.listModelsParams>): Promise<{
|
|
117
|
+
content: Array<{
|
|
118
|
+
type: "text";
|
|
119
|
+
text: string;
|
|
120
|
+
}>;
|
|
121
|
+
details: Record<string, unknown>;
|
|
122
|
+
}>;
|
|
123
|
+
readonly pickModelParams: import("@sinclair/typebox").TObject<{
|
|
124
|
+
tier: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
125
|
+
min_context: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
126
|
+
max_cost: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
127
|
+
}>;
|
|
128
|
+
pickModelTool(_id: string, params: Static<typeof this.pickModelParams>): Promise<{
|
|
129
|
+
content: Array<{
|
|
130
|
+
type: "text";
|
|
131
|
+
text: string;
|
|
132
|
+
}>;
|
|
133
|
+
details: Record<string, unknown>;
|
|
134
|
+
}>;
|
|
135
|
+
readonly summaryParams: import("@sinclair/typebox").TObject<{}>;
|
|
136
|
+
summaryTool(): Promise<{
|
|
137
|
+
content: Array<{
|
|
138
|
+
type: "text";
|
|
139
|
+
text: string;
|
|
140
|
+
}>;
|
|
141
|
+
details: Record<string, unknown>;
|
|
142
|
+
}>;
|
|
143
|
+
}
|
|
144
|
+
/** Singleton — initialised once at startup, used everywhere */
|
|
145
|
+
export declare const modelRegistry: ModelRegistry;
|
|
146
|
+
//# sourceMappingURL=ModelRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelRegistry.d.ts","sourceRoot":"","sources":["../../src/models/ModelRegistry.ts"],"names":[],"mappings":"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"}
|