invokeTool method

Future<ToolCallOutput> invokeTool({
  1. required String toolkit,
  2. required String tool,
  3. required ToolInput input,
  4. String? participantId,
  5. String? onBehalfOfId,
  6. Map<String, dynamic>? callerContext,
})

Implementation

Future<ToolCallOutput> invokeTool({
  required String toolkit,
  required String tool,
  required ToolInput input,
  String? participantId,
  String? onBehalfOfId,
  Map<String, dynamic>? callerContext,
}) async {
  final toolCallId = _uuid.v4();
  final controller = StreamController<Content>(
    onCancel: () {
      _toolCallStreams.remove(toolCallId);
    },
  );
  _toolCallStreams[toolCallId] = controller;

  final request = <String, dynamic>{
    "toolkit": toolkit,
    "tool": tool,
    "participant_id": participantId,
    "on_behalf_of_id": onBehalfOfId,
    "caller_context": callerContext,
    "tool_call_id": toolCallId,
  };

  Uint8List? invokeData;
  Future<void>? inputTask;

  if (input is ToolContentInput) {
    final packedInput = unpackMessage(input.content.pack());
    request["arguments"] = packedInput.header;
    invokeData = packedInput.payload.isEmpty ? null : packedInput.payload;
  } else if (input is ToolStreamInput) {
    final openChunk = unpackMessage(ControlContent(method: "open").pack());
    request["arguments"] = openChunk.header;
    inputTask = _streamInvokeToolRequestChunks(toolCallId: toolCallId, inputChunks: input.chunks);
  } else {
    await _closeToolCallStream(toolCallId: toolCallId, controller: controller);
    throw RoomServerException("invokeTool input must be ToolContentInput or ToolStreamInput");
  }

  try {
    final response = await _awaitInvokeResponse(
      toolCallId: toolCallId,
      requestFuture: room.sendRequest("agent.invoke_tool", request, data: invokeData),
    );

    if (response is ControlContent && response.method == "open") {
      if (inputTask != null) {
        unawaited(
          inputTask.catchError((Object error, StackTrace stackTrace) async {
            final wrapped = error is RoomServerException ? error : RoomServerException("request stream failed: $error");
            if (!controller.isClosed) {
              controller.addError(wrapped, stackTrace);
            }
            await _closeToolCallStream(toolCallId: toolCallId, controller: controller);
          }),
        );
      }
      return ToolStreamOutput(controller.stream);
    }

    if (inputTask != null) {
      await inputTask;
    }
    await _closeToolCallStream(toolCallId: toolCallId, controller: controller);
    return ToolContentOutput(response);
  } catch (error, stackTrace) {
    if (inputTask != null) {
      await Future.wait([inputTask.catchError((_) {})]);
    }
    if (!controller.isClosed) {
      controller.addError(error, stackTrace);
    }
    await _closeToolCallStream(toolCallId: toolCallId, controller: controller);
    rethrow;
  }
}