npm package: @luisss/zero
Description: Zero Agent — AI coding assistant in your terminal
Latest version: 0.0.6

# @luisss/zero

> Atomic AI Agent Framework — 用原子化的方式构建 AI Agent

Zero 是一个轻量级的 TypeScript AI Agent 框架，提供 **原子化的模块设计** 和 **开箱即用的终端 CLI**。

- **原子化架构**：Agent、Adapter、Tool、Prompt 各自独立，自由组合
- **ReAct 循环**：内置 Think → Act → Observe 循环，自动调度工具
- **流式事件**：所有输出均为 `AsyncIterable<AgentEvent>`，逐步消费
- **多模型支持**：Claude / OpenAI / 任何 OpenAI 兼容 API
- **12 个内置工具**：文件读写、命令执行、代码搜索、网络请求等
- **终端 UI**：基于 ink 的美观终端界面，开箱即用

## 快速开始

### 作为 CLI 使用

```bash
npm install -g @luisss/zero
zero
```

首次运行会引导你配置 API Key、模型和端点，配置保存在 `~/.zero/config.json`。

```bash
zero            # 启动 Agent
zero config     # 修改配置
zero --help     # 帮助
```

### 作为 SDK 使用

```bash
npm install @luisss/zero
```

## 原子化 Agent

Zero 的核心理念是 **原子化**：每个模块都是独立的、可替换的、可组合的。

```
┌─────────────────────────────────────────┐
│              createAgent()              │  ← 一行创建，开箱即用
├─────────┬───────────┬───────────────────┤
│ Adapter │ ToolMgr   │ PromptBuilder     │  ← 各自独立，自由组合
│ (LLM)   │ (Tools)   │ (System Prompt)   │
├─────────┴───────────┴───────────────────┤
│            ReactAgent                   │  ← ReAct 循环引擎
│         Think → Act → Observe           │
├─────────────────────────────────────────┤
│         AsyncIterable<AgentEvent>       │  ← 统一的流式事件
└─────────────────────────────────────────┘
```

### Demo 1：最简 Agent

```typescript
import { createAgent } from '@luisss/zero';

const agent = createAgent({
  apiKey: process.env.ANTHROPIC_API_KEY!,
  model: 'claude-sonnet-4.6',
});

// 非流式
const reply = await agent.chat('用 TypeScript 写一个快速排序');
console.log(reply);
```

### Demo 2：流式事件消费

```typescript
import { createAgent } from '@luisss/zero';

const agent = createAgent({
  apiKey: process.env.OPENAI_API_KEY!,
  model: 'gpt-4o',
  basePrompt: '你是一个专业的编程助手。',
  maxTurns: 10,
});

for await (const event of agent.chatStream('帮我创建一个 Express 项目')) {
  switch (event.type) {
    case 'text_delta':
      process.stdout.write(event.text);
      break;
    case 'tool_call_start':
      console.log(`\n🔧 ${event.toolName}...`);
      break;
    case 'tool_call_done':
      console.log(`   ${event.result.isError ? '✗' : '✓'} done`);
      break;
    case 'done':
      console.log(`\n✅ ${event.totalTurns} turns, ${event.totalUsage.outputTokens} tokens`);
      break;
  }
}
```

更多事件，参考AgentEvent 类型定义。

### Demo 3：System Prompt 段落扩展

```typescript
import { createAgent } from '@luisss/zero';

const agent = createAgent({
  apiKey: process.env.ANTHROPIC_API_KEY!,
  model: 'claude-sonnet-4-20250514',
  basePrompt: '你是一个全栈开发助手。',

  // systemSections：在 basePrompt + 工具指南之后追加自定义段落
  // 支持静态字符串和函数（每轮 build 时惰性计算）
  systemSections: [
    // 静态段：编码规范
    `## Coding Standards
- Use TypeScript strict mode
- Prefer functional components with hooks
- All exports must be named (no default exports)
- Tests co-located with source files`,

    // 动态段：每轮读取最新的 git 状态
    () => {
      const { execSync } = require('child_process');
      try {
        const branch = execSync('git branch --show-current', { encoding: 'utf-8' }).trim();
        const status = execSync('git diff --stat HEAD', { encoding: 'utf-8' }).trim();
        return `## Git Context\nBranch: ${branch}\n${status || 'Working tree clean'}`;
      } catch {
        return ''; // 非 git 仓库时返回空，自动跳过
      }
    },

    // 动态段：当前时间（每轮更新）
    () => `Current time: ${new Date().toLocaleString()}`,
  ],
});

const reply = await agent.chat('帮我 review 最近的改动');
```

最终 system prompt 结构：

```
1. basePrompt        — "你是一个全栈开发助手。"
2. ## Tools           — 自动生成的工具列表和使用规范
3. ## Coding Standards — 你的静态段
4. ## Git Context      — 每轮动态计算
5. Current time: ...   — 每轮动态计算
6. ## Environment      — 自动生成的 OS/CWD/Date
```

### Demo 4：自定义工具

```typescript
import { createAgent, buildTool } from '@luisss/zero';

const WeatherTool = buildTool<{ city: string }>({
  name: 'get_weather',
  inputSchema: {
    type: 'object',
    properties: {
      city: { type: 'string', description: '城市名称' },
    },
    required: ['city'],
  },
  prompt: () => '查询指定城市的天气信息',
  isReadOnly: () => true,

  async call({ city }) {
    const res = await fetch(`https://wttr.in/${city}?format=j1`);
    const data = await res.json();
    return { content: JSON.stringify(data.current_condition[0]) };
  },
});

const agent = createAgent({
  apiKey: process.env.ANTHROPIC_API_KEY!,
  model: 'claude-sonnet-4-20250514',
  tools: [WeatherTool],               // 追加自定义工具
  builtinToolNames: ['bash', 'read'],  // 可选：只保留需要的内置工具
});

const reply = await agent.chat('北京今天天气怎么样？');
```

### Demo 5：工具中间件

可以做到工具拦截，耗时统计、log等

```typescript
import { createAgent } from '@luisss/zero';

const agent = createAgent({
  apiKey: process.env.ANTHROPIC_API_KEY!,
  model: 'claude-sonnet-4-20250514',
});

// 洋葱模型：注册顺序执行，可拦截、修改、计时
agent.use(async (ctx, next) => {
  const start = Date.now();
  const result = await next();
  console.log(`⏱ ${ctx.toolName} took ${Date.now() - start}ms`);
  return result;
});

// 危险命令拦截
agent.use(async (ctx, next) => {
  if (ctx.toolName === 'bash') {
    const cmd = String(ctx.input.command ?? '');
    if (/rm\s+-rf/.test(cmd)) {
      return { content: 'Blocked: dangerous command', isError: true };
    }
  }
  return next();
});

// 大结果自动截断
agent.use(async (ctx, next) => {
  const result = await next();
  if (typeof result.content === 'string' && result.content.length > 50000) {
    return { content: result.content.slice(0, 50000) + '\n[truncated]' };
  }
  return result;
});

await agent.chat('列出当前目录的文件');
```

### Demo 6：上下文注入

```typescript
const agent = createAgent({ ... });

// 注入项目上下文（不放 system prompt，放 messages 中）
agent.injectMessage(`<system-reminder>
# Project: my-app
- Language: TypeScript
- Framework: React + Vite
- Style: Tailwind CSS
</system-reminder>`);

const reply = await agent.chat('帮我写一个登录页面');
```

该api的功能是往上下文信息中写一条消息，也就是llm-api中的messages字段。
你可能会想这个有什么用，实际上claude-code的skill的注入，就是通过上下文来注入的，这种方式的好处就是不污染system字段。

### Demo 7：自定义上下文压缩策略

```typescript
import { createAgent } from '@luisss/zero';

// 默认行为：头尾截断（无需配置）
const agent = createAgent({ apiKey, model });

// 自定义：用便宜模型做摘要
const agent = createAgent({
  apiKey: process.env.ANTHROPIC_API_KEY!,
  model: 'claude-sonnet-4-20250514',
  compactStrategy: async (adapter) => {
    const snapshot = adapter.getContextSnapshot();
    // 调用便宜模型生成摘要（不会污染当前 adapter 的消息历史）
    const summary = await cheapLLM.chat('请用 500 字概括以下对话：\n' + snapshot);
    adapter.compact(summary);
  },
});

// 永不压缩（适合短对话场景）
const agent = createAgent({
  apiKey, model,
  compactStrategy: async () => { /* noop */ },
});
```

当上下文 token 超过阈值（默认 80K）或遇到 context overflow 时，Agent 会调用 `compactStrategy`。
不传则使用默认的头尾截断策略。

### Demo 8：主动管理上下文

```typescript
import { createAgent } from '@luisss/zero';

const agent = createAgent({
  apiKey: process.env.ANTHROPIC_API_KEY!,
  model: 'claude-sonnet-4-20250514',
});

// 多轮对话后查看当前 token 用量
await agent.chat('帮我分析这个项目的架构');
await agent.chat('再详细说说 service 层的设计');

console.log(agent.getContextTokenCount()); // ~15000

// 手动触发压缩（使用配置的 compactStrategy，或默认头尾截断）
await agent.compact();

console.log(agent.getContextTokenCount()); // 压缩后大幅减少

// 压缩后继续对话，Agent 仍持有摘要上下文
await agent.chat('基于刚才的分析，帮我写一个重构方案');
```

也可以自己判断时机：

```typescript
// 每轮对话后检查，超阈值就主动压缩
for (const task of tasks) {
  if (agent.getContextTokenCount() > 40000) {
    await agent.compact();
  }
  await agent.chat(task);
}
```

## 内置工具

| 工具 | 名称 | 说明 |
|------|------|------|
| 📖 | `read` | 读取文件内容 |
| ✏️ | `write` | 写入文件 |
| 🔧 | `edit` | 精确编辑文件（搜索替换） |
| 📂 | `ls` | 列出目录内容 |
| 💬 | `send` | 向用户发送消息 |
| 🖥️ | `bash` | 执行 Shell 命令 |
| 🔍 | `glob` | 按模式搜索文件 |
| 🔎 | `grep` | 按内容搜索文件 |
| 🌐 | `web_fetch` | 抓取网页内容 |
| 👁️ | `vision` | 图片识别 |
| ⚙️ | `env_config` | 环境配置管理 |
| ⏰ | `scheduler` | 定时任务调度 |

## 事件类型

Agent 的所有输出都是 `AsyncIterable<AgentEvent>`：

| 事件 | 说明 |
|------|------|
| `run_start` | 运行开始 |
| `thinking` | 开始新一轮思考 |
| `text_delta` | 文本增量输出 |
| `text_done` | 本轮文本完成 |
| `tool_call_start` | 工具调用开始 |
| `tool_call_done` | 工具调用完成 |
| `turn_usage` | 本轮 Token 用量 |
| `context_overflow` | 上下文溢出，自动压缩 |
| `retry` | LLM 错误，自动重试 |
| `done` | 运行结束 |
| `error` | 错误 |

## Zero CLI

Zero 自带一个美观的终端 Agent 界面：

```
⚡ Zero Agent Setup
────────────────────────────────────
First time setup — configure your LLM provider
Press Esc to cancel

  ✓ API Key: ••••••••
  ✓ Model: claude-sonnet-4-20250514
  ❯ Base URL: https://api.anthropic.com
  
Step 3/3
```

### 命令

```bash
zero            # 启动 Agent（首次自动引导配置）
zero config     # 修改配置（API Key / Model / Base URL）
zero --version  # 查看版本
zero --help     # 帮助信息
```

### 配置文件

配置保存在 `~/.zero/config.json`：

```json
{
  "apiKey": "sk-...",
  "model": "claude-sonnet-4-20250514",
  "baseURL": "https://api.anthropic.com"
}
```

### 日志

运行日志自动记录到 `~/.zero/logs/`，每个进程独立文件，不会冲突。

使用 `/clear` 重置对话，`/exit` 退出。

## License

MIT