Merge PR #5871: docs(coding-agent): clarify async job lifecycle contract (@roboomp)
This commit is contained in:
@@ -115,6 +115,7 @@
|
||||
|
||||
### Fixed
|
||||
|
||||
- Clarified async task and hub guidance: inspecting a settled job consumes its automatic delivery, job IDs expire from process memory after roughly five minutes, and completion does not verify claimed artifacts ([#5869](https://github.com/can1357/oh-my-pi/issues/5869)).
|
||||
- Fixed loading issues for linked legacy extensions importing `DefaultPackageManager` or `linkedom`.
|
||||
- Fixed the advisor retrying terminal, non-retriable provider failures (e.g., blocked prompts), ensuring they fail immediately while transient failures still retry.
|
||||
- Fixed an issue where reassigning the `plan` role model mid-planning did not take effect until the next plan-mode entry; it now applies at the next turn boundary.
|
||||
|
||||
@@ -3,7 +3,7 @@ Use `op: "list"` to discover peers. Address peers by exact roster ID — NEVER i
|
||||
|
||||
# Messaging & Jobs
|
||||
|
||||
Background jobs deliver their results automatically the moment they finish. You NEVER need to poll for output — intervene only to block, kill, or inspect.
|
||||
Background jobs auto-deliver when they finish. You NEVER need to poll; if `jobs`/`wait` observes a settled job first, that snapshot is the delivery and suppresses duplicate `async-result`.
|
||||
|
||||
- **`send`** (with `to`): fire-and-forget, NEVER blocks. Delivery receipts (`delivered`/`failed`) immediate; `failed` → peer gone, don't retry.
|
||||
Sending wakes `idle`/`parked` peers. Answering: lead with answer, NEVER quote, set `replyTo`.
|
||||
@@ -12,7 +12,9 @@ Background jobs deliver their results automatically the moment they finish. You
|
||||
- Bare `wait` watches every running job AND incoming messages. NEVER pass an array of every running ID; `ids` narrows to specific jobs, `from` to one peer (or use `await: true` on send).
|
||||
- **`inbox`**: drain queued messages without blocking.
|
||||
- **`cancel`**: kill background jobs by `ids` when they have hung, stalled, or are no longer needed. Returns immediately.
|
||||
- **`jobs`**: status snapshot of every job without waiting. Also names running subagents with no job entry — coordinate with those via `send`.
|
||||
- **`jobs`**: status snapshot of every job without waiting. A settled row consumes auto-delivery. Also names running subagents with no job entry — coordinate with those via `send`.
|
||||
- Job rows are process-local and expire roughly five minutes after settlement. Afterward, use the agent ID with `send`, `agent://<id>`, or `history://<id>`.
|
||||
- `completed` means successful yield/job exit, not artifact acceptance. Verify claimed changes.
|
||||
- NEVER use shell tools, grep, or read other sessions' files to figure out what a peer is doing. Message them directly.
|
||||
- NEVER use hub messaging for something a tool can answer (e.g., grepping codebase, running a build).
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
No polling is needed. Inspecting a settled job with `hub jobs` or `hub wait` makes that snapshot its delivery, so no duplicate `async-result` follows. Job IDs live in process memory for roughly five minutes after settlement; afterward, use the agent ID with `hub send`, `agent://<id>`, or `history://<id>`. `completed` means the subagent yielded successfully, not that claimed artifacts were verified.
|
||||
@@ -1,7 +1,14 @@
|
||||
{{#if asyncEnabled}}{{#if batchEnabled}}Delegate work to background subagents by passing multiple items in a single `tasks[]` batch.
|
||||
Execution does not block — you receive IDs immediately; results deliver when subagents finish.{{else}}Delegate work to ONE background subagent per call.
|
||||
Execution does not block — you receive an ID immediately; the result delivers when the subagent finishes.{{/if}}{{#if hasBlockingAgents}}
|
||||
Execution does not block — you receive IDs immediately.{{else}}Delegate work to ONE background subagent per call.
|
||||
Execution does not block — you receive an ID immediately.{{/if}}{{#if hasBlockingAgents}}
|
||||
Agents marked BLOCKING run inline — results return in this call; non-blocking items in the same batch still spawn as background jobs.{{/if}}{{else}}{{#if batchEnabled}}Run subagents synchronously by passing items in a `tasks[]` batch. Execution blocks until all work finishes.{{else}}Run ONE subagent synchronously. Execution blocks until work finishes.{{/if}}{{/if}}
|
||||
{{#if asyncEnabled}}
|
||||
|
||||
# Async Job Contract
|
||||
- Results auto-deliver. A settled `hub jobs`/`hub wait` snapshot is the delivery; no duplicate `async-result` follows.
|
||||
- Job IDs are process-local and expire roughly five minutes after settlement. Afterward, use the agent ID with `hub send`, `agent://<id>`, or `history://<id>`.
|
||||
- `completed` means successful yield/job exit, not artifact acceptance. Verify claimed changes.
|
||||
{{/if}}
|
||||
|
||||
# Task Design
|
||||
- **Agent typing:** Pick each item's `agent` type. Read-only research MUST use `agent: "scout"` (faster model). Use default worker only when no specialist fits.
|
||||
|
||||
@@ -21,6 +21,7 @@ import type { ToolSession } from "..";
|
||||
import type { Theme } from "../modes/theme/theme";
|
||||
import subagentUserPromptTemplate from "../prompts/system/subagent-user-prompt.md" with { type: "text" };
|
||||
import taskDescriptionTemplate from "../prompts/tools/task.md" with { type: "text" };
|
||||
import taskAsyncContractTemplate from "../prompts/tools/task-async-contract.md" with { type: "text" };
|
||||
import taskSummaryTemplate from "../prompts/tools/task-summary.md" with { type: "text" };
|
||||
import { truncateForPrompt } from "../tools/approval";
|
||||
import { isIrcEnabled } from "../tools/hub";
|
||||
@@ -894,14 +895,16 @@ export class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskToolDetai
|
||||
failedSchedules.length > 0
|
||||
? ` Failed to schedule ${failedSchedules.length} spawn${failedSchedules.length === 1 ? "" : "s"}: ${failedSchedules.join("; ")}.`
|
||||
: "";
|
||||
const coordinationHint =
|
||||
const coordinationHint = [
|
||||
started.length === 1
|
||||
? ircEnabled
|
||||
? `DM \`${started[0].agentId}\` via \`hub\` send to coordinate while it runs; use \`hub\` only to inspect (\`jobs\`), wait, or cancel a stuck task.`
|
||||
: `Use \`hub\` to inspect (\`jobs\`), wait, or cancel a stuck task.`
|
||||
: ircEnabled
|
||||
? `DM these ids via \`hub\` send to coordinate while they run; use \`hub\` only to inspect (\`jobs\`), wait, or cancel a stuck task.`
|
||||
: `Use \`hub\` to inspect (\`jobs\`), wait, or cancel a stuck task by id.`;
|
||||
: `Use \`hub\` to inspect (\`jobs\`), wait, or cancel a stuck task by id.`,
|
||||
taskAsyncContractTemplate.trim(),
|
||||
].join("\n");
|
||||
|
||||
if (syncSpawns.length === 0) {
|
||||
if (spawns.length === 1) {
|
||||
|
||||
Reference in New Issue
Block a user