From 1f231a6ca0a21190dac9526ae0859a376c9d65af Mon Sep 17 00:00:00 2001 From: "@mrubens" <2600+mrubens@users.noreply.github.com> Date: Mon, 24 Aug 2026 23:22:05 +0000 Subject: [PATCH] fix: allow Fast parent automation management --- .../__tests__/fast-agent-service.test.ts | 37 ++++++++++--------- .../server/fast-agent/fast-agent-service.ts | 7 ++-- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-service.test.ts b/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-service.test.ts index f317c77f8..86c3b17a8 100644 --- a/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-service.test.ts +++ b/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-service.test.ts @@ -19,6 +19,7 @@ const mocks = vi.hoisted(() => ({ bindExecutor: vi.fn(), nativeExecutor: undefined as | ((call: { + agent?: string; name: string; args: Record; }) => Promise) @@ -154,9 +155,13 @@ function callbacks( }; } -async function invokeTool(name: string, args: Record) { +async function invokeTool( + name: string, + args: Record, + agent?: string, +) { if (!mocks.nativeExecutor) throw new Error('Native executor is not bound.'); - return mocks.nativeExecutor({ name, args }); + return mocks.nativeExecutor({ name, args, ...(agent ? { agent } : {}) }); } describe('answerFastAgentQuestion native OpenCode tools', () => { @@ -895,7 +900,7 @@ describe('answerFastAgentQuestion native OpenCode tools', () => { ); }); - it('runs Roomote custom automation mutations without an acknowledgement gate', async () => { + it('lets the Fast parent manage custom automations through integration_call', async () => { const resolveMcpServerConfigs = vi.fn(async () => ({})); mocks.listIntegrations.mockResolvedValue([ { @@ -906,7 +911,7 @@ describe('answerFastAgentQuestion native OpenCode tools', () => { }, ]); mocks.callIntegration.mockResolvedValue({ - automation: { id: 'automation-1', enabled: false }, + automations: [], }); const toolResults: unknown[] = []; mocks.generateText.mockImplementationOnce( @@ -914,15 +919,15 @@ describe('answerFastAgentQuestion native OpenCode tools', () => { await options.onSessionReady('opencode-session-1'); for (let attempt = 0; attempt < 2; attempt += 1) { toolResults.push( - await invokeTool(nativeToolNames.integrationCall, { - integrationId: 'roomote', - toolName: 'manage_custom_automations', - arguments: { - action: 'update', - automationId: 'automation-1', - enabled: false, + await invokeTool( + nativeToolNames.integrationCall, + { + integrationId: 'roomote', + toolName: 'manage_custom_automations', + arguments: { action: 'list' }, }, - }), + 'roomote', + ), ); } await invokeTool(nativeToolNames.sendChatReply, { @@ -940,7 +945,7 @@ describe('answerFastAgentQuestion native OpenCode tools', () => { expect(toolResults[0]).toEqual({ success: true, - result: { automation: { id: 'automation-1', enabled: false } }, + result: { automations: [] }, }); expect(toolResults[1]).toEqual({ success: false, @@ -957,11 +962,7 @@ describe('answerFastAgentQuestion native OpenCode tools', () => { { integrationId: 'roomote', toolName: 'manage_custom_automations', - args: { - action: 'update', - automationId: 'automation-1', - enabled: false, - }, + args: { action: 'list' }, }, ); }); diff --git a/packages/cloud-agents/src/server/fast-agent/fast-agent-service.ts b/packages/cloud-agents/src/server/fast-agent/fast-agent-service.ts index d0d022a06..faf8cd7f4 100644 --- a/packages/cloud-agents/src/server/fast-agent/fast-agent-service.ts +++ b/packages/cloud-agents/src/server/fast-agent/fast-agent-service.ts @@ -835,6 +835,7 @@ export async function answerFastAgentQuestion({ const executeNativeTool = async ( call: FastAgentNativeToolCall, + isFastParentAgent: boolean, ): Promise => { const recordToolFinished = diagnostics.recordNativeToolStarted(call.name); @@ -952,7 +953,7 @@ export async function answerFastAgentQuestion({ const managesCustomAutomations = args.integrationId === ROOMOTE_MCP_ID && args.toolName === MANAGE_CUSTOM_AUTOMATIONS_TOOL.name; - if (call.agent && managesCustomAutomations) { + if (!isFastParentAgent && managesCustomAutomations) { return { success: false, error: @@ -1258,7 +1259,7 @@ export async function answerFastAgentQuestion({ unbindExecutors.add( bindFastAgentNativeToolExecutor( openCodeSessionID, - executeNativeTool, + (call) => executeNativeTool(call, true), ), ); }, @@ -1275,7 +1276,7 @@ export async function answerFastAgentQuestion({ call.agent === ROOMOTE_OPENCODE_JUDGE_AGENT_NAME) && isFastAgentSubagentTool(call.name) - ? executeNativeTool(call) + ? executeNativeTool(call, false) : Promise.resolve({ success: false, error: