Repository navigation
[pull] main from danny-avila:main - #251
Merged
Merged
Conversation
#15691 paired every read of `AgentCapabilities.execute_code` / `file_search` with its role grant, and skipped `execute_code` from the resend-file priming when `RUN_CODE` was denied. It left the `file_search` half: the grant was not available inside `initializeAgent`, so a role denied `FILE_SEARCH` still had its prior-turn search files re-hydrated on every resend. Priming is not free. The files are fetched, `updateFilesUsage` bumps their counters, and `primeResources` builds `tool_resources.file_search` — all for a tool the loader is about to drop. A deployment with the capability off paid the same cost. `InitializeAgentParams.fileSearchAvailable` carries the capability AND the grant, resolved from the same single `resolveToolRoleGrants` read that already answers `codeEnvAvailable`, so pairing the second flag costs no extra role lookup. Every initializer that resolves grants forwards it: the chat path and its handoff, added-convo and discovery hand-offs, both API routes, and the OpenAI-compatible embedder route. Absent leaves priming unconditional, so an embedder that resolves no grant keeps its current behavior. The loop that selected the resend tool resources becomes `resolveResendToolResources`, which makes both halves of the gate testable rather than reachable only through a full agent initialization. The memory agent is untouched: it passes no `conversationId`, so it never reaches this priming. Co-authored-by: Claude <noreply@anthropic.com>
* fix: Bound Code Environment Status Polling * refactor: Move Code Limiters Into API Package * fix: enforce status polling boundaries
* fix: Require Platform Grants for Code Workers * fix: Separate Platform Scope From Tenant Identity
* feat: Add conversation code approval modes * refactor: Reuse shared code approval types * fix: Scope approval selector to stateful agents * fix: harden code approval state propagation * fix: fail closed during approval discovery * test: cover approval mode acceptance * test: use visible approval mode label * test: drive approval menu by keyboard * test: expose accept edits in BYOM acceptance * fix: read approval mode atomically on send * fix: align code modes with endpoint policy * fix: initialize code limiters at startup
…ck Icon (#15706) * 🕓 style: Move the Queued-Message Hint Into a Hover Tooltip on the Clock Icon "Sends when this response finishes" rendered as a caption row under the queued chips for as long as a run was pending, costing composer height for a single reassurance. The clock icon of each queued row now carries that sentence as a hover tooltip and as its accessible name, and the caption row is gone. Nothing else about the row changes: warning states keep their triangle, and the hint disappears with the run as before. * ⌨️ fix: Give the Queued-Hint Clock an Explicit Tab Stop and Focus Ring The tooltip anchor was already focusable through Ariakit's Focusable default, and opens on focus-visible, but nothing said so and no ring showed where focus was. Make the tab stop explicit, add the same focus-visible ring the row's buttons use, and prove the keyboard path with a test. The hover test now allows for Ariakit's show timer on a loaded CI shard, which is what failed the first run. Codex round 1 (P2) on #15706. * 🧪 test: Move the Pointer Between Coordinates Before Expecting the Queued Hint Tooltip Ariakit's hover detector treats a pointer as moving only when consecutive mousemove events differ in screen coordinates; its NODE_ENV=test shortcut does not apply under the CI runner's NODE_ENV, which is why the hover test passed locally and failed in the shard. Two moves at distinct coordinates make the test environment-independent; the keyboard test was already deterministic.
* fix: Clean Up MCP OAuth Teardown State * fix: Harden OAuth Teardown Boundaries * fix: harden MCP OAuth teardown races * fix: avoid flow cache dependency cycle * fix: bind OAuth teardown to credential generations * test: cover active OAuth server fixtures * style: sort OAuth cleanup imports * fix: discard mismatched OAuth token snapshots * fix: fence OAuth teardown across callback races * test: align OAuth callback fixtures with server fencing * test: complete OAuth callback server fixtures * fix: version OAuth flow settlement * fix: fence OAuth teardown snapshots * test: align OAuth teardown fixtures * test: complete OAuth snapshot fixtures * fix: snapshot OAuth deletion lifecycle * test: bind OAuth revocation snapshots * test: assert per-record OAuth fence * fix: harden MCP OAuth teardown consistency * test: expect snapshotted OAuth readers
* fix: fence concurrent MCP OAuth teardown * fix: hold MCP refresh teardown fences * fix: suppress OAuth fallback during teardown * fix: retire MCP connections before OAuth cleanup * fix: annotate refresh teardown tenant scope * fix: fence OAuth teardown across replicas * test: provide OAuth teardown leases in controller mocks * fix: fail safely around OAuth teardown leases * fix: complete OAuth lease lifecycle handling * fix: preserve OAuth single-flight admission
* fix: recover direct OpenID MCP bearer sessions * fix: harden direct bearer recovery lifecycle * fix: close direct bearer lifecycle races * test: align direct bearer checks with current dev * fix: unify direct bearer recovery budget * fix: infer direct bearer recovery from placeholder * fix: preserve bearer precedence and recovery budget * fix: propagate bearer recovery across joiners * fix: preserve direct bearer fallback without session provider * fix: close direct bearer recovery race windows * chore: sort bearer recovery test imports * fix: align bearer recovery with OAuth cleanup lifecycle * fix: fence request-scoped MCP creation during config mutations * fix: retain suspended MCP catalog authentication outcomes * fix: cancel MCP bearer recovery and reuse refreshed credentials * fix: close MCP bearer recovery lifecycle boundaries * fix: preserve ordered catalog authentication rejection * fix: isolate bearer recovery across request and transport boundaries * fix: preserve shared recovery ownership and credential precedence * fix: wait for recovery borrowers and validated OpenID publication * fix: observe the validated browser publication flight * fix: cancel abandoned OpenID publication followers * fix: fence refresh grant admission after lease acquisition
* 🗜️ feat: Manual Context Compaction as a Summarize-Only Turn Adds a user-triggered "Compact context" action that summarizes the active branch on demand. The compaction is an ordinary agent turn: the client submits it through the normal chat pipeline with `compact: true`, the controller hangs it off the branch's leaf instead of creating a user message, and the agent client runs the graph summarize-only (the SDK's new `summarizeOnly` input), so the summary streams into the response placeholder under the leaf exactly like the automatic detour's and is persisted as the boundary every later turn starts from. Nothing new is needed for job registration, billing, abort, persistence, or the usage snapshot: the run emits the same summary step and post-summary context snapshot the automatic path already emits, and the response message carries the summary part plus the `summaryUsedTokens` baseline the gauge reads. The controller validates the request (existing conversation, a real leaf, summarization enabled, no edit/regenerate/continue combination) and answers 409 when the leaf is already a bare summary. Client-side the submission borrows the regenerate shape — no new user bubble, the placeholder parents onto the leaf — while the wire payload drops `isRegenerate` so the server never treats it as a regenerated user turn. The action sits in the context-usage popover, gated by the same `summarization.enabled` switch as the automatic detour. * 🗜️ fix: Localize a Compaction That Cannot Run A compaction the graph could not attempt (summarization disabled, the instructions already exceeding the budget, or an explicit recency window covering the whole conversation) rejects with the SDK's `ManualSummarizationSkippedError`, which rendered as the generic admin error. It now maps to a typed `compaction_skipped` payload with the reason, and a run that ends with neither a summary nor a recorded error fails as `compaction_failed`; the Error component localizes both. A run that already recorded why it stopped keeps that error part instead of failing twice. * 🗜️ fix: Anchor a Compaction on the Leaf Everywhere It Is Read Review round 1. - The client sent the leaf's parent as `parentMessageId`, which the controller treats as the anchor, so the summary would have skipped the latest reply and landed as its sibling. The leaf's own id is now both the placeholder's parent and the server-side anchor. - A compaction has no user message of its own, and every consumer of the job's user-message slot now knows it: the error path parents its row on the loaded anchor and never upserts the leaf, and the job records the regenerate shape so a reconnecting client rebuilds the turn under the leaf instead of recreating it as a user message. - The controller no longer reads the anchor before the branch is loaded; `BaseClient` validates it against the history it loads anyway and answers 404 for a missing leaf or a typed `nothing_to_summarize` for a finished compaction. That predicate is shared through the data provider and ignores a summary still streaming or one that failed, so an interrupted compaction can be retried. - A compaction never consumes files staged in the composer, the action is shown only when the server advertises `compactionEnabled`, and the in-flight marker is feature-local Jotai state rather than a read of the Recoil submission store. * 🗜️ fix: Keep a Compaction Turn to Its Summary Review round 2, plus the class it belongs to. A compaction submits no user turn, so nothing that keys off one may run: the memory pass no longer runs over the history (it would have spent a model call and could repeat memory writes), and skill primes are no longer injected into the transcript the run is about to summarize. The client's in-flight marker is also reconciled on mount: a compaction that finished while the view was away left the marker set, and the next ordinary turn in that conversation would have shown as compacting. * 🧹 chore: Sort Imports in the Compaction Hook Spec * 🔧 chore: Update @librechat/agents dependency to version 3.8.1 in package-lock.json and package.json files
* 🧐 feat: Review Pending Tool Actions in the Composer (#15714) * feat: add interactive approval review to the composer * fix: Harden interactive approval boundaries * fix: Bound every approval display label * test: exercise composer approval review in BYOM acceptance * fix: reveal all directional approval controls * fix: canonicalize code approval targets across replicas * style: sort resumable approval test imports * test: Exercise Coexisting Approval Surfaces * Revert "🧐 feat: Review Pending Tool Actions in the Composer (#15714)" This reverts commit 5f79ded. * Reapply "🧐 feat: Review Pending Tool Actions in the Composer (#15714)" This reverts commit 52c7d9c. * chore: bump agents sdk to v3.8.2
* 🔒 fix: Isolate Checkpoint Cleanup by Generation Ownership * 🔒 fix: Harden Checkpoint Cleanup Ownership * 🔒 fix: Retain Checkpoint Cleanup Evidence * 🔒 fix: Persist checkpoint cleanup receipts * 🔒 fix: Bound checkpoint cleanup receipt lifecycle * fix: Bind checkpoint cleanup to durable ownership and deletion intent * fix: Bind event actor checkpoint storage to authenticated owners * fix: Resolve exact actor checkpoint ownership before lifecycle cleanup * fix: Preserve actor storage compatibility with durable ownership and prune work * fix: Defer checkpoint erasure until conversation deletion commits * fix: Reclaim orphan actor ownership and batch deletion lookups * fix: bind actor checkpoint ownership to payload rows * fix: isolate actor readers and await account persistence * fix: gate owned suspensions and drain complete account state * fix: unify checkpoint deletion lifecycle and storage authority * fix: Replay checkpoint deletion from durable owner state * fix: retain checkpoint cleanup identity before topology loss * fix: complete checkpoint catalog capture and retirement lifecycle
* feat: Enable Full Access for BYOM Coding 🛫 * test: Preserve endpoint policy under Full Access * fix: Gate Full Access on expected root agent metadata
The retry navigation reserves its width in the message footer whether or not hover has revealed it, so a response with siblings rendered the elapsed reading indented past the column the streaming dot had just vacated. Rendering the reading ahead of the navigation in all three row renderers puts it back on that column start, in the streaming footer and in the flat thread alike.
The code approval selector was the only chat control built on the shadcn `DropdownMenu` primitives — a borderless ghost button and default radio dots beside a row of bordered composer pills, with per-item text styled by hand. - Rebuild the control on the composer's own menu language (Ariakit menu + `TooltipAnchor`), matching `MCPSelect`: a pill trigger with a rotating chevron, and a `bg-presentation` popover whose options carry an icon, a description and a check on the selected row, as the model and MCP menus already do. - Extract the pill appearance into `composerControlClasses()` beside `composerSurfaceClasses()` in `@librechat/client`, and consume it from `CheckboxButton` and `MCPSelect`, which each carried their own copy of the same border/radius/height/elevation decision. - Replace the raised hand with a pair that reads as one question — a document with a question mark for "ask", a document with a pen for "accept edits" — leaving the shield to the pending review button that sits in the same row. Roles, keyboard behaviour and the stored `codeApprovalMode` are unchanged: the trigger keeps its `code-approval-mode` test id and `aria-expanded`, and the options stay `menuitemradio`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )