Skip to content

feat(core): Add deepseek support #2123

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 2, 2025
Merged

feat(core): Add deepseek support #2123

merged 2 commits into from
May 2, 2025

Conversation

unknowIfGuestInDream
Copy link
Owner

@unknowIfGuestInDream unknowIfGuestInDream commented May 2, 2025

Close: #2100

Fixes #

Proposed Changes

  1. ...
  2. ...
  3. ...

Readiness Checklist

Author/Contributor

  • If documentation is needed for this change, has that been included in this pull request

Reviewing Maintainer

  • Label as either enhancement, bug, documentation or dependencies
  • Verify design and implementation

Summary by Sourcery

Add DeepSeek AI chat client support to the core module, enabling interaction with the DeepSeek AI API

New Features:

  • Implement DeepSeek chat client with support for synchronous and asynchronous chat interactions
  • Add support for context-aware conversations
  • Implement streaming and non-streaming chat methods

Enhancements:

  • Create comprehensive AI chat client with flexible configuration options
  • Add error handling for API interactions

Build:

  • Update module-info.java to include new Jackson and DeepSeek dependencies
  • Modify pom.xml to exclude AI-related test classes

Summary by CodeRabbit

  • 新功能
    • 引入 DeepSeek 聊天 AI 客户端,支持同步和流式对话、上下文管理以及多种参数配置。
    • 新增一组用于 DeepSeek 聊天 API 的数据结构,包括消息、请求、响应、异常和用量统计等。
  • 测试
    • 新增 DeepSeek 聊天客户端的单元测试,覆盖基本用法、流式输出、上下文管理和高级参数配置。
    • 新增对 DeepSeek API 余额查询和模型列表接口的测试示例。
  • 文档
    • 模块导出新增 DeepSeek 相关包,便于外部访问。
  • 杂项
    • 构建配置调整,排除特定 AI 目录下的测试文件。

Close: #2100
Signed-off-by: unknowIfGuestInDream <liang.tang.cx@gmail.com>
Copy link

Thank you for following naming conventions! 😻

Copy link

vercel bot commented May 2, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
javafx-tool ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 2, 2025 8:53am

Copy link

quine-bot bot commented May 2, 2025

👋 Figuring out if a PR is useful is hard, hopefully this will help.

  • @unknowIfGuestInDream has been on GitHub since 2019 and in that time has had 1221 public PRs merged
  • Don't you recognize them? They've been here before 🎉
  • Here's a good example of their work: javafxTool (Javafx scaffolding, built on JDK17 + JavaFX21 + controlsfx 11.x.x + Maven)
  • From looking at their profile, they seem to be good with Java and HTML.

Their most recently public accepted PR is: #2122

Copy link

sourcery-ai bot commented May 2, 2025

Reviewer's Guide

This pull request integrates the DeepSeek AI chat completion API by introducing a DeepSeekChatClient. The client uses Java's HttpClient for synchronous and asynchronous streaming API calls to https://api.deepseek.com/v1/chat/completions, handling JSON payloads with Jackson. It manages conversation history and supports various API parameters like model, temperature, web search, and deep thought.

File-Level Changes

Change Details Files
Implement DeepSeek API client
  • Created DeepSeekChatClient using java.net.http.HttpClient.
  • Implemented methods for synchronous (chat) and asynchronous streaming (chatStream) requests.
  • Added support for API key authentication and configurable parameters (model, temperature, etc.).
  • Included logic for managing conversation history (add/clear messages).
  • Added DeepSeekApiException for error handling.
core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekApiException.java
Define DeepSeek API data models
  • Created POJOs to represent API request/response structures.
  • Defined classes for messages, choices, streaming deltas, and token usage.
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionRequest.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionResponse.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionStreamResponse.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatMessage.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionChoice.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionStreamChoice.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionDelta.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/Usage.java
Add integration tests for DeepSeek client
  • Created DeepseekTest with tests covering synchronous, streaming, and context-aware chat.
  • Used AES decryption for API key retrieval in tests.
core/src/test/java/com/tlcsdm/core/ai/DeepseekTest.java
Update module and build configuration
  • Exported the new com.tlcsdm.core.ai.deepseek package in module-info.java.
  • Adjusted static dependencies in module-info.java.
  • Excluded AI tests from default execution in pom.xml.
core/src/main/java/module-info.java
core/pom.xml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions github-actions bot added dependencies Pull requests that update a dependency file core test dependency-submission labels May 2, 2025
@mergify mergify bot added the enhancement New feature or request label May 2, 2025
Copy link

coderabbitai bot commented May 2, 2025

"""

Walkthrough

本次变更在 com.tlcsdm.core.ai.deepseek 包下引入了一套新的 DeepSeek 聊天 API 客户端实现,包括核心数据结构(如消息、请求、响应、异常、用量等)、同步及流式对话方法、会话上下文管理等。模块导出配置已更新以开放新包。新增了对应的单元测试类,演示了 DeepSeek 聊天客户端的基本用法、上下文管理、流式响应处理和参数配置。构建配置调整为排除该 AI 相关目录下的测试文件。

Changes

文件/路径分组 变更摘要
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionChoice.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionDelta.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionRequest.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionResponse.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionStreamChoice.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionStreamResponse.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatMessage.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekApiException.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java
core/src/main/java/com/tlcsdm/core/ai/deepseek/Usage.java
新增 DeepSeek 聊天 API 相关核心类,包括数据结构、异常、客户端实现等。
core/src/main/java/module-info.java 新增导出 com.tlcsdm.core.ai.deepseek 包,调整 Jackson 相关 requires 顺序。
core/pom.xml 配置 Surefire 插件排除 AI 相关目录下的测试文件。
core/src/test/java/com/tlcsdm/core/ai/DeepseekTest.java 新增 DeepSeek 聊天客户端的单元测试与用法演示。

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DeepSeekChatClient
    participant DeepSeek API

    User->>DeepSeekChatClient: chat(userMessage, ...)
    DeepSeekChatClient->>DeepSeek API: 发送 ChatCompletionRequest
    DeepSeek API-->>DeepSeekChatClient: 返回 ChatCompletionResponse
    DeepSeekChatClient-->>User: 返回 assistant 回复

    User->>DeepSeekChatClient: chatStream(userMessage, ..., chunkConsumer)
    DeepSeekChatClient->>DeepSeek API: 发送流式请求
    loop 数据流
        DeepSeek API-->>DeepSeekChatClient: 返回数据块
        DeepSeekChatClient-->>User: chunkConsumer 消费内容
    end
    DeepSeekChatClient-->>User: 返回完整 assistant 回复 future
Loading

Assessment against linked issues

Objective Addressed Explanation
Deepseek 调用功能实现(#2100

Suggested labels

size/XL

Poem

在代码的田野里,兔子轻轻跳,
DeepSeek 聊天新功能,闪亮登场妙!
同步流式皆可聊,历史上下文记牢,
测试用例伴随跑,
模块导出也做好,
兔子挥舞小耳朵,欢快把新知拥抱!
🐇✨
"""

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @unknowIfGuestInDream - I've reviewed your changes - here's some feedback:

  • Consider running the DeepSeek tests as integration tests rather than excluding the entire package in pom.xml.
  • Consider using environment variables or a configuration file for the API key in tests instead of embedding an encrypted key.
  • The private streamChatCompletion method appears unused; consider removing it if the public chatStream method provides the necessary functionality.
Here's what I looked at during the review
  • 🟡 General issues: 2 issues found
  • 🟡 Security: 1 issue found
  • 🟡 Testing: 3 issues found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

github-actions bot commented May 2, 2025

Qodana Community for JVM

It seems all right 👌

No new problems were found according to the checks applied

💡 Qodana analysis was run in the pull request mode: only the changed files were checked
☁️ View the detailed Qodana report

Contact Qodana team

Contact us at qodana-support@jetbrains.com

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (20)
core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionDelta.java (1)

33-53: 建议增强数据模型类

这个类作为聊天完成增量内容的数据容器实现得当,但可以考虑以下改进:

  1. 为字段添加初始化值或构造器
  2. 实现toString()、equals()和hashCode()方法
  3. 如果使用Jackson,添加相关序列化/反序列化注解
  4. 为类和字段添加更详细的Javadoc注释,说明其用途和功能
 public class ChatCompletionDelta {

-    private String content;
-    private String role;
+    private String content = null;
+    private String role = null;
+    
+    public ChatCompletionDelta() {
+    }
+    
+    public ChatCompletionDelta(String content, String role) {
+        this.content = content;
+        this.role = role;
+    }

     public String getContent() {
         return content;
     }

     public void setContent(String content) {
         this.content = content;
     }

     public String getRole() {
         return role;
     }

     public void setRole(String role) {
         this.role = role;
     }
+    
+    @Override
+    public String toString() {
+        return "ChatCompletionDelta{" +
+                "content='" + content + '\'' +
+                ", role='" + role + '\'' +
+                '}';
+    }
+    
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ChatCompletionDelta that = (ChatCompletionDelta) o;
+        return Objects.equals(content, that.content) &&
+               Objects.equals(role, that.role);
+    }
+    
+    @Override
+    public int hashCode() {
+        return Objects.hash(content, role);
+    }
}

不要忘记添加 import java.util.Objects;

core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatMessage.java (3)

30-33: 建议补充类级别 Javadoc 描述
当前仅有作者注解,缺少对该类在 DeepSeek 聊天 API 中表示角色和内容的数据结构说明,有助于维护者快速理解用途。


35-36: 可考虑将字段声明为 final 以增强不可变性
如果业务场景不需要在实例化后修改 rolecontent,可将字段设为 private final 并移除对应的 setter,提升线程安全性和可维护性。


38-44: 建议实现 toStringequalshashCode 方法
目前仅提供默认构造器和全参构造器,补充常用方法重写可方便日志记录、单元测试和集合操作。

core/src/main/java/com/tlcsdm/core/ai/deepseek/Usage.java (3)

30-33: 建议补充类级别 Javadoc 描述
缺少对 Usage 类在 DeepSeek API 中用于表示令牌使用统计的说明,建议添加以提高可读性。


34-36: 可考虑将字段设为 final 并通过构造器初始化
若不需要修改,使用不可变字段并移除对应 setter 方法可提升线程安全性。


38-60: 建议实现 toStringequalshashCode 方法
增强调试、日志记录及集合操作时的一致性和可用性。

core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionChoice.java (3)

30-33: 建议补充类和字段的 Javadoc 注释
应为 ChatCompletionChoice 及其 indexmessagefinishReason 字段添加详细说明,明确其在响应中的含义和取值范围。


35-37: 可将字段声明为 final 并通过构造器赋值
如果不需要在对象创建后修改这些字段,使用不可变设计可减少潜在问题。


39-61: 建议重写 toStringequalshashCode 方法
提高对响应选择项的调试、日志和集合处理能力。

core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionStreamChoice.java (3)

30-33: 建议补充类级别和字段的 Javadoc 注释
ChatCompletionStreamChoice 及其 indexdeltafinishReason 字段添加说明,帮助使用者理解流式响应片段的作用。


35-37: 可将字段设为 final 并通过构造器初始化
若不需要后续修改,采用不可变设计可提高代码健壮性。


39-61: 建议实现 toStringequalshashCode 方法
方便对流式响应数据进行日志打印和集合处理。

core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionStreamResponse.java (3)

32-35: 建议补充类级别 Javadoc 描述
ChatCompletionStreamResponse 添加用途说明,并在 Javadoc 中说明与流式响应相关的字段。


37-41: 可考虑将字段声明为 final 并移除 setter
如果该响应对象仅用于反序列化并且不需修改,使用不可变字段有助于线程安全。


43-82: 建议重写 toStringequalshashCode 方法
增强调试和集合处理时的可用性及一致性。

core/src/test/java/com/tlcsdm/core/ai/DeepseekTest.java (2)

45-53: 建议加强密钥安全性处理

当前实现中的 API 密钥虽然通过 AES 加密,但硬编码在测试代码中仍存在潜在风险。考虑通过环境变量或配置文件来提供加密密钥。

-private static final String aesKey = "3f4alpd3525678154a5e3a0183d8087b";
-private static final String encryptStr = "aac70872f21545ff2c56a590188bbe4c20035e0e130568c8dabeb699947e6cdf6df2dd72f573c55a8829ea53a2e22cd4";
+private static final String aesKey = System.getenv("DEEPSEEK_AES_KEY");
+private static final String encryptStr = System.getenv("DEEPSEEK_ENCRYPTED_TOKEN");

104-152: 移除或实现被注释的超时处理代码

代码中存在被注释掉的超时处理逻辑。建议要么移除这些未使用的代码,要么实现它们以提供完整的超时机制。

-//为流式响应添加超时机制
-//        future.orTimeout(30, TimeUnit.SECONDS)
-//            .exceptionally(e -> {
-//                if (e instanceof TimeoutException) {
-//                    System.err.println("响应超时");
-//                }
-//                return null;
-//            });
+// 为流式响应添加超时机制
+future.orTimeout(30, TimeUnit.SECONDS)
+    .exceptionally(e -> {
+        if (e instanceof TimeoutException) {
+            System.err.println("响应超时");
+        }
+        return null;
+    });
core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java (2)

77-115: 加强错误处理和异常恢复机制

当 API 调用失败时,当前实现会从会话历史中移除最后一条用户消息。这种处理方式合理,但可以考虑添加日志记录,以便于调试和监控。

 } catch (DeepSeekApiException e) {
     // 移除最后一条用户消息,因为对话失败
     if (!conversationHistory.isEmpty() &&
         "user".equals(conversationHistory.get(conversationHistory.size() - 1).getRole())) {
         conversationHistory.remove(conversationHistory.size() - 1);
+        // 添加日志记录
+        System.err.println("对话失败,已移除最后一条用户消息: " + userMessage);
     }
     throw e;
 }

200-252: 考虑添加对话历史管理机制

当前实现允许对话历史无限增长,可能导致内存问题或超出 API 的 token 限制。建议添加对话历史的大小限制或清理机制。

 public void addAssistantMessage(String content) {
     conversationHistory.add(new ChatMessage("assistant", content));
+    // 确保对话历史不会过长
+    if (conversationHistory.size() > 20) { // 设置一个合理的限制
+        // 保留最新的对话,移除较早的
+        conversationHistory.removeIf(message -> 
+            !"system".equals(message.getRole()) && conversationHistory.indexOf(message) < conversationHistory.size() - 20);
+    }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6ecee9 and ea3c8de.

📒 Files selected for processing (13)
  • core/pom.xml (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionChoice.java (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionDelta.java (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionRequest.java (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionResponse.java (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionStreamChoice.java (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionStreamResponse.java (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatMessage.java (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekApiException.java (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java (1 hunks)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/Usage.java (1 hunks)
  • core/src/main/java/module-info.java (2 hunks)
  • core/src/test/java/com/tlcsdm/core/ai/DeepseekTest.java (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java (1)
core/src/main/java/com/tlcsdm/core/util/JacksonUtil.java (1)
  • JacksonUtil (60-381)
⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: automerge
  • GitHub Check: StepSecurity Harden-Runner
  • GitHub Check: Summary
  • GitHub Check: qodana
  • GitHub Check: build (21, windows-latest, false)
  • GitHub Check: build (21, macos-latest, false)
  • GitHub Check: build (21, ubuntu-latest, false)
  • GitHub Check: build (17, windows-latest, false)
  • GitHub Check: build (17, ubuntu-latest, false)
  • GitHub Check: build (17, macos-latest, false)
🔇 Additional comments (9)
core/pom.xml (1)

474-474: Maven Surefire配置更新完成

排除了AI相关的测试文件,与新增的DeepSeek AI包的引入保持一致。这种配置确保了AI相关的测试不会在常规构建过程中自动运行,避免了可能需要额外配置或外部服务的测试失败问题。

core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekApiException.java (1)

28-41: 异常类实现正确

异常类的实现遵循了Java标准的异常处理模式,提供了两个构造方法用于不同场景的异常处理。代码结构清晰,符合最佳实践。

core/src/main/java/module-info.java (2)

52-53: Jackson模块依赖顺序优化

将Jackson相关的依赖项进行了重新排序和分组,提高了代码的可读性和维护性。


134-135: 新增AI包和水印包的导出

正确导出了新的包,确保了DeepSeek AI功能可以被其他模块访问和使用。

core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatMessage.java (1)

46-61: Getter/Setter 实现清晰且符合 Java Bean 规范
当前实现满足 Jackson 等序列化框架要求,无需修改。

core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionResponse.java (1)

35-91: POJO 类结构合理且完整

该类作为 DeepSeek API 响应的数据模型,设计符合标准的 POJO 模式,提供了所有必要字段的访问器方法。

core/src/main/java/com/tlcsdm/core/ai/deepseek/ChatCompletionRequest.java (1)

35-113: 请求模型设计合理

该请求类包含了 DeepSeek API 所需的全部参数字段,提供了默认构造函数和全参数构造函数,结构清晰。

core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java (2)

53-74: 客户端构造函数配置合理

客户端初始化了 HTTP 客户端、对象映射器和对话历史,配置看起来合理且全面。


138-203: ⚠️ Potential issue

流式处理方法中的资源释放问题

chatStream 方法中的 response.body().close() 调用可能存在问题,因为 HttpResponse<Stream<String>> 的 body 不一定有 close 方法。建议检查并修正资源管理方式。

-} finally {
-    response.body().close();
+} finally {
+    // HttpResponse<Stream<String>> 的 body 是一个 Stream,不需要显式关闭
+    // 如果确实需要关闭基础资源,可以考虑其他方式
 }

Likely an incorrect or invalid review comment.

Close: #2100
Signed-off-by: unknowIfGuestInDream <liang.tang.cx@gmail.com>
Copy link

sonarqubecloud bot commented May 2, 2025

Quality Gate Passed Quality Gate passed

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
5.4% Duplication on New Code

See analysis details on SonarQube Cloud

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (4)
core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java (2)

151-175: 流式处理异常可能多次 completeExceptionally

与之前评论一致,forEach 内部发生异常时应立即中断循环,避免对同一 CompletableFuture 多次 completeExceptionally,也能省去无意义的行解析。


56-58: ⚠️ Potential issue

conversationHistory 线程安全问题仍未解决

conversationHistory 由同步 chat 与异步 chatStream 方法共同读写,目前使用 ArrayList 无任何并发控制,容易出现数据竞争或 ConcurrentModificationException。请考虑以下方案:

- private final List<ChatMessage> conversationHistory;
+ private final List<ChatMessage> conversationHistory = Collections.synchronizedList(new ArrayList<>());

或在 Javadoc 明确声明客户端非线程安全、需由调用方保证串行访问。

core/src/test/java/com/tlcsdm/core/ai/DeepseekTest.java (2)

63-89: 缺少断言,无法自动验证行为

该测试仅打印结果,无法在 CI 中捕获功能回归。请添加必要的 assertNotNull / assertTrue / assertEquals 等断言,或拆分为多个单元测试并使用 mock。


90-110: 测试依赖真实外网 API,稳定性差且可能耗费额度

use() 方法同样无断言且直接调用线上接口。建议:

  1. 将其标记为集成测试(如使用 JUnit @Tag("integration")),并在 CI 中按需跳过。
  2. 或使用 Mockito/ WireMock 模拟 DeepSeek API。
🧹 Nitpick comments (2)
core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java (1)

123-125: 空字符串也会被当作用户消息写入历史

在调用方想利用“空消息=仅使用上下文”场景下,addUserMessage("") 会把空内容写入历史,产生噪音。可在此处跳过空/null 内容:

- addUserMessage(userMessage);
+ if (userMessage != null && !userMessage.isBlank()) {
+     addUserMessage(userMessage);
+ }
core/src/test/java/com/tlcsdm/core/ai/DeepseekTest.java (1)

199-225: 共用的 makeApiRequest 方法未设置超时与重试策略

直接阻塞调用线上接口,若网络抖动将导致测试卡死。请至少:

  • send 调用添加 Duration 超时:httpClient.send(request, BodyHandlers.ofString(Duration.ofSeconds(10)))
  • 或引入简单重试机制。
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea3c8de and ea4b90f.

📒 Files selected for processing (2)
  • core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java (1 hunks)
  • core/src/test/java/com/tlcsdm/core/ai/DeepseekTest.java (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
core/src/main/java/com/tlcsdm/core/ai/deepseek/DeepSeekChatClient.java (1)
core/src/main/java/com/tlcsdm/core/util/JacksonUtil.java (1)
  • JacksonUtil (60-381)
🪛 Gitleaks (8.21.2)
core/src/test/java/com/tlcsdm/core/ai/DeepseekTest.java

53-53: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: qodana
  • GitHub Check: build (21, macos-latest, false)
  • GitHub Check: build (21, ubuntu-latest, false)
  • GitHub Check: build (21, windows-latest, false)
  • GitHub Check: build (17, windows-latest, false)
  • GitHub Check: build (17, macos-latest, false)
  • GitHub Check: build (17, ubuntu-latest, false)
  • GitHub Check: StepSecurity Harden-Runner
  • GitHub Check: Summary

@unknowIfGuestInDream unknowIfGuestInDream merged commit 34d8d0c into master May 2, 2025
32 checks passed
@unknowIfGuestInDream unknowIfGuestInDream deleted the ds branch May 2, 2025 09:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core dependencies Pull requests that update a dependency file dependency-submission enhancement New feature or request size/XXL test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[KnowHow] Deepseek调用
1 participant