Skip to content

Commit 6d74f7b

Browse files
committed
Fix deploy subagent
1 parent 6818c51 commit 6d74f7b

File tree

4 files changed

+110
-3
lines changed

4 files changed

+110
-3
lines changed

apps/sim/app/api/mcp/copilot/route.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { type NextRequest, NextResponse } from 'next/server'
1919
import { validateOAuthAccessToken } from '@/lib/auth/oauth-token'
2020
import { getHighestPrioritySubscription } from '@/lib/billing/core/subscription'
2121
import { ORCHESTRATION_TIMEOUT_MS, SIM_AGENT_API_URL } from '@/lib/copilot/constants'
22+
import { orchestrateCopilotStream } from '@/lib/copilot/orchestrator'
2223
import { orchestrateSubagentStream } from '@/lib/copilot/orchestrator/subagent'
2324
import {
2425
executeToolServerSide,
@@ -28,6 +29,10 @@ import { DIRECT_TOOL_DEFS, SUBAGENT_TOOL_DEFS } from '@/lib/copilot/tools/mcp/de
2829
import { env } from '@/lib/core/config/env'
2930
import { RateLimiter } from '@/lib/core/rate-limiter'
3031
import { getBaseUrl } from '@/lib/core/utils/urls'
32+
import {
33+
authorizeWorkflowByWorkspacePermission,
34+
resolveWorkflowIdForUser,
35+
} from '@/lib/workflows/utils'
3136

3237
const logger = createLogger('CopilotMcpAPI')
3338
const mcpRateLimiter = new RateLimiter()
@@ -660,12 +665,110 @@ async function handleDirectToolCall(
660665
}
661666
}
662667

668+
/**
669+
* Build mode uses the main chat orchestrator with the 'fast' command instead of
670+
* the subagent endpoint. In Go, 'build' is not a registered subagent — it's a mode
671+
* (ModeFast) on the main chat processor that bypasses subagent orchestration and
672+
* executes all tools directly.
673+
*/
674+
async function handleBuildToolCall(
675+
args: Record<string, unknown>,
676+
userId: string,
677+
abortSignal?: AbortSignal
678+
): Promise<CallToolResult> {
679+
try {
680+
const requestText = (args.request as string) || JSON.stringify(args)
681+
const workflowId = args.workflowId as string | undefined
682+
683+
const resolved = workflowId
684+
? await (async () => {
685+
const authorization = await authorizeWorkflowByWorkspacePermission({
686+
workflowId,
687+
userId,
688+
action: 'read',
689+
})
690+
return authorization.allowed ? { workflowId } : null
691+
})()
692+
: await resolveWorkflowIdForUser(userId)
693+
694+
if (!resolved?.workflowId) {
695+
return {
696+
content: [
697+
{
698+
type: 'text',
699+
text: JSON.stringify(
700+
{
701+
success: false,
702+
error: 'workflowId is required for build. Call create_workflow first.',
703+
},
704+
null,
705+
2
706+
),
707+
},
708+
],
709+
isError: true,
710+
}
711+
}
712+
713+
const chatId = randomUUID()
714+
715+
const requestPayload = {
716+
message: requestText,
717+
workflowId: resolved.workflowId,
718+
userId,
719+
model: DEFAULT_COPILOT_MODEL,
720+
mode: 'agent',
721+
commands: ['fast'],
722+
messageId: randomUUID(),
723+
chatId,
724+
}
725+
726+
const result = await orchestrateCopilotStream(requestPayload, {
727+
userId,
728+
workflowId: resolved.workflowId,
729+
chatId,
730+
goRoute: '/api/mcp',
731+
autoExecuteTools: true,
732+
timeout: 300000,
733+
interactive: false,
734+
abortSignal,
735+
})
736+
737+
const responseData = {
738+
success: result.success,
739+
content: result.content,
740+
toolCalls: result.toolCalls,
741+
error: result.error,
742+
}
743+
744+
return {
745+
content: [{ type: 'text', text: JSON.stringify(responseData, null, 2) }],
746+
isError: !result.success,
747+
}
748+
} catch (error) {
749+
logger.error('Build tool call failed', { error })
750+
return {
751+
content: [
752+
{
753+
type: 'text',
754+
text: `Build failed: ${error instanceof Error ? error.message : String(error)}`,
755+
},
756+
],
757+
isError: true,
758+
}
759+
}
760+
}
761+
663762
async function handleSubagentToolCall(
664763
toolDef: (typeof SUBAGENT_TOOL_DEFS)[number],
665764
args: Record<string, unknown>,
666765
userId: string,
667766
abortSignal?: AbortSignal
668767
): Promise<CallToolResult> {
768+
if (toolDef.agentId === 'build') {
769+
return handleBuildToolCall(args, userId, abortSignal)
770+
}
771+
669772
try {
670773
const requestText =
671774
(args.request as string) ||

apps/sim/lib/copilot/orchestrator/sse/handlers/tool-execution.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ export async function executeToolAndReport(
455455
logger.info('Tool execution succeeded', {
456456
toolCallId: toolCall.id,
457457
toolName: toolCall.name,
458+
output: result.output,
458459
})
459460
} else {
460461
logger.warn('Tool execution failed', {

apps/sim/lib/copilot/orchestrator/tool-executor/deployment-tools/deploy.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,12 @@ export async function executeDeployMcp(
335335
}
336336
}
337337

338-
export async function executeRedeploy(context: ExecutionContext): Promise<ToolCallResult> {
338+
export async function executeRedeploy(
339+
params: { workflowId?: string },
340+
context: ExecutionContext
341+
): Promise<ToolCallResult> {
339342
try {
340-
const workflowId = context.workflowId
343+
const workflowId = params.workflowId || context.workflowId
341344
if (!workflowId) {
342345
return { success: false, error: 'workflowId is required' }
343346
}

apps/sim/lib/copilot/orchestrator/tool-executor/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ const SIM_WORKFLOW_TOOL_HANDLERS: Record<
864864
deploy_api: (p, c) => executeDeployApi(p as DeployApiParams, c),
865865
deploy_chat: (p, c) => executeDeployChat(p as DeployChatParams, c),
866866
deploy_mcp: (p, c) => executeDeployMcp(p as DeployMcpParams, c),
867-
redeploy: (_p, c) => executeRedeploy(c),
867+
redeploy: (p, c) => executeRedeploy(p as { workflowId?: string }, c),
868868
check_deployment_status: (p, c) =>
869869
executeCheckDeploymentStatus(p as CheckDeploymentStatusParams, c),
870870
list_workspace_mcp_servers: (p, c) =>

0 commit comments

Comments
 (0)