Commit Graph
1698 Commits
Author SHA1 Message Date
chengyongru 36253685bd fix(webui): complete temporary chat mode 2026-08-07 17:07:58 +08:00
Xubin Renandchengyongru 324a61dff1 feat(webui): add temporary chat mode 2026-08-07 17:07:15 +08:00
chengyongruandchengyongru cdb2a474f9 refactor(webui): remove legacy session messages route 2026-08-07 15:16:57 +08:00
chengyongruandGitHub ff6deda178 fix: modernize dependency recovery guidance (#5282) 2026-08-07 13:58:13 +08:00
chengyongruandchengyongru 2c7943a133 fix(memory): archive short idle sessions for Dream 2026-08-07 11:45:49 +08:00
chengyongruandchengyongru 8dfce4c162 fix(session): require user anchor for delivery retention 2026-08-07 10:53:55 +08:00
ziuusandchengyongru 60282d1588 fix(session): preserve proactive channel delivery during session retention trimming 2026-08-07 10:53:55 +08:00
Xubin Ren 9cf6cf0639 feat(webui): persist manual session ordering 2026-08-06 19:11:05 +08:00
chengyongruandGitHub a95fd0ee82 perf(webui): reduce cold-start payload (#5262) 2026-08-06 13:24:34 +08:00
chengyongruandGitHub 67805f5db8 feat: add provider-native request switches (#5254) 2026-08-05 18:26:39 +08:00
chengyongruandGitHub 9098ffd38f refactor(webui): improve visual consistency (#5249) 2026-08-05 13:24:45 +08:00
chengyongruandGitHub 6e9ae5bd05 refactor(session): remove request-scoped access grants (#5238) 2026-08-05 10:18:46 +08:00
chengyongruandchengyongru f45436b61d fix(commands): reject invalid slash commands 2026-08-04 17:11:44 +08:00
chengyongruandGitHub 2fe135db3e feat(webui): add integrated Vite dev mode (#5239) 2026-08-04 16:14:32 +08:00
chengyongruandGitHub 4e8702a47b fix(anthropic): support Opus 5 effort controls (#5236) 2026-08-04 13:38:54 +08:00
Xubin Ren d99f589a59 refactor(session): clarify reference boundaries 2026-08-04 12:14:51 +08:00
Xubin Ren d8aeb0eb2c refactor(session): simplify cross-session flow 2026-08-04 12:14:51 +08:00
Xubin Ren 62d34b5eb7 refactor(session): tighten cross-session access 2026-08-04 12:14:51 +08:00
Xubin Ren f15ea84dd1 fix(session): enforce trusted read scope 2026-08-04 12:14:51 +08:00
Xubin Ren 4c07c40b34 feat(session): link agent references 2026-08-04 12:14:51 +08:00
Xubin Ren 5dd3dc5450 fix(session): harden cross-session references 2026-08-04 12:14:51 +08:00
Xubin Ren 9b25da7b92 feat(session): add cross-session references 2026-08-04 12:14:51 +08:00
chengyongruandchengyongru 44b7e1bf41 fix(providers): keep serde errors explicit 2026-08-03 18:06:45 +08:00
arcdrake22andchengyongru 6eda67b50c fix(providers): keep reasoning items wire-valid for DeepSeek Responses
convert_messages() emitted reasoning items with ``content`` as a plain
string whenever preserve_reasoning was enabled (the DeepSeek spec).
DeepSeek's Responses gateway rejects that shape with a serde error
("input: invalid type: string ..., expected a sequence"), which surfaced
only after token consolidation cleared provider_state and forced the
full-history conversion path; replayed server items already carry list
content, which is why normal multi-turn requests never failed. Serialize
reasoning content as a list of output_text parts, matching the OpenAI
Responses schema and DeepSeek's accepted wire shape (verified live against
api.deepseek.com/responses).

The serde fallback classifier introduced in the previous commit remains as
a last-resort safeguard for any remaining wire incompatibility.

Tests: extend test_preserves_deepseek_reasoning_content to the array shape;
add a full-history regression with the observed failing item, a
replay/consolidation regression covering both replayed and converted
reasoning items, and provider-level request fixtures for both paths.
Full suite: 5773 passed, 22 skipped (only the known local-only
channels/sms packaging failure remains).
2026-08-03 18:06:45 +08:00
arcdrake22andchengyongru fb2688fd37 fix(providers): fall back to chat completions on serde body rejections
DeepSeek's new Responses endpoint (deepseek-v4-flash) intermittently rejects valid request bodies with serde deserialization errors such as 'input: invalid type: string ..., expected a sequence'. These were not classified as compatibility errors, so affected conversations died instead of falling back to Chat Completions.

The wire format is correct (input serializes as a list), so this is a server-side Responses compatibility issue; Chat Completions is strictly more permissive, making fallback safe. Extend the fallback classifier to recognize serde body-parsing markers. Repeated failures still trip the existing circuit breaker.
2026-08-03 18:06:45 +08:00
chengyongruandGitHub f11710a578 fix(webui): show actual local trigger messages (#5228) 2026-08-03 16:43:01 +08:00
Xubin Ren ac216c3e94 docs(providers): document Eden AI setup and WebUI parity 2026-08-03 16:40:13 +08:00
Xubin Ren e7ec981f79 test(providers): verify Eden AI gateway contract 2026-08-03 16:40:13 +08:00
Xubin Ren 84f98f5e92 test(cron): cover invalid schedule expressions 2026-08-03 16:20:22 +08:00
arcdrake22andXubin Ren c6bd5f0075 test(gateway): align runtime-tasks gather tests with bounded retrieval
The helper never waits on the runtime-tasks gather after cancelling it
(its children are bounded individually), so the finished-gather test must
hand the helper an already-complete gather to exercise the bounded
retrieval path, and the cancelled-gather test must settle the gather
itself instead of expecting the helper to await a still-pending future.

Use a pre-completed child for the finished case and suppress(await) for
the cancelled case; both now assert done() and a single close.
2026-08-03 16:00:39 +08:00
Xubin Ren 39e1533c3b fix(gateway): make resource teardown cancellation-safe 2026-08-03 16:00:39 +08:00
arcdrake22andXubin Ren a91ce900ef test(gateway): add shutdown teardown regression coverage
Covers the lifecycle contract of _close_gateway_runtime: runtime tasks are
cancelled before shared resources close, pending background work is drained
before the close returns, cancellation-swallowing tasks and hanging cleanup
are bounded by their timeouts, a failing close is logged without blocking the
stop, duplicate cleanup is idempotent, and the runtime_tasks gather await path
is exercised for both completed and cancelled gathers.
2026-08-03 16:00:39 +08:00
KDBandXubin Ren 52bc79d3a0 fix(plugins): use uv when pip is unavailable 2026-08-03 15:42:26 +08:00
arcdrake22andchengyongru 08fe9f7b3a fix(image): send Gemini Flash hints via generationConfig.imageConfig
The live v1beta API rejects the legacy responseFormat.image block
(enum-based aspectRatio/imageSize fields) for gemini-3.1-flash-lite-image
with INVALID_ARGUMENT, even for documented plain-string values. Gemini
Flash image models accept plain-string hints under
generationConfig.imageConfig instead (e.g. aspectRatio 16:9, imageSize
1K), which the API accepts. Switch the flash path to imageConfig and
update the provider tests accordingly. Other providers (aihubmix,
ollama, imagen) are untouched.
2026-08-03 11:22:09 +08:00
chengyongruandGitHub 580824a15a perf(webui): accelerate JSONL session list and thread loading (#5194) 2026-08-03 09:51:35 +08:00
Xubin Ren e1894d6f0b fix(providers): respect explicit cloud namespaces 2026-08-01 20:25:58 +08:00
5eb818e800 fix(providers): require api_base before local provider wins on keyword match
Ollama's spec keeps "nemotron" as a keyword so bare `nemotron-3-nano`
auto-routes to a configured Ollama install (PR #1863). NVIDIA NIM was
later registered with the same "nemotron" keyword (commit 046d0831),
creating the only keyword collision in the registry.

In `_match_provider`, the keyword loop accepted any local provider on
`spec.is_local` alone — no api_base check. Models like
`nvidia/nemotron-3-super-120b-a12b` (intended for OpenRouter or NVIDIA
NIM) were therefore hijacked to http://localhost:11434/v1 even when the
user had never configured Ollama, causing silent connection errors at
runtime.

Add the same api_base gate the local-fallback loop already uses: a local
provider only wins by keyword when the user has actually set its
api_base. Preserves PR #1863's intent for users who configured Ollama;
fixes the silent hijack for everyone else.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-08-01 20:25:58 +08:00
santhrealandXubin Ren 4c387f6633 fix(memory): handle non-string timestamp and missing role in raw_archive 2026-08-01 20:14:28 +08:00
Xubin Ren e152e7bc0b test(cron): cover stop during manual execution 2026-08-01 20:03:19 +08:00
yu-xin-candXubin Ren e26e09c205 fix(cron): preserve manual run completion state 2026-08-01 20:03:19 +08:00
KDBandXubin Ren b1030ab131 fix(exec): preserve wait targets across response truncation 2026-08-01 19:40:36 +08:00
KDBandXubin Ren 39bb20c76b fix(session): tolerate malformed persisted session summary
AutoCompact.prepare_session runs on the turn hot path
(AgentLoop._compact_session) and read the persisted _last_summary metadata
with an unguarded meta['text'] and datetime.fromisoformat(meta['last_active']).
A _last_summary dict that was hand-edited or written by another version
(missing text/last_active, or a non-ISO last_active) raised KeyError/ValueError
out of the turn.

Sibling readers already tolerate the same data: estimate_session_prompt_tokens
uses .get('text') and _archive parses inside try/except. Mirror that tolerance:
skip when text is unusable, and fall back to the session's own updated_at (the
value the writer persists) when last_active is missing or unparseable, so the
archived summary is preserved instead of crashing the turn.
2026-08-01 19:29:16 +08:00
chengyongruandGitHub cdb75f8e7d feat(providers): support DeepSeek Responses API (#5197) 2026-08-01 11:53:51 +08:00
shixi-liandchengyongru dda9b61b1e fix(config): install timezone data on all platforms 2026-07-31 19:55:22 +08:00
chengyongruandGitHub 6a1a45d07a feat: preserve Responses reasoning state and compact context (#5172) 2026-07-30 22:39:43 +08:00
Solaris-starandXubin Ren 511c764f45 fix(agent): route finish_reason='length' with blank content to length recovery
When an LLM response arrives with finish_reason='length' and has_tool_calls
but blank text content (e.g. the model spent its whole output budget on a
tool call whose closing tag was truncated), the runner dropped the tool
calls and then misrouted the blank response into the empty-response retry
branch. Retrying the same prompt cannot recover from output-budget
exhaustion, so every retry hit the same length ceiling and the turn ended
in the generic apology.

The length-recovery branch was gated on 'finish_reason == length and not
is_blank_text(clean)', so a blank-but-truncated turn could never reach it.

- The empty-response retry branch now excludes finish_reason == 'length'
  (in addition to 'error').
- The length-recovery branch no longer requires non-blank content, so a
  blank-but-truncated turn enters recovery and appends
  build_length_recovery_message (which handles a blank tail safely).

Adds a regression test asserting the length-recovery path is taken; it
fails on the unfixed code and passes with the fix.

Fixes #5133
2026-07-30 19:55:19 +08:00
Xubin Ren 0eac82984c test(mcp): stabilize idle reconnect timing 2026-07-30 19:44:09 +08:00
yu-xin-candXubin Ren 5e67fbf93e fix(exec): bound buffered session output 2026-07-30 19:44:09 +08:00
yu-xin-candXubin Ren 9ec4420104 fix(agent): release idle session locks 2026-07-30 19:17:37 +08:00
KDBandXubin Ren 52680dbe19 fix(pairing): keep approvals across transient store read failures
_load() treated any OSError like corruption and returned an empty store. When pairing.json was transiently unreadable, an unapproved DM could deny the sender, generate a pairing code from the empty view, and overwrite the store without its approved senders.

Keep the existing JSONDecodeError reset behavior, but propagate OSError so mutations cannot persist unreadable state. Read-only checks fail closed without writing; mutating /pairing subcommands report temporary unavailability; and the DM pairing path skips one reply instead of crashing the handler.

This mirrors the refuse-to-overwrite strategy used by the cron and trigger stores.
2026-07-30 19:02:37 +08:00