@alejandroroman/agent-kit 0.2.0 → 0.2.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.
File without changes
File without changes
@@ -109,6 +109,7 @@ async function _runAgentLoop(initialMessages, config, runSpan, tracer, runCtx) {
109
109
  // Prune images from old messages to save context tokens
110
110
  const prunedMessages = pruneImages(messages, 4);
111
111
  // LLM call span
112
+ config.onProgress?.("thinking");
112
113
  const llmSpan = tracer.startSpan("llm.call", undefined, iterCtx);
113
114
  let response;
114
115
  try {
@@ -194,6 +195,7 @@ async function _runAgentLoop(initialMessages, config, runSpan, tracer, runCtx) {
194
195
  log.error({ err, runId }, "failed to record agent run");
195
196
  }
196
197
  }
198
+ config.onProgress?.("complete");
197
199
  log.info({ label, stopReason: response.stopReason, iterations: iteration, inputTokens: totalUsage.inputTokens, outputTokens: totalUsage.outputTokens, elapsed }, "loop end");
198
200
  runSpan.setAttribute(ATTR.ITERATION, iteration);
199
201
  return {
@@ -219,6 +221,7 @@ async function _runAgentLoop(initialMessages, config, runSpan, tracer, runCtx) {
219
221
  else {
220
222
  const toolStart = Date.now();
221
223
  try {
224
+ config.onProgress?.("tool_use", call.name);
222
225
  result = await tool.execute(call.arguments);
223
226
  const toolElapsed = Date.now() - toolStart;
224
227
  log.debug({ label, iteration, tool: call.name, resultLength: result.length, snippet: truncate(result, 150), elapsed: toolElapsed }, "tool result");
@@ -2,6 +2,7 @@ import type { Tool } from "../tools/types.js";
2
2
  import type { ToolRegistry } from "../tools/registry.js";
3
3
  import type { TokenUsage } from "../llm/types.js";
4
4
  import type { UsageStore } from "../usage/store.js";
5
+ export type ProgressPhase = "thinking" | "tool_use" | "complete";
5
6
  export interface AgentConfig {
6
7
  model: string;
7
8
  fallbacks?: string[];
@@ -15,6 +16,7 @@ export interface AgentConfig {
15
16
  source?: string;
16
17
  maxToolResultSize?: number;
17
18
  compactionThreshold?: number;
19
+ onProgress?: (phase: ProgressPhase, detail?: string) => void;
18
20
  }
19
21
  export interface AgentResult {
20
22
  text: string;
@@ -1,100 +1,120 @@
1
- import * as readline from "readline";
1
+ import * as p from "@clack/prompts";
2
2
  import { runAgentLoop } from "../../agent/loop.js";
3
3
  import { ToolRegistry } from "../../tools/registry.js";
4
4
  import { createSetupTools } from "./tools.js";
5
5
  import { SETUP_SOUL, CREATE_SOUL } from "./soul.js";
6
6
  import { dateContext } from "../../text.js";
7
+ import { setLogLevel } from "../../logger.js";
8
+ const TOOL_LABELS = {
9
+ check_environment: "Checking environment...",
10
+ list_builtin_tools: "Looking at available tools...",
11
+ list_available_skills: "Scanning skills...",
12
+ save_agent: "Saving agent...",
13
+ create_skill: "Creating skill...",
14
+ add_cron_job: "Adding cron job...",
15
+ read_file: "Reading file...",
16
+ finish_setup: "Finishing up...",
17
+ };
7
18
  export async function runSetupAgent(opts) {
8
- // Ensure the API key is available for the Anthropic provider
9
19
  process.env.ANTHROPIC_API_KEY = opts.apiKey;
10
20
  const model = "anthropic:claude-sonnet-4-6";
11
- return new Promise((resolve) => {
12
- let finished = false;
13
- const toolRegistry = new ToolRegistry();
14
- const tools = createSetupTools({
15
- configPath: opts.configPath,
16
- dataDir: opts.dataDir,
17
- skillsDir: opts.skillsDir,
18
- basePath: opts.basePath,
19
- onFinish: (summary) => {
20
- finished = true;
21
- resolve(summary);
22
- },
23
- });
24
- for (const tool of tools) {
25
- toolRegistry.register(tool);
21
+ const prevLogLevel = process.env.LOG_LEVEL ?? "info";
22
+ setLogLevel("silent");
23
+ try {
24
+ return await _runSetupAgent(opts, model);
25
+ }
26
+ finally {
27
+ setLogLevel(prevLogLevel);
28
+ }
29
+ }
30
+ async function _runSetupAgent(opts, model) {
31
+ let finished = false;
32
+ let summary = "Setup cancelled.";
33
+ const spinner = p.spinner();
34
+ const toolRegistry = new ToolRegistry();
35
+ const tools = createSetupTools({
36
+ configPath: opts.configPath,
37
+ dataDir: opts.dataDir,
38
+ skillsDir: opts.skillsDir,
39
+ basePath: opts.basePath,
40
+ onFinish: (s) => {
41
+ finished = true;
42
+ summary = s;
43
+ },
44
+ });
45
+ for (const tool of tools) {
46
+ toolRegistry.register(tool);
47
+ }
48
+ const soul = opts.mode === "init" ? SETUP_SOUL : CREATE_SOUL;
49
+ const systemPrompt = [soul, dateContext()].join("\n\n");
50
+ const messages = [];
51
+ const onProgress = (phase, detail) => {
52
+ if (phase === "thinking") {
53
+ spinner.message("Thinking...");
26
54
  }
27
- const soul = opts.mode === "init" ? SETUP_SOUL : CREATE_SOUL;
28
- const systemPrompt = [soul, dateContext()].join("\n\n");
29
- const messages = [];
30
- const rl = readline.createInterface({
31
- input: process.stdin,
32
- output: process.stdout,
33
- });
34
- const ask = (prompt) => {
35
- if (finished) {
36
- rl.close();
37
- return;
38
- }
39
- rl.question(prompt ?? "You: ", async (input) => {
40
- const trimmed = input.trim();
41
- if (trimmed === "/quit" || trimmed === "/exit") {
42
- rl.close();
43
- resolve("Setup cancelled.");
44
- return;
45
- }
46
- if (!trimmed) {
47
- ask();
48
- return;
49
- }
50
- messages.push({ role: "user", content: trimmed });
51
- try {
52
- const result = await runAgentLoop(messages, {
53
- model,
54
- systemPrompt,
55
- toolRegistry,
56
- maxIterations: 30,
57
- source: "cli",
58
- });
59
- messages.push(...result.messages.slice(messages.length));
60
- if (!finished) {
61
- console.log(`\n${result.text}\n`);
62
- }
63
- }
64
- catch (err) {
65
- console.error(`\n Error: ${err instanceof Error ? err.message : err}\n`);
66
- }
67
- if (!finished) {
68
- ask();
69
- }
70
- else {
71
- rl.close();
72
- }
55
+ else if (phase === "tool_use") {
56
+ spinner.message(TOOL_LABELS[detail ?? ""] ?? "Working...");
57
+ }
58
+ };
59
+ const runWithSpinner = async (loopMessages, maxIterations) => {
60
+ spinner.start("Thinking...");
61
+ try {
62
+ const result = await runAgentLoop(loopMessages, {
63
+ model,
64
+ systemPrompt,
65
+ toolRegistry,
66
+ maxIterations,
67
+ source: "cli",
68
+ onProgress,
73
69
  });
74
- };
75
- // Kick off with an initial greeting from the agent
76
- (async () => {
77
- try {
78
- const greeting = opts.mode === "init"
79
- ? "The user just ran `agent-kit init`. Greet them, then call check_environment to see what's available. After that, ask what kind of agent they'd like to create first."
80
- : "The user wants to add a new agent to their existing setup. Greet them, call check_environment and list_available_skills to see the current state, then ask what kind of agent they'd like to create.";
81
- messages.push({ role: "user", content: greeting });
82
- const result = await runAgentLoop(messages, {
83
- model,
84
- systemPrompt,
85
- toolRegistry,
86
- maxIterations: 10,
87
- source: "cli",
88
- });
89
- messages.push(...result.messages.slice(messages.length));
90
- console.log(`\n${result.text}\n`);
91
- }
92
- catch (err) {
93
- console.error(`\n Error starting setup agent: ${err instanceof Error ? err.message : err}\n`);
94
- }
70
+ spinner.stop("");
71
+ return result;
72
+ }
73
+ catch (err) {
74
+ spinner.stop("Error");
75
+ throw err;
76
+ }
77
+ };
78
+ // Greeting
79
+ try {
80
+ const greeting = opts.mode === "init"
81
+ ? "The user just ran `agent-kit init`. Greet them, then call check_environment to see what's available. After that, ask what kind of agent they'd like to create first."
82
+ : "The user wants to add a new agent to their existing setup. Greet them, call check_environment and list_available_skills to see the current state, then ask what kind of agent they'd like to create.";
83
+ messages.push({ role: "user", content: greeting });
84
+ const result = await runWithSpinner(messages, 10);
85
+ messages.push(...result.messages.slice(messages.length));
86
+ console.log(`\n${result.text}\n`);
87
+ }
88
+ catch (err) {
89
+ console.error(`\n Error starting setup agent: ${err instanceof Error ? err.message : err}\n`);
90
+ return summary;
91
+ }
92
+ // Conversation loop using clack prompts (no readline — avoids stdin conflict with spinner)
93
+ while (!finished) {
94
+ const input = await p.text({
95
+ message: "You",
96
+ placeholder: "Type your response... (/quit to exit)",
97
+ });
98
+ if (p.isCancel(input)) {
99
+ return "Setup cancelled.";
100
+ }
101
+ const trimmed = input.trim();
102
+ if (trimmed === "/quit" || trimmed === "/exit") {
103
+ return "Setup cancelled.";
104
+ }
105
+ if (!trimmed)
106
+ continue;
107
+ messages.push({ role: "user", content: trimmed });
108
+ try {
109
+ const result = await runWithSpinner(messages, 30);
110
+ messages.push(...result.messages.slice(messages.length));
95
111
  if (!finished) {
96
- ask();
112
+ console.log(`\n${result.text}\n`);
97
113
  }
98
- })();
99
- });
114
+ }
115
+ catch (err) {
116
+ console.error(`\n Error: ${err instanceof Error ? err.message : err}\n`);
117
+ }
118
+ }
119
+ return summary;
100
120
  }
package/dist/cli.js CHANGED
File without changes
package/dist/logger.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  import pino from "pino";
2
2
  export declare function createLogger(name: string): pino.Logger<never, boolean>;
3
+ export declare function setLogLevel(level: pino.Level | "silent"): void;
package/dist/logger.js CHANGED
@@ -21,3 +21,6 @@ const root = pino({
21
21
  export function createLogger(name) {
22
22
  return root.child({ component: name });
23
23
  }
24
+ export function setLogLevel(level) {
25
+ root.level = level;
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alejandroroman/agent-kit",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "exports": {
@@ -12,6 +12,19 @@
12
12
  "files": [
13
13
  "dist/"
14
14
  ],
15
+ "scripts": {
16
+ "build": "pnpm --filter @agent-kit/memory run build && tsc && cp -r packages/memory/dist dist/_memory && node -e \"const f='dist/tools/builtin/memory.js',s=require('fs');s.writeFileSync(f,s.readFileSync(f,'utf8').replaceAll('from \\\"@agent-kit/memory\\\"','from \\\"../../_memory/index.js\\\"'))\"",
17
+ "prepublishOnly": "pnpm run build",
18
+ "cli": "tsx src/cli.ts",
19
+ "dev": "doppler run -- tsx src/index.ts",
20
+ "dev:local": "tsx src/index.ts",
21
+ "memory": "doppler run -- pnpm --filter @agent-kit/memory start",
22
+ "ledger": "doppler run -- pnpm --filter @agent-kit/ledger ledger",
23
+ "dev:dashboard": "pnpm --filter @agent-kit/dashboard dev",
24
+ "agent:validate": "tsx src/scripts/validate-agent-cli.ts",
25
+ "test": "vitest run",
26
+ "test:watch": "vitest"
27
+ },
15
28
  "dependencies": {
16
29
  "@anthropic-ai/sdk": "^0.78.0",
17
30
  "@clack/prompts": "^1.0.1",
@@ -35,25 +48,13 @@
35
48
  "zod": "^4.3.6"
36
49
  },
37
50
  "devDependencies": {
51
+ "@agent-kit/memory": "workspace:*",
38
52
  "@types/better-sqlite3": "^7.6.13",
39
53
  "@types/node": "^25.3.0",
40
54
  "@types/node-cron": "^3.0.11",
41
55
  "@types/sharp": "^0.32.0",
42
56
  "tsx": "^4.21.0",
43
57
  "typescript": "^5.9.3",
44
- "vitest": "^4.0.18",
45
- "@agent-kit/memory": "0.1.0"
46
- },
47
- "scripts": {
48
- "build": "pnpm --filter @agent-kit/memory run build && tsc && cp -r packages/memory/dist dist/_memory && node -e \"const f='dist/tools/builtin/memory.js',s=require('fs');s.writeFileSync(f,s.readFileSync(f,'utf8').replaceAll('from \\\"@agent-kit/memory\\\"','from \\\"../../_memory/index.js\\\"'))\"",
49
- "cli": "tsx src/cli.ts",
50
- "dev": "doppler run -- tsx src/index.ts",
51
- "dev:local": "tsx src/index.ts",
52
- "memory": "doppler run -- pnpm --filter @agent-kit/memory start",
53
- "ledger": "doppler run -- pnpm --filter @agent-kit/ledger ledger",
54
- "dev:dashboard": "pnpm --filter @agent-kit/dashboard dev",
55
- "agent:validate": "tsx src/scripts/validate-agent-cli.ts",
56
- "test": "vitest run",
57
- "test:watch": "vitest"
58
+ "vitest": "^4.0.18"
58
59
  }
59
- }
60
+ }