@aiaiaichain/agent 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/ExtensionAPI.d.ts +0 -1
- package/dist/api/ExtensionAPI.js +3 -7
- package/dist/api/Registry.d.ts +0 -1
- package/dist/api/Registry.js +54 -57
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +364 -768
- package/dist/core/AgentDir.d.ts +1 -1
- package/dist/core/AgentDir.js +45 -39
- package/dist/core/ChainConfig.d.ts +0 -1
- package/dist/core/ChainConfig.js +51 -55
- package/dist/core/EnvLoader.d.ts +4 -1
- package/dist/core/EnvLoader.js +97 -84
- package/dist/core/SystemMonitor.d.ts +0 -1
- package/dist/core/SystemMonitor.js +70 -85
- package/dist/index.d.ts +4 -61
- package/dist/index.js +19 -26
- package/dist/loader.d.ts +0 -1
- package/dist/loader.js +64 -67
- package/dist/mcp/entry.d.ts +0 -1
- package/dist/mcp/entry.js +3 -6
- package/dist/mcp/server.d.ts +0 -1
- package/dist/mcp/server.js +152 -156
- package/dist/models/CostTracker.d.ts +0 -1
- package/dist/models/CostTracker.js +58 -61
- package/dist/models/ModelRegistry.d.ts +0 -1
- package/dist/models/ModelRegistry.js +195 -155
- package/dist/providers/ProviderRegistry.d.ts +0 -1
- package/dist/providers/ProviderRegistry.js +33 -36
- package/dist/runner/AgentRunner.d.ts +0 -1
- package/dist/runner/AgentRunner.js +180 -184
- package/dist/runner/ModelClient.d.ts +0 -1
- package/dist/runner/ModelClient.js +133 -134
- package/dist/runner/SwarmRouter.d.ts +0 -1
- package/dist/runner/SwarmRouter.js +17 -22
- package/dist/runner/ToolDispatcher.d.ts +0 -1
- package/dist/runner/ToolDispatcher.js +30 -33
- package/dist/scheduler/AgentScheduler.d.ts +0 -1
- package/dist/scheduler/AgentScheduler.js +99 -103
- package/dist/session/ContextStore.d.ts +1 -1
- package/dist/session/ContextStore.js +76 -78
- package/dist/session/GoalManager.d.ts +0 -1
- package/dist/session/GoalManager.js +96 -100
- package/dist/session/MemoryStore.d.ts +2 -1
- package/dist/session/MemoryStore.js +108 -87
- package/dist/session/SessionManager.d.ts +5 -4
- package/dist/session/SessionManager.js +83 -62
- package/dist/session/SessionStore.d.ts +0 -1
- package/dist/session/SessionStore.js +112 -116
- package/dist/setup/SetupWizard.d.ts +0 -1
- package/dist/setup/SetupWizard.js +61 -64
- package/dist/tools/CrossTools.d.ts +0 -1
- package/dist/tools/CrossTools.js +140 -144
- package/dist/tools/GmgnIntegration.d.ts +0 -1
- package/dist/tools/GmgnIntegration.js +220 -230
- package/dist/tools/MarketSentiment.d.ts +0 -1
- package/dist/tools/MarketSentiment.js +213 -195
- package/dist/tools/NewsSentiment.d.ts +0 -1
- package/dist/tools/NewsSentiment.js +126 -130
- package/dist/tools/PriceFeed.d.ts +6 -1
- package/dist/tools/PriceFeed.js +201 -133
- package/dist/tools/TechnicalAnalysis.d.ts +1 -2
- package/dist/tools/TechnicalAnalysis.js +248 -216
- package/dist/tools/TechnicalAnalysis.worker.d.ts +25 -0
- package/dist/tools/TechnicalAnalysis.worker.js +92 -0
- package/dist/tools/TokenCalendar.d.ts +0 -1
- package/dist/tools/TokenCalendar.js +63 -68
- package/dist/tools/TokenSecurityScanner.d.ts +0 -1
- package/dist/tools/TokenSecurityScanner.js +93 -96
- package/dist/tools/TransactionSim.d.ts +0 -1
- package/dist/tools/TransactionSim.js +65 -71
- package/dist/tui/App.d.ts +1 -7
- package/dist/tui/App.js +896 -825
- package/dist/tui/ModelSelector.d.ts +1 -3
- package/dist/tui/ModelSelector.js +47 -50
- package/dist/tui/REPL.d.ts +1 -3
- package/dist/tui/REPL.js +222 -210
- package/dist/tui/Sparkline.d.ts +1 -3
- package/dist/tui/Sparkline.js +38 -37
- package/dist/tui/StatusBar.d.ts +1 -3
- package/dist/tui/StatusBar.js +11 -10
- package/dist/tui/ThemePresets.d.ts +0 -1
- package/dist/tui/ThemePresets.js +99 -103
- package/dist/tui/theme.d.ts +0 -1
- package/dist/tui/theme.js +50 -31
- package/dist/util/clipboard.d.ts +0 -1
- package/dist/util/clipboard.js +16 -20
- package/dist/util/commandSuggest.d.ts +0 -1
- package/dist/util/commandSuggest.js +34 -38
- package/dist/util/confirmation.d.ts +0 -1
- package/dist/util/confirmation.js +8 -11
- package/dist/util/errorHandler.d.ts +0 -1
- package/dist/util/errorHandler.js +20 -23
- package/dist/util/errors.d.ts +59 -0
- package/dist/util/errors.js +93 -0
- package/dist/util/logger.d.ts +0 -1
- package/dist/util/logger.js +30 -33
- package/dist/util/processManager.d.ts +0 -1
- package/dist/util/processManager.js +33 -36
- package/dist/util/resilientFetch.d.ts +6 -1
- package/dist/util/resilientFetch.js +134 -80
- package/dist/util/responseCache.d.ts +0 -1
- package/dist/util/responseCache.js +36 -45
- package/dist/util/rpc.d.ts +16 -0
- package/dist/util/rpc.js +69 -0
- package/dist/util/safeLog.d.ts +0 -1
- package/dist/util/safeLog.js +52 -53
- package/dist/util/scheduler.d.ts +0 -1
- package/dist/util/scheduler.js +53 -58
- package/dist/util/webhooks.d.ts +0 -1
- package/dist/util/webhooks.js +54 -58
- package/dist/wallet/ActionFeed.d.ts +0 -1
- package/dist/wallet/ActionFeed.js +189 -200
- package/dist/wallet/AgentWallet.d.ts +7 -8
- package/dist/wallet/AgentWallet.js +117 -144
- package/dist/wallet/ProfitTracker.d.ts +0 -1
- package/dist/wallet/ProfitTracker.js +71 -74
- package/package.json +14 -8
- package/scripts/build-esbuild.mjs +40 -0
- package/scripts/bundle-dts.mjs +58 -0
- package/scripts/minify.mjs +44 -0
- package/scripts/postinstall.js +41 -0
|
@@ -1,69 +1,66 @@
|
|
|
1
|
-
|
|
2
|
-
* CostTracker — tracks token usage and cost across sessions.
|
|
3
|
-
*/
|
|
1
|
+
|
|
4
2
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
3
|
import { resolve } from "node:path";
|
|
6
4
|
import { Type } from "@sinclair/typebox";
|
|
7
5
|
import { AgentDir } from "../core/AgentDir.js";
|
|
8
6
|
const LIFETIME_PATH = resolve(AgentDir.getHome(), "lifetime-cost.json");
|
|
9
7
|
export class CostTracker {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
8
|
+
registry;
|
|
9
|
+
sessionEntry = { entries: [], totalCost: 0, totalTokens: 0 };
|
|
10
|
+
lifetime = { sessions: 0, totalCost: 0, totalTokens: 0 };
|
|
11
|
+
loaded = false;
|
|
12
|
+
constructor(registry) {
|
|
13
|
+
this.registry = registry;
|
|
14
|
+
}
|
|
15
|
+
track(model, promptTokens, completionTokens) {
|
|
16
|
+
if (!this.loaded)
|
|
17
|
+
this.loadLifetime();
|
|
18
|
+
const cost = this.estimateCost(model, promptTokens, completionTokens);
|
|
19
|
+
const entry = { model, promptTokens, completionTokens, cost, timestamp: Date.now() };
|
|
20
|
+
this.sessionEntry.entries.push(entry);
|
|
21
|
+
this.sessionEntry.totalCost += cost;
|
|
22
|
+
this.sessionEntry.totalTokens += promptTokens + completionTokens;
|
|
23
|
+
}
|
|
24
|
+
estimateCost(_model, prompt, completion) {
|
|
25
|
+
return (prompt * DEFAULT_RATES.prompt) + (completion * DEFAULT_RATES.completion);
|
|
26
|
+
}
|
|
27
|
+
statusLine() {
|
|
28
|
+
return `$${this.sessionEntry.totalCost.toFixed(4)}`;
|
|
29
|
+
}
|
|
30
|
+
saveLifetime() {
|
|
31
|
+
this.lifetime.sessions++;
|
|
32
|
+
this.lifetime.totalCost += this.sessionEntry.totalCost;
|
|
33
|
+
this.lifetime.totalTokens += this.sessionEntry.totalTokens;
|
|
34
|
+
this.writeLifetime();
|
|
35
|
+
}
|
|
36
|
+
loadLifetime() {
|
|
37
|
+
try {
|
|
38
|
+
if (existsSync(LIFETIME_PATH)) {
|
|
39
|
+
this.lifetime = JSON.parse(readFileSync(LIFETIME_PATH, "utf-8"));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch { }
|
|
43
|
+
this.loaded = true;
|
|
44
|
+
}
|
|
45
|
+
writeLifetime() {
|
|
46
|
+
try {
|
|
47
|
+
writeFileSync(LIFETIME_PATH, JSON.stringify(this.lifetime, null, 2), "utf-8");
|
|
48
|
+
}
|
|
49
|
+
catch { }
|
|
50
|
+
}
|
|
51
|
+
costReportParams = Type.Object({});
|
|
52
|
+
async costReportTool() {
|
|
53
|
+
const s = this.sessionEntry;
|
|
54
|
+
const l = this.lifetime;
|
|
55
|
+
return {
|
|
56
|
+
content: [{
|
|
57
|
+
type: "text",
|
|
58
|
+
text: [
|
|
59
|
+
`Session cost: $${s.totalCost.toFixed(4)} (${s.totalTokens} tokens, ${s.entries.length} calls)`,
|
|
60
|
+
`Lifetime: $${l.totalCost.toFixed(4)} (${l.totalTokens} tokens, ${l.sessions} sessions)`,
|
|
61
|
+
].join("\n"),
|
|
62
|
+
}],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
67
65
|
}
|
|
68
66
|
const DEFAULT_RATES = { prompt: 0.000001, completion: 0.000002 };
|
|
69
|
-
//# sourceMappingURL=CostTracker.js.map
|
|
@@ -1,166 +1,206 @@
|
|
|
1
|
-
|
|
2
|
-
* ModelRegistry — discovers available models from any configured provider.
|
|
3
|
-
* Supports all 29 providers via their API keys.
|
|
4
|
-
*/
|
|
1
|
+
|
|
5
2
|
import { env } from "../core/EnvLoader.js";
|
|
6
3
|
import { Type } from "@sinclair/typebox";
|
|
7
4
|
import { logger } from "../util/logger.js";
|
|
8
5
|
import { resilientFetch } from "../util/resilientFetch.js";
|
|
9
6
|
const PROVIDERS_WITH_MODELS = [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
7
|
+
{ id: "openrouter", envVar: "OPENROUTER_API_KEY", baseUrl: "https://openrouter.ai/api/v1/models", mapper: (m) => ({ id: m.id, name: m.name, context: m.context_length ?? 131072, max: m.top_provider?.max_completion_tokens ?? 4096 }) },
|
|
8
|
+
{ id: "anthropic", envVar: "ANTHROPIC_API_KEY", baseUrl: "https://api.anthropic.com/v1/models", mapper: (m) => ({ id: m.id, name: m.name, context: m.context_length ?? 200000, max: m.top_provider?.max_completion_tokens ?? 8192 }) },
|
|
9
|
+
{ id: "openai", envVar: "OPENAI_API_KEY", baseUrl: "https://api.openai.com/v1/models", mapper: (m) => ({ id: m.id, name: m.name ?? m.id, context: m.context_length ?? 128000, max: 4096 }) },
|
|
10
|
+
{ id: "google", envVar: "GOOGLE_API_KEY", baseUrl: "https://generativelanguage.googleapis.com/v1beta/models", mapper: (m) => ({ id: m.name, name: m.displayName ?? m.name, context: m.contextLength ?? 1048576, max: 8192 }) },
|
|
11
|
+
{ id: "deepseek", envVar: "DEEPSEEK_API_KEY", baseUrl: "https://api.deepseek.com/v1/models", mapper: (m) => ({ id: m.id, name: m.name ?? m.id, context: m.context_length ?? 65536, max: 8192 }) },
|
|
12
|
+
{ id: "groq", envVar: "GROQ_API_KEY", baseUrl: "https://api.groq.com/openai/v1/models", mapper: (m) => ({ id: m.id, name: m.name ?? m.id, context: m.context_length ?? 131072, max: 4096 }) },
|
|
13
|
+
{ id: "mistral", envVar: "MISTRAL_API_KEY", baseUrl: "https://api.mistral.ai/v1/models", mapper: (m) => ({ id: m.id, name: m.name ?? m.id, context: m.context_length ?? 32000, max: 8192 }) },
|
|
14
|
+
{ id: "together", envVar: "TOGETHER_API_KEY", baseUrl: "https://api.together.xyz/v1/models", mapper: (m) => ({ id: m.id, name: m.name ?? m.id, context: m.context_length ?? 131072, max: 4096 }) },
|
|
15
|
+
{ id: "fireworks", envVar: "FIREWORKS_API_KEY", baseUrl: "https://api.fireworks.ai/inference/v1/models", mapper: (m) => ({ id: m.id, name: m.name ?? m.id, context: m.context_length ?? 131072, max: 4096 }) },
|
|
16
|
+
{ id: "cerebras", envVar: "CEREBRAS_API_KEY", baseUrl: "https://api.cerebras.ai/v1/models", mapper: (m) => ({ id: m.id, name: m.name ?? m.id, context: m.context_length ?? 131072, max: 4096 }) },
|
|
17
|
+
{ id: "nvidia", envVar: "NVIDIA_NIM_API_KEY", baseUrl: "https://integrate.api.nvidia.com/v1/models", mapper: (m) => ({ id: m.id, name: m.name ?? m.id, context: m.context_length ?? 131072, max: 4096 }) },
|
|
18
|
+
{ id: "xai", envVar: "XAI_API_KEY", baseUrl: "https://api.x.ai/v1/models", mapper: (m) => ({ id: m.id, name: m.name ?? m.id, context: m.context_length ?? 131072, max: 4096 }) },
|
|
19
|
+
{ id: "huggingface", envVar: "HUGGINGFACE_API_KEY", baseUrl: "https://huggingface.co/api/models?limit=100&inference_provider=auto", mapper: (m) => ({ id: m.id, name: m.id, context: 131072, max: 4096 }) },
|
|
23
20
|
];
|
|
21
|
+
|
|
22
|
+
const OPENROUTER_CDN = "https://openrouter.ai/api/v1/models";
|
|
24
23
|
export function classifyModel(model) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
const id = model.id.toLowerCase();
|
|
25
|
+
const name = model.name.toLowerCase();
|
|
26
|
+
if (id.includes("o1") || id.includes("o3") || id.includes("claude-3.5-sonnet") || id.includes("claude-4") || id.includes("gemini-2.5-pro") || (id.includes("gpt-4o") && !id.includes("mini")))
|
|
27
|
+
return "orchestrator";
|
|
28
|
+
if (id.includes("sonnet") || id.includes("gpt-4o-mini") || id.includes("claude-3-haiku") || id.includes("gemini-2.0-flash") || id.includes("gemini-1.5-pro") || id.includes("mistral-large") || id.includes("llama-3.1-70b") || id.includes("llama-3.3-70b") || id.includes("command-r-plus") || id.includes("deepseek-v2") || id.includes("qwen-2.5-72b") || id.includes("mixtral-8x22b"))
|
|
29
|
+
return "analyst";
|
|
30
|
+
if (id.includes("haiku") || id.includes("flash") || id.includes("mistral-7b") || id.includes("llama-3.1-8b") || id.includes("llama-3.2") || id.includes("phi-3") || id.includes("qwen-2.5-7b") || id.includes("gemma-2") || id.includes("deepseek-v2-lite") || id.includes("ministral-3b") || id.includes("command-r-08-2024") || id.includes("mixtral-8x7b") || id.includes("nemotron-4") || id.includes("claude-3-opus"))
|
|
31
|
+
return "worker";
|
|
32
|
+
return "free";
|
|
34
33
|
}
|
|
35
34
|
export class ModelRegistry {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
35
|
+
models = [];
|
|
36
|
+
tiered = new Map();
|
|
37
|
+
providerModels = new Map();
|
|
38
|
+
initialized = false;
|
|
39
|
+
async initialise() {
|
|
40
|
+
if (this.initialized)
|
|
41
|
+
return;
|
|
42
|
+
this.models = [];
|
|
43
|
+
this.providerModels.clear();
|
|
44
|
+
|
|
45
|
+
const enabledProviders = PROVIDERS_WITH_MODELS.filter(p => env.get(p.envVar));
|
|
46
|
+
const results = await Promise.allSettled(enabledProviders.map(async (provider) => {
|
|
47
|
+
const apiKey = env.get(provider.envVar);
|
|
48
|
+
const headers = { "Content-Type": "application/json" };
|
|
49
|
+
if (provider.id === "openrouter")
|
|
50
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
51
|
+
else if (provider.id === "anthropic")
|
|
52
|
+
headers["x-api-key"] = apiKey;
|
|
53
|
+
else
|
|
54
|
+
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
55
|
+
let url = provider.baseUrl;
|
|
56
|
+
if (provider.id === "google") {
|
|
57
|
+
url = `${provider.baseUrl}?key=${apiKey}`;
|
|
58
|
+
}
|
|
59
|
+
const controller = new AbortController();
|
|
60
|
+
const timer = setTimeout(() => controller.abort(), 5_000);
|
|
61
|
+
try {
|
|
62
|
+
const res = await resilientFetch(url, { timeout: 5_000, retries: 0, headers, signal: controller.signal });
|
|
63
|
+
clearTimeout(timer);
|
|
64
|
+
if (!res.ok) {
|
|
65
|
+
logger.warn('ModelRegistry', `Provider ${provider.id} returned ${res.status}`);
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
const data = await res.json();
|
|
69
|
+
const items = data.data ?? data.models ?? data;
|
|
70
|
+
if (!Array.isArray(items))
|
|
71
|
+
return [];
|
|
72
|
+
const models = [];
|
|
73
|
+
for (const item of items) {
|
|
74
|
+
try {
|
|
75
|
+
const m = provider.mapper(item);
|
|
76
|
+
if (!m || !m.id)
|
|
77
|
+
continue;
|
|
78
|
+
models.push({
|
|
79
|
+
id: m.id,
|
|
80
|
+
name: m.name ?? m.id,
|
|
81
|
+
provider: provider.id,
|
|
82
|
+
context_length: m.context ?? 131072,
|
|
83
|
+
max_tokens: m.max ?? 4096,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
logger.debug('ModelRegistry', 'Skipped bad model entry', { error: error.message });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return models;
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
clearTimeout(timer);
|
|
94
|
+
logger.warn('ModelRegistry', `Provider ${provider.id} timed out or failed`, { error: error.message });
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
}));
|
|
98
|
+
for (let i = 0; i < results.length; i++) {
|
|
99
|
+
const result = results[i];
|
|
100
|
+
const provider = enabledProviders[i];
|
|
101
|
+
if (result.status === 'fulfilled') {
|
|
102
|
+
for (const model of result.value) {
|
|
103
|
+
this.models.push(model);
|
|
104
|
+
if (!this.providerModels.has(provider.id))
|
|
105
|
+
this.providerModels.set(provider.id, []);
|
|
106
|
+
this.providerModels.get(provider.id).push(model);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (this.models.length === 0) {
|
|
112
|
+
const orApiKey = env.get("OPENROUTER_API_KEY");
|
|
113
|
+
if (orApiKey) {
|
|
114
|
+
try {
|
|
115
|
+
const res = await resilientFetch(OPENROUTER_CDN, {
|
|
116
|
+
timeout: 5_000,
|
|
117
|
+
retries: 0,
|
|
118
|
+
headers: { "Authorization": `Bearer ${orApiKey}`, "Content-Type": "application/json" },
|
|
119
|
+
});
|
|
120
|
+
if (res.ok) {
|
|
121
|
+
const data = await res.json();
|
|
122
|
+
const items = data.data ?? [];
|
|
123
|
+
for (const item of items) {
|
|
124
|
+
this.models.push({
|
|
125
|
+
id: item.id,
|
|
126
|
+
name: item.name ?? item.id,
|
|
127
|
+
provider: "openrouter",
|
|
128
|
+
context_length: item.context_length ?? 131072,
|
|
129
|
+
max_tokens: item.top_provider?.max_completion_tokens ?? 4096,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch { }
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
this.buildTiers();
|
|
138
|
+
this.initialized = true;
|
|
139
|
+
}
|
|
140
|
+
buildTiers() {
|
|
141
|
+
this.tiered.clear();
|
|
142
|
+
const tiers = ["orchestrator", "analyst", "worker", "free"];
|
|
143
|
+
for (const tier of tiers)
|
|
144
|
+
this.tiered.set(tier, []);
|
|
145
|
+
for (const model of this.models) {
|
|
146
|
+
const tier = classifyModel(model);
|
|
147
|
+
this.tiered.get(tier)?.push({ model, tier, available: true, failures: 0 });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
get modelCount() { return this.models.length; }
|
|
151
|
+
getProviderCount() { return this.providerModels.size; }
|
|
152
|
+
getProviderModels(providerId) { return this.providerModels.get(providerId) ?? []; }
|
|
153
|
+
getAllModels() { return [...this.models]; }
|
|
154
|
+
getPool(tier) { return this.tiered.get(tier) ?? []; }
|
|
155
|
+
getTier(modelId) { const m = this.models.find(m => m.id === modelId); return m ? classifyModel(m) : undefined; }
|
|
156
|
+
resolvePrimary() {
|
|
157
|
+
for (const tier of ["orchestrator", "analyst", "worker", "free"]) {
|
|
158
|
+
const pool = this.tiered.get(tier) ?? [];
|
|
159
|
+
const avail = pool.filter(tm => tm.available && tm.failures < 3);
|
|
160
|
+
if (avail.length > 0)
|
|
161
|
+
return avail[0].model.id;
|
|
162
|
+
}
|
|
163
|
+
return "openai/gpt-4o-mini";
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
listModelsParams = Type.Object({
|
|
167
|
+
query: Type.Optional(Type.String()),
|
|
168
|
+
provider: Type.Optional(Type.String()),
|
|
169
|
+
limit: Type.Optional(Type.Number({ default: 30 })),
|
|
170
|
+
available_only: Type.Optional(Type.Boolean({ default: true })),
|
|
171
|
+
});
|
|
172
|
+
async listModelsTool(_id, params) {
|
|
173
|
+
let items = [...this.models];
|
|
174
|
+
const query = (params.query || "").toLowerCase();
|
|
175
|
+
if (query)
|
|
176
|
+
items = items.filter(m => m.id.toLowerCase().includes(query) || m.name.toLowerCase().includes(query));
|
|
177
|
+
const provider = (params.provider || "").toLowerCase();
|
|
178
|
+
if (provider)
|
|
179
|
+
items = items.filter(m => m.provider === provider);
|
|
180
|
+
const limit = params.limit || 30;
|
|
181
|
+
const top = items.slice(0, limit);
|
|
182
|
+
const lines = top.map(m => {
|
|
183
|
+
const tier = classifyModel(m);
|
|
184
|
+
const tierIcon = { orchestrator: "⭐", analyst: "🔬", worker: "⚡", free: "🆓" }[tier] ?? "•";
|
|
185
|
+
return `${tierIcon} [${m.provider}] ${m.id} — ${m.name} (${m.context_length}t)`;
|
|
186
|
+
});
|
|
187
|
+
return { content: [{ type: "text", text: `Models (${items.length} from ${this.providerModels.size} providers):\n${lines.join("\n")}` }] };
|
|
188
|
+
}
|
|
189
|
+
async modelSummaryTool() {
|
|
190
|
+
const pool = this.tiered;
|
|
191
|
+
const lines = [`Total: ${this.models.length} models from ${this.providerModels.size} providers`];
|
|
192
|
+
lines.push("");
|
|
193
|
+
lines.push("Providers:");
|
|
194
|
+
for (const [id, models] of this.providerModels) {
|
|
195
|
+
lines.push(` ${id}: ${models.length} models`);
|
|
196
|
+
}
|
|
197
|
+
lines.push("");
|
|
198
|
+
for (const tier of ["orchestrator", "analyst", "worker", "free"]) {
|
|
199
|
+
const p = pool.get(tier) ?? [];
|
|
200
|
+
const avail = p.filter(tm => tm.available).length;
|
|
201
|
+
lines.push(` ${tier}: ${p.length} total, ${avail} available`);
|
|
202
|
+
}
|
|
203
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
204
|
+
}
|
|
164
205
|
}
|
|
165
206
|
export const modelRegistry = new ModelRegistry();
|
|
166
|
-
//# sourceMappingURL=ModelRegistry.js.map
|
|
@@ -13,4 +13,3 @@ export declare const PROVIDERS: Provider[];
|
|
|
13
13
|
export declare function getConfiguredCount(env: Record<string, string | undefined>): number;
|
|
14
14
|
export declare function getConfigured(env: Record<string, string | undefined>): Provider[];
|
|
15
15
|
export declare function getUnconfigured(env: Record<string, string | undefined>): Provider[];
|
|
16
|
-
//# sourceMappingURL=ProviderRegistry.d.ts.map
|
|
@@ -1,44 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
* ProviderRegistry — all 29 AI model providers with their env vars and model fetch endpoints.
|
|
3
|
-
*/
|
|
1
|
+
|
|
4
2
|
export const PROVIDERS = [
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
3
|
+
{ id: "openrouter", name: "OpenRouter", envVar: "OPENROUTER_API_KEY", baseUrl: "https://openrouter.ai/api/v1", modelsEndpoint: "https://openrouter.ai/api/v1/models", docsUrl: "https://openrouter.ai/keys" },
|
|
4
|
+
{ id: "anthropic", name: "Anthropic", envVar: "ANTHROPIC_API_KEY", baseUrl: "https://api.anthropic.com/v1", modelsEndpoint: "https://api.anthropic.com/v1/models", docsUrl: "https://console.anthropic.com" },
|
|
5
|
+
{ id: "openai", name: "OpenAI", envVar: "OPENAI_API_KEY", baseUrl: "https://api.openai.com/v1", modelsEndpoint: "https://api.openai.com/v1/models", docsUrl: "https://platform.openai.com/api-keys" },
|
|
6
|
+
{ id: "google", name: "Google Gemini", envVar: "GOOGLE_API_KEY", baseUrl: "https://generativelanguage.googleapis.com/v1beta", modelsEndpoint: "https://generativelanguage.googleapis.com/v1beta/models", docsUrl: "https://aistudio.google.com/apikey" },
|
|
7
|
+
{ id: "deepseek", name: "DeepSeek", envVar: "DEEPSEEK_API_KEY", baseUrl: "https://api.deepseek.com/v1", modelsEndpoint: "https://api.deepseek.com/v1/models", docsUrl: "https://platform.deepseek.com/api-docs/api-key" },
|
|
8
|
+
{ id: "groq", name: "Groq", envVar: "GROQ_API_KEY", baseUrl: "https://api.groq.com/openai/v1", modelsEndpoint: "https://api.groq.com/openai/v1/models", docsUrl: "https://console.groq.com/keys" },
|
|
9
|
+
{ id: "mistral", name: "Mistral", envVar: "MISTRAL_API_KEY", baseUrl: "https://api.mistral.ai/v1", modelsEndpoint: "https://api.mistral.ai/v1/models", docsUrl: "https://console.mistral.ai/api-keys" },
|
|
10
|
+
{ id: "together", name: "Together AI", envVar: "TOGETHER_API_KEY", baseUrl: "https://api.together.xyz/v1", modelsEndpoint: "https://api.together.xyz/v1/models", docsUrl: "https://api.together.xyz/settings/api-keys" },
|
|
11
|
+
{ id: "fireworks", name: "Fireworks", envVar: "FIREWORKS_API_KEY", baseUrl: "https://api.fireworks.ai/inference/v1", modelsEndpoint: "https://api.fireworks.ai/inference/v1/models", docsUrl: "https://fireworks.ai/api-keys" },
|
|
12
|
+
{ id: "cerebras", name: "Cerebras", envVar: "CEREBRAS_API_KEY", baseUrl: "https://api.cerebras.ai/v1", modelsEndpoint: "https://api.cerebras.ai/v1/models", docsUrl: "https://api.cerebras.ai/api-keys" },
|
|
13
|
+
{ id: "bedrock", name: "Amazon Bedrock", envVar: "AWS_ACCESS_KEY_ID", baseUrl: "", modelsEndpoint: "", docsUrl: "https://console.aws.amazon.com/iam" },
|
|
14
|
+
{ id: "vertex", name: "Google Vertex AI", envVar: "GOOGLE_APPLICATION_CREDENTIALS", baseUrl: "", modelsEndpoint: "", docsUrl: "https://console.cloud.google.com/apis/credentials" },
|
|
15
|
+
{ id: "azure", name: "Azure OpenAI Responses", envVar: "AZURE_OPENAI_API_KEY", baseUrl: "", modelsEndpoint: "", docsUrl: "https://portal.azure.com" },
|
|
16
|
+
{ id: "huggingface", name: "Hugging Face", envVar: "HUGGINGFACE_API_KEY", baseUrl: "https://api-inference.huggingface.co", modelsEndpoint: "https://huggingface.co/api/models", docsUrl: "https://huggingface.co/settings/tokens" },
|
|
17
|
+
{ id: "nvidia", name: "NVIDIA NIM", envVar: "NVIDIA_NIM_API_KEY", baseUrl: "https://integrate.api.nvidia.com/v1", modelsEndpoint: "https://integrate.api.nvidia.com/v1/models", docsUrl: "https://integrate.api.nvidia.com" },
|
|
18
|
+
{ id: "xai", name: "xAI", envVar: "XAI_API_KEY", baseUrl: "https://api.x.ai/v1", modelsEndpoint: "https://api.x.ai/v1/models", docsUrl: "https://console.x.ai" },
|
|
19
|
+
{ id: "moonshot", name: "Moonshot AI", envVar: "MOONSHOT_API_KEY", baseUrl: "https://api.moonshot.cn/v1", modelsEndpoint: "https://api.moonshot.cn/v1/models", docsUrl: "https://platform.moonshot.cn/docs/api/chat-completion" },
|
|
20
|
+
{ id: "moonshot_china", name: "Moonshot AI China", envVar: "MOONSHOT_CHINA_API_KEY", baseUrl: "https://api.moonshot.cn/v1", modelsEndpoint: "https://api.moonshot.cn/v1/models", docsUrl: "https://platform.moonshot.cn" },
|
|
21
|
+
{ id: "minimax", name: "MiniMax", envVar: "MINIMAX_API_KEY", baseUrl: "https://api.minimax.chat/v1", modelsEndpoint: "https://api.minimax.chat/v1/models", docsUrl: "https://www.minimax.chat/document/embedding" },
|
|
22
|
+
{ id: "minimax_china", name: "MiniMax China", envVar: "MINIMAX_CHINA_API_KEY", baseUrl: "https://api.minimax.chat/v1", modelsEndpoint: "https://api.minimax.chat/v1/models", docsUrl: "https://www.minimax.chat" },
|
|
23
|
+
{ id: "kimi", name: "Kimi For Coding", envVar: "KIMI_API_KEY", baseUrl: "https://api.moonshot.cn/v1", modelsEndpoint: "https://api.moonshot.cn/v1/models", docsUrl: "https://platform.moonshot.cn" },
|
|
24
|
+
{ id: "antling", name: "Ant Ling", envVar: "ANTLING_API_KEY", baseUrl: "", modelsEndpoint: "", docsUrl: "https://antling.ai" },
|
|
25
|
+
{ id: "cloudflare_gateway", name: "Cloudflare AI Gateway", envVar: "CF_API_KEY", baseUrl: "", modelsEndpoint: "", docsUrl: "https://dash.cloudflare.com" },
|
|
26
|
+
{ id: "cloudflare_workers", name: "Cloudflare Workers AI", envVar: "CF_API_KEY", baseUrl: "", modelsEndpoint: "", docsUrl: "https://dash.cloudflare.com" },
|
|
27
|
+
{ id: "vercel", name: "Vercel AI Gateway", envVar: "VERCEL_API_KEY", baseUrl: "", modelsEndpoint: "", docsUrl: "https://vercel.com" },
|
|
28
|
+
{ id: "opencode_go", name: "OpenCode Go", envVar: "OPENCODE_API_KEY", baseUrl: "", modelsEndpoint: "", docsUrl: "https://opencode.ai" },
|
|
29
|
+
{ id: "opencode_zen", name: "OpenCode Zen", envVar: "OPENCODE_ZEN_API_KEY", baseUrl: "", modelsEndpoint: "", docsUrl: "https://opencode.ai" },
|
|
30
|
+
{ id: "xiaomi", name: "Xiaomi MiMo", envVar: "XIAOMI_API_KEY", baseUrl: "", modelsEndpoint: "", docsUrl: "https://xiaomi.com" },
|
|
31
|
+
{ id: "xiaomi_token", name: "Xiaomi MiMo Token Plan", envVar: "XIAOMI_TOKEN_API_KEY", baseUrl: "", modelsEndpoint: "", docsUrl: "https://xiaomi.com" },
|
|
34
32
|
];
|
|
35
33
|
export function getConfiguredCount(env) {
|
|
36
|
-
|
|
34
|
+
return PROVIDERS.filter(p => p.envVar && env[p.envVar] && env[p.envVar].trim() !== "").length;
|
|
37
35
|
}
|
|
38
36
|
export function getConfigured(env) {
|
|
39
|
-
|
|
37
|
+
return PROVIDERS.filter(p => p.envVar && env[p.envVar] && env[p.envVar].trim() !== "");
|
|
40
38
|
}
|
|
41
39
|
export function getUnconfigured(env) {
|
|
42
|
-
|
|
40
|
+
return PROVIDERS.filter(p => !p.envVar || !env[p.envVar] || env[p.envVar].trim() === "");
|
|
43
41
|
}
|
|
44
|
-
//# sourceMappingURL=ProviderRegistry.js.map
|