Commit Graph

96 Commits

Author SHA1 Message Date
cyq 73cd721665 feat(tui): add mention browser completions 2026-06-01 17:33:41 -07:00
Hunter Bown ae2000b59a docs(tui): align statusline customization limits 2026-06-01 17:20:49 -07:00
cyq 9bd08c2f1c docs(tui): document statusline footer items 2026-06-01 17:20:05 -07:00
Hunter Bown bb64018a15 feat(tui): add configurable auto-compact threshold
Refs #1722

Preserves auto_compact as opt-in, adds the saved threshold setting, keeps the 500K hard floor, and wires Ctrl+L as a manual compaction shortcut for context-pressure recovery.

Harvested from PR #1723 by @aboimpinto

Co-authored-by: Paulo Aboim Pinto <aboimpinto@gmail.com>
2026-06-01 14:09:49 -07:00
Hunter B 69cff93754 docs(config): use exact path in permissions example 2026-06-01 05:43:45 -07:00
greyfreedom 3df018994f feat(config): load typed ask permissions file
(cherry picked from commit fb77cf1e0946a061376e5e9a8fc9422dddd98419)
2026-06-01 05:43:26 -07:00
Hunter B 78facf9239 chore: home-polish for v0.8.49
- Add completion_sound to config.example.toml notifications section
  (off/beep/bell, default 'beep', introduced in v0.8.48)
- Add kimi-k2.6 to Default Models comments in config.example.toml
  (default Moonshot/Kimi model, provider section already added)
- Fix stale v0.8.47 reference in docs/PROVIDERS.md Planned section
  (now says v0.8.48+, reflecting current milestones)
2026-06-01 02:33:40 -07:00
Hunter B f094db9e02 feat: add missing [providers.moonshot] section to config.example.toml
Moonshot/Kimi is a shipped provider with full support (model registry entry,
provider ID, env var plumbing, CLI provider picker), but config.example.toml
was missing its [providers.moonshot] table block while all other 15 providers
had one. This made Moonshot the only shipped provider absent from the example.

Added the section between siliconflow and sglang, matching the shipped-provider
ordering in docs/PROVIDERS.md. Includes the Kimi Code alternate path and
kimi_oauth auth_mode comment.
2026-06-01 02:33:40 -07:00
Hunter B ffb871b9db fix: remove stale qwen3.7-max references from config.example.toml
v0.8.48 removed the Qwen 3.7 Max preset (it's a hosted model, not open-weight).
Two references remained in config.example.toml:
- Default Models comment (line 41)
- OpenRouter provider section comment (line 280)

These stale references could confuse users into trying a removed model.
2026-06-01 02:33:40 -07:00
Hunter B 2b69f4e041 chore: polish codewhale home defaults 2026-05-31 19:22:12 -07:00
Hunter B a9a4213d39 fix(tui): make startup update checks configurable 2026-05-31 17:06:20 -07:00
Hunter B d6baf20721 Migrate file secrets to codewhale home 2026-05-31 15:30:35 -07:00
Hunter Bown 5a80556eb2 feat(models): add recent large OpenRouter models (#2461) 2026-05-31 11:26:25 -07:00
implecao 70ef86c600 feat(web_search): add Volcengine Ark search provider
Add Volcengine (火山引擎) as a new SearchProvider in web_search tool.
Uses Volcengine's Responses API with `tools: [{type: "web_search"}]`
and strict JSON prompt constraints to extract structured search results.

- Free tier: 20K queries/month per API key
- API key resolution: [search] api_key → VOLCENGINE_API_KEY →
  VOLCENGINE_ARK_API_KEY → ARK_API_KEY env vars
- Select via `DEEPSEEK_SEARCH_PROVIDER=volcengine` or
  `[search] provider = "volcengine"` in config.toml

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 03:54:09 -07:00
Paulo Aboim Pinto f488cd8e00 feat(tui): add pluggable tool registry (#2420)
Thanks @aboimpinto.

Adds a self-describing local plugin/override tool registry, keeps explicit [tools.overrides] above auto-discovered scripts, makes plugin discovery deterministic, hardens child-process stdin/stdout behavior, and updates the local plugin examples.

Validation:
- cargo fmt --all -- --check
- git diff --check
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target/fix-2420-rebase cargo test -p codewhale-tui tools::plugin --all-features
- CARGO_TARGET_DIR=/Volumes/VIXinSSD/codewhale-target/fix-2420-rebase cargo test -p codewhale-tui tools::registry --all-features
2026-05-31 03:34:54 -07:00
Hunter B 678484ae1d docs(provider): clarify SiliconFlow provider entries 2026-05-31 00:24:10 -07:00
Lee-take 4861bb2797 Add SiliconFlow provider support
Add SiliconFlow as an additive OpenAI-compatible hosted provider across config, secrets, CLI, agent registry, TUI runtime, picker, and docs.

Credit: based in part on the SiliconFlow provider direction from #1864 by @qychen2001, extended here with broader registry, documentation, and test coverage on current main.
2026-05-31 00:00:38 -07:00
Hunter B 0572aff79d fix: refresh Volcengine provider registry 2026-05-30 23:30:57 -07:00
Hunter B 12c9cd4193 Merge main into Baidu search provider 2026-05-30 22:39:13 -07:00
AdityaG 3f4c4496f2 feat: add Xiaomi MiMo provider
Adds native xiaomi-mimo provider configuration, auth/env aliases, model registry entries, TUI request handling, tests, and docs. Keeps credentials in existing provider-scoped config/env/keyring paths and uses placeholders only in docs.
2026-05-30 22:16:01 -07:00
Fann Hoo efb63df66e feat(lsp): add Java and Vue language server defaults 2026-05-30 19:26:42 -07:00
LING71671 02d1145add docs: clarify custom provider configuration 2026-05-30 19:15:31 -07:00
jimmyzhuu e227efbd80 docs: document baidu search backend 2026-05-30 10:52:27 +08:00
Zhao Xiaohong ee03d1fd80 feat(web): add Metaso as a web search provider (metaso.cn) (#2059)
Adds Metaso AI Search as a new SearchProvider option alongside Bing,
DuckDuckGo, Tavily, and Bocha.

Co-authored-by: Zhao Xiaohong <zhaoxiaohong@metasota.ai>
2026-05-26 10:31:09 -05:00
Hunter Bown 2a41102e0c feat: defer low-value native tools by default, reduce catalog tokens 73% (#2076) 2026-05-26 10:08:09 -05:00
Hunter Bown 1763261503 v0.8.46: release archives, sandbox depth, quick fixes, web install, docs
* docs: v0.8.46 CHANGELOG — platform archives, palette, sub-agents, sandbox, web install, search fixes

Closes #2188

* feat(v0.8.46): quick fixes — palette, model picker Esc, sub-agent sidebar, shell chip, model name casing, CVE bump (#2212)

* fix: bump qs to >=6.15.2 for CVE-2026-8723

Add qs override in feishu-bridge package.json to force transitive
dependency resolution to >=6.15.2, addressing CVE-2026-8723.

Refs: #2198

* fix: Esc in model picker applies last-highlighted choice

Previously Esc reverted to the initial model when the user hadn't
moved the selection. Now Esc always applies the currently highlighted
model and thinking-effort tier, making Esc consistent with Enter.

Also updates the picker footer hint from 'Esc cancel' to 'Esc apply'.

Refs: #2196

* feat: show ' shell running' chip in TUI footer

Adds a footer_shell_chip function that displays a ' shell running'
status chip in the footer's right cluster whenever a foreground shell
command is active via exec_shell. The chip is always visible regardless
of user-configured status items.

Refs: #2194

* feat: auto-collapse finished sub-agents in sidebar

When a sub-agent completes (status = 'done'), its detail lines
(id, steps, duration, progress) are now hidden in the sidebar agents
panel. Only the summary label line is shown, keeping the sidebar
compact. Running agents still show full detail.

Refs: #2195

* feat: refresh Whale dark palette for better contrast

Improve contrast and layer separation in the Whale dark theme:
- Deepen base background for more depth (10,17,32)
- Lighten panel (22,34,56) for clearer distinction from bg
- Lighten elevated surface (36,52,78) for better elevation
- Lighten selection (48,68,100) for clearer selected state
- Boost text hint (138,150,174) and dim (118,130,156) readability
- Brighter border (52,88,145) for better edge definition
- Update tool surface colors for consistency

Refs: #2197

* fix: preserve model name casing in normalize_model_name_for_provider

When the user enters a model name like 'DeepSeek-V4-Flash', the
normalizer was lowercasing it to 'deepseek-v4-flash' via the
canonical_official_deepseek_model_id function. Now the normalizer
preserves the caller's casing when the input already matches a known
model id case-insensitively. Compact aliases like 'deepseek-v4pro'
are still rewritten to 'deepseek-v4-pro'.

Refs: #2109

* feat(web): install download tile with arch detection, SHA256, China mirrors + companion binary fix (#2213)

* fix(web): download both codewhale and codewhale-tui binaries in install snippets

The SNIPPETS map only fetched one binary per platform, causing the
dispatcher to fail with MISSING_COMPANION_BINARY. Every arch now
downloads both codewhale AND codewhale-tui side-by-side.

- macOS/Linux: added second curl + combined chmod/xattr/mv for tui
- Windows: added second Invoke-WebRequest for codewhale-tui.exe
- VERIFY: PowerShell now hashes both binaries; Unix --ignore-missing
  covers all present binaries in a single sha256sum pass

* feat(web): add install download tile with arch detection, SHA256, and China mirrors (#2192)

* feat(sandbox/linux): process hardening — PR_SET_DUMPABLE, NO_NEW_PRIVS, RLIMIT_CORE (#2214)

* feat(sandbox/linux): add process hardening module — PR_SET_DUMPABLE, NO_NEW_PRIVS, RLIMIT_CORE (#2183)

* feat(sandbox/linux): seccomp filter + bwrap passthrough

- seccomp: BPF filter whitelisting safe syscalls, denying ptrace/mount/kexec
  and other dangerous syscalls. Uses raw BPF instructions via libc prctl to
  avoid external dependencies (#2182).
- bwrap: optional bubblewrap passthrough when /usr/bin/bwrap is present
  and [sandbox] prefer_bwrap=true in config. Creates read-only rootfs with
  write access limited to the working directory (#2184).
- landlock detect_denial extended to recognize seccomp SIGSYS/"Bad system
  call" patterns alongside existing Landlock EACCES/EPERM detection.
- SandboxManager gains prefer_bwrap field; set_prefer_bwrap on ShellManager.
- EngineConfig gains prefer_bwrap field, wired through main/ui/runtime_threads.
- Diagnostics now reports bwrap_available and cgroup_version.
- config.example.toml documents the prefer_bwrap key.

Pre-existing clippy fixes picked up in the same build:
- collapsible_if in ui.rs version-check
- cmp_owned in goal.rs test
- consecutive str::replace in normalize_auth_mode

Closes #2182, closes #2184

* docs: add cross-links to issue and PR templates in CONTRIBUTING.md (#2215)

- Link .github/ISSUE_TEMPLATE/bug_report.md and feature_request.md from
  the Reporting Issues section
- Link .github/PULL_REQUEST_TEMPLATE.md from the Pull Request Guidelines
  section

* feat(release): bundle platform archives with install scripts (#2216)

- Add bundle job to release workflow that creates per-platform archives
  (tar.gz for Linux/macOS, .zip for Windows) containing both codewhale
  and codewhale-tui binaries plus install scripts
- Create install.bat (Windows) — copies binaries to %USERPROFILE%\bin
- Create install.sh (Unix) — copies binaries to ~/.local/bin
- Windows gets a portable .zip variant without install script
- Release notes updated to promote archives as primary download method
- Individual binaries retained for npm wrapper and scripting

Closes #2193

* fix(web_search): fall back to DuckDuckGo when Bing returns zero results (#2130)

When the configured search provider is Bing and the query returns zero
results (common for technical/compound queries), fall through to the
DuckDuckGo path instead of reporting empty. A provenance message is
surfaced: "Bing returned no results; used DuckDuckGo fallback".

Also adds Security and Code of Conduct cross-links to CONTRIBUTING.md
per the sub-agent renovation (#2203).

* docs: SANDBOX.md threat model + RFCs for persistence and MCP + SandboxExecutor trait

- docs/SANDBOX.md: complete threat model describing each platform's sandbox
  (Seatbelt, Landlock, seccomp, process hardening, bwrap, Windows v1).
  Covers defense-in-depth layering, config keys, denial detection, limitations.
- docs/rfcs/2189-persistence-sqlite.md: RFC for SQLite migration (drafted by sub-agent)
- docs/rfcs/2190-mcp-modularization.md: RFC for MCP crate split into
  protocol/client/server with OAuth support
- crates/tui/src/sandbox/policy.rs: SandboxExecutor trait definition and
  SafetyLevel→SandboxPolicyBehavior mapping function with tests

Closes #2180, closes #2186, closes #2189, closes #2190

* feat: sandbox parity tests + remove sub-agent 100-turn cap

- Add sandbox parity tests covering platform detection, denial patterns,
  bwrap preference, and policy consistency across modes (#2187)
- Remove arbitrary 100-turn sub-agent cap: DEFAULT_MAX_STEPS changed
  from 100 to u32::MAX. Sub-agents now run until they produce a final
  text response, are cancelled by the parent, or hit a configured
  explicit budget (#2034)

Closes #2187, closes #2034
2026-05-26 09:52:22 -05:00
Hunter Bown 898cf2d1e1 docs(config): add missing openrouter and novita provider sections 2026-05-23 22:37:16 -05:00
Hunter Bown 5fa24733e9 chore(rebrand): update repository links for CodeWhale 2026-05-23 14:07:36 -05:00
Hunter Bown ddaabbfed2 chore(rebrand): finish codewhale release surfaces 2026-05-23 13:41:46 -05:00
Hunter Bown ad122fd6f8 feat(subagents): make step API timeout configurable 2026-05-21 00:45:04 +08:00
Hunter Bown 8597afc076 feat(provider): add Wanjie Ark support 2026-05-21 00:02:02 +08:00
Hunter Bown a3f88bf6cf fix(search): default web search to bing (#1619)
Summary:
- add Bing as explicit default web_search provider
- keep explicit DuckDuckGo configuration supported
- update docs/help/config examples

Validation: CI green before merge.
2026-05-14 03:31:15 -05:00
Hunter Bown a4637fe7d1 fix(settings): reduce motion in VTE flicker terminals
Harvested from PR #1527 by @axobase001.

Co-authored-by: axobase001 <dengzhuoran9@gmail.com>
2026-05-12 23:39:44 -05:00
Hunter Bown f964e2fd37 fix(snapshot): cap workspace size at 2 GB before first side-repo init
Users reported running `deepseek-tui` inside project directories
with hundreds of GB of content — ML datasets, model weights
(`.safetensors`, `.gguf`, `.pt`, `.onnx`), Docker image dumps,
parquet / arrow caches, anything that falls outside the snapshot
built-in excludes. The pre/post-turn snapshot path called
`SnapshotRepo::open_or_init` which initialized the side git repo
and then ran `git add -A` — which walked the entire workspace
indexing every file. On a 100-300 GB directory this hung the TUI
for minutes-to-hours while git churned through the index.

The pre-existing v0.8.27 fixes (#1112: retention cap, mid-session
prune, expanded built-in excludes) addressed the orthogonal
"snapshots grow unbounded over many turns" angle but did nothing
to prevent the first snapshot from being impossible to take.

This change adds `estimate_workspace_size_bounded()` — a bounded
`ignore::WalkBuilder` walk that respects `.gitignore` and the
snapshot module's existing skip list (`node_modules/`, `target/`,
`.next/`, `.venv/`, `__pycache__/`, etc.). The walk early-exits
at either the byte cap or 200,000 file entries, returning `None`
to signal "too big to snapshot."

`SnapshotRepo::open_or_init_with_cap(workspace, cap_bytes)` calls
the estimator *before* the side `git init`, and returns
`Err(InvalidInput)` with a "workspace too large" reason — which
`turn::snapshot_with_label` already logs at WARN and continues
past, so a too-large workspace silently disables snapshots
without blocking any turn. The check is paid only on first init;
subsequent snapshots through the existing side repo skip it.

Plumbing:
- `SnapshotsConfig.max_workspace_gb` (default 2, `0` disables)
- `EngineConfig.snapshots_max_workspace_bytes` resolved at engine
  construction from `config.snapshots_config().max_workspace_gb`
- `pre_turn_snapshot` / `post_turn_snapshot` / `pre_tool_snapshot`
  take a `cap_bytes: u64` argument threaded from the engine
- `SnapshotRepo::open_or_init` retains its v0.8.31 signature as a
  thin wrapper over `open_or_init_with_cap` using the default cap
- `config.example.toml` documents the new `max_workspace_gb` knob
  with the "set to 0 to disable" escape hatch for users with
  legitimate large monorepos

Six new tests pin both the estimator (under-cap returns Some,
over-cap returns None, builtin-excluded dirs skipped, cap=0
disables the bound) and the `open_or_init_with_cap` integration
(oversized workspace fails with the right error and references
the config knob; cap=0 succeeds even on oversized content).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 02:11:10 -05:00
Hunter Bown 3aaf0ad95e feat(vision): add image_analyze tool gated behind vision_model feature flag
`image_analyze` sends an image file to an OpenAI-compatible vision
endpoint and returns the model's natural-language description.
Complements `image_ocr` (which uses local tesseract for "what text
is on this image"); `image_analyze` is for "what is this image
about" — visual reasoning the local OCR engine can't do.

Trust-boundary scope: **two-step opt-in only**.

1. The feature is gated by `[features] vision_model = true` —
   default `false`.
2. The tool needs a `[vision_model]` config block specifying
   `model` (with optional `api_key` / `base_url` — falls back to
   the main config api_key + the OpenAI base URL).

Without both, the tool isn't registered, so no install fires a
vision API call without explicit user setup. Workspace boundary:
the tool rejects absolute paths and any `..` parent-dir
traversal before any base64 encoding or HTTP call. Stateless —
each call sends only the requested image + optional prompt; no
session, no conversation history attached. Supports PNG, JPEG,
GIF, WebP, and BMP inputs.

**Billing**: each call hits the configured vision endpoint
(OpenAI by default — `gpt-4o-mini` / `gpt-4o` family commonly
configured). Users with their own deployments (Gemini, Claude
Vision via OpenAI shim, local llama.cpp) can point `base_url` /
`api_key` at the alternative.

Tests cover the tool metadata (read-only capability, correct
name), MIME-type detection across the supported formats and the
unsupported-format rejection path, and the workspace-boundary
checks (absolute paths and `..` traversal both reject before
any API call). Skipped from the upstream PR: the
`.github/workflows/sync-cnb.yml` rewrite, which v0.8.31 already
addressed with the concurrency/scoped-push refactor; landing the
older form would regress that commit.

Resolved a clippy::collapsible_if in tool_setup.rs (the
`if feature && let Some(cfg) = ...` form) to satisfy the
workspace -D warnings gate.

Harvested from PR #1467 by @MMMarcinho

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:03:19 -05:00
Hunter Bown 8f33e4bd48 feat(providers): add AtlasCloud as a first-class provider
AtlasCloud (https://atlascloud.ai) hosts the V4 family on its own
DeepSeek-compatible endpoint at `https://api.atlascloud.ai/v1`, and
several contributors had been running it through the
OpenAI-compatible passthrough with manual `base_url` / model
overrides. Selecting `provider = "atlascloud"` in
`~/.deepseek/config.toml` (or via `DEEPSEEK_PROVIDER=atlascloud`)
now wires up:

- documented `DEFAULT_ATLASCLOUD_BASE_URL` /
  `DEFAULT_ATLASCLOUD_MODEL` defaults so a fresh install needs
  only the api_key
- a `[providers.atlascloud]` config block with the same fields
  every other named provider exposes (api_key / base_url / model
  / http_headers)
- `ATLASCLOUD_API_KEY` env var path, including the secrets test
  cleanup loop so per-test env hygiene continues to work
- the provider-picker / `/provider` slash command entries so the
  provider is reachable from the runtime UI, not just config
- the env-driven `*_BASE_URL` override branch so users who pin a
  proxy can still flip it without editing config.toml

Trust-boundary pins held: AtlasCloud is opt-in (default remains
DeepSeek), no API keys are hardcoded, the api_key resolution flows
through the same `secrets` crate path every other provider uses,
and the provider-config base_url stays settable per environment.

Resolved 3-way merge conflicts in `crates/secrets/src/lib.rs` (env
cleanup loop) and `crates/tui/src/config.rs` (per-provider
base_url match arm + `provider_passes_model_through` predicate)
so the contributor's AtlasCloud branch coexists with the v0.8.x
provider expansion already on `main`. Added the missing match arm
in `validate_provider_base_url` so the non-exhaustive-pattern
check passes after the new variant lands.

Harvested from PR #1436 by @lucaszhu-hue

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:40:43 -05:00
Hunter Bown 40df46c73d feat(web_search): add configurable Tavily and Bocha provider backends
DuckDuckGo HTML scraping with Bing fallback remains the default
`web_search` backend — no API key required, no behaviour change for
installs that don't opt in. Users in regions where those scrapers
are rate-limited or unreliable can now set `[search]
provider = "tavily" | "bocha"` plus `api_key = "..."` in
`~/.deepseek/config.toml` (or via the `DEEPSEEK_SEARCH_PROVIDER` /
`DEEPSEEK_SEARCH_API_KEY` env vars) to route every `web_search`
call through the chosen API.

Tavily targets general AI-agent search; Bocha (博查) is the
mainland-China-friendly equivalent. Both providers are gated by
the existing `[network]` policy on their respective hosts
(`api.tavily.com`, `api.bochaai.com`) and surface a clear
`ToolError` (rather than a silent fallback to DuckDuckGo) when
the user has opted in but forgotten to set `api_key`. Test pins
the missing-key behaviour for both providers.

Resolved 3-way merge conflicts in `web_search.rs` (description
text and test module) so the contributor's helpers
(`truncate_error_body`, `sanitize_error_body`) coexist with the
v0.8.30 spam-detection and query-parsing tests already on `main`.
Folded the `SearchProvider::default()` impl into a `#[default]`
derive to satisfy the workspace `-D warnings` clippy gate, and
threaded `search: Option<SearchConfig>` through `merge_config` so
the multi-config layering doesn't break the field initialiser.

Harvested from PR #1294 by @sandofree

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:37:34 -05:00
Jefsky Wong 5c112b40bf fix(config): default deepseek-cn to official api.deepseek.com (#1084)
Sets the `deepseek-cn` provider preset's default `base_url` to the official host (`https://api.deepseek.com`) per [api-docs.deepseek.com](https://api-docs.deepseek.com/). Keeps recognizing `api.deepseeki.com` in URL heuristics and chat-client normalization so existing configs continue to work, and updates the `doctor` strict-tool-mode endpoint hint, docs, and examples accordingly.

Closes #1079. Thanks to @Jefsky for the fix.
2026-05-07 12:01:07 -05:00
Hunter Bown f97604c3f0 fix(provider): enable OpenAI-compatible TUI runtime (#1017) 2026-05-07 05:32:15 -05:00
Hunter Bown c270ef81ef fix(tui): harden terminal resume and runtime context
Summary:
- Keep default auto alternate-screen mode inside the TUI so transcript scrolling stays app-owned unless users explicitly opt out.
- Queue terminal resume events when the engine channel is full, avoiding stranded paused terminal state after interactive tool cancellation or bursts.
- Scope crash-checkpoint recovery to the resolved launch workspace instead of the shell cwd.
- Add runtime deepseek_version to the prompt environment block so agents can distinguish installed runtime identity from a stale checkout.

Test plan:
- cargo test -p deepseek-tui --locked on a simulated merge with current main
- cargo fmt --all -- --check
- git diff --check
- Existing PR CI was green for lint, version drift, Linux/macOS/Windows tests, npm wrapper smoke, and GitGuardian.
2026-05-07 03:48:09 -05:00
Hunter Bown c7ed05a07c feat(api): default DeepSeek to beta endpoint
Closes #941.\n\nRefs #938, #939, #940.
2026-05-06 21:24:59 -05:00
Reid 78c415f40c feat(provider): add Ollama provider support (#921)
Source PR: #921 by @reidliu41.
Closes #908.

Local verification:
- cargo test --workspace --all-features ollama
- cargo fmt --all -- --check
- cargo build

Co-authored-by: reidliu41 <reid201711@gmail.com>
2026-05-06 20:16:46 -05:00
Hunter Bown da047c44ff feat(tui): notification_condition override + assistant text in OSC 9 body (#920)
* feat(tui): add `notification_condition` override + assistant text in body (#820)

`[notifications]` already controls method (auto/osc9/bel/off), the
`threshold_secs` gate, and the `include_summary` body. Some users
want a simpler high-level switch — "always notify on every turn" or
"never notify" — without having to know the lower-level fields.

This adds a single optional `[tui].notification_condition` field:

  - `"always"` — notify on every successful turn (no duration
    threshold). The configured `[notifications].method` and
    `include_summary` flag are still respected.
  - `"never"`  — suppress all turn-completion notifications.
  - omitted    — fall back to the existing `[notifications]` defaults
    (the v0.8.15 behavior is unchanged).

The OSC 9 / BEL body now also carries the assistant's reply text,
sanitized and truncated to 360 characters, with a fallback to the
latest assistant message in `api_messages` when the streaming buffer
was empty (e.g. a tool-only turn). When `include_summary = true`,
the elapsed/cost line is appended on a new line.

Drive-by: drop the unused `Method::from_str` helper (the new code
match-arms over the typed `NotificationMethod` enum, so the parser
helper had no remaining callers).

Differences from upstream #820:
- Keeps the `[notifications]` section in `config.example.toml`
  (with `notification_condition` documented as an opt-in override)
  rather than deleting the existing block. This avoids breaking
  configs that already set `[notifications].method` etc.
- Drops the unrelated `#[allow(dead_code)]` on
  `schema_migration::registry`.
- Threads `Option<CostEstimate>` through the helper (the cost
  surface changed from `Option<f64>` since #820 was authored).

Tests:
- `notification_settings_*` (3) — `always` keeps the configured
  method, `never` returns `None`, missing override falls back.
- `completed_turn_notification_*` (4) — streaming text wins, falls
  back to latest assistant message, default placeholder, and 360-char
  truncation with `...`.

Integrates #820.

Co-authored-by: zero <1603852@qq.com>
Co-authored-by: zerx-lab <161401688+zerx-lab@users.noreply.github.com>

* style: fmt — collapse short test message helper calls

---------

Co-authored-by: zero <1603852@qq.com>
Co-authored-by: zerx-lab <161401688+zerx-lab@users.noreply.github.com>
2026-05-06 19:29:02 -05:00
Hunter Bown 633092167c feat(config): support custom HTTP headers (#914)
Integrates the useful custom HTTP header support from #881 onto current main.

- support root, provider-specific, and DEEPSEEK_HTTP_HEADERS overrides
- apply validated extra headers to model API requests while preserving protected Authorization and Content-Type defaults
- document the config shape in README, config.example.toml, and docs/CONFIGURATION.md

Co-authored-by: Desheng <8596814+dst1213@users.noreply.github.com>
2026-05-06 18:13:18 -05:00
Hunter Bown 1043374e6a chore(release): prepare v0.8.15 2026-05-06 11:06:00 -05:00
Agent007 a335ff5e4c feat(provider): add vLLM provider support (#737)
Add vLLM as a first-class OpenAI-compatible self-hosted provider with VLLM_BASE_URL, VLLM_API_KEY, and VLLM_MODEL wiring.
2026-05-05 21:22:24 -05:00
Hunter Bown c0e27485a8 fix: remove dead config fields — prefer_handoff (#667) and use_terminal_colors (#671)
Neither field had any code path that read it. Shipping config knobs
that do nothing trains users to mistrust config. Remove until the
implementation exists.
2026-05-05 00:44:13 -05:00
Hunter Bown ff5c99965d feat(sandbox): pluggable SandboxBackend + Alibaba OpenSandbox adapter (#645) 2026-05-05 00:16:34 -05:00
Hunter Bown 937f5f33f3 feat(runtime): route large tool outputs through workshop to protect parent context (#658) 2026-05-05 00:14:16 -05:00
Hunter Bown 0370e45a97 fix(tui): replace hardcoded colors with Color::Reset + add use_terminal_colors config (#671) 2026-05-05 00:11:02 -05:00