ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Paseo SDK 实战食谱:用 TypeScript 编排 Issue 流转、并行审查与常驻 Agent

Paseo SDK 实战食谱:用 TypeScript 编排 Issue 流转、并行审查与常驻 Agent Paseo SDK 实战食谱用 TypeScript 编排 Issue 流转、并行审查与常驻 Agent【免费下载链接】paseoOrchestrate multiple coding agents from desktop and mobile项目地址: https://gitcode.com/gh_mirrors/pa/paseogetpaseo/client是 Paseo 的 TypeScript SDK它通过 WebSocket 驱动本地 Paseo 守护进程daemon来创建、运行和回收编码 Agent。本篇文章以官方 SDK Recipes 文档为主线完整呈现四个可直接落地的高频模式——把 Issue 变成可见工作、并行运行多个审查者、跨进程重启保持常驻角色、以及安全清理临时 Agent——并结合仓库源码与官方示例深入讲解其底层机制。读完你将掌握如何在自己的集成程序里创建、复用、追踪和归档 Agent并把它们与 Paseo App 中的手动任务无缝并排。前置准备连接守护进程SDK Recipes 中的所有示例都假设你已经有一个“已连接的client”它从公共包根导入import { createPaseoClient } from getpaseo/client; const client createPaseoClient({ url: ws://127.0.0.1:6767/ws }); await client.connect();守护进程默认监听ws://127.0.0.1:6767/ws可通过npx getpaseo/cli启动详见 public-docs/sdk/index.md。若守护进程设置了密码或需要连接远程 daemon则在配置中传入password字段const client createPaseoClient({ url: wss://devbox.example.com/ws, password: my-secret, });从源码看createPaseoClient在 packages/client/src/index.ts#L506-L526 中构造DaemonClient并返回带有connect()、close()、agents、workspaces、providers、config等命名空间的对象。connect()会一直等到守护进程完成自我标识才 resolve而close()只关闭 SDK 连接不会归档任何 Agent——Agent 会继续在 daemon 上运行并保持可见详见 public-docs/sdk/quickstart.md。食谱一把一个 Issue 变成可见的工作这是最经典的集成场景把外部系统Issue 跟踪器、告警、Webhook中的一条任务转化为一个由编码 Agent 执行的可见工作项。type Issue { id: string; title: string; description: string; repositoryPath: string; }; async function startIssue(issue: Issue) { const workspace await client.workspaces.open(issue.repositoryPath); const agent await workspace.agents.create({ config: { provider: codex/gpt-5.5, }, title: issue.title, labels: { issue-provider: my-tracker, issue-id: issue.id, }, prompt: [ Implement issue ${issue.id}: ${issue.title}, , issue.description, , Run focused tests and summarize the result., ].join(\n), }); return { workspaceId: workspace.id, agentId: agent.id }; }这个模式与仓库中的官方示例 packages/client/examples/issue-to-agent.ts 完全一致。其核心设计有四点workspaces.open(path)以目录为身份重复打开同一目录会复用已有的活跃 workspace源码位于 packages/client/src/index.ts#L209-L213避免重复创建项目。通过 workspace handle 创建 Agentworkspace.agents.create()由 handle 自动补全cwd与workspaceId的放置参数避免调用方重复传目录见 packages/client/src/index.ts#L818-L829。config.provider始终是provider/model格式比如codex/gpt-5.5、claude/claude-sonnet-5。Label 是集成方的元数据issue-provider、issue-id这类键是应用自有的用于后续检索和去重。create()在会话建立后即返回此时 prompt 仍在运行中Agent 会立即出现在 Paseo App 里和手动启动的任务并排显示。关键要点持久化返回的workspaceId与agentId。在下一个 Webhook 或页面加载时用workspaces.ref()和agents.ref()恢复句柄而不是重复创建造成重复 Agentconst agent client.agents.ref(savedAgentId); await agent.refresh(); await agent.run(继续完成剩余部分。);ref()不会立即联系 daemon它只是构建一个“零观察”的句柄需要确认 Agent 是否仍存在时先调用refresh()——若不存在会返回null详见 public-docs/sdk/agents.md。食谱二并行运行多个审查者把一个 diff 同时交给不同角度的审查者收集所有结论。官方食谱用Promise.all并发创建再用waitForFinish()并发等待const prompts [ Review the diff for correctness and missed edge cases., Review the diff for security and unsafe input handling., Review the diff for unnecessary complexity., ]; const reviewers await Promise.all( prompts.map((prompt, index) client.agents.create({ config: { provider: index 1 ? claude/claude-sonnet-5 : codex/gpt-5.5, }, cwd: process.cwd(), title: Review ${index 1}, prompt, }), ), ); const results await Promise.all(reviewers.map((reviewer) reviewer.waitForFinish())); for (const result of results) { console.log(result.status, result.lastMessage); }该模式与仓库示例 packages/client/examples/parallel-review.ts 高度吻合示例中还演示了最佳实践把创建出的 Agent 句柄收集进数组在finally中用Promise.allSettled逐一归档避免并发审查结束后留下游离 Agent。关于等待与状态waitForFinish()默认最多等待 10 分钟源码中DEFAULT_WAIT_FOR_FINISH_MS 10 * 60_000见 packages/client/src/index.ts#L61-L65可以传入毫秒数调整。它返回四种状态之一状态含义idle本轮结束Agent 可以接收下一条 prompt。permissionAgent 正在 Paseo 中等待某人响应权限请求。errorProvider 以错误结束本轮。timeout等待超时Agent 可能仍在运行。超时不会取消 Agent。由于waitForFinish在 packages/client/src/index.ts#L962-L971 的实现里会把最终快照写回句柄所以等待完成后可以直接读result.lastMessage与result.status。食谱三跨进程重启保持常驻角色有些场景需要一个“一直存在”的角色比如规划者 Planner、长期审查员程序重启后不重建而是找到旧实例继续对话。官方食谱给出的getPlanner模式async function getPlanner() { const listed await client.agents.list({ filter: { includeArchived: false }, page: { limit: 100 }, }); const existing listed.entries.find(({ agent }) agent.labels[my-app-role] planner); if (existing) return client.agents.ref(existing.agent); return client.agents.create({ config: { provider: claude/claude-sonnet-5, }, cwd: process.cwd(), title: Planner, labels: { my-app-role: planner }, }); } const planner await getPlanner(); const plan await planner.run(Plan the next small, shippable improvement.);Labels 是应用拥有的元数据。当多个工具可能在同一台 daemon 上管理 Agent 时务必对键做命名空间化如my-app-role而非role避免与其他工具冲突。创建时打上 label列表时由 daemon 侧完成过滤匹配const page await client.agents.list({ filter: { labels: { issue-provider: my-tracker } }, });这与 public-docs/sdk/agents.md 中“Find agents by label”一节一致agents.list()的filter支持includeArchived、labels等条件page.limit控制每页条数。常驻角色找到后的续话ref()得到句柄后直接run()即可发送新一轮 prompt。run()与send()的区别在于run()会等待本轮结束并返回结果其底层实现为发送消息后调用waitForFinish见 packages/client/src/index.ts#L950-L961而send()是即发即忘按需选择。食谱四安全清理临时 Agent临时创建的“冒烟测试”Agent 用完必须归档否则会永久留在 daemon 上占用会话。官方食谱用try/finally保证任何路径下都会清理且只清理自己创建的 Agentconst temporaryAgents []; try { const agent await client.agents.create({ config: { provider: codex/gpt-5.5, }, cwd: process.cwd(), title: Temporary smoke test, }); temporaryAgents.push(agent); const result await agent.run(Reply with READY and nothing else., { timeoutMs: 2 * 60_000, }); if (result.status ! idle) { throw new Error(result.error ?? result.status); } } finally { await Promise.allSettled(temporaryAgents.map((agent) agent.archive())); }几个值得强调的细节只归档自己创建的 Agent食谱明确警告“Do not archive agents your integration did not create”。因为 Agent 归档是软删除并关闭其运行时源码 packages/client/src/index.ts#L973-L979 将archive()实现为 daemon 的archiveAgentRPC 并回写archivedAt误删他人任务不可逆。用allSettled而非all确保某个归档失败不会阻断其余清理。超时参数run()的第二个参数可传timeoutMs此处 2 分钟结合waitForFinish的四状态结果判断成功与否。关闭 SDK 连接不会归档 Agent。如果你希望临时 Agent 在程序结束后消失必须显式归档正如 public-docs/sdk/agents.md 结尾所强调的Archive temporary agents explicitly, preferably infinally。从源码看这些食谱背后的句柄机制理解 Recipes 的关键在于 Paseo SDK 的“句柄handle”设计——一个句柄持有稳定的 Agent ID 或 Workspace ID并暴露回合生命周期而不直接暴露 daemon RPC。相关实现集中在 packages/client/src/index.tscreateAgentHandleFactoryindex.ts#L858-L997为 Agent 构建句柄。workspaceId、cwd、status、pendingPermissions、lastUsage、runtimeInfo、archivedAt等属性全部读取“句柄最近观察到的那份快照”永不主动拉取来自ref()的句柄从未观察到任何快照因此这些属性在refresh()、run()、waitForFinish()或subscribe()投递快照之前一律为null。createWorkspaceHandleFactoryindex.ts#L774-L856Workspace 句柄同样持有 ID 与快照agents.create()会先用当前快照必要时refresh()取得workspaceDirectory再把它作为放置参数传给底层createAgent——这正是“handle 负责摆放调用方无需重复目录”的实现依据。toDaemonAgentCreateOptionsindex.ts#L528-L549把provider/model字符串拆分为provider与model并把prompt转为initialPrompt、parent转为callerAgentId是 Recipes 中各参数落地为 RPC 的转换层。createPaseoClientindex.ts#L506-L526将所有 action 命名空间agents、workspaces、providers、config等组装成客户端对象close()依次释放订阅并关闭传输。关于父子的补充通过 workspace 创建子 Agent 时传入parent可建立父子关系归档父 Agent 会级联归档其子若子 Agent 需要独立存活先调用detach()解除关系。这一机制与 public-docs/sdk/agents.md 中“Create a subagent”一节对应。把这些食谱组合成完整集成四个食谱可以自然串联成一个完整的 Webhook 集成生命周期收到 Issue→ 食谱一workspaces.open(repositoryPath)workspace.agents.create(...)持久化workspaceId/agentId与 labelissue-provider、issue-id。PR 就绪→ 食谱二并发创建多个审查者waitForFinish()汇总结果。长期角色→ 食谱三用agents.list()按 label 查找命中则ref()复用否则创建重启后依然找得到。临时任务→ 食谱四try/finally中显式归档自建 Agent整个程序的退出只调用client.close()关闭连接不隐式清理任何东西。Workspace 归档与 Agent 归档相互独立workspace.archive()只归档工作区Agent 需按你的集成所拥有的生命周期分别归档详见 public-docs/sdk/workspaces.md。这套“创建 → 标记 → 复用 → 回收”的闭环就是基于getpaseo/client构建稳定自动化工作流的核心方法论更多细节可继续阅读 public-docs/sdk/agents.md、public-docs/sdk/workspaces.md、public-docs/sdk/providers.md 与 public-docs/sdk/events.md。【免费下载链接】paseoOrchestrate multiple coding agents from desktop and mobile项目地址: https://gitcode.com/gh_mirrors/pa/paseo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表