mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-07-08 08:27:39 +08:00
refactor/code-cli
978 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
fa5bbb7607 | Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 | ||
|
|
db8a1834c2 |
feat(file-manager): unified DirectoryTreeBuilder primitive for Notes (#15363)
### What this PR does Before this PR: - Directory loading is split between two pipelines: `FileStorage.getDirectoryStructure` (Notes) and `FileStorage.listDirectory` (everything else). Same workspace, two scans, two watchers. - `FileStorage.listDirectory` defaults `maxEntries: 20`, silently truncating list-mode callers (workspace trees rendered `tests/__mocks__` as a file because it sorted out of the first 20 results). - Notes' manual chokidar plumbing (`startFileWatcher` / `onFileChange`) lives on legacy `file-change` IPC and crashes with `EMFILE: too many open files` on large repos because the watcher opens one FD per directory in `node_modules`. After this PR: - One primitive — `DirectoryTreeBuilder` (`src/main/file/tree/builder.ts`, RFC §12) — owns the in-memory tree and the chokidar watcher. It is the only directory-walking code on the main side. - Builder dedupe lives behind `TreeRegistry` (lifecycle `WhenReady`): identical `(rootPath, options)` requests share one builder, with a 500ms grace window so a remount inside one React commit reuses the warm scan + watcher instead of paying for a rescan. - `.gitignore` parsing (via `ignore@7`) drives BOTH ripgrep's `--ignore-file` AND chokidar's `ignored` predicate, so EMFILE on `node_modules`-heavy workspaces is gone. `.git` is always excluded even when `.gitignore` doesn't list it. - `search.listDirectory` is the now-real Phase 2 entry point (was a stub). `maxEntries` default raised to `Number.MAX_SAFE_INTEGER`; truncation is a search-mode concern and callers that want a cap pass it explicitly. The 20-entry default was the bug. - Renderer-side `useDirectoryTree(rootPath, options)` hook applies mutation pushes to a JSON-mirrored `TreeDirRoot`. The tree DTO and `TreeNode` class live in `packages/shared/file/types/tree.ts` so main and renderer share one shape (no parent cycles in JSON; WeakMap parent ref recovered in `FromJSON`). - Notes (`NotesPage`) migrated off `getDirectoryStructure` + manual watcher onto `useDirectoryTree` + `useNote` join. The Redux `starredPaths` / `expandedPaths` path stays untouched in this PR — `useNote` already covers that surface via `noteTable`. Fixes # ### Why we need it and why it was done in this way The following tradeoffs were made: - **Builder dedupe on main, not renderer.** A renderer-side cache would still pay one IPC round-trip per remount because the expensive thing is the FS scan + watcher install, which only the main side owns. Sharing on the main means one ripgrep + one chokidar regardless of how many panes mount the same root. - **500ms grace window for builder teardown.** Long enough to cover React's "deletions before insertions" effect ordering (sub-millisecond in practice), short enough that closing a workspace doesn't keep watcher FDs alive noticeably. - **`Tree_*` IPC owned by `TreeRegistry.onInit`.** The lifetime of the handlers must match the lifetime of the chokidar watchers they reference. Putting them in `FileManager` would leak handlers across re-init. - **`TreeNode` class hierarchy (not plain DTOs)** lets `rename` mutate `path` once at the subtree root and have `adjustChildrenPaths` cascade — the alternative is rebuilding the subtree, which throws away every consumer's identity-based caching. - **Hard ESLint isolation:** `src/main/file/tree/**` does not import `@main/data/**`. Tree is a runtime concern; persistence is an orthogonal one (`noteTable` is a sparse state overlay on top of FS paths, not a tree mirror). RFC §12.6. The following alternatives were considered: - Keep the renderer-side cache (rejected — covered above; main-side dedupe is strictly stronger). - Add an `excludeGlobs` array option (rejected — the right source of truth is `.gitignore`, and users editing `.gitignore` get free updates). - One DTO without classes (rejected — rename cascade is the load-bearing case). Links to places where the discussion took place: RFC §12 (`v2-refactor-temp/docs/file-manager/rfc-file-manager.md`) ### Breaking changes - Removed legacy IPC channels: `File_GetDirectoryStructure`, `File_StartWatcher`, `File_StopWatcher`, `File_PauseWatcher`, `File_ResumeWatcher`. Only Notes used them; the migration is in this PR. No renderer outside Notes touched them. - `search.listDirectory` (renamed from `FileStorage.listDirectory`) now defaults to unbounded `maxEntries`. Existing callers that relied on the implicit 20-cap (none I could find) would need to pass `maxEntries: 20` explicitly. ### Special notes for your reviewer - `src/main/file/tree/__tests__/builder.test.ts` covers initial scan, `.gitignore` honoring, chokidar fan-out, `dispose` cleanup, and JSON round-trip (no parent cycles). - `src/main/file/tree/__tests__/registry.test.ts` covers builder dedupe, grace-window reuse, multi-consumer mutation fan-out, and `webContents`-destroyed cascade cleanup. - `src/main/utils/file/__tests__/search.test.ts` locks in the `maxEntries` default fix and the `--hidden` flag wiring. - ArtifactPane / chat-page integration of this primitive lives on `feat/chat-page` and is not part of this PR (that branch has the Shell forceMount + chat-page Tree IPC integration on top). ### 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 NONE ``` --------- Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
4439d3b283 |
chore(app-identity): rebrand bundle id to com.cherryai.CherryStudio
Rename the app bundle id from com.kangfenmao.CherryStudio to com.cherryai.CherryStudio at every definition point: electron-builder appId (packaging source of truth), macOS notarization appBundleId, Windows AppUserModelID, and the selection self-detection allowlist. Daily preview builds now use com.cherryai.CherryStudio.preview (a distinct channel id rather than a case-only variant that macOS would treat as the same app); the workflow replaceAll search strings are updated to the new id so the preview identity patch keeps matching. Incidental cleanups bundled in: - Drop the unused MAIN_VITE_BUNDLE_ID env override; env.d.ts now declares the actually-used MAIN_VITE_CHERRYAI_CLIENT_SECRET instead of leaning on vite/client's any index signature. - Remove the stale @kangfenmao/keyv-storage from pnpm.onlyBuiltDependencies. - SearchService: use @main/core/platform isDev over electron-toolkit is.dev. |
||
|
|
e80b4a4c0b |
chore: release v1.9.7 (#15362)
### What this PR does Before this PR: Version 1.9.6 was the latest release. After this PR: Prepares release v1.9.7 with updated version and bilingual release notes covering 18 commits since v1.9.6. Fixes # ### Why we need it and why it was done in this way This is a patch release that includes important bug fixes and new model support. The changes focus on: **New Features:** - Support for grok-build-0.1 capabilities (reasoning, tool use, vision) - StepFun provider now supports Claude Code / Anthropic-compatible mode - DeepSeek V4 Flash and MiMo V2.5+ now properly support 1M context window in Agent mode **Bug Fixes:** - Fix ExaMCP web search not returning result content correctly - Fix code syntax highlighting issues in light theme - Fix OpenCode launch failures after CLI updates - Fix Agent mode not forwarding custom provider headers to Claude Code - Fix Grok 4.3 reasoning effort support in xAI responses - Improve OpenClaw migration message clarity - Fix Gemini 3.x models using wrong UI and deprecated parameters - Fix Qwen max series models incorrectly showing vision capability - Fix AIHubMix reasoning effort configuration The following tradeoffs were made: None — this is a standard patch release with cherry-picked fixes. The following alternatives were considered: None — this follows the established release workflow. Links to places where the discussion took place: N/A ### Breaking changes None. ### Special notes for the reviewer This is a release preparation PR. The release notes have been generated from the 18 commits included in this release, focusing on user-facing changes as required by the release guidelines. ### 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 Cherry Studio 1.9.7 - Model Support & Bug Fixes ✨ New Features - [Models] Added support for grok-build-0.1 capabilities (reasoning, tool use, vision) - [Providers] StepFun now supports Claude Code / Anthropic-compatible mode with auto-filled endpoint - [Agents] DeepSeek V4 Flash and MiMo V2.5+ now properly support 1M context window in Claude Code 🐛 Bug Fixes - [Web Search] Fixed ExaMCP web search not returning result content correctly - [Code Viewer] Fixed code syntax highlighting issues where tokens could disappear in light theme - [OpenCode] Fixed launch failures after CLI updates by using package-local executable - [Agents] Fixed Agent mode not forwarding custom provider headers to Claude Code - [Models] Fixed Grok 4.3 reasoning effort support in xAI responses - [OpenClaw] Improved migration message clarity when external PATH installation is detected - [Models] Fixed Gemini 3.x models using wrong UI and sending deprecated sampling parameters - [Models] Fixed Qwen max series models incorrectly showing vision capability - [Providers] Fixed AIHubMix reasoning effort configuration not working properly ``` Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> |
||
|
|
f43ce3e5de |
chore(lint): suppress legacy css var warnings in lint scripts (#15216)
Signed-off-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
344c58eb8e |
feat(job): introduce JobManager + SchedulerService backbone (Phase 1)
cherry-studio v2 had 6+ ad-hoc queue/scheduler implementations (Knowledge, FileProcessing, agent SchedulerService, TopicQueue, NotificationQueue, protocol heartbeats) with no shared registry, inconsistent cancel and progress semantics, and no cross-restart recovery outside agent_task. This commit lands the unified replacement: JobManager owns Job lifecycle and SchedulerService owns time-only scheduling, both reusable independently. Phase 1 ships the backbone only: jobTable + jobScheduleTable, entity services, 6-state machine with per-handler recovery (abandon/retry/ singleton), catch-up policy (skip-missed/after-startup), retry backoff, GC, idempotencyKey dedup, useJob renderer hook, and 4 reference docs. Four-layer lock model addresses libsql client-ts issue #288 (Layer 0 global dispatch mutex serializes all transactions). croner@^10 is introduced for cron expressions (zero-dep, Electron-friendly). Application.SHUTDOWN_TIMEOUT_MS is promoted to public for JobManager reuse. cron-parser stays until Phase 2 agent task migration. No business migrations in this commit — Knowledge/FileProcessing/agent SchedulerService remain untouched and migrate in Phase 2-4 per docs/references/job-and-scheduler/migration-checklist.md. Follow-ups for Phase 1 completion: DataApi GET /jobs handler, dummy.echo smoke test, integration tests, migration feasibility report. |
||
|
|
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> |
||
|
|
7b556cf786 | Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 | ||
|
|
a574aa5e3f |
chore: release v1.9.6 (#15116)
<!-- 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: Version was 1.9.5 After this PR: Version bumped to 1.9.6 with updated bilingual release notes <!-- (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 This is an automated release preparation for version 1.9.6, containing bug fixes collected since v1.9.5. The following tradeoffs were made: None The following alternatives were considered: None Links to places where the discussion took place: N/A ### Breaking changes None ### Special notes for your reviewer **Review Checklist:** - [ ] Review generated release notes in `electron-builder.yml` - [ ] Verify version bump in `package.json` - [ ] CI passes - [ ] Merge to trigger release build **Release Summary (English):** - [AI] Fixed crash when chat model's stored provider no longer exists - [AI] Fixed streaming requests aborted after 30 minutes during active data transfer (affected models with extended thinking) - [Agents] Fixed agent session creation failures when provider settings change - [Agents] Fixed deepseek-r1 models incorrectly showing function_calling label causing errors in Agent mode - [Agents] Use task name instead of agent name for cron task sessions - [MCP] Fixed approval card not auto-expanding to show Run/Cancel buttons - [MCP] Clean up OAuth tokens when deleting servers - [Code Tools] Fixed Codex CLI launch failure when using OpenAI or other reserved providers - [Claude Code] Fixed launch failures caused by auth conflicts with provider environment variables - [Image] Fixed gpt-image-2 multi-turn editing crash - [Knowledge] Fixed HTTP/HTTPS/FTP URLs being stripped from Markdown documents - [OpenMinerU] Fixed preprocessing ENOENT errors due to ZIP structure change - [Qiniu] Fixed PDF upload regression for GPT-5.4 models ### 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. - [ ] PR: The PR description is expressive enough and will help future contributors - [ ] 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) - [ ] 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. - [ ] 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 Cherry Studio 1.9.6 - Bug Fixes 🐛 Bug Fixes - [AI] Fixed crash when chat model's stored provider no longer exists - [AI] Fixed streaming requests aborted after 30 minutes during active data transfer (affected models with extended thinking) - [Agents] Fixed agent session creation failures when provider settings change - [Agents] Fixed deepseek-r1 models incorrectly showing function_calling label causing errors in Agent mode - [Agents] Use task name instead of agent name for cron task sessions - [MCP] Fixed approval card not auto-expanding to show Run/Cancel buttons - [MCP] Clean up OAuth tokens when deleting servers - [Code Tools] Fixed Codex CLI launch failure when using OpenAI or other reserved providers - [Claude Code] Fixed launch failures caused by auth conflicts with provider environment variables - [Image] Fixed gpt-image-2 multi-turn editing crash - [Knowledge] Fixed HTTP/HTTPS/FTP URLs being stripped from Markdown documents - [OpenMinerU] Fixed preprocessing ENOENT errors due to ZIP structure change - [Qiniu] Fixed PDF upload regression for GPT-5.4 models ``` Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> |
||
|
|
d2c568e349 |
feat(file): Add schema and foundation for new file module (#13451)
### What this PR does
Adds the **Phase 1a contract surface** for the file module — types, DB
schema, DataApi + File IPC contracts, FileManager skeleton, and
architecture docs.
**Phase 1b.1 (Read Path & Repository), 1b.2 (Write Path & Lifecycle),
1b.3 (Watcher & DanglingCache), and 1b.4 (OrphanSweep &
FileRefCheckerRegistry) are now all landed on top of 1a in this same
PR.** This is the complete Phase 1b runtime — reviewers see the full
read + write + watcher + orphan-sweep picture in one place.
Design, contracts, and decision rationale live in the architecture docs:
-
[`docs/references/file/architecture.md`](docs/references/file/architecture.md)
— module boundaries, type system, IPC/DataApi contracts, layered
architecture, service lifecycle, mutation propagation
-
[`docs/references/file/file-manager-architecture.md`](docs/references/file/file-manager-architecture.md)
— FileManager internals (storage, version detection, atomic writes,
reference cleanup, DirectoryWatcher, orphan sweep, DanglingCache state
machine, key design decisions)
#### Phase 1a deliverables
- Types (`FileEntry` / `FileInfo` / `FileHandle` /
`CanonicalExternalPath` brand)
- DB schema (`file_entry` + `file_ref`) with per-origin CHECK
constraints
- DataApi schemas + stub handlers
- File IPC contract (polymorphic `FileHandle` dispatch;
`batchGetMetadata` included)
- FileManager skeleton + `internal/*` + `ops/*` + `watcher/` +
`DanglingCache` + `versionCache`
- Mutation propagation design (three typed events + prefix-based
queryKey invalidation)
#### Phase 1b.1 deliverables (read-path runtime)
- Shared utilities: `getFileTypeByExt`, `sanitizeFilename`,
`validateFileName` extracted to `@shared/file/types`
- Path utilities: `canonicalizeExternalPath` (NFC + null-byte guard +
trailing-sep strip), `isPathInside`, `isUnderInternalStorage`,
`canWrite`
- FS read primitives: `stat`, `exists`, `read` (text/base64/binary
overloads), `hash` (initial MD5; swapped to xxhash-h64 in 1b.2)
- Metadata utilities: `getFileType(path)`, `isTextFile`, `mimeToExt`
- Repositories: `FileEntryService` + `FileRefService` read methods
(Drizzle-backed, Zod-branded outputs)
- Pure-function modules: `internal/content/{read,hash}`,
`internal/dispatch.ts` (FileHandle dispatcher)
- `toFileInfo(entry)` projection
- `FileManager` class as `BaseService` (`@Injectable('FileManager')`
`@ServicePhase(WhenReady)`); read methods only
- `DanglingCache` + `VersionCache` minimal viable singletons (full impls
in 1b.3 / 1b.2)
- DataApi `/files/*` read handlers fully implemented (entries / single /
ref-counts / refs-by-source)
- 60+ TDD tests (unit + boundary + setupTestDatabase integration)
#### Phase 1b.2 deliverables (write-path runtime)
- **FS atomic primitives** (open to non-file-module consumers per
architecture §5.3): `atomicWriteFile` (tmp + fsync + rename +
fsync(dir)), `atomicWriteIfUnchanged` (re-stat OCC + content-hash
fallback for second-precision mtime), `createAtomicWriteStream`
(Writable wrapper, abort/destroy unlinks tmp)
- **FS general primitives**: `write` (delegates to atomicWriteFile),
`copy` (atomic dest), `move` (rename + EXDEV → copy+unlink fallback),
`remove` (idempotent ENOENT), `mkdir` / `ensureDir` / `removeDir`,
`download` (fetch → atomic stream)
- **Hash swap**: `hash()` migrated MD5 → `xxhash-wasm` h64 streaming;
legacy `md5` dep retained for KnowledgeService loaders
- **VersionCache LRU**: capacity-bounded (default 2000) with
re-insert-on-touch recency
- **Repository mutations**: `FileEntryService.create/update/delete`
(auto UUIDv7 default id, raw DB CHECK errors propagate);
`FileRefService.create/createMany/cleanupBySource/cleanupBySourceBatch`
(`onConflictDoNothing` for batch upsert)
- **internal/entry/**: `create.createInternal` (4 source variants: bytes
/ base64 / path / url) + `create.ensureExternal` (canonicalize + stat +
idempotent upsert + duplicate-suspect peer warn);
`lifecycle.trash/restore/permanentDelete` + batch variants (DB+FS
decoupled, internal best-effort unlink); `rename` (internal DB-only,
external fs.move + canonical externalPath); `copy` (pipes through
createInternal with rollback)
- **internal/content/write.ts**: `write` / `writeIfUnchanged`
(cache-not-trusted re-stat OCC, `StaleVersionError` rewrap from
`PathStaleVersionError`) / `createWriteStream` / `*ByPath` variants
- **internal/system/**: `shell.open` / `shell.showInFolder` (electron
`shell` wrappers); `tempCopy.withTempCopy` (isolated tmp dir; cleanup on
throw)
- **FileManager facade**: every IFileManager mutation method now
delegates to its `internal/*` counterpart (`createInternalEntry` /
`ensureExternalEntry` / `batchCreate*` / `batchEnsure*` / `write` /
`writeIfUnchanged` / `createWriteStream` / `createReadStream` / `trash`
/ `restore` / `permanentDelete` + batch / `rename` / `copy` /
`withTempCopy` / `open` / `showInFolder`); no method throws
notImplemented anymore
- ~60 new TDD tests (each behavior unit = one RED→GREEN→REFACTOR
commit); end-to-end integration scenarios via `setupTestDatabase` cover
atomic-rollback zero-residue, OCC second-precision-mtime
no-false-positive, trash-external CHECK enforcement, full
create→write→read→trash→restore→permanentDelete round-trip, and external
permanentDelete-leaves-user-file-untouched
#### Phase 1b.3 deliverables (watcher + DanglingCache observability)
- **DanglingCache class** (replaces 1a const-literal skeleton):
`byEntryId: Map<entryId, CachedState>` + `pathToEntryIds:
Map<canonicalPath, Set<entryId>>` reverse index, lazy TTL expiration
(default 30 min per architecture §11.2), `forceRecheck` escape hatch,
`Emitter<DanglingStateChangedEvent>` firing only on genuine state
transitions (same-state observations are silent). Injectable `now` /
`statProbe` / `ttlMs` / `fileEntryService` seams for deterministic
tests.
- **createDirectoryWatcher** chokidar v4 wrapper: `add` / `unlink` /
`change` / `ready` / `error` events; built-in OS-junk basename ignores
(`.DS_Store` / `.localized` / `Thumbs.db` / `desktop.ini`); idempotent
`close()`. Factory auto-wires `add` →
`danglingCache.onFsEvent(path,'present')` and `unlink` → `'missing'`.
(Architecture §8.2's richer `onAddDir`/`onUnlinkDir`/`onRename` events
deferred — no consumer needs them in scope.)
- **Reverse-index maintenance from mutation flows**: `ensureExternal`
calls `addEntry` + `onFsEvent('present','ops')` on insert (no-op on
reuse); `permanentDelete(external)` calls `removeEntry`;
`rename(external)` swaps `removeEntry(oldPath) + addEntry(newPath) +
onFsEvent(newPath,'present','ops')`.
- **FileManager surface**: `getDanglingState({id})` (internal →
'present', external → cache check, unknown id → 'unknown');
`batchGetDanglingStates({ids})` (parallel fan-out, unknown ids mapped to
'unknown'); `subscribeDangling({id}, listener)` (in-process per-entry
filter; renderer fan-out via `file-manager-event` IPC channel deferred
to Phase 2).
- **FileManager.onInit**: awaits `danglingCache.initFromDb()` (populates
reverse index from non-trashed external entries; no startup stat probe
per architecture §10.6); registers `File_GetDanglingState` /
`File_BatchGetDanglingStates` IPC handlers via `this.ipcHandle`
(auto-disposed on stop).
- New `IpcChannel` constants: `File_GetDanglingState`,
`File_BatchGetDanglingStates`.
- ~30 new TDD tests across DanglingCache (18 unit) + watcher (6 real-FS)
+ FileManager integration (INT-7..INT-10).
#### Phase 1b.4 deliverables (orphan sweep + FileRefCheckerRegistry)
- **FileRefCheckerRegistry**: `Record<FileRefSourceType,
SourceTypeChecker<...>>` typed registry forces exhaustive coverage at
compile time — adding a new variant to `FileRefSourceType` without a
checker triggers a TS build error. Phase 1 ships `FileRefSourceType =
'temp_session' | 'knowledge_item'`: real DB-backed checker for
`knowledge_item` (Drizzle `inArray` against `knowledge_item`);
`temp_session` checker treats every sourceId as gone (sessions are
in-memory only). `chat_message` / `painting` / `note` are **deliberately
not in the union yet** — each will be added in lockstep (tuple entry in
`allSourceTypes` + `createRefSchema` variant + `SourceTypeChecker`) by
the PR that migrates the owning domain's DB tables to v2. Stray writes
during the migration window fail fast at `FileRefSchema.parse` rather
than being silently persisted under a no-op stub.
- **OrphanRefScanner** (RFC §6.4): `scanOneType(sourceType)` enumerates
distinct `file_ref.sourceId` per type, asks the checker which are alive,
deletes the rest via `cleanupBySourceBatch`. `scanAll()` aggregates
across every registered sourceType. Backed by new
`FileRefService.listDistinctSourceIds` to keep all SQL inside the repo.
- **Report-only orphan-entry pass** (architecture §7.1 default policy is
"preserve"): `scanOrphanEntries` groups active entries with zero
`file_ref` rows by origin. **No deletion** — surfaced via
`getOrphanReport()` for the cleanup-UI consumer. Backed by new
`FileEntryService.findUnreferenced` LEFT JOIN-based query.
- **Startup file sweep** (architecture §10): `runStartupFileSweep`
snapshots `file_entry.id` (active + trashed) into a `Set` via new
`FileEntryService.listAllIds`, walks `{userData}/files/`, plans unlink
for (a) UUID-named files whose id is not in the snapshot and (b)
`*.tmp-<UUID>` atomic-write residue. Applies the `mtime > 5min`
freshness gate (§10.3) — files newer than that are presumed in-flight
and preserved. Plan-then-execute with the `50% / 20-count-floor /
10MB-floor` safety threshold (§10.4); aborts emit
`abortReason='count-fraction'|'byte-fraction'`. Single structured
`orphan-file-sweep` log per run (info / warn / error per outcome,
§10.5).
- **DB-sweep umbrella + observability** (`runDbSweep`): runs scanAll +
scanOrphanEntries, emits one `orphan-sweep` structured record
summarising both passes; failure path returns `outcome='failed'` +
`errorMessage` so callers don't throw on background fire-and-forget.
- **FileManager integration**: `onInit` schedules a fire-and-forget
`runStartupSweeps` that runs the FS-level + DB-level sweeps in parallel;
failures of either are logged but never block ready. `getOrphanReport()`
exposes the most recent `DbSweepReport` (orphan-ref counts already
cleaned + orphan-entry counts preserved) + `lastRunAt` for the cleanup
UI surface.
- ~30 new TDD tests across registry (14 unit) + orphan sweep (16 unit +
integration) + FileManager integration (INT-11/INT-12) + repo
(`findUnreferenced`, `listAllIds`, `listDistinctSourceIds`).
**Out of scope (deferred to Phase 2)**:
- Architecture §7.2 dangling-external auto-cleanup (external + missing +
0-ref + >30d retention) — narrow extension shipping with the cleanup UI.
- Adding `chat_message` / `painting` / `note` as `FileRefSourceType`
variants (tuple entry + schema + checker added together) — gated on each
domain's v2 batch migration.
- Cleanup-UI surface that consumes `getOrphanReport()` — Phase 2
renderer work.
Renderer-side File IPC bridge for write/dangling methods stays deferred
to Phase 2 alongside the consumer-batch migrations. The Phase 1b runtime
is consumable from main-side business services through
`application.get('FileManager')`.
### Why we need it and why it was done in this way
Contract-first concentrates design review in one place; Phase 1b.x then
becomes pure "honor the contracts". Each 1b.x phase keeps strict TDD
(RED → GREEN → REFACTOR per behavior, ~one commit per cycle); each phase
ends with a verification gate (push → CI green) before the next phase
begins.
Core decisions (origin two-state, `FileEntry`/`FileInfo` split, DataApi
SQL-only, external `permanentDelete` DB-only, TTL `DanglingCache`, OCC
trust boundary, atomic write fsync default, etc.) and their rationale
are recorded in `file-manager-architecture.md §12 Key Design Decisions`
— not duplicated here.
### Breaking changes
None — purely additive (read+write paths are new, no existing callers
replaced yet).
### Special notes for your reviewer
- Review focus: contracts (1a) + read-path runtime (1b.1) + write-path
runtime (1b.2) + watcher/DanglingCache (1b.3) + orphan sweep / registry
(1b.4). Phase 1b is now complete on this branch.
- **Phase 1a contract stability policy** (architecture.md top) is
binding — any 1b.x PR that finds a contract mismatch PRs the doc
revision first.
- Deferred (Phase 2): renderer-side File IPC bridge for
write/dangling/orphan methods (alongside consumer migration); cleanup-UI
surface consuming `getOrphanReport()`; architecture §7.2
dangling-external auto-cleanup (>30d retention); adding `chat_message` /
`painting` / `note` as `FileRefSourceType` variants (each adds tuple
entry + schema + checker in lockstep, gated on the owning domain's v2
batch migration); DanglingCache periodic snapshot logger (architecture
§11.8); `listDirectory` ripgrep wrapper; `compressImage`
(KnowledgeService consumer); FileUploadService + `file_upload` table
(Vercel AI SDK Files API).
### 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: N/A — purely additive
- [ ] Documentation: Internal architecture docs included
(`docs/references/file/`); no user-facing docs change
- [x] Self-review: I have reviewed my own code before requesting review
from others
### Release note
```release-note
NONE
```
---------
Signed-off-by: icarus <eurfelux@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com>
|
||
|
|
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> |
||
|
|
29a3750ac3 |
chore(style-reminders): add Tailwind canonical checks (#14862)
### What this PR does Before this PR: Tailwind canonical class suggestions such as `w-[420px] -> w-105` had to be fixed manually, and the PR style reminder workflow only reported newly introduced legacy renderer CSS variables. After this PR: Adds `pnpm styles:canonical <path>` to rewrite static Tailwind class strings to their canonical Tailwind v4 forms. The PR style reminders workflow now comments on both newly introduced legacy CSS variables and Tailwind canonical class suggestions. <!-- (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: The canonical class fixer is conservative: it only rewrites static JSX `class` / `className` strings and static `cn(...)` string inputs, leaving dynamic template literals untouched. It uses Tailwind's own design system canonicalization instead of maintaining a manual mapping table. The following alternatives were considered: A regex-only implementation was avoided because Tailwind canonicalization depends on Tailwind v4 parsing and theme behavior. A separate PR workflow comment was also avoided so the style reminders comment remains the single bot comment. Links to places where the discussion took place: N/A ### Breaking changes None. ### Special notes for your reviewer Compatibility aliases and legacy marker/env fallback were removed; the PR workflow now uses the `style-reminders` script, marker, and output naming. Validation performed: - `pnpm test:scripts -- scripts/__tests__/check-pr-style-reminders.test.ts scripts/__tests__/fix-tailwind-canonical-classes.test.ts` - `pnpm build:check` - `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: kangfenmao <kangfenmao@qq.com> |
||
|
|
fa2ac478d3 |
chore: release v1.9.5 (#14963)
### What this PR does Before this PR: - Version was 1.9.4 - Release notes were outdated After this PR: - Version bumped to 1.9.5 - Bilingual release notes updated with all changes since 1.9.4 This release includes 23 commits addressing bug fixes, improvements, and one new feature across multiple components including search, backup, models, agents, and more. ### Breaking changes None. This is a patch release with backward-compatible bug fixes and improvements. ### Special notes for your reviewer - Review generated release notes in `electron-builder.yml` - Verify version bump in `package.json` - CI passes - Merge to trigger release build ### Release note ```release-note Cherry Studio 1.9.5 - Bug Fixes & Improvements 🐛 Bug Fixes - [Search] Fixed built-in web search truncating assistant responses when web search was the only active tool - [Messages] Fixed outer scrolling issue in horizontal multi-model layout - [Backup] Fixed app hanging during restore when selection helper was enabled - [Backup] Fixed silent data loss when restoring v6 .zip backups on macOS/Linux - [Models] Fixed CherryIN OpenAI-protocol models not appearing in Agent model picker - [Models] Fixed DeepSeek V4 model slugs not being detected for reasoning effort - [Models] Fixed Tongyi model icon matching - [Models] Fixed Claude Opus 4.7 support - [Image] Fixed generated image re-editing in NewApiPage - [Code Tools] Disabled opencode built-in auto-update check - [API Server] Fixed trailing /v1 stripping from Anthropic SDK baseURL - [Gateway] Fixed Vercel AI Gateway model list fetch 💄 Improvements - [Agents] Show all sessions and agents in sidebar instead of capping at 20 - [Agents] Removed stale mcp__browser__* references from agent prompt - [Models] Updated DeepSeek provider defaults to use V4 model IDs - [Models] Added support for hosted Gemma 4 thinking mode - [Feishu] Use emoji reaction as typing indicator - [i18n] Fixed default assistant and topic names not updating on language switch - [Vertex] Improved model list fetch and service account setup - [Reasoning] Added enable_thinking param for SiliconFlow DeepSeek/Zhipu models - [Claw] Added timeout_minutes parameter to cron tool ✨ New Features - [Painting] Added gpt-image-2 support to AiHubMix provider ``` Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> |
||
|
|
dee3bb0928 |
feat(settings): refactor settings UI and add settings window (#14567)
Signed-off-by: kangfenmao <kangfenmao@qq.com> Signed-off-by: jdzhang <625013594@qq.com> Co-authored-by: jdzhang <625013594@qq.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com> |
||
|
|
16f120bdd3 | Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 | ||
|
|
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>
|
||
|
|
1afd70b372 | Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 | ||
|
|
750b867a60 |
chore(v2-refactor): set 2.0.0-dev and document v1 coexistence mindset
Reset version to 2.0.0-dev to reflect this branch is internal-only and not user-facing, and add a Coexistence Mindset section to CLAUDE.md so AI agents stop writing defensive code for two throwaway things: - v1 code and data (Redux, Dexie, ElectronStore) — all v1 code is deleted before v2 ships; v1 data reaches v2 only via migrators in src/main/data/migration/v2/. - Drizzle schemas and migrations/sqlite-drizzle/*.sql — rewritten freely until release, then wiped and regenerated as a single clean initial migration. Only the final regenerated migration is the correctness target. Also extend the Data Layer "Removing" list with ElectronStore so the v1 boundary referenced by the new section is canonical. |
||
|
|
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> |
||
|
|
6a6b47562b | Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 | ||
|
|
c813320bfc |
chore: release v1.9.4 (#14681)
### What this PR does This is the release PR for Cherry Studio v1.9.4, a patch release that includes bug fixes and new model support. **Changes included in this release:** - 12 commits since v1.9.3 - Version bump to 1.9.4 - Updated release notes in electron-builder.yml ### Release Notes **English:** Cherry Studio 1.9.4 - Bug Fixes & Model Support 🐛 Bug Fixes - [OpenCode] NEWAPI provider models now appear in the dropdown and route correctly - [Image Generation] Fixed gpt-image-2/gpt-image-1.5 editing and generation across multiple providers - [Models] Fixed Kimi K2.6 requests being rejected due to unsupported temperature settings - [Gateway] Fixed Vercel AI Gateway model list fetch failing due to missing authentication - [Copilot] Fixed GitHub Copilot model synchronization ✨ New Features - [Models] Added MiMo V2.5 model support with reasoning and calling capabilities - [Models] Added DeepSeek V4+ model support with reasoning effort control (high/max) - [Models] Mistral Small 4 now supports vision and adjustable reasoning effort 💄 Improvements - [Agents] Removed auto-injected @cherry/browser MCP (re-enable manually if needed) ### Commits Included |
||
|
|
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>
|
||
|
|
e72b77a09b |
chore: release v1.9.3 (#14523)
### What this PR does This PR prepares the release of Cherry Studio v1.9.3. **Release Summary:** Cherry Studio 1.9.3 is a bug fix release that addresses 17 issues across various components: - [Web Search] Fix built-in web search repeatedly running and consuming excessive tokens - [Backup] Fix Windows backup failures caused by symlinks in the Data directory - [UI] Fix horizontal multi-model message scrolling issue on card edges - [Models] Add support for OpenAI's gpt-image-2 model - [MCP] Fix MCP SSE/streamableHttp servers timing out during initialization - [AI Core] Fix native tool-call conversations stopping after first execution - [Bedrock] Fix AWS Bedrock requests failing when API Host is blank - [Agents] Fix agent skills page scroll position reset when toggling skills - [Feishu] Restore image message support from Feishu/Lark bot users - [Proxy Providers] Fix structured output error with Claude models through AiHubMix/NewAPI - [API Server] Fix API server failing for providers with comma-separated API keys - [Agents] Fix Soul Mode dropping user-provided session instructions - [File Upload] Support case-insensitive file extensions for drag-and-drop uploads - [Deep Links] Fix "Open in VS Code/Cursor/Zed" buttons being blocked - [Proxy Providers] Fix custom parameters not being passed for CherryIN/NewAPI - [Claude Code] Fix Claude Code failing to launch on all platforms - [Quick Panel] Fix model deselection bug when pasting messages with "@" **Changes in this release:** 1. Updated version to 1.9.3 in `package.json` 2. Updated release notes in `electron-builder.yml` ### Included Commits - |
||
|
|
5ec8696fd2 | Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 | ||
|
|
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>
|
||
|
|
b414dc52dc |
refactor(data-providers): migrate to handwritten Zod schema and remove drizzle-zod
- Replace userProviderInsertSchema (drizzle-zod generated) with a handwritten ProviderSchema + CreateProviderSchema / UpdateProviderSchema in api/schemas/providers.ts - Update providers handler to .parse() through the new schemas - Strip drizzle-zod generator blocks from userProvider.ts and the dead userModelInsertSchema / userModelSelectSchema from userModel.ts - Drop drizzle-zod dependency; drizzle-zod is being deprecated in drizzle v1 and its .pick()/.omit() TS output conflicts with the new whitelist derivation convention |
||
|
|
572202ae54 | feat(data-ordering): order-key infrastructure for sortable resources | ||
|
|
9f3be4bc19 |
feat: migrate agents storage to v2 main database (#14159)
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com> Co-authored-by: SuYao <sy20010504@gmail.com> |
||
|
|
9f4026f5ec | Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 | ||
|
|
c88f6aa787 |
refactor: stabilize ui package boundaries and theme contracts (#14328)
Co-authored-by: MyPrototypeWhat <daoquqiexing@gmail.com> Fixes #14331 |
||
|
|
260c5458f2 |
chore: release v1.9.2 (#14406)
### What this PR does Before this PR: - Version 1.9.1 was the latest release - Several user-facing bugs and feature requests needed to be addressed After this PR: - Bumps version to 1.9.2 - Updates release notes with bilingual (English/Chinese) changelog ### Summary of Changes This release includes 20 commits since v1.9.1, featuring: **New Features:** - Vietnamese language support (Tiếng Việt) - Agents can now author and register new skills directly from chat - Skills/memory tools now available to all agents **Bug Fixes:** - Agent settings now sync immediately to active sessions - Fixed telemetry being sent despite data collection disabled - Fixed CJK text search failures and added phrase search - Fixed Obsidian export silently failing - Fixed Ollama model loading and knowledge base issues - Fixed custom parameters not passing to Gemini API via NewAPI/AiHubMix - Various other fixes for Dify, Cherry Assistant, and OpenClaw **Included Commits:** - |
||
|
|
2120fddf4e |
fix: update node-abi for Electron 41 packaging (#14403)
### What this PR does Before this PR: Packaging failed after upgrading to Electron 41.2.1 because the pinned `node-abi` version could not resolve the ABI for the new Electron runtime. After this PR: Packaging uses `node-abi` 4.28.0, which recognizes Electron 41.2.1 and allows the build pipeline to resolve the correct ABI during packaging. <!-- (optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: --> Fixes #N/A ### Why we need it and why it was done in this way The following tradeoffs were made: A minimal override-only change was used so the fix stays suitable for a `hotfix/*` branch and avoids unrelated packaging or dependency refactors. The following alternatives were considered: Upgrading broader packaging dependencies such as `electron-builder` and related transitive tooling was considered, but rejected because it would increase scope and risk for a hotfix. Links to places where the discussion took place: <!-- optional: slack, other GH issue, mailinglist, ... --> N/A ### Breaking changes <!-- optional --> If this PR introduces breaking changes, please describe the changes and the impact on users. N/A ### Special notes for your reviewer This PR only updates the pinned `node-abi` override and lockfile entries required for Electron 41.2.1 packaging. Validation performed locally: - `pnpm format` - `pnpm test` - `pnpm lint` ### 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: kangfenmao <kangfenmao@qq.com> |
||
|
|
b85c28d50c |
fix(knowledge): support Ollama knowledge embeddings (#14172)
### What this PR does Before this PR: - Creating a knowledge base with an Ollama embedding model such as `nomic-embed-text` could fail during initialization with `Cannot read properties of undefined (reading '0')`. After this PR: - Knowledge base initialization keeps using `@cherrystudio/embedjs-ollama` instead of a Cherry Studio-only Ollama adapter. - The PR applies the Ollama response-handling hotfix in a scoped `pnpm` patch for `@cherrystudio/embedjs-ollama`. - The patched library handles the current `/api/embed` response shape and falls back to the legacy `/api/embeddings` response during dimension detection. - A focused regression test covers configured dimensions, current Ollama responses, and legacy fallback behavior. Fixes #14168 ### Why we need it and why it was done in this way The following tradeoffs were made: - Moved the fix from app-local code into a patched `@cherrystudio/embedjs-ollama` dependency so Cherry Studio can keep using the library abstraction on the frozen `main` branch. - Kept support for both current and legacy Ollama embedding APIs because the failure happens during dimension probing before any documents are added. The following alternatives were considered: - Keeping the Cherry Studio-only `OllamaEmbeddings` adapter introduced in the first revision of this PR. - Opening an upstream `CherryHQ/embed-js` PR first and waiting for a released package version before fixing Cherry Studio. - Patching `@langchain/ollama` or widening shared dependency changes on `main`. Links to places where the discussion took place: https://github.com/CherryHQ/cherry-studio/pull/14172#issuecomment-4229167072 ### Breaking changes If this PR introduces breaking changes, please describe the changes and the impact on users. None. ### Special notes for your reviewer - Per review, this PR no longer keeps a Cherry Studio-only Ollama adapter; the fix now lives in the patched `@cherrystudio/embedjs-ollama` dependency. - `pnpm exec vitest run src/main/knowledge/embedjs/embeddings/__tests__/OllamaEmbeddings.test.ts` passed. - `pnpm lint` completed successfully. - `pnpm test` still fails in pre-existing CherryClaw prompt tests under `src/main/services/agents/services/cherryclaw/__tests__/prompt.test.ts`; these failures are unrelated to this hotfix. ### 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 Fix knowledge base creation for Ollama embedding models such as `nomic-embed-text` by handling current and legacy Ollama embedding API responses through `@cherrystudio/embedjs-ollama` during dimension detection. ``` --------- Signed-off-by: 404-Page-Found <Lucas20220605@gmail.com> Co-authored-by: SuYao <sy20010504@gmail.com> |
||
|
|
d1652da1ff |
chore(deps): bump form-data from 2.3.3 to 4.0.4 (#14295)
Bumps [form-data](https://github.com/form-data/form-data) from 2.3.3 to 4.0.4. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/form-data/form-data/releases">form-data's releases</a>.</em></p> <blockquote> <h2>v4.0.4</h2> <h2><a href="https://github.com/form-data/form-data/compare/v4.0.3...v4.0.4">v4.0.4</a> - 2025-07-16</h2> <h3>Commits</h3> <ul> <li>[meta] add <code>auto-changelog</code> <a href=" |
||
|
|
365377bd03 |
chore(deps-dev): bump lodash from 4.17.21 to 4.18.1 (#14294)
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.18.1. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/lodash/lodash/releases">lodash's releases</a>.</em></p> <blockquote> <h2>4.18.1</h2> <h2>Bugs</h2> <p>Fixes a <code>ReferenceError</code> issue in <code>lodash</code> <code>lodash-es</code> <code>lodash-amd</code> and <code>lodash.template</code> when using the <code>template</code> and <code>fromPairs</code> functions from the modular builds. See <a href="https://redirect.github.com/lodash/lodash/issues/6167#issuecomment-4165269769">lodash/lodash#6167</a></p> <p>These defects were related to how lodash distributions are built from the main branch using <a href="https://github.com/lodash-archive/lodash-cli">https://github.com/lodash-archive/lodash-cli</a>. When internal dependencies change inside lodash functions, equivalent updates need to be made to a mapping in the lodash-cli. (hey, it was ahead of its time once upon a time!). We know this, but we missed it in the last release. It's the kind of thing that passes in CI, but fails bc the build is not the same thing you tested.</p> <p>There is no diff on main for this, but you can see the diffs for each of the npm packages on their respective branches:</p> <ul> <li><code>lodash</code>: <a href="https://github.com/lodash/lodash/compare/4.18.0-npm...4.18.1-npm">https://github.com/lodash/lodash/compare/4.18.0-npm...4.18.1-npm</a></li> <li><code>lodash-es</code>: <a href="https://github.com/lodash/lodash/compare/4.18.0-es...4.18.1-es">https://github.com/lodash/lodash/compare/4.18.0-es...4.18.1-es</a></li> <li><code>lodash-amd</code>: <a href="https://github.com/lodash/lodash/compare/4.18.0-amd...4.18.1-amd">https://github.com/lodash/lodash/compare/4.18.0-amd...4.18.1-amd</a></li> <li><code>lodash.template</code><a href="https://github.com/lodash/lodash/compare/4.18.0-npm-packages...4.18.1-npm-packages">https://github.com/lodash/lodash/compare/4.18.0-npm-packages...4.18.1-npm-packages</a></li> </ul> <h2>4.18.0</h2> <h2>v4.18.0</h2> <p><strong>Full Changelog</strong>: <a href="https://github.com/lodash/lodash/compare/4.17.23...4.18.0">https://github.com/lodash/lodash/compare/4.17.23...4.18.0</a></p> <h3>Security</h3> <p><strong><code>_.unset</code> / <code>_.omit</code></strong>: Fixed prototype pollution via <code>constructor</code>/<code>prototype</code> path traversal (<a href="https://github.com/lodash/lodash/security/advisories/GHSA-f23m-r3pf-42rh">GHSA-f23m-r3pf-42rh</a>, <a href=" |
||
|
|
3499c2ed9d |
chore(deps-dev): bump axios from 1.13.2 to 1.15.0 (#14293)
Bumps [axios](https://github.com/axios/axios) from 1.13.2 to 1.15.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/axios/axios/releases">axios's releases</a>.</em></p> <blockquote> <h2>v1.15.0</h2> <p>This release delivers two critical security patches, adds runtime support for Deno and Bun, and includes significant CI hardening, documentation improvements, and routine dependency updates.</p> <h2>⚠️ Important Changes</h2> <ul> <li><strong>Deprecation:</strong> <code>url.parse()</code> usage has been replaced to address Node.js deprecation warnings. If you are on a recent version of Node.js, this resolves console warnings you may have been seeing. (<strong><a href="https://redirect.github.com/axios/axios/issues/10625">#10625</a></strong>)</li> </ul> <h2>🔒 Security Fixes</h2> <ul> <li><strong>Proxy Handling:</strong> Fixed a <code>no_proxy</code> hostname normalisation bypass that could lead to Server-Side Request Forgery (SSRF). (<strong><a href="https://redirect.github.com/axios/axios/issues/10661">#10661</a></strong>)</li> <li><strong>Header Injection:</strong> Fixed an unrestricted cloud metadata exfiltration vulnerability via a header injection chain. (<strong><a href="https://redirect.github.com/axios/axios/issues/10660">#10660</a></strong>)</li> </ul> <h2>🚀 New Features</h2> <ul> <li><strong>Runtime Support:</strong> Added compatibility checks and documentation for Deno and Bun environments. (<strong><a href="https://redirect.github.com/axios/axios/issues/10652">#10652</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10653">#10653</a></strong>)</li> </ul> <h2>🔧 Maintenance & Chores</h2> <ul> <li><strong>CI Security:</strong> Hardened workflow permissions to least privilege, added the <code>zizmor</code> security scanner, pinned action versions, and gated npm publishing with OIDC and environment protection. (<strong><a href="https://redirect.github.com/axios/axios/issues/10618">#10618</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10619">#10619</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10627">#10627</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10637">#10637</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10666">#10666</a></strong>)</li> <li><strong>Dependencies:</strong> Bumped <code>serialize-javascript</code>, <code>handlebars</code>, <code>picomatch</code>, <code>vite</code>, and <code>denoland/setup-deno</code> to latest versions. Added a 7-day Dependabot cooldown period. (<strong><a href="https://redirect.github.com/axios/axios/issues/10574">#10574</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10572">#10572</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10568">#10568</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10663">#10663</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10664">#10664</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10665">#10665</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10669">#10669</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10670">#10670</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10616">#10616</a></strong>)</li> <li><strong>Documentation:</strong> Unified docs, improved <code>beforeRedirect</code> credential leakage example, clarified <code>withCredentials</code>/<code>withXSRFToken</code> behaviour, HTTP/2 support notes, async/await timeout error handling, header case preservation, and various typo fixes. (<strong><a href="https://redirect.github.com/axios/axios/issues/10649">#10649</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10624">#10624</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/7452">#7452</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/7471">#7471</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10654">#10654</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10644">#10644</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10589">#10589</a></strong>)</li> <li><strong>Housekeeping:</strong> Removed stale files, regenerated lockfile, and updated sponsor scripts and blocks. (<strong><a href="https://redirect.github.com/axios/axios/issues/10584">#10584</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10650">#10650</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10582">#10582</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10640">#10640</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10659">#10659</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10668">#10668</a></strong>)</li> <li><strong>Tests:</strong> Added regression coverage for urlencoded <code>Content-Type</code> casing. (<strong><a href="https://redirect.github.com/axios/axios/issues/10573">#10573</a></strong>)</li> </ul> <h2>🌟 New Contributors</h2> <p>We are thrilled to welcome our new contributors. Thank you for helping improve Axios:</p> <ul> <li><strong><a href="https://github.com/raashish1601"><code>@raashish1601</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10573">#10573</a></strong>)</li> <li><strong><a href="https://github.com/Kilros0817"><code>@Kilros0817</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10625">#10625</a></strong>)</li> <li><strong><a href="https://github.com/ashstrc"><code>@ashstrc</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10624">#10624</a></strong>)</li> <li><strong><a href="https://github.com/Abhi3975"><code>@Abhi3975</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10589">#10589</a></strong>)</li> <li><strong><a href="https://github.com/theamodhshetty"><code>@theamodhshetty</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/7452">#7452</a></strong>)</li> </ul> <h2>v1.14.0</h2> <p>This release focuses on compatibility fixes, adapter stability improvements, and test/tooling modernisation.</p> <h2>⚠️ Important Changes</h2> <ul> <li><strong>Breaking Changes:</strong> None identified in this release.</li> <li><strong>Action Required:</strong> If you rely on env-based proxy behaviour or CJS resolution edge-cases, validate your integration after upgrade (notably <code>proxy-from-env</code> v2 alignment and <code>main</code> entry compatibility fix).</li> </ul> <h2>🚀 New Features</h2> <ul> <li><strong>Runtime Features:</strong> No new end-user features were introduced in this release.</li> <li><strong>Test Coverage Expansion:</strong> Added broader smoke/module test coverage for CJS and ESM package usage. (<a href="https://redirect.github.com/axios/axios/pull/7510">#7510</a>)</li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Headers:</strong> Trim trailing CRLF in normalised header values. (<a href="https://redirect.github.com/axios/axios/pull/7456">#7456</a>)</li> <li><strong>HTTP/2:</strong> Close detached HTTP/2 sessions on timeout to avoid lingering sessions. (<a href="https://redirect.github.com/axios/axios/pull/7457">#7457</a>)</li> <li><strong>Fetch Adapter:</strong> Cancel <code>ReadableStream</code> created during request-stream capability probing to prevent async resource leaks. (<a href="https://redirect.github.com/axios/axios/pull/7515">#7515</a>)</li> <li><strong>Proxy Handling:</strong> Fixed env proxy behavior with <code>proxy-from-env</code> v2 usage. (<a href="https://redirect.github.com/axios/axios/pull/7499">#7499</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's changelog</a>.</em></p> <blockquote> <h2>v1.15.0 — April 7, 2026</h2> <p>This release delivers two critical security patches targeting header injection and SSRF via proxy bypass, adds official runtime support for Deno and Bun, and includes significant CI security hardening.</p> <h2>🔒 Security Fixes</h2> <ul> <li> <p><strong>Header Injection (CRLF):</strong> Rejects any header value containing <code>\r</code> or <code>\n</code> characters to block CRLF injection chains that could be used to exfiltrate cloud metadata (IMDS). Behavior change: headers with CR/LF now throw <code>"Invalid character in header content"</code>. (<strong><a href="https://redirect.github.com/axios/axios/issues/10660">#10660</a></strong>)</p> </li> <li> <p><strong>SSRF via <code>no_proxy</code> Bypass:</strong> Introduces a <code>shouldBypassProxy</code> helper that normalises hostnames (strips trailing dots, handles bracketed IPv6) before evaluating <code>no_proxy</code>/<code>NO_PROXY</code> rules, closing a gap that could cause loopback or internal hosts to be inadvertently proxied. (<strong><a href="https://redirect.github.com/axios/axios/issues/10661">#10661</a></strong>)</p> </li> </ul> <h2>🚀 New Features</h2> <ul> <li><strong>Deno & Bun Runtime Support:</strong> Added full smoke test suites for Deno and Bun, with CI workflows that run both runtimes before any release is cut. (<strong><a href="https://redirect.github.com/axios/axios/issues/10652">#10652</a></strong>)</li> </ul> <h2>🐛 Bug Fixes</h2> <ul> <li><strong>Node.js v22 Compatibility:</strong> Replaced deprecated <code>url.parse()</code> calls with the WHATWG <code>URL</code>/<code>URLSearchParams</code> API across examples, sandbox, and tests, eliminating <code>DEP0169</code> deprecation warnings on Node.js v22+. (<strong><a href="https://redirect.github.com/axios/axios/issues/10625">#10625</a></strong>)</li> </ul> <h2>🔧 Maintenance & Chores</h2> <ul> <li> <p><strong>CI Security Hardening:</strong> Added <a href="https://github.com/zizmorcore/zizmor">zizmor</a> GitHub Actions security scanner; switched npm publish to OIDC Trusted Publishing (removing the long-lived <code>NODE_AUTH_TOKEN</code>); pinned all action references to full commit SHAs; narrowed workflow permissions to least privilege; gated the publish step behind a dedicated <code>npm-publish</code> environment; and blocked the sponsor-block workflow from running on forks. (<strong><a href="https://redirect.github.com/axios/axios/issues/10618">#10618</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10619">#10619</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10627">#10627</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10637">#10637</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10641">#10641</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10666">#10666</a></strong>)</p> </li> <li> <p><strong>Docs:</strong> Clarified HTTP/2 support and the unsupported <code>httpVersion</code> option; added documentation for header case preservation; improved the <code>beforeRedirect</code> example to prevent accidental credential leakage. (<strong><a href="https://redirect.github.com/axios/axios/issues/10644">#10644</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10654">#10654</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10624">#10624</a></strong>)</p> </li> <li> <p><strong>Dependencies:</strong> Bumped <code>picomatch</code>, <code>handlebars</code>, <code>serialize-javascript</code>, <code>vite</code> (×3), <code>denoland/setup-deno</code>, and 4 additional dev dependencies to latest versions. (<strong><a href="https://redirect.github.com/axios/axios/issues/10564">#10564</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10565">#10565</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10567">#10567</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10568">#10568</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10572">#10572</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10574">#10574</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10663">#10663</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10664">#10664</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10665">#10665</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10669">#10669</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10670">#10670</a></strong>)</p> </li> </ul> <h2>🌟 New Contributors</h2> <p>We are thrilled to welcome our new contributors. Thank you for helping improve axios:</p> <ul> <li><strong><a href="https://github.com/Kilros0817"><code>@Kilros0817</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10625">#10625</a></strong>)</li> <li><strong><a href="https://github.com/shaanmajid"><code>@shaanmajid</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10616">#10616</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10617">#10617</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10618">#10618</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10619">#10619</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10637">#10637</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10641">#10641</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10666">#10666</a></strong>)</li> <li><strong><a href="https://github.com/ashstrc"><code>@ashstrc</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10624">#10624</a></strong>, <strong><a href="https://redirect.github.com/axios/axios/issues/10644">#10644</a></strong>)</li> <li><strong><a href="https://github.com/Abhi3975"><code>@Abhi3975</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10589">#10589</a></strong>)</li> <li><strong><a href="https://github.com/raashish1601"><code>@raashish1601</code></a></strong> (<strong><a href="https://redirect.github.com/axios/axios/issues/10573">#10573</a></strong>)</li> </ul> <p><a href="https://github.com/axios/axios/compare/v1.14.0...v1.15.0">Full Changelog</a></p> <hr /> <h2>v1.14.0 — March 27, 2026</h2> <p>This release fixes a security vulnerability in the <code>formidable</code> dependency, resolves a CommonJS compatibility regression, hardens proxy and HTTP/2 handling, and modernises the build and test toolchain.</p> <h2>🔒 Security Fixes</h2> <ul> <li><strong>Formidable Vulnerability:</strong> Upgraded <code>formidable</code> from v2 to v3 to address a reported arbitrary-file vulnerability. Updated test server and assertions to align with the v3 API. (<strong><a href="https://redirect.github.com/axios/axios/issues/7533">#7533</a></strong>)</li> </ul> <h2>🐛 Bug Fixes</h2> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
04b18ab7f4 | merge main into v2 | ||
|
|
bf3235be8e |
fix(selection): upgrade electron to 41.2.1 and drop resize workaround
Electron v40.8.3 (PR electron/electron#50301, backport of #49428) fixed the transparent + frameless window resize regression on Windows tracked as electron/electron#48554. The Windows-only manual resize workaround (custom 8-direction ResizeHandle + IPC + setBounds) is no longer needed. - Bump electron 40.8.0 -> 41.2.1 (latest stable) - Remove SelectionService.resizeActionWindow and its IPC handler - Remove ResizeHandle component, handleResizeStart and ResizeDirection type from SelectionActionApp; trim ReactMouseEvent and isWin imports - Remove preload resizeActionWindow bridge - Remove Selection_ActionWindowResize IPC channel Native resize now works uniformly across Windows/macOS/Linux. Signed-off-by: fullex <0xfullex@gmail.com> |
||
|
|
1fd54832e1 | Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 | ||
|
|
e54cfe97ea |
fix(agents): set NODE_PATH so spawned Claude Code process can resolve @img/sharp (#14183)
### What this PR does Before this PR: The forked Claude Agent SDK child process (`cli.js`) runs from `asar.unpacked` but cannot resolve native modules like `@img/sharp` that also live in `asar.unpacked`, because Node's module resolution doesn't search that directory by default. After this PR: Injects `NODE_PATH` pointing to the `asar.unpacked/node_modules` directory into the child process environment, so Node's module resolution finds `@img/sharp` and other native modules correctly. ### Why we need it and why it was done in this way The child process is forked via `node:child_process.fork()` with `ELECTRON_RUN_AS_NODE=1`. Its module resolution starts from the SDK's location inside `asar.unpacked` but doesn't automatically search sibling `node_modules` at the unpacked root. Setting `NODE_PATH` is the standard Node.js mechanism to add extra module search paths without patching module internals. The following alternatives were considered: - Patching `Module._resolveFilename` via a `--require` bootstrap — more invasive, harder to maintain. - Symlinking sharp into the SDK's own `node_modules` in `before-pack.js` — fragile across platforms. ### 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 and Keep it simple - [x] Self-review: I have reviewed my own code before requesting review from others ### Release note ```release-note NONE ``` --------- Signed-off-by: beyondkmp <beyondkmp@gmail.com> Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: suyao <sy20010504@gmail.com> |
||
|
|
bd61bad7ee | chore: release v1.9.1 | ||
|
|
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> |
||
|
|
798a15e919 |
feat(v2): knowledge service backend (#14090)
Co-authored-by: SuYao <sy20010504@gmail.com> Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com> |
||
|
|
780a884c67 |
feat(data): provider/model data migration and registry service (backend only) (#14115)
### What this PR does Before this PR: - v2 migration did not include provider/model data migration from legacy `llm` state. - Provider/model data APIs and handlers were incomplete. - `@cherrystudio/provider-registry` (formerly provider-catalog) package was not integrated into the data layer. After this PR: - Add provider/model migration path (`ProviderModelMigrator` + mappings) and register it in v2 migrator flow. - Add `@cherrystudio/provider-registry` package with JSON-based registry data, Zod-validated schemas, and lifecycle-managed `ProviderRegistryService`. - Complete provider/model schemas, services, handlers, shared API schemas/types, and model merger utility. - Complete provider API endpoints (`registry-models`, `auth-config`, `api-keys`) aligned with lifecycle DI patterns. **Note:** This PR is intentionally scoped to backend/data-layer only. Renderer consumer migration will be submitted in a separate PR to maintain domain separation. Fixes # N/A ### Why we need it and why it was done in this way The following tradeoffs were made: - Kept migration and data API implementation within current v2 architecture (handler -> service -> db schema) instead of adding temporary compatibility layers. - Replaced protobuf toolchain with JSON + Zod validation for simpler data pipeline and better debuggability. - Converted all numeric enums to string-valued `as-const` objects (EndpointType, ModelCapability, Modality, etc.) for runtime debuggability. - Unified separate `baseUrls`, `modelsApiUrls`, `reasoningFormatTypes` fields into a single `endpointConfigs` map keyed by EndpointType. The following alternatives were considered: - Keep protobuf-based registry data; rejected due to complexity of proto toolchain and poor debuggability of binary data. - Include renderer consumer migration in same PR; deferred to separate PR for cleaner domain boundaries. Links to places where the discussion took place: - Original combined PR: #14034 ### Breaking changes None. ### Special notes for your reviewer - This is a backend-only extraction from #14034, which contained both backend and renderer consumer code. The renderer migration will follow in a separate PR. - Please focus review on migration flow (`ProviderModelMigrator`), provider/model service contracts, and the registry package design. - The `@cherrystudio/provider-registry` package was renamed from `provider-catalog` and uses JSON data files instead of protobuf. ### 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 data layer, no user-facing changes) - [x] Self-review: I have reviewed my own code ### Release note ```release-note NONE ``` --------- Signed-off-by: jidan745le <420511176@qq.com> Signed-off-by: suyao <sy20010504@gmail.com> Co-authored-by: suyao <sy20010504@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com> |
||
|
|
6541948556 | Merge branch 'main' of github.com:CherryHQ/cherry-studio into v2 | ||
|
|
45463362c9 |
hotfix(analytics): track token usage with source distinction for chat and agent (#14149)
### What this PR does Before this PR: - Token usage tracking was missing for mini window, selection action window, and translate service (they call `fetchChatCompletion` but don't go through `baseCallbacks`) - Agent session token usage was not distinguished from regular chat usage - `baseCallbacks.ts` and `TranslateService.ts` had duplicate tracking that was redundant with `fetchChatCompletion` After this PR: - All `fetchChatCompletion` callers (chat, translate, mini window, selection action) are automatically tracked with `source: 'chat'` - Agent sessions are tracked in `baseCallbacks` with `source: 'agent'` - No duplicate tracking; each code path is tracked exactly once - Upgraded `@cherrystudio/analytics-client` to 1.3.0 with native `source` field support ### Why we need it and why it was done in this way Token usage analytics were incomplete — several code paths that consume tokens were not being tracked. Additionally, there was no way to distinguish whether token usage came from regular chat or agent sessions. The following tradeoffs were made: - Tracking is done via `onChunk` wrapper in `fetchChatCompletion` rather than requiring each caller to manually track, preventing future omissions - Agent tracking stays in `baseCallbacks` because agent sessions use `createAgentMessageStream` directly and bypass `fetchChatCompletion` The following alternatives were considered: - Adding tracking to each individual caller — rejected because it's error-prone and led to the current missing coverage ### Breaking changes None. ### Special notes for your reviewer - `fetchChatCompletion` now wraps `onChunk` to intercept `BLOCK_COMPLETE` and track usage — this covers chat, translate, mini window, and selection action - `baseCallbacks.ts` only tracks agent sessions (guarded by `isAgentSessionTopicId`) to avoid double-counting with `fetchChatCompletion` - The `source` field is `optional` in `@cherrystudio/analytics-client@1.3.0`, defaulting to `'chat'` ### 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 NONE ``` Signed-off-by: kangfenmao <kangfenmao@qq.com> |
||
|
|
af2a16a01a |
chore: release v1.9.0 (#14142)
### What this PR does This is a release PR for version 1.9.0. It updates the version number and release notes. Before this PR: - Version was set to 1.9.0-rc.0 (release candidate) - Release notes contained RC-specific content After this PR: - Version is now 1.9.0 (stable release) - Release notes updated with all bug fixes and improvements since RC ### Why we need it and why it was done in this way This marks the official 1.9.0 stable release after the RC testing period. The release includes all bug fixes committed after 1.9.0-rc.0. ### Breaking changes None. This is a version bump from RC to stable. ### Special notes for your reviewer **Included commits (since v1.9.0-rc.0):** - fix(models): add Ollama gemma4 format support for capability detection (#14036) - hotfix(mcp): preserve multi-element hub tool results (#14116) - fix: optimize agent bootstrap startup time (~1.6s → ~270ms) (#14098) - hotfix(channels): toggle single channel no longer reconnects all channels (#14112) - fix: prevent data loss when selecting model via keyboard shortcut (#14130) - fix: restore rich editor search state and scrolling (#14117) - fix(ci): restore missing Linux build dependencies in nightly workflow (#14105) - hotfix(build): include resources directory files excluded by glob pattern (#14121) - fix(agents): remove conflicting language instruction from Cherry Assistant (#14076) - hotfix(think): MiMo thinking toggle (#14109) - hotfix(renderer): rendering issue of the unescaped '|' in <sup> within Markdown tables. (#14092) ### 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 See release notes in electron-builder.yml for full details. Key fixes since RC: - [Models] Add Ollama gemma4 format support for Gemma 4 model capability detection - [MCP] Fix Hub-mode MCP tool calls silently truncating list-style responses - [Chat] Fix data loss when selecting model via keyboard shortcut - [Notes] Fix note editor search state and scrolling - [Build] Fix built-in skill files (.md) missing from packaged app - [Agents] Fix Cherry Assistant ignoring user's language - [Models] Fix Xiaomi MiMo thinking/non-thinking toggle behavior ``` Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> |
||
|
|
a83f98fd24 |
docs: consolidate bilingual docs, add link checker and architecture overview (#14138)
Co-authored-by: fullex <106392080+0xfullex@users.noreply.github.com> |
||
|
|
2e7b605b5b |
chore: release v1.9.0-rc.0 (#13987)
### What this PR does This is a release PR for Cherry Studio v1.9.0-rc.0. **Changes included:** - Bumped version from 1.8.4 to 1.9.0-rc.0 - Updated bilingual release notes in `electron-builder.yml` **Release Notes Summary:** ✨ New Features - CherryClaw autonomous agent type with personality-driven scheduling, Telegram integration, and sandbox mode - Terminal-style syntax highlighting for shell tool outputs - Flomo MCP integration for note capture - rtk token optimization (60-90% reduction) for agent shell commands - Improved agent tool rendering with syntax-highlighted diffs and file icons - AI-powered error diagnosis with classification and guided resolution - Topics list now respects pinTopicsToTop setting - Added endpoint option for aionly provider 🐛 Bug Fixes - new-api provider now uses configured host for Anthropic format requests - Claude Code sessions now respect proxy settings for child processes - Code tool validates working directory before launch - Fixed epub embedding failure - Fixed KaTeX backslash corruption in Notes editor - Fixed thinking time display race condition - Fixed Poe provider model loading - Fixed kimi-cli crash when uv binary not found - Fixed invalid env variable names for providers with dots in name - Fixed NVIDIA provider reasoning parameters for Qwen/DeepSeek/Kimi/Zhipu - Fixed Google Gemini web search for API-fetched models - Fixed Qwen3.5 model detection for 3.9 series - Fixed backup file size regression 💄 Improvements - Fixed macOS traffic light alignment ⚡ Performance - Optimized backup compression level for faster backups ### Checklist - [x] Review generated release notes in `electron-builder.yml` - [x] Verify version bump in `package.json` - [ ] CI passes - [ ] Merge to trigger release build ### Included Commits 52 commits since v1.8.4, including: - feat(agents): add CherryClaw autonomous agent type (#13359) - feat: add AI-powered error diagnosis and guided resolution (#13894) - feat: integrate rtk for reducing LLM token consumption (#13615) - feat(mcp): add flomo built-in server (#13928) - fix: resolve CherryIN supported_endpoint_types not being detected - fix: use configured host for new-api anthropic format requests (#13724) - fix(agents): route Claude Code child process through proxies (#13895) - fix: migrate epub to v2 async api (#13939) - fix(notes): prevent KaTeX backslash corruption (#13910) - fix(ThinkingBlock): prevent race condition in thinking time display (#13934) - fix(models): strip `models/` prefix from Google API model IDs (#13861) - perf(backup): adjust compression level for speed optimization (#13882) - And 40 more bug fixes and improvements --------- Co-authored-by: SuYao <sy20010504@gmail.com> |
||
|
|
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>
|