Anthropic silently switched adaptive-thinking's display default to
"omitted" starting with Claude Opus 4.7, so the Bedrock provider
stopped surfacing any reasoning content — observed in the wild as
silent streams and timeouts on long reasoning runs.
Mirrors the existing direct-Anthropic behavior in this repo:
- For adaptive-thinking models that accept the field (Opus 4.7+),
emit { type: "adaptive", display: "summarized" } by default.
- For older adaptive-thinking models (Opus 4.6, Sonnet 4.6+) that
reject the field, keep emitting just { type: "adaptive" }.
- For budget-based Claude models, always set display.
- Expose BedrockOptions.thinkingDisplay ("summarized" | "omitted")
so callers can opt out, and wire hideThinkingSummary into the
bedrock-converse-stream case in stream.ts.
Fixes#1373
Quarantined persistent session keys only while the native cancellation promise remains unsettled, so healthy cleanup restores persistent mode and stalled cleanup cannot accumulate live shell instances.
Added coverage for both stalled and settled native cleanup paths.
Fixes#1347
Queued extension-delivered user messages when deliverAs is set and waited for session_start extension message sends before prompting subagents.
Fixes#1343
Stopped marking persistent bash sessions as permanently broken when the JavaScript abort or timeout race wins.
Stopped the Rust descendant kill-wave helper once no cancellation targets remain so later commands are not swept into old cancels.
Fixes#1347
- Restructured the auth-broker `openSnapshotStream` tests to be top-level cases under the describe suite.
- Added a stream parser test asserting pure ": keepalive" lines are not included in subsequent SSE event raw output.
- AuthBrokerClient now checked the response Content-Type and rejected non-SSE responses before parsing.
- It required the first parsed SSE event to be a snapshot and treated ended or truncated streams as errors.
- Added coverage for non-SSE and missing-initial-snapshot streams, and reset raw SSE state for empty events.
- Updated nested task-rendering tests to use parent-qualified IDs for completed child task results.
- Updated in-flight nested snapshot expectations to verify parent-aware `Parent>Subtask` labeling.
- Documented the live nested task rendering behavior in the package changelog.
- Added `/v1/snapshot/stream` SSE support and discriminated `snapshot`/`entry`/`removed` event payload contracts.
- Added `openSnapshotStream()` with abort handling, unsupported-stream errors, and filtered SSE payload parsing.
- Added `streamSnapshots` as default-true in remote store with SSE-first background syncing and 404-based fallback.
- Added per-credential generation tracking and `streamKeepaliveMs` tuning for long-lived SSE connections.
- Captured `tool_execution_update` snapshots for `task` calls into in-flight progress state for live nested rendering.
- Cleared in-flight task snapshots at task start and completion to prevent stale nested progress from persisting.
- Updated progress rendering to combine completed and in-flight task details through a dedicated nested task tree view.
Added Rust-side descendant termination on shell cancellation paths so aborts and timeouts escalate to SIGKILL even if brush cleanup stalls.
Covered SIGTERM-ignoring shell workloads in native tests.
Fixes#1347
- Added a per-credential in-flight refresh map in AuthStorage and returned existing promises for concurrent OAuth refreshes.
- Updated OAuth API-key retrieval to share refreshes and persist refreshed candidate credentials.
- Added tests covering preflight persistence across multiple credentials and ensuring concurrent refreshes coalesced to one call.
- Normalized reviewer-bot matching by stripping a trailing `[bot]` suffix when resolving configured bot logins.
- Fetched PR thread history for followup comments without directives and carried it through task execution.
- Updated followup prompt rendering to include prior conversation context for handle_comment tasks.
- OAuth refresh handling updated the candidate credential and replaced the stored entry at its index.
- OAuth refresh race tests were updated to unregister the test provider during teardown.
When a previous turn's providerPayload snapshot lands in the input array
via the `dt: false` splice, any earlier `function_call` items get
wiped while the matching `function_call_output` from a later toolResult
remains. Locally-rejected tool calls (argument-validation failure, hook
reject, aborted turn before the call streamed) hit the same pattern: a
toolResult lands without a `function_call` ever being persisted.
For non-Azure/non-Copilot providers (`strictResponsesPairing=false`)
the orphan output shipped to the wire, and the Responses API responded
with `400 No tool call found for function call output with call_id …`.
Sessions in that state were unrecoverable until restart.
Add a final-pass guard, `repairOrphanResponsesToolOutputs`, that scans
the assembled input for orphan `function_call_output` /
`custom_tool_call_output` items and folds each into an assistant
`message` text note carrying the call_id and (truncated) output. This
preserves the payload the model needs to recover while keeping the
request grammatically valid. Mirrors the existing behavior in the
`openai-codex` provider's `request-transformer.ts`.
Fixes#1351
- Updated markCredentialSuspect to apply the credential entry returned from refreshCredential and throw when the broker returns a non-OAuth credential.
- Added #applyCredentialEntry to replace or append a credential in the in-memory snapshot for immediate state updates.
- Added a test covering suspect-credential refresh snapshot updates and token refresh invocation.
Raced bash execution against the JavaScript abort signal and timeout so the tool returns even when native shell cleanup does not settle.
Added regression coverage for native cleanup stalls on ESC abort and timeout.
Fixes#1347
The report_finding tool's priority is exposed as a string enum
("P0"-"P3") for ergonomics, but the reviewer agent and every
custom review agent declare priority as `type: number` in their
JTD output schema. The cast at executor.ts:1473 lied about the
runtime shape, so the auto-injected `findings[].priority` flowed
through as strings and every yield with at least one finding was
rejected with `findings.0.priority: expected number, received string`,
forcing the run into the schema_violation exit path.
Added `toReviewFinding(details)` in tools/review.ts that maps the
priority enum to its numeric ordinal via the existing PRIORITY_INFO
table and use it at the boundary in executor.ts. Render paths still
see the original `ReportFindingDetails` shape (string priority)
through normalizeReportFindings, so display formatting is unaffected.
Fixes#1350
- Extended `invalidateCredentialMatching` to accept session-scoped options and clear cached session credentials before blocking the matched credential.
- Updated the OAuth auth-error retry flow to pass `agent.sessionId` through credential invalidation.
- Added a regression test ensuring invalidating a session-sticky OAuth key rotates to the next active credential.
- Moved issue classification updates to run only after branch rename succeeds, preventing partial labeling or DB writes when rename fails.
- Adjusted workspace ownership normalization to chown workspaces to the active slot or, when slotless, to the current euid/egid, then apply shared permissions.
- Added tests for classify_issue rename-failure rollback and chown_workspace normalization in non-slot mode.
- Added `checkCredentials()` with result types/options for per-credential tri-state health checks.
- Added `/v1/credentials/check` endpoint via `handleCredentialsCheck` returning `{ generatedAt, credentials }`.
- Added `omp auth-gateway check` flow with provider grouping, `--json` output, and exit status 1 on failures.
- Added command examples, changelog updates, and tests for expired OAuth refresh, null/missing config, and ordering edge cases.
parse_issue_ref now accepts owner/repo#NN or a github issue url (with or without scheme, www., trailing slash, query, fragment). The dashboard trigger, CLI, and replay endpoint pick this up automatically; UI hints updated to match.
Loaded marketplace lspServers metadata from Claude plugin caches and embedded it for OMP marketplace installs so config-only plugins register without package code.
Fixes#1352
The JTD-to-JSON-Schema converter post-processed convertSchema's
output with normalizeMixedSchemaNode, which walked back into the
emitted JSON Schema looking for nested JTD forms. Inside a
properties block, user-defined property names whose keys happened
to collide with JTD keywords ('ref', 'elements', 'values',
'optionalProperties', 'discriminator') were misclassified as JTD
forms and re-rewritten - corrupting properties like { ref: { type:
'string' } } into { $ref: '#/$defs/[object Object]' } and breaking
the built-in explore agent's output validator with
schema_violation: files.0.ref: must not be present.
convertSchema is already fully recursive and emits pure JSON Schema,
so the post-walk is both unnecessary and unsafe. Drop it.
Fixes#1345
Documented that keybinding remaps live in ~/.omp/agent/keybindings.json and use namespaced action IDs. Added the keybindings reference page to the embedded docs set.
Fixes#1353
Pressing Enter sends `\r` (0x0D), and so does Ctrl+M; the terminal
cannot disambiguate the two in legacy mode (no Kitty keyboard protocol,
no modifyOtherKeys). matches_key was claiming both "enter" and
"ctrl+m" for the bare byte, so binding a command to Ctrl+M also fired
on Enter. Same collision applied for Ctrl+H vs Backspace, Ctrl+I vs Tab,
Ctrl+J vs LF/Enter, Ctrl+[ vs Escape, and the symmetric ctrl+alt+letter
legacy form (ESC + ctrl-char) vs Alt+Enter/Alt+Tab/Alt+Backspace.
The legacy ctrl+<letter>/<symbol> and ctrl+alt+<letter> fast-paths now
skip bytes terminals also send for named keys (0x08 0x09 0x0a 0x0d 0x1b
0x7f). The named key wins; the colliding ctrl+<letter> still matches
when the terminal disambiguates via the Kitty keyboard protocol or
modifyOtherKeys. parseKey already preferred the named key — matchesKey
now agrees.
Fixes#1354
- UAX#11 classifies U+3131..=U+318E as Wide (2 cells), but Ghostty, Terminal.app, and iTerm2 render them as 1 cell.
- Added `char_width_corrected` in Rust to override jamo width, mirroring the existing TS-side correction in `visibleWidth`.
- Replaced `UnicodeWidthStr::width` with per-char corrected sum so the override applies inside combining clusters.
- Added native-layer regression tests to guard cross-layer parity between Rust and TS width calculations.
- Exported `normalizeTools` so `AppendOnlyContext` uses the same tool normalization as the agent loop.
- Added `BuildOptions.intentTracing` to `build()`/`reset()`/`takeSnapshot()` so intent injection is consistent and included in the prefix fingerprint.
- Improved `#computeDigest` to cover tool_calls, tool_call_id, name, and id fields to catch in-place mutations.
- Fixed `#unsubscribeAppendOnly` leak and added no-op guard in `#syncAppendOnlyContext`.
- Replaced first-prompt-as-instructions + extras-as-input[role=system] with a joined "\n\n" string.
- Removes system-role messages from input array, keeping it clean for third-party proxy compatibility.
- Switched DeepSeek validation from chat-completions to GET /v1/models, fixing 401s on accounts without the deepseek-v4-pro preview model.
- Added Bearer-prefix stripping for pasted DeepSeek keys copied from curl snippets.
- Moved Xiaomi AbortSignal.timeout inside the endpoint loop so a SGP regional timeout does not abort the AMS fallback fetch.
- Extracted `mergeDiscoveredModel` so discovered baseUrl takes priority over bundled entry, fixing 401s on Xiaomi tp- token-plan streams.
- User providerOverride.baseUrl still wins over both discovered and bundled values.
- Added regression tests covering all merge priority paths.
- Added Symbol-keyed sidecar on each AgentMessage to memoize estimateTokens, with a cheap content fingerprint to detect in-place mutations.
- Fixed stale cache on same-length replaceMessages, post-hoc error attachment, and branch rebuild edge cases.
- Fixed usage fetch error backoff: stamped fetchedAt on failure so the 5-min TTL also gates retries during outages.
- Extracted computeNonMessageBreakdown as shared helper to prevent drift between status-line and context panel token counts.
- Fixed /plan and /goal history preservation by snapshotting enabled state before handlePlanModeCommand/handleGoalModeCommand executes.
- Previous check read state after the call, missing cases where the handler itself toggled the mode off (e.g., confirmed exit).
- Added tests covering confirm-exit, cancel-exit, and first-activation paths.