({
config,
setMessages,
setIsLoading,
setToolUseConfirmQueue,
tools,
}: UseDirectConnectProps)
| 40 | } |
| 41 | |
| 42 | export function useDirectConnect({ |
| 43 | config, |
| 44 | setMessages, |
| 45 | setIsLoading, |
| 46 | setToolUseConfirmQueue, |
| 47 | tools, |
| 48 | }: UseDirectConnectProps): UseDirectConnectResult { |
| 49 | const isRemoteMode = !!config |
| 50 | |
| 51 | const managerRef = useRef<DirectConnectSessionManager | null>(null) |
| 52 | const hasReceivedInitRef = useRef(false) |
| 53 | const isConnectedRef = useRef(false) |
| 54 | |
| 55 | // Keep a ref to tools so the WebSocket callback doesn't go stale |
| 56 | const toolsRef = useRef(tools) |
| 57 | useEffect(() => { |
| 58 | toolsRef.current = tools |
| 59 | }, [tools]) |
| 60 | |
| 61 | useEffect(() => { |
| 62 | if (!config) { |
| 63 | return |
| 64 | } |
| 65 | |
| 66 | hasReceivedInitRef.current = false |
| 67 | logForDebugging(`[useDirectConnect] Connecting to ${config.wsUrl}`) |
| 68 | |
| 69 | const manager = new DirectConnectSessionManager(config, { |
| 70 | onMessage: sdkMessage => { |
| 71 | if (isSessionEndMessage(sdkMessage)) { |
| 72 | setIsLoading(false) |
| 73 | } |
| 74 | |
| 75 | // Skip duplicate init messages (server sends one per turn) |
| 76 | if (sdkMessage.type === 'system' && sdkMessage.subtype === 'init') { |
| 77 | if (hasReceivedInitRef.current) { |
| 78 | return |
| 79 | } |
| 80 | hasReceivedInitRef.current = true |
| 81 | } |
| 82 | |
| 83 | const converted = convertSDKMessage(sdkMessage, { |
| 84 | convertToolResults: true, |
| 85 | }) |
| 86 | if (converted.type === 'message') { |
| 87 | setMessages(prev => [...prev, converted.message]) |
| 88 | } |
| 89 | }, |
| 90 | onPermissionRequest: (request, requestId) => { |
| 91 | logForDebugging( |
| 92 | `[useDirectConnect] Permission request for tool: ${request.tool_name}`, |
| 93 | ) |
| 94 | |
| 95 | const tool = |
| 96 | findToolByName(toolsRef.current, request.tool_name) ?? |
| 97 | createToolStub(request.tool_name) |
| 98 | |
| 99 | const syntheticMessage = createSyntheticAssistantMessage( |
no test coverage detected