Files
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
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.
2026-08-07 12:53:47 +08:00

1 line
293 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"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"}}}}