Skip to content

* feat: add DeepSeek as LLM provider#126

Open
madlas wants to merge 3 commits intomemovai:mainfrom
madlas:main
Open

* feat: add DeepSeek as LLM provider#126
madlas wants to merge 3 commits intomemovai:mainfrom
madlas:main

Conversation

@madlas
Copy link
Copy Markdown

@madlas madlas commented Mar 7, 2026

  • Add MIMI_DEEPSEEK_API_URL and deepseek provider support in llm_proxy.c
  • Extend provider_is_openai() to include deepseek (OpenAI-compatible format)
  • llm_api_url/host return api.deepseek.com when provider is deepseek
  • Update set_model_provider CLI help: anthropic|openai|deepseek
  • Update llm_proxy.h doc comment ================================================================
  • modify main/mimi_secrets.h:
    #define MIMI_SECRET_API_KEY "your api key"
    #define MIMI_SECRET_MODEL "deepseek-chat"
    #define MIMI_SECRET_MODEL_PROVIDER "deepseek"

Summary by CodeRabbit

  • New Features

    • Added DeepSeek as a selectable LLM provider in CLI and config; help text updated to list it.
    • Default provider now follows the configured secret/provider setting.
  • Bug Fixes

    • Provider selection and API key/model saves validate input and now report clear errors on failure.
    • Changes are only persisted on successful validation to prevent invalid configuration.

- Add MIMI_DEEPSEEK_API_URL and deepseek provider support in llm_proxy.c
- Extend provider_is_openai() to include deepseek (OpenAI-compatible format)
- llm_api_url/host return api.deepseek.com when provider is deepseek
- Update set_model_provider CLI help: anthropic|openai|deepseek
- Update llm_proxy.h doc comment
================================================================
modify main/mimi_secrets.h:
#define MIMI_SECRET_API_KEY         "your api key"
#define MIMI_SECRET_MODEL           "deepseek-chat"
#define MIMI_SECRET_MODEL_PROVIDER  "deepseek"
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 7, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9a7dda24-3098-45c0-bafa-54350043a21b

📥 Commits

Reviewing files that changed from the base of the PR and between d6309f9 and 0a6326c.

📒 Files selected for processing (2)
  • main/cli/serial_cli.c
  • main/llm/llm_proxy.c

📝 Walkthrough

Walkthrough

Adds "deepseek" as a supported LLM provider: CLI help and config updated, provider validation and NVS persistence hardened, routing/auth logic extended to treat Deepseek as OpenAI-compatible for API paths, and request-body token field names adjusted per provider.

Changes

Cohort / File(s) Summary
CLI
main/cli/serial_cli.c
Added error handling for saving API key, model, and provider; updated CLI help to include deepseek; return non-zero on NVS save failures.
Config
main/mimi_config.h
Default provider changed to MIMI_SECRET_MODEL_PROVIDER; added MIMI_DEEPSEEK_API_URL macro.
LLM Proxy Core
main/llm/llm_proxy.c
Treat deepseek as OpenAI-compatible in provider_is_openai(); split llm_api_url/host/path for deepseek/openai/others; use provider-specific token field names (max_tokens vs max_completion_tokens); enforce null checks and strict provider validation; robust NVS error checks and propagate errors.
LLM Proxy Docs
main/llm/llm_proxy.h
Documentation updated to list deepseek as an example provider (no API signature changes).

Sequence Diagram(s)

sequenceDiagram
participant CLI
participant LLM_Proxy
participant NVS
participant ExternalAPI

CLI->>LLM_Proxy: set_model_provider("deepseek")
LLM_Proxy->>LLM_Proxy: validate provider (anthropic|openai|deepseek)
alt valid
    LLM_Proxy->>NVS: nvs_open / nvs_set_str / nvs_commit
    NVS-->>LLM_Proxy: ESP_OK
    LLM_Proxy-->>CLI: "Model provider set."
else invalid
    LLM_Proxy-->>CLI: "Error: invalid provider..."
end

CLI->>LLM_Proxy: send chat request
LLM_Proxy->>LLM_Proxy: provider_is_openai() -> true for deepseek
LLM_Proxy->>ExternalAPI: build request (Bearer auth, deepseek URL, max_tokens)
ExternalAPI-->>LLM_Proxy: response
LLM_Proxy-->>CLI: relay response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nibbled code by moonlit screen,
Deepseek hopped into the scene.
Tokens tucked and headers neat,
Providers meet where pathways greet.
🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding DeepSeek as a new LLM provider option alongside existing providers.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
main/cli/serial_cli.c (1)

864-868: ⚠️ Potential issue | 🟡 Minor

CLI help still shows the old provider default.

This command now advertises deepseek as a valid option, but the help text still prints (default: anthropic) via MIMI_LLM_PROVIDER_DEFAULT. With the new build-time secret default set to deepseek, that becomes misleading for users about the actual startup provider.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main/cli/serial_cli.c` around lines 864 - 868, The CLI help shows the wrong
startup provider because the default macro is out of date; update the definition
of MIMI_LLM_PROVIDER_DEFAULT (or make the help use the runtime default accessor)
so it reflects the new build-time default "deepseek" and then rebuild;
specifically, locate the MIMI_LLM_PROVIDER_DEFAULT macro definition and change
its value to the new default (or change the provider_cmd help construction to
use the runtime provider getter instead of a hardcoded string) so
provider_args/provider_cmd displays the correct default.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@main/llm/llm_proxy.c`:
- Around line 193-202: The helpers llm_api_url() and llm_api_host() currently
default any unrecognized s_provider to Anthropic, which hides misconfigurations;
change them to detect unknown providers and return NULL (or an error indicator)
instead of returning MIMI_LLM_API_URL/"api.anthropic.com", and update callers to
handle that error path; additionally, add validation in llm_set_provider() to
accept only known values ("deepseek","openai","anthropic") and reject/return an
error on typos so s_provider cannot be set to arbitrary strings that later
resolve silently to Anthropic.
- Around line 185-188: The request builder currently treats DeepSeek as OpenAI
(via provider_is_openai and s_provider) and emits max_completion_tokens; update
the request-body construction so DeepSeek is branched separately: detect
s_provider == "deepseek" (or use provider_is_openai plus a deepseek check) and
when building the JSON for DeepSeek use the max_tokens field instead of
max_completion_tokens, leaving the OpenAI path unchanged; ensure the DeepSeek
branch sends the same value under "max_tokens" and keep existing behavior for
"openai".

---

Outside diff comments:
In `@main/cli/serial_cli.c`:
- Around line 864-868: The CLI help shows the wrong startup provider because the
default macro is out of date; update the definition of MIMI_LLM_PROVIDER_DEFAULT
(or make the help use the runtime default accessor) so it reflects the new
build-time default "deepseek" and then rebuild; specifically, locate the
MIMI_LLM_PROVIDER_DEFAULT macro definition and change its value to the new
default (or change the provider_cmd help construction to use the runtime
provider getter instead of a hardcoded string) so provider_args/provider_cmd
displays the correct default.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f33a12d5-654a-4adf-a00a-bada9fb2f047

📥 Commits

Reviewing files that changed from the base of the PR and between b6e11d8 and 4c3318c.

📒 Files selected for processing (4)
  • main/cli/serial_cli.c
  • main/llm/llm_proxy.c
  • main/llm/llm_proxy.h
  • main/mimi_config.h

@IRONICBo IRONICBo self-requested a review March 7, 2026 14:59
@IRONICBo IRONICBo self-assigned this Mar 7, 2026
@IRONICBo
Copy link
Copy Markdown
Member

IRONICBo commented Mar 7, 2026

@madlas Thanks for your contribution! Did you test it on your board?

@madlas
Copy link
Copy Markdown
Author

madlas commented Mar 7, 2026

@IRONICBo Thank you for your attention! Yes, I have tested a few simple dialogue use cases. my board is esp32-s3

- Use max_tokens for DeepSeek instead of max_completion_tokens
- Add provider validation in llm_set_provider (anthropic|openai|deepseek)
- Validate NVS provider on init, keep default if invalid
- CLI help default provider aligns with mimi_secrets
- Handle set_model_provider error return in CLI
Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
main/llm/llm_proxy.c (1)

811-829: Provider validation is correct; consider aligning error handling style.

The validation logic correctly rejects invalid providers before NVS persistence. The error handling for NVS operations is now proper (checking return values instead of aborting).

Note that llm_set_api_key() and llm_set_model() (lines 785-809) still use ESP_ERROR_CHECK which aborts on NVS failures, while llm_set_provider() now returns errors gracefully. This inconsistency is minor but could be unified in a follow-up if desired.

,

♻️ Optional: Align error handling across all NVS setters

If graceful error returns are preferred over aborting, consider updating llm_set_api_key() and llm_set_model() similarly:

 esp_err_t llm_set_api_key(const char *api_key)
 {
     nvs_handle_t nvs;
-    ESP_ERROR_CHECK(nvs_open(MIMI_NVS_LLM, NVS_READWRITE, &nvs));
-    ESP_ERROR_CHECK(nvs_set_str(nvs, MIMI_NVS_KEY_API_KEY, api_key));
-    ESP_ERROR_CHECK(nvs_commit(nvs));
+    esp_err_t err = nvs_open(MIMI_NVS_LLM, NVS_READWRITE, &nvs);
+    if (err != ESP_OK) return err;
+    err = nvs_set_str(nvs, MIMI_NVS_KEY_API_KEY, api_key);
+    if (err == ESP_OK) err = nvs_commit(nvs);
     nvs_close(nvs);
+    if (err != ESP_OK) return err;
 
     safe_copy(s_api_key, sizeof(s_api_key), api_key);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main/llm/llm_proxy.c` around lines 811 - 829, The review notes inconsistent
NVS error handling: llm_set_provider returns esp_err_t errors instead of
aborting, while llm_set_api_key and llm_set_model still call ESP_ERROR_CHECK
which aborts on failures; to align behavior, refactor llm_set_api_key() and
llm_set_model() to open NVS with nvs_open, call nvs_set_str and nvs_commit,
close the handle, and return esp_err_t error codes instead of using
ESP_ERROR_CHECK so their error paths mirror llm_set_provider (refer to functions
llm_set_api_key, llm_set_model, and llm_set_provider for the pattern).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@main/llm/llm_proxy.c`:
- Around line 811-829: The review notes inconsistent NVS error handling:
llm_set_provider returns esp_err_t errors instead of aborting, while
llm_set_api_key and llm_set_model still call ESP_ERROR_CHECK which aborts on
failures; to align behavior, refactor llm_set_api_key() and llm_set_model() to
open NVS with nvs_open, call nvs_set_str and nvs_commit, close the handle, and
return esp_err_t error codes instead of using ESP_ERROR_CHECK so their error
paths mirror llm_set_provider (refer to functions llm_set_api_key,
llm_set_model, and llm_set_provider for the pattern).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d7717973-b30e-4ef5-90bd-f3b027ddaa71

📥 Commits

Reviewing files that changed from the base of the PR and between 4c3318c and d6309f9.

📒 Files selected for processing (3)
  • main/cli/serial_cli.c
  • main/llm/llm_proxy.c
  • main/mimi_config.h
🚧 Files skipped from review as they are similar to previous changes (2)
  • main/cli/serial_cli.c
  • main/mimi_config.h

@madlas
Copy link
Copy Markdown
Author

madlas commented Mar 7, 2026

Addressed the code review feedback: max_tokens for DeepSeek, provider validation, CLI help fix.

mrmabo added a commit to mrmabo/mimiclaw that referenced this pull request Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants