Commit Graph

2242 Commits

Author SHA1 Message Date
Markus Hartung
46cbd62d22 fix(combo): add missing antigravityProjectPersistence module
Upstream #8894 added an import for preferAntigravityConnectionsWithStoredProject
from ../antigravityProjectPersistence.ts in quotaStrategies.ts, but the module
itself was never committed — the file doesn't exist anywhere in git history on
either side of the merge. Since Next.js's instrumentation hook must load this
import chain successfully at boot, the missing module was fatal: the dev
server crashed entirely on every fresh start (not just the affected route).

Reconstructed conservatively per the call site and the changelog note ("prefer
Antigravity connections with stored project"): reorders connections so ones
with an already-known projectId (checked via both the direct column and the
providerSpecificData.projectId fallback, matching the shape written by
antigravityProjectPersist.ts) come first. Fail-open — reorders only, never
excludes a connection, consistent with this codebase's established pattern
for capability/preference filters elsewhere in combo/.

⚠️ base-red inherited: #9298
2026-08-07 00:02:22 +02:00
Markus Hartung
9ccfa3badb Merge remote-tracking branch 'upstream/release/v3.8.50' into feat/agentic-conversation-tracking
# Conflicts:
#	config/quality/file-size-baseline.json
2026-08-06 22:14:44 +02:00
Andrew B.
0e1f40ed1f feat(oauth): add Raycast Pro provider with local auto-import (#8895)
Validated in post-merge-train sweep (boards clean on release/v3.8.50 tip)
2026-08-06 11:08:44 -03:00
Lucas Israel
2a94cbfe14 feat(executors): add isolated Claude Code bridge over Devin ACP (#8914)
Validated in post-merge-train sweep (boards clean on release/v3.8.50 tip)
2026-08-06 11:08:37 -03:00
rinseaid
813dbb6e03 fix(vision): prevent bridge streaming and normalize OMP effort (#8945)
Validated in post-merge-train sweep (boards clean on release/v3.8.50 tip)
2026-08-06 11:08:31 -03:00
Aman
d69f521491 fix: reconcile active live model catalogs (#9294)
Validated in post-merge-train sweep (boards clean on release/v3.8.50 tip)
2026-08-06 11:08:23 -03:00
Andrew B.
a598fbb090 fix(combo): least-used quota strategy and wildcard UI preservation (#8894)
Validated in post-merge-train sweep (boards clean on release/v3.8.50 tip)
2026-08-06 11:08:02 -03:00
hppsc1215
274514405f fix(oauth): GHE Copilot OAuth lifecycle — connect, manual refresh, proactive refresh (#8970)
Validated in post-merge-train sweep (boards clean on release/v3.8.50 tip)
2026-08-06 11:07:49 -03:00
Alexey Gusev
91bb6aa619 feat(providers): add comprehensive support for self-hosted Firecrawl via FIRECRAWL_BASE_URL and custom base URLs (#9052)
Validated in post-merge-train sweep (boards clean on release/v3.8.50 tip)
2026-08-06 11:07:42 -03:00
Fajar Hidayat
8e27f5ec8d fix(sse): back the CCR block store with a durable tier (#9061) (#9198)
Validated in post-merge-train sweep (boards clean on release/v3.8.50 tip)
2026-08-06 11:07:28 -03:00
Diego Rodrigues de Sa e Souza
f2e36ad0ce fix(ci): clear base-reds on release/v3.8.50 (migration collision + 4 masked gates) (#9600)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:40:56 -03:00
Diego Rodrigues de Sa e Souza
ba0a0751c4 fix(sse): shrink chat.ts model-lockout wiring back under the frozen file-size cap (#9598)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:40:46 -03:00
Diego Rodrigues de Sa e Souza
bd4407cb64 feat(sse): New-API/One-API/Sub2API aggregator balance detection (#9415) (#9539)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:40:20 -03:00
Diego Rodrigues de Sa e Souza
ce6faa44e5 feat(models): treat quota-exhausted errors as non-hideable in Test All (#9511) (#9537)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:40:00 -03:00
Diego Rodrigues de Sa e Souza
2d617325e7 feat(catalog): add hideAutoCombos and hideNoThinkVariants settings toggles (#9418) (#9535)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:39:51 -03:00
Diego Rodrigues de Sa e Souza
607bccb6d6 feat(providers): add connection-level custom upstream headers (#8369) (#9497)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:39:41 -03:00
Diego Rodrigues de Sa e Souza
a4fbdbffac feat(copilot): add approval gate for runOmniRouteCli commands (#8461) (#9495)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:39:27 -03:00
Diego Rodrigues de Sa e Souza
8fdb67f1d3 fix(auth): redirect active sessions from /login (#9491)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:39:05 -03:00
Diego Rodrigues de Sa e Souza
b553ac4d14 feat(db): add provider-scoped model aliases (#9068) (#9469)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:38:49 -03:00
Diego Rodrigues de Sa e Souza
0720305b38 feat(providers): add Regolo AI provider (#9031) (#9468)
Validated in local merge-train (diegosouzapw batch)
2026-08-06 10:38:41 -03:00
Markus Hartung
7b1f3528e6 feat(logging): bump CHAT_LOG_ARRAY_TAIL_ITEMS default 24 -> 128
Real agentic CLIs with many MCP servers routinely declare 40-50+ tools in
a single request — a live OpenClaw session logged 47. The tail-24 default
silently dropped the array's earlier entries behind an
_omniroute_truncated_array marker, so investigating why a specific tool
call (apply_patch) behaved oddly turned up nothing: its declared shape
(function vs custom type) was unrecoverable from the call log across 40
recent requests, even though the calls themselves succeeded.

Bumped the configurable default to comfortably cover real large tool
lists with headroom. Updated .env.example and docs/reference/
ENVIRONMENT.md to match (env-doc-sync check passes).

Co-authored-by: Markus Hartung <markus.hartung@gmail.com>
2026-08-06 14:57:24 +02:00
Markus Hartung
dac626026e fix(conversations): stop truncated tool_use previews from breaking JSON
A tool_use/tool_result turn's text is the tool call's raw JSON arguments
(or a stringified result) — slicing that raw JSON at a fixed character
offset (TEXT_PREVIEW_LENGTH) routinely landed mid-string, storing INVALID
JSON. The conversations page's toTurn() then failed to JSON.parse it and
fell back to showing the raw, still-escaped text verbatim: a large
edit/write/apply_patch-style tool call with a long content field rendered
with literal `\n` sequences visible instead of real line breaks, looking
exactly like a JSON-escaping bug rather than a big diff. Confirmed live on
omniroute-dev: 3 stored `edit` tool_use previews were sitting at exactly
8000 chars with "Unterminated string in JSON" on parse.

buildTextPreview now parses first and caps oversized string VALUES inside
the JSON instead of slicing the raw blob, so a truncated payload is always
valid, re-parseable JSON. Plain text turns are unaffected (still a simple
slice — a cut-off sentence is harmless).

Also fixes JsonViewer's string rendering to preserve line breaks
(whitespace-pre-wrap) — a correctly-parsed multi-line tool argument was
still visually squashing onto one line without it.

Unrelated cleanup found while editing: conversationTracker.ts had two
literal NUL bytes (pre-existing, not introduced by this change) sitting
where a template-literal space belonged, making the file register as
binary to grep/rg/file. Restored to plain spaces.

Co-authored-by: Markus Hartung <markus.hartung@gmail.com>
2026-08-06 14:50:35 +02:00
Markus Hartung
4350a38ecb feat(dashboard): prev/next conversation nav + live streaming turn preview
Adds chevron buttons in the conversation modal to step to the adjacent
conversation in the loaded list, matching the request-detail view's
prev/next pattern.

Also surfaces the true live reply while it's still generating: turn nodes
only get written once the client resends a turn as history on its NEXT
request, so the transcript had nothing new to show mid-stream even though
the request was actively producing text. /api/conversations now exposes
activeCallLogId — the in-flight request's own id from usageHistory's
pendingById, since call_logs only gets its row on completion and the
existing lastCallLogId join always lagged one request behind. The modal
polls that id's partial text (same source/cadence as RequestLoggerDetail)
and renders it as a provisional bubble.

Co-authored-by: Markus Hartung <markus.hartung@gmail.com>
2026-08-06 14:50:17 +02:00
Markus Hartung
66a2515cbc fix(dashboard): unregister leftover service workers in dev mode
A phone that previously loaded a production build on this origin (or
an old dev build from before the registration was gated) kept an
active service worker across dev restarts. It intercepted every
navigation/asset fetch, occasionally serving a JS chunk that didn't
match the running dev server, which tripped Next's dev-client
chunk-mismatch auto-reload — visible as an unexplained, unstoppable
refresh loop on that device only (confirmed via a clean private tab
on the same phone/URL not looping).

PwaRegister now actively unregisters any existing service worker
registrations and clears their caches outside production, instead of
just skipping a new registration.

Co-authored-by: Markus Hartung <markus.hartung@gmail.com>
2026-08-06 13:21:32 +02:00
Markus Hartung
d750fb78a4 Merge remote-tracking branch 'upstream/release/v3.8.50' into feat/agentic-conversation-tracking
# Conflicts:
#	config/quality/file-size-baseline.json
#	src/app/(dashboard)/dashboard/tools/agent-bridge/components/SetupWizard.tsx
#	src/i18n/messages/es.json
#	src/lib/localDb.ts
#	tests/unit/catalog-order-contract.test.ts
2026-08-06 11:57:14 +02:00
Paijo
2ddbbc61a6 [v3.8.50] feat(memory): MemoryBackend provider pattern with generic HTTP connector (#8752)
Validated in local merge-train T7 (ungrouped batch 2)
2026-08-06 06:06:29 -03:00
Sean Ford
51f9ffc007 [v3.8.50] feat(services): add Dario as a 5th embedded service (Claude Code toggle/failover) (#8523)
Validated in local merge-train T7 (ungrouped batch 2)
2026-08-06 06:05:46 -03:00
Austin Liu
5dc8631fe4 [v3.8.50] fix(db/apiKeys): respect provider parameter in group model permission checks (fixes #8803) (#8817)
Validated in local merge-train T7 (ungrouped batch 2)
2026-08-06 06:05:39 -03:00
backryun
c3ae5b8893 refactor(db): preserve normalized combo model type (#8809)
Validated in local merge-train T7 (ungrouped batch 2)
2026-08-06 06:05:32 -03:00
NOXX - Commiter
4a6871381f [v3.8.50] feat(images): add POST /v1/images/upscale (Adobe Firefly Topaz + Stability + Topaz Labs) (#8791)
Validated in local merge-train T7 (ungrouped batch 2)
2026-08-06 06:05:18 -03:00
Diego Rodrigues de Sa e Souza
e7f6b1d130 feat(radar): flag-gated signed free-model catalog overlay (#9515)
* feat(dashboard): add RADAR_ENABLED flag (default off)

* feat(db): radar feed cache + settings with encrypted supporter key

* feat(radar): signed feed sync with pinned key and version floor

- feedSchema.ts: Zod v4 schema mirroring the server feed format
  (discriminated union on budget.kind, enum constraints, etc.)
- pinnedKeys.ts: Ed25519 SPKI-DER pinned key + env override for forks
- verify.ts: signature verification over exact wire bytes, never throws
- sync.ts: full download/verify/validate/cache pipeline with injectable
  deps, feature-flag gate, opt-in gate, version floor (numeric compare),
  and sanitized error reasons (no stack traces)
- 40 tests covering: contract hash, key handling, sig verification,
  schema validation, version compare, all sync paths (disabled, opt_out,
  invalid_signature, invalid_schema, stale, updated, error), auth header
  injection, and cache-untouched assertions for every failure mode

* feat(radar): read-time overlay merge rules over the free catalog

Pure function applyFeed() merges the cached Radar feed over the static
baseline catalog at read time, honoring 4 rules:

1. Feed never overwrites a local override field.
2. enabled:false disables the entry with disabledBy:"radar" provenance.
3. User-added entry NOT in the feed survives untouched.
4. User deletion tombstone prevents feed resurrection.

getRadarCatalog() accessor in index.ts: flag off / no cache / corrupt
payload all fall back to baseline. Valid cache applies the overlay and
returns feed metadata (version, tier, fetchedAt).

TDD: 19 tests (4 rules + dedup + origin + accessor flag/cache/corrupt/
valid/bad-feed + baselineToMergedEntries converter).

* feat(dashboard): radar catalog and guided setup screens

- API routes: GET /api/radar/catalog, POST /api/radar/sync, POST /api/radar/settings
  - All gated on RADAR_ENABLED flag (404 when off)
  - Error responses via buildErrorBody(), never raw stack/message
  - Settings never echoes clear supporter key (masked omr_****<last4>)
  - Sync delegates to syncRadar() server-side, never proxies feed URL
- Dashboard pages:
  - /dashboard/radar: 4 states (flag off, opt-in pending, empty, populated)
  - /dashboard/radar/setup?provider=X: guided setup with steps, key URL, test connection
  - Uses existing Card component and next-intl patterns
- Sidebar: radar entry in costs group with icon
- i18n: pt-BR and en keys for radarPage and radarSetupPage namespaces
- Tests:
  - radar-api-routes.test.ts: 11 tests (flag-off 404, flag-on shape, error sanitization)
  - radar-page-state.test.ts: 5 tests (pure state logic)
  - All 90 radar tests pass (including prior 74)

* docs(radar): module doc and flag-off inertia test

Add docs/frameworks/RADAR.md covering the flag gate, the separate data-sync
opt-in and privacy promise, the Ed25519 signature/pinned-key security model,
tiers, the read-time overlay merge rules, and the self-hosting env vars —
plus index entries in CLAUDE.md/AGENTS.md/docs/README.md/REPOSITORY_MAP.md.

Document RADAR_FEED_URL and RADAR_FEED_PUBKEY in .env.example and
docs/reference/ENVIRONMENT.md to satisfy check:env-doc-sync, which was
failing on this branch since the sync.ts commit added the reads.

Add tests/unit/radar-inertia.test.ts as the single canonical place asserting
the "RADAR_ENABLED off => zero behavioral delta" claim end to end: the three
/api/radar/* routes 404, the flag resolves to the definition default with no
override, getRadarCatalog() returns exactly the baseline without touching the
cache, and computeFreeModelTotals() keeps its pinned values with the Radar
module imported alongside it.

* fix(db): renumber radar migration to 135 after collision with 134

The base branch introduced 134_proxy_logs_egress_ip while this branch carried
134_radar_cache_settings; the migration runner rejects duplicate numeric prefixes.
This migration has never been applied to a real database (the PR is unmerged), so
no retroactive isSchemaAlreadyApplied guard is needed.

* i18n(radar): translate radar catalog and setup strings to all locales

The UI-coverage ratchet measures (present - placeholder) / total_en, so the
__MISSING__ sentinels that i18n:sync-ui writes do not count as covered — only
real translations restore the metric. Scoped to this PR's namespaces
(radarPage, radarSetupPage, sidebar.radar*) instead of a bulk sync, which would
have pulled ~978 unrelated pending keys into this diff.

Placeholders and code identifiers verified preserved across all 1682 strings.

* fix(radar): trust the served-tier header instead of the signed body field

The signed feed body always carries tier:"live" by design (one signed
artifact per version — rewriting the field server-side per request
would break the exact-bytes Ed25519 signature). The server now returns
the tier ACTUALLY served via the x-omniroute-feed-tier response
header, so free users on a delayed community snapshot no longer see
"Ao vivo (tempo real)" in the UI.

sync.ts now reads and validates that header (falling back to the
body's tier only when the header is absent or holds an unrecognized
value) and stores the served tier in the cache; index.ts already
surfaces cache.tier to the UI unchanged.

* test(combo): shorten an assert message that exceeded the line limit

The assertion added by #9507 was 104 chars, so prettier reformatted it into
five lines on the next commit that touched the file, pushing it past its
frozen size (3449) and failing check:file-size. The message is shortened
(the issue reference stays in the comment directly above); the assertion
itself is unchanged, and the file is back to 3448 lines and prettier-clean.

* i18n(radar): use the canonical zh-TW glossary terms

The machine translation produced retired renderings the glossary gate blocks:
供應商 for provider (canonical 提供者) and 文檔 for documentation (canonical 文件).
Fixed across the 11 affected radar strings; tests/unit/i18n-glossary-consistency-check.test.ts
is back to 17/17.

* fix(radar): point the default feed URL at the domain that exists

radar.omniroute.dev was a placeholder for a domain that was never registered,
so an out-of-the-box sync would fail DNS resolution for every user. The live
feed is served from radar.omniroute.online (the subdomain the design always
specified), now behind Cloudflare TLS. Forks still override it via
RADAR_FEED_URL.

---------

Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
2026-08-06 05:58:58 -03:00
Austin Liu
8a7b2467fd [v3.8.50] feat(combo): add maxContextWindow to contextRequirements (fixes #8777) (#8790)
Validated in local merge-train T6 (ungrouped batch 1)
2026-08-06 05:24:39 -03:00
Austin Liu
f843bac030 [v3.8.50] fix(auth): accept x-api-key without anthropic-version for claude-code user-agent (fixes #8655) (#8678)
Validated in local merge-train T6 (ungrouped batch 1)
2026-08-06 05:24:27 -03:00
Éder Costa
0b4bc4f4b1 [v3.8.50] fix(antigravity): lock full quota per exact model (#8630)
Validated in local merge-train T6 (ungrouped batch 1)
2026-08-06 05:24:21 -03:00
Alberto Punter
39220a1a5c fix(i18n): correct and naturalize Spanish translations (#8339)
Validated in local merge-train T6 (ungrouped batch 1)
2026-08-06 05:23:45 -03:00
Markus Hartung
81646aaf04 fix(chatcore): restore missing mergeResponseToolNameMap import
Genuine pre-existing bug on upstream release/v3.8.50 (verified byte-
identical to their tip, not introduced by this branch's merge): chatCore.ts
calls mergeResponseToolNameMap() but never imports it from
./chatCore/passthroughToolNames.ts, throwing a ReferenceError on every
request that reaches that line (surfaced by
agentrouter-chatcore-protocols.test.ts's 3 streaming-protocol cases).

Also renumbers this branch's own migrations from 137/138 back to a
contiguous 136/137 — the earlier 135->137 renumber (done to resolve this
branch's collision with upstream's independently-added
135_migrate_model_capability_max_token.sql) skipped 136 entirely, leaving
an unexplained sequence gap that check-migration-numbering.test.ts's real-
migrations-dir check correctly flagged.
2026-08-06 07:29:44 +02:00
Diego Rodrigues de Sa e Souza
8c5bfbe631 fix(quality): reconcile inherited file-size drift on the release tip (#9554)
* fix(quality): reconcile inherited file-size drift on the release tip

13 files sit above their frozen LOC on the clean tip 8180b49ce1
(measured by the gate itself). The PR-mode base-relative check (#8522)
correctly lets innocent PRs pass, but per-PR rebaselines were lost
across successive conflict resolutions of this hot file during the
08-05/06 merge batch — so the absolute mode (nightly, local runs) is
permanently red and stops distinguishing real growth from inherited
drift.

Frozen values updated to the measured tip, each annotated with the
merged PR that grew the file (#9024 #9324 #9329 #9193 #9332 #9228
#9236 #9314 #9260 #8934 #9196 #9163); executors default.ts and kiro.ts
(above the 1000 cap with no frozen entry) join the frozen set.

* fix(quality): prune orphaned ESLint suppressions and clear the 5 unsuppressed errors

The 'No new ESLint warnings' job reds the whole queue with exit 2:
'There are suppressions left that do not occur anymore' — the 08-05
merge batch removed code whose violations were frozen in
eslint-suppressions.json, leaving orphaned entries (673->670 files,
4338->4333 violations after eslint --prune-suppressions).

The full-tree run also surfaced 5 real unsuppressed errors merged with
the batch, fixed here instead of suppressed (new violations must be
fixed, per policy): 4x no-explicit-any in
tests/unit/catalog-order-contract.test.ts ((conn as any).id -> typed
cast) and 1x react/no-unescaped-entities in the agent-bridge
SetupWizard (#9095).

Also restores the _comment policy header the successive hot-file
conflict resolutions had dropped (TS7 debt freeze provenance + prune
policy).

* fix(quality): absorb the two file-size growths merged while this PR was in CI

The base kept moving during the reconcile cycle: #9184 grew
src/sse/handlers/chat.ts 1857->1877 and #9005 grew
open-sse/executors/default.ts 1027->1042. Re-measured on the merged
tree; gate back to 0 violations.

* fix(tests): move the orphaned RTL ratchet test to a collected path as node:test

#8828 added tests/unit/scripts/check-rtl-ratchet.test.ts — a path no
runner collects (the node:test globs enumerate an explicit subdir list
without scripts/, and vitest.config.ts never included it), so the file
NEVER ran and the test-discovery orphan gate reds the queue. Moved to
tests/unit/ (collected by node:test) and converted from vitest
describe/it/expect to node:test+assert to match the runner and the
sibling check-*.test.ts files. 5/5 green under the real runner.

---------

Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
2026-08-06 01:45:28 -03:00
Markus Hartung
58f36a3484 Merge remote-tracking branch 'upstream/release/v3.8.50' into feat/agentic-conversation-tracking
# Conflicts:
#	config/quality/file-size-baseline.json
#	src/i18n/messages/fr.json
#	src/i18n/messages/it.json
#	src/i18n/messages/ru.json
#	src/i18n/messages/zh-CN.json
#	src/i18n/messages/zh-TW.json
2026-08-06 06:36:39 +02:00
Markus Hartung
ffbc46f463 fix(dashboard): Previous/Next nav closing modal on stale background list
Background list polling intentionally pauses while a request's detail
modal is open, so hitting the edge of the in-memory sorted list didn't mean
there was really nothing newer/older — it just meant the client hadn't
fetched requests that landed in the background yet. handlePrev/handleNext
now resync the list once at that boundary and let a follow-up effect decide
whether to navigate or actually close, instead of assuming the boundary is
real.

Also removes onNavigateToLog from RequestLoggerV2/RequestTimeline's calls
into RequestLoggerDetail — that prop no longer exists after the detail
panel's cross-row next-turn navigation was removed in the prior commit.
2026-08-06 06:04:03 +02:00
Markus Hartung
9384391daf refactor(dashboard): simplify request detail panel, fix Responses API tool-call gap
RequestLoggerDetail's Conversation Context section now renders only the
currently-viewed request's own buildRequestTurns/buildResponseTurns output
directly, instead of reconstructing a cross-row transcript from prior
requests sharing a session_tag. A single request's own body already is its
full context; the operator asked for this after the multi-row reconstruction
made indentation grow unboundedly (superseded by conversationTracker.ts's
no-forking redesign). Deletes multiRowConversation.ts and its test — dead
code once the panel no longer walks prior rows. Kept live-streaming updates
for an active request (extractPartialAssistantText now also accumulates
delta.reasoning_content, so the panel keeps visibly progressing during a
reasoning-only streaming phase) and added a liveRefresh toggle + scroll-to-
bottom control mirroring StreamSection's existing pattern.

Fixes a real, universal data-loss bug found while investigating why tool
calls looked different between the detail panel and the conversation tree
view: turnsFromOpenAiMessages (conversationNormalizer.ts) only handled
role-based Chat Completions messages. Real Responses API traffic (OpenClaw)
sends bare {type:"function_call"}/{type:"function_call_output"}/
{type:"reasoning"} items with NO role field at all, so they were silently
dropped — every tool call in a Responses API conversation vanished from the
Conversation Context panel. Now handled explicitly before the role-based
branches.

Also fixes a Dark Reader (browser extension) false-positive hydration
warning on OmniRouteLogo's SVG lines (suppressHydrationWarning — the
extension injects data-darkreader-inline-stroke before React hydrates), and
adds break-words to MarkdownMessage so long unspaced runs (raw JSON, ids)
wrap instead of overflowing a narrower container like the conversation
modal. ChatBubble's onClick doc comment updated to reflect it's no longer
multiRowConversation-specific.
2026-08-06 06:04:03 +02:00
Markus Hartung
a2df6cf289 fix(logging): use configurable max-depth when bounding logged tool_calls
requestLogger.ts's cloneBoundedForLog had its own hardcoded depth cap of 6,
independent of the existing configurable getChatLogMaxDepth(). A typical
Chat Completions response body's responseBody.choices[0].message.tool_calls[0].function
sits at exactly depth 6, so every logged tool call's function field
(name+arguments) was silently replaced with the literal string "[MaxDepth]"
before ever being stored — corrupting the data, not just how it renders.
Bumped the shared default 6->20 and switched requestLogger.ts to read it
instead of using its own literal.
2026-08-06 06:04:03 +02:00
Markus Hartung
f851374e62 feat(conversations): redesign to no-forking model with pagination and duplicate-anchor fix
Every conversation is now a single straight line: when a request's turn
history diverges from what's on file (real OpenClaw traffic edits/
duplicates turns to keep provider-side prompt caches warm), the diverging
history mints its own independent conversation instead of forking a branch
inside the old one. Distinguished via anchorHasChild — whether the
reconnect anchor already has a recorded child.

Also fixes the actual production-blocking bug this surfaced: real agentic
traffic is full of byte-identical repeated turns (tool-polling loop output,
heartbeat acks — one real conversation had 28 duplicates of a single turn).
findReconnectMatch used to return on the first candidate anchor found for a
repeated turn's content hash — in practice the oldest, stalest occurrence —
whose recorded next-turn differs from the current request, so it looked
like a divergence on every single request instead of ever reconnecting.
Now every candidate anchor is evaluated and the one that verifiably extends
furthest wins (ties break toward the anchor with no recorded child).

Dashboard: /dashboard/conversations lists conversations by actual turn-node
count instead of request-touch count (a freshly-forked conversation can
carry hundreds of turns from a single insert but start at turn_count=1,
which wrongly excluded it from the old turn_count>=2 filter). The
conversation view loads the last 20 turns with a "Load more" button,
scrolls to bottom on open and stays pinned there via a ResizeObserver while
large/late-settling content keeps growing (a single requestAnimationFrame
undershoots for a page containing multi-KB tool-output turns), and resyncs
its "Goto latest request"/summary fields from the background list poll so
they don't go stale while the modal stays open (keyed off the id, not the
whole row object, so the poll-for-new-turns interval isn't reset every
tick by that resync).

X-ConversationId threading: chat.ts now passes the request's own
correlationId into resolveConversationId so new turn-chain nodes can be
tagged with a request identifier that exists before the call_logs row
itself does. usageHistory's in-memory pending-request state (byModel/
byAccount/details/pendingById) is reused across Next.js dev HMR module
re-evaluations via a globalThis singleton (same pattern as db/core.ts),
so a live poll against a request that started before a hot-reload doesn't
silently lose its partialAssistantText/isActive tracking.
2026-08-06 06:04:03 +02:00
Paco Cartones
bca61af8ae fix(api/skills): sanitize error messages before returning them to clients (#9088)
Validated in local merge-train T5 (base49+contributors+pacocartones)
2026-08-06 00:09:55 -03:00
Paco Cartones
7d07f1f500 fix(a2a): timing-safe bearer comparison + drop per-request debug log (#9083)
Validated in local merge-train T5 (base49+contributors+pacocartones)
2026-08-06 00:09:49 -03:00
Paco Cartones
7c0a96c69b fix(batches): validate the list endpoint's ?limit query param (#9073)
Validated in local merge-train T5 (base49+contributors+pacocartones)
2026-08-06 00:09:43 -03:00
NOXX - Commiter
a072ff4552 fix(adobe-firefly): open browser sign-in and resolve provider slug in /login (#9097)
Validated in local merge-train T5 (base49+contributors+pacocartones)
2026-08-06 00:09:30 -03:00
3g0r1ch
065301f79d feat(model-alias): add runtime Model Alias Resolver middleware (#9020)
Validated in local merge-train T5 (base49+contributors+pacocartones)
2026-08-06 00:09:18 -03:00
3g0r1ch
07cd4c0f2e i18n(ru): complete Russian locale — fill 25 missing keys and 80 placeholders (#9001)
Validated in local merge-train T5 (base49+contributors+pacocartones)
2026-08-06 00:09:05 -03:00
Rahul sharma
a9b4c3efff fix(api): alias-backed models leak raw node UUID prefix in /v1/models (#8958) (#8961)
Validated in local merge-train T5 (base49+contributors+pacocartones)
2026-08-06 00:08:59 -03:00
Ahmet Çetinkaya
749fc75beb fix(combo): exclude hidden leaves from catalog and dispatch (#8878)
Validated in local merge-train T5 (base49+contributors+pacocartones)
2026-08-06 00:08:52 -03:00