mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-27 19:52:49 +00:00
docs(plugins): show how to attach tools to agents
This commit is contained in:
@@ -432,6 +432,9 @@ Server entries register lifecycle observers with `server.on()` and request trans
|
||||
`server.before()`. The [public reference](../public-docs/plugins/reference.md#lifecycle-hooks)
|
||||
owns callback shapes, ordering, and failure behavior. `plugin-examples/lifecycle-logger` registers all
|
||||
eleven hooks; `plugin-examples/lifecycle-actions` demonstrates common automation callbacks.
|
||||
Session-open hooks also [attach tools to individual agents](../public-docs/plugins/reference.md#attach-tools-to-agents),
|
||||
as shown in `plugin-examples/agent-tools`. The agent manager stamps their metadata per session;
|
||||
executable definitions stay in the plugin process.
|
||||
|
||||
Emit from the operation owner, not a client subscription. Provider history replay must not trigger
|
||||
live hooks. Observers must not be awaited inside agent mutations: a callback can send a prompt or
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
@@ -707,3 +708,45 @@ test("explicit SDK reload interrupts a running turn before reopening its session
|
||||
await h.close();
|
||||
}
|
||||
}, 60_000);
|
||||
|
||||
test("the agent-tools example appends notes only for labeled agents", async () => {
|
||||
const h = await setup();
|
||||
try {
|
||||
await h.client.installDirectoryPlugin(
|
||||
fileURLToPath(new URL("../../../../../plugin-examples/agent-tools", import.meta.url)),
|
||||
);
|
||||
const a = await h.create({ "notes/enabled": "true" });
|
||||
const mcpA = await h.mcp(a.id);
|
||||
expect((await mcpA.listTools()).tools.map((tool) => tool.name)).toContain(
|
||||
"append_workspace_note",
|
||||
);
|
||||
expect(
|
||||
await mcpA.callTool({
|
||||
name: "append_workspace_note",
|
||||
arguments: { note: "Run the targeted tests before committing." },
|
||||
}),
|
||||
).toMatchObject({
|
||||
content: [
|
||||
{ type: "text", text: `Saved note to ${path.join(h.directory, "AGENT_NOTES.md")}` },
|
||||
],
|
||||
structuredContent: { path: path.join(h.directory, "AGENT_NOTES.md") },
|
||||
});
|
||||
expect(await readFile(path.join(h.directory, "AGENT_NOTES.md"), "utf8")).toBe(
|
||||
"Run the targeted tests before committing.\n",
|
||||
);
|
||||
await mcpA.callTool({
|
||||
name: "append_workspace_note",
|
||||
arguments: { note: "Keep existing notes." },
|
||||
});
|
||||
expect(await readFile(path.join(h.directory, "AGENT_NOTES.md"), "utf8")).toBe(
|
||||
"Run the targeted tests before committing.\nKeep existing notes.\n",
|
||||
);
|
||||
await h.create();
|
||||
const mcpB = await h.mcp();
|
||||
expect((await mcpB.listTools()).tools.map((tool) => tool.name)).not.toContain(
|
||||
"append_workspace_note",
|
||||
);
|
||||
} finally {
|
||||
await h.close();
|
||||
}
|
||||
}, 60_000);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# Agent tools
|
||||
|
||||
Attaches `append_workspace_note` to agents whose `notes/enabled` label is `"true"`.
|
||||
Calling the tool with `{ "note": "Run the targeted tests before committing." }` appends that
|
||||
line to `AGENT_NOTES.md` in the calling agent's working directory and returns the file path.
|
||||
It creates the file if it does not exist.
|
||||
|
||||
Install on a daemon with plugins enabled:
|
||||
|
||||
```bash
|
||||
paseo plugin install /absolute/path/to/plugin-examples/agent-tools
|
||||
```
|
||||
|
||||
Create a labeled agent through the SDK:
|
||||
|
||||
```ts
|
||||
const agent = await paseo.agents.create({
|
||||
config: { provider: "codex/gpt-5.4" },
|
||||
cwd: "/projects/shop",
|
||||
labels: { "notes/enabled": "true" },
|
||||
});
|
||||
```
|
||||
|
||||
The session-open callback also runs when an agent resumes or reloads. After changing an existing
|
||||
agent's labels, call `paseo.agents.ref(id).reload()` to apply the selection immediately. This
|
||||
interrupts a running turn. `refresh()` reads the agent snapshot without reopening its session.
|
||||
|
||||
From the repository root, `npm run typecheck` includes this example. Outside this repository,
|
||||
use `paseo plugin init` to create the package and TypeScript setup, then copy `index.server.ts`
|
||||
and the manifest into that project.
|
||||
|
||||
See [Attach tools to agents](../../public-docs/plugins/reference.md#attach-tools-to-agents)
|
||||
for targeting, execution, provider gates, collisions, and plugin reload behavior.
|
||||
@@ -0,0 +1,26 @@
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { z } from "zod";
|
||||
import { defineAgentTool, type PluginServerContext } from "@getpaseo/plugin/server";
|
||||
|
||||
const appendWorkspaceNote = defineAgentTool({
|
||||
name: "append_workspace_note",
|
||||
description: "Append a note to AGENT_NOTES.md in this agent's working directory.",
|
||||
input: z.object({ note: z.string().min(1).describe("Note to append") }),
|
||||
async execute({ note }, { agent, signal }) {
|
||||
const notePath = path.join(agent.cwd, "AGENT_NOTES.md");
|
||||
await writeFile(notePath, `${note}\n`, { encoding: "utf8", flag: "a", signal });
|
||||
return {
|
||||
text: `Saved note to ${notePath}`,
|
||||
structuredContent: { path: notePath },
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default function contribute(server: PluginServerContext) {
|
||||
server.before("agent.session_open", ({ request }) => {
|
||||
if (request.labels["notes/enabled"] !== "true") return;
|
||||
return { ...request, tools: [...request.tools, appendWorkspaceNote] };
|
||||
});
|
||||
return () => {};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"id": "agent-tools",
|
||||
"requirements": { "paseo": ">=0.13.2" }
|
||||
}
|
||||
@@ -711,6 +711,120 @@ server.before("agent.session_open", ({ request }) => {
|
||||
This runs on create, resume, refresh, and import. To inject only on creation, set `env` in an
|
||||
`agent.create` callback instead.
|
||||
|
||||
### Attach tools to agents
|
||||
|
||||
Define a tool in `index.server.ts` and attach it in `before("agent.session_open")`.
|
||||
This example gives `append_workspace_note` only to agents with the label `notes/enabled: "true"`:
|
||||
|
||||
```ts
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { z } from "zod";
|
||||
import { defineAgentTool, type PluginServerContext } from "@getpaseo/plugin/server";
|
||||
|
||||
const appendWorkspaceNote = defineAgentTool({
|
||||
name: "append_workspace_note",
|
||||
description: "Append a note to AGENT_NOTES.md in this agent's working directory.",
|
||||
input: z.object({ note: z.string().min(1).describe("Note to append") }),
|
||||
async execute({ note }, { agent, signal }) {
|
||||
const notePath = path.join(agent.cwd, "AGENT_NOTES.md");
|
||||
await writeFile(notePath, `${note}\n`, { encoding: "utf8", flag: "a", signal });
|
||||
return {
|
||||
text: `Saved note to ${notePath}`,
|
||||
structuredContent: { path: notePath },
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default function contribute(server: PluginServerContext) {
|
||||
server.before("agent.session_open", ({ request }) => {
|
||||
if (request.labels["notes/enabled"] !== "true") return;
|
||||
return { ...request, tools: [...request.tools, appendWorkspaceNote] };
|
||||
});
|
||||
return () => {};
|
||||
}
|
||||
```
|
||||
|
||||
Set the label when creating an agent with the SDK:
|
||||
|
||||
```ts
|
||||
const agent = await paseo.agents.create({
|
||||
config: { provider: "codex/gpt-5.4" },
|
||||
cwd: "/projects/shop",
|
||||
labels: { "notes/enabled": "true" },
|
||||
});
|
||||
```
|
||||
|
||||
Select agents using any of the session-open request fields:
|
||||
|
||||
| Select by | Condition in the callback |
|
||||
| ---------------- | -------------------------------------------- |
|
||||
| Label | `request.labels["notes/enabled"] === "true"` |
|
||||
| Provider | `request.provider === "codex"` |
|
||||
| Workspace | `request.workspaceId === "workspace-456"` |
|
||||
| Individual agent | `request.agentId === chosenAgentId` |
|
||||
|
||||
`request.tools` starts empty for each plugin. Each callback sees the tools returned by earlier
|
||||
callbacks in that plugin; replace the array to add or remove tools. Returning `undefined` preserves
|
||||
the request. Tools are ignored for `purpose: "history"`.
|
||||
|
||||
Import `defineAgentTool`, `AgentToolDefinition`, `AgentToolContext`, and `AgentToolResult` from
|
||||
`@getpaseo/plugin/server`. The helper infers the validated input from your Zod schema:
|
||||
|
||||
```ts
|
||||
declare function defineAgentTool<Input extends z.ZodType>(tool: {
|
||||
name: string;
|
||||
title?: string;
|
||||
description: string;
|
||||
input: Input;
|
||||
execute(
|
||||
input: z.output<Input>,
|
||||
context: AgentToolContext,
|
||||
): AgentToolResult | Promise<AgentToolResult>;
|
||||
}): AgentToolDefinition;
|
||||
|
||||
interface AgentToolResult {
|
||||
text?: string;
|
||||
structuredContent?: unknown;
|
||||
isError?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
| Execution context | Value |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------- |
|
||||
| `agent` | Calling agent as a `PluginHookAgent`, including `id`, `workspaceId`, `provider`, `cwd`, and `title` |
|
||||
| `paseo` | SDK connected to this daemon |
|
||||
| `signal` | Abort signal for this tool call; pass it to file operations or external requests |
|
||||
|
||||
`execute` runs in the plugin process. Closures and the original Zod schema stay there; only tool
|
||||
metadata and call inputs/results cross the process boundary. Paseo validates input before calling
|
||||
`execute`. Invalid input returns schema issues to the agent. A thrown error becomes
|
||||
`{ isError: true, text: message }` and the plugin keeps running. Canceling the call or closing its
|
||||
transport aborts `signal` and discards the result. Tool calls have a 10 minute ceiling, separate
|
||||
from the 30 second hook timeout. Closing or reopening an agent session drops its old definitions.
|
||||
|
||||
Return model-visible text in `text`. `structuredContent` must be JSON-serializable; when `text` is
|
||||
omitted, Paseo formats that value as text for the model. Set `isError: true` to report a tool error.
|
||||
|
||||
Paseo delivers attached tools through its agent tool transport, using MCP or native registration
|
||||
as the provider supports. The same definition and callback work with either. Attached tools obey
|
||||
the [same gates as Paseo tools](/docs/mcp#limit-paseo-tools-by-provider). Only that agent sees them.
|
||||
|
||||
Names must match `/^[a-z][a-z0-9_]*$/` and be at most 64 characters. A name colliding with a Paseo
|
||||
tool or another plugin's tool on the same agent fails the session open and names both owners.
|
||||
A duplicate name within one plugin also fails the session open. Agents the callback does not
|
||||
target are unaffected.
|
||||
|
||||
| Change | When the agent receives it |
|
||||
| -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Start, stop, or reload a plugin declaring `agent.session_open` | Open sessions become stale. Each reopens before its next idle prompt; a running turn continues without interruption. The next prompt after that reopen reuses the session. |
|
||||
| Change which agents the callback targets | Run `paseo plugin reload agent-tools` after editing this example, then send the agent a prompt when it is idle. |
|
||||
| Apply immediately | Call `await paseo.agents.ref(id).reload({ requestId: "reload-notes" })`. `requestId` is optional. This reopens the provider session, reruns hooks with `reason: "refresh"`, and interrupts a running turn. |
|
||||
| Read the current snapshot | Call `await paseo.agents.ref(id).refresh()`. This reads state without reopening the session. |
|
||||
|
||||
If an automatic reopen fails, the triggering prompt fails with that error. See the
|
||||
[complete agent-tools example](https://github.com/getpaseo/paseo/tree/main/plugin-examples/agent-tools).
|
||||
|
||||
### Choose workspace isolation
|
||||
|
||||
```ts
|
||||
@@ -878,11 +992,11 @@ type PluginTurnOutcome =
|
||||
|
||||
### Before hooks
|
||||
|
||||
| Name | Request fields | Editable |
|
||||
| -------------------- | ----------------------------------------------------------------------- | --------------------------------------- |
|
||||
| `agent.create` | `config`, optional `env` | Public agent config except `cwd`; `env` |
|
||||
| `agent.session_open` | `agentId`, `workspaceId`, `provider`, `cwd`, `reason`, `purpose`, `env` | Only `env` |
|
||||
| `workspace.create` | `source`, optional `title`, `firstAgentContext` | Entire explicit creation request |
|
||||
| Name | Request fields | Editable |
|
||||
| -------------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
|
||||
| `agent.create` | `config`, optional `env` | Public agent config except `cwd`; `env` |
|
||||
| `agent.session_open` | `agentId`, `workspaceId`, `provider`, `cwd`, read-only `title` and `labels`, `reason`, `purpose`, `env`, `tools` | `env` and `tools` |
|
||||
| `workspace.create` | `source`, optional `title`, `firstAgentContext` | Entire explicit creation request |
|
||||
|
||||
**`agent.create.config`** uses `AgentSessionConfig`:
|
||||
|
||||
@@ -903,6 +1017,9 @@ type PluginTurnOutcome =
|
||||
"workspaceId": "workspace-456",
|
||||
"provider": "codex",
|
||||
"cwd": "/projects/shop",
|
||||
"title": "Workspace notes",
|
||||
"labels": { "notes/enabled": "true" },
|
||||
"tools": [],
|
||||
"reason": "resume",
|
||||
"purpose": "interactive",
|
||||
"env": { "COMPANY_ENV": "development" }
|
||||
@@ -912,6 +1029,9 @@ type PluginTurnOutcome =
|
||||
| Field | Values |
|
||||
| ------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `workspaceId` | String or `null` |
|
||||
| `title` | Read-only string or `null`; creation title on create, stored title on resume. |
|
||||
| `labels` | Read-only string map; creation labels on create, stored labels on resume. |
|
||||
| `tools` | Editable `AgentToolDefinition[]`, local to this plugin. See [Attach tools to agents](#attach-tools-to-agents). |
|
||||
| `reason` | `create`, `resume`, `refresh`, `import` |
|
||||
| `purpose` | `interactive`, `history` |
|
||||
| `env` | Launch override map; excludes the daemon's inherited environment. Replace the map to add, replace, or remove overrides. |
|
||||
@@ -923,7 +1043,7 @@ Creation request
|
||||
→ agent.create hooks (plugin-ID order; registration order within each plugin)
|
||||
→ resolve defaults and validate provider configuration
|
||||
→ derive launch configuration with Paseo runtime tools and daemon prompt
|
||||
→ agent.session_open hooks (same ordering; env only)
|
||||
→ agent.session_open hooks (same ordering; env and plugin-local tools)
|
||||
→ set PASEO_AGENT_ID and PASEO_AGENT_CWD
|
||||
→ open provider session and save agent configuration
|
||||
```
|
||||
@@ -960,6 +1080,7 @@ saved; environment overrides are not persisted with it.
|
||||
| [lifecycle-logger](https://github.com/getpaseo/paseo/tree/main/plugin-examples/lifecycle-logger) | All eleven hooks; JSON logs with environment values redacted |
|
||||
| [lifecycle-actions](https://github.com/getpaseo/paseo/tree/main/plugin-examples/lifecycle-actions) | Follow-ups, permissions, environment, provider switching, worktree selection |
|
||||
| [agent-configuration](https://github.com/getpaseo/paseo/tree/main/plugin-examples/agent-configuration) | MCP injection and Codex sandbox/approval options |
|
||||
| [agent-tools](https://github.com/getpaseo/paseo/tree/main/plugin-examples/agent-tools) | Label-targeted tools and file operations in the plugin process |
|
||||
|
||||
Read logger output with `paseo plugin logs lifecycle-logger` or the host's `daemon.log`.
|
||||
|
||||
|
||||
@@ -585,6 +585,117 @@ server.before("agent.session_open", ({ request }) => {
|
||||
|
||||
它会在创建、恢复、刷新和导入时运行。如果只想在创建时注入,请改为在 `agent.create` 回调中设置 `env`。
|
||||
|
||||
### 为 Agent 附加工具 {#attach-tools-to-agents}
|
||||
|
||||
在 `index.server.ts` 中定义工具,并在 `before("agent.session_open")` 中附加它。
|
||||
此示例只向带有 `notes/enabled: "true"` 标签的 Agent 提供 `append_workspace_note`:
|
||||
|
||||
```ts
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { z } from "zod";
|
||||
import { defineAgentTool, type PluginServerContext } from "@getpaseo/plugin/server";
|
||||
|
||||
const appendWorkspaceNote = defineAgentTool({
|
||||
name: "append_workspace_note",
|
||||
description: "Append a note to AGENT_NOTES.md in this agent's working directory.",
|
||||
input: z.object({ note: z.string().min(1).describe("Note to append") }),
|
||||
async execute({ note }, { agent, signal }) {
|
||||
const notePath = path.join(agent.cwd, "AGENT_NOTES.md");
|
||||
await writeFile(notePath, `${note}\n`, { encoding: "utf8", flag: "a", signal });
|
||||
return {
|
||||
text: `Saved note to ${notePath}`,
|
||||
structuredContent: { path: notePath },
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default function contribute(server: PluginServerContext) {
|
||||
server.before("agent.session_open", ({ request }) => {
|
||||
if (request.labels["notes/enabled"] !== "true") return;
|
||||
return { ...request, tools: [...request.tools, appendWorkspaceNote] };
|
||||
});
|
||||
return () => {};
|
||||
}
|
||||
```
|
||||
|
||||
通过 SDK 创建 Agent 时设置标签:
|
||||
|
||||
```ts
|
||||
const agent = await paseo.agents.create({
|
||||
config: { provider: "codex/gpt-5.4" },
|
||||
cwd: "/projects/shop",
|
||||
labels: { "notes/enabled": "true" },
|
||||
});
|
||||
```
|
||||
|
||||
使用会话打开请求中的字段选择 Agent:
|
||||
|
||||
| 选择依据 | 回调中的条件 |
|
||||
| ---------- | -------------------------------------------- |
|
||||
| 标签 | `request.labels["notes/enabled"] === "true"` |
|
||||
| Provider | `request.provider === "codex"` |
|
||||
| 工作区 | `request.workspaceId === "workspace-456"` |
|
||||
| 单个 Agent | `request.agentId === chosenAgentId` |
|
||||
|
||||
每个插件的 `request.tools` 都从空数组开始。同一插件中的后续回调会看到前面回调返回的工具;
|
||||
替换数组即可添加或移除工具。返回 `undefined` 会保留请求。`purpose: "history"` 时会忽略工具。
|
||||
|
||||
从 `@getpaseo/plugin/server` 导入 `defineAgentTool`、`AgentToolDefinition`、`AgentToolContext`
|
||||
和 `AgentToolResult`。辅助函数会根据 Zod schema 推断验证后的输入类型:
|
||||
|
||||
```ts
|
||||
declare function defineAgentTool<Input extends z.ZodType>(tool: {
|
||||
name: string;
|
||||
title?: string;
|
||||
description: string;
|
||||
input: Input;
|
||||
execute(
|
||||
input: z.output<Input>,
|
||||
context: AgentToolContext,
|
||||
): AgentToolResult | Promise<AgentToolResult>;
|
||||
}): AgentToolDefinition;
|
||||
|
||||
interface AgentToolResult {
|
||||
text?: string;
|
||||
structuredContent?: unknown;
|
||||
isError?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
| 执行 context | 值 |
|
||||
| ------------ | --------------------------------------------------------------------------------------------------- |
|
||||
| `agent` | 发起调用的 Agent,以 `PluginHookAgent` 表示,包括 `id`、`workspaceId`、`provider`、`cwd` 和 `title` |
|
||||
| `paseo` | 已连接到此 daemon 的 SDK |
|
||||
| `signal` | 此次工具调用的中止信号;请把它传给文件操作或外部请求 |
|
||||
|
||||
`execute` 在插件进程中运行。闭包和原始 Zod schema 保留在该进程中;只有工具元数据和调用的
|
||||
输入、结果会跨进程传递。Paseo 在调用 `execute` 前验证输入。无效输入会将 schema 问题返回给
|
||||
Agent。抛出的错误会转换为 `{ isError: true, text: message }`,插件继续运行。取消调用或关闭
|
||||
其传输连接会中止 `signal` 并丢弃结果。工具调用最长运行 10 分钟,与钩子的 30 秒超时分开。
|
||||
关闭或重新打开 Agent 会话会移除旧定义。
|
||||
|
||||
在 `text` 中返回模型可见的文本。`structuredContent` 必须可序列化为 JSON;省略 `text` 时,
|
||||
Paseo 会将该值格式化为供模型读取的文本。设置 `isError: true` 可报告工具错误。
|
||||
|
||||
Paseo 通过 Agent 工具传输提供附加的工具,按 Provider 的支持情况使用 MCP 或原生注册。
|
||||
同一份定义和回调适用于这两种方式。附加的工具遵循[与 Paseo 工具相同的限制](/docs/mcp#limit-paseo-tools-by-provider)。
|
||||
只有该 Agent 能看到这些工具。
|
||||
|
||||
名称必须匹配 `/^[a-z][a-z0-9_]*$/`,且不超过 64 个字符。如果名称与同一 Agent 的 Paseo
|
||||
工具或另一插件的工具冲突,会话打开会失败,并指出双方。一个插件内的重复名称也会导致
|
||||
会话打开失败。回调未选中的 Agent 不受影响。
|
||||
|
||||
| 变更 | Agent 何时收到变更 |
|
||||
| ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 启动、停止或重新加载声明了 `agent.session_open` 的插件 | 已打开的会话会标记为过期。每个会话在下一次空闲提示词前重新打开;正在运行的轮次会继续,不会被中断。重新打开后的下一条提示词复用该会话。 |
|
||||
| 修改回调选择的 Agent | 编辑此示例后运行 `paseo plugin reload agent-tools`,然后在 Agent 空闲时发送提示词。 |
|
||||
| 立即应用 | 调用 `await paseo.agents.ref(id).reload({ requestId: "reload-notes" })`。`requestId` 可选。这会重新打开 Provider 会话,以 `reason: "refresh"` 再次运行钩子,并中断正在运行的轮次。 |
|
||||
| 读取当前快照 | 调用 `await paseo.agents.ref(id).refresh()`。这只读取状态,不会重新打开会话。 |
|
||||
|
||||
如果自动重新打开失败,触发它的提示词会返回该错误。参阅
|
||||
[完整 agent-tools 示例](https://github.com/getpaseo/paseo/tree/main/plugin-examples/agent-tools)。
|
||||
|
||||
### 选择工作区隔离方式 {#choose-workspace-isolation}
|
||||
|
||||
```ts
|
||||
@@ -741,11 +852,11 @@ type PluginTurnOutcome =
|
||||
|
||||
### before 钩子 {#before-hooks}
|
||||
|
||||
| 名称 | 请求字段 | 可编辑 |
|
||||
| -------------------- | ----------------------------------------------------------------------- | ----------------------------------- |
|
||||
| `agent.create` | `config`,可选的 `env` | 除 `cwd` 外的公开 Agent 配置;`env` |
|
||||
| `agent.session_open` | `agentId`, `workspaceId`, `provider`, `cwd`, `reason`, `purpose`, `env` | 仅 `env` |
|
||||
| `workspace.create` | `source`,可选的 `title`,`firstAgentContext` | 整个显式创建请求 |
|
||||
| 名称 | 请求字段 | 可编辑 |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------------------------ | ----------------------------------- |
|
||||
| `agent.create` | `config`,可选的 `env` | 除 `cwd` 外的公开 Agent 配置;`env` |
|
||||
| `agent.session_open` | `agentId`, `workspaceId`, `provider`, `cwd`,只读的 `title` 和 `labels`,`reason`, `purpose`, `env`, `tools` | `env` 和 `tools` |
|
||||
| `workspace.create` | `source`,可选的 `title`,`firstAgentContext` | 整个显式创建请求 |
|
||||
|
||||
**`agent.create.config`** 使用 `AgentSessionConfig`:
|
||||
|
||||
@@ -766,18 +877,24 @@ type PluginTurnOutcome =
|
||||
"workspaceId": "workspace-456",
|
||||
"provider": "codex",
|
||||
"cwd": "/projects/shop",
|
||||
"title": "Workspace notes",
|
||||
"labels": { "notes/enabled": "true" },
|
||||
"tools": [],
|
||||
"reason": "resume",
|
||||
"purpose": "interactive",
|
||||
"env": { "COMPANY_ENV": "development" }
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 取值 |
|
||||
| ------------- | ------------------------------------------------------------------------------------ |
|
||||
| `workspaceId` | 字符串或 `null` |
|
||||
| `reason` | `create`、`resume`、`refresh`、`import` |
|
||||
| `purpose` | `interactive`、`history` |
|
||||
| `env` | 启动覆盖映射;不包括 daemon 继承的环境变量。替换整个映射即可添加、替换或移除覆盖项。 |
|
||||
| 字段 | 取值 |
|
||||
| ------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `workspaceId` | 字符串或 `null` |
|
||||
| `title` | 只读字符串或 `null`;创建时使用创建请求的标题,恢复时使用已保存的标题。 |
|
||||
| `labels` | 只读的字符串映射;创建时使用创建请求的标签,恢复时使用已保存的标签。 |
|
||||
| `tools` | 可编辑的 `AgentToolDefinition[]`,仅包含此插件的工具。参阅[为 Agent 附加工具](#attach-tools-to-agents)。 |
|
||||
| `reason` | `create`、`resume`、`refresh`、`import` |
|
||||
| `purpose` | `interactive`、`history` |
|
||||
| `env` | 启动覆盖映射;不包括 daemon 继承的环境变量。替换整个映射即可添加、替换或移除覆盖项。 |
|
||||
|
||||
### 顺序与返回值 {#ordering-and-returned-values}
|
||||
|
||||
@@ -786,7 +903,7 @@ Creation request
|
||||
→ agent.create hooks (plugin-ID order; registration order within each plugin)
|
||||
→ resolve defaults and validate provider configuration
|
||||
→ derive launch configuration with Paseo runtime tools and daemon prompt
|
||||
→ agent.session_open hooks (same ordering; env only)
|
||||
→ agent.session_open hooks (same ordering; env and plugin-local tools)
|
||||
→ set PASEO_AGENT_ID and PASEO_AGENT_CWD
|
||||
→ open provider session and save agent configuration
|
||||
```
|
||||
@@ -822,6 +939,7 @@ Creation request
|
||||
| [lifecycle-logger](https://github.com/getpaseo/paseo/tree/main/plugin-examples/lifecycle-logger) | 全部十一个钩子;隐去环境变量值的 JSON 日志 |
|
||||
| [lifecycle-actions](https://github.com/getpaseo/paseo/tree/main/plugin-examples/lifecycle-actions) | 后续消息、权限、环境变量、切换 Provider、选择 worktree |
|
||||
| [agent-configuration](https://github.com/getpaseo/paseo/tree/main/plugin-examples/agent-configuration) | MCP 注入以及 Codex 沙盒/批准选项 |
|
||||
| [agent-tools](https://github.com/getpaseo/paseo/tree/main/plugin-examples/agent-tools) | 按标签选择 Agent,并在插件进程中执行文件操作的工具 |
|
||||
|
||||
用 `paseo plugin logs lifecycle-logger` 或主机的 `daemon.log` 读取 logger 的输出。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user