package dev.langchain4j.model.openai;

import dev.ai4j.openai4j.chat.ChatCompletionModel;
import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.agent.tool.ToolSpecification;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.Tokenizer;
import dev.langchain4j.model.output.Response;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.opentest4j.AssertionFailedError;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;

import static dev.ai4j.openai4j.chat.ChatCompletionModel.*;
import static dev.langchain4j.agent.tool.JsonSchemaProperty.*;
import static dev.langchain4j.data.message.AiMessage.aiMessage;
import static dev.langchain4j.data.message.SystemMessage.systemMessage;
import static dev.langchain4j.data.message.ToolExecutionResultMessage.toolExecutionResultMessage;
import static dev.langchain4j.data.message.UserMessage.userMessage;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.data.Percentage.withPercentage;
import static org.junit.jupiter.params.provider.Arguments.arguments;

// TODO use exact model for Tokenizer (the one returned by LLM)
@Disabled("this test is very long and expensive, we will need to set a schedule for it to run maybe 1 time per month")
class OpenAiTokenizerIT {

    // my API key does not have access to these models
    private static final Set<ChatCompletionModel> MODELS_WITHOUT_ACCESS = new HashSet<>(asList(
            GPT_3_5_TURBO_0125,
            GPT_4_32K,
            GPT_4_32K_0314,
            GPT_4_32K_0613
    ));

    private static final Set<ChatCompletionModel> MODELS_WITHOUT_TOOL_SUPPORT = new HashSet<>(asList(
            GPT_4_0314,
            GPT_4_VISION_PREVIEW
    ));

    private static final Set<ChatCompletionModel> MODELS_WITH_PARALLEL_TOOL_SUPPORT = new HashSet<>(asList(
            // TODO add GPT_3_5_TURBO once it points to GPT_3_5_TURBO_1106
            GPT_3_5_TURBO_1106,
            GPT_3_5_TURBO_0125,
            GPT_4_TURBO_PREVIEW,
            GPT_4_1106_PREVIEW,
            GPT_4_0125_PREVIEW
    ));

    @ParameterizedTest
    @MethodSource
    void should_count_tokens_in_messages(List<ChatMessage> messages, ChatCompletionModel modelName) {

        // given
        OpenAiChatModel model = OpenAiChatModel.builder()
                .baseUrl(System.getenv("OPENAI_BASE_URL"))
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName(modelName.toString())
                .maxTokens(1) // we don't need outputs, let's not waste tokens
                .logRequests(true)
                .logResponses(true)
                .build();

        int expectedTokenCount = model.generate(messages).tokenUsage().inputTokenCount();

        Tokenizer tokenizer = new OpenAiTokenizer(modelName.toString());

        // when
        int tokenCount = tokenizer.estimateTokenCountInMessages(messages);

        // then
        assertThat(tokenCount).isEqualTo(expectedTokenCount);
    }

    static Stream<Arguments> should_count_tokens_in_messages() {
        return stream(ChatCompletionModel.values())
                .filter(model -> !MODELS_WITHOUT_ACCESS.contains(model))
                .flatMap(model -> Stream.of(
                        arguments(singletonList(systemMessage("Be friendly.")), model),
                        arguments(singletonList(systemMessage("You are a helpful assistant, help the user!")), model),

                        arguments(singletonList(userMessage("Hi")), model),
                        arguments(singletonList(userMessage("Hello, how are you?")), model),

                        arguments(singletonList(userMessage("Stan", "Hi")), model),
                        arguments(singletonList(userMessage("Klaus", "Hi")), model),
                        arguments(singletonList(userMessage("Giovanni", "Hi")), model),

                        arguments(singletonList(aiMessage("Hi")), model),
                        arguments(singletonList(aiMessage("Hello, how can I help you?")), model),

                        arguments(asList(
                                systemMessage("Be helpful"),
                                userMessage("hi")
                        ), model),

                        arguments(asList(
                                systemMessage("Be helpful"),
                                userMessage("hi"),
                                aiMessage("Hello, how can I help you?"),
                                userMessage("tell me a joke")
                        ), model),

                        arguments(asList(
                                systemMessage("Be helpful"),
                                userMessage("hi"),
                                aiMessage("Hello, how can I help you?"),
                                userMessage("tell me a joke"),
                                aiMessage("Why don't scientists trust atoms?\n\nBecause they make up everything!"),
                                userMessage("tell me another one, this one is not funny")
                        ), model)
                ));
    }

    @ParameterizedTest
    @MethodSource
    void should_count_tokens_in_messages_with_single_tool(List<ChatMessage> messages, ChatCompletionModel modelName) {

        // given
        OpenAiChatModel model = OpenAiChatModel.builder()
                .baseUrl(System.getenv("OPENAI_BASE_URL"))
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName(modelName.toString())
                .maxTokens(1) // we don't need outputs, let's not waste tokens
                .logRequests(true)
                .logResponses(true)
                .build();

        int expectedTokenCount = model.generate(messages).tokenUsage().inputTokenCount();

        Tokenizer tokenizer = new OpenAiTokenizer(modelName.toString());

        // when
        int tokenCount = tokenizer.estimateTokenCountInMessages(messages);

        // then
        assertThat(tokenCount).isCloseTo(expectedTokenCount, withPercentage(4));
    }

    static Stream<Arguments> should_count_tokens_in_messages_with_single_tool() {
        return stream(ChatCompletionModel.values())
                .filter(model -> !MODELS_WITHOUT_ACCESS.contains(model))
                .filter(model -> !MODELS_WITHOUT_TOOL_SUPPORT.contains(model))
                .flatMap(model -> Stream.of(

                        // various tool "name" lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("time") // 1 token
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23:59")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_time") // 2 tokens
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("b", null, "23:59")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("c")
                                                .name("get_current_time") // 3 tokens
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("c", null, "23:59")
                        ), model),

                        // 1 argument, various argument "name" lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\"}") // 1 token
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23:59")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_time")
                                                .arguments("{\"target_city\":\"Berlin\"}") // 2 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("b", null, "23:59")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("c")
                                                .name("current_time")
                                                .arguments("{\"target_city_name\":\"Berlin\"}") // 3 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("c", null, "23:59")
                        ), model),

                        // 1 argument, various argument "value" lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\"}") // 1 token
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23:59")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Munich\"}") // 3 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("b", null, "23:59")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("c")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Pietramontecorvino\"}") // 8 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("c", null, "23:59")
                        ), model),

                        // 1 argument, various numeric argument "value" lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city_id\": 189}") // 1 token
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23:59")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_time")
                                                .arguments("{\"city_id\": 189647}") // 2 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("b", null, "23:59")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("c")
                                                .name("current_time")
                                                .arguments("{\"city_id\": 189647852}") // 3 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("c", null, "23:59")
                        ), model),

                        // 2 arguments
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\",\"country\":\"Germany\"}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23:59")
                        ), model),

                        // 3 arguments
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\",\"country\":\"Germany\",\"format\":\"24\"}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23:59")
                        ), model),

                        // various result lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23") // 1 token
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_time")
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("b", null, "23:59") // 3 tokens
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("c")
                                                .name("current_time")
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("c", null, "23:59:59") // 5 tokens
                        ), model)
                ));
    }

    @ParameterizedTest
    @MethodSource
    void should_count_tokens_in_messages_with_multiple_tools(List<ChatMessage> messages,
                                                             ChatCompletionModel modelName) {
        // given
        OpenAiChatModel model = OpenAiChatModel.builder()
                .baseUrl(System.getenv("OPENAI_BASE_URL"))
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName(modelName.toString())
                .maxTokens(1) // we don't need outputs, let's not waste tokens
                .logRequests(true)
                .logResponses(true)
                .build();

        int expectedTokenCount = model.generate(messages).tokenUsage().inputTokenCount();

        Tokenizer tokenizer = new OpenAiTokenizer(modelName.toString());

        // when
        int tokenCount = tokenizer.estimateTokenCountInMessages(messages);

        // then
        assertThat(tokenCount).isCloseTo(expectedTokenCount, withPercentage(4));
    }

    static Stream<Arguments> should_count_tokens_in_messages_with_multiple_tools() {
        return stream(ChatCompletionModel.values())
                .filter(model -> !MODELS_WITHOUT_ACCESS.contains(model))
                .filter(MODELS_WITH_PARALLEL_TOOL_SUPPORT::contains)
                .flatMap(model -> Stream.of(

                        // various tool "name" lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("time") // 1 token
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("temperature") // 1 token
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time") // 2 tokens
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature") // 2 tokens
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("get_current_time") // 3 tokens
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("get_current_temperature") // 3 tokens
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),

                        // 1 argument, various argument "name" lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\"}") // 1 token
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"city\":\"Berlin\"}") // 1 token
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"target_city\":\"Berlin\"}") // 2 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"target_city\":\"Berlin\"}") // 2 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"target_city_name\":\"Berlin\"}") // 3 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"target_city_name\":\"Berlin\"}") // 3 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),

                        // 1 argument, various argument "value" lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\"}") // 1 token
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"city\":\"Berlin\"}") // 1 token
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Munich\"}") // 3 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"city\":\"Munich\"}") // 3 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Pietramontecorvino\"}") // 8 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"city\":\"Pietramontecorvino\"}") // 8 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),

                        // 1 argument, various numeric argument "value" lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city_id\": 189}") // 1 token
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"city_id\": 189}") // 1 token
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city_id\": 189647}") // 2 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"city_id\": 189647}") // 2 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city_id\": 189647852}") // 3 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"city_id\": 189647852}") // 3 tokens
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),

                        // 2 arguments
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\",\"country\":\"Germany\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"city\":\"Berlin\",\"country\":\"Germany\"}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),

                        // 3 arguments
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\",\"country\":\"Germany\",\"format\":\"24\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{\"city\":\"Berlin\",\"country\":\"Germany\",\"unit\":\"C\"}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2")
                        ), model),

                        // various result lengths
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23"), // 1 token
                                toolExecutionResultMessage("b", null, "17") // 1 token
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23:59"), // 3 tokens
                                toolExecutionResultMessage("b", null, "17.5") // 3 tokens
                        ), model),
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("current_time")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("current_temperature")
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "23:59:59"), // 5 tokens
                                toolExecutionResultMessage("b", null, "17.5 grad C") // 5 tokens
                        ), model),

                        // 3 tools without arguments
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("time")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("temperature")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("c")
                                                .name("weather")
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2"),
                                toolExecutionResultMessage("c", null, "3")
                        ), model),

                        // 3 tools with arguments
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("time")
                                                .arguments("{\"city\":\"Berlin\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("temperature")
                                                .arguments("{\"city\":\"Berlin\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("c")
                                                .name("weather")
                                                .arguments("{\"city\":\"Berlin\"}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2"),
                                toolExecutionResultMessage("c", null, "3")
                        ), model),

                        // 4 tools without arguments
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("time")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("temperature")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("c")
                                                .name("weather")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("d")
                                                .name("UV")
                                                .arguments("{}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2"),
                                toolExecutionResultMessage("c", null, "3"),
                                toolExecutionResultMessage("d", null, "4")
                        ), model),

                        // 4 tools with arguments
                        arguments(asList(
                                aiMessage(
                                        ToolExecutionRequest.builder()
                                                .id("a")
                                                .name("time")
                                                .arguments("{\"city\":\"Berlin\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("b")
                                                .name("temperature")
                                                .arguments("{\"city\":\"Berlin\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("c")
                                                .name("weather")
                                                .arguments("{\"city\":\"Berlin\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .id("d")
                                                .name("UV")
                                                .arguments("{\"city\":\"Berlin\"}")
                                                .build()
                                ),
                                toolExecutionResultMessage("a", null, "1"),
                                toolExecutionResultMessage("b", null, "2"),
                                toolExecutionResultMessage("c", null, "3"),
                                toolExecutionResultMessage("d", null, "4")
                        ), model)
                ));
    }

    @ParameterizedTest
    @MethodSource
    void should_count_tokens_in_tool_specifications(List<ToolSpecification> toolSpecifications,
                                                    ChatCompletionModel modelName) {
        // given
        OpenAiChatModel model = OpenAiChatModel.builder()
                .baseUrl(System.getenv("OPENAI_BASE_URL"))
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName(modelName.toString())
                .maxTokens(2) // we don't need outputs, let's not waste tokens
                .logRequests(true)
                .logResponses(true)
                .build();

        List<ChatMessage> dummyMessages = singletonList(userMessage("hi"));

        Tokenizer tokenizer = new OpenAiTokenizer(modelName.toString());

        int expectedTokenCount = model.generate(dummyMessages, toolSpecifications).tokenUsage().inputTokenCount()
                - tokenizer.estimateTokenCountInMessages(dummyMessages);

        // when
        int tokenCount = tokenizer.estimateTokenCountInToolSpecifications(toolSpecifications);

        // then
        assertThat(tokenCount).isCloseTo(expectedTokenCount, withPercentage(2));
    }

    static Stream<Arguments> should_count_tokens_in_tool_specifications() {
        return stream(ChatCompletionModel.values())
                .filter(model -> !MODELS_WITHOUT_ACCESS.contains(model))
                .filter(model -> !MODELS_WITHOUT_TOOL_SUPPORT.contains(model))
                .flatMap(model -> Stream.of(

                        // "name" of various lengths
                        arguments(singletonList(ToolSpecification.builder()
                                .name("time") // 1 token
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time") // 2 tokens
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("get_current_time") // 3 tokens
                                .build()), model),

                        // "description" of various lengths
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("time") // 1 token
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time") // 2 tokens
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("returns current time in 24-hour format") // 8 tokens
                                .build()), model),

                        // 1 parameter with "name" of various lengths
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("city") // 1 token
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("target_city") // 2 tokens
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("target_city_name") // 3 tokens
                                .build()), model),

                        // 1 parameter with "description" of various lengths
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("city", description("city")) // 1 token
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("city", description("target city name")) // 3 tokens
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("city", description("city for which time should be returned")) // 7 tokens
                                .build()), model),

                        // 1 parameter with varying "type"
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("city", STRING)
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("city", INTEGER)
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("cities", ARRAY, items(INTEGER))
                                .build()), model),

                        // 1 parameter with "enum" of various range of values
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_temperature")
                                .description("current temperature")
                                .addParameter("unit", enums("C"))
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_temperature")
                                .description("current temperature")
                                .addParameter("unit", enums("C", "K"))
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_temperature")
                                .description("current temperature")
                                .addParameter("unit", enums("C", "K", "F"))
                                .build()), model),

                        // 1 parameter with "enum" of various name lengths
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_temperature")
                                .description("current temperature")
                                .addParameter("unit", enums("celsius", "kelvin", "fahrenheit")) // 2 tokens each
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_temperature")
                                .description("current temperature")
                                .addParameter("unit", enums("CELSIUS", "KELVIN", "FAHRENHEIT")) // 3-5 tokens
                                .build()), model),

                        // 2 parameters with "name" of various length
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("city") // 1 token
                                .addParameter("country") // 1 token
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("target_city") // 2 tokens
                                .addParameter("target_country") // 2 tokens
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("target_city_name") // 3 tokens
                                .addParameter("target_country_name") // 3 tokens
                                .build()), model),

                        // 3 parameters with "name" of various length
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("city") // 1 token
                                .addParameter("country") // 1 token
                                .addParameter("format", enums("12H", "24H")) // 1 token
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("target_city") // 2 tokens
                                .addParameter("target_country") // 2 tokens
                                .addParameter("time_format", enums("12H", "24H")) // 2 tokens
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("target_city_name") // 3 tokens
                                .addParameter("target_country_name") // 3 tokens
                                .addParameter("current_time_format", enums("12H", "24H")) // 3 tokens
                                .build()), model),

                        // 1 optional parameter with "name" of various lengths
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addOptionalParameter("city") // 1 token
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addOptionalParameter("target_city") // 2 tokens
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addOptionalParameter("target_city_name") // 3 tokens
                                .build()), model),

                        // 2 optional parameters with "name" of various lengths
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addOptionalParameter("city") // 1 token
                                .addOptionalParameter("country") // 1 token
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addOptionalParameter("target_city") // 2 tokens
                                .addOptionalParameter("target_country") // 2 tokens
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addOptionalParameter("target_city_name") // 3 tokens
                                .addOptionalParameter("target_country_name") // 3 tokens
                                .build()), model),

                        // 1 mandatory, 1 optional parameters with "name" of various lengths
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("city") // 1 token
                                .addOptionalParameter("country") // 1 token
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("target_city") // 2 tokens
                                .addOptionalParameter("target_country") // 2 tokens
                                .build()), model),
                        arguments(singletonList(ToolSpecification.builder()
                                .name("current_time")
                                .description("current time")
                                .addParameter("target_city_name") // 3 tokens
                                .addOptionalParameter("target_country_name") // 3 tokens
                                .build()), model),

                        // 2 tools
                        arguments(asList(
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("current time")
                                        .addParameter("city_name", description("city name"))
                                        .addOptionalParameter("country_name", description("optional country name"))
                                        .build(),
                                ToolSpecification.builder()
                                        .name("current_temperature")
                                        .description("current temperature")
                                        .addParameter("city_name", description("city name"))
                                        .addOptionalParameter("country_name", description("optional country name"))
                                        .build()
                        ), model),

                        // 3 tools
                        arguments(asList(
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("current time")
                                        .addParameter("city_name", description("city name"))
                                        .addOptionalParameter("country_name", description("optional country name"))
                                        .build(),
                                ToolSpecification.builder()
                                        .name("current_temperature")
                                        .description("current temperature")
                                        .addParameter("city_name", description("city name"))
                                        .addOptionalParameter("country_name", description("optional country name"))
                                        .build(),
                                ToolSpecification.builder()
                                        .name("current_weather")
                                        .description("current weather")
                                        .addParameter("city_name", description("city name"))
                                        .addOptionalParameter("country_name", description("optional country name"))
                                        .build()
                        ), model)
                ));
    }

    @ParameterizedTest
    @MethodSource
    void should_count_tokens_in_tool_execution_request(UserMessage userMessage,
                                                       ToolSpecification toolSpecification,
                                                       ToolExecutionRequest expectedToolExecutionRequest,
                                                       ChatCompletionModel modelName) {
        // given
        OpenAiChatModel model = OpenAiChatModel.builder()
                .baseUrl(System.getenv("OPENAI_BASE_URL"))
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName(modelName.toString())
                .logRequests(true)
                .logResponses(true)
                .build();

        Response<AiMessage> response = model.generate(singletonList(userMessage), singletonList(toolSpecification));

        List<ToolExecutionRequest> toolExecutionRequests = response.content().toolExecutionRequests();
        // we need to ensure that model generated expected tool execution request,
        // then we can use output token count as a reference
        assertThat(toolExecutionRequests).hasSize(1);
        ToolExecutionRequest toolExecutionRequest = toolExecutionRequests.get(0);
        assertThat(toolExecutionRequest.name()).isEqualTo(expectedToolExecutionRequest.name());
        assertThat(toolExecutionRequest.arguments()).isEqualToIgnoringWhitespace(expectedToolExecutionRequest.arguments());

        int expectedTokenCount = response.tokenUsage().outputTokenCount();

        Tokenizer tokenizer = new OpenAiTokenizer(modelName.toString());

        // when
        int tokenCount = tokenizer.estimateTokenCountInToolExecutionRequests(toolExecutionRequests);

        // then
        try {
            assertThat(tokenCount).isEqualTo(expectedTokenCount);
        } catch (AssertionFailedError e) {
            if (modelName == GPT_3_5_TURBO_1106) {
                // sometimes GPT_3_5_TURBO_1106 calculates tokens wrongly
                // see https://community.openai.com/t/inconsistent-token-billing-for-tool-calls-in-gpt-3-5-turbo-1106
                // TODO remove once they fix it
                e.printStackTrace();
                // there is some pattern to it, so we are going to check if this is really the case or our calculation is wrong
                Tokenizer tokenizer2 = new OpenAiTokenizer(GPT_3_5_TURBO.toString());
                int tokenCount2 = tokenizer2.estimateTokenCountInToolExecutionRequests(toolExecutionRequests);
                assertThat(tokenCount2).isEqualTo(expectedTokenCount - 3);
            } else {
                throw e;
            }
        }
    }

    @ParameterizedTest
    @MethodSource("should_count_tokens_in_tool_execution_request")
    void should_count_tokens_in_forceful_tool_specification_and_execution_request(UserMessage userMessage,
                                                                                  ToolSpecification toolSpecification,
                                                                                  ToolExecutionRequest expectedToolExecutionRequest,
                                                                                  ChatCompletionModel modelName) {
        // given
        OpenAiChatModel model = OpenAiChatModel.builder()
                .baseUrl(System.getenv("OPENAI_BASE_URL"))
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName(modelName.toString())
                .logRequests(true)
                .logResponses(true)
                .build();

        Response<AiMessage> response = model.generate(singletonList(userMessage), toolSpecification);

        Tokenizer tokenizer = new OpenAiTokenizer(modelName.toString());

        int expectedTokenCountInSpecification = response.tokenUsage().inputTokenCount()
                - tokenizer.estimateTokenCountInMessages(singletonList(userMessage));

        // when
        int tokenCountInSpecification = tokenizer.estimateTokenCountInForcefulToolSpecification(toolSpecification);

        // then
        assertThat(tokenCountInSpecification).isEqualTo(expectedTokenCountInSpecification);

        // given
        List<ToolExecutionRequest> toolExecutionRequests = response.content().toolExecutionRequests();
        // we need to ensure that model generated expected tool execution request,
        // then we can use output token count as a reference
        assertThat(toolExecutionRequests).hasSize(1);
        ToolExecutionRequest toolExecutionRequest = toolExecutionRequests.get(0);
        assertThat(toolExecutionRequest.name()).isEqualTo(expectedToolExecutionRequest.name());
        assertThat(toolExecutionRequest.arguments()).isEqualToIgnoringWhitespace(expectedToolExecutionRequest.arguments());

        int expectedTokenCountInToolRequest = response.tokenUsage().outputTokenCount();

        // when
        int tokenCountInToolRequest = tokenizer.estimateTokenCountInForcefulToolExecutionRequest(toolExecutionRequest);

        // then
        assertThat(tokenCountInToolRequest).isEqualTo(expectedTokenCountInToolRequest);
    }

    static Stream<Arguments> should_count_tokens_in_tool_execution_request() {
        return stream(ChatCompletionModel.values())
                .filter(model -> !MODELS_WITHOUT_ACCESS.contains(model))
                .filter(model -> !MODELS_WITHOUT_TOOL_SUPPORT.contains(model))
                .flatMap(model -> Stream.of(

                        // no arguments, different lengths of "name"
                        arguments(
                                userMessage("What is the time now?"),
                                ToolSpecification.builder()
                                        .name("time") // 1 token
                                        .description("returns current time")
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("time") // 1 token
                                        .arguments("{}")
                                        .build(),
                                model
                        ),
                        arguments(
                                userMessage("What is the time now?"),
                                ToolSpecification.builder()
                                        .name("current_time") // 2 tokens
                                        .description("returns current time")
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time") // 2 tokens
                                        .arguments("{}")
                                        .build(),
                                model
                        ),
                        arguments(
                                userMessage("What is the time now?"),
                                ToolSpecification.builder()
                                        .name("get_current_time") // 3 tokens
                                        .description("returns current time")
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("get_current_time") // 3 tokens
                                        .arguments("{}")
                                        .build(),
                                model
                        ),

                        // one argument, different lengths of "arguments"
                        arguments(
                                userMessage("What is the time in Berlin now?"),
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("returns current time")
                                        .addParameter("city")
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time")
                                        .arguments("{\"city\":\"Berlin\"}") // 5 tokens
                                        .build(),
                                model
                        ),
                        arguments(
                                userMessage("What is the time in Munich now?"),
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("returns current time")
                                        .addParameter("city")
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time")
                                        .arguments("{\"city\":\"Munich\"}") // 7 tokens
                                        .build(),
                                model
                        ),
                        arguments(
                                userMessage("What is the time in Pietramontecorvino now?"),
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("returns current time")
                                        .addParameter("city")
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time")
                                        .arguments("{\"city\":\"Pietramontecorvino\"}") // 12 tokens
                                        .build(),
                                model
                        ),

                        // two arguments, different lengths of "arguments"
                        arguments(
                                userMessage("What is the time in Berlin now?"),
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("returns current time")
                                        .addParameter("city")
                                        .addParameter("country")
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time")
                                        .arguments("{\"country\":\"Germany\",\"city\":\"Berlin\"}") // 9 tokens
                                        .build(),
                                model
                        ),
                        arguments(
                                userMessage("What is the time in Munich now?"),
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("returns current time")
                                        .addParameter("city")
                                        .addParameter("country")
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time")
                                        .arguments("{\"country\":\"Germany\",\"city\":\"Munich\"}") // 11 tokens
                                        .build(),
                                model
                        ),
                        arguments(
                                userMessage("What is the time in Pietramontecorvino now?"),
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("returns current time")
                                        .addParameter("city")
                                        .addParameter("country")
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time")
                                        .arguments("{\"country\":\"Italy\",\"city\":\"Pietramontecorvino\"}") // 16 tokens
                                        .build(),
                                model
                        ),

                        // three arguments, different lengths of "arguments"
                        arguments(
                                userMessage("What is the time in Berlin now in 24-hour format?"),
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("returns current time")
                                        .addParameter("city")
                                        .addParameter("country")
                                        .addParameter("format", enums("12", "24"))
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time")
                                        .arguments("{\"country\":\"Germany\",\"city\":\"Berlin\",\"format\":\"24\"}") // 13 tokens
                                        .build(),
                                model
                        ),
                        arguments(
                                userMessage("What is the time in Munich now in 24-hour format?"),
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("returns current time")
                                        .addParameter("city")
                                        .addParameter("country")
                                        .addParameter("format", enums("12", "24"))
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time")
                                        .arguments("{\"country\":\"Germany\",\"city\":\"Munich\",\"format\":\"24\"}") // 15 tokens
                                        .build(),
                                model
                        ),
                        arguments(
                                userMessage("What is the time in Pietramontecorvino now in 24-hour format?"),
                                ToolSpecification.builder()
                                        .name("current_time")
                                        .description("returns current time")
                                        .addParameter("city")
                                        .addParameter("country")
                                        .addParameter("format", enums("12", "24"))
                                        .build(),
                                ToolExecutionRequest.builder()
                                        .name("current_time")
                                        .arguments("{\"country\":\"Italy\",\"city\":\"Pietramontecorvino\",\"format\":\"24\"}") // 20 tokens
                                        .build(),
                                model
                        )
                ));
    }

    @ParameterizedTest
    @MethodSource
    void should_count_tokens_in_multiple_tool_execution_requests(UserMessage userMessage,
                                                                 List<ToolSpecification> toolSpecifications,
                                                                 List<ToolExecutionRequest> expectedToolExecutionRequests,
                                                                 ChatCompletionModel modelName) {
        // given
        OpenAiChatModel model = OpenAiChatModel.builder()
                .baseUrl(System.getenv("OPENAI_BASE_URL"))
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .modelName(modelName.toString())
                .logRequests(true)
                .logResponses(true)
                .build();

        Response<AiMessage> response = model.generate(singletonList(userMessage), toolSpecifications);

        List<ToolExecutionRequest> toolExecutionRequests = response.content().toolExecutionRequests();
        // we need to ensure that model generated expected tool execution requests,
        // then we can use output token count as a reference
        assertThat(toolExecutionRequests).hasSize(expectedToolExecutionRequests.size());
        for (int i = 0; i < toolExecutionRequests.size(); i++) {
            ToolExecutionRequest toolExecutionRequest = toolExecutionRequests.get(i);
            ToolExecutionRequest expectedToolExecutionRequest = expectedToolExecutionRequests.get(i);
            assertThat(toolExecutionRequest.name()).isEqualTo(expectedToolExecutionRequest.name());
            assertThat(toolExecutionRequest.arguments()).isEqualToIgnoringWhitespace(expectedToolExecutionRequest.arguments());
        }

        int expectedTokenCount = response.tokenUsage().outputTokenCount();

        Tokenizer tokenizer = new OpenAiTokenizer(modelName.toString());

        // when
        int tokenCount = tokenizer.estimateTokenCountInToolExecutionRequests(toolExecutionRequests);

        // then
        assertThat(tokenCount).isEqualTo(expectedTokenCount);
    }

    static Stream<Arguments> should_count_tokens_in_multiple_tool_execution_requests() {
        return stream(ChatCompletionModel.values())
                .filter(model -> !MODELS_WITHOUT_ACCESS.contains(model))
                .filter(MODELS_WITH_PARALLEL_TOOL_SUPPORT::contains)
                .flatMap(model -> Stream.of(

                        // no arguments, different lengths of "name"
                        arguments(
                                userMessage("What is the time and date now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("time")
                                                .description("returns current time")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("date")
                                                .description("returns current date")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("time") // 1 token
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("date") // 1 token
                                                .arguments("{}")
                                                .build()
                                ),
                                model
                        ),
                        arguments(
                                userMessage("What is the time and date now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("current_time")
                                                .description("returns current time")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("current_date")
                                                .description("returns current date")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("current_time") // 2 tokens
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_date") // 2 tokens
                                                .arguments("{}")
                                                .build()
                                ),
                                model
                        ),
                        arguments(
                                userMessage("What is the time and date now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("get_current_time")
                                                .description("returns current time")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("get_current_date")
                                                .description("returns current date")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("get_current_time") // 3 tokens
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("get_current_date") // 3 tokens
                                                .arguments("{}")
                                                .build()
                                ),
                                model
                        ),

                        // no arguments, 3 tools
                        arguments(
                                userMessage("What is the time and date and location?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("time")
                                                .description("returns current time")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("date")
                                                .description("returns current date")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("location")
                                                .description("returns current location")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("time")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("date")
                                                .arguments("{}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("location")
                                                .arguments("{}")
                                                .build()
                                ),
                                model
                        ),

                        // no arguments, 1 argument
                        arguments(
                                userMessage("What is the time in Munich and date now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("date")
                                                .description("returns current date")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("time")
                                                .arguments("{\"city\":\"Munich\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("date")
                                                .arguments("{}")
                                                .build()
                                ),
                                model
                        ),

                        // one argument, 2 different tools, different lengths of "arguments"
                        arguments(
                                userMessage("What is the time and date in Berlin now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("current_time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("current_date")
                                                .description("returns current date")
                                                .addParameter("city")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\"}") // 5 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_date")
                                                .arguments("{\"city\":\"Berlin\"}") // 5 tokens
                                                .build()
                                ),
                                model
                        ),
                        arguments(
                                userMessage("What is the time and date in Pietramontecorvino now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("current_time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("current_date")
                                                .description("returns current date")
                                                .addParameter("city")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("current_time")
                                                .arguments("{\"city\":\"Pietramontecorvino\"}") // 12 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_date")
                                                .arguments("{\"city\":\"Pietramontecorvino\"}") // 12 tokens
                                                .build()
                                ),
                                model
                        ),

                        // different tools, different lengths of argument values
                        arguments(
                                userMessage("What is the time in Berlin and date in Munich now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("current_time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("current_date")
                                                .description("returns current date")
                                                .addParameter("city")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("current_time")
                                                .arguments("{\"city\":\"Berlin\"}") // 5 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_date")
                                                .arguments("{\"city\":\"Munich\"}") // 7 tokens
                                                .build()
                                ),
                                model
                        ),

                        // different tools, different lengths of "name", different lengths of argument values
                        arguments(
                                userMessage("What is the time in Berlin and date in Munich now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("current_date")
                                                .description("returns current date")
                                                .addParameter("city")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("time") // 1 tokens
                                                .arguments("{\"city\":\"Berlin\"}") // 5 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_date") // 2 tokens
                                                .arguments("{\"city\":\"Munich\"}") // 7 tokens
                                                .build()
                                ),
                                model
                        ),

                        // one argument, 4 tool requests
                        arguments(
                                userMessage("What is the time in Berlin, Munich, London and Paris now?"),
                                singletonList(
                                        ToolSpecification.builder()
                                                .name("time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("time")
                                                .arguments("{\"city\":\"Berlin\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("time")
                                                .arguments("{\"city\":\"Munich\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("time")
                                                .arguments("{\"city\":\"London\"}")
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("time")
                                                .arguments("{\"city\":\"Paris\"}")
                                                .build()
                                ),
                                model
                        ),

                        // two arguments, different lengths of "arguments"
                        arguments(
                                userMessage("What is the time and date in Berlin now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("current_time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .addParameter("country")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("current_date")
                                                .description("returns current date")
                                                .addParameter("city")
                                                .addParameter("country")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("current_time")
                                                .arguments("{\"country\":\"Germany\",\"city\":\"Berlin\"}") // 9 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_date") // 2 tokens
                                                .arguments("{\"country\":\"Germany\",\"city\":\"Berlin\"}") // 9 tokens
                                                .build()
                                ),
                                model
                        ),
                        arguments(
                                userMessage("What is the time and date in Pietramontecorvino now?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("current_time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .addParameter("country")
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("current_date")
                                                .description("returns current date")
                                                .addParameter("city")
                                                .addParameter("country")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("current_time")
                                                .arguments("{\"country\":\"Italy\",\"city\":\"Pietramontecorvino\"}") // 16 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_date")
                                                .arguments("{\"country\":\"Italy\",\"city\":\"Pietramontecorvino\"}") // 16 tokens
                                                .build()
                                ),
                                model
                        ),

                        // three arguments, different lengths of "arguments"
                        arguments(
                                userMessage("What is the time in Berlin and Pietramontecorvino in 24-hour format?"),
                                singletonList(
                                        ToolSpecification.builder()
                                                .name("current_time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .addParameter("country")
                                                .addParameter("format", enums("12", "24"))
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("current_time") // 2 tokens
                                                .arguments("{\"country\":\"Germany\",\"city\":\"Berlin\",\"format\":\"24\"}") // 13 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_time") // 2 tokens
                                                .arguments("{\"country\":\"Italy\",\"city\":\"Pietramontecorvino\",\"format\":\"24\"}") // 20 tokens
                                                .build()
                                ),
                                model
                        ),

                        // three tool execution requests, different tools and lengths of "arguments"
                        arguments(
                                userMessage("What is the time in Berlin and Pietramontecorvino in 24-hour format now and date in Munich?"),
                                asList(
                                        ToolSpecification.builder()
                                                .name("current_time")
                                                .description("returns current time")
                                                .addParameter("city")
                                                .addParameter("country")
                                                .addParameter("format", enums("12", "24"))
                                                .build(),
                                        ToolSpecification.builder()
                                                .name("current_date")
                                                .description("returns current date")
                                                .addParameter("city")
                                                .addParameter("country")
                                                .build()
                                ),
                                asList(
                                        ToolExecutionRequest.builder()
                                                .name("current_time")
                                                .arguments("{\"country\":\"Germany\",\"city\":\"Berlin\",\"format\": \"24\"}") // 14 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_time")
                                                .arguments("{\"country\":\"Italy\",\"city\":\"Pietramontecorvino\",\"format\": \"24\"}") // 21 tokens
                                                .build(),
                                        ToolExecutionRequest.builder()
                                                .name("current_date")
                                                .arguments("{\"country\":\"Germany\",\"city\":\"Munich\"}") // 11 tokens
                                                .build()
                                ),
                                model
                        )
                ));
    }
}
[((6990, 7272), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((6990, 7215), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((6990, 7139), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((6990, 7077), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((7547, 7838), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((7547, 7781), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((7547, 7704), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((7547, 7634), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((8113, 8408), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((8113, 8351), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((8113, 8274), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((8113, 8200), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((8755, 9064), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((8755, 8996), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((8755, 8912), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((8755, 8842), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((9339, 9656), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((9339, 9587), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((9339, 9496), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((9339, 9426), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((9931, 10253), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((9931, 10184), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((9931, 10088), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((9931, 10018), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((10601, 10910), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((10601, 10842), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((10601, 10758), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((10601, 10688), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((11185, 11495), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((11185, 11426), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((11185, 11342), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((11185, 11272), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((11770, 12092), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((11770, 12023), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((11770, 11927), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((11770, 11857), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((12448, 12754), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((12448, 12686), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((12448, 12605), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((12448, 12535), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((13029, 13339), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((13029, 13270), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((13029, 13186), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((13029, 13116), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((13614, 13927), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((13614, 13858), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((13614, 13771), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((13614, 13701), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((14242, 14564), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((14242, 14507), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((14242, 14399), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((14242, 14329), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((14879, 15219), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((14879, 15162), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((14879, 15036), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((14879, 14966), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((15545, 15824), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((15545, 15767), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((15545, 15702), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((15545, 15632), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((16107, 16386), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((16107, 16329), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((16107, 16264), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((16107, 16194), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((16673, 16952), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((16673, 16895), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((16673, 16830), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((16673, 16760), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((18650, 18932), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((18650, 18875), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((18650, 18799), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((18650, 18737), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((18974, 19263), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((18974, 19206), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((18974, 19130), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((18974, 19061), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((19610, 19901), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((19610, 19844), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((19610, 19767), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((19610, 19697), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((19943, 20241), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((19943, 20184), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((19943, 20107), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((19943, 20030), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((20588, 20883), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((20588, 20826), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((20588, 20749), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((20588, 20675), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((20925, 21227), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((20925, 21170), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((20925, 21093), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((20925, 21012), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((21646, 21955), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((21646, 21887), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((21646, 21803), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((21646, 21733), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((21997, 22313), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((21997, 22245), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((21997, 22161), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((21997, 22084), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((22660, 22977), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((22660, 22908), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((22660, 22817), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((22660, 22747), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((23019, 23343), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((23019, 23274), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((23019, 23183), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((23019, 23106), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((23690, 24012), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((23690, 23943), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((23690, 23847), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((23690, 23777), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((24054, 24383), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((24054, 24314), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((24054, 24218), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((24054, 24141), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((24803, 25112), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((24803, 25044), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((24803, 24960), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((24803, 24890), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((25154, 25470), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((25154, 25402), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((25154, 25318), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((25154, 25241), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((25817, 26127), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((25817, 26058), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((25817, 25974), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((25817, 25904), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((26169, 26486), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((26169, 26417), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((26169, 26333), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((26169, 26256), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((26833, 27155), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((26833, 27086), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((26833, 26990), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((26833, 26920), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((27197, 27526), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((27197, 27457), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((27197, 27361), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((27197, 27284), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((27954, 28260), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((27954, 28192), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((27954, 28111), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((27954, 28041), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((28302, 28615), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((28302, 28547), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((28302, 28466), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((28302, 28389), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((28962, 29272), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((28962, 29203), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((28962, 29119), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((28962, 29049), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((29314, 29631), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((29314, 29562), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((29314, 29478), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((29314, 29401), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((29978, 30291), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((29978, 30222), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((29978, 30135), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((29978, 30065), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((30333, 30653), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((30333, 30584), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((30333, 30497), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((30333, 30420), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((31040, 31362), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((31040, 31305), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((31040, 31197), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((31040, 31127), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((31404, 31733), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((31404, 31676), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((31404, 31568), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((31404, 31491), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((32120, 32460), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((32120, 32403), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((32120, 32277), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((32120, 32207), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((32502, 32846), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((32502, 32789), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((32502, 32666), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((32502, 32589), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((33244, 33523), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((33244, 33466), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((33244, 33401), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((33244, 33331), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((33565, 33851), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((33565, 33794), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((33565, 33729), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((33565, 33652), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((34222, 34501), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((34222, 34444), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((34222, 34379), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((34222, 34309), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((34543, 34829), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((34543, 34772), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((34543, 34707), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((34543, 34630), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((35207, 35486), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((35207, 35429), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((35207, 35364), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((35207, 35294), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((35528, 35814), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((35528, 35757), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((35528, 35692), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((35528, 35615), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36256, 36527), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36256, 36470), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36256, 36405), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36256, 36343), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36569, 36847), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36569, 36790), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36569, 36725), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36569, 36656), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36889, 37163), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36889, 37106), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36889, 37041), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((36889, 36976), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((37637, 37927), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((37637, 37870), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((37637, 37786), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((37637, 37724), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((37969, 38266), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((37969, 38209), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((37969, 38125), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((37969, 38056), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((38308, 38601), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((38308, 38544), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((38308, 38460), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((38308, 38395), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39078, 39349), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39078, 39292), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39078, 39227), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39078, 39165), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39391, 39669), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39391, 39612), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39391, 39547), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39391, 39478), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39711, 39985), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39711, 39928), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39711, 39863), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((39711, 39798), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((40027, 40296), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((40027, 40239), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((40027, 40174), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((40027, 40114), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((40846, 41136), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((40846, 41079), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((40846, 40995), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((40846, 40933), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41178, 41475), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41178, 41418), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41178, 41334), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41178, 41265), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41517, 41810), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41517, 41753), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41517, 41669), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41517, 41604), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41852, 42140), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41852, 42083), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41852, 41999), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((41852, 41939), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((44161, 44286), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((44161, 44234), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((44345, 44479), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((44345, 44426), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((44538, 44676), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((44538, 44623), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((44796, 44982), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((44796, 44930), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((44796, 44877), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45041, 45236), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45041, 45183), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45041, 45122), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45295, 45516), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45295, 45463), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45295, 45376), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45646, 45894), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45646, 45842), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45646, 45788), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45646, 45727), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45953, 46209), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45953, 46156), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45953, 46095), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((45953, 46034), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46268, 46529), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46268, 46476), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46268, 46410), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46268, 46349), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46666, 46935), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46666, 46883), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46666, 46808), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46666, 46747), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46994, 47276), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46994, 47223), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46994, 47136), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((46994, 47075), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((47335, 47639), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((47335, 47586), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((47335, 47477), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((47335, 47416), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((47758, 48003), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((47758, 47962), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((47758, 47900), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((47758, 47839), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48062, 48308), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48062, 48267), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48062, 48204), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48062, 48143), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48367, 48629), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48367, 48588), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48367, 48509), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48367, 48448), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48767, 49030), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48767, 48989), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48767, 48923), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((48767, 48855), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49089, 49357), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49089, 49316), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49089, 49245), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49089, 49177), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49416, 49689), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49416, 49648), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49416, 49572), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49416, 49504), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49824, 50134), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49824, 50076), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49824, 49980), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((49824, 49912), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((50193, 50500), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((50193, 50445), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((50193, 50349), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((50193, 50281), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((50630, 50946), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((50630, 50894), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((50630, 50826), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((50630, 50772), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((50630, 50711), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51005, 51337), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51005, 51284), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51005, 51208), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51005, 51147), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51005, 51086), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51396, 51738), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51396, 51685), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51396, 51604), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51396, 51538), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51396, 51477), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51868, 52272), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51868, 52220), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51868, 52132), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51868, 52064), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51868, 52010), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((51868, 51949), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52331, 52757), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52331, 52704), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52331, 52610), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52331, 52534), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52331, 52473), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52331, 52412), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52816, 53260), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52816, 53207), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52816, 53105), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52816, 53024), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52816, 52958), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((52816, 52897), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((53399, 53655), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((53399, 53603), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((53399, 53541), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((53399, 53480), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((53714, 53978), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((53714, 53925), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((53714, 53856), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((53714, 53795), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54037, 54306), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54037, 54253), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54037, 54179), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54037, 54118), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54446, 54778), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54446, 54726), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54446, 54650), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54446, 54588), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54446, 54527), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54837, 55185), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54837, 55132), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54837, 55048), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54837, 54979), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((54837, 54918), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55244, 55602), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55244, 55549), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55244, 55460), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55244, 55386), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55244, 55325), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55755, 56079), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55755, 56027), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55755, 55951), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55755, 55897), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((55755, 55836), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56138, 56478), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56138, 56425), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56138, 56341), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56138, 56280), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56138, 56219), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56537, 56887), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56537, 56834), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56537, 56745), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56537, 56679), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((56537, 56618), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57008, 57424), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57008, 57375), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57008, 57259), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57008, 57166), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57008, 57097), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57458, 57888), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57458, 57839), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57458, 57723), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57458, 57630), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((57458, 57554), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58034, 58450), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58034, 58401), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58034, 58285), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58034, 58192), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58034, 58123), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58484, 58914), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58484, 58865), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58484, 58749), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58484, 58656), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58484, 58580), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58948, 59370), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58948, 59321), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58948, 59205), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58948, 59112), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((58948, 59040), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((65100, 65318), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((65100, 65269), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((65100, 65181), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((65352, 65553), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((65352, 65504), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((65352, 65436), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((65757, 65984), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((65757, 65935), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((65757, 65846), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((66018, 66228), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((66018, 66179), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((66018, 66110), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((66432, 66663), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((66432, 66614), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((66432, 66525), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((66697, 66911), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((66697, 66862), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((66697, 66793), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((67200, 67477), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((67200, 67428), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((67200, 67366), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((67200, 67289), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((67511, 67740), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((67511, 67679), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((67511, 67603), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((67954, 68231), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((67954, 68182), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((67954, 68120), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((67954, 68043), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((68265, 68494), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((68265, 68433), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((68265, 68357), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((68720, 68997), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((68720, 68948), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((68720, 68886), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((68720, 68809), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((69031, 69273), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((69031, 69211), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((69031, 69123), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((69563, 69905), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((69563, 69856), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((69563, 69791), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((69563, 69729), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((69563, 69652), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((69939, 70192), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((69939, 70131), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((69939, 70031), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((70406, 70748), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((70406, 70699), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((70406, 70634), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((70406, 70572), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((70406, 70495), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((70782, 71036), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((70782, 70974), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((70782, 70874), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((71262, 71604), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((71262, 71555), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((71262, 71490), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((71262, 71428), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((71262, 71351), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((71638, 71902), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((71638, 71840), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((71638, 71730), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((72212, 72637), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((72212, 72588), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((72212, 72505), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((72212, 72440), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((72212, 72378), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((72212, 72301), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((72671, 72943), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((72671, 72881), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((72671, 72763), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((73175, 73600), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((73175, 73551), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((73175, 73468), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((73175, 73403), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((73175, 73341), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((73175, 73264), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((73634, 73906), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((73634, 73844), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((73634, 73726), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((74150, 74575), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((74150, 74526), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((74150, 74443), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((74150, 74378), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((74150, 74316), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((74150, 74239), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((74609, 74891), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((74609, 74829), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((74609, 74701), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((77661, 77892), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((77661, 77835), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((77661, 77750), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((77934, 78165), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((77934, 78108), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((77934, 78023), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((78281, 78506), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((78281, 78449), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((78281, 78373), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((78548, 78773), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((78548, 78716), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((78548, 78640), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((79068, 79307), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((79068, 79250), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((79068, 79165), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((79349, 79588), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((79349, 79531), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((79349, 79446), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((79704, 79938), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((79704, 79881), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((79704, 79804), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((79980, 80214), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((79980, 80157), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((79980, 80080), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((80509, 80752), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((80509, 80695), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((80509, 80610), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((80794, 81037), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((80794, 80980), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((80794, 80895), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((81153, 81391), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((81153, 81334), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((81153, 81257), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((81433, 81671), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((81433, 81614), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((81433, 81537), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((82025, 82256), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((82025, 82199), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((82025, 82114), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((82298, 82529), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((82298, 82472), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((82298, 82387), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((82571, 82810), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((82571, 82753), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((82571, 82664), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((82926, 83140), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((82926, 83083), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((82926, 83018), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((83182, 83396), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((83182, 83339), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((83182, 83274), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((83438, 83656), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((83438, 83599), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((83438, 83534), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((84014, 84315), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((84014, 84258), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((84014, 84188), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((84014, 84103), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((84357, 84588), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((84357, 84531), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((84357, 84446), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((84704, 84937), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((84704, 84880), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((84704, 84796), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((84979, 85193), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((84979, 85136), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((84979, 85071), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((85592, 85901), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((85592, 85844), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((85592, 85774), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((85592, 85689), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((85943, 86252), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((85943, 86195), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((85943, 86125), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((85943, 86040), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((86368, 86621), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((86368, 86552), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((86368, 86468), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((86663, 86916), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((86663, 86847), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((86663, 86763), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((87233, 87542), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((87233, 87485), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((87233, 87415), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((87233, 87330), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((87584, 87893), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((87584, 87836), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((87584, 87766), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((87584, 87681), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((88009, 88275), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((88009, 88205), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((88009, 88109), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((88317, 88583), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((88317, 88513), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((88317, 88417), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((88980, 89289), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((88980, 89232), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((88980, 89162), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((88980, 89077), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((89331, 89640), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((89331, 89583), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((89331, 89513), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((89331, 89428), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((89756, 90009), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((89756, 89940), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((89756, 89856), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((90051, 90304), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((90051, 90235), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((90051, 90151), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((90730, 91031), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((90730, 90974), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((90730, 90904), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((90730, 90819), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((91073, 91382), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((91073, 91325), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((91073, 91255), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((91073, 91170), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((91498, 91755), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((91498, 91686), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((91498, 91590), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((91797, 92062), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((91797, 91993), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((91797, 91897), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((92449, 92750), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((92449, 92693), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((92449, 92623), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((92449, 92538), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((92866, 93099), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((92866, 93042), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((92866, 92958), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((93141, 93374), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((93141, 93317), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((93141, 93233), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((93416, 93649), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((93416, 93592), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((93416, 93508), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((93691, 93923), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((93691, 93866), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((93691, 93783), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((94304, 94686), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((94304, 94629), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((94304, 94556), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((94304, 94486), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((94304, 94401), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((94728, 95110), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((94728, 95053), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((94728, 94980), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((94728, 94910), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((94728, 94825), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((95226, 95503), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((95226, 95434), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((95226, 95326), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((95545, 95834), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((95545, 95765), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((95545, 95645), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((96151, 96533), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((96151, 96476), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((96151, 96403), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((96151, 96333), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((96151, 96248), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((96575, 96957), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((96575, 96900), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((96575, 96827), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((96575, 96757), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((96575, 96672), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((97073, 97361), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((97073, 97291), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((97073, 97173), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((97403, 97691), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((97403, 97621), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((97403, 97503), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((98109, 98582), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((98109, 98525), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((98109, 98434), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((98109, 98361), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((98109, 98291), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((98109, 98206), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((98698, 99006), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((98698, 98936), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((98698, 98798), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((99048, 99366), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((99048, 99296), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((99048, 99148), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((99824, 100297), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((99824, 100240), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((99824, 100149), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((99824, 100076), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((99824, 100006), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((99824, 99921), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((100339, 100721), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((100339, 100664), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((100339, 100591), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((100339, 100521), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((100339, 100436), 'dev.langchain4j.agent.tool.ToolSpecification.builder'), ((100837, 101134), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((100837, 101064), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((100837, 100937), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((101176, 101483), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((101176, 101413), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((101176, 101276), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((101525, 101803), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((101525, 101733), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder'), ((101525, 101625), 'dev.langchain4j.agent.tool.ToolExecutionRequest.builder')]