pigpig-agent 1.0.0
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/.skills/code-review/SKILL.md +42 -0
- package/dist/agent/loop-detection.js +135 -0
- package/dist/agent/loop.js +123 -0
- package/dist/agent/retry.js +39 -0
- package/dist/agents/registry.js +59 -0
- package/dist/agents/spawn.js +124 -0
- package/dist/agents/types.js +5 -0
- package/dist/commands/agent.js +33 -0
- package/dist/commands/context.js +27 -0
- package/dist/commands/cron.js +38 -0
- package/dist/commands/debug.js +44 -0
- package/dist/commands/dream.js +36 -0
- package/dist/commands/index.js +10 -0
- package/dist/commands/memory.js +40 -0
- package/dist/commands/plugin.js +73 -0
- package/dist/commands/rag.js +25 -0
- package/dist/commands/security.js +44 -0
- package/dist/commands/skill.js +84 -0
- package/dist/config/init.js +69 -0
- package/dist/config/loader.js +52 -0
- package/dist/config/schema.js +55 -0
- package/dist/context/compressor.js +165 -0
- package/dist/context/defense.js +201 -0
- package/dist/context/prompt-builder.js +56 -0
- package/dist/context/prompt-pipes.js +14 -0
- package/dist/context/tool-result-output.js +25 -0
- package/dist/context/view.js +185 -0
- package/dist/cron/parser.js +27 -0
- package/dist/cron/service.js +211 -0
- package/dist/cron/store.js +53 -0
- package/dist/cron/types.js +1 -0
- package/dist/index.js +9 -0
- package/dist/main.js +270 -0
- package/dist/memory/store.js +175 -0
- package/dist/memory/validator.js +62 -0
- package/dist/mock-model.js +534 -0
- package/dist/plugins/manager.js +97 -0
- package/dist/plugins/supabase-plugin.js +111 -0
- package/dist/plugins/types.js +1 -0
- package/dist/rag/chunker.js +54 -0
- package/dist/rag/embedder.js +53 -0
- package/dist/rag/search.js +123 -0
- package/dist/rag/sqlite-store.js +195 -0
- package/dist/rag/store.js +29 -0
- package/dist/security/bash-classifier.js +39 -0
- package/dist/security/hook.js +53 -0
- package/dist/security/roles.js +16 -0
- package/dist/session/store.js +60 -0
- package/dist/skills/loader.js +100 -0
- package/dist/tools/cron-tools.js +94 -0
- package/dist/tools/file-tools.js +115 -0
- package/dist/tools/index.js +17 -0
- package/dist/tools/mcp-client.js +100 -0
- package/dist/tools/memory-tools.js +81 -0
- package/dist/tools/rag-tools.js +54 -0
- package/dist/tools/registry.js +270 -0
- package/dist/tools/search-tools.js +116 -0
- package/dist/tools/shell-tools.js +39 -0
- package/dist/tools/spawn-tools.js +35 -0
- package/dist/tools/tool-search.js +17 -0
- package/dist/tools/web-search.js +150 -0
- package/dist/usage/tracker.js +83 -0
- package/package.json +55 -0
- package/readme.md +131 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { appendFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
export const PRICE_TABLE = {
|
|
4
|
+
'claude-sonnet-4-6': { input: 3.00, output: 15.00, cacheWrite: 3.75, cacheRead: 0.30 },
|
|
5
|
+
'gpt-5': { input: 1.25, output: 10.00, cacheWrite: 1.25, cacheRead: 0.125 },
|
|
6
|
+
'deepseek-v4-pro': { input: 9.00, output: 27.00, cacheWrite: 1.80, cacheRead: 0.30 },
|
|
7
|
+
'qwen3.8-max': { input: 2.00, output: 6.00, cacheWrite: 2.50, cacheRead: 0.25 },
|
|
8
|
+
'qwen3.8-flash': { input: 0.75, output: 2.00, cacheWrite: 1.00, cacheRead: 0.10 },
|
|
9
|
+
'glm-5': { input: 0.15, output: 0.47, cacheWrite: 0.23, cacheRead: 0.018 },
|
|
10
|
+
'mock-model': { input: 0, output: 0, cacheWrite: 0, cacheRead: 0 },
|
|
11
|
+
};
|
|
12
|
+
// 把 AI SDK 返回的 usage 对象,规范分成四类 token
|
|
13
|
+
export function normalizeUsage(usage, context = {}) {
|
|
14
|
+
if (!usage)
|
|
15
|
+
return { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 };
|
|
16
|
+
const cacheRead = usage.cachedInputTokens ?? 0; // AI SDK 标准字段
|
|
17
|
+
const cacheWrite = usage.cacheCreationInputTokens // Anthropic SDK 直接挂顶层
|
|
18
|
+
?? context.providerMetadata?.anthropic?.cacheCreationInputTokens // AI SDK provider 元数据 兼容 Anthropic SDK 的 cacheCreationInputTokens 字段
|
|
19
|
+
?? 0;
|
|
20
|
+
const rawInputTokens = usage.inputTokens ?? 0;
|
|
21
|
+
const inputTokens = context.provider?.startsWith('openai') // 兼容 OpenAI SDK 的 inputTokens 字段
|
|
22
|
+
? Math.max(0, rawInputTokens - cacheRead)
|
|
23
|
+
: rawInputTokens;
|
|
24
|
+
return {
|
|
25
|
+
inputTokens,
|
|
26
|
+
outputTokens: usage.outputTokens ?? 0,
|
|
27
|
+
cacheReadTokens: cacheRead,
|
|
28
|
+
cacheWriteTokens: cacheWrite,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export function computeCost(model, usage) {
|
|
32
|
+
const p = PRICE_TABLE[model] || PRICE_TABLE['mock-model'];
|
|
33
|
+
return ((usage.inputTokens * p.input
|
|
34
|
+
+ usage.outputTokens * p.output
|
|
35
|
+
+ usage.cacheReadTokens * p.cacheRead
|
|
36
|
+
+ usage.cacheWriteTokens * p.cacheWrite)
|
|
37
|
+
/ 1_000_000);
|
|
38
|
+
}
|
|
39
|
+
// 按价格表做每一步的价格计算
|
|
40
|
+
export class UsageTracker {
|
|
41
|
+
steps = [];
|
|
42
|
+
logPath;
|
|
43
|
+
constructor(logPath) {
|
|
44
|
+
this.logPath = logPath;
|
|
45
|
+
if (logPath)
|
|
46
|
+
mkdirSync(dirname(logPath), { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
record(model, usage) {
|
|
49
|
+
const cost = computeCost(model, usage);
|
|
50
|
+
const record = { ts: Date.now(), model, cost, ...usage };
|
|
51
|
+
this.steps.push(record);
|
|
52
|
+
if (this.logPath) {
|
|
53
|
+
appendFileSync(this.logPath, JSON.stringify(record) + '\n');
|
|
54
|
+
}
|
|
55
|
+
return record;
|
|
56
|
+
}
|
|
57
|
+
totals() {
|
|
58
|
+
const t = this.steps.reduce((a, s) => ({
|
|
59
|
+
inputTokens: a.inputTokens + s.inputTokens,
|
|
60
|
+
outputTokens: a.outputTokens + s.outputTokens,
|
|
61
|
+
cacheReadTokens: a.cacheReadTokens + s.cacheReadTokens,
|
|
62
|
+
cacheWriteTokens: a.cacheWriteTokens + s.cacheWriteTokens,
|
|
63
|
+
cost: a.cost + s.cost,
|
|
64
|
+
}), { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, cost: 0 });
|
|
65
|
+
const totalInputLike = t.inputTokens + t.cacheReadTokens + t.cacheWriteTokens;
|
|
66
|
+
const hitRate = totalInputLike > 0 ? t.cacheReadTokens / totalInputLike : 0;
|
|
67
|
+
// 没有 cache 时的"假想成本":把所有 input-like token 当成 miss 全付
|
|
68
|
+
const baselineCost = (() => {
|
|
69
|
+
let c = 0;
|
|
70
|
+
for (const s of this.steps) {
|
|
71
|
+
const p = PRICE_TABLE[s.model] || PRICE_TABLE['mock-model'];
|
|
72
|
+
const inputLike = s.inputTokens + s.cacheReadTokens + s.cacheWriteTokens;
|
|
73
|
+
c += (inputLike * p.input) / 1_000_000;
|
|
74
|
+
c += (s.outputTokens * p.output) / 1_000_000;
|
|
75
|
+
}
|
|
76
|
+
return c;
|
|
77
|
+
})();
|
|
78
|
+
return { ...t, hitRate, baselineCost, savedCost: baselineCost - t.cost, steps: this.steps.length };
|
|
79
|
+
}
|
|
80
|
+
recent(n) {
|
|
81
|
+
return this.steps.slice(-n);
|
|
82
|
+
}
|
|
83
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pigpig-agent",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A terminal-first AI agent with tools, MCP, memory, RAG, scheduled tasks, and context management.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"pigpig-agent": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
".skills",
|
|
12
|
+
"readme.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc -p tsconfig.json",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"prepack": "tsc -p tsconfig.json",
|
|
18
|
+
"start": "tsx src/index.ts",
|
|
19
|
+
"init": "tsx src/index.ts init",
|
|
20
|
+
"continue": "tsx src/index.ts --continue"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"ai",
|
|
24
|
+
"agent",
|
|
25
|
+
"cli",
|
|
26
|
+
"terminal",
|
|
27
|
+
"mcp",
|
|
28
|
+
"rag"
|
|
29
|
+
],
|
|
30
|
+
"author": "PigPig Agent",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20"
|
|
34
|
+
},
|
|
35
|
+
"type": "module",
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/better-sqlite3": "^9.6.0",
|
|
38
|
+
"@types/json-schema": "^7.0.15",
|
|
39
|
+
"@types/node": "^26.2.0",
|
|
40
|
+
"@types/turndown": "^5.0.6",
|
|
41
|
+
"tsx": "^4.23.12",
|
|
42
|
+
"typescript": "^7.0.2"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@ai-sdk/openai": "^4.0.46",
|
|
46
|
+
"ai": "^7.0.77",
|
|
47
|
+
"better-sqlite3": "^13.0.3",
|
|
48
|
+
"croner": "^10.0.1",
|
|
49
|
+
"dotenv": "^17.4.2",
|
|
50
|
+
"fast-glob": "^3.3.3",
|
|
51
|
+
"sqlite-vec": "^0.1.9",
|
|
52
|
+
"turndown": "^7.2.4",
|
|
53
|
+
"zod": "^4.5.4"
|
|
54
|
+
}
|
|
55
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# PigPig Agent
|
|
2
|
+
|
|
3
|
+
PigPig Agent 是一个运行在终端里的 AI Agent,支持模型对话、工具调用、MCP、记忆、RAG、定时任务和上下文管理。
|
|
4
|
+
|
|
5
|
+
## 环境要求
|
|
6
|
+
|
|
7
|
+
- Node.js 20 或更高版本
|
|
8
|
+
- npm 10 或更高版本
|
|
9
|
+
- pnpm 11.10 或更高版本,仅当需要使用 GitHub MCP 工具时安装
|
|
10
|
+
|
|
11
|
+
检查环境:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
node -v
|
|
15
|
+
npm -v
|
|
16
|
+
pnpm -v
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 安装
|
|
20
|
+
|
|
21
|
+
全局安装:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g pigpig-agent
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
安装完成后会得到一个终端命令:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pigpig-agent
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 首次使用
|
|
34
|
+
|
|
35
|
+
### 1. 初始化配置
|
|
36
|
+
|
|
37
|
+
建议先创建一个专门的工作目录,然后在这个目录里初始化:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
mkdir pigpig-agent
|
|
41
|
+
cd pigpig-agent
|
|
42
|
+
pigpig-agent init
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
初始化向导会让你选择:
|
|
46
|
+
|
|
47
|
+
- 模型:`glm-5`、`qwen-turbo-latest` 或 `qwen-max-latest`
|
|
48
|
+
- DashScope API Key
|
|
49
|
+
- 子 Agent 最大并发数
|
|
50
|
+
|
|
51
|
+
完成后会生成:
|
|
52
|
+
|
|
53
|
+
- `pigpig-agent.config.json`:Agent 配置文件
|
|
54
|
+
- `.env`:如果你在向导中输入了 API Key
|
|
55
|
+
|
|
56
|
+
### 2. 启动 Agent
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pigpig-agent
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
看到 `You:` 提示后,直接输入问题或任务即可。
|
|
63
|
+
|
|
64
|
+
退出:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
exit
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## 配置 API Key
|
|
71
|
+
|
|
72
|
+
如果你没有在初始化向导中输入 API Key,可以手动创建 `.env` 文件:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
DASHSCOPE_API_KEY=your-dashscope-api-key
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
可选配置:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
GITHUB_PERSONAL_ACCESS_TOKEN=your-github-token
|
|
82
|
+
TAVILY_API_KEY=your-tavily-api-key
|
|
83
|
+
SERPER_API_KEY=your-serper-api-key
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
说明:
|
|
87
|
+
|
|
88
|
+
- `DASHSCOPE_API_KEY`:调用真实模型必需;未配置时 Agent 会使用 Mock Model
|
|
89
|
+
- `GITHUB_PERSONAL_ACCESS_TOKEN`:启用 GitHub MCP 工具,需要 pnpm
|
|
90
|
+
- `TAVILY_API_KEY` 或 `SERPER_API_KEY`:启用联网搜索
|
|
91
|
+
|
|
92
|
+
不要把 `.env` 提交到 Git,也不要发布到 npm。
|
|
93
|
+
|
|
94
|
+
## 常用命令
|
|
95
|
+
|
|
96
|
+
启动 Agent 后,可以直接输入以下命令:
|
|
97
|
+
|
|
98
|
+
| 命令 | 作用 |
|
|
99
|
+
| --- | --- |
|
|
100
|
+
| `status` | 查看当前消息数、Token 估算和记忆数量 |
|
|
101
|
+
| `context` | 查看上下文占用情况 |
|
|
102
|
+
| `usage` | 查看当前 Token 用量 |
|
|
103
|
+
| `memory` | 查看长期记忆 |
|
|
104
|
+
| `/memory search 关键词` | 搜索长期记忆 |
|
|
105
|
+
| `rag` | 查看 RAG 状态 |
|
|
106
|
+
| `skill list` | 查看可用技能 |
|
|
107
|
+
| `/skill load code-review` | 激活指定技能 |
|
|
108
|
+
| `/cron list` | 查看定时任务 |
|
|
109
|
+
| `/cron logs` | 查看定时任务执行记录 |
|
|
110
|
+
| `/agents` | 查看子 Agent 状态 |
|
|
111
|
+
| `exit` | 退出 Agent |
|
|
112
|
+
|
|
113
|
+
## 工作目录
|
|
114
|
+
|
|
115
|
+
PigPig Agent 会在当前目录保存运行数据,例如:
|
|
116
|
+
|
|
117
|
+
- `.memory/`
|
|
118
|
+
- `.sessions/`
|
|
119
|
+
- `.usage/`
|
|
120
|
+
- `.cron/`
|
|
121
|
+
- `knowledge.db`
|
|
122
|
+
|
|
123
|
+
请在一个固定目录中启动 Agent,这样记忆、会话和使用统计才能持续保留。
|
|
124
|
+
|
|
125
|
+
## 卸载
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npm uninstall -g pigpig-agent
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
卸载不会删除你在工作目录里生成的配置和运行数据。
|