Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## v1.0.4-beta.7 (2026-05-11)
- Added Mistral as a built-in provider, including model icons, provider catalog support, and deeplink handling
- Agent runs now budget tool schemas and tool output more defensively, reducing oversized context failures and follow-up stalls
- Agent terminal execution is steadier when shells, working directories, or context compaction need fallback handling
- Disabled providers no longer trigger verification requests from settings screens
- Plugin MCP servers now keep their lifecycle more isolated, improving start/stop behavior and built-in plugin visibility
- 新增 Mistral 内置 Provider,补齐模型图标、Provider 目录与 deeplink 支持
- Agent 运行会更谨慎地预算工具 schema 与工具输出,减少上下文过大和后续执行卡住的问题
- 当 shell、工作目录或上下文压缩需要 fallback 时,Agent 终端执行更稳定
- 设置页不会再对已禁用的 Provider 发起验证请求
- Plugin MCP server 的生命周期隔离更清晰,启动、停止和内置插件展示更可靠

## v1.0.4-beta.6 (2026-05-09)
- Agents can now generate images right inside chat, with OpenAI image settings available when you want more control
- Image previews and image actions feel smoother, especially around generated results and tool output
Expand Down
19 changes: 19 additions & 0 deletions docs/features/mistral-provider-support/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Mistral Provider Support Plan

## Runtime

- Add `mistral` to `DEFAULT_PROVIDERS` with `apiType: "mistral"`, default base URL `https://api.mistral.ai/v1`, Mistral website links, and disabled default state.
- Register `mistral` in `providerRegistry` as an OpenAI-compatible AI SDK provider.
- Use provider DB model metadata for model list refreshes and use `generate-text` verification with `mistral-small-latest`.

## Renderer And Deeplinks

- Add `mistral` to provider DB-backed refresh hints.
- Add `mistral` to provider install custom types and the manual deeplink playground.
- Wire `ModelIcon.vue` to the existing Mistral color SVG.
- Expose Mistral AI in the custom provider API type select.

## Compatibility

- Existing users keep their stored provider settings. The provider helper appends the new default if it is missing.
- Existing custom providers with id `mistral` are not overwritten by migration code.
20 changes: 20 additions & 0 deletions docs/features/mistral-provider-support/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Mistral Provider Support Spec

## User Story

Users can enable Mistral AI from the built-in Model Providers list, enter a Mistral API key, refresh models, verify the provider, and use Mistral chat and vision-capable models without editing provider files or creating a custom OpenAI-compatible provider.

## Acceptance Criteria

- A disabled built-in provider with id `mistral` appears in default provider settings.
- The provider uses `https://api.mistral.ai/v1` as its default base URL and Bearer API key authentication.
- Mistral uses the existing OpenAI-compatible runtime with no new SDK dependency.
- Refreshing models maps existing provider DB metadata for Mistral, including vision, tool call, reasoning, context, and output limits.
- Provider verification sends a small generate-text request to `mistral-small-latest`.
- Provider install deeplinks support built-in `id: "mistral"` and custom `type: "mistral"`.

## Non-Goals

- Add a dedicated Mistral SDK package.
- Add new IPC routes or renderer APIs.
- Change existing custom provider behavior beyond allowing `mistral` as a supported type.
8 changes: 8 additions & 0 deletions docs/features/mistral-provider-support/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Mistral Provider Support Tasks

- [x] Add SDD spec, plan, and task documents.
- [x] Add built-in Mistral provider metadata.
- [x] Register Mistral in the AI SDK provider registry.
- [x] Add renderer, deeplink, icon, and manual playground wiring.
- [x] Add targeted tests for provider metadata, runtime mapping, verification, and icon/deeplink support.
- [x] Run formatting, i18n, lint, typecheck, and targeted tests.
24 changes: 24 additions & 0 deletions docs/issues/agent-tool-context-budget/plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,30 @@ consumes more context and fails on small formatting deviations.
- Add a compact tool-schema mode for legacy function-call fallback.
- Add UI diagnostics for "context budget pressure" and suggested remediation.

## Second Increment

- Add a provider-call preflight helper that estimates messages, tool definitions, the safety margin,
and the temporary effective output cap before every loop request.
- Reserve a 256-token safety margin for normal model context windows so off-by-one provider
validators do not reject otherwise fitted requests.
- When preflight pressure would reduce a normal request below 4000 output tokens, run an internal
recovery pass before the provider call: compact persisted old turns when enabled, then rely on the
request fitter to trim older in-memory messages while preserving the active tail.
- Write recovered messages back into the active request array so later tool-continuation loops use
the same compacted/trimmed history.
- Keep generation settings unchanged; only the provider call's `maxTokens` argument is reduced.
- Use the same safety-adjusted budget in tool-output fitting so continuation turns do not inject
tool results that leave the next request over the provider limit.
- Report zero effective output tokens when a fitted request still cannot fit at all, and fail before
calling the provider.

## Review Hardening

- Treat non-positive context windows as unknown/unbounded during request preflight, matching the
existing fitting and max-token helpers.
- Judge tool-output continuation fitting against the next preflight-fitted request shape, so older
history that would be trimmed before the next provider call does not falsely fail the tool result.

## Manual Validation Notes

For a MiniMax-M2.7 agent session, inspect trace/log output rather than running automated test
Expand Down
19 changes: 19 additions & 0 deletions docs/issues/agent-tool-context-budget/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,22 @@ Observed risk points:
- Legacy parser accepts complete function-call tags, a trailing unclosed function-call tag, and JSON
wrapped in Markdown fences.
- No ACP-specific behavior is required for the first increment.

## Second Increment: Context Pressure Backoff

Additional acceptance criteria:

- Every agent-loop provider request must satisfy
`estimated messages + tool schemas + effective maxTokens <= contextLength - 256` for normal model
windows.
- If the estimated input and configured request output would exceed that budget, DeepChat must
temporarily reduce only the per-call `maxTokens` value passed to the provider.
- If context pressure would reduce a normally sized request below 4000 output tokens, DeepChat must
internally recover context first, using auto-compaction when enabled and transient request-window
trimming otherwise.
- User-configured `maxTokens` values below 4000 are respected and do not force recovery by
themselves.
- If no output token can fit after request fitting, preflight reports `effectiveMaxTokens = 0`
instead of a positive budget.
- Context-pressure recovery updates the in-memory request history used by later tool-continuation
loops.
7 changes: 7 additions & 0 deletions docs/issues/agent-tool-context-budget/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
- [x] Preflight-fit provider-loop requests.
- [x] Add effective per-request output cap and shared budget module.
- [x] Harden legacy function-call parsing.
- [x] Add 256-token provider-call safety margin and preflight backoff.
- [x] Trigger internal compaction/trim recovery before pressure-shrunk calls below 4000 output.
- [x] Keep recovered request messages in sync for later provider-loop iterations.
- [x] Apply safety-adjusted budget checks to tool-output continuation fitting.
- [x] Drop orphaned tool results and invalid provider options before AI SDK requests.
- [x] Report zero effective output tokens for unfittable preflight results.
- [x] Harden preflight for unknown context windows and refitted tool continuations.
- [ ] Add request budget telemetry.
- [ ] Add reasoning retention budget.
- [ ] Add compact legacy tool schema mode.
27 changes: 27 additions & 0 deletions docs/issues/background-exec-shell-fallback/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Background Exec Shell Fallback Plan

## Approach

- Centralize fallback behavior in `getUserShell()` so foreground exec, background exec, and shell
environment bootstrap share the same shell resolution.
- Check absolute shell candidates for path and executable availability before returning them.
- Search `PATH` plus DeepChat default paths when `SHELL` is a bare command name.
- Use conservative POSIX fallback chains and keep Windows behavior intact.
- Return only resolved fallback candidates from the platform fallback chain; if none resolve, use
`/bin/sh` as the final default.
- Validate shell process working directories before calling `spawn`, because Node reports missing
`cwd` as `spawn <shell> ENOENT`.

## Affected Paths

- `src/main/lib/agentRuntime/shellEnvHelper.ts`
- `src/main/lib/agentRuntime/backgroundExecSessionManager.ts`
- Existing shell environment and background exec tests.

## Compatibility

- Existing valid user shells are still preferred.
- Missing or non-executable shells now fall back to an available POSIX shell instead of failing
with `ENOENT`/`EACCES`.
- Plain `sh` bootstrap no longer receives login-shell flags it may not support.
- Missing working directories now produce a direct working-directory error.
25 changes: 25 additions & 0 deletions docs/issues/background-exec-shell-fallback/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Background Exec Shell Fallback

## User Story

Users can run foreground and background shell commands even when the configured POSIX login shell
path, such as `/bin/zsh`, is unavailable in the current runtime environment.

## Acceptance Criteria

- POSIX shell execution does not blindly spawn a missing `process.env.SHELL` path.
- POSIX shell fallback skips existing but non-executable shell candidates.
- macOS falls back from zsh to bash and then sh; Linux falls back from bash to sh and then zsh.
- If no configured or platform fallback shell resolves, DeepChat uses `/bin/sh` instead of an
unchecked rejected candidate.
- Background exec sessions use the resolved executable shell path.
- Shell environment bootstrap uses plain `sh -c` flags when the fallback is `sh`.
- Missing or inaccessible working directories are reported before spawn instead of surfacing as a
misleading shell `ENOENT`.
- Windows shell selection is unchanged.

## Non-goals

- Do not add renderer settings or IPC for shell configuration.
- Do not persist a detected fallback shell.
- Do not change user command permission behavior or output formatting.
10 changes: 10 additions & 0 deletions docs/issues/background-exec-shell-fallback/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Background Exec Shell Fallback Tasks

- [x] Document the issue and desired behavior.
- [x] Add available shell resolution and POSIX fallback ordering.
- [x] Verify fallback shell candidates are executable before spawn.
- [x] Avoid returning an unchecked platform fallback after candidate validation fails.
- [x] Avoid login bootstrap flags for plain `sh`.
- [x] Validate spawn working directories before launching shell processes.
- [x] Add unit coverage for missing configured shell fallback.
- [x] Run format, i18n, lint, typecheck, and targeted tests.
15 changes: 15 additions & 0 deletions docs/issues/beta-7-release-test-gate/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Plan

## Scope

- Update release metadata for the next beta version.
- Repair test fixtures that lag behind the structured message/search table additions.
- Keep platform path expectations stable on macOS `/var` and `/private/var` aliases.

## Validation

- Run `pnpm run format`.
- Run `pnpm run i18n`.
- Run `pnpm run lint`.
- Run `pnpm run typecheck`.
- Run focused failing test files, then the full test suite if practical.
21 changes: 21 additions & 0 deletions docs/issues/beta-7-release-test-gate/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Beta 7 Release Test Gate

## User Story

As a maintainer preparing `v1.0.4-beta.7`, I need the local release gate to pass so the beta branch is cut from a verified `dev` commit.

## Acceptance Criteria

- Release metadata reflects `v1.0.4-beta.7`.
- Required release checks pass locally.
- Test failures caused by stale mocks or platform-sensitive assertions are fixed before cutting the release branch.

## Non-goals

- No unrelated feature work.
- No changelog entries for test-only maintenance.

## Constraints

- Preserve the existing `dev` to `release/<version>` flow.
- Keep release branch contents identical to a commit on `dev`.
8 changes: 8 additions & 0 deletions docs/issues/beta-7-release-test-gate/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Tasks

- [x] Inspect release state and choose `v1.0.4-beta.7`.
- [x] Update `package.json` and `CHANGELOG.md`.
- [x] Fix stale release-gate tests.
- [x] Re-run release checks and focused tests.
- [ ] Commit metadata and test-gate fixes on `dev`.
- [ ] Cut and push `release/v1.0.4-beta.7`.
32 changes: 32 additions & 0 deletions docs/issues/plugin-mcp-lifecycle-isolation/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Plugin MCP Lifecycle Isolation Plan

## Architecture

- Treat plugin MCP servers as managed plugin resources when `ownerPluginId` is present or
`source/sourceId` identifies a plugin.
- Keep plugin-owned server configs in the MCP config store for compatibility, but branch lifecycle
behavior in `McpPresenter`.
- Store transient per-server runtime errors in `ServerManager` and expose them through
`IMCPPresenter.getServerLastError`.

## Implementation

- Update MCP initialization and global enable/disable to skip plugin-owned servers when applying the
global switch.
- Start plugin MCP servers from `PluginPresenter` without checking the global MCP setting.
- Filter tools, prompts, and resources so global MCP disabled hides non-plugin results but keeps
plugin-owned results.
- Suppress global MCP error notifications for plugin-owned start/listTools failures.
- Surface plugin MCP errors in plugin list and CUA settings status.

## Test Strategy

- Add main-process tests for global switch isolation and plugin start behavior.
- Add error-notification tests for plugin-owned connection and tool-list failures.
- Add renderer tests for disabled-global MCP state with plugin tools still visible.
- Add CUA settings regression coverage for MCP error state.

## Risks

- Moderate. MCP tools are shared across runtime and UI surfaces, so filtering must happen in the
presenter/store boundaries without changing stored config.
26 changes: 26 additions & 0 deletions docs/issues/plugin-mcp-lifecycle-isolation/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Plugin MCP Lifecycle Isolation

## User Story

As a user with the CUA plugin enabled, I want the plugin MCP runtime to follow plugin state rather
than the global MCP switch, so Computer Use remains available when I disable normal MCP tools and
does not spam global connection failure toasts.

## Acceptance Criteria

- The global MCP switch starts and stops only non-plugin MCP servers.
- Plugin-owned MCP servers are identified by `ownerPluginId` or `source: plugin`.
- Enabled plugin MCP servers start when the plugin is active even if global MCP is disabled.
- Plugin MCP connection and tool-list failures do not show global MCP error toasts.
- Plugin MCP failures are visible from plugin status surfaces.
- DeepChat agent tools can still include plugin MCP tools while global MCP is disabled.

## Non-goals

- Redesigning plugin installation or runtime detection.
- Changing ACP agent MCP selection behavior.
- Migrating existing MCP settings.

## Open Questions

None.
9 changes: 9 additions & 0 deletions docs/issues/plugin-mcp-lifecycle-isolation/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Plugin MCP Lifecycle Isolation Tasks

- [x] Document plugin MCP lifecycle requirements.
- [x] Make MCP presenter lifecycle owner-aware.
- [x] Suppress plugin MCP global notifications and track last error.
- [x] Keep plugin MCP visible in renderer state when global MCP is disabled.
- [x] Surface plugin MCP errors in plugin settings UI.
- [x] Add focused regression coverage.
- [x] Run format, i18n, lint, and focused tests.
21 changes: 21 additions & 0 deletions docs/issues/provider-validation-disabled/plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Provider Validation Disabled State Plan

## Scope

The regression is limited to provider settings verification controls in renderer components.

## Implementation

- Gate verify-key entry points on `provider.enable` in the affected settings components.
- Disable the visible verify buttons so the UI matches the runtime behavior.
- Add a focused renderer regression test around `ProviderApiConfig`, which is the shared verify
entry point for generic providers.

## Test Strategy

- Run the focused renderer test for `ProviderApiConfig`.
- Run repository-required formatting, i18n, and lint checks when dependencies are available.

## Risks

- Low. The change only blocks verification while a provider is explicitly disabled.
22 changes: 22 additions & 0 deletions docs/issues/provider-validation-disabled/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Provider Validation Disabled State

## User Story

As a user editing provider settings, I want the verify-key action to stay unavailable while the
provider is disabled so that I do not see a misleading `Provider not initialized` error.

## Acceptance Criteria

- Disabled providers do not open the model check flow from the generic verify-key action.
- Disabled providers do not run inline verification handlers that would surface the initialization
error.
- Enabled providers keep the existing verification behavior.

## Non-goals

- Redesigning the provider settings layout.
- Changing provider initialization behavior in the main process.

## Open Questions

None.
7 changes: 7 additions & 0 deletions docs/issues/provider-validation-disabled/tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Provider Validation Disabled State Tasks

- [x] Confirm the verify-key error is triggered from disabled providers.
- [x] Guard verification actions behind the provider enabled state.
- [x] Add focused renderer regression coverage for the shared verify button.
- [ ] Run `pnpm run format`, `pnpm run i18n`, and `pnpm run lint` (blocked locally: `pnpm install`
cannot fetch `https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz` in this sandbox).
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "DeepChat",
"version": "1.0.4-beta.6",
"version": "1.0.4-beta.7",
"description": "DeepChat,一个简单易用的 Agent 客户端",
"main": "./out/main/index.js",
"author": "ThinkInAIXYZ",
Expand Down
7 changes: 7 additions & 0 deletions plugins/cua/settings/assets/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,19 @@ async function refreshStatus() {
const cuaMcp = status.mcpServers?.find((server) => server.serverId === 'cua-driver')
if (!cuaMcp) {
setText(mcpStateNode, 'Unavailable')
setMessage('')
} else if (cuaMcp.lastError) {
setText(mcpStateNode, 'Error')
setMessage(cuaMcp.lastError)
} else if (cuaMcp.running) {
setText(mcpStateNode, 'Running')
setMessage('')
} else if (cuaMcp.enabled) {
setText(mcpStateNode, 'Stopped')
setMessage('')
} else {
setText(mcpStateNode, 'Disabled')
setMessage('')
}
}

Expand Down
Loading
Loading