Merge pull request #4381 from code-yeongyu/fix/team-mode-closure-prompts
fix(team-mode): make lead close teams on its own initiative
This commit is contained in:
@@ -91,7 +91,7 @@ Do not use \`oracle\`, \`prometheus\`, or other non-eligible agents here. For th
|
||||
|
||||
## Lifecycle
|
||||
|
||||
Teams are **ephemeral**: one team per phase of work. The moment a phase ends, or the team's shape no longer fits the next problem, **call \`team_delete\` immediately and spawn a fresh team for the next phase**. There is no in-place reshape; restructuring is delete-then-create. Lingering teams burn sessions, mailbox quota, and member-turn budget.
|
||||
Teams are **ephemeral**. There is no in-place reshape — restructuring is delete-then-create. Lingering teams burn sessions, mailbox quota, and member-turn budget every idle minute.
|
||||
|
||||
One cycle:
|
||||
|
||||
@@ -99,8 +99,28 @@ One cycle:
|
||||
2. Lead assigns work with \`team_send_message\` or \`team_task_create\`.
|
||||
3. Members report progress with \`team_send_message\` plus \`team_task_update\`.
|
||||
4. Lead and members track progress with \`team_task_list\`, \`team_task_get\`, and \`team_status\`.
|
||||
5. A member that finishes early asks to leave with \`team_shutdown_request\`; the lead handles \`team_approve_shutdown\` or \`team_reject_shutdown\`.
|
||||
6. **Phase done or shape outgrown? Call \`team_delete\` now; no idle members "just in case." Loop to step 1 for the next phase.**
|
||||
5. When the **Closure Contract** below holds, the lead runs the **Closure Sequence** in the same turn. Loop to step 1 for the next phase.
|
||||
|
||||
### Closure Contract
|
||||
|
||||
A team is **closable** when ALL of the following hold, as observed by \`team_task_list({ teamRunId })\` and \`team_status({ teamRunId })\`:
|
||||
|
||||
- Every task is in a terminal state: \`completed\` or \`failed\`. (No \`pending\`, no \`claimed\`, no \`in_progress\`.)
|
||||
- No outstanding \`team_shutdown_request\` is still awaiting approval.
|
||||
- The user has not asked you to keep the team open for follow-up.
|
||||
|
||||
Closure is **the lead's responsibility**, not the user's. Do not wait to be told. The check runs after every \`team_task_update\` that completes or fails a task — if the contract holds, close in the same turn. Closure now is cheaper than closure after the next user message, because by then the model has paged out the context.
|
||||
|
||||
### Closure Sequence
|
||||
|
||||
Run in order:
|
||||
|
||||
1. For each active member \`M\` returned by \`team_status\`:
|
||||
- \`team_shutdown_request({ teamRunId, memberName: M })\`
|
||||
- \`team_approve_shutdown({ teamRunId, memberName: M })\`
|
||||
2. \`team_delete({ teamRunId })\`
|
||||
|
||||
If step 2 errors because a member is still active, re-run \`team_status\`. Use \`team_delete({ teamRunId, force: true })\` **only** after confirming the remaining member is not mid-write — for example, after an unrecoverable error path where graceful shutdown is impossible. Do not use \`force: true\` to skip step 1.
|
||||
|
||||
## Task ownership
|
||||
|
||||
|
||||
@@ -38,9 +38,9 @@ Going idle after sending a message is the expected flow — it does NOT mean you
|
||||
|
||||
## Wrap-up
|
||||
|
||||
When you finish your assigned work, ALWAYS:
|
||||
1. Send your results to the lead via \`team_send_message\`.
|
||||
2. Mark your task as completed via \`team_task_update\`.
|
||||
3. Send a completion message to the lead so the lead can decide whether to request shutdown.
|
||||
When you finish your assigned work, ALWAYS, in this order:
|
||||
1. Mark your task \`status: "completed"\` (or \`"failed"\` with a reason) via \`team_task_update\` — the lead's closure check reads \`team_task_list\`, so the task update must land before any completion message.
|
||||
2. Re-check \`team_task_list\` for newly unblocked work. If there is any, claim it and continue — do not idle.
|
||||
3. If \`team_task_list\` shows nothing left for you, send the lead a single short \`team_send_message\` with your results and the phrase \`closure-ready\` so the lead knows you have no more work in flight. Then go idle.
|
||||
`
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ describe("createTeamRun", () => {
|
||||
expect(firstPrompt).toContain("Include `summary` and `references`")
|
||||
expect(firstPrompt).toContain("Move to `status: \"in_progress\"` when you start working")
|
||||
expect(firstPrompt).toContain("Do NOT call this from inside team members")
|
||||
expect(firstPrompt).toContain("lead can decide whether to request shutdown")
|
||||
expect(firstPrompt).toContain("closure-ready")
|
||||
expect(firstPrompt).toContain("user interacts primarily with the team lead")
|
||||
expect(firstPrompt).toContain("Idle is normal")
|
||||
expect(firstPrompt).toContain("structured JSON status messages")
|
||||
|
||||
Reference in New Issue
Block a user