feat(FN-3957): add delegate_task override flag to bypass executor role poli

Adds a `delegate_override` flag to the `delegate_task` tool that allows executor-role tasks to be assigned to non-executor agents. The override is persisted as metadata in the extension and honored by the heartbeat inbox guard, with test coverage across engine, core, and CLI packages plus updated do

Fusion-Task-Id: FN-3957
This commit is contained in:
Fusion
2026-05-10 19:19:15 -07:00
committed by gsxdsm
parent a5a794d12e
commit a0c7c3315a
12 changed files with 160 additions and 10 deletions

View File

@@ -27,7 +27,7 @@ These tools are **not** part of the user-invokable extension surface. They are i
| `fn_update_identity` | heartbeat | Update the current agent's own `soul`, `instructionsText`, or `memory` fields | `soul?` (string), `instructionsText?` (string), `memory?` (string) |
| `fn_reflect_on_performance` | executor, heartbeat (when reflection service enabled) | Generate reflection insights from prior runs | `focus_area?` (string) |
| `fn_list_agents` | triage, executor, heartbeat | List agents (optionally filtered) | `role?` (string), `state?` (string), `includeEphemeral?` (boolean) |
| `fn_delegate_task` | triage, executor, heartbeat | Create and assign a new task to a specific agent | `agent_id` (string), `description` (string), `dependencies?` (string[]) |
| `fn_delegate_task` | triage, executor, heartbeat | Create and assign a new task to a specific agent | `agent_id` (string), `description` (string), `dependencies?` (string[]), `override?` (boolean) |
| `fn_get_agent_config` | executor, heartbeat | Read full config for a direct-report agent | `agent_id` (string) |
| `fn_update_agent_config` | executor, heartbeat | Update config fields for a direct-report, non-ephemeral agent | `agent_id` (string), optional: `soul`, `instructions_text`, `instructions_path`, `heartbeat_procedure_path`, `heartbeat_interval_ms`, `heartbeat_timeout_ms`, `max_concurrent_runs`, `message_response_mode` |
| `fn_agent_create` | executor, heartbeat | Create a non-ephemeral direct-report agent | `name` (string), `role` (string), optional: `soul`, `instructions_text`, `instructions_path`, `reportsTo`, `heartbeat_interval_ms`, `heartbeat_timeout_ms`, `max_concurrent_runs`, `message_response_mode` |

View File

@@ -2007,6 +2007,14 @@ describe("fn pi extension (runnable structured-output regression slice)", () =>
expect(result.isError).not.toBe(true);
expect(result.details.agentId).toBe(reviewer.id);
const store = new TaskStore(tmpDir);
await store.init();
const task = await store.getTask(result.details.taskId);
expect(task.sourceMetadata).toMatchObject({ executorRoleOverride: true });
const selected = await store.selectNextTaskForAgent(reviewer.id, { id: reviewer.id, role: reviewer.role });
expect(selected?.task.id).toBe(task.id);
});
it("wires dependencies correctly", async () => {

View File

@@ -2747,7 +2747,10 @@ export default function kbExtension(pi: ExtensionAPI) {
dependencies: params.dependencies,
column: "todo",
assignedAgentId: params.agent_id,
source: { sourceType: "api" },
source: {
sourceType: "api",
...(params.override === true ? { sourceMetadata: { executorRoleOverride: true } } : {}),
},
});
const deps = task.dependencies.length ? ` (depends on: ${task.dependencies.join(", ")})` : "";