@swifty.js/swifty 0.0.1-canary → 0.0.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.
- package/dist/anthropic-737END4X.js +4 -0
- package/dist/builtin/teach-me/SKILL.md +1 -1
- package/dist/bwrap-TPE6G4BM.js +4 -0
- package/dist/{chunk-DNCLVUXL.js → chunk-2PFMEUGN.js} +1 -1
- package/dist/chunk-GW6RG76F.js +4 -0
- package/dist/chunk-SC34YHMX.js +521 -0
- package/dist/{chunk-XWWKIJ5J.js → chunk-Z3E5YV3P.js} +31 -31
- package/dist/{devtools-X2EGZM6L.js → devtools-CUVBHY35.js} +1 -1
- package/dist/glob_addon.node +0 -0
- package/dist/main.js +294 -1182
- package/dist/{openai-4CKFFKCY.js → openai-4KX74QBZ.js} +12 -12
- package/dist/seatbelt-YXUQ5XR3.js +5 -0
- package/dist/server-XPKSROM2.js +244 -0
- package/dist/tool-filter-6ETY4ZEY.js +4 -0
- package/docs/ch1.md +3 -3
- package/docs/ch10.md +5 -5
- package/docs/ch11.md +3 -3
- package/docs/ch12.md +3 -2
- package/docs/ch13.md +28 -28
- package/docs/ch14.md +8 -2
- package/docs/ch15.md +508 -23
- package/docs/ch3.md +1 -1
- package/docs/ch4.md +6 -6
- package/docs/ch5.md +8 -8
- package/docs/ch6.md +2 -2
- package/docs/ch7.md +2 -2
- package/docs/ch8.md +11 -12
- package/docs/ch9.md +2 -2
- package/package.json +4 -5
- package/dist/anthropic-IS6JB2DP.js +0 -4
- package/dist/builtin/commit/SKILL.md +0 -41
- package/dist/builtin/test/SKILL.md +0 -42
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __swiftyCreateRequire } from "node:module";
|
|
3
|
+
const require = __swiftyCreateRequire(import.meta.url);
|
|
4
|
+
import{b as a,c as b,d as c,e as d,f as e,g as f}from"./chunk-GW6RG76F.js";import"./chunk-X3UA5OZL.js";export{a as ALL_AGENT_DISALLOWED_TOOLS,c as ASYNC_AGENT_ALLOWED_TOOLS,b as CUSTOM_AGENT_DISALLOWED_TOOLS,e as FORK_QUERY_SOURCE,f as cloneRegistryForFork,d as filterToolsForAgent};
|
package/docs/ch1.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# 什么是 Agent
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
agent 是 LLM 在循环中根据环境反馈自主使用工具的系统
|
|
4
4
|
|
|
5
5
|
- LLM 是大脑,负责理解和思考
|
|
6
6
|
- 循环: 意味着不是一次性问答就结束, 做一步操作, 拿到结果,再决定下一步
|
|
7
|
-
- 反馈:
|
|
7
|
+
- 反馈: agent 每做一步操作, 都能拿到到结果, 这些反馈驱动下一步决策
|
|
8
8
|
- 执行一条命令, 拿到输出
|
|
9
9
|
- 读一个文件, 拿到内容
|
|
10
10
|
- 跑一个测试, 拿到错误信息
|
|
11
|
-
- 自主使用工具:
|
|
11
|
+
- 自主使用工具: agent 自主判断使用什么工具, 是读文件还是写文件, 是 grep 搜索代码还是执行 shell 命令
|
|
12
12
|
|
|
13
13
|
## Swifty 的 5 层架构
|
|
14
14
|
|
package/docs/ch10.md
CHANGED
|
@@ -6,14 +6,14 @@ Slash Command: 以 / 开头的输入会被命令解析器拦截
|
|
|
6
6
|
|
|
7
7
|
<!-- 源码: src/commands/commands.ts -->
|
|
8
8
|
|
|
9
|
-
- local: 不参与
|
|
10
|
-
- local_ui: 不参与
|
|
11
|
-
- prompt: 参与
|
|
9
|
+
- local: 不参与 agent loop
|
|
10
|
+
- local_ui: 不参与 agent loop, 需要重新渲染 UI
|
|
11
|
+
- prompt: 参与 agent loop, CLI 负责构造 prompt
|
|
12
12
|
- skill_fork: skill 加载后自动注册为 Slash Command (prompt 命令)
|
|
13
13
|
|
|
14
|
-
> 不参与
|
|
14
|
+
> 不参与 agent loop != 不调用 LLM API
|
|
15
15
|
>
|
|
16
|
-
> 例如 /compact 命令调用 LLM API 生成摘要, 但是不参与
|
|
16
|
+
> 例如 /compact 命令调用 LLM API 生成摘要, 但是不参与 agent loop
|
|
17
17
|
|
|
18
18
|
命令拦截时机: 消息发送给 LLM API 前, 用户按下回车, 先判断输入是不是命令, 如果是命令则走命令处理逻辑, 不是命令才发送给 LLM API
|
|
19
19
|
|
package/docs/ch11.md
CHANGED
|
@@ -35,11 +35,11 @@ fork_context: 可选的, 仅在 mode: fork 时生效, 决定携带的上下文;
|
|
|
35
35
|
|
|
36
36
|
### inline 模式
|
|
37
37
|
|
|
38
|
-
默认执行模式, 内联 skill 的 prompt 到用户消息, 参与
|
|
38
|
+
默认执行模式, 内联 skill 的 prompt 到用户消息, 参与 agent loop
|
|
39
39
|
|
|
40
40
|
### fork 模式
|
|
41
41
|
|
|
42
|
-
开启新对话, 调用 LLM API, 只将 LLM API 的响应返回给主对话, 不参与
|
|
42
|
+
开启新对话, 调用 LLM API, 只将 LLM API 的响应返回给主对话, 不参与 agent loop
|
|
43
43
|
|
|
44
44
|
fork 模式的实现:
|
|
45
45
|
|
|
@@ -90,7 +90,7 @@ Swifty 启动时, 扫描 skills 目录, 加载所有 skill 的 frontmatter 元
|
|
|
90
90
|
|
|
91
91
|
LLM 判断用户意图匹配某个 skill 时, 调用 LoadSkill 工具
|
|
92
92
|
|
|
93
|
-
LoadSkill 工具根据该 skill 的 name, 读取 SKILL.md 的 SOP 作为工具调用结果返回, LLM 在下一轮
|
|
93
|
+
LoadSkill 工具根据该 skill 的 name, 读取 SKILL.md 的 SOP 作为工具调用结果返回, LLM 在下一轮 agent loop turn 中可以看到该 skill 的 SOP
|
|
94
94
|
|
|
95
95
|
### LoadSkill
|
|
96
96
|
|
package/docs/ch12.md
CHANGED
|
@@ -47,7 +47,7 @@ hooks:
|
|
|
47
47
|
### Agent Loop 轮次级
|
|
48
48
|
|
|
49
49
|
- turn_start 用户发送新消息时触发, 一轮对话开始
|
|
50
|
-
- turn_end LLM 退出
|
|
50
|
+
- turn_end LLM 退出 agent loop 时触发, 一轮对话结束
|
|
51
51
|
- LLM 决定退出循环
|
|
52
52
|
- 超过最大循环次数后强制退出循环
|
|
53
53
|
- 用户按 esc 退出循环
|
|
@@ -156,7 +156,8 @@ action:
|
|
|
156
156
|
prompt: 先阅读 ARCHITECTURE.md 了解项目架构, 再开始工作
|
|
157
157
|
```
|
|
158
158
|
|
|
159
|
-
- 使用 `<
|
|
159
|
+
- 使用 `<system-reminder />` 标签包裹, 作为一条 user 消息追加到对话历史, LLM 在下一轮 agent loop turn 请求中可以读到
|
|
160
|
+
- system prompt 不变、prompt cache 前缀不变
|
|
160
161
|
- 可以只在指定项目中注入, 或者只在第一轮对话中注入 (使用执行控制 `once: true`)
|
|
161
162
|
|
|
162
163
|
### http
|
package/docs/ch13.md
CHANGED
|
@@ -47,7 +47,7 @@ interface Tool {
|
|
|
47
47
|
|
|
48
48
|
## 两种创建模式
|
|
49
49
|
|
|
50
|
-
- 预定义的 subagent (Definition-based):
|
|
50
|
+
- 预定义的 subagent (Definition-based): 预定义的 subagent 角色, 无对话历史
|
|
51
51
|
- fork 的 subagent (Fork-based): spawn (fork) 一个 subagent, 继承父 Agent 的完整对话历史
|
|
52
52
|
|
|
53
53
|
### 预定义的 subagent (Definition-based)
|
|
@@ -121,11 +121,11 @@ Rules (non-negotiable):
|
|
|
121
121
|
Your task: ${prompt}
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
fork 的 subagent 必须后台异步运行, 执行结束后使用 `<task-notification />` 标签包裹执行结果, 作为一条 user
|
|
124
|
+
fork 的 subagent 必须后台异步运行, 执行结束后使用 `<task-notification />` 标签包裹执行结果, 作为一条 user 消息注入到主 agent 的上下文 (TODO)
|
|
125
125
|
|
|
126
126
|
> 为什么 fork 的 subagent 必须后台异步运行?
|
|
127
127
|
|
|
128
|
-
1. fork 的场景是主
|
|
128
|
+
1. fork 的场景是主 agent 分发多个子任务, 并发执行
|
|
129
129
|
2. fork 的 subagent 继承父 Agent 的完整对话历史, 首次 API 请求耗时长; 前台同步等待, 父 Agent 阻塞, 用户体验很差
|
|
130
130
|
|
|
131
131
|
> 定义式 subagent 默认前台同步运行
|
|
@@ -152,11 +152,11 @@ background: true
|
|
|
152
152
|
- 可以精确控制 subagent 的能力边界
|
|
153
153
|
- 可以限制 subagent 调用的工具
|
|
154
154
|
- 可以指定一个更小更快的模型: haiku, sonnet, deepseek...
|
|
155
|
-
- 如果任务不通用、与主
|
|
155
|
+
- 如果任务不通用、与主 agent 的当前工作高度相关, 例如: 迁移一个组件的 useImperativeHandle 从 react18 到 react19, fork 3 个 subagent 迁移剩余的类组件, 使用 fork 的 subagent, subagent_type 为空
|
|
156
156
|
|
|
157
157
|
## 上下文隔离
|
|
158
158
|
|
|
159
|
-
- 基础设施共享: API Key、LLM API
|
|
159
|
+
- 基础设施共享: API Key、LLM API 连接池、工具集、MCP、Skill、Hook
|
|
160
160
|
- 权限 (permissionMode) 隔离
|
|
161
161
|
- 文件系统: 默认共享, 使用 `isolation: "worktree"` 时隔离
|
|
162
162
|
|
|
@@ -164,26 +164,26 @@ background: true
|
|
|
164
164
|
|
|
165
165
|
<!-- 源码: src/subagent/loader.ts -->
|
|
166
166
|
|
|
167
|
-
| | Skill | Subagent
|
|
168
|
-
| ---------------------------- | ------------------------- |
|
|
169
|
-
| body | 注入 messages 的 SOP 指令 | 对于定义式 subagent, 作为 system prompt; 对于 fork 的 subagent, body 使用 `<fork_boilerplate />` 标签包裹注入到 user
|
|
170
|
-
| frontmatter.name | name | name, 映射到 AgentDefinition 的 agentType
|
|
171
|
-
| frontmatter.description | description | description, 映射到 AgentDefinition 的 whenToUse
|
|
172
|
-
| frontmatter.model | model | model
|
|
173
|
-
| frontmatter.system_prompt | X | 覆盖默认 system prompt
|
|
174
|
-
| frontmatter.subagent_type | X | 预定义的 agent 角色, 例如 explore, plan, code-review
|
|
175
|
-
| frontmatter.background | X | 是否后台异步运行, fork 的 subagent 必须后台异步运行, 为了对齐 Claude, properties (parameters) 中是 run_in_background
|
|
176
|
-
| frontmatter.isolation | X | `isolation: undefined \| 'worktree'`, 是否使用 git worktree 文件系统隔离
|
|
177
|
-
| frontmatter.memory | X | 记忆范围: `"user" \| "project" \| "local"`
|
|
178
|
-
| frontmatter.tools | X | 工具白名单
|
|
179
|
-
| frontmatter.disallowed_tools | X | 工具黑名单
|
|
180
|
-
| frontmatter.permission_mode | X | 例如 `permissionMode: "acceptEdits"` 调用工具, 不弹出对话框
|
|
181
|
-
| frontmatter.max_turns | X | 最大
|
|
167
|
+
| | Skill | Subagent |
|
|
168
|
+
| ---------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
169
|
+
| body | 注入 messages 的 SOP 指令 | 对于定义式 subagent, 作为 system prompt; 对于 fork 的 subagent, body 使用 `<fork_boilerplate />` 标签包裹注入到 user 消息 |
|
|
170
|
+
| frontmatter.name | name | name, 映射到 AgentDefinition 的 agentType |
|
|
171
|
+
| frontmatter.description | description | description, 映射到 AgentDefinition 的 whenToUse |
|
|
172
|
+
| frontmatter.model | model | model |
|
|
173
|
+
| frontmatter.system_prompt | X | 覆盖默认 system prompt |
|
|
174
|
+
| frontmatter.subagent_type | X | 预定义的 agent 角色, 例如 explore, plan, code-review |
|
|
175
|
+
| frontmatter.background | X | 是否后台异步运行, fork 的 subagent 必须后台异步运行, 为了对齐 Claude, properties (parameters) 中是 run_in_background |
|
|
176
|
+
| frontmatter.isolation | X | `isolation: undefined \| 'worktree'`, 是否使用 git worktree 文件系统隔离 |
|
|
177
|
+
| frontmatter.memory | X | 记忆范围: `"user" \| "project" \| "local"` |
|
|
178
|
+
| frontmatter.tools | X | 工具白名单 |
|
|
179
|
+
| frontmatter.disallowed_tools | X | 工具黑名单 |
|
|
180
|
+
| frontmatter.permission_mode | X | 例如 `permissionMode: "acceptEdits"` 调用工具, 不弹出对话框 |
|
|
181
|
+
| frontmatter.max_turns | X | 最大 agent loop 次数数 |
|
|
182
182
|
|
|
183
183
|
<!-- 源码: src/subagent/definition.ts -->
|
|
184
184
|
|
|
185
185
|
```ts
|
|
186
|
-
/** Memory scope for a
|
|
186
|
+
/** Memory scope for a subagent. Mirrors Go's AgentMemoryScope. */
|
|
187
187
|
export type AgentMemoryScope = "user" | "project" | "local";
|
|
188
188
|
|
|
189
189
|
export interface AgentDefinition {
|
|
@@ -217,11 +217,11 @@ Agent 定义文件, 优先级从低到高
|
|
|
217
217
|
|
|
218
218
|
## Subagent Loop
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
subagent loop 和主 agent loop 的区别
|
|
221
221
|
|
|
222
|
-
1.
|
|
223
|
-
2. LLM 不再调用工具,
|
|
224
|
-
3. pre_tool_use hook -> 调用 AgentTool ->
|
|
222
|
+
1. subagent loop turn 不等待用户输入
|
|
223
|
+
2. LLM 不再调用工具, subagent loop 结束, 返回执行结果
|
|
224
|
+
3. pre_tool_use hook -> 调用 AgentTool -> subagent loop -> post_tool_use hook
|
|
225
225
|
|
|
226
226
|
## Subagent 不能继续 spawn
|
|
227
227
|
|
|
@@ -249,7 +249,7 @@ Subagent Loop 和主 Agent Loop 的区别
|
|
|
249
249
|
3. 按 esc 键将前台同步运行的 subagent 手动切换到后台异步运行
|
|
250
250
|
4. fork 的 subagent 无条件后台异步运行
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
swifty 没有管理后台异步任务的 Slash Command, 后台异步任务通过 4 个内置工具暴露给 agent:
|
|
253
253
|
|
|
254
254
|
- TaskList 任务列表
|
|
255
255
|
- TaskGet 获取某个任务的状态或结果
|
|
@@ -281,7 +281,7 @@ permission_mode: plan
|
|
|
281
281
|
- 使用 Grep 搜索内容
|
|
282
282
|
- 使用 ReadFile 读取指定路径的文件
|
|
283
283
|
- 只允许执行只读的 Bash 命令
|
|
284
|
-
-
|
|
284
|
+
- 尽可能并发调用多个工具以提高效率
|
|
285
285
|
```
|
|
286
286
|
|
|
287
287
|
### Plan
|
|
@@ -315,6 +315,6 @@ permission_mode: plan
|
|
|
315
315
|
```md
|
|
316
316
|
---
|
|
317
317
|
name: general-purpose
|
|
318
|
-
description: 你是 Swifty 的 Subagent, 不是主
|
|
318
|
+
description: 你是 Swifty 的 Subagent, 不是主 agent
|
|
319
319
|
---
|
|
320
320
|
```
|
package/docs/ch14.md
CHANGED
|
@@ -108,6 +108,7 @@ git rev-list --count ${headCommit}..HEAD
|
|
|
108
108
|
- 进程崩溃、用户强制退出, 会导致 .swifty/worktree 堆积大量的 worktree 目录
|
|
109
109
|
- workflow 创建的 worktree: `wf-[hash]`, 会被自动清理
|
|
110
110
|
- subagent 创建的 worktree: `agent-[hash]`, 会被自动清理
|
|
111
|
+
- agent team leader 指定 teammate `isolation: "worktree"`, leader 创建的 worktree: `team-${teamNae}/${teammateName}`, 见 ch15
|
|
111
112
|
- 用户手动创建的 worktree, 不会被自动清理
|
|
112
113
|
- 如果 worktree 没有未 commit 的修改, 也没有新增的 commit, 则可以自动清理
|
|
113
114
|
- 如果 worktree 已过期、有新增的 commit 并且推送到远端, 则可以自动清理
|
|
@@ -141,6 +142,11 @@ export function buildWorktreeNotice(parentCwd: string, wtPath: string): string {
|
|
|
141
142
|
|
|
142
143
|
> 考虑以下场景
|
|
143
144
|
|
|
144
|
-
subagent 在 worktree 中修改并提交了 server.ts, 主
|
|
145
|
+
subagent 在 worktree 中修改并提交了 server.ts, 主 agent 期望将该 subagent 的变更merge/rebase/cherry-pick 到主分支; Swifty 没有内置的 merge/rebase/cherry-pick 工具, 主 agent 调用 Bash 工具, 执行 `git merge/rebase/cherry-pick`
|
|
145
146
|
|
|
146
|
-
为什么 Swifty 没有将 merge 作为内置工具?
|
|
147
|
+
为什么 Swifty 没有将 merge/rebase/cherry-pick 作为内置工具?
|
|
148
|
+
|
|
149
|
+
- merge/rebase/cherry-pick 不是 Agent 的原子操作
|
|
150
|
+
- 主 agent 可以调用 Bash 工具执行 git 命令
|
|
151
|
+
- 主 agent 需要调用 ReadFile 工具查看冲突文件, 以确定 merge/rebase/cherry-pick 顺序和冲突解决策略
|
|
152
|
+
- merge/rebase/cherry-pick 失败时, 主 agent 需要调用 Bash 工具 abort
|