startTool method

Future<void> startTool(
  1. String toolId, {
  2. required void onData(
    1. CommandResultDto commandOutput
    ),
  3. required void onError(
    1. CommandResultDto commandOutput
    ),
  4. void onStreamError(
    1. Object error,
    2. StackTrace stackTrace
    )?,
  5. int timeoutSeconds = -1,
})

POST /tools/{toolId}/start

Implementation

Future<void> startTool(
  String toolId, {
  required void Function(CommandResultDto commandOutput) onData,
  required void Function(CommandResultDto commandError) onError,
  void Function(Object error, StackTrace stackTrace)? onStreamError,
  int timeoutSeconds = -1,
}) async {
  var terminalErrorReported = false;
  try {
    final queryParameters = <String, dynamic>{
      if (timeoutSeconds >= 0) 'timeout': '$timeoutSeconds',
    };
    final sseStream = await toolSse.request(
      '/${toolId}/start',
      queryParameters: queryParameters,
    );
    var terminalReceived = false;
    await for (final chunk in sseStream) {
      DaemonApiException? terminalError;
      SseClient.parse(chunk, (event, data) {
        final result = CommandResultDto.fromJson(data);
        if (event == EventType.DATA) {
          onData(result);
        } else if (event == EventType.DONE) {
          terminalReceived = true;
        } else if (event == EventType.ERROR) {
          terminalReceived = true;
          terminalErrorReported = true;
          onError(result);
          terminalError = DaemonApiException(
            code: 'TOOL_START_FAILED',
            message: result.error ?? 'OpenTool start failed',
            retryable: false,
            details: result.toJson(),
          );
        }
      });
      if (terminalError != null) throw terminalError!;
      if (terminalReceived) return;
    }
    if (!terminalReceived) {
      throw const SseProtocolException(
        'Start stream closed before a terminal done or error event',
      );
    }
  } catch (error, stackTrace) {
    final normalized = _normalizeError(error);
    if (!terminalErrorReported && onStreamError != null) {
      onStreamError(normalized, stackTrace);
    }
    if (identical(normalized, error)) rethrow;
    Error.throwWithStackTrace(normalized, stackTrace);
  }
}