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