Commit Graph
1120 Commits
Author SHA1 Message Date
Yichen Jiang d54475a681 fix(llm): preserve header overrides and safe failure diagnostics 2026-10-29 15:52:41 +08:00
Yichen Jiang a05a0d02fa feat(llm): allow plugins to prepare pi-ai request headers 2026-10-29 14:42:09 +08:00
Shigma 1aead808e2 chore(cordis): merge master into cordis-core-rc11 2026-10-28 17:27:40 +08:00
Yichen Jiang 9170c7b285 Merge remote-tracking branch 'origin/master' into worktree/issue-7150-investigation-4fc2ca
# Conflicts:
#	docs/capability-seams.i18n.yaml
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-schema.json
2026-10-28 12:39:39 +08:00
imccyu 00d541438b release(dsh): 0.2.2-alpha.2 2026-10-28 02:03:15 +08:00
imccyu 69c389ae11 release(dsh): 0.2.2-alpha.1 2026-10-28 00:00:58 +08:00
Yichen Jiang 9890d095bb test(models): cover account listing automatic badge removal 2026-10-27 16:36:55 +08:00
Yichen Jiang 825945fd40 fix(models): validate badge text and preserve tags beside long names 2026-10-27 16:17:36 +08:00
Yichen Jiang 67af01533e fix(models): retain badges when listing refresh fails 2026-10-27 15:26:08 +08:00
Yichen Jiang a36745f6ee refactor(models): share listing cache lifecycle wiring 2026-10-27 15:01:54 +08:00
Yichen Jiang 8394a200b9 fix(models): refresh listed badges in open selectors 2026-10-27 14:53:23 +08:00
Yichen Jiang af086ad377 Merge remote-tracking branch 'origin/master' into worktree/pr-7027-badge-refresh
# Conflicts:
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	docs/persistence-catalog.i18n.yaml
#	docs/persistence-catalog.md
#	docs/persistence-catalog.zh.md
#	docs/persistence-schema.json
#	packages/client/ui-deepseek-model-label-1017/package.json
2026-10-27 14:38:36 +08:00
Yichen Jiang a36ddf4c40 refactor(session): register request upload exclusions 2026-10-26 13:55:47 +08:00
imccyu 3014b0af0f Merge master into DSH 0.2.1-rc.4 synchronization branch 2026-10-26 01:29:12 +08:00
imccyu 341beb33c0 release(dsh): 0.2.1-rc.4 2026-10-26 00:57:37 +08:00
Tianyi Cui 940aafcadb test(acp): use shared cleanup for the stdout regression 2026-10-25 12:09:34 +08:00
Tianyi Cui 41736cdec5 fix(acp): keep account catalog diagnostics off stdout 2026-10-25 12:09:00 +08:00
Yichen Jiang 6fcb9b6c78 fix(auto-review): route review requests by their Session
Auto review requests omitted sessionId, so pi-ai never added the
x-opencode-session header that OpenCode routes require, and every
reviewed tool call failed with 400 MissingSessionID before its body ran.

Review requests now carry the reviewed Session's id and the new
GenerateOptions purpose 'auto-review'. The DeepSeek Session-log upload
skips that purpose, so a review neither uploads the log nor appends an
acceptance record to the Session.

Refs #7150
2026-10-24 22:26:35 +08:00
Yichen Jiang c92c81727c Merge remote-tracking branch 'origin/master' into worktree/model-badge-schema-fb132b 2026-10-23 13:23:05 +08:00
Yichen Jiang 23c2ee5f73 feat(llm-deepseek): read model badges from client_metadata
Each /models entry now declares its selector badge under
client_metadata["deepseek-harness"].badge, keyed by the User-Agent product
token like client_requirements, so the public model fields stay unchanged
and later DeepSeek Harness fields join the same object. Every field under
client_metadata is ignorable: null at any level shows no badge, and a level
that is not an object drops only the badge with a diagnostic naming it.
2026-10-23 13:12:16 +08:00
imccyu 14f0b2aafe Merge master into DSH 0.2.1-rc.3 synchronization branch 2026-10-23 11:56:34 +08:00
imccyu b049cd257c Merge pull request #6980 from deepseek-harness/07akioni/more-locales
feat(i18n): add Spanish, French, German, Russian and Portuguese
2026-10-23 11:22:55 +08:00
Yichen Jiang 439783d38f Merge remote-tracking branch 'origin/master' into worktree/model-badge-schema-fb132b 2026-10-23 10:37:32 +08:00
imccyu d02ea370ee release(dsh): 0.2.1-rc.3 2026-10-23 01:11:35 +08:00
imccyu 261f2db185 Merge master into DSH 0.2.1 navigation and model listing sync 2026-10-22 23:22:35 +08:00
Shigma 21e19d3639 chore(cordis): merge master into cordis-core-rc11 2026-10-22 21:20:45 +08:00
Yichen Jiang c48f8523f2 feat(llm): follow the official /models listing on the DeepSeek API-key route (#6944)
* refactor(llm-deepseek): share the /models listing machinery

Move the account route's `/models` request and decoding, its
credential-scoped listing cache, and listed-catalog resolution with the
version gate into the shared DeepSeek Messages library, so a second
route can follow the same listing. Names drop the account prefix, the
cache takes each access's endpoint settings with the call, and it gains
`invalidate()` for a forced reload. `isBuiltInCatalog()` recognizes the
catalog an uncustomized `models` setting resolves to.

The account route keeps its behavior; only its imports and the
override diagnostic wording ("model listing") change.

* feat(llm-deepseek-api-key): follow the official /models listing

While `models` equals the built-in catalog and the Messages origin is
https://api.deepseek.com, `deepseek-official` serves the official
`GET /models` listing, authenticated with the API key in `x-api-key`.
Loading, refresh, fallback, merging, and the client-version gate match
the account route: the first access waits up to `modelsTimeoutMs`, a
listing older than `modelsMaxAgeMs` refreshes in the background on the
next access, a failure keeps the last good listing or the built-in
catalog, and listed models this build cannot serve are refused before
network I/O.

A customized `models` list replaces the catalog and requests nothing.
Switching between a customized catalog and the listing discards the
cached listing, so Restore defaults reloads it on the next access.

Suites that boot the route on the official endpoint now answer the
listing themselves instead of reaching the network.

* docs: describe the official route model listing

Document when `deepseek-official` follows the official `/models`
listing, its timing fields, customization precedence, and the forced
reload after Restore defaults in the API-key README, the shared
transport README, and the provider guide. Record the decision in a new
Agent Note, keep the account note's statement of where the shared
listing code lives current, and regenerate the configuration catalog.

* test(llm-deepseek-api-key): pin the once-per-listing hidden-entry diagnostic

* docs: regenerate module and event graphs for the shared listing

* fix(llm-deepseek-api-key): report credential failures on the model request

On the official endpoint, `connect` waited for the listing view, whose
credential lookup rethrew a malformed key or a credential-store failure
before the agent loop recorded the prompt. A failed lookup now resolves
the connection from the current listing view, so `resolveAuth` reports
the failure on the model request and the turn keeps the prompt and the
failed attempt. A caller abort still rejects.

* docs(llm-deepseek-api-key): name which hidden listing entries are logged

* test: keep unit suites off the official model listing

Suites that boot the DeepSeek routes with a dummy or inherited key now
request `GET https://api.deepseek.com/models` on the official endpoint.
A unit-lane setup file rejects that request at once, so such a suite
serves the built-in catalog instead of reaching production or waiting
out the listing deadline on a network that never answers; suites that
exercise the listing answer `fetch` themselves. Other requests pass
through unchanged.

* feat(llm-deepseek): read tool_update from the model listing

Both DeepSeek routes now take a listed model's Messages tool update mode
from `api_capabilities.anthropic_messages.tool_update`, alongside the
system prompt mode. `in-history` and `addition-only` replace the
bundled mode; any other value reads as `leading-only` and removes it.
An absent or `null` mode keeps the bundled one, so a listing that does
not declare the field leaves `deepseek-flash` on `addition-only`.

`system_prompt_update: null` likewise keeps the bundled mode now; it
previously read as `leading-only`, which a serializer writing empty
values as null would have turned into a cache-unfriendly downgrade.

* fix(llm-deepseek): sync the built-in context window with the official listing

The official `/models` listing declares a 1,048,576-token context window
for `deepseek-flash` and `deepseek-v4-pro`; the built-in catalog said
1,000,000, a decimal-versus-binary mismatch. Both built-in entries now
carry the listed value, so offline starts and listing failures size the
context the same way the listing does. The Models page shows the exact
count for these rows, since 1,048,576 has no decimal K/M spelling.

`defaultContextWindow`, the fallback for model ids the catalog does not
describe, stays 1,000,000.

* test(llm-deepseek-api-key): reject the stubbed listing request with an Error

* test(cli): keep the built SDK smoke off the official model listing

The SDK profile's initialize now resolves the deepseek-official catalog,
which requests GET https://api.deepseek.com/models on the official
endpoint. With the smoke's fixture key that request answers 401 and the
route warns on stderr, so the test's empty-stderr assertion failed in the
e2e and snapshots lanes. Point the run at a loopback mock and assert it
received no model call.

* test(llm-deepseek): compose the malformed-key turn without the native executor

release/dsh-0.2.1 predates @deepseek-ai/dsh-tool-executor-native; its tool
runtime executes tools itself. Compose the official-route turn the way
account-routing.spec.ts does on this branch.

* fix(llm-deepseek-api-key): gate nothing when the credential lookup fails

The listing cache switches scope only after it reads a credential, so a
failed lookup left `connect` serving the previous credential's listing.
After a key whose listing refuses a model was replaced by a malformed one,
`admit` refused that model with CLIENT_UPGRADE_REQUIRED before the turn
recorded the prompt, instead of `resolveAuth` reporting the credential
error on the request. Serve the built-in catalog without listing gates
when the lookup fails.

* test(llm-deepseek-api-key): pin the once-per-listing diagnostic across request preparation

The hidden-entry diagnostic test repeated the same discovery assertion to
prove a second pass reports nothing new, which read as a duplicate. Assert
the single warning after the request preparations instead; they resolve
the same listing, so dropping the per-listing deduplication still fails
the test.

* docs(llm-deepseek-api-key): note that a list matching an earlier built-in catalog counts as customized

Customization is judged against the running version's built-in catalog,
so a saved `models` list equal to an earlier version's catalog stops
following the listing once the built-in catalog changes, until Restore
defaults. Record the consequence in the Agent Note and the README's known
limitations.
2026-10-22 20:42:19 +08:00
07akioni 84edeadc2b feat(i18n): add Spanish French German Russian and Portuguese 2026-10-22 19:53:52 +08:00
Yichen Jiang 663aa618c5 feat(llm): carry /models badges into the model catalog
The shared DeepSeek listing decoder reads an optional per-entry
`badge: { text, tone }`. Text is one literal or translations keyed by
lowercase language id with a required English entry, each trimmed to 1
to 12 characters on one line; tone is neutral, info, success, or
warning, and an absent or unrecognized tone reads as neutral. An absent
or null badge declares none; an unreadable one is dropped with a listing
problem and never hides its model.

resolveListedCatalog keeps the badges of offered models, both DeepSeek
routes attach them through catalogModelInfo, LlmRuntime.listModels
detaches them, and the Host model catalog forwards them as
ModelCatalogModel.badge. resolveModelInfo omits the badge, so no model
request, Session event, or model-facing tool carries it.
2026-10-22 18:47:30 +08:00
Yichen Jiang 8bef97a894 test(llm-deepseek-api-key): reject the stubbed listing request with an Error 2026-10-22 13:47:44 +08:00
Yichen Jiang e3a485bd32 fix(llm-deepseek): sync the built-in context window with the official listing
The official `/models` listing declares a 1,048,576-token context window
for `deepseek-flash` and `deepseek-v4-pro`; the built-in catalog said
1,000,000, a decimal-versus-binary mismatch. Both built-in entries now
carry the listed value, so offline starts and listing failures size the
context the same way the listing does. The Models page shows the exact
count for these rows, since 1,048,576 has no decimal K/M spelling.

`defaultContextWindow`, the fallback for model ids the catalog does not
describe, stays 1,000,000.
2026-10-22 13:34:14 +08:00
Yichen Jiang 70b945901d feat(llm-deepseek): read tool_update from the model listing
Both DeepSeek routes now take a listed model's Messages tool update mode
from `api_capabilities.anthropic_messages.tool_update`, alongside the
system prompt mode. `in-history` and `addition-only` replace the
bundled mode; any other value reads as `leading-only` and removes it.
An absent or `null` mode keeps the bundled one, so a listing that does
not declare the field leaves `deepseek-flash` on `addition-only`.

`system_prompt_update: null` likewise keeps the bundled mode now; it
previously read as `leading-only`, which a serializer writing empty
values as null would have turned into a cache-unfriendly downgrade.
2026-10-22 13:25:06 +08:00
Yichen Jiang 115fd8017e docs(llm-deepseek-api-key): name which hidden listing entries are logged 2026-10-22 12:04:25 +08:00
Yichen Jiang 542e0530ea fix(llm-deepseek-api-key): report credential failures on the model request
On the official endpoint, `connect` waited for the listing view, whose
credential lookup rethrew a malformed key or a credential-store failure
before the agent loop recorded the prompt. A failed lookup now resolves
the connection from the current listing view, so `resolveAuth` reports
the failure on the model request and the turn keeps the prompt and the
failed attempt. A caller abort still rejects.
2026-10-22 12:01:37 +08:00
Yichen Jiang db915a239d test(llm-deepseek-api-key): pin the once-per-listing hidden-entry diagnostic 2026-10-22 11:25:35 +08:00
Yichen Jiang 08fa1e4d5a docs: describe the official route model listing
Document when `deepseek-official` follows the official `/models`
listing, its timing fields, customization precedence, and the forced
reload after Restore defaults in the API-key README, the shared
transport README, and the provider guide. Record the decision in a new
Agent Note, keep the account note's statement of where the shared
listing code lives current, and regenerate the configuration catalog.
2026-10-22 11:23:52 +08:00
Yichen Jiang e90f65c0d7 feat(llm-deepseek-api-key): follow the official /models listing
While `models` equals the built-in catalog and the Messages origin is
https://api.deepseek.com, `deepseek-official` serves the official
`GET /models` listing, authenticated with the API key in `x-api-key`.
Loading, refresh, fallback, merging, and the client-version gate match
the account route: the first access waits up to `modelsTimeoutMs`, a
listing older than `modelsMaxAgeMs` refreshes in the background on the
next access, a failure keeps the last good listing or the built-in
catalog, and listed models this build cannot serve are refused before
network I/O.

A customized `models` list replaces the catalog and requests nothing.
Switching between a customized catalog and the listing discards the
cached listing, so Restore defaults reloads it on the next access.

Suites that boot the route on the official endpoint now answer the
listing themselves instead of reaching the network.
2026-10-22 11:19:22 +08:00
Yichen Jiang a0324bc09f refactor(llm-deepseek): share the /models listing machinery
Move the account route's `/models` request and decoding, its
credential-scoped listing cache, and listed-catalog resolution with the
version gate into the shared DeepSeek Messages library, so a second
route can follow the same listing. Names drop the account prefix, the
cache takes each access's endpoint settings with the call, and it gains
`invalidate()` for a forced reload. `isBuiltInCatalog()` recognizes the
catalog an uncustomized `models` setting resolves to.

The account route keeps its behavior; only its imports and the
override diagnostic wording ("model listing") change.
2026-10-22 11:11:28 +08:00
_Kerman d98025a089 Merge origin/master into xtr/tool-executor-plugins 2026-10-21 18:01:55 +08:00
07akioni ed783066e6 fix(i18n): complete Japanese plugin metadata and guard locale coverage 2026-10-21 16:14:12 +08:00
_Kerman a53ecb2f3a Merge origin/master into xtr/tool-executor-plugins 2026-10-21 15:56:44 +08:00
Magolor a6a5c41b3b refactor(token-meter): 分离计量恢复信息与价格缓存 (#6728)
* refactor(token-meter): checkpoint measurement facts without pricing caches

* refactor(token-meter): reuse cached headers without new history reads

* fix(token-meter): isolate measurement recovery failures
2026-10-21 15:15:42 +08:00
_Kerman 38b9a095f3 Merge remote-tracking branch 'origin/master' into xtr/tool-executor-plugins
# Conflicts:
#	docs/event-producer-consumer.md
#	docs/event-producer-consumer.zh.md
#	packages/web/tool-web/tests/integration.spec.ts
#	pnpm-lock.yaml
#	scripts/check-workspace-constraints.spec.ts
#	scripts/check-workspace-constraints.ts
2026-10-21 11:22:06 +08:00
_Kerman 200dedd494 chore: trim unrelated model-selection changes 2026-10-20 22:13:30 +08:00
_Kerman a9c006f9c3 refactor(agent): own model selection on each agent 2026-10-20 21:09:09 +08:00
_Kerman 639602e63a Merge origin/master into xtr/session-model-selection 2026-10-20 20:57:11 +08:00
Yixiang Tu 84a6d2bcaf fix(llm-pi-ai): preserve later system reminders in request history 2026-10-20 18:13:24 +08:00
_Kerman 8b79a1ddcc Merge origin/master into xtr/session-model-selection 2026-10-20 17:22:59 +08:00
Turtle 29959ed1ab Merge pull request #6537 from deepseek-harness/turtle/gemini-thought-signature-945bf702b56d
fix(llm-pi-ai): replay Gemini tool-call thought signatures over Chat Completions
2026-10-20 13:29:16 +08:00
_Kerman 7d0301fe05 Merge master into scoped tool executors 2026-10-19 21:53:41 +08:00