Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
1 line
293 KiB
JSON
1 line
293 KiB
JSON
{"repo": "agents-flex/agents-flex", "files": {"demos/skills-demo/src/main/java/com/agentsflex/skills/SkillsConsoleDemoMain.java": {"8d98490336909545c2816b2f86e1eefab77f095f": {"t": 1785745655.8205125, "n": 8658, "h": "8230a0a7dce71642", "c": "package com.agentsflex.skills;\n\nimport com.agentsflex.core.message.AiMessage;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.model.chat.StreamResponseListener;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.prompt.MemoryPrompt;\nimport com.agentsflex.core.util.StringUtil;\nimport com.agentsflex.model.chat.openai.OpenAIChatConfig;\nimport com.agentsflex.model.chat.openai.OpenAIChatModel;\nimport com.agentsflex.skill.SkillsTool;\nimport com.agentsflex.skill.runtime.SkillRuntime;\nimport com.alibaba.fastjson2.JSON;\nimport com.alibaba.fastjson2.JSONWriter;\n\nimport java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicReference;\n\n/**\n * 可在控制台中持续输入问题的 Skills 多轮对话示例。\n */\npublic class SkillsConsoleDemoMain {\n\n public static void main(String[] args) throws Exception {\n SkillsDemoMain.disableObservabilityByDefault();\n\n String skillsDirectory = SkillsDemoMain.resolveSkillsDirectory();\n long turnTimeoutSeconds = SkillsDemoMain.environmentLong(\"SKILLS_DEMO_TIMEOUT_SECONDS\", 900L);\n OpenAIChatModel chatModel = createChatModel();\n\n try (SkillRuntime runtime = SkillsDemoMain.createRuntime();\n BufferedReader reader = new BufferedReader(\n new InputStreamReader(System.in, StandardCharsets.UTF_8))) {\n MemoryPrompt prompt = createPrompt(skillsDirectory, runtime);\n\n System.out.println(\"Skills directory: \" + skillsDirectory);\n System.out.println(\"Skill runtime: \" + runtime.getName());\n System.out.println(\"持续对话已启动。输入 /clear 清空对话历史,输入 /exit 或 /quit 退出。\\n\");\n\n while (true) {\n System.out.print(\"You> \");\n System.out.flush();\n String input = reader.readLine();\n if (input == null || isExitCommand(input)) {\n System.out.println(\"Bye.\");\n break;\n }\n if (\"/clear\".equalsIgnoreCase(input.trim())) {\n prompt.clear();\n System.out.println(\"对话历史已清空。\\n\");\n continue;\n }\n if (!StringUtil.hasText(input)) {\n continue;\n }\n\n prompt.addUserMessage(input.trim());\n System.out.print(\"Assistant> \");\n runTurn(chatModel, prompt, turnTimeoutSeconds);\n System.out.println();\n }\n }\n }\n\n private static OpenAIChatModel createChatModel() {\n return OpenAIChatConfig.builder()\n .provider(SkillsDemoMain.environment(\"DEEPSEEK_PROVIDER\", \"DeepSeek\"))\n .endpoint(SkillsDemoMain.environment(\"DEEPSEEK_ENDPOINT\", \"https://api.deepseek.com\"))\n .requestPath(SkillsDemoMain.environment(\"DEEPSEEK_REQUEST_PATH\", \"/chat/completions\"))\n .apiKey(SkillsDemoMain.requireEnvironment(\"DEEPSEEK_API_KEY\"))\n .model(SkillsDemoMain.environment(\"DEEPSEEK_MODEL\", \"deepseek-v4-pro\"))\n .logEnabled(Boolean.parseBoolean(\n SkillsDemoMain.environment(\"CHAT_LOG_ENABLED\", \"true\")))\n .buildModel();\n }\n\n private static MemoryPrompt createPrompt(String skillsDirectory, SkillRuntime runtime) {\n MemoryPrompt prompt = new MemoryPrompt();\n prompt.setSystemMessage(\"Always use the available skills when they match the request. \"\n + \"Run every shell command with the provided Bash tool in the configured skill runtime.\");\n prompt.addTools(SkillsTool.builder()\n .addSkillsDirectory(skillsDirectory)\n .runtime(runtime)\n .buildTools());\n return prompt;\n }\n\n private static void runTurn(OpenAIChatModel chatModel, MemoryPrompt prompt,\n long timeoutSeconds) throws InterruptedException {\n CountDownLatch completed = new CountDownLatch(1);\n AtomicReference<Throwable> failure = new AtomicReference<>();\n chatModel.chatStream(prompt, new ConsoleConversationListener(\n chatModel, prompt, completed, failure));\n\n if (!completed.await(timeoutSeconds, TimeUnit.SECONDS)) {\n throw new IllegalStateException(\"Conversation turn timed out after \"\n + timeoutSeconds + \" seconds\");\n }\n if (failure.get() != null) {\n throw new IllegalStateException(\"Conversation turn failed\", failure.get());\n }\n }\n\n private static boolean isExitCommand(String input) {\n String command = input.trim();\n return \"/exit\".equalsIgnoreCase(command) || \"/quit\".equalsIgnoreCase(command);\n }\n\n private static class ConsoleConversationListener implements StreamResponseListener {\n\n private final OpenAIChatModel chatModel;\n private final MemoryPrompt prompt;\n private final CountDownLatch completed;\n private final AtomicReference<Throwable> failure;\n private final AtomicBoolean streamActive = new AtomicBoolean(false);\n private final AtomicBoolean followUpStarted = new AtomicBoolean(false);\n\n private ConsoleConversationListener(OpenAIChatModel chatModel, MemoryPrompt prompt,\n CountDownLatch completed,\n AtomicReference<Throwable> failure) {\n this.chatModel = chatModel;\n this.prompt = prompt;\n this.completed = completed;\n this.failure = failure;\n }\n\n @Override\n public void onOpen(StreamContext context) {\n streamActive.set(true);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n try {\n if (response.isError()) {\n recordFailure(new IllegalStateException(response.getErrorMessage()));\n return;\n }\n\n AiMessage message = response.getMessage();\n if (message == null) {\n return;\n }\n String content = StringUtil.hasText(message.getContent())\n ? message.getContent() : message.getReasoningContent();\n if (content != null) {\n System.out.print(content);\n System.out.flush();\n }\n\n if (!message.isFinalDelta()) {\n return;\n }\n\n prompt.addMessage(message);\n if (!message.hasToolCalls()) {\n return;\n }\n\n System.out.println(\"\\n\\n---------- tools ----------\");\n for (ToolCall toolCall : message.getToolCalls()) {\n System.out.println(toolCall.getName() + \": \"\n + JSON.toJSONString(toolCall.getArgsMap(), JSONWriter.Feature.PrettyFormat));\n }\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n for (ToolMessage toolMessage : toolMessages) {\n System.out.println(\"result: \" + toolMessage.getContent());\n }\n System.out.println(\"---------------------------\\n\");\n prompt.addMessages(toolMessages);\n followUpStarted.set(true);\n try {\n chatModel.chatStream(prompt, new ConsoleConversationListener(\n chatModel, prompt, completed, failure));\n } catch (RuntimeException e) {\n followUpStarted.set(false);\n throw e;\n }\n } catch (RuntimeException e) {\n recordFailure(e);\n }\n }\n\n @Override\n public void onError(StreamContext context, Throwable throwable) {\n recordFailure(throwable == null\n ? new IllegalStateException(\"Unknown model failure\") : throwable);\n }\n\n @Override\n public void onClose(StreamContext context) {\n if (streamActive.compareAndSet(true, false) && !followUpStarted.get()) {\n completed.countDown();\n }\n }\n\n private void recordFailure(Throwable throwable) {\n failure.compareAndSet(null, throwable);\n }\n }\n}\n"}, "5ca99d8c1fe87679751890b200c1b109725319d4": {"t": 1785755430.174862, "n": 8658, "h": "8230a0a7dce71642", "c": "package com.agentsflex.skills;\n\nimport com.agentsflex.core.message.AiMessage;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.model.chat.StreamResponseListener;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.prompt.MemoryPrompt;\nimport com.agentsflex.core.util.StringUtil;\nimport com.agentsflex.model.chat.openai.OpenAIChatConfig;\nimport com.agentsflex.model.chat.openai.OpenAIChatModel;\nimport com.agentsflex.skill.SkillsTool;\nimport com.agentsflex.skill.runtime.SkillRuntime;\nimport com.alibaba.fastjson2.JSON;\nimport com.alibaba.fastjson2.JSONWriter;\n\nimport java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicReference;\n\n/**\n * 可在控制台中持续输入问题的 Skills 多轮对话示例。\n */\npublic class SkillsConsoleDemoMain {\n\n public static void main(String[] args) throws Exception {\n SkillsDemoMain.disableObservabilityByDefault();\n\n String skillsDirectory = SkillsDemoMain.resolveSkillsDirectory();\n long turnTimeoutSeconds = SkillsDemoMain.environmentLong(\"SKILLS_DEMO_TIMEOUT_SECONDS\", 900L);\n OpenAIChatModel chatModel = createChatModel();\n\n try (SkillRuntime runtime = SkillsDemoMain.createRuntime();\n BufferedReader reader = new BufferedReader(\n new InputStreamReader(System.in, StandardCharsets.UTF_8))) {\n MemoryPrompt prompt = createPrompt(skillsDirectory, runtime);\n\n System.out.println(\"Skills directory: \" + skillsDirectory);\n System.out.println(\"Skill runtime: \" + runtime.getName());\n System.out.println(\"持续对话已启动。输入 /clear 清空对话历史,输入 /exit 或 /quit 退出。\\n\");\n\n while (true) {\n System.out.print(\"You> \");\n System.out.flush();\n String input = reader.readLine();\n if (input == null || isExitCommand(input)) {\n System.out.println(\"Bye.\");\n break;\n }\n if (\"/clear\".equalsIgnoreCase(input.trim())) {\n prompt.clear();\n System.out.println(\"对话历史已清空。\\n\");\n continue;\n }\n if (!StringUtil.hasText(input)) {\n continue;\n }\n\n prompt.addUserMessage(input.trim());\n System.out.print(\"Assistant> \");\n runTurn(chatModel, prompt, turnTimeoutSeconds);\n System.out.println();\n }\n }\n }\n\n private static OpenAIChatModel createChatModel() {\n return OpenAIChatConfig.builder()\n .provider(SkillsDemoMain.environment(\"DEEPSEEK_PROVIDER\", \"DeepSeek\"))\n .endpoint(SkillsDemoMain.environment(\"DEEPSEEK_ENDPOINT\", \"https://api.deepseek.com\"))\n .requestPath(SkillsDemoMain.environment(\"DEEPSEEK_REQUEST_PATH\", \"/chat/completions\"))\n .apiKey(SkillsDemoMain.requireEnvironment(\"DEEPSEEK_API_KEY\"))\n .model(SkillsDemoMain.environment(\"DEEPSEEK_MODEL\", \"deepseek-v4-pro\"))\n .logEnabled(Boolean.parseBoolean(\n SkillsDemoMain.environment(\"CHAT_LOG_ENABLED\", \"true\")))\n .buildModel();\n }\n\n private static MemoryPrompt createPrompt(String skillsDirectory, SkillRuntime runtime) {\n MemoryPrompt prompt = new MemoryPrompt();\n prompt.setSystemMessage(\"Always use the available skills when they match the request. \"\n + \"Run every shell command with the provided Bash tool in the configured skill runtime.\");\n prompt.addTools(SkillsTool.builder()\n .addSkillsDirectory(skillsDirectory)\n .runtime(runtime)\n .buildTools());\n return prompt;\n }\n\n private static void runTurn(OpenAIChatModel chatModel, MemoryPrompt prompt,\n long timeoutSeconds) throws InterruptedException {\n CountDownLatch completed = new CountDownLatch(1);\n AtomicReference<Throwable> failure = new AtomicReference<>();\n chatModel.chatStream(prompt, new ConsoleConversationListener(\n chatModel, prompt, completed, failure));\n\n if (!completed.await(timeoutSeconds, TimeUnit.SECONDS)) {\n throw new IllegalStateException(\"Conversation turn timed out after \"\n + timeoutSeconds + \" seconds\");\n }\n if (failure.get() != null) {\n throw new IllegalStateException(\"Conversation turn failed\", failure.get());\n }\n }\n\n private static boolean isExitCommand(String input) {\n String command = input.trim();\n return \"/exit\".equalsIgnoreCase(command) || \"/quit\".equalsIgnoreCase(command);\n }\n\n private static class ConsoleConversationListener implements StreamResponseListener {\n\n private final OpenAIChatModel chatModel;\n private final MemoryPrompt prompt;\n private final CountDownLatch completed;\n private final AtomicReference<Throwable> failure;\n private final AtomicBoolean streamActive = new AtomicBoolean(false);\n private final AtomicBoolean followUpStarted = new AtomicBoolean(false);\n\n private ConsoleConversationListener(OpenAIChatModel chatModel, MemoryPrompt prompt,\n CountDownLatch completed,\n AtomicReference<Throwable> failure) {\n this.chatModel = chatModel;\n this.prompt = prompt;\n this.completed = completed;\n this.failure = failure;\n }\n\n @Override\n public void onOpen(StreamContext context) {\n streamActive.set(true);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n try {\n if (response.isError()) {\n recordFailure(new IllegalStateException(response.getErrorMessage()));\n return;\n }\n\n AiMessage message = response.getMessage();\n if (message == null) {\n return;\n }\n String content = StringUtil.hasText(message.getContent())\n ? message.getContent() : message.getReasoningContent();\n if (content != null) {\n System.out.print(content);\n System.out.flush();\n }\n\n if (!message.isFinalDelta()) {\n return;\n }\n\n prompt.addMessage(message);\n if (!message.hasToolCalls()) {\n return;\n }\n\n System.out.println(\"\\n\\n---------- tools ----------\");\n for (ToolCall toolCall : message.getToolCalls()) {\n System.out.println(toolCall.getName() + \": \"\n + JSON.toJSONString(toolCall.getArgsMap(), JSONWriter.Feature.PrettyFormat));\n }\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n for (ToolMessage toolMessage : toolMessages) {\n System.out.println(\"result: \" + toolMessage.getContent());\n }\n System.out.println(\"---------------------------\\n\");\n prompt.addMessages(toolMessages);\n followUpStarted.set(true);\n try {\n chatModel.chatStream(prompt, new ConsoleConversationListener(\n chatModel, prompt, completed, failure));\n } catch (RuntimeException e) {\n followUpStarted.set(false);\n throw e;\n }\n } catch (RuntimeException e) {\n recordFailure(e);\n }\n }\n\n @Override\n public void onError(StreamContext context, Throwable throwable) {\n recordFailure(throwable == null\n ? new IllegalStateException(\"Unknown model failure\") : throwable);\n }\n\n @Override\n public void onClose(StreamContext context) {\n if (streamActive.compareAndSet(true, false) && !followUpStarted.get()) {\n completed.countDown();\n }\n }\n\n private void recordFailure(Throwable throwable) {\n failure.compareAndSet(null, throwable);\n }\n }\n}\n"}, "ec28e62e6c63c998b15f7209d1d47e34c2f1ad20": {"t": 1785755431.7820513, "n": 8660, "h": "e1a7e0f8c909c1c8", "c": "package com.agentsflex.skills;\n\nimport com.agentsflex.core.message.AiMessage;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.model.chat.StreamResponseListener;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.prompt.MemoryPrompt;\nimport com.agentsflex.core.util.StringUtil;\nimport com.agentsflex.model.chat.openai.OpenAIChatConfig;\nimport com.agentsflex.model.chat.openai.OpenAIChatModel;\nimport com.agentsflex.skill.SkillsTool;\nimport com.agentsflex.skill.runtime.SkillRuntime;\nimport com.alibaba.fastjson2.JSON;\nimport com.alibaba.fastjson2.JSONWriter;\n\nimport java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicReference;\n\n/**\n * 可在控制台中持续输入问题的 Skills 多轮对话示例。\n */\npublic class SkillsConsoleDemoMain {\n\n public static void main(String[] args) throws Exception {\n SkillsDemoMain.disableObservabilityByDefault();\n\n String skillsDirectory = SkillsDemoMain.resolveSkillsDirectory();\n long turnTimeoutSeconds = SkillsDemoMain.environmentLong(\"SKILLS_DEMO_TIMEOUT_SECONDS\", 900L);\n OpenAIChatModel chatModel = createChatModel();\n\n try (SkillRuntime runtime = SkillsDemoMain.createRuntime();\n BufferedReader reader = new BufferedReader(\n new InputStreamReader(System.in, StandardCharsets.UTF_8))) {\n MemoryPrompt prompt = createPrompt(skillsDirectory, runtime);\n\n System.out.println(\"Skills directory: \" + skillsDirectory);\n System.out.println(\"Skill runtime: \" + runtime.getName());\n System.out.println(\"持续对话已启动。输入 /clear 清空对话历史,输入 /exit 或 /quit 退出。\\n\");\n\n while (true) {\n System.out.print(\"You> \");\n System.out.flush();\n String input = reader.readLine();\n if (input == null || isExitCommand(input)) {\n System.out.println(\"Bye.\");\n break;\n }\n if (\"/clear\".equalsIgnoreCase(input.trim())) {\n prompt.clear();\n System.out.println(\"对话历史已清空。\\n\");\n continue;\n }\n if (!StringUtil.hasText(input)) {\n continue;\n }\n\n prompt.addUserMessage(input.trim());\n System.out.print(\"Assistant> \");\n runTurn(chatModel, prompt, turnTimeoutSeconds);\n System.out.println();\n }\n }\n }\n\n private static OpenAIChatModel createChatModel() {\n return OpenAIChatConfig.builder()\n .provider(SkillsDemoMain.environment(\"DEEPSEEK_PROVIDER\", \"DeepSeek\"))\n .endpoint(SkillsDemoMain.environment(\"DEEPSEEK_ENDPOINT\", \"https://api.deepseek.com\"))\n .requestPath(SkillsDemoMain.environment(\"DEEPSEEK_REQUEST_PATH\", \"/chat/completions\"))\n .apiKey(SkillsDemoMain.requireEnvironment(\"DEEPSEEK_API_KEY\"))\n .model(SkillsDemoMain.environment(\"DEEPSEEK_MODEL\", \"deepseek-v4-pro\"))\n .logEnabled(Boolean.parseBoolean(\n SkillsDemoMain.environment(\"CHAT_LOG_ENABLED\", \"true\")))\n .buildModel();\n }\n\n private static MemoryPrompt createPrompt(String skillsDirectory, SkillRuntime runtime) {\n MemoryPrompt prompt = new MemoryPrompt();\n prompt.setSystemMessage(\"Always use the available skills when they match the request. \"\n + \"Run every shell command with the provided Bash tool in the configured skill runtime.\");\n prompt.addTools(SkillsTool.builder()\n .addSkillsDirectory(skillsDirectory)\n .runtime(runtime)\n .buildTools());\n return prompt;\n }\n\n private static void runTurn(OpenAIChatModel chatModel, MemoryPrompt prompt,\n long timeoutSeconds) throws InterruptedException {\n CountDownLatch completed = new CountDownLatch(1);\n AtomicReference<Throwable> failure = new AtomicReference<>();\n chatModel.chatStream(prompt, new ConsoleConversationListener(\n chatModel, prompt, completed, failure));\n\n if (!completed.await(timeoutSeconds, TimeUnit.SECONDS)) {\n throw new IllegalStateException(\"Conversation turn timed out after \"\n + timeoutSeconds + \" seconds\");\n }\n if (failure.get() != null) {\n throw new IllegalStateException(\"Conversation turn failed\", failure.get());\n }\n }\n\n private static boolean isExitCommand(String input) {\n String command = input.trim();\n return \"/exit\".equalsIgnoreCase(command) || \"/quit\".equalsIgnoreCase(command);\n }\n\n private static class ConsoleConversationListener implements StreamResponseListener {\n\n private final OpenAIChatModel chatModel;\n private final MemoryPrompt prompt;\n private final CountDownLatch completed;\n private final AtomicReference<Throwable> failure;\n private final AtomicBoolean streamActive = new AtomicBoolean(false);\n private final AtomicBoolean followUpStarted = new AtomicBoolean(false);\n\n private ConsoleConversationListener(OpenAIChatModel chatModel, MemoryPrompt prompt,\n CountDownLatch completed,\n AtomicReference<Throwable> failure) {\n this.chatModel = chatModel;\n this.prompt = prompt;\n this.completed = completed;\n this.failure = failure;\n }\n\n @Override\n public void onStart(StreamContext context) {\n streamActive.set(true);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n try {\n if (response.isError()) {\n recordFailure(new IllegalStateException(response.getErrorMessage()));\n return;\n }\n\n AiMessage message = response.getMessage();\n if (message == null) {\n return;\n }\n String content = StringUtil.hasText(message.getContent())\n ? message.getContent() : message.getReasoningContent();\n if (content != null) {\n System.out.print(content);\n System.out.flush();\n }\n\n if (!message.isFinalDelta()) {\n return;\n }\n\n prompt.addMessage(message);\n if (!message.hasToolCalls()) {\n return;\n }\n\n System.out.println(\"\\n\\n---------- tools ----------\");\n for (ToolCall toolCall : message.getToolCalls()) {\n System.out.println(toolCall.getName() + \": \"\n + JSON.toJSONString(toolCall.getArgsMap(), JSONWriter.Feature.PrettyFormat));\n }\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n for (ToolMessage toolMessage : toolMessages) {\n System.out.println(\"result: \" + toolMessage.getContent());\n }\n System.out.println(\"---------------------------\\n\");\n prompt.addMessages(toolMessages);\n followUpStarted.set(true);\n try {\n chatModel.chatStream(prompt, new ConsoleConversationListener(\n chatModel, prompt, completed, failure));\n } catch (RuntimeException e) {\n followUpStarted.set(false);\n throw e;\n }\n } catch (RuntimeException e) {\n recordFailure(e);\n }\n }\n\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n recordFailure(throwable == null\n ? new IllegalStateException(\"Unknown model failure\") : throwable);\n }\n\n @Override\n public void onStop(StreamContext context) {\n if (streamActive.compareAndSet(true, false) && !followUpStarted.get()) {\n completed.countDown();\n }\n }\n\n private void recordFailure(Throwable throwable) {\n failure.compareAndSet(null, throwable);\n }\n }\n}\n"}, "3a2b0b1bff557e9a769d6b66bcd848020a0af2c4": {"t": 1786068300.1241388, "n": 8658, "h": "8230a0a7dce71642", "c": "package com.agentsflex.skills;\n\nimport com.agentsflex.core.message.AiMessage;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.model.chat.StreamResponseListener;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.prompt.MemoryPrompt;\nimport com.agentsflex.core.util.StringUtil;\nimport com.agentsflex.model.chat.openai.OpenAIChatConfig;\nimport com.agentsflex.model.chat.openai.OpenAIChatModel;\nimport com.agentsflex.skill.SkillsTool;\nimport com.agentsflex.skill.runtime.SkillRuntime;\nimport com.alibaba.fastjson2.JSON;\nimport com.alibaba.fastjson2.JSONWriter;\n\nimport java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.util.List;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicReference;\n\n/**\n * 可在控制台中持续输入问题的 Skills 多轮对话示例。\n */\npublic class SkillsConsoleDemoMain {\n\n public static void main(String[] args) throws Exception {\n SkillsDemoMain.disableObservabilityByDefault();\n\n String skillsDirectory = SkillsDemoMain.resolveSkillsDirectory();\n long turnTimeoutSeconds = SkillsDemoMain.environmentLong(\"SKILLS_DEMO_TIMEOUT_SECONDS\", 900L);\n OpenAIChatModel chatModel = createChatModel();\n\n try (SkillRuntime runtime = SkillsDemoMain.createRuntime();\n BufferedReader reader = new BufferedReader(\n new InputStreamReader(System.in, StandardCharsets.UTF_8))) {\n MemoryPrompt prompt = createPrompt(skillsDirectory, runtime);\n\n System.out.println(\"Skills directory: \" + skillsDirectory);\n System.out.println(\"Skill runtime: \" + runtime.getName());\n System.out.println(\"持续对话已启动。输入 /clear 清空对话历史,输入 /exit 或 /quit 退出。\\n\");\n\n while (true) {\n System.out.print(\"You> \");\n System.out.flush();\n String input = reader.readLine();\n if (input == null || isExitCommand(input)) {\n System.out.println(\"Bye.\");\n break;\n }\n if (\"/clear\".equalsIgnoreCase(input.trim())) {\n prompt.clear();\n System.out.println(\"对话历史已清空。\\n\");\n continue;\n }\n if (!StringUtil.hasText(input)) {\n continue;\n }\n\n prompt.addUserMessage(input.trim());\n System.out.print(\"Assistant> \");\n runTurn(chatModel, prompt, turnTimeoutSeconds);\n System.out.println();\n }\n }\n }\n\n private static OpenAIChatModel createChatModel() {\n return OpenAIChatConfig.builder()\n .provider(SkillsDemoMain.environment(\"DEEPSEEK_PROVIDER\", \"DeepSeek\"))\n .endpoint(SkillsDemoMain.environment(\"DEEPSEEK_ENDPOINT\", \"https://api.deepseek.com\"))\n .requestPath(SkillsDemoMain.environment(\"DEEPSEEK_REQUEST_PATH\", \"/chat/completions\"))\n .apiKey(SkillsDemoMain.requireEnvironment(\"DEEPSEEK_API_KEY\"))\n .model(SkillsDemoMain.environment(\"DEEPSEEK_MODEL\", \"deepseek-v4-pro\"))\n .logEnabled(Boolean.parseBoolean(\n SkillsDemoMain.environment(\"CHAT_LOG_ENABLED\", \"true\")))\n .buildModel();\n }\n\n private static MemoryPrompt createPrompt(String skillsDirectory, SkillRuntime runtime) {\n MemoryPrompt prompt = new MemoryPrompt();\n prompt.setSystemMessage(\"Always use the available skills when they match the request. \"\n + \"Run every shell command with the provided Bash tool in the configured skill runtime.\");\n prompt.addTools(SkillsTool.builder()\n .addSkillsDirectory(skillsDirectory)\n .runtime(runtime)\n .buildTools());\n return prompt;\n }\n\n private static void runTurn(OpenAIChatModel chatModel, MemoryPrompt prompt,\n long timeoutSeconds) throws InterruptedException {\n CountDownLatch completed = new CountDownLatch(1);\n AtomicReference<Throwable> failure = new AtomicReference<>();\n chatModel.chatStream(prompt, new ConsoleConversationListener(\n chatModel, prompt, completed, failure));\n\n if (!completed.await(timeoutSeconds, TimeUnit.SECONDS)) {\n throw new IllegalStateException(\"Conversation turn timed out after \"\n + timeoutSeconds + \" seconds\");\n }\n if (failure.get() != null) {\n throw new IllegalStateException(\"Conversation turn failed\", failure.get());\n }\n }\n\n private static boolean isExitCommand(String input) {\n String command = input.trim();\n return \"/exit\".equalsIgnoreCase(command) || \"/quit\".equalsIgnoreCase(command);\n }\n\n private static class ConsoleConversationListener implements StreamResponseListener {\n\n private final OpenAIChatModel chatModel;\n private final MemoryPrompt prompt;\n private final CountDownLatch completed;\n private final AtomicReference<Throwable> failure;\n private final AtomicBoolean streamActive = new AtomicBoolean(false);\n private final AtomicBoolean followUpStarted = new AtomicBoolean(false);\n\n private ConsoleConversationListener(OpenAIChatModel chatModel, MemoryPrompt prompt,\n CountDownLatch completed,\n AtomicReference<Throwable> failure) {\n this.chatModel = chatModel;\n this.prompt = prompt;\n this.completed = completed;\n this.failure = failure;\n }\n\n @Override\n public void onOpen(StreamContext context) {\n streamActive.set(true);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n try {\n if (response.isError()) {\n recordFailure(new IllegalStateException(response.getErrorMessage()));\n return;\n }\n\n AiMessage message = response.getMessage();\n if (message == null) {\n return;\n }\n String content = StringUtil.hasText(message.getContent())\n ? message.getContent() : message.getReasoningContent();\n if (content != null) {\n System.out.print(content);\n System.out.flush();\n }\n\n if (!message.isFinalDelta()) {\n return;\n }\n\n prompt.addMessage(message);\n if (!message.hasToolCalls()) {\n return;\n }\n\n System.out.println(\"\\n\\n---------- tools ----------\");\n for (ToolCall toolCall : message.getToolCalls()) {\n System.out.println(toolCall.getName() + \": \"\n + JSON.toJSONString(toolCall.getArgsMap(), JSONWriter.Feature.PrettyFormat));\n }\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n for (ToolMessage toolMessage : toolMessages) {\n System.out.println(\"result: \" + toolMessage.getContent());\n }\n System.out.println(\"---------------------------\\n\");\n prompt.addMessages(toolMessages);\n followUpStarted.set(true);\n try {\n chatModel.chatStream(prompt, new ConsoleConversationListener(\n chatModel, prompt, completed, failure));\n } catch (RuntimeException e) {\n followUpStarted.set(false);\n throw e;\n }\n } catch (RuntimeException e) {\n recordFailure(e);\n }\n }\n\n @Override\n public void onError(StreamContext context, Throwable throwable) {\n recordFailure(throwable == null\n ? new IllegalStateException(\"Unknown model failure\") : throwable);\n }\n\n @Override\n public void onClose(StreamContext context) {\n if (streamActive.compareAndSet(true, false) && !followUpStarted.get()) {\n completed.countDown();\n }\n }\n\n private void recordFailure(Throwable throwable) {\n failure.compareAndSet(null, throwable);\n }\n }\n}\n"}}, "agents-flex-chat/agents-flex-chat-openai/src/test/java/com/agentsflex/model/chat/openai/OpenAIChatModelTest.java": {"8d98490336909545c2816b2f86e1eefab77f095f": {"t": 1785746127.1569421, "n": 28332, "h": "6dd2424f3fe0e46b", "c": "package com.agentsflex.model.chat.openai;\n\nimport com.agentsflex.core.agent.react.ReActAgent;\nimport com.agentsflex.core.agent.react.ReActAgentListener;\nimport com.agentsflex.core.agent.react.ReActAgentState;\nimport com.agentsflex.core.agent.react.ReActStep;\nimport com.agentsflex.core.memory.ChatMemory;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.message.UserMessage;\nimport com.agentsflex.core.model.chat.*;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.chat.tool.ProviderTool;\nimport com.agentsflex.core.model.chat.tool.Tool;\nimport com.agentsflex.core.model.chat.tool.ToolScanner;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.model.exception.ModelException;\nimport com.agentsflex.core.prompt.SimplePrompt;\nimport com.agentsflex.core.util.Maps;\nimport org.junit.Test;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\npublic class OpenAIChatModelTest {\n\n @Test(expected = ModelException.class)\n public void testChat() {\n\n String output = OpenAIChatConfig.builder()\n .endpoint(\"https://ai.gitee.com\")\n .provider(\"GiteeAI\")\n .model(\"Qwen3-32B\")\n .apiKey(\"PXW1****D12\")\n .buildModel()\n .chat(\"你叫什么名字\");\n\n System.out.println(output);\n }\n\n @Test()\n public void testChatStream() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"PXW1GXE***\");\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setLogEnabled(true);\n\n ChatOptions options = ChatOptions.builder().thinkingEnabled(false).build();\n options.setContextAttributes(Maps.of(\"name\", \"张三\"));\n\n ChatModel chatModel = new OpenAIChatModel(config);\n\n\n ChatModelTestUtils.waitForStream(chatModel, \"你叫什么名字\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onError(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onClose(StreamContext context) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(\"stop!!!!\");\n }\n }, options);\n\n }\n\n\n @Test()\n public void testChatStreamBailian() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32ab******57502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京的天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onError(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onClose(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test()\n public void testChatStreamBailianSearch() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32a*****502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max-2026-01-23\");\n config.addSupportProviderTools(\"web_search\", \"web_extractor\", \"code_interpreter\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"杭州明天天气如何\");\n// prompt.addToolsFromClass(WeatherFunctions.class);\n prompt.addTools(ProviderTool.ofList(\"web_search\", \"web_extractor\", \"code_interpreter\"));\n\n ChatOptions options = new ChatOptions();\n options.addExtraBody(\"enable_search\", true);\n// options.addExtraBody(\"search_options\", Maps.of(\"forced_search\",true));\n\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onError(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n// System.out.println(\"onMessage >>>>>\" + response.getMessage().getReasoningContent());\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onClose(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test\n public void testChatOllama() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setEndpoint(\"http://localhost:11434\");\n config.setModel(\"llama3\");\n config.setLogEnabled(true);\n\n ChatModel chatModel = new OpenAIChatModel(config);\n chatModel.chatStream(\"who are you\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onClose(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n// try {\n// Thread.sleep(2000);\n// } catch (InterruptedException e) {\n// throw new RuntimeException(e);\n// }\n }\n\n\n @Test()\n public void testChatWithImage() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-5gqOcl*****\");\n config.setModel(\"gpt-4-turbo\");\n config.setRetryEnabled(false);\n\n\n ChatModel chatModel = new OpenAIChatModel(config);\n SimplePrompt prompt = new SimplePrompt(\"What's in this image?\");\n prompt.addImageUrl(\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg\");\n\n\n AiMessageResponse response = chatModel.chat(prompt);\n System.out.println(response);\n }\n\n\n @Test()\n public void testFunctionCalling1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n System.out.println(response.executeToolCallsAndGetResults());\n // 阴转多云\n }\n\n @Test()\n public void testFunctionCalling2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling3() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57a\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling4() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57aa75\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling44() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d5\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling444() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n// config.setRequestPath(\"/api/v3/chat/completions\");\n// config.setModel(\"Qwen3-32B\");\n config.setModel(\"DeepSeek-V3.2\");\n config.setApiKey(\"PXW1G***L7D12\");\n config.setRetryEnabled(false);\n// config.setLogEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n// System.out.println(\"onMessage11 >>>>>\" + response);\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(toolMessages);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::22\" + msg);\n }\n\n @Override\n public void onClose(StreamContext context) {\n System.out.println(\"onStop >>>>>\");\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n\n }\n\n\n @Test()\n public void testFunctionCalling5() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1G*********D12\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n// System.out.println(\"onMessage >>>>>\" + response);\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling55() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling56() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling6() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n\n System.out.println(llm.chat(prompt));\n\n }\n\n\n @Test()\n public void testReAct1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"****\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n// ReActAgent reActAgent = new ReActAgent(llm, functions, \"北京和上海的天气怎么样?\");\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"介绍一下北京\");\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n }\n\n @Override\n public void onNonActionResponse(AiMessageResponse response) {\n System.out.println(\"onNonActionResponse >>>>>\" + response.getMessage().getContent());\n }\n });\n\n reActAgent.execute();\n }\n\n\n @Test()\n public void testReAct2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen2-72B-Instruct\");\n config.setApiKey(\"*****\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"今天的天气怎么样?\");\n// reActAgent.setStreamable(true);\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onChatResponseStream(StreamContext context, AiMessageResponse response) {\n// System.out.print(response.getMessage().getContent());\n }\n\n @Override\n public void onRequestUserInput(String question) {\n System.out.println(\"onRequestUserInput>>>\" + question);\n\n ReActAgentState state = reActAgent.getState();\n state.addMessage(new UserMessage(\"我在北京市\"));\n ReActAgent newAgent = new ReActAgent(llm, tools, state);\n newAgent.addListener(this);\n newAgent.execute();\n }\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n ChatMemory memory = reActAgent.getMemoryPrompt().getMemory();\n System.out.println(memory);\n }\n\n @Override\n public void onNonActionResponseStream(StreamContext context) {\n System.out.println(\"onNonActionResponseStream >>>>>\" + context);\n }\n });\n\n reActAgent.execute();\n\n TimeUnit.SECONDS.sleep(20);\n }\n\n\n @Test()\n public void testBailian() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3.5-plus\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : response.getMessage().getReasoningContent();\n\n if (content != null)\n System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n\n @Test()\n public void testDeepseek() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://api.deepseek.com\");\n config.setRequestPath(\"/chat/completions\");\n config.setModel(\"deepseek-v4-pro\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-***691\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : \"[null]\";\n\n System.out.println(\">>>>>> raw: \" + response.getRawText());\n System.out.println(\">>>>>> msg: \" + msg +\" lastMsg: \" + response.getMessage().isFinalDelta());\n\n// if (content != null)\n// System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n}\n"}, "5ca99d8c1fe87679751890b200c1b109725319d4": {"t": 1785755429.2551503, "n": 28332, "h": "6dd2424f3fe0e46b", "c": "package com.agentsflex.model.chat.openai;\n\nimport com.agentsflex.core.agent.react.ReActAgent;\nimport com.agentsflex.core.agent.react.ReActAgentListener;\nimport com.agentsflex.core.agent.react.ReActAgentState;\nimport com.agentsflex.core.agent.react.ReActStep;\nimport com.agentsflex.core.memory.ChatMemory;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.message.UserMessage;\nimport com.agentsflex.core.model.chat.*;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.chat.tool.ProviderTool;\nimport com.agentsflex.core.model.chat.tool.Tool;\nimport com.agentsflex.core.model.chat.tool.ToolScanner;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.model.exception.ModelException;\nimport com.agentsflex.core.prompt.SimplePrompt;\nimport com.agentsflex.core.util.Maps;\nimport org.junit.Test;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\npublic class OpenAIChatModelTest {\n\n @Test(expected = ModelException.class)\n public void testChat() {\n\n String output = OpenAIChatConfig.builder()\n .endpoint(\"https://ai.gitee.com\")\n .provider(\"GiteeAI\")\n .model(\"Qwen3-32B\")\n .apiKey(\"PXW1****D12\")\n .buildModel()\n .chat(\"你叫什么名字\");\n\n System.out.println(output);\n }\n\n @Test()\n public void testChatStream() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"PXW1GXE***\");\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setLogEnabled(true);\n\n ChatOptions options = ChatOptions.builder().thinkingEnabled(false).build();\n options.setContextAttributes(Maps.of(\"name\", \"张三\"));\n\n ChatModel chatModel = new OpenAIChatModel(config);\n\n\n ChatModelTestUtils.waitForStream(chatModel, \"你叫什么名字\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onError(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onClose(StreamContext context) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(\"stop!!!!\");\n }\n }, options);\n\n }\n\n\n @Test()\n public void testChatStreamBailian() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32ab******57502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京的天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onError(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onClose(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test()\n public void testChatStreamBailianSearch() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32a*****502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max-2026-01-23\");\n config.addSupportProviderTools(\"web_search\", \"web_extractor\", \"code_interpreter\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"杭州明天天气如何\");\n// prompt.addToolsFromClass(WeatherFunctions.class);\n prompt.addTools(ProviderTool.ofList(\"web_search\", \"web_extractor\", \"code_interpreter\"));\n\n ChatOptions options = new ChatOptions();\n options.addExtraBody(\"enable_search\", true);\n// options.addExtraBody(\"search_options\", Maps.of(\"forced_search\",true));\n\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onError(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n// System.out.println(\"onMessage >>>>>\" + response.getMessage().getReasoningContent());\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onClose(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test\n public void testChatOllama() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setEndpoint(\"http://localhost:11434\");\n config.setModel(\"llama3\");\n config.setLogEnabled(true);\n\n ChatModel chatModel = new OpenAIChatModel(config);\n chatModel.chatStream(\"who are you\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onClose(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n// try {\n// Thread.sleep(2000);\n// } catch (InterruptedException e) {\n// throw new RuntimeException(e);\n// }\n }\n\n\n @Test()\n public void testChatWithImage() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-5gqOcl*****\");\n config.setModel(\"gpt-4-turbo\");\n config.setRetryEnabled(false);\n\n\n ChatModel chatModel = new OpenAIChatModel(config);\n SimplePrompt prompt = new SimplePrompt(\"What's in this image?\");\n prompt.addImageUrl(\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg\");\n\n\n AiMessageResponse response = chatModel.chat(prompt);\n System.out.println(response);\n }\n\n\n @Test()\n public void testFunctionCalling1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n System.out.println(response.executeToolCallsAndGetResults());\n // 阴转多云\n }\n\n @Test()\n public void testFunctionCalling2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling3() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57a\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling4() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57aa75\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling44() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d5\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling444() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n// config.setRequestPath(\"/api/v3/chat/completions\");\n// config.setModel(\"Qwen3-32B\");\n config.setModel(\"DeepSeek-V3.2\");\n config.setApiKey(\"PXW1G***L7D12\");\n config.setRetryEnabled(false);\n// config.setLogEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n// System.out.println(\"onMessage11 >>>>>\" + response);\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(toolMessages);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::22\" + msg);\n }\n\n @Override\n public void onClose(StreamContext context) {\n System.out.println(\"onStop >>>>>\");\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n\n }\n\n\n @Test()\n public void testFunctionCalling5() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1G*********D12\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n// System.out.println(\"onMessage >>>>>\" + response);\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling55() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling56() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling6() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n\n System.out.println(llm.chat(prompt));\n\n }\n\n\n @Test()\n public void testReAct1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"****\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n// ReActAgent reActAgent = new ReActAgent(llm, functions, \"北京和上海的天气怎么样?\");\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"介绍一下北京\");\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n }\n\n @Override\n public void onNonActionResponse(AiMessageResponse response) {\n System.out.println(\"onNonActionResponse >>>>>\" + response.getMessage().getContent());\n }\n });\n\n reActAgent.execute();\n }\n\n\n @Test()\n public void testReAct2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen2-72B-Instruct\");\n config.setApiKey(\"*****\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"今天的天气怎么样?\");\n// reActAgent.setStreamable(true);\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onChatResponseStream(StreamContext context, AiMessageResponse response) {\n// System.out.print(response.getMessage().getContent());\n }\n\n @Override\n public void onRequestUserInput(String question) {\n System.out.println(\"onRequestUserInput>>>\" + question);\n\n ReActAgentState state = reActAgent.getState();\n state.addMessage(new UserMessage(\"我在北京市\"));\n ReActAgent newAgent = new ReActAgent(llm, tools, state);\n newAgent.addListener(this);\n newAgent.execute();\n }\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n ChatMemory memory = reActAgent.getMemoryPrompt().getMemory();\n System.out.println(memory);\n }\n\n @Override\n public void onNonActionResponseStream(StreamContext context) {\n System.out.println(\"onNonActionResponseStream >>>>>\" + context);\n }\n });\n\n reActAgent.execute();\n\n TimeUnit.SECONDS.sleep(20);\n }\n\n\n @Test()\n public void testBailian() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3.5-plus\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : response.getMessage().getReasoningContent();\n\n if (content != null)\n System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n\n @Test()\n public void testDeepseek() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://api.deepseek.com\");\n config.setRequestPath(\"/chat/completions\");\n config.setModel(\"deepseek-v4-pro\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-***691\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : \"[null]\";\n\n System.out.println(\">>>>>> raw: \" + response.getRawText());\n System.out.println(\">>>>>> msg: \" + msg +\" lastMsg: \" + response.getMessage().isFinalDelta());\n\n// if (content != null)\n// System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n}\n"}, "2c9423d263b6ca283e32b435fe618f173ce61fd8": {"t": 1785755431.0909922, "n": 28333, "h": "0301ebcc55f5a173", "c": "package com.agentsflex.model.chat.openai;\n\nimport com.agentsflex.core.agent.react.ReActAgent;\nimport com.agentsflex.core.agent.react.ReActAgentListener;\nimport com.agentsflex.core.agent.react.ReActAgentState;\nimport com.agentsflex.core.agent.react.ReActStep;\nimport com.agentsflex.core.memory.ChatMemory;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.message.UserMessage;\nimport com.agentsflex.core.model.chat.*;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.chat.tool.ProviderTool;\nimport com.agentsflex.core.model.chat.tool.Tool;\nimport com.agentsflex.core.model.chat.tool.ToolScanner;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.model.exception.ModelException;\nimport com.agentsflex.core.prompt.SimplePrompt;\nimport com.agentsflex.core.util.Maps;\nimport org.junit.Test;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\npublic class OpenAIChatModelTest {\n\n @Test(expected = ModelException.class)\n public void testChat() {\n\n String output = OpenAIChatConfig.builder()\n .endpoint(\"https://ai.gitee.com\")\n .provider(\"GiteeAI\")\n .model(\"Qwen3-32B\")\n .apiKey(\"PXW1****D12\")\n .buildModel()\n .chat(\"你叫什么名字\");\n\n System.out.println(output);\n }\n\n @Test()\n public void testChatStream() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"PXW1GXE***\");\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setLogEnabled(true);\n\n ChatOptions options = ChatOptions.builder().thinkingEnabled(false).build();\n options.setContextAttributes(Maps.of(\"name\", \"张三\"));\n\n ChatModel chatModel = new OpenAIChatModel(config);\n\n\n ChatModelTestUtils.waitForStream(chatModel, \"你叫什么名字\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onStop(StreamContext context) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(\"stop!!!!\");\n }\n }, options);\n\n }\n\n\n @Test()\n public void testChatStreamBailian() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32ab******57502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京的天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test()\n public void testChatStreamBailianSearch() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32a*****502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max-2026-01-23\");\n config.addSupportProviderTools(\"web_search\", \"web_extractor\", \"code_interpreter\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"杭州明天天气如何\");\n// prompt.addToolsFromClass(WeatherFunctions.class);\n prompt.addTools(ProviderTool.ofList(\"web_search\", \"web_extractor\", \"code_interpreter\"));\n\n ChatOptions options = new ChatOptions();\n options.addExtraBody(\"enable_search\", true);\n// options.addExtraBody(\"search_options\", Maps.of(\"forced_search\",true));\n\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n// System.out.println(\"onMessage >>>>>\" + response.getMessage().getReasoningContent());\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test\n public void testChatOllama() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setEndpoint(\"http://localhost:11434\");\n config.setModel(\"llama3\");\n config.setLogEnabled(true);\n\n ChatModel chatModel = new OpenAIChatModel(config);\n chatModel.chatStream(\"who are you\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n// try {\n// Thread.sleep(2000);\n// } catch (InterruptedException e) {\n// throw new RuntimeException(e);\n// }\n }\n\n\n @Test()\n public void testChatWithImage() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-5gqOcl*****\");\n config.setModel(\"gpt-4-turbo\");\n config.setRetryEnabled(false);\n\n\n ChatModel chatModel = new OpenAIChatModel(config);\n SimplePrompt prompt = new SimplePrompt(\"What's in this image?\");\n prompt.addImageUrl(\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg\");\n\n\n AiMessageResponse response = chatModel.chat(prompt);\n System.out.println(response);\n }\n\n\n @Test()\n public void testFunctionCalling1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n System.out.println(response.executeToolCallsAndGetResults());\n // 阴转多云\n }\n\n @Test()\n public void testFunctionCalling2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling3() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57a\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling4() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57aa75\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling44() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d5\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling444() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n// config.setRequestPath(\"/api/v3/chat/completions\");\n// config.setModel(\"Qwen3-32B\");\n config.setModel(\"DeepSeek-V3.2\");\n config.setApiKey(\"PXW1G***L7D12\");\n config.setRetryEnabled(false);\n// config.setLogEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n// System.out.println(\"onMessage11 >>>>>\" + response);\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(toolMessages);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::22\" + msg);\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"onStop >>>>>\");\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n\n }\n\n\n @Test()\n public void testFunctionCalling5() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1G*********D12\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n// System.out.println(\"onMessage >>>>>\" + response);\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling55() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling56() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling6() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n\n System.out.println(llm.chat(prompt));\n\n }\n\n\n @Test()\n public void testReAct1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"****\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n// ReActAgent reActAgent = new ReActAgent(llm, functions, \"北京和上海的天气怎么样?\");\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"介绍一下北京\");\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n }\n\n @Override\n public void onNonActionResponse(AiMessageResponse response) {\n System.out.println(\"onNonActionResponse >>>>>\" + response.getMessage().getContent());\n }\n });\n\n reActAgent.execute();\n }\n\n\n @Test()\n public void testReAct2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen2-72B-Instruct\");\n config.setApiKey(\"*****\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"今天的天气怎么样?\");\n// reActAgent.setStreamable(true);\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onChatResponseStream(StreamContext context, AiMessageResponse response) {\n// System.out.print(response.getMessage().getContent());\n }\n\n @Override\n public void onRequestUserInput(String question) {\n System.out.println(\"onRequestUserInput>>>\" + question);\n\n ReActAgentState state = reActAgent.getState();\n state.addMessage(new UserMessage(\"我在北京市\"));\n ReActAgent newAgent = new ReActAgent(llm, tools, state);\n newAgent.addListener(this);\n newAgent.execute();\n }\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n ChatMemory memory = reActAgent.getMemoryPrompt().getMemory();\n System.out.println(memory);\n }\n\n @Override\n public void onNonActionResponseStream(StreamContext context) {\n System.out.println(\"onNonActionResponseStream >>>>>\" + context);\n }\n });\n\n reActAgent.execute();\n\n TimeUnit.SECONDS.sleep(20);\n }\n\n\n @Test()\n public void testBailian() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3.5-plus\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : response.getMessage().getReasoningContent();\n\n if (content != null)\n System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n\n @Test()\n public void testDeepseek() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://api.deepseek.com\");\n config.setRequestPath(\"/chat/completions\");\n config.setModel(\"deepseek-v4-pro\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-***691\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : \"[null]\";\n\n System.out.println(\">>>>>> raw: \" + response.getRawText());\n System.out.println(\">>>>>> msg: \" + msg +\" lastMsg: \" + response.getMessage().isFinalDelta());\n\n// if (content != null)\n// System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n}\n"}, "17a0f04ccfe6cecb83391cb3ad819e6af4060dc5": {"t": 1785755434.12444, "n": 25891, "h": "342250ccf8967edf", "c": "package com.agentsflex.model.chat.openai;\n\nimport com.agentsflex.core.agent.react.ReActAgent;\nimport com.agentsflex.core.agent.react.ReActAgentListener;\nimport com.agentsflex.core.agent.react.ReActAgentState;\nimport com.agentsflex.core.agent.react.ReActStep;\nimport com.agentsflex.core.memory.ChatMemory;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.message.UserMessage;\nimport com.agentsflex.core.model.chat.*;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.chat.tool.ProviderTool;\nimport com.agentsflex.core.model.chat.tool.Tool;\nimport com.agentsflex.core.model.chat.tool.ToolScanner;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.model.exception.ModelException;\nimport com.agentsflex.core.prompt.SimplePrompt;\nimport com.agentsflex.core.util.Maps;\nimport org.junit.Test;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\npublic class OpenAIChatModelTest {\n\n @Test(expected = ModelException.class)\n public void testChat() {\n\n String output = OpenAIChatConfig.builder()\n .endpoint(\"https://ai.gitee.com\")\n .provider(\"GiteeAI\")\n .model(\"Qwen3-32B\")\n .apiKey(\"PXW1****D12\")\n .buildModel()\n .chat(\"你叫什么名字\");\n\n System.out.println(output);\n }\n\n @Test()\n public void testChatStream() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"PXW1GXE***\");\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setLogEnabled(true);\n\n ChatOptions options = ChatOptions.builder().thinkingEnabled(false).build();\n options.setContextAttributes(Maps.of(\"name\", \"张三\"));\n\n ChatModel chatModel = new OpenAIChatModel(config);\n\n\n ChatModelTestUtils.waitForStream(chatModel, \"你叫什么名字\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onStop(StreamContext context) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(\"stop!!!!\");\n }\n }, options);\n\n }\n\n\n @Test()\n public void testChatStreamBailian() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32ab******57502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京的天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test()\n public void testChatStreamBailianSearch() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32a*****502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max-2026-01-23\");\n config.addSupportProviderTools(\"web_search\", \"web_extractor\", \"code_interpreter\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"杭州明天天气如何\");\n// prompt.addToolsFromClass(WeatherFunctions.class);\n prompt.addTools(ProviderTool.ofList(\"web_search\", \"web_extractor\", \"code_interpreter\"));\n\n ChatOptions options = new ChatOptions();\n options.addExtraBody(\"enable_search\", true);\n// options.addExtraBody(\"search_options\", Maps.of(\"forced_search\",true));\n\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n// System.out.println(\"onMessage >>>>>\" + response.getMessage().getReasoningContent());\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test\n public void testChatOllama() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setEndpoint(\"http://localhost:11434\");\n config.setModel(\"llama3\");\n config.setLogEnabled(true);\n\n ChatModel chatModel = new OpenAIChatModel(config);\n chatModel.chatStream(\"who are you\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n// try {\n// Thread.sleep(2000);\n// } catch (InterruptedException e) {\n// throw new RuntimeException(e);\n// }\n }\n\n\n @Test()\n public void testChatWithImage() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-5gqOcl*****\");\n config.setModel(\"gpt-4-turbo\");\n config.setRetryEnabled(false);\n\n\n ChatModel chatModel = new OpenAIChatModel(config);\n SimplePrompt prompt = new SimplePrompt(\"What's in this image?\");\n prompt.addImageUrl(\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg\");\n\n\n AiMessageResponse response = chatModel.chat(prompt);\n System.out.println(response);\n }\n\n\n @Test()\n public void testFunctionCalling1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n System.out.println(response.executeToolCallsAndGetResults());\n // 阴转多云\n }\n\n @Test()\n public void testFunctionCalling2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling3() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57a\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling4() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57aa75\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling44() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d5\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling444() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n// config.setRequestPath(\"/api/v3/chat/completions\");\n// config.setModel(\"Qwen3-32B\");\n config.setModel(\"DeepSeek-V3.2\");\n config.setApiKey(\"PXW1G***L7D12\");\n config.setRetryEnabled(false);\n// config.setLogEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n// System.out.println(\"onMessage11 >>>>>\" + response);\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(toolMessages);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::22\" + msg);\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"onStop >>>>>\");\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n\n }\n\n\n @Test()\n public void testFunctionCalling5() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1G*********D12\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n// System.out.println(\"onMessage >>>>>\" + response);\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling55() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling56() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling6() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n\n System.out.println(llm.chat(prompt));\n\n }\n\n\n @Test()\n public void testReAct1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"****\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n// ReActAgent reActAgent = new ReActAgent(llm, functions, \"北京和上海的天气怎么样?\");\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"介绍一下北京\");\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n }\n\n @Override\n public void onNonActionResponse(AiMessageResponse response) {\n System.out.println(\"onNonActionResponse >>>>>\" + response.getMessage().getContent());\n }\n });\n\n reActAgent.execute();\n }\n\n\n @Test()\n public void testReAct2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen2-72B-Instruct\");\n config.setApiKey(\"*****\");\n config.setRetryEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"今天的天气怎么样?\");\n// reActAgent.setStreamable(true);\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onChatResponseStream(StreamContext context, AiMessageResponse response) {\n// System.out.print(response.getMessage().getContent());\n }\n\n @Override\n public void onRequestUserInput(String question) {\n System.out.println(\"onRequestUserInput>>>\" + question);\n\n ReActAgentState state = reActAgent.getState();\n state.addMessage(new UserMessage(\"我在北京市\"));\n ReActAgent newAgent = new ReActAgent(llm, tools, state);\n newAgent.addListener(this);\n newAgent.execute();\n }\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n ChatMemory memory = reActAgent.getMemoryPrompt().getMemory();\n System.out.println(memory);\n }\n\n @Override\n public void onNonActionResponseStream(StreamContext context) {\n System.out.println(\"onNonActionResponseStream >>>>>\" + context);\n }\n });\n\n reActAgent.execute();\n\n TimeUnit.SECONDS.sleep(20);\n }\n\n\n @Test()\n public void testBailian() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3.5-plus\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-\");\n config.setRetryEnabled(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : response.getMessage().getReasoningContent();\n\n if (content != null)\n System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n}\n"}, "418447e4bbdefec2ec87d490a4a6982f94185e36": {"t": 1785755435.842826, "n": 25384, "h": "ea4af9797abab6b6", "c": "package com.agentsflex.model.chat.openai;\n\nimport com.agentsflex.core.agent.react.ReActAgent;\nimport com.agentsflex.core.agent.react.ReActAgentListener;\nimport com.agentsflex.core.agent.react.ReActAgentState;\nimport com.agentsflex.core.agent.react.ReActStep;\nimport com.agentsflex.core.memory.ChatMemory;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.message.UserMessage;\nimport com.agentsflex.core.model.chat.*;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.chat.tool.ProviderTool;\nimport com.agentsflex.core.model.chat.tool.Tool;\nimport com.agentsflex.core.model.chat.tool.ToolScanner;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.model.exception.ModelException;\nimport com.agentsflex.core.prompt.SimplePrompt;\nimport com.agentsflex.core.util.Maps;\nimport org.junit.Test;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\npublic class OpenAIChatModelTest {\n\n @Test(expected = ModelException.class)\n public void testChat() {\n\n String output = OpenAIChatConfig.builder()\n .endpoint(\"https://ai.gitee.com\")\n .provider(\"GiteeAI\")\n .model(\"Qwen3-32B\")\n .apiKey(\"PXW1****D12\")\n .buildModel()\n .chat(\"你叫什么名字\");\n\n System.out.println(output);\n }\n\n @Test()\n public void testChatStream() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"PXW1GXE***\");\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setLogEnabled(true);\n\n ChatOptions options = ChatOptions.builder().thinkingEnabled(false).build();\n options.setContextAttributes(Maps.of(\"name\", \"张三\"));\n\n ChatModel chatModel = new OpenAIChatModel(config);\n\n\n ChatModelTestUtils.waitForStream(chatModel, \"你叫什么名字\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onStop(StreamContext context) {\n ChatContext x = ChatContextHolder.currentContext();\n System.out.println(x);\n System.out.println(\"stop!!!!\");\n }\n }, options);\n\n }\n\n\n @Test()\n public void testChatStreamBailian() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32ab******57502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京的天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test()\n public void testChatStreamBailianSearch() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32a*****502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max-2026-01-23\");\n config.addSupportProviderTools(\"web_search\", \"web_extractor\", \"code_interpreter\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"杭州明天天气如何\");\n// prompt.addToolsFromClass(WeatherFunctions.class);\n prompt.addTools(ProviderTool.ofList(\"web_search\", \"web_extractor\", \"code_interpreter\"));\n\n ChatOptions options = new ChatOptions();\n options.addExtraBody(\"enable_search\", true);\n// options.addExtraBody(\"search_options\", Maps.of(\"forced_search\",true));\n\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n// System.out.println(\"onMessage >>>>>\" + response.getMessage().getReasoningContent());\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test\n public void testChatOllama() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setEndpoint(\"http://localhost:11434\");\n config.setModel(\"llama3\");\n config.setLogEnabled(true);\n\n ChatModel chatModel = new OpenAIChatModel(config);\n chatModel.chatStream(\"who are you\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n// try {\n// Thread.sleep(2000);\n// } catch (InterruptedException e) {\n// throw new RuntimeException(e);\n// }\n }\n\n\n @Test()\n public void testChatWithImage() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-5gqOcl*****\");\n config.setModel(\"gpt-4-turbo\");\n\n\n ChatModel chatModel = new OpenAIChatModel(config);\n SimplePrompt prompt = new SimplePrompt(\"What's in this image?\");\n prompt.addImageUrl(\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg\");\n\n\n AiMessageResponse response = chatModel.chat(prompt);\n System.out.println(response);\n }\n\n\n @Test()\n public void testFunctionCalling1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n System.out.println(response.executeToolCallsAndGetResults());\n // 阴转多云\n }\n\n @Test()\n public void testFunctionCalling2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling3() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57a\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling4() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57aa75\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling44() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d5\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling444() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n// config.setRequestPath(\"/api/v3/chat/completions\");\n// config.setModel(\"Qwen3-32B\");\n config.setModel(\"DeepSeek-V3.2\");\n config.setApiKey(\"PXW1G***L7D12\");\n// config.setLogEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n// System.out.println(\"onMessage11 >>>>>\" + response);\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(toolMessages);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::22\" + msg);\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"onStop >>>>>\");\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n\n }\n\n\n @Test()\n public void testFunctionCalling5() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1G*********D12\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n// System.out.println(\"onMessage >>>>>\" + response);\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling55() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setApiKey(\"PXW1\");\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling56() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n config.setApiKey(\"PXW1\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling6() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n\n System.out.println(llm.chat(prompt));\n\n }\n\n\n @Test()\n public void testReAct1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"****\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n// ReActAgent reActAgent = new ReActAgent(llm, functions, \"北京和上海的天气怎么样?\");\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"介绍一下北京\");\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n }\n\n @Override\n public void onNonActionResponse(AiMessageResponse response) {\n System.out.println(\"onNonActionResponse >>>>>\" + response.getMessage().getContent());\n }\n });\n\n reActAgent.execute();\n }\n\n\n @Test()\n public void testReAct2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen2-72B-Instruct\");\n config.setApiKey(\"*****\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"今天的天气怎么样?\");\n// reActAgent.setStreamable(true);\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onChatResponseStream(StreamContext context, AiMessageResponse response) {\n// System.out.print(response.getMessage().getContent());\n }\n\n @Override\n public void onRequestUserInput(String question) {\n System.out.println(\"onRequestUserInput>>>\" + question);\n\n ReActAgentState state = reActAgent.getState();\n state.addMessage(new UserMessage(\"我在北京市\"));\n ReActAgent newAgent = new ReActAgent(llm, tools, state);\n newAgent.addListener(this);\n newAgent.execute();\n }\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n ChatMemory memory = reActAgent.getMemoryPrompt().getMemory();\n System.out.println(memory);\n }\n\n @Override\n public void onNonActionResponseStream(StreamContext context) {\n System.out.println(\"onNonActionResponseStream >>>>>\" + context);\n }\n });\n\n reActAgent.execute();\n\n TimeUnit.SECONDS.sleep(20);\n }\n\n\n @Test()\n public void testBailian() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3.5-plus\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-\");\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : response.getMessage().getReasoningContent();\n\n if (content != null)\n System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n}\n"}, "c7dacad3f01023b644c45d18fed65bda316e9cfd": {"t": 1785755438.0681622, "n": 25229, "h": "71e84377dc5ef14c", "c": "package com.agentsflex.model.chat.openai;\n\nimport com.agentsflex.core.agent.react.ReActAgent;\nimport com.agentsflex.core.agent.react.ReActAgentListener;\nimport com.agentsflex.core.agent.react.ReActAgentState;\nimport com.agentsflex.core.agent.react.ReActStep;\nimport com.agentsflex.core.memory.ChatMemory;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.message.UserMessage;\nimport com.agentsflex.core.model.chat.ChatModel;\nimport com.agentsflex.core.model.chat.ChatOptions;\nimport com.agentsflex.core.model.chat.StreamResponseListener;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.chat.tool.ProviderTool;\nimport com.agentsflex.core.model.chat.tool.Tool;\nimport com.agentsflex.core.model.chat.tool.ToolScanner;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.model.exception.ModelException;\nimport com.agentsflex.core.prompt.SimplePrompt;\nimport com.agentsflex.core.util.Maps;\nimport org.junit.Test;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\npublic class OpenAIChatModelTest {\n\n @Test(expected = ModelException.class)\n public void testChat() {\n\n String output = OpenAIChatConfig.builder()\n .endpoint(\"https://ai.gitee.com\")\n .provider(\"GiteeAI\")\n .model(\"Qwen3-32B\")\n .apiKey(\"PXW1****D12\")\n .buildModel()\n .chat(\"你叫什么名字\");\n\n System.out.println(output);\n }\n\n @Test()\n public void testChatStream() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"PXW1GXE***\");\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setLogEnabled(true);\n\n ChatOptions options = ChatOptions.builder().thinkingEnabled(false).build();\n\n ChatModel chatModel = new OpenAIChatModel(config);\n\n ChatModelTestUtils.waitForStream(chatModel, \"你叫什么名字\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n }, options);\n\n }\n\n\n @Test()\n public void testChatStreamBailian() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32ab******57502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京的天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test()\n public void testChatStreamBailianSearch() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32a*****502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max-2026-01-23\");\n config.addSupportProviderTools(\"web_search\", \"web_extractor\", \"code_interpreter\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"杭州明天天气如何\");\n// prompt.addToolsFromClass(WeatherFunctions.class);\n prompt.addTools(ProviderTool.ofList(\"web_search\", \"web_extractor\", \"code_interpreter\"));\n\n ChatOptions options = new ChatOptions();\n options.addExtraBody(\"enable_search\", true);\n// options.addExtraBody(\"search_options\", Maps.of(\"forced_search\",true));\n\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n// System.out.println(\"onMessage >>>>>\" + response.getMessage().getReasoningContent());\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test\n public void testChatOllama() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setEndpoint(\"http://localhost:11434\");\n config.setModel(\"llama3\");\n config.setLogEnabled(true);\n\n ChatModel chatModel = new OpenAIChatModel(config);\n chatModel.chatStream(\"who are you\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n// try {\n// Thread.sleep(2000);\n// } catch (InterruptedException e) {\n// throw new RuntimeException(e);\n// }\n }\n\n\n @Test()\n public void testChatWithImage() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-5gqOcl*****\");\n config.setModel(\"gpt-4-turbo\");\n\n\n ChatModel chatModel = new OpenAIChatModel(config);\n SimplePrompt prompt = new SimplePrompt(\"What's in this image?\");\n prompt.addImageUrl(\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg\");\n\n\n AiMessageResponse response = chatModel.chat(prompt);\n System.out.println(response);\n }\n\n\n @Test()\n public void testFunctionCalling1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n System.out.println(response.executeToolCallsAndGetResults());\n // 阴转多云\n }\n\n @Test()\n public void testFunctionCalling2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling3() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57a\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling4() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57aa75\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling44() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d5\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling444() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n// config.setRequestPath(\"/api/v3/chat/completions\");\n// config.setModel(\"Qwen3-32B\");\n config.setModel(\"DeepSeek-V3.2\");\n config.setApiKey(\"PXW1G***L7D12\");\n// config.setLogEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n// System.out.println(\"onMessage11 >>>>>\" + response);\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(toolMessages);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::22\" + msg);\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"onStop >>>>>\");\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n\n }\n\n\n @Test()\n public void testFunctionCalling5() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1G*********D12\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n// System.out.println(\"onMessage >>>>>\" + response);\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling55() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setApiKey(\"PXW1\");\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling56() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n config.setApiKey(\"PXW1\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling6() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n\n System.out.println(llm.chat(prompt));\n\n }\n\n\n @Test()\n public void testReAct1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"****\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n// ReActAgent reActAgent = new ReActAgent(llm, functions, \"北京和上海的天气怎么样?\");\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"介绍一下北京\");\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n }\n\n @Override\n public void onNonActionResponse(AiMessageResponse response) {\n System.out.println(\"onNonActionResponse >>>>>\" + response.getMessage().getContent());\n }\n });\n\n reActAgent.execute();\n }\n\n\n @Test()\n public void testReAct2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen2-72B-Instruct\");\n config.setApiKey(\"*****\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"今天的天气怎么样?\");\n// reActAgent.setStreamable(true);\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onChatResponseStream(StreamContext context, AiMessageResponse response) {\n// System.out.print(response.getMessage().getContent());\n }\n\n @Override\n public void onRequestUserInput(String question) {\n System.out.println(\"onRequestUserInput>>>\" + question);\n\n ReActAgentState state = reActAgent.getState();\n state.addMessage(new UserMessage(\"我在北京市\"));\n ReActAgent newAgent = new ReActAgent(llm, tools, state);\n newAgent.addListener(this);\n newAgent.execute();\n }\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n ChatMemory memory = reActAgent.getMemoryPrompt().getMemory();\n System.out.println(memory);\n }\n\n @Override\n public void onNonActionResponseStream(StreamContext context) {\n System.out.println(\"onNonActionResponseStream >>>>>\" + context);\n }\n });\n\n reActAgent.execute();\n\n TimeUnit.SECONDS.sleep(20);\n }\n\n\n @Test()\n public void testBailian() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3.5-plus\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-\");\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : response.getMessage().getReasoningContent();\n\n if (content != null)\n System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n}\n"}, "af05784bc48b00fbfffe5910130818c6b306231b": {"t": 1785755440.6010883, "n": 23119, "h": "0d982b2594683bd8", "c": "package com.agentsflex.model.chat.openai;\n\nimport com.agentsflex.core.agent.react.ReActAgent;\nimport com.agentsflex.core.agent.react.ReActAgentListener;\nimport com.agentsflex.core.agent.react.ReActAgentState;\nimport com.agentsflex.core.agent.react.ReActStep;\nimport com.agentsflex.core.memory.ChatMemory;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.message.UserMessage;\nimport com.agentsflex.core.model.chat.ChatModel;\nimport com.agentsflex.core.model.chat.ChatOptions;\nimport com.agentsflex.core.model.chat.StreamResponseListener;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.chat.tool.Tool;\nimport com.agentsflex.core.model.chat.tool.ToolScanner;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.model.exception.ModelException;\nimport com.agentsflex.core.prompt.SimplePrompt;\nimport org.junit.Test;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\npublic class OpenAIChatModelTest {\n\n @Test(expected = ModelException.class)\n public void testChat() {\n\n String output = OpenAIChatConfig.builder()\n .endpoint(\"https://ai.gitee.com\")\n .provider(\"GiteeAI\")\n .model(\"Qwen3-32B\")\n .apiKey(\"PXW1****D12\")\n .buildModel()\n .chat(\"你叫什么名字\");\n\n System.out.println(output);\n }\n\n @Test()\n public void testChatStream() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"PXW1GXE***\");\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setLogEnabled(true);\n\n ChatOptions options = ChatOptions.builder().thinkingEnabled(false).build();\n\n ChatModel chatModel = new OpenAIChatModel(config);\n\n ChatModelTestUtils.waitForStream(chatModel, \"你叫什么名字\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n }, options);\n\n }\n\n\n @Test()\n public void testChatStreamBailian() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32ab******57502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京的天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test\n public void testChatOllama() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setEndpoint(\"http://localhost:11434\");\n config.setModel(\"llama3\");\n config.setLogEnabled(true);\n\n ChatModel chatModel = new OpenAIChatModel(config);\n chatModel.chatStream(\"who are you\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n// try {\n// Thread.sleep(2000);\n// } catch (InterruptedException e) {\n// throw new RuntimeException(e);\n// }\n }\n\n\n @Test()\n public void testChatWithImage() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-5gqOcl*****\");\n config.setModel(\"gpt-4-turbo\");\n\n\n ChatModel chatModel = new OpenAIChatModel(config);\n SimplePrompt prompt = new SimplePrompt(\"What's in this image?\");\n prompt.addImageUrl(\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg\");\n\n\n AiMessageResponse response = chatModel.chat(prompt);\n System.out.println(response);\n }\n\n\n @Test()\n public void testFunctionCalling1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n System.out.println(response.executeToolCallsAndGetResults());\n // 阴转多云\n }\n\n @Test()\n public void testFunctionCalling2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling3() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57a\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling4() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57aa75\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling44() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d5\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling444() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n// config.setRequestPath(\"/api/v3/chat/completions\");\n// config.setModel(\"Qwen3-32B\");\n config.setModel(\"DeepSeek-V3.2\");\n config.setApiKey(\"PXW1G***L7D12\");\n// config.setLogEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n// System.out.println(\"onMessage11 >>>>>\" + response);\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(toolMessages);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::22\" + msg);\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"onStop >>>>>\");\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n\n }\n\n\n @Test()\n public void testFunctionCalling5() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1G*********D12\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n// System.out.println(\"onMessage >>>>>\" + response);\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling55() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setApiKey(\"PXW1\");\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling56() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n config.setApiKey(\"PXW1\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n\n @Test()\n public void testFunctionCalling6() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n\n System.out.println(llm.chat(prompt));\n\n }\n\n\n @Test()\n public void testReAct1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"****\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n// ReActAgent reActAgent = new ReActAgent(llm, functions, \"北京和上海的天气怎么样?\");\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"介绍一下北京\");\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n }\n\n @Override\n public void onNonActionResponse(AiMessageResponse response) {\n System.out.println(\"onNonActionResponse >>>>>\" + response.getMessage().getContent());\n }\n });\n\n reActAgent.execute();\n }\n\n\n @Test()\n public void testReAct2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen2-72B-Instruct\");\n config.setApiKey(\"*****\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"今天的天气怎么样?\");\n// reActAgent.setStreamable(true);\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onChatResponseStream(StreamContext context, AiMessageResponse response) {\n// System.out.print(response.getMessage().getContent());\n }\n\n @Override\n public void onRequestUserInput(String question) {\n System.out.println(\"onRequestUserInput>>>\" + question);\n\n ReActAgentState state = reActAgent.getState();\n state.addMessage(new UserMessage(\"我在北京市\"));\n ReActAgent newAgent = new ReActAgent(llm, tools, state);\n newAgent.addListener(this);\n newAgent.execute();\n }\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n ChatMemory memory = reActAgent.getMemoryPrompt().getMemory();\n System.out.println(memory);\n }\n\n @Override\n public void onNonActionResponseStream(StreamContext context) {\n System.out.println(\"onNonActionResponseStream >>>>>\" + context);\n }\n });\n\n reActAgent.execute();\n\n TimeUnit.SECONDS.sleep(20);\n }\n\n\n\n @Test()\n public void testBailian() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3.5-plus\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-\");\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String content = response.getMessage().getContent();\n String msg = content != null ? content : response.getMessage().getReasoningContent();\n\n if (content != null)\n System.out.println(content);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n}\n"}, "06a04fec97a8fc6faa4590580c38d2c7a1edf7ca": {"t": 1785755444.2578332, "n": 23064, "h": "01be9927c9adb1a3", "c": "package com.agentsflex.model.chat.openai;\n\nimport com.agentsflex.core.agent.react.ReActAgent;\nimport com.agentsflex.core.agent.react.ReActAgentListener;\nimport com.agentsflex.core.agent.react.ReActAgentState;\nimport com.agentsflex.core.agent.react.ReActStep;\nimport com.agentsflex.core.memory.ChatMemory;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.ToolMessage;\nimport com.agentsflex.core.message.UserMessage;\nimport com.agentsflex.core.model.chat.ChatModel;\nimport com.agentsflex.core.model.chat.ChatOptions;\nimport com.agentsflex.core.model.chat.StreamResponseListener;\nimport com.agentsflex.core.model.chat.response.AiMessageResponse;\nimport com.agentsflex.core.model.chat.tool.Tool;\nimport com.agentsflex.core.model.chat.tool.ToolScanner;\nimport com.agentsflex.core.model.client.StreamContext;\nimport com.agentsflex.core.model.exception.ModelException;\nimport com.agentsflex.core.prompt.SimplePrompt;\nimport org.junit.Test;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\npublic class OpenAIChatModelTest {\n\n @Test(expected = ModelException.class)\n public void testChat() {\n\n String output = OpenAIChatConfig.builder()\n .endpoint(\"https://ai.gitee.com\")\n .provider(\"GiteeAI\")\n .model(\"Qwen3-32B\")\n .apiKey(\"PXW1****D12\")\n .buildModel()\n .chat(\"你叫什么名字\");\n\n System.out.println(output);\n }\n\n @Test()\n public void testChatStream() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"PXW1GXE***\");\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setLogEnabled(true);\n\n ChatOptions options = ChatOptions.builder().thinkingEnabled(false).build();\n\n ChatModel chatModel = new OpenAIChatModel(config);\n\n ChatModelTestUtils.waitForStream(chatModel, \"你叫什么名字\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n }, options);\n\n }\n\n\n @Test()\n public void testChatStreamBailian() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-32ab******57502\");\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3-max\");\n ChatModel chatModel = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京的天气如何?\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n ChatModelTestUtils.waitForStream(chatModel, prompt, new StreamResponseListener() {\n @Override\n public void onFailure(StreamContext context, Throwable throwable) {\n System.out.println(\"onFailure>>>>\" + throwable);\n }\n\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().getContent() == null) {\n System.out.println(response.getMessage());\n }\n\n if (response.getMessage().isFinalDelta()) {\n List<ToolCall> toolCalls = response.getMessage().getToolCalls();\n System.out.println(toolCalls);\n }\n\n System.out.println(\"onMessage >>>>>\" + response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n }\n\n @Test\n public void testChatOllama() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setEndpoint(\"http://localhost:11434\");\n config.setModel(\"llama3\");\n config.setLogEnabled(true);\n\n ChatModel chatModel = new OpenAIChatModel(config);\n chatModel.chatStream(\"who are you\", new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(response.getMessage().getContent());\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"stop!!!!\");\n }\n });\n\n// try {\n// Thread.sleep(2000);\n// } catch (InterruptedException e) {\n// throw new RuntimeException(e);\n// }\n }\n\n\n @Test()\n public void testChatWithImage() {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-5gqOcl*****\");\n config.setModel(\"gpt-4-turbo\");\n\n\n ChatModel chatModel = new OpenAIChatModel(config);\n SimplePrompt prompt = new SimplePrompt(\"What's in this image?\");\n prompt.addImageUrl(\"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg\");\n\n\n AiMessageResponse response = chatModel.chat(prompt);\n System.out.println(response);\n }\n\n\n @Test()\n public void testFunctionCalling1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n System.out.println(response.executeToolCallsAndGetResults());\n // 阴转多云\n }\n\n @Test()\n public void testFunctionCalling2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setApiKey(\"sk-rts5NF6n*******\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling3() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57a\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n if (response.hasToolCalls()) {\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n AiMessageResponse response1 = llm.chat(prompt);\n System.out.println(response1.getMessage().getContent());\n } else {\n System.out.println(response);\n }\n }\n\n @Test()\n public void testFunctionCalling4() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d57aa75\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling44() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ark.cn-beijing.volces.com\");\n config.setRequestPath(\"/api/v3/chat/completions\");\n config.setModel(\"deepseek-v3-250324\");\n config.setApiKey(\"2d5\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"今天北京的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n System.out.println(\" onMessage >>>>>\" + response.hasToolCalls());\n }\n });\n\n TimeUnit.SECONDS.sleep(5);\n }\n\n @Test()\n public void testFunctionCalling444() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n// config.setRequestPath(\"/api/v3/chat/completions\");\n// config.setModel(\"Qwen3-32B\");\n config.setModel(\"DeepSeek-V3.2\");\n config.setApiKey(\"PXW1G***L7D12\");\n// config.setLogEnabled(false);\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n// System.out.println(\"onMessage11 >>>>>\" + response);\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n List<ToolMessage> toolMessages = response.executeToolCallsAndGetToolMessages();\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(toolMessages);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::22\" + msg);\n }\n\n @Override\n public void onStop(StreamContext context) {\n System.out.println(\"onStop >>>>>\");\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n\n }\n\n\n @Test()\n public void testFunctionCalling5() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1G*********D12\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n// System.out.println(\"onMessage >>>>>\" + response);\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling55() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setApiKey(\"PXW1\");\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n @Test()\n public void testFunctionCalling56() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3.5-35B-A3B\");\n config.setApiKey(\"PXW1\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions1.class);\n\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n System.out.println(\":::::::: start....\");\n prompt.setAiMessage(response.getMessage());\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\":::\" + msg);\n }\n });\n } else {\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(\">>>\" + msg);\n }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n\n @Test()\n public void testFunctionCalling6() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"PXW1\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"/no_think 北京和上海的天气怎么样\");\n prompt.addToolsFromClass(WeatherFunctions.class);\n AiMessageResponse response = llm.chat(prompt);\n\n prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n\n System.out.println(llm.chat(prompt));\n\n }\n\n\n @Test()\n public void testReAct1() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen3-32B\");\n config.setApiKey(\"****\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n// ReActAgent reActAgent = new ReActAgent(llm, functions, \"北京和上海的天气怎么样?\");\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"介绍一下北京\");\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n }\n\n @Override\n public void onNonActionResponse(AiMessageResponse response) {\n System.out.println(\"onNonActionResponse >>>>>\" + response.getMessage().getContent());\n }\n });\n\n reActAgent.execute();\n }\n\n\n @Test()\n public void testReAct2() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n// config.setDebug(true);\n config.setEndpoint(\"https://ai.gitee.com\");\n config.setModel(\"Qwen2-72B-Instruct\");\n config.setApiKey(\"*****\");\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n List<Tool> tools = ToolScanner.scan(WeatherFunctions.class);\n ReActAgent reActAgent = new ReActAgent(llm, tools, \"今天的天气怎么样?\");\n// reActAgent.setStreamable(true);\n reActAgent.addListener(new ReActAgentListener() {\n\n @Override\n public void onChatResponseStream(StreamContext context, AiMessageResponse response) {\n// System.out.print(response.getMessage().getContent());\n }\n\n @Override\n public void onRequestUserInput(String question) {\n System.out.println(\"onRequestUserInput>>>\" + question);\n\n ReActAgentState state = reActAgent.getState();\n state.addMessage(new UserMessage(\"我在北京市\"));\n ReActAgent newAgent = new ReActAgent(llm, tools, state);\n newAgent.addListener(this);\n newAgent.execute();\n }\n\n @Override\n public void onActionStart(ReActStep step) {\n System.out.println(\">>>>>>\" + step.getThought());\n System.out.println(\"正在调用工具 >>>>> \" + step.getAction() + \":\" + step.getActionInput());\n }\n\n @Override\n public void onActionEnd(ReActStep step, Object result) {\n System.out.println(\"工具调用结束 >>>>> \" + step.getAction() + \":\" + step.getActionInput() + \">>>>结果:\" + result);\n }\n\n @Override\n public void onFinalAnswer(String finalAnswer) {\n System.out.println(\"onFinalAnswer >>>>>\" + finalAnswer);\n ChatMemory memory = reActAgent.getMemoryPrompt().getMemory();\n System.out.println(memory);\n }\n\n @Override\n public void onNonActionResponseStream(StreamContext context) {\n System.out.println(\"onNonActionResponseStream >>>>>\" + context);\n }\n });\n\n reActAgent.execute();\n\n TimeUnit.SECONDS.sleep(20);\n }\n\n\n\n @Test()\n public void testBailian() throws InterruptedException {\n OpenAIChatConfig config = new OpenAIChatConfig();\n config.setLogEnabled(true);\n config.setEndpoint(\"https://dashscope.aliyuncs.com\");\n config.setRequestPath(\"/compatible-mode/v1/chat/completions\");\n config.setModel(\"qwen3.5-plus\");\n// config.setModel(\"DeepSeek-V3\");\n// config.setSupportToolMessage(false);\n config.setLogEnabled(false);\n config.setApiKey(\"sk-\");\n\n\n OpenAIChatModel llm = new OpenAIChatModel(config);\n\n SimplePrompt prompt = new SimplePrompt(\"这个学生默写的化学公式,你帮忙最大程度识别出来,然后判断他写的是对是错,如果错的,你给出正确答案。 输出时,请按 Latex 进行输出。\");\n\n llm.chatStream(prompt, new StreamResponseListener() {\n @Override\n public void onMessage(StreamContext context, AiMessageResponse response) {\n\n String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n System.out.println(msg);\n\n// if (response.getMessage().isFinalDelta() && response.hasToolCalls()) {\n// System.out.println(\":::::::: start....\");\n// prompt.setAiMessage(response.getMessage());\n// prompt.setToolMessages(response.executeToolCallsAndGetToolMessages());\n// llm.chatStream(prompt, new StreamResponseListener() {\n// @Override\n// public void onMessage(StreamContext context, AiMessageResponse response) {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\":::\" + msg);\n// }\n// });\n// } else {\n// String msg = response.getMessage().getContent() != null ? response.getMessage().getContent() : response.getMessage().getReasoningContent();\n// System.out.println(\">>>\" + msg);\n// }\n }\n });\n\n TimeUnit.SECONDS.sleep(25);\n }\n\n\n}\n"}}, "demos/agent-console-demo/src/main/java/com/agentsflex/demo/agent/console/StreamingAgentConsoleDemo.java": {"3a2b0b1bff557e9a769d6b66bcd848020a0af2c4": {"t": 1786068377.866146, "n": 37596, "h": "8f87db3ac9b43357", "c": "/*\n * Copyright (c) 2023-2026, Agents-Flex (fuhai999@gmail.com).\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n */\npackage com.agentsflex.demo.agent.console;\n\nimport com.agentsflex.agent.Agent;\nimport com.agentsflex.agent.AgentBudget;\nimport com.agentsflex.agent.AgentExecutionPolicy;\nimport com.agentsflex.agent.AgentResumeCommand;\nimport com.agentsflex.agent.AgentRunner;\nimport com.agentsflex.agent.AgentSuspension;\nimport com.agentsflex.agent.AgentTurn;\nimport com.agentsflex.agent.AgentTurnOptions;\nimport com.agentsflex.agent.AgentTurnStatus;\nimport com.agentsflex.agent.event.AgentEvent;\nimport com.agentsflex.agent.event.AgentEventType;\nimport com.agentsflex.agent.loader.InMemoryAgentLoader;\nimport com.agentsflex.agent.message.AgentFormMessage;\nimport com.agentsflex.agent.task.AgentPlanningPolicy;\nimport com.agentsflex.agent.task.AgentTask;\nimport com.agentsflex.agent.task.AgentTaskProgress;\nimport com.agentsflex.agent.tool.AgentFormDefinition;\nimport com.agentsflex.agent.tool.AgentFormRequiredException;\nimport com.agentsflex.agent.tool.AgentToolContext;\nimport com.agentsflex.agent.tool.AgentUserInputTool;\nimport com.agentsflex.agent.tool.ToolApprovalDecision;\nimport com.agentsflex.core.memory.ChatMemory;\nimport com.agentsflex.core.memory.ChatMemoryProvider;\nimport com.agentsflex.core.memory.DefaultChatMemory;\nimport com.agentsflex.core.message.Message;\nimport com.agentsflex.core.message.ToolCall;\nimport com.agentsflex.core.message.UserMessage;\nimport com.agentsflex.core.model.chat.ChatModel;\nimport com.agentsflex.core.model.chat.tool.Parameter;\nimport com.agentsflex.core.model.chat.tool.Tool;\nimport com.agentsflex.model.chat.openai.OpenAIChatConfig;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.nio.charset.StandardCharsets;\nimport java.time.DateTimeException;\nimport java.time.ZoneId;\nimport java.time.ZonedDateTime;\nimport java.time.format.DateTimeFormatter;\nimport java.util.Arrays;\nimport java.util.Collections;\nimport java.util.LinkedHashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.UUID;\nimport java.util.concurrent.atomic.AtomicInteger;\nimport java.util.concurrent.ConcurrentHashMap;\n\n/**\n * 使用真实大模型演示持续对话、任务规划、原生 ToolCall 和 Human-in-the-loop 的控制台程序。\n *\n * <p>业务代码维护 conversationId 和 ChatMemory,Runner 按配置的消息窗口读取模型历史,并把本轮新增\n * 消息幂等投影回业务 ChatMemory。模型直接回答时 Turn 一步完成;模型选择工具时 Runner 自动执行工具\n * 并继续调用模型;工具可以在副作用前请求结构化表单,控制台按 Schema 收集数据并恢复原调用;复杂\n * 目标可拆成顺序子任务;高风险工具会先进入审批等待状态,控制台收集人的决定后按根 turnId 恢复\n * 实际阻塞的 Turn。</p>\n */\npublic final class StreamingAgentConsoleDemo {\n\n private static final Set<String> STREAMED_TURNS = ConcurrentHashMap.newKeySet();\n\n private static final String API_KEY_ENV = \"AGENT_DEMO_API_KEY\";\n private static final String ENDPOINT_ENV = \"AGENT_DEMO_ENDPOINT\";\n private static final String REQUEST_PATH_ENV = \"AGENT_DEMO_REQUEST_PATH\";\n private static final String MODEL_ENV = \"AGENT_DEMO_MODEL\";\n private static final int HISTORY_DISPLAY_LIMIT = 50;\n\n private StreamingAgentConsoleDemo() {\n }\n\n public static void main(String[] args) throws IOException {\n DemoConfiguration configuration = DemoConfiguration.fromEnvironment();\n ChatModel chatModel = createChatModel(configuration);\n AtomicInteger ticketSequence = new AtomicInteger(1000);\n\n Tool currentTime = createCurrentTimeTool();\n AgentFormDefinition meetingRequestForm = createMeetingRequestForm();\n Tool reserveMeetingRoom = createMeetingReservationTool();\n AgentFormDefinition ticketDetailsForm = createTicketDetailsForm();\n Tool prepareTicket = createTicketPreparationTool(ticketDetailsForm);\n Tool createTicket = createTicketTool(ticketSequence);\n Agent agent = createAgent(chatModel, currentTime, meetingRequestForm,\n reserveMeetingRoom, prepareTicket, createTicket);\n\n String conversationId = \"console-\" + UUID.randomUUID();\n ChatMemory memory = new DefaultChatMemory(conversationId);\n\n // 业务系统按 conversationId 提供 ChatMemory;Runner 只保存 Turn 状态,不拥有会话生命周期。\n ChatMemoryProvider memoryProvider =\n id -> conversationId.equals(id) ? memory : null;\n AgentRunner runner = AgentRunner.builder()\n .agentLoader(new InMemoryAgentLoader(agent))\n .chatMemoryProvider(memoryProvider)\n .build();\n runner.addEventListener(StreamingAgentConsoleDemo::printEvent);\n\n printWelcome(configuration, conversationId);\n try (BufferedReader reader = new BufferedReader(\n new InputStreamReader(System.in, StandardCharsets.UTF_8))) {\n runConsole(reader, runner, agent, conversationId, memory);\n }\n }\n\n /**\n * 持续读取控制台输入;每次循环表示一次新的正常对话轮次。\n */\n private static void runConsole(BufferedReader reader, AgentRunner runner, Agent agent,\n String conversationId, ChatMemory memory) throws IOException {\n while (true) {\n System.out.print(\"\\n你 > \");\n String input = reader.readLine();\n if (input == null || isExit(input)) {\n System.out.println(\"对话已结束。\");\n return;\n }\n if (input.trim().isEmpty()) {\n continue;\n }\n if (\"/help\".equalsIgnoreCase(input.trim())) {\n printHelp();\n continue;\n }\n if (\"/history\".equalsIgnoreCase(input.trim())) {\n printHistory(memory);\n continue;\n }\n\n UserMessage userMessage = new UserMessage(input);\n try {\n AgentTurn turn = runner.run(agent.getId(), conversationId, userMessage,\n AgentTurnOptions.builder()\n .streaming(true)\n .metadata(\"requestId\", UUID.randomUUID().toString())\n .metadata(\"userId\", \"console-user\")\n .build());\n turn = handleBlockedTurn(reader, runner, turn);\n if (turn == null) {\n System.out.println(\"对话已结束。当前 Demo 使用内存 Store,未完成 Turn 会随进程退出丢失。\");\n return;\n }\n printTurnResult(turn);\n } catch (RuntimeException error) {\n System.err.println(\"本轮执行异常 [\" + error.getClass().getSimpleName()\n + \"]: \" + error.getMessage());\n }\n }\n }\n\n /**\n * 处理 Turn 的外部等待状态。\n *\n * <p>审批和用户补充都恢复当前 turnId,不会创建新的 AgentTurn。循环结构允许一次任务中连续出现\n * 多个审批点。</p>\n */\n private static AgentTurn handleBlockedTurn(BufferedReader reader, AgentRunner runner,\n AgentTurn turn)\n throws IOException {\n AgentTurn current = turn;\n while (current.getStatus().isBlocked()) {\n AgentTurn active = activeBlockedTurn(runner, current);\n if (active.getStatus() == AgentTurnStatus.WAITING_FOR_APPROVAL) {\n AgentResumeCommand decision = readApprovalDecision(reader, active);\n if (decision == null) {\n return null;\n }\n // 传根 turnId 即可;Runner 会把命令路由到规划中实际等待审批的子 Turn。\n current = runner.resume(current.getId(), decision);\n continue;\n }\n if (active.getStatus() == AgentTurnStatus.WAITING_FOR_USER) {\n AgentSuspension suspension = requireSuspension(active);\n AgentResumeCommand input = readUserInput(reader, active, suspension);\n if (input == null) {\n return null;\n }\n current = runner.resume(current.getId(), input);\n continue;\n }\n\n // 延迟重试等状态通常由 Worker 或外部事件恢复,不应在控制台中盲目推进。\n System.out.println(\"Turn 正在等待外部事件: \" + active.getStatus());\n return current;\n }\n return current;\n }\n\n /**\n * 根据 Suspension 是否携带表单 Schema,选择结构化表单或纯文本恢复协议。\n */\n private static AgentResumeCommand readUserInput(BufferedReader reader, AgentTurn turn,\n AgentSuspension suspension)\n throws IOException {\n Map<String, Object> schema = mapValue(suspension.getMetadata().get(\"schema\"));\n String callId = suspension.getCorrelationId();\n if (!schema.isEmpty() && callId != null && !callId.trim().isEmpty()) {\n Map<String, Object> values = readForm(reader, turn, suspension, schema);\n return values == null ? null\n : AgentResumeCommand.userInput(callId, values)\n .withMetadata(\"submittedBy\", \"console-user\")\n .withMetadata(\"source\", \"console-form\");\n }\n\n System.out.println(\"\\n[需要补充信息] \" + suspension.getMessage());\n while (true) {\n System.out.print(\"补充 > \");\n String value = reader.readLine();\n if (value == null || isExit(value)) return null;\n if (!value.trim().isEmpty()) {\n return AgentResumeCommand.userInput(value)\n .withMetadata(\"source\", \"console\");\n }\n System.out.println(\"补充信息不能为空,请重新输入,或输入 /exit 退出。\");\n }\n }\n\n /**\n * 使用 JSON Schema 的 properties、required 和 enum 渲染简单控制台表单。\n */\n private static Map<String, Object> readForm(BufferedReader reader, AgentTurn turn,\n AgentSuspension suspension,\n Map<String, Object> schema)\n throws IOException {\n Map<String, Object> properties = mapValue(schema.get(\"properties\"));\n if (properties.isEmpty()) {\n throw new IllegalStateException(\"表单 Schema 缺少 properties\");\n }\n List<?> required = schema.get(\"required\") instanceof List\n ? (List<?>) schema.get(\"required\") : Collections.emptyList();\n System.out.println(\"\\n-------------------- 表单输入 --------------------\");\n System.out.println(\"Turn ID : \" + turn.getId());\n System.out.println(\"Form : \" + suspension.getMetadata().get(\"formKey\"));\n System.out.println(\"标题 : \" + textValue(schema.get(\"title\"), suspension.getMessage()));\n System.out.println(\"说明 : 输入 /exit 可退出;带 * 的字段为必填项。\");\n\n Map<String, Object> values = new LinkedHashMap<>();\n for (Map.Entry<String, Object> entry : properties.entrySet()) {\n String fieldName = entry.getKey();\n Map<String, Object> field = mapValue(entry.getValue());\n boolean fieldRequired = required.contains(fieldName);\n while (true) {\n printFieldPrompt(fieldName, field, fieldRequired);\n String input = reader.readLine();\n if (input == null || isExit(input)) return null;\n input = input.trim();\n if (input.isEmpty()) {\n if (!fieldRequired) break;\n System.out.println(\"该字段不能为空,请重新输入。\");\n continue;\n }\n List<?> allowed = field.get(\"enum\") instanceof List\n ? (List<?>) field.get(\"enum\") : Collections.emptyList();\n if (!allowed.isEmpty() && !containsText(allowed, input)) {\n System.out.println(\"请输入允许值之一: \" + allowed);\n continue;\n }\n try {\n values.put(fieldName, parseFieldValue(input, field.get(\"type\")));\n break;\n } catch (IllegalArgumentException error) {\n System.out.println(error.getMessage());\n }\n }\n }\n System.out.println(\"[表单提交] \" + values);\n return values;\n }\n\n private static void printFieldPrompt(String fieldName, Map<String, Object> field,\n boolean required) {\n String title = textValue(field.get(\"title\"), fieldName);\n Object description = field.get(\"description\");\n Object allowed = field.get(\"enum\");\n if (description != null) {\n System.out.println(\" 提示: \" + description);\n }\n System.out.print(title + (required ? \" *\" : \"\")\n + (allowed instanceof List ? \" \" + allowed : \"\") + \" > \");\n }\n\n private static Object parseFieldValue(String input, Object type) {\n String valueType = type == null ? \"string\" : String.valueOf(type);\n try {\n if (\"integer\".equals(valueType)) return Long.valueOf(input);\n if (\"number\".equals(valueType)) return Double.valueOf(input);\n if (\"boolean\".equals(valueType)) {\n if (\"true\".equalsIgnoreCase(input) || \"是\".equals(input)) return true;\n if (\"false\".equalsIgnoreCase(input) || \"否\".equals(input)) return false;\n throw new IllegalArgumentException(\"请输入 true/false 或 是/否。\");\n }\n return input;\n } catch (NumberFormatException error) {\n throw new IllegalArgumentException(\"请输入有效的 \" + valueType + \" 数值。\");\n }\n }\n\n private static boolean containsText(List<?> values, String input) {\n for (Object value : values) {\n if (input.equals(String.valueOf(value))) return true;\n }\n return false;\n }\n\n /**\n * 规划根 Turn 会以 WAITING_FOR_CHILD 表示等待;交互信息则保存在当前活动子 Turn 中。\n */\n private static AgentTurn activeBlockedTurn(AgentRunner runner, AgentTurn root) {\n if (root.getStatus() != AgentTurnStatus.WAITING_FOR_CHILD) {\n return root;\n }\n AgentTaskProgress progress = runner.getTaskProgress(root.getId());\n AgentTask task = progress == null ? null : progress.getCurrentTask();\n if (task == null || task.getChildTurnId() == null) {\n return root;\n }\n return runner.restore(task.getChildTurnId());\n }\n\n /**\n * 展示审批上下文并把人的选择转换为结构化恢复命令。\n */\n private static AgentResumeCommand readApprovalDecision(BufferedReader reader, AgentTurn turn)\n throws IOException {\n AgentSuspension suspension = requireSuspension(turn);\n String callId = suspension.getCorrelationId();\n if (callId == null || callId.trim().isEmpty()) {\n throw new IllegalStateException(\"审批等待状态缺少 toolCall correlationId\");\n }\n ToolCall pending = findPendingCall(turn, suspension.getCorrelationId());\n System.out.println(\"\\n-------------------- 人工审批 --------------------\");\n System.out.println(\"Turn ID : \" + turn.getId());\n System.out.println(\"工具 : \" + (pending == null ? \"未知\" : pending.getName()));\n System.out.println(\"参数 : \" + (pending == null ? \"{}\" : pending.getArguments()));\n System.out.println(\"说明 : \" + suspension.getMessage());\n System.out.println(\"风险信息 : \" + suspension.getMetadata());\n while (true) {\n System.out.print(\"是否批准执行?[y/n] > \");\n String answer = reader.readLine();\n if (answer == null || isExit(answer)) return null;\n if (isApproved(answer)) {\n return AgentResumeCommand.approveTool(callId)\n .withMetadata(\"approverId\", \"console-user\")\n .withMetadata(\"approvalChannel\", \"terminal\");\n }\n if (isRejected(answer)) {\n return AgentResumeCommand.rejectTool(callId, \"控制台用户拒绝执行\")\n .withMetadata(\"approverId\", \"console-user\")\n .withMetadata(\"approvalChannel\", \"terminal\");\n }\n System.out.println(\"请输入 y/yes/同意 或 n/no/拒绝,也可以输入 /exit 退出。\");\n }\n }\n\n /**\n * 当前时间工具没有副作用,因此审批策略会允许 Runner 立即执行。\n */\n private static Tool createCurrentTimeTool() {\n return Tool.builder(\"get_current_time\", \"查询指定时区的真实当前日期和时间\")\n .addParameter(Parameter.builder()\n .name(\"zoneId\")\n .type(\"string\")\n .description(\"IANA 时区,例如 Asia/Shanghai;不确定时使用 Asia/Shanghai\")\n .required(true)\n .build())\n .metadata(\"sideEffect\", false)\n .metadata(\"category\", \"read-only\")\n .function(arguments -> {\n String zoneValue = String.valueOf(arguments.get(\"zoneId\"));\n try {\n ZoneId zone = ZoneId.of(zoneValue);\n return ZonedDateTime.now(zone).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);\n } catch (DateTimeException error) {\n return \"无效时区: \" + zoneValue + \",请使用 IANA ZoneId\";\n }\n })\n .build();\n }\n\n /**\n * 定义工具运行时请求的故障详情表单。Schema 不发送给模型,Runner 会将它保存到暂停快照。\n */\n private static AgentFormDefinition createTicketDetailsForm() {\n Map<String, Object> affectedSystem = new LinkedHashMap<>();\n affectedSystem.put(\"type\", \"string\");\n affectedSystem.put(\"title\", \"受影响系统\");\n affectedSystem.put(\"description\", \"例如统一登录系统、管理后台或移动端\");\n\n Map<String, Object> impactScope = new LinkedHashMap<>();\n impactScope.put(\"type\", \"string\");\n impactScope.put(\"title\", \"影响范围\");\n impactScope.put(\"enum\", Arrays.asList(\n \"ONE_USER\", \"PARTIAL_USERS\", \"ALL_USERS\"));\n\n Map<String, Object> errorMessage = new LinkedHashMap<>();\n errorMessage.put(\"type\", \"string\");\n errorMessage.put(\"title\", \"错误提示\");\n errorMessage.put(\"description\", \"选填,填写页面上看到的错误信息\");\n\n Map<String, Object> properties = new LinkedHashMap<>();\n properties.put(\"affectedSystem\", affectedSystem);\n properties.put(\"impactScope\", impactScope);\n properties.put(\"errorMessage\", errorMessage);\n\n Map<String, Object> schema = new LinkedHashMap<>();\n schema.put(\"type\", \"object\");\n schema.put(\"title\", \"补充登录故障信息\");\n schema.put(\"properties\", properties);\n schema.put(\"required\", Arrays.asList(\"affectedSystem\", \"impactScope\"));\n\n return AgentFormDefinition.builder(\"support_ticket_details\")\n .description(\"准备故障工单时缺少受影响系统或影响范围\")\n .schema(schema)\n .build();\n }\n\n /**\n * 定义由模型通过 request_user_input 主动选择的会议信息表单。\n */\n private static AgentFormDefinition createMeetingRequestForm() {\n Map<String, Object> subject = new LinkedHashMap<>();\n subject.put(\"type\", \"string\");\n subject.put(\"title\", \"会议主题\");\n\n Map<String, Object> preferredTime = new LinkedHashMap<>();\n preferredTime.put(\"type\", \"string\");\n preferredTime.put(\"title\", \"期望时间\");\n preferredTime.put(\"description\", \"例如明天下午 3 点或 2026-08-10 15:00\");\n\n Map<String, Object> participantCount = new LinkedHashMap<>();\n participantCount.put(\"type\", \"integer\");\n participantCount.put(\"title\", \"参会人数\");\n\n Map<String, Object> properties = new LinkedHashMap<>();\n properties.put(\"subject\", subject);\n properties.put(\"preferredTime\", preferredTime);\n properties.put(\"participantCount\", participantCount);\n\n Map<String, Object> schema = new LinkedHashMap<>();\n schema.put(\"type\", \"object\");\n schema.put(\"title\", \"填写会议安排\");\n schema.put(\"properties\", properties);\n schema.put(\"required\", Arrays.asList(\n \"subject\", \"preferredTime\", \"participantCount\"));\n\n return AgentFormDefinition.builder(\"meeting_room_booking\")\n .description(\"预定会议室时收集会议主题、时间和参会人数\")\n .schema(schema)\n .build();\n }\n\n /** 模型读取表单提交结果后可以选择调用的真实业务工具。 */\n private static Tool createMeetingReservationTool() {\n return Tool.builder(\"reserve_meeting_room\", \"根据完整会议资料预定会议室\")\n .addParameter(Parameter.builder().name(\"subject\").type(\"string\")\n .description(\"会议主题\").required(true).build())\n .addParameter(Parameter.builder().name(\"preferredTime\").type(\"string\")\n .description(\"会议时间\").required(true).build())\n .addParameter(Parameter.builder().name(\"participantCount\").type(\"integer\")\n .description(\"参会人数\").required(true).build())\n .function(arguments -> {\n String roomId = \"ROOM-SH-101\";\n System.out.println(\"\\n[工具已执行] 预定会议室 \" + roomId + \",参数=\" + arguments);\n return \"会议室预定成功,roomId=\" + roomId;\n })\n .build();\n }\n\n /**\n * 工单准备工具没有副作用;首次执行请求表单,恢复后返回可供模型创建工单的完整资料。\n */\n private static Tool createTicketPreparationTool(AgentFormDefinition formDefinition) {\n return Tool.builder(\"prepare_support_ticket\", \"整理创建支持工单所需的完整资料,不会写入业务系统\")\n .addParameter(Parameter.builder()\n .name(\"title\")\n .type(\"string\")\n .description(\"简短明确的工单标题\")\n .required(true)\n .build())\n .addParameter(Parameter.builder()\n .name(\"priority\")\n .type(\"string\")\n .description(\"优先级:LOW、MEDIUM、HIGH\")\n .required(true)\n .build())\n .addParameter(Parameter.builder()\n .name(\"description\")\n .type(\"string\")\n .description(\"根据当前对话整理的初步工单详情\")\n .required(true)\n .build())\n .metadata(\"sideEffect\", false)\n .metadata(\"category\", \"preparation\")\n .function(arguments -> {\n AgentToolContext context = AgentToolContext.current();\n if (context == null) {\n throw new IllegalStateException(\n \"prepare_support_ticket requires AgentToolContext\");\n }\n Map<String, Object> submitted = context.getSubmittedFormData();\n if (submitted.isEmpty()) {\n throw new AgentFormRequiredException(formDefinition);\n }\n Map<String, Object> prepared = new LinkedHashMap<>(arguments);\n prepared.putAll(submitted);\n prepared.put(\"idempotencyKey\", context.getIdempotencyKey());\n System.out.println(\"\\n[表单已提交] 工单资料=\" + prepared);\n return prepared;\n })\n .build();\n }\n\n /**\n * 创建工单工具模拟真实写操作,只有审批通过后函数体才会执行。\n */\n private static Tool createTicketTool(AtomicInteger sequence) {\n return Tool.builder(\"create_support_ticket\", \"在支持系统中创建工单,这是会产生业务副作用的写操作\")\n .addParameter(Parameter.builder()\n .name(\"title\")\n .type(\"string\")\n .description(\"简短明确的工单标题\")\n .required(true)\n .build())\n .addParameter(Parameter.builder()\n .name(\"priority\")\n .type(\"string\")\n .description(\"优先级:LOW、MEDIUM、HIGH\")\n .required(true)\n .build())\n .addParameter(Parameter.builder()\n .name(\"description\")\n .type(\"string\")\n .description(\"根据当前对话整理的工单详情\")\n .required(true)\n .build())\n .addParameter(Parameter.builder()\n .name(\"affectedSystem\")\n .type(\"string\")\n .description(\"表单中确认的受影响系统\")\n .required(true)\n .build())\n .addParameter(Parameter.builder()\n .name(\"impactScope\")\n .type(\"string\")\n .description(\"表单中确认的影响范围\")\n .required(true)\n .build())\n .addParameter(Parameter.builder()\n .name(\"errorMessage\")\n .type(\"string\")\n .description(\"用户看到的错误提示;没有时可以省略\")\n .required(false)\n .build())\n .metadata(\"sideEffect\", true)\n .metadata(\"riskLevel\", \"MEDIUM\")\n .metadata(\"approvalType\", \"HUMAN\")\n .function(arguments -> {\n String ticketId = \"TICKET-\" + sequence.incrementAndGet();\n System.out.println(\"\\n[工具已执行] 创建工单 \" + ticketId + \",参数=\" + arguments);\n return \"工单创建成功,ticketId=\" + ticketId;\n })\n .build();\n }\n\n /**\n * 配置 Agent 的模型指令、规划边界、工具、审批规则和执行预算。\n */\n private static Agent createAgent(ChatModel chatModel, Tool currentTime,\n AgentFormDefinition meetingRequestForm,\n Tool reserveMeetingRoom,\n Tool prepareTicket, Tool createTicket) {\n return Agent.builder(\"console-assistant\")\n .id(\"console-assistant\")\n .version(\"1\")\n .description(\"查询真实时间、整理支持信息并创建需要审批的工单\")\n .instructions(\n \"你是一个支持持续对话的中文助手。请结合完整会话历史理解代词和省略信息。\"\n + \"普通问候或知识问题直接回答。用户询问当前日期或时间时,必须调用 get_current_time,\"\n + \"不能依靠训练数据猜测。用户要求预定会议室时,必须调用 \"\n + \"request_user_input 并选择 meeting_room_booking;收到表单提交结果后,必须调用 \"\n + \"reserve_meeting_room 完成预定,不要只回复已收到表单。\"\n + \"用户明确要求创建、提交或登记支持工单时,必须先调用 \"\n + \"prepare_support_ticket 整理标题、优先级和描述;该工具补齐资料并返回后,再调用 \"\n + \"create_support_ticket,不能跳过准备工具,也不能猜测表单字段。\"\n + \"当请求需要两个或更多独立工具调用时,必须先调用 create_task_plan 创建计划,\"\n + \"不能直接调用业务工具;例如比较两个城市当前时间时,每个城市查询一个任务,\"\n + \"比较、归纳和建议由父 Agent 在全部任务完成后汇总。单步请求不要创建计划。\"\n + \"工具返回后必须根据真实结果回答,绝不能虚构工具已经执行。\")\n .chatModel(chatModel)\n .tool(currentTime)\n .tool(AgentUserInputTool.builder().form(meetingRequestForm).build())\n .tool(reserveMeetingRoom)\n .tool(prepareTicket)\n .tool(createTicket)\n .maxAttachedMessages(40)\n .planningPolicy(AgentPlanningPolicy.builder()\n .enabled(true)\n .maxTasks(4)\n .maxDepth(1)\n .childPlanningAllowed(false)\n .taskResultMaxLength(2_000)\n .planningInstructions(\n \"请求需要两个或更多独立工具调用时必须规划。每个任务只执行一个可独立完成的数据\"\n + \"获取或业务动作;不要创建比较、归纳或最终总结任务,这些工作由父 Agent 在全部\"\n + \"子任务完成后完成。\")\n .build())\n .toolApprovalPolicy((turn, call, tool) ->\n Boolean.TRUE.equals(tool.getMetadata().get(\"sideEffect\"))\n ? ToolApprovalDecision.requireApproval()\n .code(\"CONSOLE_WRITE_APPROVAL\")\n .message(\"该工具会写入支持系统,需要人工确认\")\n .reason(\"工具 metadata.sideEffect=true\")\n .metadata(\"riskLevel\", tool.getMetadata().get(\"riskLevel\"))\n .build()\n : ToolApprovalDecision.ALLOW)\n .executionPolicy(AgentExecutionPolicy.builder()\n .maxIterations(8)\n .budget(AgentBudget.builder()\n .maxToolCalls(8)\n .maxTotalTokens(100_000)\n .maxDurationMillis(1200_000)\n .build())\n .build())\n .build();\n }\n\n /**\n * 创建真实的 OpenAI-compatible ChatModel。\n */\n private static ChatModel createChatModel(DemoConfiguration configuration) {\n return OpenAIChatConfig.builder()\n .apiKey(configuration.apiKey)\n .endpoint(configuration.endpoint)\n .requestPath(configuration.requestPath)\n .model(configuration.model)\n .supportTool(true)\n .observabilityEnabled(false)\n .logEnabled(false)\n .supportThinking(true)\n .preserveThinkingEnable(true)\n .logEnabled(false)\n .buildModel();\n }\n\n /**\n * 只打印对学习执行过程有帮助的实时事件,避免控制台被所有 Snapshot 事件淹没。\n */\n private static void printEvent(AgentEvent event) {\n AgentEventType type = event.getType();\n if (type == AgentEventType.MODEL_STARTED) {\n // 一个 Turn 可能包含多次模型调用;工具执行后的最终回答必须重新判断是否已有增量。\n STREAMED_TURNS.remove(event.getTurnId());\n }\n if (type == AgentEventType.MODEL_TEXT_DELTA) {\n STREAMED_TURNS.add(event.getTurnId());\n Object content = event.getData().get(\"content\");\n if (content != null) {\n System.out.print(content);\n System.out.flush();\n }\n return;\n }\n if (type == AgentEventType.MODEL_REASONING_DELTA) {\n return;\n }\n// if (type == AgentEventType.MODEL_STARTED\n// || type == AgentEventType.MODEL_COMPLETED\n// || type == AgentEventType.TOOL_STARTED\n// || type == AgentEventType.TOOL_COMPLETED\n// || type == AgentEventType.TOOL_APPROVAL_REQUESTED\n// || type == AgentEventType.PLAN_CREATED\n// || type == AgentEventType.PLAN_UPDATED\n// || type == AgentEventType.TASK_STARTED\n// || type == AgentEventType.TASK_COMPLETED\n// || type == AgentEventType.TASK_FAILED\n// || type == AgentEventType.TURN_SUSPENDED\n// || type == AgentEventType.TURN_RESUMED) {\n System.out.println(\"[事件] \" + type + \" turn=\" + event.getTurnId() +\" data:\" + event.getData());\n// + planningEventDetails(event));\n// }\n }\n\n private static String planningEventDetails(AgentEvent event) {\n AgentEventType type = event.getType();\n if (type == AgentEventType.PLAN_CREATED) {\n return \" goal=\" + event.getData().get(\"goal\")\n + \" tasks=\" + event.getData().get(\"taskCount\");\n }\n if (type == AgentEventType.TASK_STARTED\n || type == AgentEventType.TASK_COMPLETED\n || type == AgentEventType.TASK_FAILED) {\n if (type == AgentEventType.TASK_STARTED) {\n return \" task=\" + event.getData().get(\"title\")\n + \" taskId=\" + event.getData().get(\"taskId\");\n }\n return \" taskId=\" + event.getData().get(\"taskId\")\n + \" status=\" + event.getData().get(\"taskStatus\");\n }\n return \"\";\n }\n\n private static ToolCall findPendingCall(AgentTurn turn, String callId) {\n if (callId == null) return null;\n for (ToolCall call : turn.getPendingToolCalls()) {\n if (call != null && callId.equals(call.getId())) {\n return call;\n }\n }\n return null;\n }\n\n private static AgentSuspension requireSuspension(AgentTurn turn) {\n AgentSuspension suspension = turn.getSuspension();\n if (suspension == null) {\n throw new IllegalStateException(\"阻塞 Turn 缺少 Suspension: \" + turn.getId());\n }\n return suspension;\n }\n\n private static void printTurnResult(AgentTurn turn) {\n if (turn.getStatus() == AgentTurnStatus.COMPLETED) {\n // 流式增量已经实时输出;只有服务端没有产生任何增量时才回退打印完整结果。\n if (STREAMED_TURNS.remove(turn.getId())) {\n System.out.println(\"\\n[助手输出完成]\");\n } else {\n System.out.println(\"\\n助手 > \" + turn.getFinalOutput());\n }\n } else if (turn.getStatus().isBlocked()) {\n System.out.println(\"\\n助手 > Turn 仍在等待外部事件: \" + turn.getStatus());\n } else {\n System.out.println(\"\\n助手 > 本轮未正常完成,status=\" + turn.getStatus()\n + \", error=\" + (turn.getError() == null ? null : turn.getError().getMessage()));\n }\n System.out.println(\"[Turn] id=\" + turn.getId() + \", iterations=\" + turn.getIterationCount()\n + \", toolCalls=\" + turn.getToolCallCount() + \", tokens=\" + turn.getTotalTokens());\n printTaskPlan(turn);\n }\n\n private static void printTaskPlan(AgentTurn turn) {\n if (turn.getTaskPlan() == null) {\n return;\n }\n System.out.println(\"[计划] goal=\" + turn.getTaskPlan().getGoal()\n + \", status=\" + turn.getTaskPlan().getStatus());\n for (AgentTask task : turn.getTaskPlan().getTasks()) {\n System.out.println(\" [\" + task.getStatus() + \"] \" + task.getTitle()\n + \" -> \" + (task.getAssignedAgentId() == null\n ? turn.getAgent().getId() : task.getAssignedAgentId())\n + (task.getResult() == null ? \"\" : \" | \" + abbreviate(task.getResult(), 100)));\n }\n }\n\n private static void printHistory(ChatMemory memory) {\n List<Message> messages = memory.getMessages(0, HISTORY_DISPLAY_LIMIT);\n System.out.println(\"\\n当前会话最近 \" + messages.size() + \" 条消息\"\n + \"(最多展示 \" + HISTORY_DISPLAY_LIMIT + \" 条):\");\n for (int i = 0; i < messages.size(); i++) {\n Message message = messages.get(i);\n String details = \"\";\n if (message instanceof AgentFormMessage) {\n AgentFormMessage form = (AgentFormMessage) message;\n details = \" formKey=\" + form.getFormKey() + \" status=\" + form.getStatus();\n }\n System.out.println(\" \" + (i + 1) + \". \" + message.getClass().getSimpleName()\n + \" modelVisible=\" + message.isModelVisible()\n + details + \" \" + abbreviate(message.getTextContent(), 120));\n }\n }\n\n private static void printWelcome(DemoConfiguration configuration,\n String conversationId) {\n System.out.println(\"============================================================\");\n System.out.println(\"Agents-Flex 真实模型 Agent 控制台 Demo\");\n System.out.println(\"============================================================\");\n System.out.println(\"model : \" + configuration.model);\n System.out.println(\"endpoint : \" + configuration.endpoint + configuration.requestPath);\n System.out.println(\"conversation : \" + conversationId);\n System.out.println(\"storage : in-memory(进程退出后清空)\");\n printHelp();\n }\n\n private static void printHelp() {\n System.out.println(\"\\n建议依次尝试:\");\n System.out.println(\" 1. 你好,我叫小明。 (普通持续对话)\");\n System.out.println(\" 2. 你还记得我叫什么吗? (读取业务 ChatMemory)\");\n System.out.println(\" 3. 上海现在几点? (自动调用只读工具)\");\n System.out.println(\" 4. 请帮我收集会议安排信息。(模型主动请求表单)\");\n System.out.println(\" 5. 帮我创建一个高优先级登录故障工单。(工具请求表单 + 人工审批)\");\n System.out.println(\" 6. 分别查询上海和东京当前时间,并比较时差给出会议建议。(任务规划)\");\n System.out.println(\"命令:/history 查看最近的时间线消息,/help 查看帮助,/exit 退出。\");\n }\n\n private static boolean isApproved(String value) {\n String answer = value == null ? \"\" : value.trim();\n return \"y\".equalsIgnoreCase(answer)\n || \"yes\".equalsIgnoreCase(answer)\n || \"是\".equals(answer)\n || \"同意\".equals(answer)\n || \"批准\".equals(answer);\n }\n\n private static boolean isRejected(String value) {\n String answer = value == null ? \"\" : value.trim();\n return \"n\".equalsIgnoreCase(answer)\n || \"no\".equalsIgnoreCase(answer)\n || \"否\".equals(answer)\n || \"不同意\".equals(answer)\n || \"拒绝\".equals(answer)\n || \"不批准\".equals(answer);\n }\n\n private static boolean isExit(String value) {\n return value != null && (\"/exit\".equalsIgnoreCase(value.trim())\n || \"exit\".equalsIgnoreCase(value.trim())\n || \"quit\".equalsIgnoreCase(value.trim()));\n }\n\n private static String abbreviate(String value, int maxLength) {\n if (value == null) {\n return \"\";\n }\n String oneLine = value.replace('\\n', ' ').replace('\\r', ' ');\n return oneLine.length() <= maxLength ? oneLine\n : oneLine.substring(0, maxLength) + \"...\";\n }\n\n @SuppressWarnings(\"unchecked\")\n private static Map<String, Object> mapValue(Object value) {\n return value instanceof Map\n ? new LinkedHashMap<>((Map<String, Object>) value)\n : Collections.emptyMap();\n }\n\n private static String textValue(Object value, String defaultValue) {\n return value == null || String.valueOf(value).trim().isEmpty()\n ? defaultValue : String.valueOf(value);\n }\n\n /**\n * 模型连接参数只从环境变量读取,避免 API Key 进入源码或 Git。\n */\n private static final class DemoConfiguration {\n private final String apiKey;\n private final String endpoint;\n private final String requestPath;\n private final String model;\n\n private DemoConfiguration(String apiKey, String endpoint, String requestPath, String model) {\n this.apiKey = apiKey;\n this.endpoint = endpoint;\n this.requestPath = requestPath;\n this.model = model;\n }\n\n private static DemoConfiguration fromEnvironment() {\n String apiKey = environment(API_KEY_ENV, System.getenv(\"OPENAI_API_KEY\"));\n if (apiKey == null || apiKey.trim().isEmpty()) {\n throw new IllegalStateException(\"请设置环境变量 \" + API_KEY_ENV\n + \"(也兼容 OPENAI_API_KEY),不要把 API Key 写入源码\");\n }\n return new DemoConfiguration(\n apiKey,\n environment(ENDPOINT_ENV, \"https://api.deepseek.com\"),\n environment(REQUEST_PATH_ENV, \"/chat/completions\"),\n environment(MODEL_ENV, \"deepseek-v4-pro\"));\n }\n }\n\n private static String environment(String name, String defaultValue) {\n String value = System.getenv(name);\n return value == null || value.trim().isEmpty() ? defaultValue : value.trim();\n }\n}\n"}}}} |