@agentskit/cli 0.7.1 → 0.8.2
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 +2 -2
- package/dist/bin.cjs +183 -0
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-72XFU2X2.js → chunk-FLIR7BRS.js} +185 -2
- package/dist/chunk-FLIR7BRS.js.map +1 -0
- package/dist/index.cjs +183 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +20 -9
- package/dist/chunk-72XFU2X2.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -20,6 +20,7 @@ import kleur3 from 'kleur';
|
|
|
20
20
|
import { createRAG } from '@agentskit/rag';
|
|
21
21
|
import { Command } from 'commander';
|
|
22
22
|
import { input, select, checkbox, confirm } from '@inquirer/prompts';
|
|
23
|
+
import { validateAgentSchema } from '@agentskit/core/agent-schema';
|
|
23
24
|
|
|
24
25
|
async function loadJsonConfig(path5) {
|
|
25
26
|
try {
|
|
@@ -2950,6 +2951,187 @@ function registerRagCommand(program) {
|
|
|
2950
2951
|
});
|
|
2951
2952
|
}
|
|
2952
2953
|
|
|
2954
|
+
// src/ai/scaffold.ts
|
|
2955
|
+
function snakeToCamel(name) {
|
|
2956
|
+
return name.replace(/[-_](\w)/g, (_, c) => c.toUpperCase());
|
|
2957
|
+
}
|
|
2958
|
+
function toolStub(tool) {
|
|
2959
|
+
const fnName = snakeToCamel(tool.name);
|
|
2960
|
+
const schema = tool.schema ? JSON.stringify(tool.schema, null, 2) : '{ type: "object", properties: {} }';
|
|
2961
|
+
return `import { defineTool } from '@agentskit/core'
|
|
2962
|
+
|
|
2963
|
+
/**
|
|
2964
|
+
* ${tool.description ?? tool.name}
|
|
2965
|
+
* ${tool.implementation ? `
|
|
2966
|
+
* Implementation hint: ${tool.implementation}` : ""}
|
|
2967
|
+
*/
|
|
2968
|
+
export const ${fnName} = defineTool({
|
|
2969
|
+
name: '${tool.name}',
|
|
2970
|
+
description: ${JSON.stringify(tool.description ?? "")},
|
|
2971
|
+
schema: ${schema} as const,
|
|
2972
|
+
${tool.requiresConfirmation ? "requiresConfirmation: true," : ""}
|
|
2973
|
+
async execute(args) {
|
|
2974
|
+
// TODO: implement ${tool.name}
|
|
2975
|
+
return { args }
|
|
2976
|
+
},
|
|
2977
|
+
})
|
|
2978
|
+
`;
|
|
2979
|
+
}
|
|
2980
|
+
function indexTs(schema) {
|
|
2981
|
+
const toolImports2 = (schema.tools ?? []).map((t) => `import { ${snakeToCamel(t.name)} } from './tools/${t.name}'`).join("\n");
|
|
2982
|
+
const toolList2 = (schema.tools ?? []).map((t) => snakeToCamel(t.name)).join(", ");
|
|
2983
|
+
return `import { createRuntime } from '@agentskit/runtime'
|
|
2984
|
+
${toolImports2}
|
|
2985
|
+
|
|
2986
|
+
export const agent = {
|
|
2987
|
+
name: '${schema.name}',
|
|
2988
|
+
systemPrompt: ${JSON.stringify(schema.systemPrompt ?? "")},
|
|
2989
|
+
tools: [${toolList2}],
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
export function createAgent(adapter: Parameters<typeof createRuntime>[0]['adapter']) {
|
|
2993
|
+
return createRuntime({
|
|
2994
|
+
adapter,
|
|
2995
|
+
systemPrompt: agent.systemPrompt,
|
|
2996
|
+
tools: agent.tools,
|
|
2997
|
+
})
|
|
2998
|
+
}
|
|
2999
|
+
`;
|
|
3000
|
+
}
|
|
3001
|
+
function readme(schema) {
|
|
3002
|
+
const lines = [];
|
|
3003
|
+
lines.push(`# ${schema.name}`);
|
|
3004
|
+
lines.push("");
|
|
3005
|
+
if (schema.description) lines.push(schema.description, "");
|
|
3006
|
+
lines.push(`## Model`);
|
|
3007
|
+
lines.push("");
|
|
3008
|
+
lines.push(`- Provider: \`${schema.model.provider}\``);
|
|
3009
|
+
if (schema.model.model) lines.push(`- Model: \`${schema.model.model}\``);
|
|
3010
|
+
lines.push("");
|
|
3011
|
+
if (schema.tools && schema.tools.length > 0) {
|
|
3012
|
+
lines.push("## Tools");
|
|
3013
|
+
lines.push("");
|
|
3014
|
+
for (const t of schema.tools) {
|
|
3015
|
+
lines.push(`- \`${t.name}\` \u2014 ${t.description ?? ""}`);
|
|
3016
|
+
}
|
|
3017
|
+
lines.push("");
|
|
3018
|
+
}
|
|
3019
|
+
if (schema.skills && schema.skills.length > 0) {
|
|
3020
|
+
lines.push("## Skills");
|
|
3021
|
+
lines.push("");
|
|
3022
|
+
for (const s of schema.skills) lines.push(`- ${s}`);
|
|
3023
|
+
lines.push("");
|
|
3024
|
+
}
|
|
3025
|
+
lines.push("## Generated by");
|
|
3026
|
+
lines.push("");
|
|
3027
|
+
lines.push('`npx agentskit ai "<description>"`');
|
|
3028
|
+
lines.push("");
|
|
3029
|
+
return lines.join("\n");
|
|
3030
|
+
}
|
|
3031
|
+
function scaffoldAgent(schema) {
|
|
3032
|
+
const files = [
|
|
3033
|
+
{ path: "agent.json", content: JSON.stringify(schema, null, 2) + "\n" },
|
|
3034
|
+
{ path: "agent.ts", content: indexTs(schema) },
|
|
3035
|
+
{ path: "README.md", content: readme(schema) }
|
|
3036
|
+
];
|
|
3037
|
+
for (const tool of schema.tools ?? []) {
|
|
3038
|
+
files.push({ path: `tools/${tool.name}.ts`, content: toolStub(tool) });
|
|
3039
|
+
}
|
|
3040
|
+
return files;
|
|
3041
|
+
}
|
|
3042
|
+
async function writeScaffold(files, outDir, opts = {}) {
|
|
3043
|
+
const { writeFile: writeFile2, mkdir: mkdir2, access } = await import('fs/promises');
|
|
3044
|
+
const { dirname, join: join5 } = await import('path');
|
|
3045
|
+
const written = [];
|
|
3046
|
+
for (const f of files) {
|
|
3047
|
+
const full = join5(outDir, f.path);
|
|
3048
|
+
await mkdir2(dirname(full), { recursive: true });
|
|
3049
|
+
if (!opts.overwrite) {
|
|
3050
|
+
try {
|
|
3051
|
+
await access(full);
|
|
3052
|
+
continue;
|
|
3053
|
+
} catch {
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
await writeFile2(full, f.content, "utf8");
|
|
3057
|
+
written.push(f.path);
|
|
3058
|
+
}
|
|
3059
|
+
return written;
|
|
3060
|
+
}
|
|
3061
|
+
var PLANNER_SYSTEM_PROMPT = `You design AI agents for the AgentsKit framework.
|
|
3062
|
+
Given a user's plain-language description, return a single JSON object
|
|
3063
|
+
matching the AgentsKit AgentSchema type. Do not include commentary or
|
|
3064
|
+
markdown fences \u2014 emit raw JSON only.
|
|
3065
|
+
|
|
3066
|
+
Schema:
|
|
3067
|
+
{
|
|
3068
|
+
"name": "kebab-or-snake-case",
|
|
3069
|
+
"description": "short summary",
|
|
3070
|
+
"systemPrompt": "you are...",
|
|
3071
|
+
"model": { "provider": "anthropic"|"openai"|"gemini"|..., "model": "..." },
|
|
3072
|
+
"tools": [{ "name": "search", "description": "...", "schema": {...}, "implementation": "fetch('/api/search?q=...')" }],
|
|
3073
|
+
"memory": { "kind": "inMemory"|"localStorage", "key": "..." },
|
|
3074
|
+
"skills": ["researcher", "critic"]
|
|
3075
|
+
}
|
|
3076
|
+
|
|
3077
|
+
Prefer fewer well-scoped tools over many overlapping ones. Name tools
|
|
3078
|
+
in snake_case.`;
|
|
3079
|
+
function extractJson(text) {
|
|
3080
|
+
const fenced = text.match(/```(?:json)?\s*([\s\S]+?)```/);
|
|
3081
|
+
const raw = fenced?.[1] ?? text;
|
|
3082
|
+
const start = raw.indexOf("{");
|
|
3083
|
+
const end = raw.lastIndexOf("}");
|
|
3084
|
+
if (start < 0 || end <= start) throw new Error("Planner response did not contain a JSON object");
|
|
3085
|
+
return raw.slice(start, end + 1);
|
|
3086
|
+
}
|
|
3087
|
+
function createAdapterPlanner(adapter) {
|
|
3088
|
+
return async (description) => {
|
|
3089
|
+
const messages = [
|
|
3090
|
+
{ id: "sys", role: "system", content: PLANNER_SYSTEM_PROMPT, status: "complete", createdAt: /* @__PURE__ */ new Date(0) },
|
|
3091
|
+
{ id: "user", role: "user", content: description, status: "complete", createdAt: /* @__PURE__ */ new Date(0) }
|
|
3092
|
+
];
|
|
3093
|
+
const request = { messages, context: { temperature: 0 } };
|
|
3094
|
+
const source = adapter.createSource(request);
|
|
3095
|
+
let text = "";
|
|
3096
|
+
for await (const chunk of source.stream()) {
|
|
3097
|
+
if (chunk.type === "text" && chunk.content) text += chunk.content;
|
|
3098
|
+
}
|
|
3099
|
+
const json = extractJson(text);
|
|
3100
|
+
return validateAgentSchema(JSON.parse(json));
|
|
3101
|
+
};
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3104
|
+
// src/commands/ai.ts
|
|
3105
|
+
function registerAiCommand(program) {
|
|
3106
|
+
program.command("ai <description...>").description("Generate an agent (config + tools + skill wiring) from a natural-language description.").option("-o, --out <dir>", "Output directory", "./my-agent").option("--provider <provider>", "Planner provider (openai | anthropic | ...)", "anthropic").option("--model <model>", "Planner model id").option("--api-key <key>", "API key (falls back to env)").option("--base-url <url>", "Override base URL (for OpenAI-compatible endpoints)").option("--overwrite", "Overwrite existing files", false).option("--dry-run", "Print the plan + files without writing", false).action(async (descriptionWords, options) => {
|
|
3107
|
+
const description = descriptionWords.join(" ").trim();
|
|
3108
|
+
if (!description) {
|
|
3109
|
+
process.stderr.write("agentskit ai: missing description.\n");
|
|
3110
|
+
process.exit(1);
|
|
3111
|
+
}
|
|
3112
|
+
const resolved = resolveChatProvider({
|
|
3113
|
+
provider: options.provider,
|
|
3114
|
+
model: options.model,
|
|
3115
|
+
apiKey: options.apiKey,
|
|
3116
|
+
baseUrl: options.baseUrl
|
|
3117
|
+
});
|
|
3118
|
+
const planner2 = createAdapterPlanner(resolved.adapter);
|
|
3119
|
+
process.stderr.write(`Planning agent for: "${description}"
|
|
3120
|
+
`);
|
|
3121
|
+
const schema = await planner2(description);
|
|
3122
|
+
const files = scaffoldAgent(schema);
|
|
3123
|
+
if (options.dryRun) {
|
|
3124
|
+
process.stdout.write(JSON.stringify({ schema, files: files.map((f) => f.path) }, null, 2) + "\n");
|
|
3125
|
+
return;
|
|
3126
|
+
}
|
|
3127
|
+
const written = await writeScaffold(files, options.out, { overwrite: options.overwrite });
|
|
3128
|
+
process.stderr.write(`Wrote ${written.length} file(s) to ${options.out}
|
|
3129
|
+
`);
|
|
3130
|
+
for (const f of written) process.stderr.write(` + ${f}
|
|
3131
|
+
`);
|
|
3132
|
+
});
|
|
3133
|
+
}
|
|
3134
|
+
|
|
2953
3135
|
// src/commands/index.ts
|
|
2954
3136
|
function createCli() {
|
|
2955
3137
|
const program = new Command();
|
|
@@ -2962,9 +3144,10 @@ function createCli() {
|
|
|
2962
3144
|
registerConfigCommand(program);
|
|
2963
3145
|
registerTunnelCommand(program);
|
|
2964
3146
|
registerRagCommand(program);
|
|
3147
|
+
registerAiCommand(program);
|
|
2965
3148
|
return program;
|
|
2966
3149
|
}
|
|
2967
3150
|
|
|
2968
3151
|
export { ChatApp, HookDispatcher, McpClient, applyPolicyToTool, applyPolicyToTools, bridgeMcpServers, buildRagFromConfig, computeCost, configHooksToHandlers, createCli, createOpenAiEmbedder, defaultPolicy, derivePreview, disposeMcpClients, evaluatePolicy, findLatestSession, findSession, forkSession, generateSessionId, getPricing, indexSources, listSessions, loadConfig, loadPlugins, mergePluginsIntoBundle, registerPricing, renameSession, renderChatHeader, renderReport, resolveChatProvider, resolveSession, runAgent, runDoctor, sessionFilePath, startDev, startTunnel, writeSessionMeta, writeStarterProject };
|
|
2969
|
-
//# sourceMappingURL=chunk-
|
|
2970
|
-
//# sourceMappingURL=chunk-
|
|
3152
|
+
//# sourceMappingURL=chunk-FLIR7BRS.js.map
|
|
3153
|
+
//# sourceMappingURL=chunk-FLIR7BRS.js.map
|