@sqfcy/liteagent 0.1.2 → 0.1.3
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 +23 -20
- package/dist/main.js +15 -15
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -37,6 +37,7 @@ la
|
|
|
37
37
|
|
|
38
38
|
**关于 Bun 的下载与使用(初学者指南):**
|
|
39
39
|
Bun 是一个极速的 JavaScript/TypeScript 运行时,内置了包管理器和打包工具,执行速度远超传统的 Node.js。
|
|
40
|
+
|
|
40
41
|
- **macOS / Linux 安装**: 打开终端执行 `curl -fsSL https://bun.sh/install | bash`
|
|
41
42
|
- **Windows 安装**: 打开 PowerShell 执行 `powershell -c "irm bun.sh/install.ps1 | iex"`(或通过 npm 安装:`npm install -g bun`)
|
|
42
43
|
- **验证安装**: 运行 `bun --version` 确认安装成功。
|
|
@@ -55,7 +56,20 @@ bun install
|
|
|
55
56
|
bun start
|
|
56
57
|
```
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
_首次启动时,系统会引导你配置 `BASE_URL`、`MODEL_NAME` 和 `API_KEY`。_
|
|
60
|
+
|
|
61
|
+
### 📁 配置目录(自动创建)
|
|
62
|
+
|
|
63
|
+
LiteAgent 默认会在用户主目录下创建全局配置目录,用于保存模型列表、全局配置以及 Skills。
|
|
64
|
+
|
|
65
|
+
- **全局配置目录**:
|
|
66
|
+
- macOS / Linux:`~/.liteagent/`
|
|
67
|
+
- Windows:`%USERPROFILE%\.liteagent\`
|
|
68
|
+
- **目录内容**(关键文件):
|
|
69
|
+
- `.agentrc`:默认全局配置(BASE_URL、MODEL_NAME、API_KEY 等)
|
|
70
|
+
- `models.json`:模型注册表(`/mode` 菜单中的模型列表)
|
|
71
|
+
- `AGENT.md` / `SOUL.md`:可选的全局 Persona/行为约束(会被注入到系统提示词)
|
|
72
|
+
- `skills/`:技能目录(每个技能一个子目录)
|
|
59
73
|
|
|
60
74
|
### 🔍 开发者模式(Dev Mode)与日志分析
|
|
61
75
|
|
|
@@ -69,32 +83,15 @@ bun start
|
|
|
69
83
|
|
|
70
84
|
---
|
|
71
85
|
|
|
72
|
-
## 📂 项目目录说明
|
|
73
|
-
|
|
74
|
-
```text
|
|
75
|
-
LiteAgent/
|
|
76
|
-
├── src/
|
|
77
|
-
│ ├── buddy/ # React Ink 终端 UI 层(负责终端渲染、输入接管、配置向导)
|
|
78
|
-
│ ├── commands/ # CLI 命令行入口解析
|
|
79
|
-
│ ├── config/ # 配置文件读写与全局模型状态管理
|
|
80
|
-
│ ├── mcp/ # Model Context Protocol (MCP) 客户端与工具集成
|
|
81
|
-
│ ├── services/ # Agent 核心驱动层(包含 agentEngine 对话主循环)
|
|
82
|
-
│ ├── skills/ # 动态 Skill 加载器(负责读取和解析自定义技能工作流)
|
|
83
|
-
│ ├── tools/ # 内置系统工具实现(Bash执行、文件读写、权限校验等)
|
|
84
|
-
│ └── main.tsx # 应用程序主入口
|
|
85
|
-
├── package.json # 项目依赖与 NPM 脚本
|
|
86
|
-
└── tsconfig.json # TypeScript 编译配置
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
86
|
## 🧠 核心架构与逻辑说明
|
|
92
87
|
|
|
93
88
|
为了帮助初学者快速理解 Agent Harness 的运作原理,以下是本项目中四个最核心的技术设计:
|
|
94
89
|
|
|
95
90
|
### 1. 对话主循环 (Conversation Main Loop)
|
|
91
|
+
|
|
96
92
|
Agent 的核心并非单次的一问一答,而是一个基于状态机的**循环系统**(位于 `src/services/agentEngine.ts`)。
|
|
97
93
|
LiteAgent 采用了异步生成器(`async function*`)来驱动主循环:
|
|
94
|
+
|
|
98
95
|
- 引擎向大模型发起流式请求,实时 yield 文本块供 UI 渲染。
|
|
99
96
|
- 当大模型决定调用工具时(触发 `tool_calls`),引擎会挂起生成器,暂停文本输出。
|
|
100
97
|
- 引擎在本地执行大模型指定的工具,获取结果(stdout/stderr)。
|
|
@@ -102,19 +99,25 @@ LiteAgent 采用了异步生成器(`async function*`)来驱动主循环:
|
|
|
102
99
|
- 循环直至大模型判定任务完成,输出最终文本。
|
|
103
100
|
|
|
104
101
|
### 2. 工具调用 (Tool Invocation)
|
|
102
|
+
|
|
105
103
|
工具是大模型与物理世界交互的手脚。LiteAgent 的工具系统(`src/tools/`)设计如下:
|
|
104
|
+
|
|
106
105
|
- **Schema 定义**: 强制使用 `Zod` 定义工具的输入参数结构,大模型必须严格遵循此结构输出 JSON。
|
|
107
106
|
- **并发与权限**: 框架层支持工具的并行执行校验,并在敏感工具(如执行 Shell 命令)调用前,通过权限管道拦截,确保系统安全。
|
|
108
107
|
- **标准化接口**: 所有工具继承自统一的基类,开发者只需实现 `execute` 方法,即可轻松扩展自定义工具。
|
|
109
108
|
|
|
110
109
|
### 3. Skill 加载 (Skill Loading)
|
|
110
|
+
|
|
111
111
|
为了避免系统提示词(System Prompt)过于臃肿导致 Token 浪费与指令漂移,LiteAgent 引入了动态 Skill 加载机制。
|
|
112
|
+
|
|
112
113
|
- 框架会在启动时扫描特定目录下的技能定义(Markdown/YAML)。
|
|
113
114
|
- 根据用户的当前输入意图,按需将相关的专家级工作流(Workflow)、规范和上下文注入到 System Prompt 中。
|
|
114
115
|
- 这种模块化的提示词工程,使得一个轻量级 Agent 能够灵活地在“前端专家”、“运维工程师”等多种角色间无缝切换。
|
|
115
116
|
|
|
116
117
|
### 4. Fork 模式设计 (Fork Mode Design)
|
|
118
|
+
|
|
117
119
|
在处理极其复杂的代码检索或试错性质的任务时,传统的单线对话会导致上下文迅速被垃圾信息填满(Context Pollution),进而引发 Token 爆炸和模型幻觉。
|
|
120
|
+
|
|
118
121
|
- **分支探索**: 架构支持在当前对话节点“Fork”出一个隐形的子 Agent 进程。
|
|
119
122
|
- **状态隔离**: 子 Agent 携带特定的目标(如:搜索某个 API 的具体用法),在独立且干净的上下文中大量调用搜索、读取工具进行试错。
|
|
120
123
|
- **结果归并**: 当子 Agent 找到答案后,它会对探索过程进行摘要,并仅将**最终结论**返回给主进程。这不仅保护了主线对话的纯净性,也极大降低了长期运行的成本。
|
package/dist/main.js
CHANGED
|
@@ -17624,7 +17624,7 @@ var require_emoji_regex = __commonJS((exports, module) => {
|
|
|
17624
17624
|
};
|
|
17625
17625
|
});
|
|
17626
17626
|
|
|
17627
|
-
// node_modules/ws/lib/constants.js
|
|
17627
|
+
// node_modules/ink/node_modules/ws/lib/constants.js
|
|
17628
17628
|
var require_constants2 = __commonJS((exports, module) => {
|
|
17629
17629
|
var BINARY_TYPES = ["nodebuffer", "arraybuffer", "fragments"];
|
|
17630
17630
|
var hasBlob = typeof Blob !== "undefined";
|
|
@@ -17644,7 +17644,7 @@ var require_constants2 = __commonJS((exports, module) => {
|
|
|
17644
17644
|
};
|
|
17645
17645
|
});
|
|
17646
17646
|
|
|
17647
|
-
// node_modules/ws/lib/buffer-util.js
|
|
17647
|
+
// node_modules/ink/node_modules/ws/lib/buffer-util.js
|
|
17648
17648
|
var require_buffer_util = __commonJS((exports, module) => {
|
|
17649
17649
|
var { EMPTY_BUFFER } = require_constants2();
|
|
17650
17650
|
var FastBuffer = Buffer[Symbol.species];
|
|
@@ -17722,7 +17722,7 @@ var require_buffer_util = __commonJS((exports, module) => {
|
|
|
17722
17722
|
}
|
|
17723
17723
|
});
|
|
17724
17724
|
|
|
17725
|
-
// node_modules/ws/lib/limiter.js
|
|
17725
|
+
// node_modules/ink/node_modules/ws/lib/limiter.js
|
|
17726
17726
|
var require_limiter = __commonJS((exports, module) => {
|
|
17727
17727
|
var kDone = Symbol("kDone");
|
|
17728
17728
|
var kRun = Symbol("kRun");
|
|
@@ -17754,7 +17754,7 @@ var require_limiter = __commonJS((exports, module) => {
|
|
|
17754
17754
|
module.exports = Limiter;
|
|
17755
17755
|
});
|
|
17756
17756
|
|
|
17757
|
-
// node_modules/ws/lib/permessage-deflate.js
|
|
17757
|
+
// node_modules/ink/node_modules/ws/lib/permessage-deflate.js
|
|
17758
17758
|
var require_permessage_deflate = __commonJS((exports, module) => {
|
|
17759
17759
|
var zlib = __require("zlib");
|
|
17760
17760
|
var bufferUtil = require_buffer_util();
|
|
@@ -18018,7 +18018,7 @@ var require_permessage_deflate = __commonJS((exports, module) => {
|
|
|
18018
18018
|
}
|
|
18019
18019
|
});
|
|
18020
18020
|
|
|
18021
|
-
// node_modules/ws/lib/validation.js
|
|
18021
|
+
// node_modules/ink/node_modules/ws/lib/validation.js
|
|
18022
18022
|
var require_validation = __commonJS((exports, module) => {
|
|
18023
18023
|
var { isUtf8 } = __require("buffer");
|
|
18024
18024
|
var { hasBlob } = require_constants2();
|
|
@@ -18205,7 +18205,7 @@ var require_validation = __commonJS((exports, module) => {
|
|
|
18205
18205
|
}
|
|
18206
18206
|
});
|
|
18207
18207
|
|
|
18208
|
-
// node_modules/ws/lib/receiver.js
|
|
18208
|
+
// node_modules/ink/node_modules/ws/lib/receiver.js
|
|
18209
18209
|
var require_receiver = __commonJS((exports, module) => {
|
|
18210
18210
|
var { Writable } = __require("stream");
|
|
18211
18211
|
var PerMessageDeflate = require_permessage_deflate();
|
|
@@ -18586,7 +18586,7 @@ var require_receiver = __commonJS((exports, module) => {
|
|
|
18586
18586
|
module.exports = Receiver;
|
|
18587
18587
|
});
|
|
18588
18588
|
|
|
18589
|
-
// node_modules/ws/lib/sender.js
|
|
18589
|
+
// node_modules/ink/node_modules/ws/lib/sender.js
|
|
18590
18590
|
var require_sender = __commonJS((exports, module) => {
|
|
18591
18591
|
var { Duplex } = __require("stream");
|
|
18592
18592
|
var { randomFillSync } = __require("crypto");
|
|
@@ -18940,7 +18940,7 @@ var require_sender = __commonJS((exports, module) => {
|
|
|
18940
18940
|
}
|
|
18941
18941
|
});
|
|
18942
18942
|
|
|
18943
|
-
// node_modules/ws/lib/event-target.js
|
|
18943
|
+
// node_modules/ink/node_modules/ws/lib/event-target.js
|
|
18944
18944
|
var require_event_target = __commonJS((exports, module) => {
|
|
18945
18945
|
var { kForOnEventAttribute, kListener } = require_constants2();
|
|
18946
18946
|
var kCode = Symbol("kCode");
|
|
@@ -19091,7 +19091,7 @@ var require_event_target = __commonJS((exports, module) => {
|
|
|
19091
19091
|
}
|
|
19092
19092
|
});
|
|
19093
19093
|
|
|
19094
|
-
// node_modules/ws/lib/extension.js
|
|
19094
|
+
// node_modules/ink/node_modules/ws/lib/extension.js
|
|
19095
19095
|
var require_extension = __commonJS((exports, module) => {
|
|
19096
19096
|
var { tokenChars } = require_validation();
|
|
19097
19097
|
function push(dest, name, elem) {
|
|
@@ -19256,7 +19256,7 @@ var require_extension = __commonJS((exports, module) => {
|
|
|
19256
19256
|
module.exports = { format, parse };
|
|
19257
19257
|
});
|
|
19258
19258
|
|
|
19259
|
-
// node_modules/ws/lib/websocket.js
|
|
19259
|
+
// node_modules/ink/node_modules/ws/lib/websocket.js
|
|
19260
19260
|
var require_websocket = __commonJS((exports, module) => {
|
|
19261
19261
|
var EventEmitter = __require("events");
|
|
19262
19262
|
var https = __require("https");
|
|
@@ -20022,7 +20022,7 @@ var require_websocket = __commonJS((exports, module) => {
|
|
|
20022
20022
|
}
|
|
20023
20023
|
});
|
|
20024
20024
|
|
|
20025
|
-
// node_modules/ws/lib/stream.js
|
|
20025
|
+
// node_modules/ink/node_modules/ws/lib/stream.js
|
|
20026
20026
|
var require_stream = __commonJS((exports, module) => {
|
|
20027
20027
|
var WebSocket = require_websocket();
|
|
20028
20028
|
var { Duplex } = __require("stream");
|
|
@@ -20125,7 +20125,7 @@ var require_stream = __commonJS((exports, module) => {
|
|
|
20125
20125
|
module.exports = createWebSocketStream;
|
|
20126
20126
|
});
|
|
20127
20127
|
|
|
20128
|
-
// node_modules/ws/lib/subprotocol.js
|
|
20128
|
+
// node_modules/ink/node_modules/ws/lib/subprotocol.js
|
|
20129
20129
|
var require_subprotocol = __commonJS((exports, module) => {
|
|
20130
20130
|
var { tokenChars } = require_validation();
|
|
20131
20131
|
function parse(header) {
|
|
@@ -20170,7 +20170,7 @@ var require_subprotocol = __commonJS((exports, module) => {
|
|
|
20170
20170
|
module.exports = { parse };
|
|
20171
20171
|
});
|
|
20172
20172
|
|
|
20173
|
-
// node_modules/ws/lib/websocket-server.js
|
|
20173
|
+
// node_modules/ink/node_modules/ws/lib/websocket-server.js
|
|
20174
20174
|
var require_websocket_server = __commonJS((exports, module) => {
|
|
20175
20175
|
var EventEmitter = __require("events");
|
|
20176
20176
|
var http = __require("http");
|
|
@@ -20476,7 +20476,7 @@ var require_websocket_server = __commonJS((exports, module) => {
|
|
|
20476
20476
|
}
|
|
20477
20477
|
});
|
|
20478
20478
|
|
|
20479
|
-
// node_modules/ws/wrapper.mjs
|
|
20479
|
+
// node_modules/ink/node_modules/ws/wrapper.mjs
|
|
20480
20480
|
var import_stream, import_extension, import_permessage_deflate, import_receiver, import_sender, import_subprotocol, import_websocket, import_websocket_server, wrapper_default;
|
|
20481
20481
|
var init_wrapper = __esm(() => {
|
|
20482
20482
|
import_stream = __toESM(require_stream(), 1);
|
|
@@ -55559,4 +55559,4 @@ main().catch((err) => {
|
|
|
55559
55559
|
process.exit(1);
|
|
55560
55560
|
});
|
|
55561
55561
|
|
|
55562
|
-
//# debugId=
|
|
55562
|
+
//# debugId=96DE64B6A4B37DB264756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqfcy/liteagent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A lightweight, general-purpose AI agent harness",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
"ink-text-input": "^6.0.0",
|
|
27
27
|
"marked": "^14.1.2",
|
|
28
28
|
"react": "^18.2.0",
|
|
29
|
-
"react-devtools-core": "^7.0.1",
|
|
30
29
|
"yaml": "^2.8.3",
|
|
31
30
|
"zod": "^3.23.8"
|
|
32
31
|
},
|
|
@@ -34,6 +33,7 @@
|
|
|
34
33
|
"@types/node": "^20.0.0",
|
|
35
34
|
"@types/react": "^18.2.79",
|
|
36
35
|
"bun-types": "^1.3.11",
|
|
36
|
+
"react-devtools-core": "^7.0.1",
|
|
37
37
|
"typescript": "^5.4.5"
|
|
38
38
|
}
|
|
39
39
|
}
|