FN-7962: back off idle triage patrol task creation during model outages
Teach idle heartbeat patrol prompts to skip fn_task_create when recent model-availability failures are visible, and to base progress claims only on board state fetched in the current heartbeat. - Add standard and concise triage heartbeat guidance to check for model-availability, fallback exhaustion, 429/rate-limit, and 404/model-unavailable failures before creating work - Require existing-task progress/status claims to come from fn_task_list or fn_task_show results in the current heartbeat run - Extend agent-prompts tests to cover both template variants - Add patch changeset for the published package Files changed: .changeset/fn-7962-idle-heartbeat-patrol-backoff.md | 7 +++++++ packages/core/src/__tests__/agent-prompts.test.ts | 14 ++++++++++++++ packages/core/src/agent-prompts.ts | 8 ++++++++ 3 files changed, 29 insertions(+) Fusion-Task-Id: FN-7962 Fusion-Task-Lineage: 0a233b5d-00d8-4dda-b627-95d4b8122a55 Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
7
.changeset/fn-7962-idle-heartbeat-patrol-backoff.md
Normal file
7
.changeset/fn-7962-idle-heartbeat-patrol-backoff.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
summary: Make idle triage patrol back off during model outages.
|
||||||
|
category: fix
|
||||||
|
dev: Updates built-in standard and concise triage heartbeat prompt guidance.
|
||||||
@@ -473,6 +473,13 @@ describe("resolveAgentPrompt", () => {
|
|||||||
it("triage heartbeat guidance is customized for standard and concise templates", () => {
|
it("triage heartbeat guidance is customized for standard and concise templates", () => {
|
||||||
const defaultTriage = resolveAgentPrompt("triage");
|
const defaultTriage = resolveAgentPrompt("triage");
|
||||||
expect(defaultTriage).toContain("Patrol for vague requests");
|
expect(defaultTriage).toContain("Patrol for vague requests");
|
||||||
|
expect(defaultTriage).toContain("Before calling `fn_task_create` during a no-task heartbeat");
|
||||||
|
expect(defaultTriage).toContain("recent triage or model-availability failures");
|
||||||
|
expect(defaultTriage).toContain("model fallback exhaustion");
|
||||||
|
expect(defaultTriage).toContain("429/rate-limit");
|
||||||
|
expect(defaultTriage).toContain("404/model-unavailable");
|
||||||
|
expect(defaultTriage).toContain("skip creating new work rather than adding load");
|
||||||
|
expect(defaultTriage).toContain("`fn_task_list` or `fn_task_show` result fetched during this heartbeat run");
|
||||||
|
|
||||||
const conciseConfig: AgentPromptsConfig = {
|
const conciseConfig: AgentPromptsConfig = {
|
||||||
roleAssignments: {
|
roleAssignments: {
|
||||||
@@ -482,6 +489,13 @@ describe("resolveAgentPrompt", () => {
|
|||||||
const conciseTriage = resolveAgentPrompt("triage", conciseConfig);
|
const conciseTriage = resolveAgentPrompt("triage", conciseConfig);
|
||||||
expect(conciseTriage).toContain("Keep heartbeat output lean and useful");
|
expect(conciseTriage).toContain("Keep heartbeat output lean and useful");
|
||||||
expect(conciseTriage).toContain("minimum complete PROMPT.md");
|
expect(conciseTriage).toContain("minimum complete PROMPT.md");
|
||||||
|
expect(conciseTriage).toContain("Before `fn_task_create`");
|
||||||
|
expect(conciseTriage).toContain("recent model-availability");
|
||||||
|
expect(conciseTriage).toContain("model fallback exhaustion");
|
||||||
|
expect(conciseTriage).toContain("429/rate-limit");
|
||||||
|
expect(conciseTriage).toContain("404/model-unavailable");
|
||||||
|
expect(conciseTriage).toContain("back off instead of adding load");
|
||||||
|
expect(conciseTriage).toContain("`fn_task_list`/`fn_task_show` results fetched in this heartbeat run");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("merger and senior-engineer heartbeat guidance is role-specific", () => {
|
it("merger and senior-engineer heartbeat guidance is role-specific", () => {
|
||||||
|
|||||||
@@ -1224,12 +1224,18 @@ Treat each heartbeat as a short autonomous execution cycle.
|
|||||||
- If no task is assigned: execute your standing instructions. Review unread messages, scan for blocked or failing engineering work, create narrowly scoped follow-up tasks, and capture durable implementation notes other agents will need later.
|
- If no task is assigned: execute your standing instructions. Review unread messages, scan for blocked or failing engineering work, create narrowly scoped follow-up tasks, and capture durable implementation notes other agents will need later.
|
||||||
- Do not idle simply because no task is linked. Use heartbeat time to reduce engineering risk, unblock work, and keep execution moving in small, concrete increments.`;
|
- Do not idle simply because no task is linked. Use heartbeat time to reduce engineering risk, unblock work, and keep execution moving in small, concrete increments.`;
|
||||||
|
|
||||||
|
/*
|
||||||
|
FNXC:HeartbeatPatrol 2026-07-14-00:00:
|
||||||
|
Idle planning patrol should keep queues actionable, but must not amplify provider outages by creating more work while recent model-availability, fallback-exhaustion, rate-limit, or model-unavailable failures are visible. Progress claims must come from board state fetched in the current heartbeat so stale context does not misreport task status.
|
||||||
|
*/
|
||||||
const TRIAGE_HEARTBEAT_GUIDANCE = `## Heartbeat Run Behavior
|
const TRIAGE_HEARTBEAT_GUIDANCE = `## Heartbeat Run Behavior
|
||||||
|
|
||||||
Use heartbeat runs to keep the planning pipeline healthy.
|
Use heartbeat runs to keep the planning pipeline healthy.
|
||||||
|
|
||||||
- If a task is assigned: turn the rough request into a complete, execution-ready PROMPT.md with clear scope, steps, dependencies, and verification criteria.
|
- If a task is assigned: turn the rough request into a complete, execution-ready PROMPT.md with clear scope, steps, dependencies, and verification criteria.
|
||||||
- If no task is assigned: execute your planning instructions. Patrol for vague requests, blocked tasks that need better specification, review follow-ups that should become new tasks, and dependency gaps that are slowing executors down.
|
- If no task is assigned: execute your planning instructions. Patrol for vague requests, blocked tasks that need better specification, review follow-ups that should become new tasks, and dependency gaps that are slowing executors down.
|
||||||
|
- Before calling \`fn_task_create\` during a no-task heartbeat, check fresh board/tool evidence for recent triage or model-availability failures such as \`unable to select a usable model\`, model fallback exhaustion, 429/rate-limit, or 404/model-unavailable errors. If that condition is present, skip creating new work rather than adding load.
|
||||||
|
- Any claim about an existing task's progress, step completion, blocker, or status must be based on a \`fn_task_list\` or \`fn_task_show\` result fetched during this heartbeat run, not memory or assumptions from previous context.
|
||||||
- Favor ambiguity reduction over busywork. Every heartbeat should leave the queue more actionable than you found it.`;
|
- Favor ambiguity reduction over busywork. Every heartbeat should leave the queue more actionable than you found it.`;
|
||||||
|
|
||||||
const REVIEWER_HEARTBEAT_GUIDANCE = `## Heartbeat Run Behavior
|
const REVIEWER_HEARTBEAT_GUIDANCE = `## Heartbeat Run Behavior
|
||||||
@@ -1270,6 +1276,8 @@ Keep heartbeat output lean and useful.
|
|||||||
|
|
||||||
- If a task is assigned: produce the minimum complete PROMPT.md needed for an executor to act safely.
|
- If a task is assigned: produce the minimum complete PROMPT.md needed for an executor to act safely.
|
||||||
- If no task is assigned: execute your planning instructions, scan for underspecified or blocked work, and turn it into short, actionable task specs or follow-up tickets.
|
- If no task is assigned: execute your planning instructions, scan for underspecified or blocked work, and turn it into short, actionable task specs or follow-up tickets.
|
||||||
|
- Before \`fn_task_create\`, check fresh board/tool evidence for recent model-availability, model fallback exhaustion, 429/rate-limit, or 404/model-unavailable failures; if present, back off instead of adding load.
|
||||||
|
- State existing-task progress, blockers, or status only from \`fn_task_list\`/\`fn_task_show\` results fetched in this heartbeat run.
|
||||||
- Prefer crisp decisions, clear file scope, and concrete verification steps over narrative detail.`;
|
- Prefer crisp decisions, clear file scope, and concrete verification steps over narrative detail.`;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user