Commit Graph

40 Commits

Author SHA1 Message Date
fullex
9b9570116a refactor(db): replace libsql with better-sqlite3 + sqlite-vec (#16626) 2026-07-02 13:21:13 +08:00
robin
65c54e5ce5 chore(deps): bump @openrouter/ai-sdk-provider to ^2.10.0 (#16467)
Signed-off-by: Robinnnnn <12162433+Robinnnnn@users.noreply.github.com>
2026-06-29 16:51:14 +08:00
SuYao
611944599f refactor(deps): replace lodash with es-toolkit/compat and drop it (#16528)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-29 12:28:57 +08:00
SuYao
0665ce7270 fix(anthropic): strip unsupported JSON Schema keywords from tool schemas (#16480)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-27 18:22:00 +08:00
亢奋猫
eb2622e9af refactor(ui): remove antd dependency (#16336)
Co-authored-by: gujiaming <52187003+AtomsH4@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: kangfenmao <kangfenmao@qq.com>
Signed-off-by: gujiaming <52187003+AtomsH4@users.noreply.github.com>
2026-06-26 15:49:22 +08:00
SuYao
22ffb62f62 feat(richeditor): native @tiptap/markdown AST on Tiptap 3.26.1 (#16118)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-17 18:38:54 +08:00
槑囿脑袋
1382a8dd7c feat(knowledge): route embeddings and reranking through the AI service (#15796)
### What this PR does

Before this PR:

- Knowledge embeddings and reranking ran through the legacy
embedjs-based
knowledgeV1 stack with their own provider clients, independent of the
app's
  AI service.
- File-processing intake accepted several heterogeneous input shapes,
and
knowledge file items were tracked by FileEntry ids, coupling file
content to
  the file-manager entry/cache.

After this PR:

- Embeddings and reranking are routed through the unified `AiService`
(with
cherryin rerank support) and guarded by strict embedding-dimension
validation
  that rejects stale/mismatched vectors.
- File-processing intake is collapsed to a single path-based model;
knowledge
  file items are stored by base-relative path under the knowledge-base
directory, and v1 uploads are copied into the v2 base dir during
migration so
  migrated items stay reindexable/restorable.
- Legacy `knowledgeV1` is removed; the orchestration services were
renamed to
  `KnowledgeService` / `FileProcessingService`.
- Chat -> knowledge attach is temporarily disconnected (tracked TODO)
while the
  v2 file-manager bridge is rebuilt.

Fixes #N/A (no linked issue)

### Why we need it and why it was done in this way

Routing embeddings/rerank through `AiService` unifies provider handling
and
credentials and removes the parallel embedjs client stack and its v1
coupling.
Storing knowledge files by base-relative path (instead of FileEntry ids)
makes
each knowledge base self-contained and portable.

The following tradeoffs were made:

- A large, coordinated refactor plus a migration step that physically
copies v1
uploads into the v2 base dir, in exchange for removing the parallel
client
  stack and making bases self-contained.
- Base-relative path storage required a fail-fast/dedup strategy for
same-named
  files and a guard for blank legacy filenames.

The following alternatives were considered:

- Keeping the embedjs stack behind an adapter — rejected; perpetuates
the
  parallel client and v1 coupling.
- Keeping FileEntry-id storage — rejected; couples knowledge files to
the
  file-manager cache and blocks portability.

### Breaking changes

- `knowledgeV1` is removed. Legacy v1 knowledge data reaches v2 only
through the
  v2 migrators; there is no v1 fallback.
- The v2 knowledge HTTP API (API gateway) now returns v2-native
per-entry fields
(`embeddingModelId`, `createdAt` on base entries; `chunkId`,
`scoreKind`,
  `rank` on search results). The response envelope (`knowledge_bases`,
  `searched_bases`, `total`) is unchanged. See

`v2-refactor-temp/docs/breaking-changes/2026-06-05-knowledge-api-v2.md`.

### Special notes for your reviewer

- This branch went through several rounds of multi-agent code review.
The most
recent 6 commits address review findings: directory-import path
collisions,
migrated-file source copying + blank `relativePath` guard, addItems
rollback
error preservation, eager `document_to_markdown` output-target
validation, a
`CompletedKnowledgeBase` type guard, and breaking-changes doc
corrections.
- Chat -> knowledge attach is intentionally disconnected for now
(tracked in
  `v2-refactor-temp/docs/knowledge/knowledge-todo.md`).
- Local full `pnpm lint`/`pnpm test` was not run per the project's
review
  conventions; please rely on CI / `pnpm build:check`.

### Checklist

- [x] Branch: This PR targets the correct branch — `main` for active
development, `v1` for v1 maintenance fixes
- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A user-guide update was considered and is present
(link) or not required.
- [x] Self-review: I have reviewed my own code before requesting review
from others

### Release note

```release-note
NONE
```

---------

Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:04:29 +08:00
亢奋猫
26508591f8 refactor(paintings): migrate to v2 data layer and UI (#15154)
Co-authored-by: jidan745le <420511176@qq.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: jidan745le <420511176@qq.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-06-02 15:18:53 +08:00
fullex
fa5bbb7607 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-05-28 19:38:52 -07:00
Asurada
0b697210bd fix: support Grok 4.3 reasoning effort in xAI responses (#15137)
### What this PR does

Before this PR:

- Grok 4.3 did not fully support reasoning effort through the xAI
responses path.
- Cherry Studio did not expose the Grok 4.3 reasoning options
consistently in model configuration.
- The local @ai-sdk/xai patch could fail pnpm install after manual patch
edits.

After this PR:

- Grok 4.3 correctly maps `reasoning_effort` to xAI responses with
`none`, `low`, `medium`, and `high`.
- The renderer exposes Grok 4.3 as a supported reasoning model with the
correct option set.
- The local @ai-sdk/xai patch is regenerated and narrowed to the
responses path so pnpm install succeeds.

Fixes #

N/A

### Why we need it and why it was done in this way

The following tradeoffs were made:

- The change is scoped to the xAI responses path because Grok is already
routed to `xai-responses` in this repository.
- A local patch is still required because the latest stable
`@ai-sdk/xai` release does not yet support `none` for xAI responses
`reasoningEffort`.
- The patch was narrowed to responses-only to avoid widening behavior
for the base xAI chat path.

The following alternatives were considered:

- Upgrading directly to the latest stable `@ai-sdk/xai`, but the latest
stable release still does not support `none` for responses
`reasoningEffort`.
- Broadening the patch to cover xAI chat options as well, but that would
expand behavior beyond the required Grok 4.3 responses path.

Links to places where the discussion took place: None

### Breaking changes

None.

If this PR introduces breaking changes, please describe the changes and
the impact on users.

### Special notes for your reviewer

- Focused validation passed with `pnpm install`, `pnpm typecheck:web`,
and targeted Vitest suites for xAI/Grok reasoning and model config.
- Full `pnpm test` on Windows still has unrelated baseline failures
outside this change set.

### Checklist

This checklist is not enforcing, but it's a reminder of items that could
be relevant to every PR.
Approvers are expected to review this list.

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [x] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others

### Release note

<!--  Write your release note:
1. Enter your extended release note in the below block. If the PR
requires additional action from users switching to the new release,
include the string "action required".
2. If no release note is required, just write "NONE".
3. Only include user-facing changes (new features, bug fixes visible to
users, UI changes, behavior changes). For CI, maintenance, internal
refactoring, build tooling, or other non-user-facing work, write "NONE".
-->

```release-note
Fixed Grok 4.3 reasoning effort support in xAI responses so Cherry Studio now correctly exposes and applies the `none`, `low`, `medium`, and `high` reasoning levels.
```

---------

Signed-off-by: ousugo <dkzydkzyxh@gmail.com>
Co-authored-by: ousugo <dkzydkzyxh@gmail.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
2026-05-18 16:24:22 +08:00
fullex
7b556cf786 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-05-15 05:51:51 -07:00
Qin Lingguang
72bb96ed71 fix(knowledge): preserve HTTP URLs in knowledge base documents (#14983)
### What this PR does

Before this PR:

When adding Markdown documents to a knowledge base, all HTTP/HTTPS/FTP
URLs are silently stripped from the indexed content. Searching the
knowledge base returns text with all links removed.

After this PR:

URLs in knowledge base documents are preserved in the indexed chunks, so
searches return the full original content including links.

Fixes #14956 #14962

### Why we need it and why it was done in this way

**Root cause:** The `@cherrystudio/embedjs-loader-web` package (forked
from upstream `@llm-tools/embedjs`) contains a regex in `WebLoader` that
unconditionally strips all URLs from text content:

```js
.replace(/(?:https?|ftp):\/\/[\n\S]+/g, '')
```

This was originally designed for web scraping — removing noisy
navigation/footer URLs when crawling web pages. In the upstream's
primary use case (crawling web pages for RAG), this is reasonable
behavior since navigation bars, footers, and sidebars produce many
irrelevant URLs that add noise to embeddings. So this is not a bug in
the upstream library — it's a difference in usage context. Cherry Studio
uses these loaders for user-provided Markdown documents where URLs are
intentional, meaningful content authored by the user.

However, `MarkdownLoader` delegates to `WebLoader` (Markdown → HTML via
micromark → WebLoader), so Markdown file URLs get caught by the same
regex and removed.

The `CherryHQ/embed-js` fork inherited this behavior as-is from upstream
`@llm-tools/embedjs` — the fork only changed the `@llm-tools/` namespace
to `@cherrystudio/` with no functional modifications to the loader
logic.

**Why pnpm patch instead of fixing the fork repo:**

1. This is not an upstream bug but a usage context mismatch — submitting
an upstream PR to change this behavior could break the upstream's
intended web-scraping use case.
2. The `CherryHQ/embed-js` fork periodically syncs with upstream (e.g.,
`chore: sync to upstream` commits), so any fork-side change would be
overwritten on next sync.
3. The fork has been intentionally kept minimal — only namespace renames
— to make syncing straightforward.
4. Using `pnpm patch` is consistent with the project's existing pattern
(22+ patches already in `patches/`).

The following alternatives were considered:

- Fixing the `CherryHQ/embed-js` fork directly — rejected due to the
sync-overwrite risk described above.
- Adding a `keepUrls` constructor option to `WebLoader` — rejected as
more invasive than needed for a hotfix.

### Breaking changes

None. The only behavior change is that URLs are now preserved in
knowledge base chunks instead of being silently removed. This is the
expected/correct behavior.

### Special notes for your reviewer

- The patch removes the URL-stripping regex from both `web-loader.js`
(ESM) and `web-loader.cjs` (CommonJS).
- The `MarkdownLoader` bracket-stripping regex (`[[\](){}]`) is a
separate cosmetic issue not addressed in this hotfix — with URLs
preserved, `text [https://url]` becomes `text https://url` after bracket
stripping, so the URL itself is intact.
- Users who have already added Markdown files to their knowledge base
will need to re-index those files to get URLs in the indexed content.

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others

### Release note

```release-note
Fixed a bug where all HTTP/HTTPS/FTP URLs were stripped from Markdown documents when adding them to a knowledge base, causing search results to lose all links.
```

---------

Signed-off-by: raymond <13162938362@163.com>
Co-authored-by: SuYao <sy20010504@gmail.com>
2026-05-12 22:51:38 +08:00
fullex
1afd70b372 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-05-03 00:11:34 -07:00
zhibisora
794698f527 fix: refresh openrouter provider patch (#14750)
<!-- Template from
https://github.com/kubevirt/kubevirt/blob/main/.github/PULL_REQUEST_TEMPLATE.md?-->
<!--  Thanks for sending a pull request!  Here are some tips for you:
1. Consider creating this PR as draft:
https://github.com/CherryHQ/cherry-studio/blob/main/CONTRIBUTING.md
-->

<!--

🚨 Branch Strategy Change (Effective April 3, 2026) 🚨

The `main` branch is now under CODE FREEZE.

- main branch: Only accepts critical bug fixes via `hotfix/*` branches.
Fix PRs must be minimal in scope and must not include any refactoring
code.
- v2 branch: All new features, refactoring, and optimizations should be
submitted to the `v2` branch.

If you are submitting a bug fix to main, please ensure your PR is from a
`hotfix/*` branch.

-->

### What this PR does

Before this PR:

The `@openrouter/ai-sdk-provider` pnpm patch no longer applied cleanly
to the current `2.3.3` package contents, causing install-time patch
warnings.

After this PR:

The patch has been refreshed for the current package layout, keeps
`strictJsonSchema` support for OpenRouter tool schemas, strips that
internal option from API request bodies, and updates the pnpm patch
hash.

<!-- (optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)`
format, will close the issue(s) when PR gets merged)*: -->

Fixes #

### Why we need it and why it was done in this way

The following tradeoffs were made:

This keeps the dependency version unchanged and only refreshes the
existing patch, minimizing scope for the `main` branch.

The following alternatives were considered:

Upgrading `@openrouter/ai-sdk-provider` was avoided because this PR only
needs to restore the existing patch behavior.

Links to places where the discussion took place: N/A

### Breaking changes

None.

If this PR introduces breaking changes, please describe the changes and
the impact on users.

### Special notes for your reviewer

Validated with `pnpm install --ignore-scripts`, `pnpm lint`, `pnpm
test`, `pnpm format`, and `git diff --check`.

### Checklist

This checklist is not enforcing, but it's a reminder of items that could
be relevant to every PR.
Approvers are expected to review this list.

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others

### Release note

<!--  Write your release note:
1. Enter your extended release note in the below block. If the PR
requires additional action from users switching to the new release,
include the string "action required".
2. If no release note is required, just write "NONE".
3. Only include user-facing changes (new features, bug fixes visible to
users, UI changes, behavior changes). For CI, maintenance, internal
refactoring, build tooling, or other non-user-facing work, write "NONE".
-->

```release-note
NONE
```

Signed-off-by: zhibisora <73344387+zhibisora@users.noreply.github.com>
2026-04-30 21:44:15 +08:00
SuYao
7ddceb698f fix(deps): omit max_tokens for non-Anthropic models in @ai-sdk/anthropic (#14749)
### What this PR does

Before this PR:

When `@ai-sdk/anthropic`'s `AnthropicMessagesLanguageModel` was used as
transport for non-Anthropic models (e.g. NewAPI configured with
`endpointType: 'anthropic'` routing non-Claude models, or any gateway
proxying non-Claude models through an Anthropic-compatible API), the SDK
silently injected a default `max_tokens` value (4096 for unknown models,
model-specific for Claude). This overrode the user's intent when they
had disabled `enableMaxTokens` in assistant settings — Cherry Studio's
`getMaxTokens` deliberately returns `undefined` in that case.

After this PR:

`max_tokens` is only emitted when either (a) the user has explicitly set
it, or (b) the model is actually a Claude model (`isKnownModel ||
modelId.startsWith("claude-")`). For non-Anthropic models routed through
the Anthropic SDK, the field is omitted, respecting the user's choice.

The fix lives in `patches/@ai-sdk__anthropic.patch`:
1. Make the fallback to `maxOutputTokensForModel` Claude-only.
2. Use a conditional spread for `max_tokens` in `baseArgs` so it's
omitted when undefined.
3. Guard the thinking-budget addition (`maxTokens + thinkingBudget`) so
it doesn't compute `NaN`.

Fixes #

### Why we need it and why it was done in this way

The Anthropic API itself requires `max_tokens`, so the SDK's default
fallback is correct for actual Claude requests. But the same SDK class
is reused as a transport for non-Anthropic backends in NewAPI /
aggregator providers, and there the silent default leaks through and
caps generation.

The following tradeoffs were made:

- Patched the upstream package via the existing `pnpm patch` workflow
rather than wrapping/intercepting the SDK at the call site, because the
field is constructed deep inside `getArgs()` and forking that path would
duplicate a lot of logic.

The following alternatives were considered:

- Setting `maxOutputTokens` explicitly per-provider in `getMaxTokens`.
Rejected because we want `undefined` to mean "let the server decide" for
non-Anthropic backends, and there is no generic safe default.
- Pre-stripping `max_tokens` after the SDK builds the body. Rejected:
the SDK posts directly via `postJsonToApi`; there is no public hook
between body construction and request dispatch.

Links to places where the discussion took place: N/A

### Breaking changes

None. Behavior for real Anthropic Claude requests is unchanged (the
default is still applied). The change only affects requests where the
SDK is used against a non-Claude model and the user has not set
`maxOutputTokens` — previously they got a silent 4096 cap, now they get
whatever the upstream server defaults to.

### Special notes for your reviewer

- The patch is regenerated via `pnpm patch @ai-sdk/anthropic@3.0.71` +
`pnpm patch-commit`, so the hash in `pnpm-lock.yaml` updates
accordingly.
- Existing 28 tests in
`src/renderer/src/aiCore/prepareParams/__tests__/model-parameters.test.ts`
still pass.
- Hotfix branch per the post-2026-04-03 main-branch policy. No
refactoring included.

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others

### Release note

```release-note
fix(deps): prevent @ai-sdk/anthropic from injecting a default max_tokens when used as transport for non-Anthropic models (e.g. NewAPI with anthropic endpoint type for non-Claude models). User's choice to disable max tokens is now respected on those backends.
```

Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 20:23:01 +08:00
SuYao
06f93a0d2f fix(deps): bump @ai-sdk/deepseek to 2.0.30 (#14718)
### What this PR does

Before this PR:

- `@ai-sdk/deepseek` was pinned to `2.0.29`, missing an upstream fix for
`deepseek-v4` reasoning content in multi-turn conversations.

After this PR:

- Bumps `@ai-sdk/deepseek` from `2.0.29` to `2.0.30` (latest stable).
- Renames the local patch file to `@ai-sdk__deepseek@2.0.30.patch` and
updates the `pnpm.patchedDependencies` key. The patch (which adds the
`reasoning_effort` option for `high`/`max`) re-applies cleanly because
the patched regions are unchanged in `2.0.30`.

Fixes #

### Why we need it and why it was done in this way

Upstream `2.0.30` ships a single fix from vercel/ai commit `0498012`:
`fix(provider/deepseek): preserve reasoning_content for deepseek-v4 in
multi-turn requests`. It threads the `modelId` into
`convertToDeepSeekChatMessages`, stops dropping `reasoning` blocks
before the last user message for `deepseek-v4`, and ensures
`reasoning_content` is at least `""` rather than `undefined` so the
field is preserved across turns. Keeping the local patch in sync with
upstream prevents drift and unblocks future DeepSeek model rollouts.

The following tradeoffs were made:

- Patch file content is byte-identical; only the filename and
`pnpm.patchedDependencies` key are updated. This avoids gratuitous diff
churn while keeping the patch addressable to the new version.

The following alternatives were considered:

- Wait for a larger DeepSeek change before bumping — rejected; the
upstream fix is small, isolated, and there is no reason to delay.
- Move to `3.0.0-beta.x` — rejected; betas track AI SDK v6 and are out
of scope for the `main` branch hotfix lane.

Links to places where the discussion took place: N/A

### Breaking changes

None. Public API surface, exported types, and the `reasoning_effort`
patch behavior are unchanged.

### Special notes for your reviewer

- Verified the patch applied to `2.0.30` in `node_modules` — both the
local addition (`reasoning_effort`) and the upstream fix
(`isDeepSeekV4`) are present after `pnpm install`.
- `pnpm build:check` passes locally (4199 tests, 0 errors).
- This change is restricted to `main` per the code-freeze policy and is
delivered from a `hotfix/*` branch with no refactoring.

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A user-guide update was considered and is present
(link) or not required. Check this only when the PR introduces or
changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code before requesting review
from others

### Release note

```release-note
NONE
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
2026-04-30 14:17:43 +08:00
fullex
6a6b47562b Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-04-29 20:32:41 -07:00
SuYao
26d877e0fa hotfix(image-generation): fix gpt-image-2 / gpt-image-1.5 failures and stuck pending placeholder (#14578)
<!-- Template from
https://github.com/kubevirt/kubevirt/blob/main/.github/PULL_REQUEST_TEMPLATE.md?-->
<!--  Thanks for sending a pull request!  Here are some tips for you:
1. Consider creating this PR as draft:
https://github.com/CherryHQ/cherry-studio/blob/main/CONTRIBUTING.md
-->

<!--

🚨 Branch Strategy Change (Effective April 3, 2026) 🚨

The `main` branch is now under CODE FREEZE.

- main branch: Only accepts critical bug fixes via `hotfix/*` branches.
Fix PRs must be minimal in scope and must not include any refactoring
code.
- v2 branch: All new features, refactoring, and optimizations should be
submitted to the `v2` branch.

If you are submitting a bug fix to main, please ensure your PR is from a
`hotfix/*` branch.

-->

### What this PR does

Before this PR:

- `gpt-image-2` (and any image-edit request routed through AiHubMix /
NewAPI / CherryIN) failed with `common.UnmarshalBodyReusable failed:
bind request body failed: invalid character '-' in numeric literal`. The
providers hard-coded `Content-Type: application/json` in
`authHeaders()`, but `OpenAICompatibleImageModel.doGenerate` uses
`postFormDataToApi` for `/images/edits` and relies on `fetch` to
auto-set `multipart/form-data; boundary=...`. Forcing JSON made the
server receive a multipart body under a JSON content-type and choke on
the leading `--boundary`.
- Even when the request reached the server, image uploads failed with
`unsupported mimetype ('image')` because `collectImagesFromMessages`
built data URIs using `block.file.type` — which is the `FileType` enum
(`"image"`), not a MIME type.
- Some saved/pasted images produced `ENOENT: ... <uuid>jpg` because
`saveBase64Image` / `savePastedImage` return `ext` without the leading
dot, and the caller was concatenating `file.id + file.ext`.
- After a successful image generation, a `BeatLoader` placeholder kept
spinning next to the finished image. `fetchImageGeneration` only emitted
`LLM_RESPONSE_COMPLETE`; the trailing loader in `Blocks/index.tsx` is
driven by `isMessageProcessing(message)`, which is only cleared when
`onComplete` runs on `BLOCK_COMPLETE`.
- If a `file` chunk arrived without a preceding `IMAGE_CREATED`, the
initial UNKNOWN placeholder block was never claimed, leaving an orphan
spinner below the image.
- `gpt-image-2` / `gpt-image-1.5` / `gpt-image-1*` / `chatgpt-image-*`
generations through any OpenAI-compatible provider still failed with
`400 Unknown parameter: 'response_format'` (see #14485, #14540, #14579).
The earlier `@ai-sdk/openai@3.0.53` patch (#14488) only covered
`OpenAIImageModel` (direct OpenAI + Azure via `@ai-sdk/azure`);
`OpenAICompatibleImageModel.doGenerate` unconditionally added
`response_format: "b64_json"` to the `/images/generations` body, so
every provider whose image model is wired to
`OpenAICompatibleImageModel` kept hitting the 400 — including `type:
'openai-compatible'` and the AiHubMix / NewAPI / CherryIN gateway image
models in this repo.

After this PR:

- `aihubmix-provider`, `newapi-provider`, and `cherryin-provider` no
longer hard-code `Content-Type` in auth headers. `postJsonToApi` still
defaults JSON for other endpoints, and `postFormDataToApi` is free to
let `fetch` set `multipart/form-data; boundary=...` for `/images/edits`.
- `collectImagesFromMessages` reads via
`window.api.file.base64Image(block.file.name)`, which returns a correct
`data:image/<ext>;base64,...` URI (with `jpg → jpeg` normalization) and
uses the consistent on-disk filename regardless of whether the stored
`ext` has a leading dot.
- `fetchImageGeneration` now emits `ChunkType.BLOCK_COMPLETE` before
`LLM_RESPONSE_COMPLETE`, so `onComplete` runs and the assistant message
transitions out of `PROCESSING`.
- `onImageGenerated` reuses the initial UNKNOWN placeholder when one
exists, so a `file` chunk without a prior `IMAGE_CREATED` no longer
leaves an orphan spinner.
- `gpt-image-2` is registered in `IMAGE_ENHANCEMENT_MODELS`.
- `patches/@ai-sdk__openai-compatible@2.0.37.patch` is extended with the
same `hasDefaultResponseFormat` guard that `@ai-sdk/openai` already
uses. `OpenAICompatibleImageModel.doGenerate` now spreads
`response_format: "b64_json"` only when the model ID does **not** start
with `chatgpt-image-`, `gpt-image-1-mini`, `gpt-image-1.5`,
`gpt-image-1`, or `gpt-image-2`. This fixes #14485, #14540, #14579 for
`openai-compatible` typed providers and the AiHubMix / NewAPI / CherryIN
gateways.

Fixes #14485
Fixes #14540
Fixes #14579

### Why we need it and why it was done in this way

The following tradeoffs were made:

- The `ext`-with-or-without-dot inconsistency exists in historical DB
records, so patching only `FileStorage.ts` would not help already-saved
rows. The fix uses `file.name` at the consumer side — always the real
on-disk filename across every save path — without touching the storage
layer.
- The provider `authHeaders()` change could theoretically affect
non-JSON, non-multipart requests, but all SDK models in use go through
`postJsonToApi`, which already defaults `Content-Type: application/json`
internally, so behavior is preserved.
- Extending the `@ai-sdk/openai-compatible` patch rather than overriding
`response_format` per-provider keeps the fix in one place and
automatically covers every caller of `OpenAICompatibleImageModel`
(current and future). The guard list mirrors the upstream
`@ai-sdk/openai` list, so the two stay in sync.

The following alternatives were considered:

- Normalizing `ext` in `FileStorage.saveBase64Image` /
`savePastedImage`: rejected because it would not repair existing records
and could regress other callers that have compensated for the dotless
form.
- Overriding `Content-Type` only inside the image model factory:
rejected as more surface area than needed; the global `authHeaders()`
already defers to `postJsonToApi` defaults.
- Stripping `response_format` in each custom provider (AiHubMix / NewAPI
/ CherryIN) instead of patching the SDK: rejected — it would leave
`type: 'openai-compatible'` users still broken and duplicate the
model-prefix list in three places.

Links to places where the discussion took place: #14485, #14540, #14579,
#14488

### Breaking changes

<!-- optional -->

None.

### Special notes for your reviewer

<!-- optional -->

Scope is intentionally minimal for the main branch freeze: no
refactoring, no new abstractions. Surface changes:

- `authHeaders()` in three custom providers (drops one hard-coded
header).
- `collectImagesFromMessages` (one helper, swaps input building).
- `fetchImageGeneration` (one extra chunk emission).
- `onImageGenerated` (placeholder-claim fallback).
- `IMAGE_ENHANCEMENT_MODELS` (one new entry).
- `patches/@ai-sdk__openai-compatible@2.0.37.patch` (adds
`hasDefaultResponseFormat` helper + conditional spread of
`response_format`; mirrors `@ai-sdk/openai@3.0.53` patch).

Drop the openai-compatible patch addition once
`@ai-sdk/openai-compatible` ships the equivalent check upstream.

### Checklist

This checklist is not enforcing, but it's a reminder of items that could
be relevant to every PR.
Approvers are expected to review this list.

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others

### Release note

<!--  Write your release note:
1. Enter your extended release note in the below block. If the PR
requires additional action from users switching to the new release,
include the string "action required".
2. If no release note is required, just write "NONE".
3. Only include user-facing changes (new features, bug fixes visible to
users, UI changes, behavior changes). For CI, maintenance, internal
refactoring, build tooling, or other non-user-facing work, write "NONE".
-->

```release-note
Fix image generation and editing for gpt-image-2 / gpt-image-1.5 / gpt-image-1* / chatgpt-image-* across AiHubMix, NewAPI, CherryIN, Azure OpenAI, and other OpenAI-compatible providers: requests no longer fail with `Unknown parameter: 'response_format'`, multipart content-type, or mimetype errors; generated/pasted images are resolved correctly; and the loading placeholder disappears once the image is rendered.
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
2026-04-26 00:34:41 +08:00
SuYao
4e1e4548bb hotfix(deepseek): forward reasoning effort for DeepSeek V4+ via Claude endpoint (#14572)
### What this PR does

Before this PR:

- For DeepSeek V4+ models served through a Claude-compatible endpoint,
`getAnthropicReasoningParams` returned only `{ thinking: { type:
'enabled', budgetTokens } }`. The requested `reasoning_effort` was
dropped before the request left the client, so `high` / `xhigh` behaved
identically to default.
- `@ai-sdk/deepseek` had no `reasoning_effort` field on its Zod options
schema, so even if the effort were forwarded the SDK would strip it from
the request body.
- `@ai-sdk/anthropic` silently omitted the `thinking` field when
thinking was turned off, preventing downstream providers that require an
explicit `{ type: 'disabled' }` from honoring the disable.

After this PR:

- Non-Anthropic Claude-endpoint models (Kimi, MiniMax, DeepSeek V4+,
etc.) receive `sendReasoning: true` so reasoning output is actually
streamed back.
- DeepSeek V4+ additionally receives `effort: 'max'` when the user picks
`xhigh`, otherwise `effort: 'high'`.
- `@ai-sdk/deepseek@2.0.29` is patched to accept `reasoning_effort` on
its language-model options schema and forward it into the request body.
- `@ai-sdk/anthropic` is patched to emit an explicit `thinking: { type:
'disabled' }` when thinking is disabled.
- Updated one existing `getAnthropicReasoningParams` unit test to assert
the new `sendReasoning: true` payload, and added a new V4+ reasoning
test suite.

Fixes #

### Why we need it and why it was done in this way

Follow-up to #14551, which introduced `isDeepSeekV4PlusModel` and the
`deepseek_v4` reasoning category but did not wire the selected effort
into the outgoing request for the Claude-compatible endpoint path.
Without this PR the `high` / `xhigh` options are cosmetic for V4+.

The following tradeoffs were made:

- Patched upstream SDKs (`@ai-sdk/deepseek`, `@ai-sdk/anthropic`)
instead of waiting for upstream releases, so the fix ships on `main`'s
code freeze window. Patches are narrow (single field additions).
- Kept all non-Anthropic Claude-endpoint models on `sendReasoning: true`
rather than gating per-provider — the field is harmless for providers
that don't emit reasoning and restores visibility for those that do.

The following alternatives were considered:

- Upstreaming the `reasoning_effort` change to `@ai-sdk/deepseek` —
rejected for timing; patch is mechanical and easy to drop once upstream
lands.
- Sending effort via a custom header — rejected; DeepSeek documents
`reasoning_effort` in the request body.

Links to places where the discussion took place:

### Breaking changes

None. The added fields (`sendReasoning`, `effort`, `reasoning_effort`)
are additive and only take effect for models already routed through the
Claude-compatible path with reasoning enabled.

### Special notes for your reviewer

- Two new patch files under `patches/` are registered in
`package.json#pnpm.patchedDependencies`; they are narrow dist-only
additions.
- The implementation change is localized to
`getAnthropicReasoningParams` in
`src/renderer/src/aiCore/utils/reasoning.ts`.
- Targeting `main` via `hotfix/*` branch per the branch-strategy rule,
since this restores intended V4+ behavior shipped in #14551 and contains
no refactoring.

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [x] Documentation: A user-guide update was considered and is present
(link) or not required. Check this only when the PR introduces or
changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code before requesting review
from others

### Release note

```release-note
Fix: DeepSeek V4+ reasoning effort (high / xhigh) is now actually forwarded to the API when the model is served via a Claude-compatible endpoint; reasoning output is also streamed back to the UI.
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 02:12:47 +08:00
fullex
5ec8696fd2 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-04-23 19:13:26 -07:00
SuYao
c0b3c880e3 hotfix(ai-sdk/openai): patch @ai-sdk/openai to support gpt-image-2 (#14488)
### What this PR does

Before this PR:

Calling the newly-released `gpt-image-2` model (shipped 2026-04-21) via
OpenAI image generation fails with `400 Unknown parameter:
'response_format'`. `@ai-sdk/openai@3.0.49` (our current AI SDK v6 line
dep) unconditionally sends `response_format: 'b64_json'` for any model
not in its `defaultResponseFormatPrefixes` allow-list, and `gpt-image-2`
is not in that list.

After this PR:

`@ai-sdk/openai@3.0.49` is patched to add `gpt-image-2` to both
`modelMaxImagesPerCall` and `defaultResponseFormatPrefixes` in all four
compiled dist entry points (`dist/index.{js,mjs}`,
`dist/internal/index.{js,mjs}`). This mirrors vercel/ai#14680, which was
backported to `release-v6.0` via vercel/ai#14682 on 2026-04-21 but has
not yet been published to npm. The patch is registered in
`pnpm.patchedDependencies` alongside the existing AI SDK patches.

Fixes #14485

### Why we need it and why it was done in this way

The upstream fix (vercel/ai#14680 / #14682) is already merged into the
`release-v6.0` branch, so a patch is a stable, low-risk equivalent of
the forthcoming `@ai-sdk/openai@3.0.54+`. Once that version ships on
npm, this patch can be dropped and replaced with a dependency bump.

The following tradeoffs were made:

- Patching compiled `dist/` files instead of source: matches the
repository's existing convention (see
`patches/@ai-sdk__google@3.0.55.patch`,
`patches/@ai-sdk__openai-compatible@2.0.37.patch`) and avoids rebuilding
the package.
- Not touching `.d.ts` type declarations: the upstream
`OpenAIImageModelId` union already accepts `(string & {})`, so runtime
behavior is the only thing that needs correcting.

The following alternatives were considered:

- Waiting for the npm release of `@ai-sdk/openai@3.0.54` — rejected
because users are actively hitting the bug today.
- Using a pnpm `overrides` entry pointing at the `release-v6.0` git
branch — rejected because it pulls an unversioned moving target and
conflicts with the locked semver range.
- Stripping `response_format` in an `aiCore` plugin — rejected because
the fix belongs at the provider layer and a plugin would permanently
mask similar issues for other models.

Links to places where the discussion took place: vercel/ai#14680,
vercel/ai#14682

### Breaking changes

None.

### Special notes for your reviewer

- The patch adds `gpt-image-2` at the expected positions in each of the
four dist files; diff is small and mechanical. Verified locally:
`node_modules/@ai-sdk/openai/dist/index.js:1753,1761` now contain
`gpt-image-2` after `pnpm install`.
- UI model picker changes are intentionally out of scope. Users select
`gpt-image-2` by model ID today; once upstream publishes, a follow-up
can refresh `src/renderer/src/config/models/default.ts` and friends.

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others

### Release note

```release-note
fix(ai-sdk/openai): patch @ai-sdk/openai to support OpenAI's gpt-image-2 model, resolving "Unknown parameter: 'response_format'" errors.
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
2026-04-22 23:29:50 +08:00
fullex
8f9bf0b516 fix(data): patch @libsql/client to replay PRAGMAs after transaction()
`Sqlite3Client.transaction()` nullifies its internal connection
(`this.#db = null`), causing the next operation to create a new
connection with default PRAGMAs. This resets `synchronous` from
NORMAL back to FULL — roughly 2x write performance degradation.

Patch `@libsql/client@0.15.15` to add `setPragma()` which registers
per-connection PRAGMAs and replays them in `#getDb()` and `reconnect()`
whenever a new connection is created. Pattern borrowed from upstream
PR #328's ATTACH replay mechanism.

Update DbService and MigrationDbService to use `createClient()` +
`setPragma()` instead of `db.run(sql\`PRAGMA ...\`)` for per-connection
settings.

Upstream issues (still open, no official fix):
- tursodatabase/libsql-client-ts#229
- tursodatabase/libsql-client-ts#288

Signed-off-by: fullex <0xfullex@gmail.com>
2026-04-10 08:21:49 -07:00
suyao
6b14fcd5ce refactor: bump AI SDK deps and fix provider API host formatting
- Bump @ai-sdk/* packages to latest versions and update patches
- Fix newapi provider: defer API version suffix to build phase so gemini
  endpoints get /v1beta instead of /v1
- Fix Azure provider: split host formatting so azure-anthropic (Claude)
  endpoints don't get the /openai suffix meant for Azure OpenAI
- Re-add @ai-sdk/google getModelPath patch (includes("models/") check)
- Support azure-openai provider type in Claude Code agent service by
  auto-constructing the /anthropic base URL for Claude models

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-04-03 14:18:02 +08:00
SuYao
a58bbf52fd refactor: migrate to ai sdk v6 Phase 3 (#12235)
Continued from #12227

## Summary

Phase 3 of AI SDK v6 migration:

- **Image generation**: Migrate to native AI SDK
`generateImage`/`editImage`, remove legacy image middleware
- **Embedding**: Migrate to AI SDK `embedMany`, remove legacy embedding
clients
- **Model listing**: Refactor `ModelListService` to Strategy Registry
pattern (`listModels.ts`), consolidate 7 schema files into one
`schemas.ts`
- **OpenRouter image**: Bump `@openrouter/ai-sdk-provider` to 2.3.3 with
native image endpoint support, remove `isNativeImageGenerationProvider`
guard
- **GitHub Copilot**: Simplify extension by removing `ProviderV2` cast
and `wrapProvider`
- **Legacy removal**: Delete all legacy API clients, middleware
pipeline, and barrel `index.ts`
- **Rename**: `index_new.ts` → `AiProvider.ts`, `ModelListService.ts` →
`listModels.ts`

## Manual Test Plan

### P0 — Core paths + PR change focus

#### 1. Core Chat
- [ ] OpenAI model (e.g. GPT-4o): send text, verify streaming output
- [ ] Anthropic model (e.g. Claude Sonnet): verify chat works
- [ ] Gemini model: verify chat works
- [ ] DeepSeek model: verify chat works
- [ ] Reasoning mode (o3-mini, DeepSeek R1): verify thinking process
displays
- [ ] Send message with image (multimodal): verify model recognizes
image
- [ ] Abort mid-stream: verify clean termination, no errors

#### 2. Image Generation (key change area)
- [ ] DALL-E 3 / GPT-Image-1: verify image generation works
- [ ] OpenRouter image model: verify **native image endpoint** is used
(no longer chat completions)
- [ ] Image editing: upload image + text prompt, verify editImage path
- [ ] Verify generated images display correctly (both base64 and URL
formats)

#### 3. Model Listing (refactored area)
- [ ] Sync OpenAI models: verify names and groups
- [ ] Sync Gemini models: verify `models/` prefix stripped
- [ ] Sync Ollama models (local): verify display
- [ ] Sync OpenRouter models: verify chat + embedding models both appear
- [ ] Sync SiliconFlow models: verify grouping (e.g. `deepseek-ai/`)
- [ ] Sync GitHub Models
- [ ] Sync Together models
- [ ] Sync NewAPI service (e.g. CherryIn)
- [ ] Sync PPIO models: verify chat + embedding + reranker endpoints
merged

### P1 — Affected by refactor

#### 4. Provider Extensions
- [ ] GitHub Copilot: verify chat works (simplified wrapProvider logic)
- [ ] Ollama: verify chat works
- [ ] Vertex AI / Bedrock: verify chat works (if configured)

#### 5. MCP Tool Calling
- [ ] Enable MCP server, send tool-requiring message, verify tool
execution
- [ ] Verify both prompt tool use and function calling modes

#### 6. Auxiliary Functions
- [ ] Auto topic title generation (fetchMessagesSummary)
- [ ] Note summary (fetchNoteSummary)
- [ ] Translation/generation (fetchGenerate)
- [ ] API check (click "Check" button in settings)

### P2 — Indirect impact

#### 7. Knowledge Base
- [ ] Create knowledge base, associate with assistant, verify RAG
retrieval and embedding

#### 8. Web Search
- [ ] Enable native web search (Gemini/Perplexity), verify search
results in response

#### 9. Tracing
- [ ] Enable developer mode, send message, verify trace spans recorded
and displayed

---------

Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: icarus <eurfelux@gmail.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-04-03 14:18:02 +08:00
suyao
f990e200a7 refactor: bump AI SDK deps and fix provider API host formatting
- Bump @ai-sdk/* packages to latest versions and update patches
- Fix newapi provider: defer API version suffix to build phase so gemini
  endpoints get /v1beta instead of /v1
- Fix Azure provider: split host formatting so azure-anthropic (Claude)
  endpoints don't get the /openai suffix meant for Azure OpenAI
- Re-add @ai-sdk/google getModelPath patch (includes("models/") check)
- Support azure-openai provider type in Claude Code agent service by
  auto-constructing the /anthropic base URL for Claude models

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: suyao <sy20010504@gmail.com>
2026-04-02 20:29:47 +08:00
SuYao
1c0a5a95fa refactor: migrate to ai sdk v6 Phase 3 (#12235)
Continued from #12227

## Summary

Phase 3 of AI SDK v6 migration:

- **Image generation**: Migrate to native AI SDK
`generateImage`/`editImage`, remove legacy image middleware
- **Embedding**: Migrate to AI SDK `embedMany`, remove legacy embedding
clients
- **Model listing**: Refactor `ModelListService` to Strategy Registry
pattern (`listModels.ts`), consolidate 7 schema files into one
`schemas.ts`
- **OpenRouter image**: Bump `@openrouter/ai-sdk-provider` to 2.3.3 with
native image endpoint support, remove `isNativeImageGenerationProvider`
guard
- **GitHub Copilot**: Simplify extension by removing `ProviderV2` cast
and `wrapProvider`
- **Legacy removal**: Delete all legacy API clients, middleware
pipeline, and barrel `index.ts`
- **Rename**: `index_new.ts` → `AiProvider.ts`, `ModelListService.ts` →
`listModels.ts`

## Manual Test Plan

### P0 — Core paths + PR change focus

#### 1. Core Chat
- [ ] OpenAI model (e.g. GPT-4o): send text, verify streaming output
- [ ] Anthropic model (e.g. Claude Sonnet): verify chat works
- [ ] Gemini model: verify chat works
- [ ] DeepSeek model: verify chat works
- [ ] Reasoning mode (o3-mini, DeepSeek R1): verify thinking process
displays
- [ ] Send message with image (multimodal): verify model recognizes
image
- [ ] Abort mid-stream: verify clean termination, no errors

#### 2. Image Generation (key change area)
- [ ] DALL-E 3 / GPT-Image-1: verify image generation works
- [ ] OpenRouter image model: verify **native image endpoint** is used
(no longer chat completions)
- [ ] Image editing: upload image + text prompt, verify editImage path
- [ ] Verify generated images display correctly (both base64 and URL
formats)

#### 3. Model Listing (refactored area)
- [ ] Sync OpenAI models: verify names and groups
- [ ] Sync Gemini models: verify `models/` prefix stripped
- [ ] Sync Ollama models (local): verify display
- [ ] Sync OpenRouter models: verify chat + embedding models both appear
- [ ] Sync SiliconFlow models: verify grouping (e.g. `deepseek-ai/`)
- [ ] Sync GitHub Models
- [ ] Sync Together models
- [ ] Sync NewAPI service (e.g. CherryIn)
- [ ] Sync PPIO models: verify chat + embedding + reranker endpoints
merged

### P1 — Affected by refactor

#### 4. Provider Extensions
- [ ] GitHub Copilot: verify chat works (simplified wrapProvider logic)
- [ ] Ollama: verify chat works
- [ ] Vertex AI / Bedrock: verify chat works (if configured)

#### 5. MCP Tool Calling
- [ ] Enable MCP server, send tool-requiring message, verify tool
execution
- [ ] Verify both prompt tool use and function calling modes

#### 6. Auxiliary Functions
- [ ] Auto topic title generation (fetchMessagesSummary)
- [ ] Note summary (fetchNoteSummary)
- [ ] Translation/generation (fetchGenerate)
- [ ] API check (click "Check" button in settings)

### P2 — Indirect impact

#### 7. Knowledge Base
- [ ] Create knowledge base, associate with assistant, verify RAG
retrieval and embedding

#### 8. Web Search
- [ ] Enable native web search (Gemini/Perplexity), verify search
results in response

#### 9. Tracing
- [ ] Enable developer mode, send message, verify trace spans recorded
and displayed

---------

Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: icarus <eurfelux@gmail.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-04-02 15:38:23 +08:00
SuYao
adc1c27221 fix(models): strip models/ prefix from Google API model IDs (#13861)
### What this PR does

Before this PR:
Google API returns model IDs with a `models/` prefix (e.g.
`models/gemini-flash-latest`). This prefix was stored as-is and passed
to `@ai-sdk/google`. The SDK's `prepareTools` function uses strict
equality to check model names against an unprefixed allowlist, so it
failed to recognize the model as Gemini 2+ and routed web search to the
deprecated `google_search_retrieval` API, causing the error:
`google_search_retrieval is not supported. Please use google_search tool
instead.`

After this PR:
The `models/` prefix is stripped at the model adapter layer
(`adaptSdkModel`), so all downstream consumers receive consistent
unprefixed model IDs. Web search is correctly routed to the
`google_search` API.

### Why we need it and why it was done in this way

The fix is applied at the `ModelAdapter` layer because it is the single
entry point where SDK model responses are normalized into the app's
`Model` type. This ensures all consumers (SDK tool routing, app-level
model detection functions like `isGemini3FlashModel`) work with
consistent IDs without needing per-consumer workarounds.

The following alternatives were considered:
- Patching `@ai-sdk/google`'s `prepareTools` to handle the prefix —
rejected because it's better to normalize data at ingestion rather than
patching every consumer.

### Breaking changes

None.

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [ ] Upgrade: N/A
- [ ] Documentation: Not required (internal bug fix)
- [x] Self-review: I have reviewed my own code before requesting review
from others

### Release note

```release-note
Fix Google Gemini web search failing with "google_search_retrieval is not supported" error for models fetched from Google API (e.g. gemini-flash-latest).
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-28 18:35:23 +08:00
Konv Suu
65271f386e fix: route copilot gpt-5.4 models to responses (#13632) 2026-03-20 10:05:05 +08:00
LiuVaayne
781e04145c chore: upgrade @anthropic-ai/claude-agent-sdk from 0.2.56 to 0.2.71 (#13339)
### What this PR does

Before this PR:

`@anthropic-ai/claude-agent-sdk` was pinned at version 0.2.56.

After this PR:

Upgraded to 0.2.71. The postinstall regex patch (spawn→fork for IPC)
applies successfully on the new version (3/3 patches matched). Also
fixed `cli.js` resolution since the new version removed `./cli.js` from
its `exports` field.

### Why we need it and why it was done in this way

Keep the SDK up to date with the latest bug fixes and improvements from
Anthropic.

The following tradeoffs were made: N/A

The following alternatives were considered: N/A

### Breaking changes

None. The SDK's Node engine requirement (≥18) is compatible with the
project. The `cli.js` file still exists in the package — only the
`exports` mapping was removed, so the resolution path was updated to use
`path.join(path.dirname(require.resolve(...)), 'cli.js')`.

### Special notes for your reviewer

- The postinstall script (`scripts/patch-claude-agent-sdk.ts`) applies 3
regex patches to `sdk.mjs`. All 3 matched successfully on version
0.2.71.
- `cli.js` resolution in `ClaudeCodeService` constructor was updated
since the new SDK version no longer lists `./cli.js` in its package.json
`exports` field.

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: Not required — no user-facing feature or behavior
change
- [x] Self-review: I have reviewed my own code before requesting review
from others

### Release note

```release-note
NONE
```

---------

Signed-off-by: Vaayne <liu.vaayne@gmail.com>
2026-03-09 23:37:24 +08:00
SuYao
e72bde30eb refactor: replace static pnpm patch with postinstall script for claude-agent-sdk (#13139)
### What this PR does

Before this PR:
`claude-agent-sdk` is patched via a static pnpm `.patch` file that
replaces entire minified lines. This breaks every time the SDK is
upgraded because obfuscated variable names change with each
minification.

After this PR:
A Node.js postinstall script (`scripts/patch-claude-agent-sdk.mjs`) uses
semantic regex patterns to apply the same 3 patches. Since it matches
structural patterns (not variable names), it survives SDK version bumps
as long as the code structure remains the same.

### Why we need it and why it was done in this way

The following tradeoffs were made:
- Regex-based patching is slightly less precise than a static `.patch`
file, but far more resilient to minified code changes.
- The script validates all 3 patches applied and exits with error if
patterns don't match, so SDK structure changes are caught immediately.

The following alternatives were considered:
- Keeping the pnpm patch approach — rejected because it requires manual
regeneration on every SDK upgrade.
- Using AST-based patching — rejected as overkill for 3 targeted
replacements in minified code.

### Breaking changes

None. The same 3 modifications are applied (spawn→fork, remove command
destructuring, IPC stdio), just via a different mechanism.

### Special notes for your reviewer

The 3 patches applied by the script:
1. `import{spawn as X}` → `import{fork as X}` — enables IPC channel
2. Remove `command:VAR,` from `spawnLocalProcess` destructuring
3. Rewrite spawn call to `fork(args[0], args.slice(1), ...)` with IPC
stdio, removing `windowsHide:!0`

43 unit tests cover: variable name variations, idempotency, partial
matches, and no-match detection.

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [ ] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: Not required — internal build tooling change
- [x] Self-review: I have reviewed my own code before requesting review
from others

### Release note

```release-note
NONE
```

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 01:23:49 +08:00
Pleasure1234
a9656674ff fix: upgrade ollama provider to 3.3.1 (#13085)
<!-- Template from
https://github.com/kubevirt/kubevirt/blob/main/.github/PULL_REQUEST_TEMPLATE.md?-->
<!--  Thanks for sending a pull request!  Here are some tips for you:
1. Consider creating this PR as draft:
https://github.com/CherryHQ/cherry-studio/blob/main/CONTRIBUTING.md
-->

<!--

⚠️ Important: Redux/IndexedDB Data-Changing Feature PRs Temporarily On
Hold ⚠️

Please note: For our current development cycle, we are not accepting
feature Pull Requests that introduce changes to Redux data models or
IndexedDB schemas.

While we value your contributions, PRs of this nature will be blocked
without merge. We welcome all other contributions (bug fixes, perf
enhancements, docs, etc.). Thank you!

Once version 2.0.0 is released, we will resume reviewing feature PRs.

-->

### What this PR does

Before this PR:

After this PR:

<!-- (optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)`
format, will close the issue(s) when PR gets merged)*: -->

continue #12526 

Fix #11612 Fix #12642 Fix #13083

### Why we need it and why it was done in this way

The following tradeoffs were made:

Bump ollama-ai-provider-v2 from 1.5.5 to 3.3.1 and update its patch
filename. Update pnpm lock entries for the new provider version and
related provider deps. Adjust compiled dist files to expose ollama
provider option types and add support for the expanded "think" option
(boolean | 'low' | 'medium' | 'high'). Add a new
ollamaReasoningOrderMiddleware to reorder reasoning stream parts ahead
of text/tool parts and wire it into AiSdkMiddlewareBuilder when
reasoning is enabled. Update options builder to use
OllamaProviderOptions and map assistant reasoning_effort (including
explicitly disabling thinking when reasoning is off).

The following alternatives were considered:

Links to places where the discussion took place: <!-- optional: slack,
other GH issue, mailinglist, ... -->

### Breaking changes

<!-- optional -->

If this PR introduces breaking changes, please describe the changes and
the impact on users.

### Special notes for your reviewer

<!-- optional -->

### Checklist

This checklist is not enforcing, but it's a reminder of items that could
be relevant to every PR.
Approvers are expected to review this list.

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [ ] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [x] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others

### Release note

<!--  Write your release note:
1. Enter your extended release note in the below block. If the PR
requires additional action from users switching to the new release,
include the string "action required".
2. If no release note is required, just write "NONE".
3. Only include user-facing changes (new features, bug fixes visible to
users, UI changes, behavior changes). For CI, maintenance, internal
refactoring, build tooling, or other non-user-facing work, write "NONE".
-->

```release-note
fix(ollama): reasoning order
```

---------

Co-authored-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 22:52:46 +08:00
SuYao
842ccf0272 refactor: migrate to aisdk v6 Phase 1 (#12078)
<!-- Template from
https://github.com/kubevirt/kubevirt/blob/main/.github/PULL_REQUEST_TEMPLATE.md?-->
<!--  Thanks for sending a pull request!  Here are some tips for you:
1. Consider creating this PR as draft:
https://github.com/CherryHQ/cherry-studio/blob/main/CONTRIBUTING.md
-->

<!--

⚠️ Important: Redux/IndexedDB Data-Changing Feature PRs Temporarily On
Hold ⚠️

Please note: For our current development cycle, we are not accepting
feature Pull Requests that introduce changes to Redux data models or
IndexedDB schemas.

While we value your contributions, PRs of this nature will be blocked
without merge. We welcome all other contributions (bug fixes, perf
enhancements, docs, etc.). Thank you!

Once version 2.0.0 is released, we will resume reviewing feature PRs.

-->

### What this PR does

regular upgrade

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: icarus <eurfelux@gmail.com>
2026-02-27 14:25:40 +08:00
Pleasure1234
ef27726fa1 chore(deps): fix security vulnerabilities in edge dependencies (#13054)
- fast-xml-parser: ^5.2.0 → ^5.3.5 (critical, entity encoding bypass)
- tar: ^7.4.3 → ^7.5.9 (high, path traversal via hardlink)
- diff: ^8.0.2 → ^8.0.3 (low, ReDoS in parsePatch/applyPatch)
- markdown-it: ^14.1.0 → ^14.1.1 (moderate, ReDoS)
- add pnpm overrides for tar@7.5.9 and fast-xml-parser@5.4.1 to patch
transitive deps

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: icarus <eurfelux@gmail.com>
2026-02-26 17:52:47 +08:00
SuYao
a734a74b6f chore(deps): bump @anthropic-ai/claude-agent-sdk from 0.1.76 to 0.2.56 (#13044)
### What this PR does

Before this PR:
`@anthropic-ai/claude-agent-sdk` was pinned at v0.1.76 with a patch to
replace `spawn` with `fork` for IPC support.

After this PR:
`@anthropic-ai/claude-agent-sdk` is upgraded to v0.2.56 with the same
`spawn→fork` patch regenerated for the new version.

### Why we need it and why it was done in this way

The following tradeoffs were made:
N/A

The following alternatives were considered:
N/A

fix this problem via bump:
https://github.com/anthropics/claude-code/issues/8430

### Breaking changes

None. The patch applies the same `spawn→fork` transformation as before,
just targeting the updated minified code in v0.2.56.

### Special notes for your reviewer

- The old patch file
`patches/@anthropic-ai__claude-agent-sdk@0.1.76.patch` is no longer
referenced but was not deleted (pnpm removed the reference
automatically).
- The new patch `patches/@anthropic-ai__claude-agent-sdk.patch` is large
in bytes because it diffs minified single-line JS, but the logical
change is small (spawn→fork, add IPC stdio, remove windowsHide).

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: Not required

### Release note

```release-note
NONE
```

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 10:32:35 +08:00
Phantom
486ed0f148 fix: handle Gemini OpenAI-compatible thought signatures and missing tool_call index (#12769)
* fix: Handle missing providerOptions in Gemini thought signature skip

* fix: Update @ai-sdk/openai-compatible patch for tool call schema

Add support for reasoning_content field and make tool call index
optional with default value

* fix: add thought_signature support for tool-call parts in OpenAI-compatible path

- Add PartWithProviderOptions interface for type safety
- Handle tool-call parts that need thought_signature for Gemini OpenAI-compatible API
- When a message has thinking indicators, add extra_content.google.thought_signature
to all tool-call parts for the OpenAI-compatible path
- Reference: https://ai.google.dev/gemini-api/docs/thought-signatures#openai

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: Skip Gemini thought signature for all tool calls

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:55:33 +08:00
槑囿脑袋
5e2bdf4591 fix: correct openai-compatible strictJsonSchema patch (#12762) 2026-02-07 13:49:39 +08:00
SuYao
c7c380d706 fix: disable strict JSON schema for OpenRouter to support MCP tools (#12415)
* fix: update dependencies and patch files for strict JSON schema compliance

- Updated `@ai-sdk/openai-compatible` to include version 1.0.30 and adjusted related patch files.
- Removed obsolete patch for `@ai-sdk/openai-compatible@1.0.28`.
- Added new patch for `@openrouter/ai-sdk-provider` to support strict JSON schema options.
- Modified `options.ts` to set `strictJsonSchema` to false for OpenAI models.
- Enhanced OpenAI compatible provider options to include `sendReasoning` and `strictJsonSchema`.
- Updated lockfile to reflect changes in patched dependencies and their hashes.

* fix: filter strictJsonSchema from request body in OpenRouter patch

- Destructure and remove strictJsonSchema from openrouterOptions before spreading into request body
- This prevents sending the internal option to the OpenRouter API

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 21:55:09 +08:00
defi-failure
9b8420f9b9 fix: restore patch for claude-agent-sdk (#12391)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 16:26:39 +08:00
LiuVaayne
ed3401a016 ⬆️ chore(deps): upgrade @anthropic-ai/claude-agent-sdk to 0.1.76 (#12317)
- Upgrade from 0.1.62 to 0.1.76 (latest stable)
- Remove version-specific patch (no longer needed)
2026-01-07 14:48:27 +08:00
George·Dong
2a31fa2ad5 refactor: switch yarn to pnpm (#12260)
* refactor: switch workflows from yarn to pnpm

Replace Yarn usage with pnpm in CI workflows to standardize package
management and leverage pnpm's store/cache behavior.

- Use pnpm/action-setup to install pnpm (v) instead of enabling corepack
  and preparing Yarn.
- Retrieve pnpm store path and update cache actions to cache the pnpm
  store and use pnpm-lock.yaml for cache keys and restores.
- Replace yarn commands with pnpm equivalents across workflows:
  install, i18n:sync/translate, format, build:* and tsx invocation.
- Avoid committing lockfile changes by resetting pnpm-lock.yaml instead
  of yarn.lock when checking for changes.
- Update install flags: use pnpm install --frozen-lockfile / --install
  semantics where appropriate.

These changes unify dependency tooling, improve caching correctness,
and ensure CI uses pnpm-specific lockfile and cache paths.

* build: switch pre-commit hook to pnpm lint-staged

Update .husky/pre-commit to run pnpm lint-staged instead of yarn.
This aligns the pre-commit hook with the project's package manager
and ensures lint-staged runs using pnpm's environment and caching.

* chore(ci): remove pinned pnpm version from GH Action steps

Remove the explicit `with: version: 9` lines from multiple GitHub Actions workflows
(auto-i18n.yml, nightly-build.yml, pr-ci.yml, update-app-upgrade-config.yml,
sync-to-gitcode.yml, release.yml). The workflows still call `pnpm/action-setup@v4`
but no longer hardcode a pnpm version.

This simplifies maintenance and allows the action to resolve an appropriate pnpm
version (or use its default) without needing updates whenever the pinned
version becomes outdated. It reduces churn when bumping pnpm across CI configs
and prevents accidental pin drift between workflow files.

* build: Update pnpm to 10.27.0 and add onlyBuiltDependencies config

* Update @cherrystudio/openai to 6.15.0 and consolidate overrides

* Add @langchain/core to overrides

* Add override for openai-compatible 1.0.27

* build: optimize pnpm config and add missing dependencies

- Comment out shamefully-hoist in .npmrc for better pnpm compatibility
- Add React-related packages to optimizeDeps in electron.vite.config.ts
- Add missing peer dependencies and packages that were previously hoisted

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* build: refine pnpm configuration and dependency management

- Simplify .npmrc to only essential electron mirror config
- Move platform-specific dependencies to devDependencies
- Pin sharp version to 0.34.3 for consistency
- Update sharp-libvips versions to 1.2.4

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* reduce app size

* format

* build: remove unnecessary disableOxcRecommendation option from react plugin configuration

* docs: Replace yarn commands with pnpm in documentation and scripts

* Revert "build: optimize pnpm config and add missing dependencies"

This reverts commit acffad31f8.

* build: import dependencies from yarn.lock

* build: Add some phantom dependencies and reorganize dependencies

* build: Keep consistent by removing types of semver

It's not in the previous package.json

* build: Add some phantom dependencies

Keep same version with yarn.lock

* build: Add form-data dependency version 4.0.4

* Add chalk dependency

* build: downgrade some dependencies

Reference: .yarn-state-copy.yml. These phantom dependencies should use top-level package of that version in node_modules

* build: Add phantom dependencies

* build: pin tiptap dependencies to exact versions

Ensure consistent dependency resolution by removing caret ranges and pinning all @tiptap packages to exact version 3.2.0

* chore: pin embedjs dependencies to exact versions

* build: pin @modelcontextprotocol/sdk to exact version 1.23.0

Remove caret from version specifier to prevent automatic upgrades and ensure consistent dependencies

* chore: update @types/node dependency to 22.17.2

Update package.json and pnpm-lock.yaml to use @types/node version 22.17.2 instead of 22.19.3 to maintain consistency across dependencies

* build: move some dependencies to dev deps and pin dependency versions to exact numbers

Remove caret (^) from version ranges to ensure consistent dependency resolution across environments

* chore: move dependencies from prod to dev and update lockfile

Move @ant-design/icons, chalk, form-data, and open from dependencies to devDependencies
Update pnpm-lock.yaml to reflect dependency changes

* build: update package dependencies

- Add new dependencies: md5, @libsql/win32-x64-msvc, @strongtz/win32-arm64-msvc, bonjour-service, emoji-picker-element-data, gray-matter, js-yaml
- Remove redundant dependencies from devDependencies

* build: add cors, katex and pako dependencies

add new dependencies to support cross-origin requests, mathematical notation rendering and data compression

* move some js deps to dev deps

* test: update snapshot tests for Spinner and InputEmbeddingDimension

* chore: exclude .zed directory from biome formatting

* Update @ai-sdk/openai-compatible patch hash

* chore: update @kangfenmao/keyv-storage to version 0.1.3 in package.json and pnpm-lock.yaml

---------

Co-authored-by: icarus <eurfelux@gmail.com>
Co-authored-by: beyondkmp <beyondkmp@gmail.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: kangfenmao <kangfenmao@qq.com>
2026-01-05 22:16:34 +08:00