Commit Graph
2643 Commits
Author SHA1 Message Date
chengyongru 2c7943a133 fix(memory): archive short idle sessions for Dream 2026-08-07 11:45:49 +08:00
chengyongru 8dfce4c162 fix(session): require user anchor for delivery retention 2026-08-07 10:53:55 +08:00
ziuus 60282d1588 fix(session): preserve proactive channel delivery during session retention trimming 2026-08-07 10:53:55 +08:00
Xubin Ren c2fd41b44d fix(webui): persist large sidebar ordering state 2026-08-06 19:11:05 +08:00
Xubin Ren 9cf6cf0639 feat(webui): persist manual session ordering 2026-08-06 19:11:05 +08:00
Orrin Witt 5c4c2cb819 fix(matrix): send non-empty POST body on room join for Continuwuity compatibility (#5248) 2026-08-06 18:29:57 +08:00
chengyongru a95fd0ee82 perf(webui): reduce cold-start payload (#5262) 2026-08-06 13:24:34 +08:00
chengyongru 67805f5db8 feat: add provider-native request switches (#5254) 2026-08-05 18:26:39 +08:00
chengyongru 5a1ab44baa fix(whatsapp): detect outbound media content before dispatch (#5203) 2026-08-05 15:44:23 +08:00
chengyongru 9098ffd38f refactor(webui): improve visual consistency (#5249) 2026-08-05 13:24:45 +08:00
chengyongru 6e9ae5bd05 refactor(session): remove request-scoped access grants (#5238) 2026-08-05 10:18:46 +08:00
Xubin Ren 858f6d96a6 fix(mattermost): preserve thread policy compatibility 2026-08-05 09:31:55 +08:00
Kenneth Zhao cd4c1d0f6e feat(mattermost): separate group policy for threads vs channels 2026-08-05 09:31:55 +08:00
Xubin Ren be5af019b9 fix(wecom): sanitize fallback media filename 2026-08-04 22:04:21 +08:00
santhreal 98507ae4fe fix(wecom): fallback to default filename when sanitize strips to empty 2026-08-04 22:04:21 +08:00
concertypin cb2f9d0bbd fix(webui): configure public websocket URL 2026-08-04 21:53:16 +08:00
concertypin e318e21cad fix(webui): require proxy-generated auth assertions 2026-08-04 21:53:16 +08:00
concertypin 465a918cf8 feat(webui): bypass tokens for trusted proxy auth 2026-08-04 21:53:16 +08:00
concertypin 5cd14a42df feat(webui): support trusted proxy bootstrap auth 2026-08-04 21:53:16 +08:00
santhreal 170c7083ed fix(telegram): require newline for language tag to preserve single-line fenced code 2026-08-04 21:40:03 +08:00
santhreal a13e29bf07 fix(telegram): preserve code block content when language tag contains special characters 2026-08-04 21:40:03 +08:00
chengyongru f45436b61d fix(commands): reject invalid slash commands 2026-08-04 17:11:44 +08:00
chengyongru 2fe135db3e feat(webui): add integrated Vite dev mode (#5239) 2026-08-04 16:14:32 +08:00
chengyongru 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
chengyongru 44b7e1bf41 fix(providers): keep serde errors explicit 2026-08-03 18:06:45 +08:00
arcdrake22 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
arcdrake22 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
chengyongru f11710a578 fix(webui): show actual local trigger messages (#5228) 2026-08-03 16:43:01 +08:00
Xubin Ren e7ec981f79 test(providers): verify Eden AI gateway contract 2026-08-03 16:40:13 +08:00
Victor M. SMITH f42a44817a feat(providers): add Eden AI as an OpenAI-compatible gateway provider
Eden AI (https://www.edenai.co) is an EU-hosted, OpenAI-compatible gateway exposing 100+ models from many providers through a single endpoint and API key. Models use the provider/model naming scheme (the full id is sent upstream, like OpenRouter).

Adds it following the registry's documented two-step recipe:
- a ProviderSpec in providers/registry.py (backend openai_compat, gateway, default_api_base https://api.edenai.run/v3, EDENAI_API_KEY, reasoning_effort)
- the matching field in ProvidersConfig (config/schema.py)

API key via EDENAI_API_KEY only; never hardcoded.

Signed-off-by: Victor M. SMITH <72023257+MVS-source@users.noreply.github.com>
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
ferkans-amir 73a0080484 fix(cron): validate expression syntax in _validate_schedule_for_add 2026-08-03 16:20:22 +08:00
Xubin Ren 39e1533c3b fix(gateway): make resource teardown cancellation-safe 2026-08-03 16:00:39 +08:00
arcdrake22 8942c22d86 fix(gateway): close agent resources deterministically on shutdown
The gateway shutdown path never closed agent resources explicitly: it relied
on the agent loop task's own finally to run close_mcp() when that task is
cancelled. When the service stops with an in-flight exec session or MCP
subprocess, that path can be skipped or cut short, leaving asyncio subprocess
transports alive after the event loop closes. They are then finalized by
__del__ against a closed loop, producing "RuntimeError: Event loop is closed"
noise in the shutdown log, and in the worst case orphaned subprocesses with
the stop stalling until systemd's timeout kills the cgroup.

The teardown is now extracted into _close_gateway_runtime() with explicit
ordering and bounds:

- Runtime tasks (including the agent loop and any in-flight turn) are
  cancelled and awaited -- bounded -- before exec sessions, subagents, and MCP
  servers are closed, so no active turn is using a shared resource when it
  closes.
- Channel transports are closed before waiting for their runners to exit, since
  some SDKs swallow task cancellation while attempting to reconnect.
- agent.close_mcp() is invoked explicitly, bounded to 15s, and is idempotent:
  it is a no-op when the agent loop's own cleanup already ran, and the
  guaranteed final close otherwise.
- A coroutine that swallows cancellation (e.g. an SDK reconnect loop) can no
  longer hold the stop open until systemd's timeout kills the cgroup; cleanup
  failures are logged instead of blocking shutdown.
2026-08-03 16:00:39 +08:00
KDB 52bc79d3a0 fix(plugins): use uv when pip is unavailable 2026-08-03 15:42:26 +08:00
chengyongru 5c72fdcd88 fix(webui): remove unused bot identity settings 2026-08-03 14:06:44 +08:00
yang1andamkile f7a6bc2d21 fix(webui): globally register correct MIME types for static assets (#5190)
On Windows, mimetypes.guess_type() reads the Content Type value from
HKEY_CLASSES_ROOT\.js (and other extensions) in the registry, which is
commonly set to text/plain because .js is associated with Windows Script
Host rather than web JavaScript. The registry value overrides Python's
built-in mapping and causes browsers to reject ES module scripts.

Fix by explicitly registering correct MIME types via mimetypes.add_type()
at module import time for common web static extensions (.js, .mjs, .css,
.html, .json, .svg, .wasm). Using strict=True ensures the values replace
the registry-backed standard mappings used by mimetypes.guess_type(). This
benefits all callers of mimetypes.guess_type() in the gateway process, not
just _serve_static.

Closes #5190

Co-authored-by: amkile <44280409+amkile@users.noreply.github.com>
2026-08-03 11:33:02 +08:00
arcdrake22 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
chengyongru 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
NearlCrewsandClaude Opus 4.7 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
santhreal 4c387f6633 fix(memory): handle non-string timestamp and missing role in raw_archive 2026-08-01 20:14:28 +08:00
yu-xin-c e26e09c205 fix(cron): preserve manual run completion state 2026-08-01 20:03:19 +08:00