Commit Graph

81 Commits

Author SHA1 Message Date
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
16ebe2443c feat(ai-provider): route provider HTTP through proxy-aware net.fetch (#16207)
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-21 18:11:47 +08:00
xianzuyang9-blip
cdeaf05af0 fix(ai-core): align package exports with tsdown output (#15830)
Co-authored-by: SuYao <sy20010504@gmail.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-06-09 18:01:37 +08:00
槑囿脑袋
67554c5703 feat(ai-service): add rerank runtime support (#15542)
Co-authored-by: 亢奋猫 <kangfenmao@qq.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
Signed-off-by: eeee0717 <chentao020717Work@outlook.com>
2026-06-06 17:33:18 +08:00
SuYao
5706307451 refactor(ai-service): consolidate AI runtime to main process (#14911)
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: suyao <sy20010504@gmail.com>
2026-06-05 00:06:51 +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
8fe0d6448a refactor(dead-code): remove orphaned modules and components after v2 migration
Remove 75 dead files left behind by v2 refactors that replaced their
implementations but did not delete the originals. All deletions verified
by pnpm typecheck (0 errors) and pnpm test (670/670 files, 9416 passed).

Whole-feature removals:
- pages/onboarding/* (6 files): superseded by new onboarding flow
- components/Popups/ApiKeyListPopup/* (6 files): replaced by v2
  ProviderApiKeyListDrawer
- components/Sortable/* (8 files): replaced by packages/ui composites
  Sortable (#14940 antd/styled-components migration)
- components/RichEditor/.../dragContextMenu/* (12 files): notes module
  drag-context-menu feature removed
- components/HealthStatusIndicator/* (4 files): consumers removed in
  d15e15e1f v1 provider/model hooks retire

Cross-cutting cleanup:
- Settings page residuals from provider-settings v2 migration (#14631)
- Message component residuals: MessageImage, MessageSelect,
  NewTopicButton, PermissionModeDisplay, SectionName
- AgentSettings Tasks: TaskListItem, TaskLogsModal (per 6f37603d6)
- Legacy UI wrappers obsoleted by @cherrystudio/ui migration:
  ConfirmDialog, PopoverConfirm, CustomCollapse, Ellipsis,
  ModelIdWithTags (x2), ModelSelectButton, Tags/{Error,Success,Warn}Tag,
  TableActionMenu, RichEditPopup, VideoPopup, OpenaiAlert
- Built-in tools removed: tools/{index,think}.ts (per eff583abb)
- Legacy aiCore layer plugin: reasoningTimePlugin (per 188f25478)
- Main process leftovers: proxy/bootstrap, PreprocessingService,
  createStreamAbortController, IBaseService
- Misc fossils: utils/stream (Windows7-era), base-transformer,
  model-test-utils, endpointTypes, files/ContentView,
  mini-apps/MiniAppFullPageView
2026-05-22 08:45:28 -07:00
fullex
16f120bdd3 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-05-08 00:27:46 -07:00
SuYao
1f867749b8 fix(anthropic): support Claude Opus 4.7 (#14349)
### What this PR does

Before this PR:
- Selecting Claude Opus 4.7 (`claude-opus-4-7`) in Cherry Studio could
not work:
- The model is not in the catalog, so users could only add it manually
as a custom model.
- With reasoning enabled, Cherry would send `effort: 'max'` (4.6
mapping) instead of the native `xhigh` that 4.7 supports, and
`thinking.display` would default to `omitted` — stripping reasoning text
from the response and breaking Cherry's thinking UI.
- Temperature and top_p were still sent when `reasoning_effort` was
`default` or `none`, which Opus 4.7 rejects with HTTP 400 regardless of
reasoning settings.
- `getMaxTokens` subtracted a thinking budget for 4.6 / 4.7 (both use
adaptive thinking and do not send `budgetTokens`), incorrectly shrinking
`max_tokens`.

After this PR:
- `claude-opus-4-7` is catalogued under the Anthropic provider with a
128K output-token limit, routed through the existing `claude46`
reasoning-effort type so it shares the `[low, medium, high, xhigh]`
option list.
- Opus 4.7 sends native `xhigh` to Anthropic (Opus 4.6 still sends
`max`). Bedrock continues to map `xhigh → 'max'` until
`@ai-sdk/amazon-bedrock` adds `xhigh`.
- Adaptive thinking defaults to `display: 'summarized'` on Opus 4.7, so
reasoning text continues to stream back for Cherry's UI.
- `temperature` and `top_p` are dropped unconditionally for Opus 4.7 in
`getTemperature` / `getTopP`.
- `getMaxTokens` skips the budget subtraction for both 4.6 and 4.7
(shared adaptive-thinking path).
- At the agent-session dispatch site, `effort: 'xhigh'` is mapped to
`'max'` and the `display` field is stripped before reaching the Claude
Agent SDK (whose types do not yet include them).

Fixes #

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

The following tradeoffs were made:
- Opus 4.7 shares the `claude46` thinking model type (same effort
options) instead of introducing a new `claude47` enum member. This
avoids churn in `ThinkingModelType` / `MODEL_SUPPORTED_OPTIONS`, and the
provider-boundary mapping (xhigh → native on 4.7, xhigh → max on 4.6)
cleanly expresses the only real difference.
- `thinking.display` is defaulted to `'summarized'` so existing Cherry
behavior (reasoning text streamed to the UI) is preserved. The Anthropic
API default is `'omitted'`, which would silently remove reasoning
content.
- `getMaxTokens` fix for 4.6 is applied alongside 4.7 because the same
code path is touched. This is in scope for the hotfix — the 4.7 path
cannot work correctly without it.
- The agent-session call site performs a local narrowing (`xhigh →
'max'`, strip `display`) rather than extending `AgentEffort` /
`AgentThinkingConfig` schemas. This keeps the change small and
compatible with the currently installed `@anthropic-ai/claude-agent-sdk`
type shape.

The following alternatives were considered:
- Introducing a new `claude47` `ThinkingModelType` variant and dedicated
option lists. Rejected — the effort list is identical to 4.6; a new
variant would duplicate data without adding behavior.
- Wiring `taskBudget` support (the agentic-workflow token budget
introduced in the same Vercel AI SDK PR). Intentionally out of scope —
Cherry has no UI or call site that would supply one, and it is not a
hotfix-class concern.
- Extending `AgentEffortSchema` and `AgentThinkingConfigSchema`
end-to-end. Rejected — the Claude Agent SDK still types `effort` as
`'low' | 'medium' | 'high' | 'max'` and `ThinkingAdaptive` as `{ type:
'adaptive' }`, so the schema widening would have to be undone at the SDK
boundary anyway.

Links to places where the discussion took place:
https://github.com/vercel/ai/pull/14529

### Breaking changes

None. Existing Claude 4.6 and earlier Claude models are unchanged.

### Special notes for your reviewer

- Targeted at `main` as a hotfix per the code-freeze policy. The same
fix should probably land on `v2` as well after this merges, but that is
a separate PR.
- `@ai-sdk/anthropic` is bumped to `^3.0.71` (minimum version that
exposes the Opus 4.7 / `xhigh` / `display` / `taskBudget` types). The
lockfile resolves to `3.0.71`. No other `@ai-sdk/*` packages are
touched.
- Added tests:
- `src/renderer/src/config/models/__tests__/utils.test.ts` —
`isClaude47SeriesModel` detection across direct API / Bedrock / Vertex
formats.
- `src/renderer/src/config/models/__tests__/reasoning.test.ts` —
`findTokenLimit` returns 128K for 4.7, and `getThinkModelType` routes
4.7 to `claude46`.
- `src/renderer/src/aiCore/utils/__tests__/reasoning.test.ts` —
`getAnthropicReasoningParams` returns `{ thinking: { type: 'adaptive',
display: 'summarized' }, effort: 'xhigh' }` for Opus 4.7 + xhigh, and
the `display` field is present even when no effort is set.
-
`src/renderer/src/aiCore/prepareParams/__tests__/model-parameters.test.ts`
— `getTemperature` / `getTopP` return `undefined` for Opus 4.7
regardless of reasoning settings.
- `pnpm lint` and `pnpm test` pass locally (3488 passed | 72 skipped).
One pre-existing Shiki tokenizer test is flaky under full-suite ordering
but passes in isolation and on clean `main`; unrelated to this change.

### 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

```release-note
Add support for Claude Opus 4.7 (`claude-opus-4-7`), including native `xhigh` reasoning effort, adaptive thinking with summarized display (so reasoning text continues to stream to the UI), and the new API requirement that `temperature` / `top_p` be omitted.
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
2026-05-07 13:27:56 +08:00
fullex
1afd70b372 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-05-03 00:11:34 -07: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
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
e3ab9704b4 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-04-11 04:40:00 -07:00
github-actions[bot]
668ed35429 chore: version packages (#14154)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @cherrystudio/ai-core@2.0.1

### Patch Changes

- [#14087](https://github.com/CherryHQ/cherry-studio/pull/14087)
[`1f72f98`](1f72f98905)
Thanks [@DeJeune](https://github.com/DeJeune)! - fix(providers):
azure-anthropic variant uses correct Anthropic toolFactories for web
search

- Add `TOutput` generic to `ProviderVariant` so `transform` output type
flows to `toolFactories` and `resolveModel`
- Add Anthropic-specific `toolFactories` to `azure-anthropic` variant
(fixes `provider.tools.webSearchPreview is not a function`)
- Fix `urlContext` factory incorrectly mapping to `webSearch` tool key
instead of `urlContext`
- Fix `BedrockExtension` `satisfies` type to use `AmazonBedrockProvider`
instead of `ProviderV3`

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-11 15:15:45 +08:00
fullex
6541948556 Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 2026-04-09 23:23:32 -07:00
SuYao
1f72f98905 fix(providers): azure-anthropic web search uses correct Anthropic toolFactories (#14087)
### What this PR does

Before this PR:

Using web search with the `azure-anthropic` variant throws
`provider.tools.webSearchPreview is not a function` because it falls
back to the Azure base extension's `toolFactories`, which calls
`webSearchPreview` — a method that doesn't exist on `AnthropicProvider`.

Additionally, the `urlContext` tool factory for Anthropic incorrectly
maps `webFetch` to the `webSearch` tool key instead of `urlContext`.

After this PR:

- `azure-anthropic` variant has its own Anthropic-specific
`toolFactories` (webSearch + urlContext)
- `ProviderVariant` gains a `TOutput` generic so `transform` output type
correctly flows to `toolFactories` and `resolveModel`
- `urlContext` factory correctly maps to `urlContext` tool key (not
`webSearch`)
- `BedrockExtension` uses `AmazonBedrockProvider` instead of
`ProviderV3` in its `satisfies` type

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

The root cause is that `ProviderVariant` typed `toolFactories` against
`TProvider` (the base provider), but `transform` can return a completely
different provider type. Adding `TOutput` generic (defaulting to
`TProvider`) lets variants declare their output type, so `toolFactories`
gets the correct type without casts.

The following tradeoffs were made:

- `variants` array type uses `ProviderVariant<TSettings, TProvider,
any>` to allow heterogeneous output types per variant

The following alternatives were considered:

- Using `unknown` + `as` casts in each toolFactory — rejected for being
less type-safe

### Breaking changes

None. The `TOutput` generic defaults to `TProvider`, so existing code is
unaffected.

### Special notes for your reviewer

The `urlContext` → `webSearch` key bug exists in the original
`AnthropicExtension` too (not just the variant), both are fixed in this
PR.

### 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: 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
fix: Azure Anthropic web search no longer crashes with "webSearchPreview is not a function"
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: 亢奋猫 <kangfenmao@qq.com>
2026-04-10 10:42:31 +08:00
SuYao
fe502e8504 feat(aiCore): add createAgent factory for ToolLoopAgent with plugin pipeline (#14032)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
2026-04-04 16:20:18 +08: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
github-actions[bot]
4083bd7083 chore: version packages (#13974)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @cherrystudio/ai-core@2.0.0

### Major Changes

- [#12235](https://github.com/CherryHQ/cherry-studio/pull/12235)
[`1c0a5a9`](1c0a5a95fa)
Thanks [@DeJeune](https://github.com/DeJeune)! - Migrate to AI SDK v6 -
complete rewrite of provider and middleware architecture

- **BREAKING**: Remove all legacy API clients, middleware pipeline, and
barrel `index.ts`
- **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, consolidate schema files
- **OpenRouter image**: Native image endpoint support via
`@openrouter/ai-sdk-provider` 2.3.3
- **GitHub Copilot**: Simplify extension by removing `ProviderV2` cast
and `wrapProvider`
- **Rename**: `index_new.ts` → `AiProvider.ts`, `ModelListService.ts` →
`listModels.ts`

### Patch Changes

- [#13787](https://github.com/CherryHQ/cherry-studio/pull/13787)
[`6b4c928`](6b4c928056)
Thanks [@EurFelux](https://github.com/EurFelux)! - Add missing
@openrouter/ai-sdk-provider dependency to fix package build

- [#12783](https://github.com/CherryHQ/cherry-studio/pull/12783)
[`336176b`](336176be08)
Thanks [@EurFelux](https://github.com/EurFelux)! - Baseline release for
previously unmanaged package changes while introducing changesets-based
publishing

- Updated dependencies
\[[`336176b`](336176be08)]:
    -   @cherrystudio/ai-sdk-provider@0.1.6

## @cherrystudio/ai-sdk-provider@0.1.6

### Patch Changes

- [#12783](https://github.com/CherryHQ/cherry-studio/pull/12783)
[`336176b`](336176be08)
Thanks [@EurFelux](https://github.com/EurFelux)! - Baseline release for
previously unmanaged package changes while introducing changesets-based
publishing

## @cherrystudio/extension-table-plus@3.0.12

### Patch Changes

- [#13840](https://github.com/CherryHQ/cherry-studio/pull/13840)
[`ae13786`](ae13786b55)
Thanks [@EurFelux](https://github.com/EurFelux)! - Add local
tsconfig.json to fix dts build failure in packages:build

- [#13817](https://github.com/CherryHQ/cherry-studio/pull/13817)
[`7c2610b`](7c2610b1e3)
Thanks [@EurFelux](https://github.com/EurFelux)! - Remove reference to
non-existent tsconfig.build.json to fix CI build failure

- [#12783](https://github.com/CherryHQ/cherry-studio/pull/12783)
[`336176b`](336176be08)
Thanks [@EurFelux](https://github.com/EurFelux)! - Baseline release for
previously unmanaged package changes while introducing changesets-based
publishing

---------

Signed-off-by: icarus <eurfelux@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: icarus <eurfelux@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.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
github-actions[bot]
07bbed0d83 chore: version packages (#13974)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @cherrystudio/ai-core@2.0.0

### Major Changes

- [#12235](https://github.com/CherryHQ/cherry-studio/pull/12235)
[`1c0a5a9`](1c0a5a95fa)
Thanks [@DeJeune](https://github.com/DeJeune)! - Migrate to AI SDK v6 -
complete rewrite of provider and middleware architecture

- **BREAKING**: Remove all legacy API clients, middleware pipeline, and
barrel `index.ts`
- **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, consolidate schema files
- **OpenRouter image**: Native image endpoint support via
`@openrouter/ai-sdk-provider` 2.3.3
- **GitHub Copilot**: Simplify extension by removing `ProviderV2` cast
and `wrapProvider`
- **Rename**: `index_new.ts` → `AiProvider.ts`, `ModelListService.ts` →
`listModels.ts`

### Patch Changes

- [#13787](https://github.com/CherryHQ/cherry-studio/pull/13787)
[`6b4c928`](6b4c928056)
Thanks [@EurFelux](https://github.com/EurFelux)! - Add missing
@openrouter/ai-sdk-provider dependency to fix package build

- [#12783](https://github.com/CherryHQ/cherry-studio/pull/12783)
[`336176b`](336176be08)
Thanks [@EurFelux](https://github.com/EurFelux)! - Baseline release for
previously unmanaged package changes while introducing changesets-based
publishing

- Updated dependencies
\[[`336176b`](336176be08)]:
    -   @cherrystudio/ai-sdk-provider@0.1.6

## @cherrystudio/ai-sdk-provider@0.1.6

### Patch Changes

- [#12783](https://github.com/CherryHQ/cherry-studio/pull/12783)
[`336176b`](336176be08)
Thanks [@EurFelux](https://github.com/EurFelux)! - Baseline release for
previously unmanaged package changes while introducing changesets-based
publishing

## @cherrystudio/extension-table-plus@3.0.12

### Patch Changes

- [#13840](https://github.com/CherryHQ/cherry-studio/pull/13840)
[`ae13786`](ae13786b55)
Thanks [@EurFelux](https://github.com/EurFelux)! - Add local
tsconfig.json to fix dts build failure in packages:build

- [#13817](https://github.com/CherryHQ/cherry-studio/pull/13817)
[`7c2610b`](7c2610b1e3)
Thanks [@EurFelux](https://github.com/EurFelux)! - Remove reference to
non-existent tsconfig.build.json to fix CI build failure

- [#12783](https://github.com/CherryHQ/cherry-studio/pull/12783)
[`336176b`](336176be08)
Thanks [@EurFelux](https://github.com/EurFelux)! - Baseline release for
previously unmanaged package changes while introducing changesets-based
publishing

---------

Signed-off-by: icarus <eurfelux@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: icarus <eurfelux@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 19:45:11 +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
Phantom
6b4c928056 fix(aiCore): add missing @openrouter/ai-sdk-provider dependency (#13787)
### What this PR does

Before this PR:

The `@cherrystudio/ai-core` package imports
`@openrouter/ai-sdk-provider` in its source code (`schemas.ts` and
`types.ts`), but this dependency was not declared in
`packages/aiCore/package.json`. This caused `tsdown` to inline-bundle it
and exit with an error, failing the **Release Packages** CI workflow.

After this PR:

`@openrouter/ai-sdk-provider` is properly declared as a dependency in
`packages/aiCore/package.json`, so `tsdown` treats it as an external
dependency and the build succeeds.

Fixes #

N/A

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

The following tradeoffs were made:

None — this is a straightforward missing dependency declaration.

The following alternatives were considered:

None.

Links to places where the discussion took place:

N/A

### Breaking changes

None.

### Special notes for your reviewer

The root `package.json` already has `@openrouter/ai-sdk-provider@^2.2.3`
with a patch applied. The aiCore package now correctly declares the same
version range so it resolves through the workspace.

### 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
NONE
```

---------

Signed-off-by: icarus <eurfelux@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 13:16:17 +08:00
Phantom
937c2e883e refactor: add no-unnecessary-type-assertion rule and remove redundant assertions (#13741) 2026-03-25 19:16:16 +08:00
Phantom
336176be08 feat: introduce changeset for monorepo version management (#12783)
## Summary

This PR introduces
[changesets](https://github.com/changesets/changesets) to automate
version management and publishing for the Cherry Studio monorepo.

## Changes

### Changeset Setup
- `.changeset/config.json` - Changeset configuration with GitHub
changelog integration
- `.changeset/README.md` - Documentation for using changesets and CI/CD
release flow
- `.changeset/initial-setup.md` - Initial changeset marking the setup

### CI/CD Workflows
- `.github/workflows/release-packages.yml` - Automated release workflow
(creates Version Packages PR, publishes on merge)
- `.github/workflows/snapshot.yml` - Manual snapshot release workflow
- `.github/workflows/ci.yml` - Added `changeset-check` job to verify PRs
include changesets when packages are modified

### Package Updates
- `package.json` - Added changeset scripts (`changeset`,
`changeset:status`, `changeset:version`, `changeset:publish`,
`packages:build`, `packages:release`)
- `packages/aiCore/package.json` - Added `prepublishOnly` script
- `packages/ai-sdk-provider/package.json` - Added `prepublishOnly`
script
- `packages/extension-table-plus/package.json` - Added `prepublishOnly`
script
- `packages/extension-table-plus/CHANGELOG-OLD.md` - Backup of
historical changelog

## How It Works

1. **Developers**: Run `pnpm changeset add` in PRs that modify packages
2. **CI**: `changeset-check` job validates PRs include changesets when
needed
3. **Accumulate**: Merging PRs with changesets auto-creates/updates a
"Version Packages" PR
4. **Release**: Maintainers merge the Version Packages PR when ready →
packages are published to npm

## Requirements

- [ ] `NPM_TOKEN` secret must be configured in GitHub repository
settings

## Test Plan

- [x] `pnpm changeset:status` runs successfully
- [x] `GITHUB_TOKEN=$(gh auth token) pnpm changeset:version` bumps
versions and generates changelogs correctly
- [x] `pnpm packages:build` builds all packages in correct order
- [x] `pnpm format` passes

## Release Note

```release-note
NONE (internal tooling change)
```

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

---------

Signed-off-by: icarus <eurfelux@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:00:45 +08:00
Phantom
6aa4b567ce fix: resolve all await-thenable lint violations (#13712)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 21:32:59 +08:00
cherry-ai-bot[bot]
83d7575695 fix(azure): keep dated api versions on chat transport (#13506)
## Summary

Fix the Azure OpenAI regression reported in #13499.

Dated Azure API versions such as `2024-12-01-preview` are intended to
stay on Cherry's chat / deployment-based path, while only generic
`preview` / `v1` should use the Responses API. The regression was that
aiCore's internal `azure` provider still defaulted to the Responses
transport, so deployment-based Azure requests could still generate
`/openai/deployments/<deployment>/responses` URLs and fail with 404.

This PR restores the intended split by:
- making the `azure` provider default to `provider.chat(...)`
- keeping `azure-responses` on `provider.responses(...)`
- aligning the registry's `azure-chat` fallback with the same chat
wrapper
- adding regression coverage for provider routing and registry behavior

## Verification

- `node node_modules/vitest/vitest.mjs run --project renderer
src/renderer/src/aiCore/provider/__tests__/providerConfig.test.ts`
- `node node_modules/vitest/vitest.mjs run --project aiCore
packages/aiCore/src/core/providers/__tests__/registry-functionality.test.ts`

Fixes #13499

Co-authored-by: cherryai002 <cherryai002@192.168.5.55>
2026-03-16 16:53:54 +08:00
Phantom
d676b3b39a chore: add Zed editor settings example, clean up configs, and improve dev guides (#13457)
### What this PR does

Before this PR:
- No Zed editor configuration example existed for contributors using Zed
- Several config files had inconsistent JSON array formatting
- `biome.jsonc` had redundant exclude rules
- Contributing guides did not reference the development guide
- `development.md` (zh) was not translated to Chinese
- Node.js and pnpm versions were hardcoded in the development guide

After this PR:
- Added `.zed/settings.json.example` with Biome formatter,
oxc/eslint/biome fixAll, and import organization
- Cleaned up redundant Biome exclude rules and unified JSON array
formatting
- Added "Setting Up Your Development Environment" section to
`CONTRIBUTING.md` (en/zh) linking to the development guide
- Added Zed editor setup guide to `development.md` (en/zh)
- Translated `docs/zh/guides/development.md` to Chinese
- Node.js version now references `.node-version`; pnpm version
references `packageManager` in `package.json`
- VSCode extensions now reference `.vscode/extensions.json`

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

The following tradeoffs were made:
- The Zed settings file is provided as an `.example` rather than a
direct `.zed/settings.json` to avoid overriding individual contributor
preferences.
- Versions reference their source of truth files rather than being
hardcoded, so docs stay in sync automatically.

The following alternatives were considered:
- N/A

### Breaking changes

None

### Special notes for your reviewer

- The JSON formatting changes are purely cosmetic — no behavior changes.
They align with Biome's default formatting rules.
- The `.zed/settings.json.example` includes `source.fixAll.eslint` and
`source.fixAll.oxc` alongside Biome, matching the project's
triple-linter setup.

### 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
- [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

```release-note
NONE
```

---------

Signed-off-by: icarus <eurfelux@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 18:03:54 +08:00
PhoenixCPH
2bbf09b546 fix: upgrade xAI web search from deprecated Live Search to Responses API (#12812)
### What this PR does

Upgrades `@ai-sdk/xai` from 2.0.36 to 2.0.56 and migrates xAI web search
from the deprecated Live Search (provider options) approach to the
Responses API with tool-based web search (`xai.tools.webSearch()` +
`xai.tools.xSearch()`).

Before this PR:
- xAI web search used the deprecated Live Search approach via
`searchParameters` provider options
- No support for xSearch (X/Twitter post search)
- X.com citation links showed raw URLs with no tweet content preview

After this PR:
- xAI provider uses `xai.responses(modelId)` with
`xai.tools.webSearch()` and `xai.tools.xSearch()`
- X/Twitter post search results are displayed in the chat UI via
`x_search` tool rendering
- Citation tooltips and the citation panel show tweet content via oEmbed
API (`publish.x.com/oembed`)
- `isXPostUrl` handles all hostname variants (`x.com`, `www.x.com`,
`twitter.com`, `www.twitter.com`)

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

xAI deprecated the Live Search approach in favor of the Responses API
with explicit tool calls. This migration:

- Adopts the new `xai.responses()` + `xai.tools.webSearch()` /
`xai.tools.xSearch()` pattern
- Simplifies web search config to use only `excludedDomains` (max 5)
- Adds proper citation rendering for X/Twitter posts using the oEmbed
API, consistent between `CitationTooltip.tsx` and `CitationsList.tsx`

The following tradeoffs were made:
- oEmbed data is fetched via a separate `useQuery` (cache key
`['xOembed', url]`) shared across components to avoid duplicate requests
while keeping the author display title reliable (no string parsing from
truncated content)

### Breaking changes

None. The migration is transparent to users — web search continues to
work with the same UI, now with richer X/Twitter citation support.

### Special notes for your reviewer

- The `webSearchSource` detection was updated to handle xAI's Responses
API behavior where `providerMetadata` may be empty — falls back to
`providerId`
- `normalizeCitationMarks` now handles the `[[N]](url)` format from GROK
- GROK citation formatting falls back to hostname when `title` is just a
number

### 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: 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.

### Release note

```release-note
Upgrade xAI web search to Responses API with xSearch support and rich X/Twitter citation previews
```

---------

Signed-off-by: suyao <sy20010504@gmail.com>
Co-authored-by: Peihao Cao <caopeihao@PeihaodeMacBook-Pro.local>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: suyao <sy20010504@gmail.com>
Co-authored-by: George·Dong <98630204+GeorgeDong32@users.noreply.github.com>
2026-03-12 14:07:35 +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
Phantom
9174b96bc2 chore: upgrade tsdown to ^0.20.3 to fix build issues (#12800)
* chore: update tsdown to ^0.20.3 in ai-sdk-provider and aiCore

* chore: Update tsdown to v0.20.3 in extension-table-plus

* refactor: Fix TypeScript type in ttsdown config format array

* chore: Update @cherrystudio/ai-sdk-provider to ^0.1.4

* chore: use workspace reference for ai-sdk-provider
2026-02-09 01:46:29 +08:00
Phantom
26f37c1c56 feat: add Claude Opus 4.6 model support (#12777)
* chore: update @ai-sdk/anthropic to v2.0.59

* feat: add Claude Opus 4.6 model with adaptive thinking support

- Add Opus 4.6 to system models and reasoning configuration
- Implement adaptive thinking + effort parameters for Opus 4.6
- Map reasoningEffort to supported API values (low, medium, high, max)
- Update thinking budget to support 128K output tokens for Opus 4.6

* feat: add Claude Opus 4.6 model support and detection

- Add `isOpus46Model` utility function for detecting Claude Opus 4.6
  models
- Update token limit regex to support both hyphen and dot separators
  (4-6 and 4.6)
- Add comprehensive test coverage for Opus 4.6 detection, reasoning
  effort options, and token limits
- Ensure proper distinction between Opus 4.6 (128K tokens) and earlier
  versions

* chore: Update @ai-sdk/anthropic to ^2.0.59

* feat: Bump @cherrystudio/ai-sdk-provider version to 0.1.4

* chore: Update @ai-sdk/anthropic of aiCore package to v2.0.59

* fix: Map high reasoning effort to 'high' instead of 'max'

* feat: Add 'none' reasoning option for opus46 model

* chore: Update @ai-sdk/amazon-bedrock to v3.0.76

* feat: add reasoning config support for Opus 4.6 models

* fix: Add 'none' reasoning effort option for Claude Opus 4.6

* docs: Improve Anthropic reasoning params documentation
2026-02-08 01:43:00 +08:00
Phantom
2894d13b02 fix: escape double quotes in MCP tool use prompt examples (#12773)
* fix: Clarify JSON escaping in tool use prompt

Update tool use prompt to explicitly mention escaping double quotes
within JSON arguments. The example now shows proper escaping for
strings containing double quotes.

* fix: Escape quotes in tool use example JSON
2026-02-07 14:14:07 +08:00
SuYao
c53d6f3fd0 fix: prevent System Prompt duplication on recursive MCP tool calls (#12643)
When using prompt-based tool calling (for models without native function
call support), the system prompt containing MCP tool definitions was being
duplicated on each recursive call after tool execution.

Root cause: In `transformParams`, the system prompt was rebuilt even on
recursive calls, causing tool definitions to be appended repeatedly.

Fix: Check `context.isRecursiveCall` before rebuilding the system prompt.
On recursive calls, skip the system prompt transformation to preserve the
already-processed prompt.

Fixes #12638

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 00:40:44 +08:00
kangfenmao
3737c1680b Revert "fix(header): resolve User-Agent forbidden header in renderer process (#12549)"
This reverts commit 56bfa95d08.
2026-01-25 21:17:54 +08:00
SuYao
56bfa95d08 fix(header): resolve User-Agent forbidden header in renderer process (#12549)
* fix(header): merge user-agent add header gracefully

* fix(test): mock os release

* fix(test): again
2026-01-23 14:18:28 +08:00
LiuVaayne
6d15b0dfd1 feat(mcp): add MCP Hub server for multi-server tool orchestration (#12192)
* feat(mcp): add hub server type definitions

- Add 'hub' to BuiltinMCPServerNames enum as '@cherry/hub'
- Create GeneratedTool, SearchQuery, ExecInput, ExecOutput types
- Add ExecutionContext and ConsoleMethods interfaces

Amp-Thread-ID: https://ampcode.com/threads/T-019b4e7d-86a3-770d-82f8-9e646e7e597e
Co-authored-by: Amp <amp@ampcode.com>

* feat(mcp): implement hub server core components

- generator.ts: Convert MCP tools to JS functions with JSDoc
- tool-registry.ts: In-memory cache with 10-min TTL
- search.ts: Comma-separated keyword search with ranking
- runtime.ts: Code execution with parallel/settle/console helpers

Amp-Thread-ID: https://ampcode.com/threads/T-019b4e7d-86a3-770d-82f8-9e646e7e597e
Co-authored-by: Amp <amp@ampcode.com>

* feat(mcp): integrate hub server with MCP infrastructure

- Create HubServer class with search/exec tools
- Implement mcp-bridge for calling tools via MCPService
- Register hub server in factory with dependency injection
- Initialize hub dependencies in MCPService constructor
- Add hub server description label for i18n

Amp-Thread-ID: https://ampcode.com/threads/T-019b4e7d-86a3-770d-82f8-9e646e7e597e
Co-authored-by: Amp <amp@ampcode.com>

* test(mcp): add unit tests for hub server

- generator.test.ts: Test schema conversion and JSDoc generation
- search.test.ts: Test keyword matching, ranking, and limits
- runtime.test.ts: Test code execution, helpers, and error handling

Amp-Thread-ID: https://ampcode.com/threads/T-019b4e7d-86a3-770d-82f8-9e646e7e597e
Co-authored-by: Amp <amp@ampcode.com>

* docs(mcp): add hub server documentation

- Document search/exec tool usage and parameters
- Explain configuration and caching behavior
- Include architecture diagram and file structure

Amp-Thread-ID: https://ampcode.com/threads/T-019b4e7d-86a3-770d-82f8-9e646e7e597e
Co-authored-by: Amp <amp@ampcode.com>

* ♻️ refactor(hub): simplify dependency injection for HubServer

- Remove HubServerDependencies interface and setHubServerDependencies from factory
- Add initHubBridge() to mcp-bridge for direct initialization
- Make HubServer constructor parameterless (uses pre-initialized bridge)
- MCPService now calls initHubBridge() directly instead of factory setter
- Add integration tests for full search → exec flow

* 📝 docs(hub): add comments explaining why hub is not in builtin list

- Add JSDoc to HubServer class explaining its purpose and design
- Add comment to builtinMCPServers explaining hub exclusion
- Hub is a meta-server for LLM code mode, auto-enabled internally

*  feat: add available tools section to HUB_MODE_SYSTEM_PROMPT

- Add shared utility for generating MCP tool function names (serverName_toolName format)
- Update hub server to use consistent function naming across search, exec and prompt
- Add fetchAllActiveServerTools to ApiService for renderer process
- Update parameterBuilder to include available tools in auto/hub mode prompt
- Use CacheService for 1-minute tools caching in hub server
- Remove ToolRegistry in favor of direct fetching with caching
- Update search ranking to include server name matching
- Fix tests to use new naming format

Amp-Thread-ID: https://ampcode.com/threads/T-019b6971-d5c9-7719-9245-a89390078647
Co-authored-by: Amp <amp@ampcode.com>

* ♻️ refactor: consolidate MCP tool name utilities into shared module

- Merge buildFunctionCallToolName from src/main/utils/mcp.ts into packages/shared/mcp.ts
- Create unified buildMcpToolName base function with options for prefix, delimiter, maxLength, existingNames
- Fix toCamelCase to normalize uppercase snake case (MY_SERVER → myServer)
- Fix maxLength + existingNames interaction to respect length limit when adding collision suffix
- Add comprehensive JSDoc documentation
- Update tests and hub.test.ts for new lowercase normalization behavior

*  feat: isolate hub exec worker and filter disabled tools

* 🐛 fix: inline hub worker source

* 🐛 fix: sync hub tool cache and map

* Update import path for buildFunctionCallToolName in BaseService

*  feat: refine hub mode system prompt

* 🐛 fix: propagate hub tool errors

* 📝 docs: clarify hub exec return

*  feat(hub): improve prompts and tool descriptions for better LLM success rate

- Rewrite HUB_MODE_SYSTEM_PROMPT_BASE with Critical Rules section
- Add Common Mistakes to Avoid section with examples
- Update exec tool description with IMPORTANT return requirement
- Improve search tool description clarity
- Simplify generator output with return reminder in header
- Add per-field @param JSDoc with required/optional markers

Fixes issue where LLMs forgot to return values from exec code

* ♻️ refactor(hub): return empty string when no tools available

*  feat(hub): add dedicated AUTO_MODE_SYSTEM_PROMPT for auto mode

- Create self-contained prompt teaching XML tool_use format
- Only shows search/exec tools (no generic examples)
- Add complete workflow example with common mistakes
- Update parameterBuilder to use getAutoModeSystemPrompt()
- User prompt comes first, then auto mode instructions
- Skip hub prompt when no tools available

* ♻️ refactor: move hub prompts to dedicated prompts-code-mode.ts

- Create src/renderer/src/config/prompts-code-mode.ts
- Move HUB_MODE_SYSTEM_PROMPT_BASE and AUTO_MODE_SYSTEM_PROMPT_BASE
- Move getHubModeSystemPrompt() and getAutoModeSystemPrompt()
- Extract shared buildToolsSection() helper
- Update parameterBuilder.ts import

* ♻️ refactor: add mcpMode support to promptToolUsePlugin

- Add mcpMode parameter to PromptToolUseConfig and defaultBuildSystemPrompt
- Pass mcpMode through middleware config to plugin builder
- Consolidate getAutoModeSystemPrompt into getHubModeSystemPrompt
- Update parameterBuilder to use getHubModeSystemPrompt

* ♻️ refactor: move getHubModeSystemPrompt to shared package

- Create @cherrystudio/shared workspace package with exports
- Move getHubModeSystemPrompt and ToolInfo to packages/shared/prompts
- Add @cherrystudio/shared dependency to @cherrystudio/ai-core
- Update promptToolUsePlugin to import from shared package
- Update renderer prompts-code-mode.ts to re-export from shared
- Add toolSetToToolInfoArray converter for type compatibility

* Revert "♻️ refactor: move getHubModeSystemPrompt to shared package"

This reverts commit 894b2fd487.

* Remove duplicate Tool Use Examples header from system prompt

* fix: add handleModeChange call in MCPToolsButton for manual mode activation

* style: update AssistantMCPSettings to use min-height instead of overflow for better layout control

* feat(i18n): add MCP server modes and truncate messages in multiple languages

- Introduced new "mode" options for MCP servers: auto, disabled, and manual with corresponding descriptions and labels.
- Added translations for "base64DataTruncated" and "truncated" messages across various language files.
- Enhanced user experience by providing clearer feedback on data truncation.

* Normalize tool names for search and exec in parser

* Clarify tool usage rules in code mode prompts and examples

* Clarify code execution instructions and update example usage

* refactor: simplify JSDoc description handling by removing unnecessary truncation

* refactor: optimize listAllActiveServerTools method to use Promise.allSettled for improved error handling and performance

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: kangfenmao <kangfenmao@qq.com>
2026-01-07 16:35:51 +08:00
George·Dong
af7896b900 fix(prompts): standardize tool use example format to use 'A:' label consistently (#12313)
- Changed all 'Assistant:' labels to 'A:' in tool use examples for consistency
- Added missing blank line before final response in both files
- Affects promptToolUsePlugin.ts and prompt.ts
- Resolves #12310
2026-01-06 21:45: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
SuYao
09e58d3756 fix: interleaved thinking support (#12084)
* fix: update @ai-sdk/openai-compatible to version 1.0.28 and adjust related patches

* fix: add sendReasoning option to OpenAICompatibleProviderOptions and update message conversion logic

* fix: add interval thinking model support and related tests

* fix: add sendReasoning option to OpenAICompatibleProviderOptions and update related logic

* fix: remove MiniMax reasoning model support and update interval thinking model regex

* chore: add comment

* fix: rename interval thinking model references to interleaved thinking model
2025-12-23 20:08:53 +08:00
Phantom
c747b8e2a4 fix(prompt): remove unprofessional reward text and improve language instruction clarity (#12054)
* fix(toolUsePlugin): correct prompt formatting and instructions

- Remove misleading reward statement from tool use prompt
- Fix typo in XML tag format instruction ("MARK" to "MAKE")
- Reorganize response rules section for better clarity

* refactor(tool-use): consolidate default system prompt into shared module

Move DEFAULT_SYSTEM_PROMPT to core plugin module and reuse it in renderer
Update prompt to allow multiple tool uses per message and add response language rule
2025-12-21 17:20:16 +08:00
SuYao
dc0c47c64d feat: support gpt 5.2 series (#11873)
* feat: support gpt 5.2

* feat: support param when set to 'none'

* chore version & simply type

* fix: comment

* fix: typecheck

* replace placeholder

* simplify func

* feat: add gpt-5.1-codex-max
2025-12-12 22:53:10 +08:00
MyPrototypeWhat
96aba33077 fix: correct token calculation in prompt tool use plugin (#11867)
* fix: correct token calculation in prompt tool use plugin

- Fix duplicate token accumulation in recursive stream handling
- Accumulate usage for finish-step without tool calls
- Filter out recursive stream's start/finish events (only one per conversation)
- Make accumulateUsage method public for reuse

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

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

* refactor: simplify pipeRecursiveStream method in StreamEventManager

- Removed unnecessary context parameter from pipeRecursiveStream method
- Streamlined the invocation of pipeRecursiveStream in recursive call handling

This change enhances code clarity and reduces complexity in stream management.

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-12 18:23:49 +08:00
SuYao
9ac7e2c78d feat: enhance web search tool switching logic to support provider-specific context (#11769)
* feat: enhance web search tool switching logic to support provider-specific context

* Update packages/aiCore/src/core/plugins/built-in/webSearchPlugin/helper.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* refactor: consolidate control flow in switchWebSearchTool (#11771)

* Initial plan

* refactor: make control flow consistent in switchWebSearchTool

Replace early returns with break statements in all switch cases to ensure
consistent control flow. Move fallback logic into default case for clarity.

Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>

* Update packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update packages/aiCore/src/core/plugins/built-in/webSearchPlugin/index.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore: format

* fix: ensure switchWebSearchTool is always called for cherryin providers

- Add missing else branch to prevent silent failure when provider extraction fails
- Add empty string check for extracted providerId from split operation
- Ensures web search functionality is preserved in all edge cases

Addresses PR review feedback from #11769

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

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

* refactor: simplify repetitive switchWebSearchTool calls

- Extract providerId determination logic before calling switchWebSearchTool
- Call switchWebSearchTool only once at the end with updated providerId
- Reduce code duplication while maintaining all edge case handling

Addresses review feedback from @kangfenmao

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

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

* refactor: eliminate code duplication in switchWebSearchTool

- Extract helper functions: ensureToolsObject, applyToolBasedSearch, applyProviderOptionsSearch
- Replace switch statement and fallback if-else chain with providerHandlers map
- Use array-based priority order for fallback logic
- Reduce code from 73 lines to 80 lines but with much better maintainability
- Eliminates 12 instances of "if (!params.tools) params.tools = {}"
- Single source of truth for each provider's configuration logic

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

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

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-11 15:01:01 +08:00
zane
711f805a5b fix(aiCore): omit empty content in assistant messages with tool_calls (#11818)
* fix(aiCore): omit empty content in assistant messages with tool_calls

When an assistant message contains tool_calls but no text content,
the content field was being set to undefined or empty string.
This caused API errors on strict OpenAI-compatible endpoints like CherryIn:
"messages: text content blocks must be non-empty"

The fix conditionally includes the content field only when there is
actual text content, which conforms to the OpenAI API specification.

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

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

* fix(aiCore): omit empty assistant message in new aiCore StreamEventManager

When building recursive params after tool execution, only add the assistant
message when textBuffer has content. This avoids sending empty/invalid
assistant messages to strict OpenAI-compatible APIs like CherryIn, which
causes "text content blocks must be non-empty" errors.

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

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

* revert: remove legacy OpenAIApiClient fix (legacy is deprecated)

The legacy aiCore code is no longer used. Only the fix in the new aiCore
architecture (StreamEventManager.ts) is needed.

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

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

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 10:46:13 +08:00
Copilot
a2a6c62f48 Fix custom parameters placement for Vercel AI Gateway (#11605)
* Initial plan

* Fix custom parameters placement for Vercel AI Gateway

For AI Gateway provider, custom parameters are now placed at the body level
instead of being nested inside providerOptions.gateway. This fixes the issue
where parameters like 'tools' were being incorrectly added to
providerOptions.gateway when they should be at the same level as providerOptions.

Fixes #4197

Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>

* Revert "Fix custom parameters placement for Vercel AI Gateway"

This reverts commit b14e48dd78.

* fix: rename 'ai-gateway' to 'gateway' across the codebase and update related configurations

* fix: resolve PR review issues for custom parameters field

- Fix Migration 174: use string literal 'ai-gateway' instead of non-existent constant for historical compatibility
- Fix Migration 180: update model.provider references to prevent orphaned models when renaming provider ID
- Add logging in mapVertexAIGatewayModelToProviderId when unknown model type is encountered
- Replace `any` with `Record<string, unknown>` in buildAIGatewayOptions return type for better type safety
- Add gateway mapping to getAiSdkProviderId mock in options.test.ts to match production behavior

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

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

* chore: version

* fix(options): enhance custom parameters handling for proxy providers

* fix(options): add support for cherryin provider with custom parameters handling

* chore

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DeJeune <67425183+DeJeune@users.noreply.github.com>
Co-authored-by: suyao <sy20010504@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 21:19:30 +08:00
SuYao
981bb9f451 fix: update deepseek logic to match deepseek v3.2 (#11648)
* fix: update deepseek dependency to version 1.0.31 and improve provider creation logging

* chore

* feat: deepseek official hybrid infer

* fix: deepseek-v3.2-speciale tooluse and reasoning

* fix: 添加固定推理模型支持并更新相关逻辑

* refactor: simplify logic

* feat: aihubmix

* all system_providers

* feat: cherryin

* temp fix

* fix: address PR review feedback for DeepSeek v3.2 implementation

- Add default case in buildCherryInProviderOptions to fallback to genericProviderOptions
- Add clarifying comment for switch fall-through in reasoning.ts
- Add comprehensive test coverage for isFixedReasoningModel (negative cases)
- Add test coverage for new provider whitelist (deepseek, cherryin, new-api, aihubmix, sophnet, dmxapi)
- Add test coverage for isDeepSeekHybridInferenceModel prefix patterns
- Verify function calling logic works correctly via regex matching after removing provider-based checks
- Use includes() for deepseek-chat matching to support potential variants

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

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

* fix: remove unnecessary fall-through case for unknown providers in getReasoningEffort

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-04 19:13:51 +08:00