feat(FN-5053): merge fusion/fn-5053 — align no-task heartbeat prompts
Squash-merge of fusion/fn-5053 (7 commits including retry duplicates).
Drops stale conflict in packages/core/src/index.ts (FN-5053 branch
re-exported symbols that main already exports) and packages/core/src/store.ts
(branch had a stale, narrower updateTask signature; main is authoritative).
Manual CEO recovery after the trailerless-commit attribution bug
(now fixed by FN-5090 in 92be8225e) stranded this task in in-review.
Fusion-Task-Id: FN-5053
This commit is contained in:
@@ -13,6 +13,9 @@ import {
|
||||
HEARTBEAT_NO_TASK_SYSTEM_PROMPT,
|
||||
HEARTBEAT_PROCEDURE,
|
||||
HEARTBEAT_NO_TASK_PROCEDURE,
|
||||
HEARTBEAT_NO_TASK_PROCEDURE_STRICT,
|
||||
HEARTBEAT_NO_TASK_PROCEDURE_LITE,
|
||||
HEARTBEAT_NO_TASK_PROCEDURE_OFF,
|
||||
} from "../agent-heartbeat.js";
|
||||
import { AgentLogger } from "../agent-logger.js";
|
||||
import * as agentTools from "../agent-tools.js";
|
||||
@@ -97,9 +100,68 @@ describe("createHeartbeatTools", () => {
|
||||
|
||||
it("heartbeat no-task system prompt documents coding-capable workspace access without task-scoped tools", () => {
|
||||
expect(HEARTBEAT_NO_TASK_SYSTEM_PROMPT).toContain("coding-capable workspace tools");
|
||||
expect(HEARTBEAT_NO_TASK_SYSTEM_PROMPT).not.toContain("fn_task_document_write");
|
||||
expect(HEARTBEAT_NO_TASK_SYSTEM_PROMPT).not.toContain("fn_task_document_read");
|
||||
expect(HEARTBEAT_NO_TASK_SYSTEM_PROMPT).not.toContain("fn_task_log");
|
||||
});
|
||||
|
||||
describe("FN-5053 no-task heartbeat prompt/tool alignment", () => {
|
||||
const FORBIDDEN_NO_TASK_TOOLS = [
|
||||
"fn_task_log",
|
||||
"fn_task_document_write",
|
||||
"fn_task_document_read",
|
||||
"fn_task_update",
|
||||
"fn_task_done",
|
||||
] as const;
|
||||
|
||||
const REQUIRED_NO_TASK_TOOLS = [
|
||||
"fn_task_create",
|
||||
"fn_list_agents",
|
||||
"fn_delegate_task",
|
||||
"fn_get_agent_config",
|
||||
"fn_update_agent_config",
|
||||
"fn_agent_create",
|
||||
"fn_agent_delete",
|
||||
"fn_send_message",
|
||||
"fn_read_messages",
|
||||
"fn_post_room_message",
|
||||
"fn_memory_search",
|
||||
"fn_memory_get",
|
||||
"fn_memory_append",
|
||||
"fn_web_fetch",
|
||||
"fn_read_evaluations",
|
||||
"fn_update_identity",
|
||||
"fn_reflect_on_performance",
|
||||
"fn_heartbeat_done",
|
||||
] as const;
|
||||
|
||||
const NO_TASK_PROMPT_VARIANTS = [
|
||||
HEARTBEAT_NO_TASK_SYSTEM_PROMPT,
|
||||
HEARTBEAT_NO_TASK_PROCEDURE_STRICT,
|
||||
HEARTBEAT_NO_TASK_PROCEDURE_LITE,
|
||||
HEARTBEAT_NO_TASK_PROCEDURE_OFF,
|
||||
] as const;
|
||||
|
||||
it.each(FORBIDDEN_NO_TASK_TOOLS)("FN-5053 excludes forbidden no-task tool reference %s", (toolName) => {
|
||||
for (const promptText of NO_TASK_PROMPT_VARIANTS) {
|
||||
expect(promptText).not.toContain(toolName);
|
||||
}
|
||||
});
|
||||
|
||||
it.each(REQUIRED_NO_TASK_TOOLS)("FN-5053 keeps required no-task tool in inventory: %s", (toolName) => {
|
||||
expect(HEARTBEAT_NO_TASK_SYSTEM_PROMPT).toContain(toolName);
|
||||
});
|
||||
|
||||
it("FN-5053 keeps no-task procedure persist-progress guidance on ambient tools", () => {
|
||||
const expectedPersistLine = "fn_task_create, fn_delegate_task, fn_send_message, fn_memory_append.";
|
||||
expect(HEARTBEAT_NO_TASK_PROCEDURE_STRICT).toContain(expectedPersistLine);
|
||||
expect(HEARTBEAT_NO_TASK_PROCEDURE_LITE).toContain(expectedPersistLine);
|
||||
expect(HEARTBEAT_NO_TASK_PROCEDURE_STRICT).toContain("fn_heartbeat_done");
|
||||
expect(HEARTBEAT_NO_TASK_PROCEDURE_LITE).toContain("fn_heartbeat_done");
|
||||
expect(HEARTBEAT_NO_TASK_PROCEDURE_OFF).toContain("fn_heartbeat_done");
|
||||
});
|
||||
|
||||
it("FN-5053 keeps task-bound task-scoped guidance intact", () => {
|
||||
expect(HEARTBEAT_SYSTEM_PROMPT).toContain("fn_task_log");
|
||||
expect(HEARTBEAT_SYSTEM_PROMPT).toContain("fn_task_document_write");
|
||||
});
|
||||
});
|
||||
|
||||
it("returns task, delegation, and agent-config tools", () => {
|
||||
|
||||
@@ -422,7 +422,7 @@ Your job:
|
||||
3. Use fn_task_create to spawn follow-up work.
|
||||
4. Use fn_list_agents and fn_delegate_task to coordinate with other agents.
|
||||
5. Use fn_get_agent_config and fn_update_agent_config to read/tune direct-report agents for better routing outcomes.
|
||||
5. Call fn_heartbeat_done when finished with an optional summary of what was accomplished.
|
||||
6. Call fn_heartbeat_done when finished with an optional summary of what was accomplished.
|
||||
|
||||
Examples of ONE useful action:
|
||||
- DO: create a clearly scoped task for a newly discovered reliability issue.
|
||||
@@ -436,6 +436,10 @@ You have coding-capable workspace tools (read/write/edit/bash within worktree bo
|
||||
- fn_task_create
|
||||
- fn_list_agents and fn_delegate_task
|
||||
- fn_get_agent_config and fn_update_agent_config (for direct reports only)
|
||||
- fn_agent_create and fn_agent_delete (for direct reports only)
|
||||
- fn_read_evaluations and fn_update_identity (available in no-task runs)
|
||||
- fn_reflect_on_performance when reflection is enabled for this run
|
||||
- fn_web_fetch
|
||||
- fn_memory_search, fn_memory_get, and fn_memory_append
|
||||
- fn_heartbeat_done
|
||||
- fn_send_message, fn_read_messages, and fn_post_room_message when messaging/room tools are enabled for this run (they may not always be available)
|
||||
@@ -2142,7 +2146,9 @@ export class HeartbeatMonitor {
|
||||
// For no-task runs, exclude fn_task_log and document tools (they require a taskId)
|
||||
let heartbeatTools: ToolDefinition[];
|
||||
if (isNoTaskRun) {
|
||||
// No-task runs: fn_task_create, fn_list_agents, fn_delegate_task, fn_get_agent_config, fn_update_agent_config, messaging, memory, fn_heartbeat_done
|
||||
// No-task runs: task creation/delegation, direct-report config + provisioning,
|
||||
// optional messaging/room + reflection, evaluation/identity, web fetch,
|
||||
// memory tools, and fn_heartbeat_done. Task-scoped tools are intentionally excluded.
|
||||
heartbeatTools = [];
|
||||
|
||||
// fn_task_create tool
|
||||
|
||||
Reference in New Issue
Block a user