diff --git a/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-integration-broker.test.ts b/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-integration-broker.test.ts index dda3fc8dd..599d7194c 100644 --- a/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-integration-broker.test.ts +++ b/packages/cloud-agents/src/server/fast-agent/__tests__/fast-agent-integration-broker.test.ts @@ -376,6 +376,85 @@ describe('fast-agent integration broker', () => { }); }); + it('defaults Brain query controls and preserves the native result', async () => { + const nativeResult = [ + { + slug: 'tasks/example', + page_id: 42, + title: 'Example', + chunk_text: 'Full native result', + score: 0.9, + }, + ]; + mocks.callMcpTool.mockResolvedValue(nativeResult); + + const result = await callFastAgentIntegration( + auditContext, + [ + { + id: 'gbrain', + name: 'Brain', + description: 'Shared memory', + tools: [{ name: 'query' }], + }, + ], + { + integrationId: 'gbrain', + toolName: 'query', + args: { query: 'fast mode' }, + }, + ); + + expect(mocks.callMcpTool).toHaveBeenCalledWith( + expect.objectContaining({ + args: { + query: 'fast mode', + detail: 'low', + adaptive_return: true, + limit: 6, + }, + }), + ); + expect(result).toBe(nativeResult); + }); + + it('preserves explicit Brain query detail controls', async () => { + mocks.callMcpTool.mockResolvedValue([]); + + await callFastAgentIntegration( + auditContext, + [ + { + id: 'gbrain', + name: 'Brain', + description: 'Shared memory', + tools: [{ name: 'query' }], + }, + ], + { + integrationId: 'gbrain', + toolName: 'query', + args: { + query: 'all context', + detail: 'high', + adaptive_return: false, + limit: 20, + }, + }, + ); + + expect(mocks.callMcpTool).toHaveBeenCalledWith( + expect.objectContaining({ + args: { + query: 'all context', + detail: 'high', + adaptive_return: false, + limit: 20, + }, + }), + ); + }); + it('does not execute a tool when its durable audit cannot be created', async () => { mocks.beginIntegrationCall.mockRejectedValue(new Error('database offline')); diff --git a/packages/cloud-agents/src/server/fast-agent/fast-agent-integration-broker.ts b/packages/cloud-agents/src/server/fast-agent/fast-agent-integration-broker.ts index 8faad1283..cc1c5d81b 100644 --- a/packages/cloud-agents/src/server/fast-agent/fast-agent-integration-broker.ts +++ b/packages/cloud-agents/src/server/fast-agent/fast-agent-integration-broker.ts @@ -58,6 +58,7 @@ const FAST_AGENT_INTEGRATION_TOOL_CACHE_TTL_MS = 5 * 60_000; const FAST_AGENT_INTEGRATION_TOOL_CACHE_RETRY_MS = 30_000; const FAST_AGENT_INTEGRATION_DISCOVERY_TIMEOUT_MS = 10_000; const FAST_AGENT_INTEGRATION_CALL_TIMEOUT_MS = 60_000; +const FAST_AGENT_BRAIN_QUERY_DEFAULT_LIMIT = 6; type IntegrationToolCacheEntry = { expiresAt: number; @@ -329,20 +330,28 @@ export async function callFastAgentIntegration( try { const { apiBaseUrl, authToken } = await resolveBrokerAuth(context); + const effectiveArgs = + integration.id === BRAIN_MCP_ID && request.toolName === 'query' + ? { + ...request.args, + detail: request.args.detail ?? 'low', + adaptive_return: request.args.adaptive_return ?? true, + limit: request.args.limit ?? FAST_AGENT_BRAIN_QUERY_DEFAULT_LIMIT, + } + : request.args; const result = await withFastIntegrationTimeout( (signal) => callMcpTool({ url: integrationProxyUrl(apiBaseUrl, integration.id), headers: { Authorization: `Bearer ${authToken}` }, toolName: request.toolName, - args: request.args, + args: effectiveArgs, toolCallId: `fast:${audit.id}:${integration.id}:${request.toolName}`, signal, }), FAST_AGENT_INTEGRATION_CALL_TIMEOUT_MS, `Fast ${integration.id}/${request.toolName} integration call`, ); - try { await completeSlackFastIntegrationCall({ id: audit.id,