* Invoke a tool.
(
tool: string,
args: Record<string, unknown>,
options: InvokeToolOptions = {},
)
| 145 | * Invoke a tool. |
| 146 | */ |
| 147 | async invokeTool( |
| 148 | tool: string, |
| 149 | args: Record<string, unknown>, |
| 150 | options: InvokeToolOptions = {}, |
| 151 | ): Promise<ToolInvokeResult> { |
| 152 | const id = randomUUID(); |
| 153 | const req: DaemonRequest<ToolInvokeParams> = { |
| 154 | v: DAEMON_PROTOCOL_VERSION, |
| 155 | id, |
| 156 | method: 'tool.invoke', |
| 157 | params: { |
| 158 | tool, |
| 159 | args, |
| 160 | }, |
| 161 | }; |
| 162 | |
| 163 | return new Promise<ToolInvokeResult>((resolve, reject) => { |
| 164 | const socket = net.createConnection(this.socketPath); |
| 165 | let settled = false; |
| 166 | let terminalResult: ToolInvokeResult | undefined; |
| 167 | let receivedTerminalResult = false; |
| 168 | let timeoutId: NodeJS.Timeout; |
| 169 | |
| 170 | const failWithTransportError = (err: Error): void => { |
| 171 | if (!settled) { |
| 172 | settled = true; |
| 173 | clearTimeout(timeoutId); |
| 174 | socket.destroy(); |
| 175 | reject(err); |
| 176 | } |
| 177 | }; |
| 178 | |
| 179 | const scheduleTimeout = (): void => { |
| 180 | clearTimeout(timeoutId); |
| 181 | timeoutId = setTimeout(() => { |
| 182 | failWithTransportError(new Error(`Daemon request timed out after ${this.timeout}ms`)); |
| 183 | }, this.timeout); |
| 184 | }; |
| 185 | |
| 186 | const resolveTerminalResult = (): void => { |
| 187 | queueMicrotask(() => { |
| 188 | if (settled || terminalResult === undefined) { |
| 189 | return; |
| 190 | } |
| 191 | |
| 192 | settled = true; |
| 193 | clearTimeout(timeoutId); |
| 194 | socket.end(); |
| 195 | resolve(terminalResult); |
| 196 | }); |
| 197 | }; |
| 198 | |
| 199 | scheduleTimeout(); |
| 200 | |
| 201 | socket.on('error', (err) => { |
| 202 | if (settled) { |
| 203 | return; |
| 204 | } |
no test coverage detected