Skip to content

fix(ai): detect DeepSeek base URLs case-insensitively - #7933

Merged
badlogic merged 1 commit into
earendil-works:mainfrom
yearth:fix/deepseek-baseurl-case
Aug 11, 2026
Merged

badlogic merged 1 commit into
earendil-works:mainfrom
yearth:fix/deepseek-baseurl-case

Conversation

@yearth

@yearth yearth commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #7886

Custom OpenAI-compatible models can use a DeepSeek base URL with different casing. Hostnames are case-insensitive, but Pi's compatibility detection compared the URL case-sensitively. That made maxTokens use max_completion_tokens instead of DeepSeek's max_tokens.

This lowercases the base URL before the existing DeepSeek substring check in both runtime detection and model generation. It intentionally leaves the existing substring-matching behavior unchanged.

Added a regression case for https://API.DeepSeek.COM.

Testing

  • npm run check
  • npm run build:offline
  • ./test.sh

@badlogic
badlogic merged commit b647d18 into earendil-works:main Aug 11, 2026
1 check passed
@badlogic

Copy link
Copy Markdown
Collaborator

cheers

teknium1 added a commit to NousResearch/hermes-agent that referenced this pull request Aug 15, 2026
… checks

Port of the bug class from earendil-works/pi#7933 (DeepSeek base-URL
detection matched by raw substring, missing case variants and matching
lookalike URLs). Hermes had the same class at five sites:

- cli_agent_setup_mixin.py: keyless-custom-endpoint detection treated any
  URL containing the OpenRouter host substring (path segment, lookalike
  domain) as OpenRouter, and missed case variants of the real host.
- models.py validate_requested_model: same substring check for routing an
  openrouter provider with a custom base_url to the custom catalog.
- runtime_provider.py: local-endpoint autodetect matched the string
  localhost anywhere in the URL, including remote hostnames containing it.
- gateway/run.py: /status endpoint display, same local-host substring.
- agent_runtime_helpers.py: Nous Portal cache-layout detection matched
  the nousresearch substring anywhere in the URL.

All sites now use the existing base_url_host_matches / base_url_hostname
helpers (exact host or subdomain, case-insensitive). Regression tests
proven to fail against the old predicates.
dadezzz pushed a commit to dadezzz/forgejo-agent that referenced this pull request Aug 19, 2026
….2 (#213)

This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@earendil-works/pi-coding-agent](https://github.com/earendil-works/pi) ([source](https://github.com/earendil-works/pi/tree/HEAD/packages/coding-agent)) | [`0.84.1` → `0.84.2`](https://renovatebot.com/diffs/npm/@earendil-works%2fpi-coding-agent/0.84.1/0.84.2) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@earendil-works%2fpi-coding-agent/0.84.2?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@earendil-works%2fpi-coding-agent/0.84.1/0.84.2?slim=true) |

---

### Release Notes

<details>
<summary>earendil-works/pi (@&#8203;earendil-works/pi-coding-agent)</summary>

### [`v0.84.2`](https://github.com/earendil-works/pi/blob/HEAD/packages/coding-agent/CHANGELOG.md#0842---2026-08-14)

[Compare Source](earendil-works/pi@v0.84.1...v0.84.2)

##### New Features

- **Fullscreen transcript search** — Search and navigate matches in fullscreen mode. See [TUI Fullscreen Viewport](docs/keybindings.md#tui-fullscreen-viewport).
- **Configurable default tools** — Choose startup built-in tools globally or per project. See [Tools](docs/settings.md#tools).
- **Configurable fullscreen exit output** — Print the transcript or only a resume hint on exit. See [Interactive Mode](docs/usage.md#interactive-mode).

##### Added

- Added fullscreen transcript search with `Ctrl+Shift+F`, incremental match highlighting, configurable search match theme colors, and next/previous navigation with `Enter`/`Ctrl+G` and `Shift+Enter`/`Ctrl+Shift+G`.
- Added experimental strict JSON-schema constrained sampling for the default `read`, `bash`, `edit`, and `write` tools under `PI_EXPERIMENTAL=1`.
- Added a fullscreen exit output setting to choose between printing the final transcript and only a session resume hint.
- Added the `defaultTools` setting for configuring the initial built-in tool selection globally or per project.
- Added `--use-theme <name[/name]>` to choose an initial per-run interactive theme without changing saved settings ([#&#8203;7722](earendil-works/pi#7722) by [@&#8203;rwachtler](https://github.com/rwachtler)).
- Added `expandPromptTemplates` to extension `pi.sendUserMessage()` options for explicitly dispatching commands and expanding skills and prompt templates. See [`pi.sendUserMessage()`](docs/extensions.md#pisendusermessagecontent-options) ([#&#8203;7857](earendil-works/pi#7857) by [@&#8203;mrexodia](https://github.com/mrexodia)).
- Added inherited `createGatewayBindingFetch()` for routing Cloudflare AI Gateway requests through a Workers AI binding without an API token ([#&#8203;7901](earendil-works/pi#7901) by [@&#8203;Maximo-Guk](https://github.com/Maximo-Guk)).
- Added inherited `AssistantMessage.endTurn` to preserve OpenAI Codex's terminal `end_turn` signal for diagnostics ([#&#8203;7766](earendil-works/pi#7766)).
- Added inherited unbound single-line transcript scrolling actions for fullscreen mode. See [TUI Fullscreen Viewport](docs/keybindings.md#tui-fullscreen-viewport) ([#&#8203;7903](earendil-works/pi#7903) by [@&#8203;midastruth](https://github.com/midastruth)).

##### Changed

- Changed inherited Kimi Coding requests to use pi's runtime `User-Agent` header.
- Replaced the inherited Mistral SDK transport with a native Chat Completions HTTP stream, eliminating its generated client and schema runtime overhead.
- Documented the generic `AI_AGENT=pi` process marker and how it differs from `PI_CODING_AGENT=true` ([#&#8203;7747](earendil-works/pi#7747)).
- Changed inherited OpenAI Responses deferred tool loading to prefer message-anchored `additional_tools` where supported while retaining tool-search and top-level fallbacks ([#&#8203;7709](earendil-works/pi#7709)).
- Reduced inherited fullscreen rendering allocation churn by painting full-width layout rows directly instead of recompositing them on every frame.

##### Fixed

- Fixed root Markdown files such as `README.md` and `AGENTS.md` in skill directories being reported as broken skills unless they declare valid skill frontmatter ([#&#8203;7805](earendil-works/pi#7805)).
- Fixed single-object `edit` tool inputs failing validation by accepting them as one-edit arrays in both coding-agent and harness edit tools ([#&#8203;7835](earendil-works/pi#7835)).
- Fixed managed-tool downloads delaying TUI startup and hiding diagnostics in fullscreen mode by mounting the TUI first and showing download progress and warnings inside it.
- Fixed opening a model selector immediately after startup cancelling and restarting the in-progress model catalog refresh.
- Fixed inherited GitHub Copilot login triggering API rate limits while enabling model policies by limiting concurrent policy updates ([#&#8203;6187](earendil-works/pi#6187)).
- Fixed fullscreen transcript search snapping back to the current match during manual scrolling and fragmented mouse input leaking into the search query.
- Fixed inherited required LaTeX arguments starting on a new line being parsed as empty ([#&#8203;7760](earendil-works/pi#7760)).
- Updated the transitive `nanoid` development dependency to address a denial-of-service vulnerability.
- Fixed fallback rendering for extension tool results to collapse long output and honor tool expansion ([#&#8203;7979](earendil-works/pi#7979)).
- Fixed JSON and RPC `message_update` events dropping cumulative usage during streaming. See [JSON Event Mode](docs/json.md) and [RPC `message_update`](docs/rpc.md#message_update-streaming) ([#&#8203;7982](earendil-works/pi#7982) by [@&#8203;christianklotz](https://github.com/christianklotz)).
- Fixed `pi.sendMessage(..., { triggerTurn: false })` steering an active run instead of only recording the custom message ([#&#8203;8022](earendil-works/pi#8022) by [@&#8203;cristinaponcela](https://github.com/cristinaponcela)).
- Fixed the `defaultTools` setting dropping extension and SDK custom tools when selecting built-in defaults.
- Fixed the subagent example rejecting YAML array syntax for the `tools` frontmatter field ([#&#8203;7598](earendil-works/pi#7598) by [@&#8203;alexsavio](https://github.com/alexsavio)).
- Fixed the subagent example dropping parent session model, thinking, and tool configuration ([#&#8203;7897](earendil-works/pi#7897) by [@&#8203;virtuald](https://github.com/virtuald)).
- Fixed custom system prompts concatenating the current working directory with later appended prompt content ([#&#8203;7887](earendil-works/pi#7887) by [@&#8203;distributedlock](https://github.com/distributedlock)).
- Fixed inherited OpenAI Responses function and custom tool calls losing namespaces during streaming, proxying, and replay ([#&#8203;7709](earendil-works/pi#7709)).
- Fixed inherited upstream request buffer failures not triggering automatic assistant retries.
- Fixed inherited built-in and custom DeepSeek API models sending output limits through an unsupported field.
- Fixed inherited Amazon Bedrock replay rejecting tool arguments that contain empty object keys while preserving all valid nested values ([#&#8203;7882](earendil-works/pi#7882) by [@&#8203;muyiyr](https://github.com/muyiyr)).
- Fixed inherited DeepSeek compatibility detection for base URLs whose hostname contains uppercase letters ([#&#8203;7933](earendil-works/pi#7933) by [@&#8203;yearth](https://github.com/yearth)).
- Fixed inherited Google Generative AI and Vertex AI responses with tool calls incorrectly treating output-limit or provider-error stops as normal tool use ([#&#8203;8059](earendil-works/pi#8059)).
- Fixed inherited fullscreen mouse drag selection and OSC 8 link activation in terminals that report generic SGR mouse release button codes ([#&#8203;7963](earendil-works/pi#7963)).
- Fixed inherited focused fullscreen overlays not receiving mouse wheel or viewport scroll keys such as PageUp and PageDown ([#&#8203;7894](earendil-works/pi#7894)).
- Fixed inherited LaTeX control spaces split across line endings causing complete expressions to fall back to raw source.
- Fixed split `Alt+Enter` input over SSH being misread as Escape, added `PI_TUI_ESC_TIMEOUT` for high-latency terminals, and limited that timeout to lone Escape input ([#&#8203;7899](earendil-works/pi#7899) by [@&#8203;powerfooI](https://github.com/powerfooI)).
- Fixed inherited idle fullscreen sessions repainting and clearing text selection when the terminal loses focus ([#&#8203;7892](earendil-works/pi#7892) by [@&#8203;terrorobe](https://github.com/terrorobe)).
- Fixed fullscreen selection copy to use the host clipboard and report failure instead of claiming success when OSC 52 is unsupported ([#&#8203;8110](earendil-works/pi#8110) by [@&#8203;Panoplos](https://github.com/Panoplos)).

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4zMS4wIiwidXBkYXRlZEluVmVyIjoiNDQuMzEuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
TrungKiencding pushed a commit to TrungKiencding/AgentX-Workmate that referenced this pull request Aug 25, 2026
… checks

Port of the bug class from earendil-works/pi#7933 (DeepSeek base-URL
detection matched by raw substring, missing case variants and matching
lookalike URLs). Hermes had the same class at five sites:

- cli_agent_setup_mixin.py: keyless-custom-endpoint detection treated any
  URL containing the OpenRouter host substring (path segment, lookalike
  domain) as OpenRouter, and missed case variants of the real host.
- models.py validate_requested_model: same substring check for routing an
  openrouter provider with a custom base_url to the custom catalog.
- runtime_provider.py: local-endpoint autodetect matched the string
  localhost anywhere in the URL, including remote hostnames containing it.
- gateway/run.py: /status endpoint display, same local-host substring.
- agent_runtime_helpers.py: Nous Portal cache-layout detection matched
  the nousresearch substring anywhere in the URL.

All sites now use the existing base_url_host_matches / base_url_hostname
helpers (exact host or subdomain, case-insensitive). Regression tests
proven to fail against the old predicates.

(cherry picked from commit bc5805c)
bobaba76 pushed a commit to bobaba76/hermes-agent that referenced this pull request Aug 27, 2026
… checks

Port of the bug class from earendil-works/pi#7933 (DeepSeek base-URL
detection matched by raw substring, missing case variants and matching
lookalike URLs). Hermes had the same class at five sites:

- cli_agent_setup_mixin.py: keyless-custom-endpoint detection treated any
  URL containing the OpenRouter host substring (path segment, lookalike
  domain) as OpenRouter, and missed case variants of the real host.
- models.py validate_requested_model: same substring check for routing an
  openrouter provider with a custom base_url to the custom catalog.
- runtime_provider.py: local-endpoint autodetect matched the string
  localhost anywhere in the URL, including remote hostnames containing it.
- gateway/run.py: /status endpoint display, same local-host substring.
- agent_runtime_helpers.py: Nous Portal cache-layout detection matched
  the nousresearch substring anywhere in the URL.

All sites now use the existing base_url_host_matches / base_url_hostname
helpers (exact host or subdomain, case-insensitive). Regression tests
proven to fail against the old predicates.
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
… checks

Port of the bug class from earendil-works/pi#7933 (DeepSeek base-URL
detection matched by raw substring, missing case variants and matching
lookalike URLs). Hermes had the same class at five sites:

- cli_agent_setup_mixin.py: keyless-custom-endpoint detection treated any
  URL containing the OpenRouter host substring (path segment, lookalike
  domain) as OpenRouter, and missed case variants of the real host.
- models.py validate_requested_model: same substring check for routing an
  openrouter provider with a custom base_url to the custom catalog.
- runtime_provider.py: local-endpoint autodetect matched the string
  localhost anywhere in the URL, including remote hostnames containing it.
- gateway/run.py: /status endpoint display, same local-host substring.
- agent_runtime_helpers.py: Nous Portal cache-layout detection matched
  the nousresearch substring anywhere in the URL.

All sites now use the existing base_url_host_matches / base_url_hostname
helpers (exact host or subdomain, case-insensitive). Regression tests
proven to fail against the old predicates.
jinhuang712 pushed a commit to jinhuang712/pi that referenced this pull request Sep 11, 2026
qaworkfree pushed a commit to qaworkfree/pipipiPopopo that referenced this pull request Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DeepSeek maxTokens stops working when a custom baseUrl uses uppercase letters

2 participants