mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
fix(logs) Run workflows client side in mothership to transmit logs (#3529)
* Run workflows client side in mothership to transmit logs * Initialize set as constant, prevent duplicate execution * Fix lint --------- Co-authored-by: Theodore Li <theo@sim.ai>
This commit is contained in:
@@ -2,7 +2,9 @@ import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { createLogger } from '@sim/logger'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { executeRunToolOnClient } from '@/lib/copilot/client-sse/run-tool-execution'
|
||||
import { MOTHERSHIP_CHAT_API_PATH } from '@/lib/copilot/constants'
|
||||
import { isWorkflowToolName } from '@/lib/copilot/workflow-tools'
|
||||
import { knowledgeKeys } from '@/hooks/queries/kb/knowledge'
|
||||
import { tableKeys } from '@/hooks/queries/tables'
|
||||
import {
|
||||
@@ -249,6 +251,7 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet
|
||||
let buffer = ''
|
||||
const blocks: ContentBlock[] = []
|
||||
const toolMap = new Map<string, number>()
|
||||
const clientExecutionStarted = new Set<string>()
|
||||
let activeSubagent: string | undefined
|
||||
let lastTableId: string | null = null
|
||||
let lastWorkflowId: string | null = null
|
||||
@@ -336,6 +339,7 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet
|
||||
const id = parsed.toolCallId
|
||||
const data = getPayloadData(parsed)
|
||||
const name = parsed.toolName || data?.name || 'unknown'
|
||||
const isPartial = data?.partial === true
|
||||
if (!id) break
|
||||
|
||||
if (RESOURCE_TOOL_NAMES.has(name)) {
|
||||
@@ -373,6 +377,18 @@ export function useChat(workspaceId: string, initialChatId?: string): UseChatRet
|
||||
}
|
||||
}
|
||||
flush()
|
||||
|
||||
if (
|
||||
parsed.type === 'tool_call' &&
|
||||
ui?.clientExecutable &&
|
||||
isWorkflowToolName(name) &&
|
||||
!isPartial &&
|
||||
!clientExecutionStarted.has(id)
|
||||
) {
|
||||
clientExecutionStarted.add(id)
|
||||
const args = data?.arguments ?? data?.input ?? {}
|
||||
executeRunToolOnClient(id, name, args as Record<string, unknown>)
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'tool_result': {
|
||||
|
||||
@@ -202,6 +202,7 @@ export interface SSEPayloadUI {
|
||||
phaseLabel?: string
|
||||
icon?: string
|
||||
internal?: boolean
|
||||
clientExecutable?: boolean
|
||||
}
|
||||
|
||||
export interface SSEPayloadData {
|
||||
@@ -209,6 +210,7 @@ export interface SSEPayloadData {
|
||||
ui?: SSEPayloadUI
|
||||
id?: string
|
||||
agent?: string
|
||||
partial?: boolean
|
||||
arguments?: Record<string, unknown>
|
||||
input?: Record<string, unknown>
|
||||
result?: unknown
|
||||
|
||||
@@ -18,6 +18,7 @@ import type {
|
||||
StreamingContext,
|
||||
ToolCallState,
|
||||
} from '@/lib/copilot/orchestrator/types'
|
||||
import { isWorkflowToolName } from '@/lib/copilot/workflow-tools'
|
||||
import { executeToolAndReport, waitForToolCompletion, waitForToolDecision } from './tool-execution'
|
||||
|
||||
const logger = createLogger('CopilotSseHandlers')
|
||||
@@ -265,9 +266,17 @@ export const sseHandlers: Record<string, SSEHandler> = {
|
||||
})
|
||||
}
|
||||
|
||||
// Non-interactive mode (Mothership/MCP): skip confirmation & client gates,
|
||||
// execute server-side directly.
|
||||
if (options.interactive === false) {
|
||||
if (clientExecutable && isWorkflowToolName(toolName)) {
|
||||
toolCall.status = 'executing'
|
||||
const completion = await waitForToolCompletion(
|
||||
toolCallId,
|
||||
options.timeout || STREAM_TIMEOUT_MS,
|
||||
options.abortSignal
|
||||
)
|
||||
handleClientCompletion(toolCall, toolCallId, completion)
|
||||
return
|
||||
}
|
||||
if (options.autoExecuteTools !== false) {
|
||||
fireToolExecution()
|
||||
}
|
||||
@@ -514,9 +523,17 @@ export const subAgentHandlers: Record<string, SSEHandler> = {
|
||||
})
|
||||
}
|
||||
|
||||
// Non-interactive mode (Mothership/MCP): skip confirmation & client gates,
|
||||
// execute server-side directly.
|
||||
if (options.interactive === false) {
|
||||
if (clientExecutable && isWorkflowToolName(toolName)) {
|
||||
toolCall.status = 'executing'
|
||||
const completion = await waitForToolCompletion(
|
||||
toolCallId,
|
||||
options.timeout || STREAM_TIMEOUT_MS,
|
||||
options.abortSignal
|
||||
)
|
||||
handleClientCompletion(toolCall, toolCallId, completion)
|
||||
return
|
||||
}
|
||||
if (options.autoExecuteTools !== false) {
|
||||
fireToolExecution()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user