fix(engine): wire TaskStore into runtime AgentStore so heartbeat auto-claim works
The InProcessRuntime constructed its AgentStore with only `rootDir`, leaving task-claim/checkout/release operations unconfigured. As a result, the heartbeat auto-claim scan logged "TaskStore not configured for task-claim operations" whenever a relevant todo was found. Pass the runtime's TaskStore through to the AgentStore so claimTaskForAgent succeeds. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -55,6 +55,11 @@ vi.mock("@fusion/core", async () => {
|
||||
self.init = vi.fn().mockResolvedValue(undefined);
|
||||
self.listTasks = vi.fn().mockResolvedValue([]);
|
||||
self.getTask = mockTaskStoreGetTask;
|
||||
// AgentStore now receives this TaskStore (passed from the runtime),
|
||||
// so methods it calls during assign/claim/checkout flows must exist.
|
||||
self.logEntry = vi.fn().mockResolvedValue(undefined);
|
||||
self.updateTask = vi.fn().mockImplementation(async (taskId: string, patch: Record<string, unknown>) => ({ id: taskId, ...patch }));
|
||||
self.moveTask = vi.fn().mockResolvedValue(undefined);
|
||||
self.getSettings = vi.fn().mockImplementation(async () => structuredClone(mockTaskStoreSettings));
|
||||
self.getMissionStore = vi.fn().mockReturnValue({
|
||||
listMissions: vi.fn().mockReturnValue([]),
|
||||
@@ -475,6 +480,26 @@ describe("InProcessRuntime", () => {
|
||||
expect(monitor).toBeDefined();
|
||||
}, 30000);
|
||||
|
||||
// Regression: heartbeat auto-claim path was warning
|
||||
// "TaskStore not configured for task-claim operations" because the
|
||||
// runtime built its AgentStore without passing taskStore through.
|
||||
it("wires AgentStore with TaskStore so claimTaskForAgent does not throw", async () => {
|
||||
await runtime.start();
|
||||
const store = getAgentStore(runtime);
|
||||
const agent = await store.createAgent({
|
||||
name: "claim-wiring",
|
||||
role: "executor",
|
||||
metadata: { agentKind: "task-worker" },
|
||||
runtimeConfig: { enabled: false },
|
||||
});
|
||||
// taskStore.getTask is mocked to return null in this suite, so we
|
||||
// expect the guarded "task_not_found" path rather than the
|
||||
// unconfigured-taskStore throw.
|
||||
mockTaskStoreGetTask.mockResolvedValueOnce(null);
|
||||
const result = await store.claimTaskForAgent(agent.id, "FN-DOES-NOT-EXIST");
|
||||
expect(result).toEqual({ ok: false, reason: "task_not_found" });
|
||||
}, 30000);
|
||||
|
||||
it("should return TriggerScheduler after start", async () => {
|
||||
await runtime.start();
|
||||
const triggerScheduler = runtime.getTriggerScheduler();
|
||||
|
||||
@@ -321,7 +321,7 @@ export class InProcessRuntime
|
||||
let agentStoreForReflection: import("@fusion/core").AgentStore | undefined;
|
||||
try {
|
||||
const { AgentStore: AgentStoreClass } = await import("@fusion/core");
|
||||
agentStoreForReflection = new AgentStoreClass({ rootDir: this.taskStore.getFusionDir() });
|
||||
agentStoreForReflection = new AgentStoreClass({ rootDir: this.taskStore.getFusionDir(), taskStore: this.taskStore });
|
||||
await agentStoreForReflection.init();
|
||||
runtimeLog.log("AgentStore initialized for reflection service");
|
||||
} catch (agentErr) {
|
||||
|
||||
Reference in New Issue
Block a user