Commit Graph

215 Commits

Author SHA1 Message Date
ghreprimand 151da49824 Honor disabled speech service toggles (#814)
Co-authored-by: ghreprimand <203024559+ghreprimand@users.noreply.github.com>
2026-06-02 10:44:39 +09:00
pewdiepie-archdaemon 9cf2eaceae Protect memory tidy owner scope 2026-06-02 09:52:52 +09:00
pewdiepie-archdaemon 028f00f81b Label Docker bind mounts for SELinux 2026-06-02 09:50:35 +09:00
pewdiepie-archdaemon 05432e7418 Allow Docker startup without env file 2026-06-02 09:49:35 +09:00
pewdiepie-archdaemon de64bda6bc Fix endpoint model preservation for tasks 2026-06-02 09:44:24 +09:00
PewDiePie 5a04c78e56 Merge pull request #797 from ErnestHysa/fix/research-path-traversal
fix(research): validate session_id to block path traversal
2026-06-02 09:42:23 +09:00
PewDiePie 73d2e25d1e Merge pull request #782 from tanmayraut45/fix/active-streams-toctou
Fix TOCTOU race in chat stream status endpoint
2026-06-02 09:42:07 +09:00
PewDiePie 29052ea60b Merge pull request #776 from tanmayraut45/fix/searxng-container-caps
Fix searxng container permission errors during setup
2026-06-02 09:41:46 +09:00
PewDiePie 0769bb8559 Merge pull request #809 from BSG-Walter/main
fix: resolve DuckDuckGo redirect URLs in HTML fallback search
2026-06-02 09:41:34 +09:00
PewDiePie f857255f14 Merge pull request #824 from ooovenenoso/fix/odysseus-issue-802-windows-js-mime
fix: normalize JS static MIME types on Windows
2026-06-02 09:41:18 +09:00
PewDiePie 72575775f6 Merge pull request #837 from jamesarslan/fix/agent-toolcall-null-content
Fix tool-calling HTTP 400 on Gemini and Ollama (empty assistant content with tool_calls)
2026-06-02 09:41:01 +09:00
pewdiepie-archdaemon 45bdb1a666 Polish task UI slash commands and Ollama serving 2026-06-02 09:36:03 +09:00
James Arslan 583efe9846 Fix tool-calling HTTP 400 on Gemini and Ollama: send null, not empty, assistant content
When an agent turn uses native (OpenAI-style) function calling and the model
returns only tool calls with no prose, _append_tool_results built the follow-up
assistant message with content "" (empty string).

Google Gemini's OpenAI-compatible endpoint and Ollama both reject an assistant
message that carries tool_calls alongside an empty-string content with HTTP 400.
Because that message feeds the tool results back to the model, every tool-using
turn on these providers dies at the second round: the tool runs, but the agent
never produces a result.

Use None (JSON null) instead, which is the spec-correct form the OpenAI SDK
itself emits and which OpenAI and Anthropic accept too. Adds tests covering the
native tool-call content shaping.
2026-06-02 00:34:51 +00:00
Kevin a4010d85a0 fix: normalize JS static MIME types on Windows
Refs #802
2026-06-02 01:32:00 +02:00
BSG-Walter a9ce8d5439 fix: resolve DuckDuckGo redirect URLs in HTML fallback search
The DuckDuckGo HTML fallback returns redirect URLs (//duckduckgo.com/l/?uddg=...)
instead of actual page URLs. This caused fetch_webpage_content() to reject them
instantly because _public_http_url() requires an http/https scheme, making search
results unfetchable in deep research mode.
Added _resolve_url() to:
- Convert protocol-relative URLs to absolute (https:)
- Convert path-relative URLs to absolute
- Extract the real URL from DuckDuckGo's /l/?uddg= redirect parameters
2026-06-01 19:42:01 -03:00
pewdiepie-archdaemon f991e01df3 Show Ollama models in Cookbook Serve 2026-06-02 07:38:45 +09:00
Ernest Hysa 9176c4d63a fix(research): validate session_id to block path traversal
Every research endpoint interpolates session_id into filesystem paths
(Path('data/deep_research') / f'{session_id}.json') without checking
for traversal sequences. A crafted ID like '../../data/auth' reaches
arbitrary JSON files — readable via research_detail (which also leaks
file paths in error messages), writable via research_archive, and
deletable via research_delete.

Add _validate_session_id() which rejects anything outside
[a-zA-Z0-9-]{1,128}. Called before filesystem access in all 12
endpoints that accept a session_id path parameter.
2026-06-01 23:25:38 +01:00
pewdiepie-archdaemon 24ebb44073 Clarify AI tasks and skipped activity rows 2026-06-02 07:11:40 +09:00
pewdiepie-archdaemon 452eae2bfd Fix Brain tab panel visibility 2026-06-02 07:07:51 +09:00
pewdiepie-archdaemon b194604557 Match mobile task state button height 2026-06-02 07:06:17 +09:00
pewdiepie-archdaemon f5fb1f3995 Polish task activity icons 2026-06-02 07:04:52 +09:00
pewdiepie-archdaemon f12dfaf025 Compact mobile task controls 2026-06-02 07:02:26 +09:00
pewdiepie-archdaemon fd59d2d7d5 Remove mobile notes close button 2026-06-02 07:00:40 +09:00
pewdiepie-archdaemon 0df806259d Clarify task status controls on mobile 2026-06-02 06:57:53 +09:00
pewdiepie-archdaemon 91af23e508 Make favorite dot feedback transient 2026-06-02 06:52:03 +09:00
pewdiepie-archdaemon fae1a75fbe Add model favorite dot feedback 2026-06-02 06:50:22 +09:00
pewdiepie-archdaemon ba8de14b4d Remove broken remind slash command 2026-06-02 06:48:41 +09:00
pewdiepie-archdaemon fdb25198d7 Nudge model picker favorite dots 2026-06-02 06:46:05 +09:00
pewdiepie-archdaemon f9133748db Add direct tool slash commands 2026-06-02 06:44:29 +09:00
pewdiepie-archdaemon fb1d399764 Refresh slash command hints 2026-06-02 06:40:23 +09:00
pewdiepie-archdaemon c7cc6f025a Adjust model picker favorite dot alignment 2026-06-02 06:36:10 +09:00
pewdiepie-archdaemon ccb9600d71 Polish model picker favorites 2026-06-02 06:33:53 +09:00
tanmayraut45 12bc2c3025 Fix TOCTOU race in chat stream status endpoint
The /api/chat/stream_status handler did a membership test against
_active_streams followed by an indexed read of the same key. Between
those two ops, a sibling stream's finally block (or a stop / cleanup
path) can pop the entry, turning the indexed read into a KeyError that
bubbles up as a 500. The race is the exact one _stream_set was already
written to avoid; the comment on the helper at the top of the module
spells out why a single .get() is the right pattern here too.

Collapse the two-step into a single .get() call so the lookup either
returns the live record or None, and report 'detached' / 404 based on
that single read. No behavior change on the happy path; the failure
mode under concurrent stream cleanup is now handled deterministically.

Closes #658.
2026-06-02 03:02:30 +05:30
pewdiepie-archdaemon 4ebf370669 Merge branch 'pr-673' into visual-pr-playground 2026-06-02 06:26:32 +09:00
pewdiepie-archdaemon 721ccf85a5 Merge branch 'pr-644' into visual-pr-playground 2026-06-02 06:26:32 +09:00
pewdiepie-archdaemon 8f6bd52b86 Merge branch 'pr-738' into visual-pr-playground 2026-06-02 06:26:32 +09:00
pewdiepie-archdaemon f2f631cd9c Merge branch 'pr-480' into visual-pr-playground 2026-06-02 06:26:32 +09:00
pewdiepie-archdaemon 77a3c86cba Merge branch 'pr-611' into visual-pr-playground 2026-06-02 06:26:32 +09:00
pewdiepie-archdaemon 64d9c14841 Merge branch 'pr-506' into visual-pr-playground 2026-06-02 06:26:32 +09:00
pewdiepie-archdaemon e556b87caf Merge branch 'pr-550' into visual-pr-playground 2026-06-02 06:26:32 +09:00
pewdiepie-archdaemon 97705007ee Merge branch 'pr-594' into visual-pr-playground 2026-06-02 06:26:31 +09:00
pewdiepie-archdaemon a7acd335f3 Merge branch 'pr-575' into visual-pr-playground 2026-06-02 06:26:31 +09:00
pewdiepie-archdaemon 693c6983ea Merge branch 'pr-469' into visual-pr-playground 2026-06-02 06:26:31 +09:00
pewdiepie-archdaemon 2ef0121ac0 Merge branch 'pr-684' into visual-pr-playground 2026-06-02 06:26:31 +09:00
pewdiepie-archdaemon 30b4e544b8 Merge branch 'pr-668' into visual-pr-playground 2026-06-02 06:26:31 +09:00
pewdiepie-archdaemon d889fe8769 Merge branch 'pr-696' into visual-pr-playground 2026-06-02 06:26:31 +09:00
tanmayraut45 a113ee4f6f Fix searxng container permission errors during setup
A fresh `docker compose up -d` shows the searxng container failing its
healthcheck with permission errors at setup (reported in #721 — the
service comes up under names like `odysseus_searxng_1` and never goes
ready, which then blocks the main odysseus container because of the
`depends_on: searxng: condition: service_healthy` gate).

Root cause: the official `searxng/searxng:latest` image runs as the
non-root `searxng` user but its entrypoint still needs to

1. chown /etc/searxng on first boot so the persisted named volume is
   owned by the searxng user inside the container,
2. su-exec to drop / re-assert privileges before launching uwsgi, and
3. let our wrapper entrypoint (which seeds settings.yml into the named
   volume on first boot) write the file through the volume mount.

Without explicit `cap_add`, the container has neither CHOWN nor
DAC_OVERRIDE nor SETUID/SETGID, so the entrypoint aborts at the first
chown / su-exec / redirection with EACCES. The upstream searxng-docker
compose file solves this with the standard "drop everything, grant only
what's needed" capability pattern.

Fix: mirror the upstream cap_drop ALL / cap_add CHOWN, SETGID, SETUID,
DAC_OVERRIDE on the searxng service. This grants only the four caps the
entrypoint actually needs, matches what searxng-docker ships with, and
leaves ports, volumes, env, healthcheck, and the wrapper entrypoint
unchanged.

Closes #721.
2026-06-02 02:47:30 +05:30
pewdiepie-archdaemon 90b64f32c9 Stabilize auth session revocation tests 2026-06-02 06:02:49 +09:00
Lohinth ae37a3103e Scope document tools to caller owner
Co-authored-by: Lohinth <lohinth25@proton.me>
2026-06-02 06:00:02 +09:00
Ernest Hysa 3969e059fa Scope skill mutations to caller owner
SkillsManager.update_skill walks every SKILL.md on disk and matches by
slug only; the 'owner' key in its scalar_keys whitelist meant a caller
could pass updates={'owner': 'attacker', 'description': 'pwned'} and the
first matching file on disk got silently re-owned. Two users with the
same slug under different category directories (which is supported by
the on-disk layout <category>/<name>/SKILL.md) could each stomp the
other's skill via the manage_skills tool or the in-process callers in
tool_implementations.py (edit, patch, publish, delete).

update_skill and delete_skill now require the caller's owner and only
match a file whose parsed owner field matches. The default of None
means 'no scope' and only matches ownerless skills, so an unsafe call
without an explicit owner is now a no-op. 'owner' is also removed from
scalar_keys so the updates dict cannot be used to reassign ownership
even when the manager is called from an in-process path that didn't
supply the owner argument.

The in-process callers in tool_implementations.py are updated to pass
owner=owner (which was already in scope at every call site) so the
HTTP and agent paths both go through the scoped check. The HTTP route
at routes/skills_routes.py:1499 was already owner-scoped via
sm.load(owner=user); the fix brings the in-process path up to the
same standard.
2026-06-02 05:59:43 +09:00