@agentskit/cli 0.13.33 → 0.13.35
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 +13 -4
- package/dist/bin.cjs +285 -41
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-54AIH25E.js → chunk-DZKCRKFS.js} +288 -44
- package/dist/chunk-DZKCRKFS.js.map +1 -0
- package/dist/index.cjs +285 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/package.json +11 -11
- package/dist/chunk-54AIH25E.js.map +0 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Chat with any LLM, scaffold projects, and run agents — all from your terminal.
|
|
|
20
20
|
## Verified proof
|
|
21
21
|
|
|
22
22
|
- Package metadata and tests live under `packages/cli/`.
|
|
23
|
-
- Package guide: https://www.agentskit.io/docs/packages/cli
|
|
23
|
+
- Package guide: https://www.agentskit.io/docs/reference/packages/cli
|
|
24
24
|
- Stability map: [docs/STABILITY.md](../../docs/STABILITY.md)
|
|
25
25
|
|
|
26
26
|
## How this fits the ecosystem
|
|
@@ -32,14 +32,14 @@ Chat with any LLM, scaffold projects, and run agents — all from your terminal.
|
|
|
32
32
|
- **Playbook**: learn the production patterns behind this layer at [playbook.agentskit.io](https://playbook.agentskit.io).
|
|
33
33
|
- **AKOS**: run the same concepts with enterprise deployment, governance, and observability at [akos.agentskit.io](https://akos.agentskit.io).
|
|
34
34
|
|
|
35
|
-
Docs: [package guide](https://www.agentskit.io/docs/packages/cli) · [agent handoff](https://github.com/AgentsKit-io/agentskit/blob/main/llms.txt)
|
|
35
|
+
Docs: [package guide](https://www.agentskit.io/docs/reference/packages/cli) · [agent handoff](https://github.com/AgentsKit-io/agentskit/blob/main/llms.txt)
|
|
36
36
|
|
|
37
37
|
## Why cli
|
|
38
38
|
|
|
39
39
|
- **Zero setup for prototyping** — go from idea to running conversation in under a minute; no boilerplate, no config files to write
|
|
40
40
|
- **Scaffold production-ready projects** — generate a React chat app or terminal agent with the right structure so you skip the boring setup
|
|
41
41
|
- **Script and automate** — pipe inputs, use env vars for keys, and compose with other Unix tools for lightweight agent scripting
|
|
42
|
-
- **Every provider, one command** — switch between OpenAI, Anthropic, Ollama (local), and more with a single flag
|
|
42
|
+
- **Every provider, one command** — switch between OpenAI, Anthropic, Groq, OpenRouter, Ollama (local), and more with a single flag
|
|
43
43
|
|
|
44
44
|
## Install
|
|
45
45
|
|
|
@@ -57,6 +57,13 @@ ANTHROPIC_API_KEY=... agentskit chat --provider anthropic --model claude-sonnet-
|
|
|
57
57
|
# Chat with a local model (no API key needed)
|
|
58
58
|
agentskit chat --provider ollama --model llama3.1
|
|
59
59
|
|
|
60
|
+
# Chat through DeepSeek, Grok, Kimi, Groq, or OpenRouter
|
|
61
|
+
DEEPSEEK_API_KEY=... agentskit chat --provider deepseek
|
|
62
|
+
XAI_API_KEY=... agentskit chat --provider grok
|
|
63
|
+
KIMI_API_KEY=... agentskit chat --provider kimi
|
|
64
|
+
GROQ_API_KEY=... agentskit chat --provider groq
|
|
65
|
+
OPENROUTER_API_KEY=... agentskit chat --provider openrouter
|
|
66
|
+
|
|
60
67
|
# Scaffold a new React chat app
|
|
61
68
|
agentskit init --template react --dir my-app
|
|
62
69
|
|
|
@@ -84,8 +91,10 @@ agentskit run --help
|
|
|
84
91
|
- **Extensibility** — plugins (slash commands, tools, skills, providers, hooks, MCP servers), permission policy with modes, lifecycle hooks (shell or JS), MCP stdio bridge, session rename + fork, `/usage` + `/cost`
|
|
85
92
|
- Provider flags: `--provider`, `--model`, `--system`, `--skill`, `--memory`, `--mode`, `--plugin-dir`
|
|
86
93
|
- Env-var based key injection — works seamlessly in CI and scripts
|
|
94
|
+
- Built-in live providers include OpenAI, Anthropic, Gemini, DeepSeek, Grok, Kimi, Groq, and OpenRouter; Ollama remains local and keyless
|
|
95
|
+
- `agentskit init --provider deepseek|grok|kimi|groq|openrouter` — scaffold a starter already wired to the selected provider
|
|
87
96
|
|
|
88
|
-
Full reference: [docs/
|
|
97
|
+
Full reference: [docs/production/cli](https://www.agentskit.io/docs/production/cli) · [ARCHITECTURE.md](./ARCHITECTURE.md)
|
|
89
98
|
|
|
90
99
|
### agentskit doctor
|
|
91
100
|
|
package/dist/bin.cjs
CHANGED
|
@@ -105,12 +105,12 @@ var providers = {
|
|
|
105
105
|
anthropic: {
|
|
106
106
|
label: "Anthropic",
|
|
107
107
|
envKeys: ["ANTHROPIC_API_KEY"],
|
|
108
|
-
defaultModel: "claude-
|
|
108
|
+
defaultModel: "claude-sonnet-4-6",
|
|
109
109
|
factory: (c) => adapters.anthropic(c)
|
|
110
110
|
},
|
|
111
111
|
gemini: {
|
|
112
112
|
label: "Gemini",
|
|
113
|
-
envKeys: ["GEMINI_API_KEY"],
|
|
113
|
+
envKeys: ["GEMINI_API_KEY", "GOOGLE_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"],
|
|
114
114
|
defaultModel: "gemini-2.5-flash",
|
|
115
115
|
factory: (c) => adapters.gemini(c)
|
|
116
116
|
},
|
|
@@ -129,14 +129,26 @@ var providers = {
|
|
|
129
129
|
grok: {
|
|
130
130
|
label: "xAI Grok",
|
|
131
131
|
envKeys: ["XAI_API_KEY"],
|
|
132
|
-
|
|
132
|
+
defaultModel: "grok-4.20-0309-non-reasoning",
|
|
133
133
|
factory: (c) => adapters.grok(c)
|
|
134
134
|
},
|
|
135
135
|
kimi: {
|
|
136
136
|
label: "Kimi",
|
|
137
137
|
envKeys: ["KIMI_API_KEY", "MOONSHOT_API_KEY"],
|
|
138
|
-
|
|
138
|
+
defaultModel: "kimi-k2-0711-preview",
|
|
139
139
|
factory: (c) => adapters.kimi(c)
|
|
140
|
+
},
|
|
141
|
+
groq: {
|
|
142
|
+
label: "Groq",
|
|
143
|
+
envKeys: ["GROQ_API_KEY"],
|
|
144
|
+
defaultModel: "openai/gpt-oss-120b",
|
|
145
|
+
factory: (c) => adapters.groq(c)
|
|
146
|
+
},
|
|
147
|
+
openrouter: {
|
|
148
|
+
label: "OpenRouter",
|
|
149
|
+
envKeys: ["OPENROUTER_API_KEY"],
|
|
150
|
+
defaultModel: "~anthropic/claude-haiku-latest",
|
|
151
|
+
factory: (c) => adapters.openrouter(c)
|
|
140
152
|
}
|
|
141
153
|
};
|
|
142
154
|
function createDemoAdapter(provider, model) {
|
|
@@ -429,7 +441,7 @@ ${lines.join("\n")}`, "info");
|
|
|
429
441
|
{
|
|
430
442
|
name: "provider",
|
|
431
443
|
description: "Switch the adapter provider.",
|
|
432
|
-
usage: "/provider openai|anthropic|gemini|ollama|deepseek|grok|kimi|demo",
|
|
444
|
+
usage: "/provider openai|anthropic|gemini|ollama|deepseek|grok|kimi|groq|openrouter|demo",
|
|
433
445
|
run(ctx, args) {
|
|
434
446
|
const value = args.trim();
|
|
435
447
|
if (!value) {
|
|
@@ -1695,17 +1707,29 @@ function registerRunCommand(program) {
|
|
|
1695
1707
|
}
|
|
1696
1708
|
});
|
|
1697
1709
|
}
|
|
1710
|
+
|
|
1711
|
+
// src/init-providers.ts
|
|
1698
1712
|
var PROVIDER_IMPORT = {
|
|
1699
1713
|
openai: "openai",
|
|
1700
1714
|
anthropic: "anthropic",
|
|
1701
1715
|
gemini: "gemini",
|
|
1702
|
-
ollama: "ollama"
|
|
1716
|
+
ollama: "ollama",
|
|
1717
|
+
deepseek: "deepseek",
|
|
1718
|
+
grok: "grok",
|
|
1719
|
+
kimi: "kimi",
|
|
1720
|
+
groq: "groq",
|
|
1721
|
+
openrouter: "openrouter"
|
|
1703
1722
|
};
|
|
1704
1723
|
var PROVIDER_DEFAULT_MODEL = {
|
|
1705
1724
|
openai: "gpt-4o-mini",
|
|
1706
1725
|
anthropic: "claude-sonnet-4-6",
|
|
1707
1726
|
gemini: "gemini-2.5-flash",
|
|
1708
1727
|
ollama: "llama3.1",
|
|
1728
|
+
deepseek: "deepseek-chat",
|
|
1729
|
+
grok: "grok-4.20-0309-non-reasoning",
|
|
1730
|
+
kimi: "kimi-k2-0711-preview",
|
|
1731
|
+
groq: "openai/gpt-oss-120b",
|
|
1732
|
+
openrouter: "~anthropic/claude-haiku-latest",
|
|
1709
1733
|
demo: "demo"
|
|
1710
1734
|
};
|
|
1711
1735
|
var PROVIDER_ENV_KEY = {
|
|
@@ -1713,8 +1737,15 @@ var PROVIDER_ENV_KEY = {
|
|
|
1713
1737
|
anthropic: "ANTHROPIC_API_KEY",
|
|
1714
1738
|
gemini: "GEMINI_API_KEY",
|
|
1715
1739
|
ollama: null,
|
|
1740
|
+
deepseek: "DEEPSEEK_API_KEY",
|
|
1741
|
+
grok: "XAI_API_KEY",
|
|
1742
|
+
kimi: "KIMI_API_KEY",
|
|
1743
|
+
groq: "GROQ_API_KEY",
|
|
1744
|
+
openrouter: "OPENROUTER_API_KEY",
|
|
1716
1745
|
demo: null
|
|
1717
1746
|
};
|
|
1747
|
+
|
|
1748
|
+
// src/init.ts
|
|
1718
1749
|
function adapterCall(provider, prefix = "process.env") {
|
|
1719
1750
|
const model = PROVIDER_DEFAULT_MODEL[provider];
|
|
1720
1751
|
if (provider === "demo") return `demoAdapter()`;
|
|
@@ -1722,6 +1753,11 @@ function adapterCall(provider, prefix = "process.env") {
|
|
|
1722
1753
|
const envKey = PROVIDER_ENV_KEY[provider];
|
|
1723
1754
|
return `${PROVIDER_IMPORT[provider]}({ apiKey: ${prefix}.${envKey} ?? '', model: '${model}' })`;
|
|
1724
1755
|
}
|
|
1756
|
+
function denoAdapterCall(provider) {
|
|
1757
|
+
if (provider === "demo") return "demoAdapter()";
|
|
1758
|
+
if (provider === "ollama") return `ollama({ model: '${PROVIDER_DEFAULT_MODEL[provider]}' })`;
|
|
1759
|
+
return `${PROVIDER_IMPORT[provider]}({ apiKey: Deno.env.get('${PROVIDER_ENV_KEY[provider]}') ?? '', model: '${PROVIDER_DEFAULT_MODEL[provider]}' })`;
|
|
1760
|
+
}
|
|
1725
1761
|
function viteAdapterCall(provider) {
|
|
1726
1762
|
if (provider === "demo") return `demoAdapter()`;
|
|
1727
1763
|
if (provider === "ollama") return `ollama({ model: '${PROVIDER_DEFAULT_MODEL[provider]}' })`;
|
|
@@ -2402,7 +2438,7 @@ function cloudflareWorkersStarter(ctx) {
|
|
|
2402
2438
|
"itty-router": "^5.0.0"
|
|
2403
2439
|
};
|
|
2404
2440
|
if (ctx.provider !== "demo") deps["@agentskit/adapters"] = "^0.4.0";
|
|
2405
|
-
const adapterCallEdge =
|
|
2441
|
+
const adapterCallEdge = adapterCall(ctx.provider, "env");
|
|
2406
2442
|
const adapterImport2 = buildAdapterServerImport(ctx.provider);
|
|
2407
2443
|
const demoSnippet = ctx.provider === "demo" ? demoAdapterSnippet() : "";
|
|
2408
2444
|
const envKey = PROVIDER_ENV_KEY[ctx.provider];
|
|
@@ -2885,7 +2921,7 @@ export const useAuth = () => useContext(AuthCtx)
|
|
|
2885
2921
|
};
|
|
2886
2922
|
}
|
|
2887
2923
|
function denoDeployStarter(ctx) {
|
|
2888
|
-
const adapterCallEdge =
|
|
2924
|
+
const adapterCallEdge = denoAdapterCall(ctx.provider);
|
|
2889
2925
|
const adapterImport2 = ctx.provider === "demo" ? "" : `import { ${PROVIDER_IMPORT[ctx.provider]} } from 'npm:@agentskit/adapters'
|
|
2890
2926
|
`;
|
|
2891
2927
|
const demoSnippet = ctx.provider === "demo" ? demoAdapterSnippet() : "";
|
|
@@ -3070,8 +3106,8 @@ ${runCmd}
|
|
|
3070
3106
|
## Next steps
|
|
3071
3107
|
|
|
3072
3108
|
- Open the AgentsKit docs at https://www.agentskit.io/docs
|
|
3073
|
-
- Add a custom skill: https://www.agentskit.io/docs/concepts/skill
|
|
3074
|
-
- Wire up RAG: https://www.agentskit.io/docs/recipes/rag-chat
|
|
3109
|
+
- Add a custom skill: https://www.agentskit.io/docs/get-started/concepts/skill
|
|
3110
|
+
- Wire up RAG: https://www.agentskit.io/docs/reference/recipes/rag-chat
|
|
3075
3111
|
|
|
3076
3112
|
## License
|
|
3077
3113
|
|
|
@@ -3154,7 +3190,12 @@ ${kleur__default.default.bold().green("\u25B2")} ${kleur__default.default.bold("
|
|
|
3154
3190
|
{ name: "OpenAI", value: "openai" },
|
|
3155
3191
|
{ name: "Anthropic", value: "anthropic" },
|
|
3156
3192
|
{ name: "Gemini", value: "gemini" },
|
|
3157
|
-
{ name: "Ollama (local, no key)", value: "ollama" }
|
|
3193
|
+
{ name: "Ollama (local, no key)", value: "ollama" },
|
|
3194
|
+
{ name: "DeepSeek", value: "deepseek" },
|
|
3195
|
+
{ name: "xAI Grok", value: "grok" },
|
|
3196
|
+
{ name: "Kimi", value: "kimi" },
|
|
3197
|
+
{ name: "Groq", value: "groq" },
|
|
3198
|
+
{ name: "OpenRouter", value: "openrouter" }
|
|
3158
3199
|
]
|
|
3159
3200
|
});
|
|
3160
3201
|
let tools = [];
|
|
@@ -3253,7 +3294,7 @@ function printNextSteps(options) {
|
|
|
3253
3294
|
|
|
3254
3295
|
// src/commands/init.ts
|
|
3255
3296
|
function registerInitCommand(program) {
|
|
3256
|
-
program.command("init").description("Generate a starter project. Run with no flags for interactive mode.").option("--template <template>", "Starter template (react|nextjs|sveltekit|nuxt|ink|vite-ink|cloudflare-workers|bun|deno-deploy|expo|angular|runtime|multi-agent)").option("--dir <directory>", "Target directory", "agentskit-app").option("--provider <provider>", "LLM provider (openai|anthropic|gemini|ollama|demo)").option("--tools <tools>", "Comma-separated tools (web_search,filesystem,shell)").option("--memory <backend>", "Memory backend (none|file|sqlite)").option("--pm <packageManager>", "Package manager (pnpm|npm|yarn|bun)").option("-y, --yes", "Skip interactive prompts; use flag values + defaults").action(async (rawOptions) => {
|
|
3297
|
+
program.command("init").description("Generate a starter project. Run with no flags for interactive mode.").option("--template <template>", "Starter template (react|nextjs|sveltekit|nuxt|ink|vite-ink|cloudflare-workers|bun|deno-deploy|expo|angular|runtime|multi-agent)").option("--dir <directory>", "Target directory", "agentskit-app").option("--provider <provider>", "LLM provider (openai|anthropic|gemini|ollama|deepseek|grok|kimi|groq|openrouter|demo)").option("--tools <tools>", "Comma-separated tools (web_search,filesystem,shell)").option("--memory <backend>", "Memory backend (none|file|sqlite)").option("--pm <packageManager>", "Package manager (pnpm|npm|yarn|bun)").option("-y, --yes", "Skip interactive prompts; use flag values + defaults").action(async (rawOptions) => {
|
|
3257
3298
|
const isCi = !process.stdout.isTTY || rawOptions.yes || rawOptions.template;
|
|
3258
3299
|
let resolved;
|
|
3259
3300
|
if (isCi) {
|
|
@@ -3288,20 +3329,206 @@ function registerInitCommand(program) {
|
|
|
3288
3329
|
}
|
|
3289
3330
|
});
|
|
3290
3331
|
}
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
}
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3332
|
+
|
|
3333
|
+
// src/provider-registry.ts
|
|
3334
|
+
var PROVIDER_REGISTRY = [
|
|
3335
|
+
{
|
|
3336
|
+
id: "demo",
|
|
3337
|
+
label: "Demo",
|
|
3338
|
+
runtime: "local",
|
|
3339
|
+
env: { status: "not-required", reason: "Demo adapter does not use provider credentials." },
|
|
3340
|
+
reachability: { status: "unsupported", reason: "Demo adapter has no upstream endpoint." },
|
|
3341
|
+
defaultModel: { status: "known", id: "demo" }
|
|
3342
|
+
},
|
|
3343
|
+
{
|
|
3344
|
+
id: "openai",
|
|
3345
|
+
label: "OpenAI",
|
|
3346
|
+
runtime: "cli",
|
|
3347
|
+
catalogId: "openai",
|
|
3348
|
+
env: { status: "required", keys: ["OPENAI_API_KEY"] },
|
|
3349
|
+
reachability: { status: "supported", url: "https://api.openai.com/v1/models" },
|
|
3350
|
+
defaultModel: { status: "known", id: "gpt-4o-mini" },
|
|
3351
|
+
doctorDefault: true
|
|
3352
|
+
},
|
|
3353
|
+
{
|
|
3354
|
+
id: "anthropic",
|
|
3355
|
+
label: "Anthropic",
|
|
3356
|
+
runtime: "cli",
|
|
3357
|
+
catalogId: "anthropic",
|
|
3358
|
+
env: { status: "required", keys: ["ANTHROPIC_API_KEY"] },
|
|
3359
|
+
reachability: { status: "supported", url: "https://api.anthropic.com/v1/messages" },
|
|
3360
|
+
defaultModel: { status: "known", id: "claude-sonnet-4-6" },
|
|
3361
|
+
doctorDefault: true
|
|
3362
|
+
},
|
|
3363
|
+
{
|
|
3364
|
+
id: "gemini",
|
|
3365
|
+
label: "Gemini",
|
|
3366
|
+
runtime: "cli",
|
|
3367
|
+
catalogId: "google",
|
|
3368
|
+
env: { status: "required", keys: ["GEMINI_API_KEY", "GOOGLE_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"] },
|
|
3369
|
+
reachability: { status: "supported", url: "https://generativelanguage.googleapis.com/v1beta/models" },
|
|
3370
|
+
defaultModel: { status: "known", id: "gemini-2.5-flash" },
|
|
3371
|
+
doctorDefault: true
|
|
3372
|
+
},
|
|
3373
|
+
{
|
|
3374
|
+
id: "ollama",
|
|
3375
|
+
label: "Ollama",
|
|
3376
|
+
runtime: "local",
|
|
3377
|
+
env: { status: "not-required", reason: "Ollama runs locally and does not require an API key." },
|
|
3378
|
+
reachability: { status: "supported", url: "http://localhost:11434/api/tags" },
|
|
3379
|
+
defaultModel: { status: "known", id: "llama3.1" },
|
|
3380
|
+
doctorDefault: true
|
|
3381
|
+
},
|
|
3382
|
+
{
|
|
3383
|
+
id: "deepseek",
|
|
3384
|
+
label: "DeepSeek",
|
|
3385
|
+
runtime: "cli",
|
|
3386
|
+
catalogId: "deepseek",
|
|
3387
|
+
env: { status: "required", keys: ["DEEPSEEK_API_KEY"] },
|
|
3388
|
+
reachability: { status: "supported", url: "https://api.deepseek.com/models" },
|
|
3389
|
+
defaultModel: { status: "known", id: "deepseek-chat" }
|
|
3390
|
+
},
|
|
3391
|
+
{
|
|
3392
|
+
id: "grok",
|
|
3393
|
+
label: "xAI Grok",
|
|
3394
|
+
runtime: "cli",
|
|
3395
|
+
catalogId: "xai",
|
|
3396
|
+
env: { status: "required", keys: ["XAI_API_KEY"] },
|
|
3397
|
+
reachability: { status: "supported", url: "https://api.x.ai/v1/models" },
|
|
3398
|
+
defaultModel: { status: "known", id: "grok-4.20-0309-non-reasoning" }
|
|
3399
|
+
},
|
|
3400
|
+
{
|
|
3401
|
+
id: "kimi",
|
|
3402
|
+
label: "Kimi",
|
|
3403
|
+
runtime: "cli",
|
|
3404
|
+
catalogId: "moonshotai",
|
|
3405
|
+
env: { status: "required", keys: ["KIMI_API_KEY", "MOONSHOT_API_KEY"] },
|
|
3406
|
+
reachability: { status: "supported", url: "https://api.moonshot.ai/v1/models" },
|
|
3407
|
+
defaultModel: { status: "known", id: "kimi-k2-0711-preview" }
|
|
3408
|
+
},
|
|
3409
|
+
{
|
|
3410
|
+
id: "groq",
|
|
3411
|
+
label: "Groq",
|
|
3412
|
+
runtime: "cli",
|
|
3413
|
+
catalogId: "groq",
|
|
3414
|
+
env: { status: "required", keys: ["GROQ_API_KEY"] },
|
|
3415
|
+
reachability: { status: "supported", url: "https://api.groq.com/openai/v1/models" },
|
|
3416
|
+
defaultModel: { status: "known", id: "openai/gpt-oss-120b" }
|
|
3417
|
+
},
|
|
3418
|
+
{
|
|
3419
|
+
id: "openrouter",
|
|
3420
|
+
label: "OpenRouter",
|
|
3421
|
+
runtime: "cli",
|
|
3422
|
+
catalogId: "openrouter",
|
|
3423
|
+
env: { status: "required", keys: ["OPENROUTER_API_KEY"] },
|
|
3424
|
+
reachability: { status: "supported", url: "https://openrouter.ai/api/v1/models" },
|
|
3425
|
+
defaultModel: { status: "known", id: "~anthropic/claude-haiku-latest" }
|
|
3426
|
+
},
|
|
3427
|
+
{
|
|
3428
|
+
id: "mistral",
|
|
3429
|
+
label: "Mistral",
|
|
3430
|
+
runtime: "adapter-only",
|
|
3431
|
+
catalogId: "mistral",
|
|
3432
|
+
env: { status: "required", keys: ["MISTRAL_API_KEY"] },
|
|
3433
|
+
reachability: { status: "supported", url: "https://api.mistral.ai/v1/models" },
|
|
3434
|
+
defaultModel: { status: "known", id: "codestral-latest" }
|
|
3435
|
+
},
|
|
3436
|
+
{
|
|
3437
|
+
id: "cohere",
|
|
3438
|
+
label: "Cohere",
|
|
3439
|
+
runtime: "adapter-only",
|
|
3440
|
+
catalogId: "cohere",
|
|
3441
|
+
env: { status: "required", keys: ["COHERE_API_KEY"] },
|
|
3442
|
+
reachability: { status: "supported", url: "https://api.cohere.com/v1/models" },
|
|
3443
|
+
defaultModel: { status: "known", id: "c4ai-aya-expanse-32b" }
|
|
3444
|
+
},
|
|
3445
|
+
{
|
|
3446
|
+
id: "together",
|
|
3447
|
+
label: "Together",
|
|
3448
|
+
runtime: "adapter-only",
|
|
3449
|
+
catalogId: "togetherai",
|
|
3450
|
+
env: { status: "required", keys: ["TOGETHER_API_KEY"] },
|
|
3451
|
+
reachability: { status: "supported", url: "https://api.together.xyz/v1/models" },
|
|
3452
|
+
defaultModel: { status: "known", id: "deepseek-ai/DeepSeek-R1" }
|
|
3453
|
+
},
|
|
3454
|
+
{
|
|
3455
|
+
id: "fireworks",
|
|
3456
|
+
label: "Fireworks",
|
|
3457
|
+
runtime: "adapter-only",
|
|
3458
|
+
catalogId: "fireworks-ai",
|
|
3459
|
+
env: { status: "required", keys: ["FIREWORKS_API_KEY"] },
|
|
3460
|
+
reachability: { status: "supported", url: "https://api.fireworks.ai/inference/v1/models" },
|
|
3461
|
+
defaultModel: { status: "known", id: "accounts/fireworks/models/deepseek-v4-flash" }
|
|
3462
|
+
},
|
|
3463
|
+
{
|
|
3464
|
+
id: "huggingface",
|
|
3465
|
+
label: "Hugging Face",
|
|
3466
|
+
runtime: "adapter-only",
|
|
3467
|
+
catalogId: "huggingface",
|
|
3468
|
+
env: { status: "required", keys: ["HF_TOKEN"] },
|
|
3469
|
+
reachability: { status: "supported", url: "https://router.huggingface.co/v1/models" },
|
|
3470
|
+
defaultModel: { status: "known", id: "deepseek-ai/DeepSeek-R1-0528" }
|
|
3471
|
+
},
|
|
3472
|
+
{
|
|
3473
|
+
id: "lmstudio",
|
|
3474
|
+
label: "LM Studio",
|
|
3475
|
+
runtime: "local",
|
|
3476
|
+
catalogId: "lmstudio",
|
|
3477
|
+
env: { status: "not-required", reason: "LM Studio runs locally and does not require a provider key." },
|
|
3478
|
+
reachability: { status: "supported", url: "http://127.0.0.1:1234/v1/models" },
|
|
3479
|
+
defaultModel: { status: "known", id: "openai/gpt-oss-20b" }
|
|
3480
|
+
},
|
|
3481
|
+
{
|
|
3482
|
+
id: "vllm",
|
|
3483
|
+
label: "vLLM",
|
|
3484
|
+
runtime: "local",
|
|
3485
|
+
env: { status: "not-required", reason: "vLLM is a local server and does not require a provider key." },
|
|
3486
|
+
reachability: { status: "supported", url: "http://localhost:8000/v1/models" },
|
|
3487
|
+
defaultModel: { status: "known", id: "meta-llama/Llama-3.1-8B-Instruct" }
|
|
3488
|
+
},
|
|
3489
|
+
{
|
|
3490
|
+
id: "llamacpp",
|
|
3491
|
+
label: "llama.cpp",
|
|
3492
|
+
runtime: "local",
|
|
3493
|
+
env: { status: "not-required", reason: "llama.cpp is a local server and does not require a provider key." },
|
|
3494
|
+
reachability: { status: "supported", url: "http://localhost:8080/v1/models" },
|
|
3495
|
+
defaultModel: { status: "known", id: "local-model" }
|
|
3496
|
+
},
|
|
3497
|
+
{
|
|
3498
|
+
id: "cerebras",
|
|
3499
|
+
label: "Cerebras",
|
|
3500
|
+
runtime: "adapter-only",
|
|
3501
|
+
catalogId: "cerebras",
|
|
3502
|
+
env: { status: "required", keys: ["CEREBRAS_API_KEY"] },
|
|
3503
|
+
reachability: { status: "supported", url: "https://api.cerebras.ai/v1/models" },
|
|
3504
|
+
defaultModel: { status: "known", id: "gpt-oss-120b" }
|
|
3505
|
+
}
|
|
3506
|
+
];
|
|
3507
|
+
var DEFAULT_DOCTOR_PROVIDERS = PROVIDER_REGISTRY.filter((entry) => "doctorDefault" in entry && entry.doctorDefault === true).map((entry) => entry.id);
|
|
3508
|
+
function getProviderRegistryEntry(provider) {
|
|
3509
|
+
return PROVIDER_REGISTRY.find((entry) => entry.id === provider.toLowerCase());
|
|
3510
|
+
}
|
|
3511
|
+
function resolveProviderRegistryEntry(provider) {
|
|
3512
|
+
return getProviderRegistryEntry(provider) ?? {
|
|
3513
|
+
id: provider,
|
|
3514
|
+
label: provider,
|
|
3515
|
+
runtime: "adapter-only",
|
|
3516
|
+
env: { status: "unsupported", reason: "Provider is not in the CLI doctor registry." },
|
|
3517
|
+
reachability: { status: "unsupported", reason: "Provider is not in the CLI doctor registry." },
|
|
3518
|
+
defaultModel: { status: "unsupported", reason: "Provider is not in the CLI doctor registry." }
|
|
3519
|
+
};
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3522
|
+
// src/doctor.ts
|
|
3523
|
+
function providerReachabilityFix(entry) {
|
|
3524
|
+
if (entry.id === "ollama") {
|
|
3525
|
+
return "Start Ollama: `ollama serve` (or install from https://ollama.com)";
|
|
3526
|
+
}
|
|
3527
|
+
if (entry.runtime === "local") {
|
|
3528
|
+
return `Start ${entry.label} server and verify its local endpoint`;
|
|
3529
|
+
}
|
|
3530
|
+
return "Check network / firewall / VPN settings";
|
|
3531
|
+
}
|
|
3305
3532
|
async function checkNodeVersion() {
|
|
3306
3533
|
const major = Number(process.versions.node.split(".")[0]);
|
|
3307
3534
|
if (Number.isNaN(major)) {
|
|
@@ -3380,17 +3607,22 @@ async function checkPackageJson() {
|
|
|
3380
3607
|
}
|
|
3381
3608
|
}
|
|
3382
3609
|
async function checkProviderEnv(provider) {
|
|
3383
|
-
const
|
|
3384
|
-
if (
|
|
3385
|
-
return { status: "skip", name: `${provider} API key`, detail:
|
|
3610
|
+
const entry = resolveProviderRegistryEntry(provider);
|
|
3611
|
+
if (entry.env.status === "unsupported") {
|
|
3612
|
+
return { status: "skip", name: `${provider} API key`, detail: entry.env.reason };
|
|
3613
|
+
}
|
|
3614
|
+
if (entry.env.status === "not-required") {
|
|
3615
|
+
return { status: "skip", name: `${provider} API key`, detail: entry.env.reason };
|
|
3386
3616
|
}
|
|
3387
|
-
const
|
|
3617
|
+
const envKey = entry.env.keys.find((key) => process.env[key]);
|
|
3618
|
+
const expectedKeys = entry.env.keys.join(" or ");
|
|
3619
|
+
const value = envKey ? process.env[envKey] : void 0;
|
|
3388
3620
|
if (!value) {
|
|
3389
3621
|
return {
|
|
3390
3622
|
status: "skip",
|
|
3391
3623
|
name: `${provider} API key`,
|
|
3392
|
-
detail: `${
|
|
3393
|
-
fix: `export ${
|
|
3624
|
+
detail: `${expectedKeys} not set`,
|
|
3625
|
+
fix: `export ${entry.env.keys[0]}=... (only needed if you use ${provider})`
|
|
3394
3626
|
};
|
|
3395
3627
|
}
|
|
3396
3628
|
if (value.length < 16) {
|
|
@@ -3404,12 +3636,12 @@ async function checkProviderEnv(provider) {
|
|
|
3404
3636
|
return { status: "pass", name: `${provider} API key`, detail: `${envKey} set (${value.length} chars)` };
|
|
3405
3637
|
}
|
|
3406
3638
|
async function checkProviderReachable(provider, fetchImpl = fetch, timeoutMs = 4e3) {
|
|
3407
|
-
const
|
|
3408
|
-
if (
|
|
3409
|
-
return { status: "skip", name: `${provider} reachable`, detail:
|
|
3639
|
+
const entry = resolveProviderRegistryEntry(provider);
|
|
3640
|
+
if (entry.reachability.status === "unsupported") {
|
|
3641
|
+
return { status: "skip", name: `${provider} reachable`, detail: entry.reachability.reason };
|
|
3410
3642
|
}
|
|
3411
|
-
const
|
|
3412
|
-
if (
|
|
3643
|
+
const url = entry.reachability.url;
|
|
3644
|
+
if (entry.env.status === "required" && !entry.env.keys.some((key) => process.env[key])) {
|
|
3413
3645
|
return { status: "skip", name: `${provider} reachable`, detail: "Skipped \u2014 no API key configured" };
|
|
3414
3646
|
}
|
|
3415
3647
|
const controller = new AbortController();
|
|
@@ -3437,12 +3669,23 @@ async function checkProviderReachable(provider, fetchImpl = fetch, timeoutMs = 4
|
|
|
3437
3669
|
status: "fail",
|
|
3438
3670
|
name: `${provider} reachable`,
|
|
3439
3671
|
detail: `${url} \u2192 ${reason}`,
|
|
3440
|
-
fix:
|
|
3672
|
+
fix: providerReachabilityFix(entry)
|
|
3441
3673
|
};
|
|
3442
3674
|
} finally {
|
|
3443
3675
|
clearTimeout(timer);
|
|
3444
3676
|
}
|
|
3445
3677
|
}
|
|
3678
|
+
async function checkProviderDefaultModel(provider) {
|
|
3679
|
+
const entry = resolveProviderRegistryEntry(provider);
|
|
3680
|
+
if (entry.defaultModel.status === "unsupported") {
|
|
3681
|
+
return { status: "skip", name: `${provider} default model`, detail: entry.defaultModel.reason };
|
|
3682
|
+
}
|
|
3683
|
+
return {
|
|
3684
|
+
status: "pass",
|
|
3685
|
+
name: `${provider} default model`,
|
|
3686
|
+
detail: entry.defaultModel.id
|
|
3687
|
+
};
|
|
3688
|
+
}
|
|
3446
3689
|
async function checkConfig() {
|
|
3447
3690
|
try {
|
|
3448
3691
|
const config = await loadConfig();
|
|
@@ -3463,7 +3706,7 @@ async function checkConfig() {
|
|
|
3463
3706
|
}
|
|
3464
3707
|
}
|
|
3465
3708
|
async function runDoctor(options = {}) {
|
|
3466
|
-
const providers2 = options.providers ??
|
|
3709
|
+
const providers2 = options.providers ?? DEFAULT_DOCTOR_PROVIDERS;
|
|
3467
3710
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
3468
3711
|
const checks = [
|
|
3469
3712
|
checkNodeVersion(),
|
|
@@ -3473,6 +3716,7 @@ async function runDoctor(options = {}) {
|
|
|
3473
3716
|
];
|
|
3474
3717
|
for (const provider of providers2) {
|
|
3475
3718
|
checks.push(checkProviderEnv(provider));
|
|
3719
|
+
checks.push(checkProviderDefaultModel(provider));
|
|
3476
3720
|
if (!options.noNetwork) {
|
|
3477
3721
|
checks.push(checkProviderReachable(provider, fetchImpl));
|
|
3478
3722
|
}
|
|
@@ -3558,7 +3802,7 @@ function renderReport(report, opts = {}) {
|
|
|
3558
3802
|
function registerDoctorCommand(program) {
|
|
3559
3803
|
program.command("doctor").description("Diagnose your AgentsKit environment.").option("--no-network", "Skip provider reachability checks").option(
|
|
3560
3804
|
"--providers <providers>",
|
|
3561
|
-
|
|
3805
|
+
`Comma-separated providers to check (default: ${DEFAULT_DOCTOR_PROVIDERS.join(",")})`
|
|
3562
3806
|
).option("--json", "Emit JSON instead of formatted output").action(async (options) => {
|
|
3563
3807
|
const providers2 = options.providers ? options.providers.split(",").map((p) => p.trim()).filter(Boolean) : void 0;
|
|
3564
3808
|
const report = await runDoctor({
|
|
@@ -5554,7 +5798,7 @@ async function tryComponentAdd(name, options) {
|
|
|
5554
5798
|
function registerAddCommand(program) {
|
|
5555
5799
|
program.command("add <name>").description(
|
|
5556
5800
|
'Add a ready-made agent or UI component from the AgentsKit registry (registry.agentskit.io). Auto-detects which: a component is scanned/validated against your project and installed transactionally; an agent is copied into ./agents. You own the code. e.g. `agentskit add docs-chat` (component) or `agentskit add research --run "\u2026"` (agent).'
|
|
5557
|
-
).option("--out <dir>", "Directory to install into (component: the port dir; agent: ./agents)").option("-f, --force", "Overwrite existing files").option("--registry <url>", "Registry base URL override (component install)").option("--run <task>", "Run the agent on this task right after adding it").option("--provider <provider>", "Provider for --run (openai, anthropic, gemini, ollama, demo)", "demo").option("--model <model>", "Model for --run").option("--api-key <key>", "API key for --run (else read from the provider env var)").action(
|
|
5801
|
+
).option("--out <dir>", "Directory to install into (component: the port dir; agent: ./agents)").option("-f, --force", "Overwrite existing files").option("--registry <url>", "Registry base URL override (component install)").option("--run <task>", "Run the agent on this task right after adding it").option("--provider <provider>", "Provider for --run (openai, anthropic, gemini, ollama, groq, openrouter, demo)", "demo").option("--model <model>", "Model for --run").option("--api-key <key>", "API key for --run (else read from the provider env var)").action(
|
|
5558
5802
|
async (agent, options) => {
|
|
5559
5803
|
try {
|
|
5560
5804
|
const outcome = await tryComponentAdd(agent, {
|