mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-11 10:57:07 +00:00
Give plugins an agent's background work count and a background flag on hooks (#9362)
* feat(plugins): give plugins the agent's sidebar indicator and background flag Plugin UI re-derived agent state from status and attention fields and could not see background work, so it showed agents as done while a shell they left running was still live. Agent snapshots now carry the sidebar's own bucket as indicator/indicatorLabel, computed by the same function the sidebar uses so the two cannot drift. Lifecycle hooks and the agent.open.before request now carry `background`, so a hook can skip a hidden helper agent without a lookup. A hook cannot change it; an omitted value means unchanged, like metadata. `finished` attention still means the turn finished; background work is the indicator's concern. * fix(plugins): keep session-open hooks that omit background typechecking A hook that returns its own object instead of spreading the request has no background field; the result type now treats it as optional, like metadata, matching the runtime where an omitted value means unchanged. * refactor(plugins): give agent snapshots the background work count instead of an indicator * fix(plugins): keep legacy session-open hooks that omit background typechecking
This commit is contained in:
@@ -76,6 +76,7 @@ interface PluginHookAgent {
|
||||
provider: string;
|
||||
cwd: string;
|
||||
title: string | null;
|
||||
readonly background: boolean;
|
||||
metadata: Record<string, JsonValue>;
|
||||
}
|
||||
|
||||
@@ -96,6 +97,7 @@ type PluginTurnOutcome =
|
||||
|
||||
| Field | Shape / meaning |
|
||||
| ------------ | -------------------------------------------------------------------------------------- |
|
||||
| `background` | `true` for a [background agent](#background-agents) |
|
||||
| `turnId` | Provider-reported `string` or `null`; unique across resumed sessions |
|
||||
| `timeline` | Deprecated, always `[]`; fetch history with the SDK. |
|
||||
| `request` | SDK `AgentPermissionRequest`; `kind` is `tool`, `plan`, `question`, `mode`, or `other` |
|
||||
@@ -303,6 +305,7 @@ server.addHook("agent.open.before", async ({ request }, { paseo }) => {
|
||||
"provider": "codex",
|
||||
"cwd": "/projects/shop",
|
||||
"title": "Workspace notes",
|
||||
"background": false,
|
||||
"labels": { "notes/enabled": "true" },
|
||||
"metadata": { "linear.issue": { "id": "ENG-123" } },
|
||||
"tools": [],
|
||||
@@ -317,6 +320,7 @@ server.addHook("agent.open.before", async ({ request }, { paseo }) => {
|
||||
| ------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `workspaceId` | String or `null` |
|
||||
| `title` | Read-only string or `null`; creation title on create, stored title on resume. |
|
||||
| `background` | Read-only `true` for a [background agent](#background-agents). Fixed at creation. |
|
||||
| `labels` | Read-only string map; creation labels on create, stored labels on resume. |
|
||||
| `metadata` | Read-only JSON map; the [metadata](#metadata) stored on the agent. |
|
||||
| `tools` | Editable `AgentToolDefinition[]`, local to this plugin. See [Attach tools to agents](#attach-tools-to-agents). |
|
||||
@@ -350,7 +354,7 @@ the placeholder URL with your MCP endpoint:
|
||||
|
||||
```ts
|
||||
server.addHook("agent.open.before", async ({ request }) => {
|
||||
if (request.provider !== "codex") return;
|
||||
if (request.provider !== "codex" || request.background) return;
|
||||
|
||||
return {
|
||||
...request,
|
||||
@@ -426,6 +430,7 @@ Select agents using any of the session-open request fields:
|
||||
| Provider | `request.provider === "codex"` |
|
||||
| Workspace | `request.workspaceId === "workspace-456"` |
|
||||
| Individual agent | `request.agentId === chosenAgentId` |
|
||||
| Background agent | `request.background` |
|
||||
|
||||
`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
|
||||
@@ -623,8 +628,21 @@ server.addHook("agent.permission.after", async ({ agent, requestId, resolution }
|
||||
});
|
||||
```
|
||||
|
||||
## Background agents
|
||||
|
||||
Agent hooks exclude the daemon's private disposable helpers. Background agents and the agents in background workspaces use the same hooks.
|
||||
|
||||
A [background agent](/docs/sdk/agents#run-a-helper-as-a-background-agent) is a helper hidden from tabs, lists and attention. Every hook's `agent.background` and the `agent.open.before` request's `background` are `true` for one, so you can skip it without a lookup:
|
||||
|
||||
```ts
|
||||
server.addHook("agent.turn.after", async ({ agent }) => {
|
||||
if (agent.background) return; // A helper reports to the agent that created it.
|
||||
await notifyTeam(agent);
|
||||
});
|
||||
```
|
||||
|
||||
`background` is fixed when the agent is created and a hook cannot change it. An agent created in a background workspace without `background: true` reads `false`. Hosts older than 0.16.0 omit the field, so it reads as `undefined`.
|
||||
|
||||
## Ordering and returned values
|
||||
|
||||
```text
|
||||
|
||||
Reference in New Issue
Block a user