Commit Graph
2522 Commits
Author SHA1 Message Date
pewdiepie-archdaemon da215cf242 audit search variety with model provenance and per-turn latency 2026-09-17 20:01:38 +00:00
pewdiepie-archdaemon a7576f721c verify embedded articles skip redundant retrieval rounds 2026-09-17 19:58:06 +00:00
pewdiepie-archdaemon 02200b2874 reuse embedded search articles and reject browser error pages 2026-09-17 19:57:20 +00:00
pewdiepie-archdaemon f27070c469 buffer rejected search drafts and cap interactive rounds 2026-09-17 19:53:40 +00:00
pewdiepie-archdaemon ff4d01a55e ground fresh searches and verify official documents 2026-09-17 19:49:28 +00:00
pewdiepie-archdaemon 994413c435 compose explicit search and fetch workflows 2026-09-17 19:43:20 +00:00
pewdiepie-archdaemon 8c7ea10520 ground current lookups and recover failed fetches 2026-09-17 19:42:38 +00:00
pewdiepie-archdaemon dfd4d5a80e preserve evidence after bounded web search 2026-09-17 19:35:54 +00:00
pewdiepie-archdaemon f2fb42c7d1 synthesize after bounded search suppression 2026-09-17 19:27:16 +00:00
pewdiepie-archdaemon 295578514e route current events through bounded news search 2026-09-17 19:26:04 +00:00
pewdiepie-archdaemon e9a117df0d bound optional search fallback latency 2026-09-17 19:22:51 +00:00
pewdiepie-archdaemon 6b135eab73 finish resource lookups from verified search metadata 2026-09-17 19:18:05 +00:00
pewdiepie-archdaemon e49264ae47 preserve product identity in manual search 2026-09-17 19:15:39 +00:00
pewdiepie-archdaemon e48ea98d2f broaden empty searches through resilient providers 2026-09-17 19:12:28 +00:00
pewdiepie-archdaemon e22cf4b500 bound search attempts by research depth 2026-09-17 19:07:22 +00:00
pewdiepie-archdaemon 483fdc7054 require linked broad research synthesis 2026-09-17 19:04:08 +00:00
pewdiepie-archdaemon e3107a645d enforce distinct research refinement 2026-09-17 19:02:11 +00:00
pewdiepie-archdaemon 6121442658 unify broad web briefing semantics 2026-09-17 18:58:31 +00:00
pewdiepie-archdaemon be48da1146 recognize natural broad current queries 2026-09-17 18:55:19 +00:00
pewdiepie-archdaemon cdc0734347 require breadth for broad current research 2026-09-17 18:51:56 +00:00
pewdiepie-archdaemon 69a1b97c96 recover rendered pages from fetch boilerplate 2026-09-17 18:49:59 +00:00
pewdiepie-archdaemon 4d7c9d44d1 keep compact agent core tools available 2026-09-17 18:47:04 +00:00
pewdiepie-archdaemon 25ff725c1d repair broad web research recovery 2026-09-17 18:36:12 +00:00
pewdiepie-archdaemon 0aa470b095 recover synthesis after unavailable web search 2026-09-17 13:34:36 +00:00
pewdiepie-archdaemon 337a47d27d skip redundant synthesis after email actions 2026-09-17 13:21:11 +00:00
pewdiepie-archdaemon 10d637f8b9 ground research synthesis in retrieved source urls 2026-09-17 10:50:20 +00:00
pewdiepie-archdaemon 8ae0c31666 bound web research to retrieval and synthesis 2026-09-17 10:41:14 +00:00
pewdiepie-archdaemon 218d762427 Consolidate Odysseus agent harness and tool contracts 2026-09-17 10:07:40 +00:00
Boody 3b6c169162 Merge pull request #6280 from isharak7m/fix/token-cache-race-condition
fix: atomic token cache swap to eliminate race condition
2026-09-14 00:53:34 +03:00
isharak7m 6001f82019 test: rewrite to exercise actual production _refresh_token_cache
The previous test used a _SharedCache simulation that proved the atomic
swap pattern works but didn't exercise the real app.py code. This rewrite
imports app.py with AUTH_ENABLED=true, mocks SessionLocal and logger,
creates a real AuthManager user, and calls the actual _refresh_token_cache()
while concurrent readers access the actual _token_cache global.

7 tests: single row, multiple prefixes, empty DB, app.state sync, dirty
flag cleared, 4 concurrent readers x 100 refreshes (zero empty reads),
and 50 create/revoke churn cycles with concurrent readers.
2026-09-13 19:19:12 +05:30
isharak7m 0b6d44890f test: add regression for token cache atomic swap race condition
Exercises the concurrent reader/writer scenario that the atomic swap
fix in app.py addresses. Uses a _SharedCache helper that mirrors the
module-level _token_cache global — both reader and writer access the
same .current reference, so the GIL-atomic swap is properly tested.

6 tests: swap correctness, concurrent readers (4 threads x 100 refreshes,
zero empty reads), app.state sync, multiple prefixes, empty DB, and
concurrent refresh from 4 threads.
2026-09-13 18:46:27 +05:30
isharak7m 984337b35b fix: atomic token cache swap to eliminate race condition
Replaced _token_cache.clear() + _token_cache.update(new_map) with an
atomic reference swap (_token_cache = dict(new_map)). The two-step
mutate approach had a window where the dict was empty — any request
hitting the reader at line 428 during that window would see zero
candidates and return 401.

Python's GIL makes the reference assignment atomic: readers always see
either the old fully-populated dict or the new one, never an empty state.
2026-09-12 10:30:40 +05:30
Amir Fathi 9d5c031914 fix(mcp): reject malformed Args on Add MCP Server instead of silently defaulting to [] (#6215)
* fix(mcp): reject malformed Args on Add MCP Server instead of silently defaulting to []

* test(mcp): pass every Form param add_server reads past args validation

CI's pytest run showed test_add_server_still_accepts_valid_json_args and
test_add_server_still_defaults_empty_args_to_empty_list failing with
TypeError: the JSON object must be str, bytes or bytearray, not Form.

Calling the endpoint function directly bypasses FastAPI's dependency
resolution, so an unpassed Form(...) parameter (url, oauth_file,
oauth_config) arrives as the Form marker object itself rather than its
declared default, and add_server's later `if oauth_file:` check reads
that marker as truthy. The malformed-args test never hit this because it
raises before reaching that code. Not a production bug: a real HTTP
request resolves these through FastAPI before add_server ever runs.

* fix(mcp): reject non-list args and surface the new 400 in the Admin panel

o3LL's review on #6215 found two gaps in the args validation this PR adds:
the Admin panel posts to the same /api/mcp/servers endpoint but never
validates Args client-side, so the new 400 falls into the generic failure
branch and shows "Added but connection failed: unknown". Mirror the same
JSON.parse guard settings.js already has.

Also add an isinstance(list) check next to the existing JSON parse, since
valid-but-wrong-shaped JSON (args=5) reaches StdioServerParameters(args=5)
and 500s in the error formatter. Pre-existing on dev, same validation site
this PR already touches.

* fix(admin): surface the server's 400 detail instead of a generic connection-failed message

The Admin add-server handler read needs_oauth/connected/error but never
res.ok, so a request rejected by the isinstance(list) check added for
#6211 (args=5, a valid-JSON-but-non-list value the client-side JSON.parse
guard cannot catch) fell into the same-shape else branch as a successful
add whose connection attempt failed, and the form fields were cleared as
if the server had accepted it.
2026-09-11 15:36:41 +02:00
pewdiepie-archdaemon 84aa9a91de Squash Odysseus development history 2026-09-11 06:04:19 +00:00
nopozandRaresKeY 934d23c0be Merge commit from fork
* fix(security): keep agent file tools out of the app state directory

The agent's read tools (read_file, grep, glob, ls) resolved model-supplied
paths against a root list whose first entry was the whole data directory.
That directory holds the session store, the auth database, the app
encryption key and the settings file, so prompt-injected content could ask
for any of them. No approval prompt stood in the way: reads are classified
read_workspace and pass the untrusted-context gate untouched, which is
correct for reading a workspace and wrong for reading the app's own state.

The agent gets data/agent_workspace/ instead, and the subprocess cwd and
HOME move with it so bash and read_file agree on where scratch files live.

The deny itself is a property of the path, not of the root it arrived
through, because three routes reach the same bytes and closing only the
first leaves the other two working:

  - the default root list
  - a workspace bound at or above the data directory, which vet_workspace
    accepted and chat_routes auto-binds from a path named in the message
  - a tool_path_extra_roots setting covering the data directory

_resolve_search_root also returned the workspace root unchecked when the
path was empty, so a bare ls enumerated the directory whatever the deny
list said. It now resolves that case through the same guards.

A containment rule rather than a filename deny list, so state files added
later are covered without anyone remembering to list them, and so a user's
own settings.json or app.db inside a real workspace is not caught.

Four directories of user content stay readable, because the application
hands their paths to the model and tells it to open them: the chat upload
manifest, downloaded mail attachments, personal docs (which covers the
runbook) and personal uploads.

* fix: enforce state deny during recursive file search

* fix: bound protected filesystem searches

* fix(security): reject inode aliases and workspace redirects

* fix(security): harden partitioned agent searches

* fix(security): report fallback worker exits promptly

* fix(security): clean up search readers and retain relative data roots

---------

Co-authored-by: RaresKeY <158580472+RaresKeY@users.noreply.github.com>
2026-09-05 19:21:12 +02:00
nopozandRaresKeY f88e2d1f7f Merge commit from fork
* fix(security): stop API tokens reaching privileged agent tools

A bearer API token resolves to the human who minted it, and minting is admin-only, so every owner-keyed privilege check in the agent path answers "admin". A token issued for a narrow integration therefore reached bash and python with the authority of the account that created it.

Three independent routes to that sink, each closed here.

The token could answer its own tool-approval prompt. An approval records that a person authorized one dangerous action, and a token cannot make that statement, so /api/chat_stream now refuses an approval resume from a bearer caller.

The chat-session grant was reconstructable from caller-supplied message metadata. Two routes persist a metadata blob on the caller's behalf, so the shape of a resolved approval card could be written straight into a transcript and was then read back as authority. The server now signs the grant when it resolves an approval and verifies that signature when reading it back, binding it to the chat and the approval it was issued for. Both routes also drop server-owned keys from an inbound blob.

A run driven by a token inherited its owner's tool set. Such a run is now capped at the non-admin policy regardless of who minted the credential, which holds even where no approval is raised at all.

The human path is unchanged: a browser session still receives the prompt, still approves, and a granted chat-session scope still carries to later turns in that chat.

Scope enforcement across the wider route surface is a separate gap and is not addressed here.

* fix scoped chat delegation boundaries

* fix(auth): reject malformed chat approval signatures

---------

Co-authored-by: RaresKeY <158580472+RaresKeY@users.noreply.github.com>
2026-09-05 19:20:49 +02:00
rauljuaandRaul c7a8637475 fix(docker): repair app cache parent ownership (#6158)
* fix(docker): repair app cache parent ownership

* fix(docker): avoid walking mounted model cache

* test(docker): exercise nested cache ownership

---------

Co-authored-by: Raul <9117159+raultcj@users.noreply.github.com>
2026-09-05 18:05:38 +02:00
VykosandClaude affaee1e66 fix(discovery): cache a successful but empty Tailscale lookup (#6228)
The host cache was gated on the list being non-empty, so "queried fine, no
eligible peers" looked exactly like a cold cache and every caller paid for
another `tailscale status --json` — a subprocess with a 5s timeout.

Gate on the timestamp instead. Failures still leave the timestamp unset, so a
missing binary, a non-zero exit or unparseable output stays retryable rather
than being cached for the full TTL.

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-02 12:05:01 +02:00
daixiheguu ce04dc1db4 fix(tasks): clean up singleflight cache on cancellation (#6174)
Signed-off-by: daixiheguu <daixihegu@outlook.com>
2026-09-01 18:34:50 +02:00
cybernetus@xda 5154bae544 fix(deps): switch psycopg2 to psycopg2-binary (#5937)
Building psycopg2 from source needs libpq-dev/pg_config, which isn't
in the Docker image or most dev hosts, so pip install silently fails
and Postgres users hit ModuleNotFoundError at import time.
2026-09-01 17:49:21 +02:00
Glitch3dPenguin 9473d980a4 Merge remote-tracking branch 'upstream/dev' into fix/5728-ghcr-registry-image
# Conflicts:
#	README.md
2026-08-29 21:59:21 +00:00
RaresKeY c9dd68d890 refactor(docs): separate Pages site source (#6176)
* refactor(docs): separate Pages site source

* fix(docs): preserve published guide pages

* fix(ci): run asset ownership tests for site changes

* fix(docs): track future website media

* fix(ci): let Pages deployments finish

* build(deps): update Pages checkout action

* fix(ci): follow moved setup guide

* fix(docs): repair published setup guide

* fix(docs): retarget preview encoder
2026-08-27 10:20:36 +02:00
Max Kulik ba6eb42e0b Merge remote-tracking branch 'upstream/dev' into fix/5728-ghcr-registry-image 2026-08-25 14:26:08 -05:00
RaresKeYandStressTestor 7026cf40b5 docs: bootstrap specs ground truth (#5794)
* docs(specs): restore bootstrap after dev rewrite

* docs(specs): remove runtime inventory snapshot

* docs(specs): reconcile current dev truth

* docs(specs): document scheduled task actions as an owner-attribution source

Owner Attribution covered cookie, bearer-token and internal-loopback
requests. Scheduled task actions are a fourth source and behave
differently: _execute_action passes owner=task.owner off the stored
ScheduledTask row, so no request and no resolved principal are in
flight, and route-level require_user() never runs.

Webhook triggers are the sharp case. They are unauthenticated by
design with the token as the only credential and execute under the
stored task.owner.

Paths cite routes/task/task_routes.py, the canonical location after
the task subpackage move (#6081); routes/task_routes.py on current dev
is the backward-compat shim.

* docs(specs): add chained tasks to the trigger list, refresh dev stamp

Review feedback from RaresKeY on the previous commit.

"Every trigger path" was too broad: success-chained tasks are another
path into _execute_action. Added them with their own citation, and
noted that chaining additionally requires the target task to share
task.owner and rejects cycles, which is stricter than the trigger-side
checks. Softened the lead-in to "these trigger paths".

Line 56 still pointed at routes/task_routes.py for webhook credential
validation. That path is the backward-compat shim on current dev after
the task subpackage move (#6081); repointed to the canonical
routes/task/task_routes.py.

Stamp moved to dev@2a6b09b. Inspection backing that bump was scoped:
every file path cited in this spec was mechanically checked to resolve
on 2a6b09b, and every file:line in the Owner Attribution additions was
read against it. Behavioral claims elsewhere in the file were not
re-audited.

* docs(specs): correct SECURE_COOKIES description to match current behavior

Third of the stale details RaresKeY enumerated. The cookie section
described SECURE_COOKIES as purely opt-in, which stopped being true.

_secure_cookie() (routes/auth_routes.py:89) treats an explicit true or
false as authoritative and derives the Secure attribute from the
request otherwise, including when the variable is unset and when
docker-compose injects it present-but-empty. Either the connection
scheme or the first X-Forwarded-Proto hop being https is enough.

* docs(specs): refresh current dev truth

---------

Co-authored-by: StressTestor <212606152+StressTestor@users.noreply.github.com>
2026-08-25 14:18:44 +02:00
dependabot[bot] bc7514fa3e build(deps): bump the actions group with 11 updates (#6141)
Bumps the actions group with 11 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `7.0.0` | `7.0.1` |
| [actions/setup-python](https://github.com/actions/setup-python) | `6.2.0` | `7.0.0` |
| [actions/setup-node](https://github.com/actions/setup-node) | `6.4.0` | `7.0.0` |
| [github/codeql-action/init](https://github.com/github/codeql-action) | `4.36.2` | `4.37.7` |
| [github/codeql-action/analyze](https://github.com/github/codeql-action) | `4.36.2` | `4.37.7` |
| [hadolint/hadolint-action](https://github.com/hadolint/hadolint-action) | `3.3.0` | `3.4.0` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.1.0` | `4.3.0` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `7.2.0` | `7.3.0` |
| [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.36.2` | `4.37.7` |
| [docker/login-action](https://github.com/docker/login-action) | `4.2.0` | `4.6.0` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `6.1.0` | `6.2.0` |


Updates `actions/checkout` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0...3d3c42e5aac5ba805825da76410c181273ba90b1)

Updates `actions/setup-python` from 6.2.0 to 7.0.0
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/a309ff8b426b58ec0e2a45f0f869d46889d02405...5fda3b95a4ea91299a34e894583c3862153e4b97)

Updates `actions/setup-node` from 6.4.0 to 7.0.0
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e...820762786026740c76f36085b0efc47a31fe5020)

Updates `github/codeql-action/init` from 4.36.2 to 4.37.7
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd)

Updates `github/codeql-action/analyze` from 4.36.2 to 4.37.7
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd)

Updates `hadolint/hadolint-action` from 3.3.0 to 3.4.0
- [Release notes](https://github.com/hadolint/hadolint-action/releases)
- [Commits](https://github.com/hadolint/hadolint-action/compare/2332a7b74a6de0dda2e2221d575162eba76ba5e5...2a66e89f53d0771bb131a7fa31f3136336094aa6)

Updates `docker/setup-buildx-action` from 4.1.0 to 4.3.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5...37fe631027851001ddb9b187196cc803df7f5f0e)

Updates `docker/build-push-action` from 7.2.0 to 7.3.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/f9f3042f7e2789586610d6e8b85c8f03e5195baf...53b7df96c91f9c12dcc8a07bcb9ccacbed38856a)

Updates `github/codeql-action/upload-sarif` from 4.36.2 to 4.37.7
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8aad20d150bbac5944a9f9d289da16a4b0d87c1e...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd)

Updates `docker/login-action` from 4.2.0 to 4.6.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/650006c6eb7dba73a995cc03b0b2d7f5ca915bee...dbcb813823bdd20940b903addbd779551569679f)

Updates `docker/metadata-action` from 6.1.0 to 6.2.0
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](https://github.com/docker/metadata-action/compare/80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9...dc802804100637a589fabce1cb79ff13a1411302)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: actions/setup-python
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: actions/setup-node
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.37.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: hadolint/hadolint-action
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: docker/build-push-action
  dependency-version: 7.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.7
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: docker/login-action
  dependency-version: 4.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: docker/metadata-action
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-25 14:06:31 +02:00
dependabot[bot] e5ab632270 build(deps-dev): bump @antithesishq/bombadil (#6026)
Bumps the npm group with 1 update in the / directory: [@antithesishq/bombadil](https://github.com/antithesishq/bombadil).


Updates `@antithesishq/bombadil` from 0.6.1 to 0.7.0
- [Release notes](https://github.com/antithesishq/bombadil/releases)
- [Changelog](https://github.com/antithesishq/bombadil/blob/main/CHANGELOG.md)
- [Commits](https://github.com/antithesishq/bombadil/compare/v0.6.1...v0.7.0)

---
updated-dependencies:
- dependency-name: "@antithesishq/bombadil"
  dependency-version: 0.7.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-25 14:03:11 +02:00
RaresKeY e71f8ceb65 chore(release): align dev version with 1.0.3 (#6168)
Keep dev version metadata aligned with the current hotfix release while the rolling branch continues toward 1.1.0.

Evidence: the canonical APP_VERSION imports as 1.0.3 and the diff check is clean. This commit changes version metadata only; it does not tag or publish a release.
2026-08-25 10:26:18 +01:00
nopoz d0d8edf5d8 Merge commit from fork
scripts/mlx_image_server.py resolved the model per request
(`req.model or _args.model`) on both /v1/images/generations and
/v1/images/edits, so the caller chose which model was served.

`_is_hidream()` is a substring test and `_snapshot_path()` accepts either a
local directory or a Hugging Face repo id, so a caller-supplied string
selected the HiDream branch and then supplied the directory it runs
`scripts/hidream_o1/generate_hidream_o1_mlx.py` from, under sys.executable.
The server has no auth, and the Cookbook binds it to 0.0.0.0 whenever it is
serving to a remote host, so one POST executed attacker code on the serving
host.

Both paths now use `_args.model`. The request field is still accepted for
OpenAI wire compatibility and ignored, matching scripts/diffusion_server.py,
and Odysseus already sends the served model's own id, so this is a no-op for
legitimate callers. /v1/images/harmonize already pinned.

Regression tests cover both endpoints, the local-directory and
Hugging-Face-repo halves, and that a server actually launched with a HiDream
model still serves it. Three of the four fail on the unfixed code.
2026-08-24 17:38:40 +02:00
Joeseph Grey b4d12932a9 fix(agent): drop the empty assistant turn from an approved-action replay (#6124)
The approved-action replay appends the sealed tool result with no assistant
prose for that round, which produced an assistant message with content "".
Anthropic's Messages API rejects a non-final assistant message with empty
content, so a resumed turn after a tool approval failed before the model saw
the result. A turn carrying neither prose nor reasoning has nothing to say to
any provider, so it is no longer appended. A round with prose, and a
reasoning-only round that DeepSeek thinking mode needs, both still append.
2026-08-20 13:06:22 +02:00
Nikhil Chaudhary 85297cee44 fix(core): clean up orphaned temp files on atomic write failure (#6068)
* fix(core): clean up orphaned temp files on atomic write failure

* fixed reviewer suggestion

* removed whitespace
2026-08-19 17:38:24 +02:00