Commit Graph
42 Commits
Author SHA1 Message Date
lexmin0412 f590a727a0 fix(ai): use correct DeepSeek API format to disable thinking 2026-07-09 18:12:05 +08:00
Abeautifulsnow ffc0279352 fix(ai): make stop button actually cancel the agent stream
The stop button called aiCancelStream -> notify_one(), but the four
stream_*_with_tools SSE loops only `break`ed and returned Ok(token_usage)
when cancelled. run_agent_loop treated that as a normal completed turn and
kept going (often into contract-repair or the next turn), so isGenerating
stayed true and a single click did not stop the agent.

Return Err(AGENT_CANCELLED_ERROR) from the cancel branch so the existing
Err-cancel match arm sets loop_exit = Cancelled and stops the loop cleanly,
preserving whatever was streamed so far.

Additional:
- Promote AGENT_CANCELLED_ERROR to a shared `pub const` in ai.rs; agent_loop
  now references ai::AGENT_CANCELLED_ERROR.
- Check cancellation before executing requested tools, so a stop landing
  between stream-end and tool execution is honored.
- Wire cancellation into the text-only fallback (previously `_cancelled`,
  ignored) via tokio::select! racing ai::complete against cancelled.notified().

Known limitation left: in-flight tool execution (e.g. execute_query) is
still not interruptible mid-call.
2026-07-08 18:44:13 +08:00
zipg d90847bbba feat(ai): support SQL library file references 2026-07-07 15:39:10 +08:00
t8y2 3e01840825 fix(ai): remove temperature from AI requests 2026-07-02 17:58:35 +08:00
二丫讲梵 f871e00330 feat(ai): support OpenAI max completion tokens 2026-07-02 01:15:49 +08:00
jischeng c6719eec55 fix(ai): preserve tool name when OpenAI-compatible provider re-sends empty id (#2196)
GLM-5.2 (and potentially other OpenAI-compatible providers) send id="" on
every tool-call delta after the first, while only the first delta carries
function.name. The streaming parser treated Some("") as a valid id and
emitted ToolCallStart for every chunk; the accumulator's insert then
overwrote the previously-correct name with "", producing "Unknown tool:"
errors and trapping the agent in a retry loop until the 30-turn limit.

Two fixes, mutually reinforcing:

1. OpenAI parser: only treat a non-empty id as a genuine tool-call start
   (filter out id=""), so subsequent deltas no longer trigger ToolCallStart.

2. Accumulator: merge ToolCallStart into an existing entry instead of
   blind insert — keep the known name when the new one is empty, and
   preserve accumulated arguments. Defense in depth for any other provider
   that re-sends id or splits name across chunks.

Added a regression test that feeds a re-sent ToolCallStart with an empty
name and asserts the name and arguments survive.

Verified end-to-end with the real GLM-5.2 provider: Unknown tool count
dropped from 12+ to 0, and the agent completed in 3 turns instead of
hitting the 30-turn safety limit.
2026-06-30 19:52:43 +08:00
LC b951d3a50a fix(ai): 修复 OpenAI Responses API 请求和流解析 (#2149) 2026-06-29 21:21:45 +08:00
t8y2 2d2284a0ef fix(ai): preserve UTF-8 in streamed responses 2026-06-29 01:25:43 +08:00
huangyemin 4ad6723512 feat(ai): support custom Anthropic messages API 2026-06-27 10:02:13 +08:00
Abeautifulsnow 5f2b24d700 fix(ai): enforce SQL task contracts structurally instead of keyword heuristics
* fix: enforce agent task contracts

* fix(ai): enforce SQL task contracts structurally
2026-06-26 13:18:49 +08:00
t8y2 fe01de3f17 fix(ai): round temperature precision 2026-06-26 00:58:53 +08:00
Oleksandr Liakhevych 034cce47e0 fix(ai): Codex CLI provider reliability fixes for DBX Desktop
* fix(ai): resolve Codex CLI from shell PATH on macOS

* fix(ai): hide Codex CLI subprocess windows on Windows

* feat(ai): allow to set environment variable for Codex CLI

* fix(ai): parse Codex MCP tool events

* fix(mcp): honor Postgres TLS settings in direct queries
2026-06-25 22:31:14 +08:00
t8y2 cc7b034341 fix(ai): omit Kimi test connection temperature 2026-06-23 12:05:50 +08:00
lexmin0412 c026647785 fix(ai): handle non-JSON error response in AI connection test
Replace res.json() with res.text() + fallback JSON parse so that
non-JSON error bodies (e.g. HTTP 502 with empty body) no longer
produce the unclear 'error decoding response body' message.

Also add 502/503/504 to classify_error for proper category prefixes.
2026-06-23 12:04:46 +08:00
t8y2 c9ab2fb60a fix(ci): sync diagnostics and AI sampling 2026-06-19 14:49:34 +08:00
t8y2 dc90a80468 fix(ai): enable temperature for Kimi models and default to 1.0 2026-06-19 11:36:29 +08:00
Oleksandr Liakhevych 4f5d09aaa8 feat(ai): add Codex CLI as a no-API-key AI provider for Desktop
* codex cli provider

* fixes

* mcp check

* reasoning

* simplify

* minor fixes
2026-06-19 08:51:10 +08:00
t8y2 a9d1b48dd5 fix(ai): skip temperature and thinking-disable for Kimi K2.5+ models 2026-06-18 12:32:10 +08:00
t8y2 a0136c5bd7 fix(ai): parse ollama reasoning stream chunks 2026-06-17 17:13:48 +08:00
t8y2 95b03998d1 fix(tests): reorder imports for better readability in AI module tests 2026-06-16 19:23:31 +08:00
iiusky 57f1b6cedc fix(ai): avoid empty Claude system field rejected by Anthropic
Anthropic rejects requests whose system field is an empty string with
"system: text content blocks must be non-empty". The connection test
hardcoded an empty system, and regular completion/stream requests sent
an empty system_prompt when none was configured.

Add a claude_system_prompt() helper that substitutes a non-empty default
for empty or whitespace-only prompts, and apply it to all Claude request
sites. Covered by a unit test.
2026-06-16 18:52:02 +08:00
t8y2 c57e18bf3e fix: resolve clippy warnings and missing struct fields in tests 2026-06-16 00:55:32 +08:00
Abeautifulsnow c300336281 feat(ai): context window management and token usage tracking
* @
feat(ai): add conversation context management and token usage tracking (Phase 4)

## Background
Phase 4 of AI agent loop upgrade: token usage extraction from LLM responses,
cost estimation display, and automatic context window management (summarization
when approaching limits).

## Changes

### Backend (Rust)
- New token_usage::TokenUsage — cross-turn token accumulation
- New agent_loop::maybe_compact — proactive context compaction: token estimation
  → cut-point selection → LLM summarization → fallback summary
  → tool-pair integrity protection → drain/insert
- New agent_loop::context_window_for_model — auto-detect context window by model
- New agent_loop::is_context_length_error — detect upstream context-length errors
- New agent_loop::compact_tool_result_for_context — JSON/text sampling for large results
- Modified agent_loop::run_agent_loop — pre-turn compaction check, retry on context error
- Modified agent_events::AgentEnd — split total_tokens into input_tokens/output_tokens
- New agent_events::ContextCompacted — compaction event with metrics
- New AiConfig.context_window — user-configurable context window size
- New AiChatMessage.kind — context summary message marker
- Modified stream_with_tools & 3 provider stream functions — extract TokenUsage
  - Claude: message_start(input) + message_delta(output)
  - OpenAI: stream_options { include_usage } → final usage chunk
  - Gemini: usageMetadata per chunk, keep last

### Frontend (TypeScript/Vue)
- AiAssistant.vue: token + cost display row, estimateCost() with 7 model families,
  contextCompacted UI step, pendingCompaction deferred apply,
  messagesForAgentHistory post-compaction history reconstruction
- EditorSettingsDialog.vue: contextWindow input (min=1000, auto-detect)
- settingsStore.ts: AiConfig.contextWindow field
- tauri.ts: AgentEvent type updates, AiChatMessage.kind
- i18n: 6 new keys in en.ts and zh-CN.ts

## Fixed Issues
- messages[0] dropped from LLM context after compaction
- estimate_text_tokens hard threshold causing 2.8x estimate jump
- context_compacted event field semantics mismatch with frontend insert position
- validate_summary English-only keywords causing fallback on non-English LLMs
- Stale agentTokens after conversation switch
@

* remove cost computation logic
2026-06-15 18:55:22 +08:00
t8y2 c6e50f80f2 fix(ai): accept thinking/reasoning deltas as first stream chunk in connection test 2026-06-12 20:40:40 +08:00
t8y2 484658c6b7 feat(ai): streaming probe for connection test with latency measurement 2026-06-12 19:29:55 +08:00
t8y2 2395727b6b fix(ai): auto-add /v1 prefix for bare-origin OpenAI-compatible endpoints 2026-06-12 16:10:42 +08:00
Abeautifulsnow 082e3bb4eb feat(ai): add agent tool calling loop 2026-06-12 13:18:36 +08:00
t8y2 293df56274 fix(ai): relax connection test token limit 2026-06-11 11:59:23 +08:00
t8y2 8df9484447 feat(ai): support auth methods 2026-06-10 12:14:36 +08:00
Oleksandr Liakhevych efb0dba0ae fix(ai): do not provide temperature for OpenAI reasoning models 2026-06-09 16:22:28 +08:00
t8y2 87b8f1f462 fix(ai): support proxied API channels 2026-06-08 20:32:54 +08:00
e9ee982843 Preserve ordered SSH and proxy connection layers (#802)
* Preserve ordered SSH and proxy connection layers

Replace separate SSH/proxy connection fields with ordered transport_layers while keeping legacy migration and secret fallback paths intact. The UI now edits SSH tunnel/proxy layers in configured order without a global SSH enable gate.

Constraint: Existing saved SSH tunnels, proxy settings, and secret-store keys must continue to load through migration.
Rejected: Folding proxy fields into SshTunnelConfig | mixes proxy semantics into an SSH-specific structure.
Confidence: high
Scope-risk: moderate
Directive: Keep SSH/proxy structs provider-specific; put cross-layer chaining in transport_layer_tunnel orchestration.
Tested: git diff --check; cargo fmt --check; cargo check --workspace; cargo test -p dbx-core --lib; vue-tsc --noEmit --project apps/desktop/tsconfig.json; tsc -p packages/node-core/tsconfig.json --noEmit; oxlint --vue-plugin apps/desktop/src; tsx --tsconfig apps/desktop/tsconfig.json --test packages/app-tests/*.test.ts; tsx --test packages/node-core/tests/*.test.ts
Not-tested: Live external SSH/proxy/database endpoint integration.

* Keep ordered transport changes CI-format clean

Constraint: CI pnpm check failed only on oxfmt formatting for two desktop TypeScript files
Confidence: high
Scope-risk: narrow
Directive: Keep generated/editor config changes out of this PR fix commit
Tested: PATH="/Volumes/data/code/rust/dbx/node_modules/.bin:/Users/hekx/.codex/tmp/arg0/codex-arg0nuL34n:/Users/hekx/.cargo/bin:/Users/hekx/.local/bin:/opt/homebrew/opt/llvm/bin:/opt/homebrew/opt/libpq/bin:/Volumes/data/Users/hekx/.opencode/bin:/Users/hekx/.bun/bin:/Volumes/data/sdks/flutter/bin:/Volumes/data/Users/hekx/.cargo/bin:/Users/hekx/.local/bin:/opt/homebrew/opt/llvm/bin:/opt/homebrew/opt/libpq/bin:/Volumes/data/Users/hekx/.opencode/bin:/Users/hekx/.bun/bin:/Volumes/data/Users/hekx/Library/pnpm:/Volumes/data/sdks/flutter/bin:/Volumes/data/Users/hekx/.cargo/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/pkg/env/global/bin:/opt/X11/bin:/Library/Apple/usr/bin:/Applications/Wireshark.app/Contents/MacOS:/usr/local/go/bin:/opt/homebrew/bin:/opt/podman/bin:/Applications/Ghostty.app/Contents/MacOS" rtk node scripts/run-check.mjs
Not-tested: GitHub Actions rerun not observed locally

* Keep Rust checks warning-clean

Constraint: cargo clippy --workspace --all-targets --all-features -- -D warnings failed across core, web, and tauri crates
Rejected: Broad workspace-level clippy suppression | kept allows local to long-argument command/API boundaries
Confidence: high
Scope-risk: moderate
Directive: Preserve src-tauri/tauri.conf.json as an unrelated local change outside this commit
Tested: rtk cargo clippy --workspace --all-targets --all-features -- -D warnings
Not-tested: Full GitHub Actions rerun not observed locally

* Reuse existing proxy tunnels on retry

Proxy tunnel startup now mirrors SSH tunnel behavior by returning the existing local port for an active connection id instead of replacing the managed handle. A second map check aborts a just-spawned duplicate handle if a concurrent retry won the race before insertion, preventing orphaned listeners while keeping the change narrow.

Constraint: Reviewer requested proxy tunnel behavior align with SSH local-port reuse

Rejected: Always overwrite and abort the previous handle | less consistent with SSH behavior and churns listeners during retries

Confidence: high

Scope-risk: narrow

Tested: cargo fmt --check --all

Tested: cargo test -p dbx-core db::proxy_tunnel::tests::start_tunnel_reuses_existing_local_port

Tested: cargo clippy -p dbx-core --all-targets -- -D warnings

---------

Co-authored-by: hekx <hekx@momandeMac-mini.local>
Co-authored-by: caisin <caisin@caisins-Mac-mini.local>
2026-06-06 23:22:29 +08:00
t8y2 0dbb30f614 fix(ai): clamp responses output tokens 2026-06-03 00:48:01 +08:00
t8y2 ef4baba57a feat: support double-clicking .db/.sqlite/.duckdb files to open in IDE
Add OS file association for database files (.db, .sqlite, .sqlite3, .duckdb)
so double-clicking them in Finder/Explorer automatically creates a connection.
If the same file path is already connected, prompts the user to switch instead.

Also fix 42 pre-existing clippy warnings in dbx-core (needless_borrow,
too_many_arguments, derivable_impls, manual_div_ceil, type_complexity, etc.).

Closes #527
2026-05-29 17:25:52 +08:00
Abeautifulsnow 222ebefa6a feat(ai): add model list fetching in settings (#364)
- Add `ai_list_models` Tauri command and core support for fetching available models from OpenAI-compatible, Claude, and Ollama providers
- Replace manual model ID input with SearchableSelect in EditorSettingsDialog, including refresh button and loading state
- Add i18n translations for model list UI (en, es, zh-CN)
- Add tests for settings dialog layout and web driver management
2026-05-20 16:14:56 +08:00
t8y2 2afcfff4e3 fix(ai): extend timeout and token budget for thinking models
Thinking models like DeepSeek V4 Flash can exceed the 120s stream
timeout during long reasoning, causing truncated output and missing
answers. Increase stream timeout to 600s when thinking is enabled,
raise max_tokens floor to 8192, and bump reasoning display max-height.

Closes #326
2026-05-19 18:08:08 +08:00
t8y2 52033f0846 feat(ai): add provider presets 2026-05-17 14:59:18 +08:00
t8y2 20d1fa724d fix: make AI stream cancel respond instantly via tokio::select
Replace AtomicBool polling (only checked between chunks) with
tokio::sync::Notify + tokio::select!, so the stop button takes
effect immediately even when the LLM is thinking.
2026-05-13 14:59:55 +08:00
rarnu 4f0a13f24f add: 为AI设置增加了thinking的开关 2026-05-12 01:16:40 +08:00
t8y2 79277c660f feat(proxy): 增加数据库和 AI 代理支持 2026-05-11 15:05:25 +08:00
t8y2 41445ff474 chore: add rustfmt.toml and apply unified code formatting 2026-05-05 14:16:18 +08:00
t8y2 cf4f25fd52 feat: extract dbx-core crate for web deployment support
Refactor all database drivers, query execution, schema operations, and
business logic into a shared `dbx-core` crate. The Tauri desktop app
becomes a thin shell delegating to dbx-core, enabling future web and
CLI frontends to reuse the same core.
2026-05-05 03:16:24 +08:00