@alejandroroman/agent-kit 0.2.0 → 0.2.1

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,15 +1,37 @@
1
1
  import * as readline from "readline";
2
+ import * as p from "@clack/prompts";
2
3
  import { runAgentLoop } from "../../agent/loop.js";
3
4
  import { ToolRegistry } from "../../tools/registry.js";
4
5
  import { createSetupTools } from "./tools.js";
5
6
  import { SETUP_SOUL, CREATE_SOUL } from "./soul.js";
6
7
  import { dateContext } from "../../text.js";
8
+ import { setLogLevel } from "../../logger.js";
9
+ const TOOL_LABELS = {
10
+ check_environment: "Checking environment...",
11
+ list_builtin_tools: "Looking at available tools...",
12
+ list_available_skills: "Scanning skills...",
13
+ save_agent: "Saving agent...",
14
+ create_skill: "Creating skill...",
15
+ add_cron_job: "Adding cron job...",
16
+ read_file: "Reading file...",
17
+ finish_setup: "Finishing up...",
18
+ };
7
19
  export async function runSetupAgent(opts) {
8
- // Ensure the API key is available for the Anthropic provider
9
20
  process.env.ANTHROPIC_API_KEY = opts.apiKey;
10
21
  const model = "anthropic:claude-sonnet-4-6";
22
+ const prevLogLevel = process.env.LOG_LEVEL ?? "info";
23
+ setLogLevel("silent");
24
+ try {
25
+ return await _runSetupAgent(opts, model);
26
+ }
27
+ finally {
28
+ setLogLevel(prevLogLevel);
29
+ }
30
+ }
31
+ async function _runSetupAgent(opts, model) {
11
32
  return new Promise((resolve) => {
12
33
  let finished = false;
34
+ const spinner = p.spinner();
13
35
  const toolRegistry = new ToolRegistry();
14
36
  const tools = createSetupTools({
15
37
  configPath: opts.configPath,
@@ -27,19 +49,52 @@ export async function runSetupAgent(opts) {
27
49
  const soul = opts.mode === "init" ? SETUP_SOUL : CREATE_SOUL;
28
50
  const systemPrompt = [soul, dateContext()].join("\n\n");
29
51
  const messages = [];
52
+ const onProgress = (phase, detail) => {
53
+ if (phase === "thinking") {
54
+ spinner.message("Thinking...");
55
+ }
56
+ else if (phase === "tool_use") {
57
+ spinner.message(TOOL_LABELS[detail ?? ""] ?? "Working...");
58
+ }
59
+ // "complete" phase — spinner will be stopped by the caller
60
+ };
61
+ const runWithSpinner = async (loopMessages, maxIterations) => {
62
+ spinner.start("Thinking...");
63
+ try {
64
+ const result = await runAgentLoop(loopMessages, {
65
+ model,
66
+ systemPrompt,
67
+ toolRegistry,
68
+ maxIterations,
69
+ source: "cli",
70
+ onProgress,
71
+ });
72
+ spinner.stop("");
73
+ return result;
74
+ }
75
+ catch (err) {
76
+ spinner.stop("Error");
77
+ throw err;
78
+ }
79
+ };
30
80
  const rl = readline.createInterface({
31
81
  input: process.stdin,
32
82
  output: process.stdout,
33
83
  });
84
+ const cleanup = async () => {
85
+ rl.close();
86
+ process.stdin.pause();
87
+ await new Promise((r) => setTimeout(r, 200));
88
+ };
34
89
  const ask = (prompt) => {
35
90
  if (finished) {
36
- rl.close();
91
+ cleanup();
37
92
  return;
38
93
  }
39
94
  rl.question(prompt ?? "You: ", async (input) => {
40
95
  const trimmed = input.trim();
41
96
  if (trimmed === "/quit" || trimmed === "/exit") {
42
- rl.close();
97
+ await cleanup();
43
98
  resolve("Setup cancelled.");
44
99
  return;
45
100
  }
@@ -49,13 +104,7 @@ export async function runSetupAgent(opts) {
49
104
  }
50
105
  messages.push({ role: "user", content: trimmed });
51
106
  try {
52
- const result = await runAgentLoop(messages, {
53
- model,
54
- systemPrompt,
55
- toolRegistry,
56
- maxIterations: 30,
57
- source: "cli",
58
- });
107
+ const result = await runWithSpinner(messages, 30);
59
108
  messages.push(...result.messages.slice(messages.length));
60
109
  if (!finished) {
61
110
  console.log(`\n${result.text}\n`);
@@ -68,7 +117,7 @@ export async function runSetupAgent(opts) {
68
117
  ask();
69
118
  }
70
119
  else {
71
- rl.close();
120
+ await cleanup();
72
121
  }
73
122
  });
74
123
  };
@@ -79,13 +128,7 @@ export async function runSetupAgent(opts) {
79
128
  ? "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
129
  : "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
130
  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
- });
131
+ const result = await runWithSpinner(messages, 10);
89
132
  messages.push(...result.messages.slice(messages.length));
90
133
  console.log(`\n${result.text}\n`);
91
134
  }
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.1",
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
+ }