Skip to content

Add Agent permission approval flow - #826

Merged
ross0x01 merged 55 commits into
mainfrom
codex/agent-permission-selector
Jul 13, 2026
Merged

Add Agent permission approval flow#826
ross0x01 merged 55 commits into
mainfrom
codex/agent-permission-selector

Conversation

@ross0x01

@ross0x01 ross0x01 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a persisted Agent permission selector with Full access as the default and Ask for approval as the gated mode
  • start Trigger Sessions for approval-mode runs and append decisions directly to the durable session input stream
  • persist reusable command and file grants on the current chat so they survive later requests and reloads
  • harden reusable grants with exact parsed argv matching, conservative shell-syntax and wrapper rejection, whitespace-safe normalized file paths, and run-only PTY interaction grants
  • submit custom denial feedback with Enter and keep approval/tool status synchronized while streaming
  • reconcile the computer sidebar during regeneration: show the latest surviving tool output or close it when none remain
  • keep healthy approval waits suspended without consuming active-runtime budget, with bounded token refresh, snapshot-safe cancellation, and stale-session cleanup

Behavior

  • Yes approves one operation
  • Yes, and don't ask again stores the server-derived exact command or file target on that chat; the grant has no time expiry and is capped to the 100 most recent entries
  • an exact approved command is reused after reload and on later requests in the same chat; changed argv, another executable, another chat, dynamic/compound shell syntax, or another file path still requires approval
  • terminal interaction grants remain scoped to the current PTY session and run
  • temporary chats keep grants in memory for the current run only
  • client-provided grant metadata is not trusted for authorization

Testing

  • full Jest suite: 228 suites, 2,289 tests passed
  • pnpm typecheck
  • ESLint for all changed files
  • Prettier check for all changed files
  • git diff --check
  • GitHub test, Trigger.dev preview deployment, and Vercel preview deployment pass

Visual verification

  • verified the deployed Vercel preview with a signed-in account at desktop and 390x844 mobile sizes
  • confirmed the selector uses the chat-input surface and reads How should HackerAI actions be approved?
  • typed custom denial feedback and pressed Enter; the prompt submitted once and the Agent continued with the denial message
  • approved printf approval-persistence-test for the chat, reloaded, and repeated the request; it executed with no second approval prompt
  • opened printf sidebar-latest-test in the computer sidebar, regenerated its response, and confirmed the sidebar immediately fell back to the previous printf approval-persistence-test output

Manual verification

  • Leave an Ask for approval run pending, reload later, and approve it. The same run should continue after its token refresh.
  • Approve an exact reusable command, then retry the same argv and a changed argv. Only the exact command should bypass the prompt.
  • Regenerate a response while its tool output is open. The sidebar should select the previous surviving tool or close if none exists.

Summary by CodeRabbit

  • New Features
    • Added agent permission modes (“Full access” and “Ask for approval”) with a “Default agent permissions” selector in the Agents tab and agent-mode toolbar.
    • Introduced an approval prompt for agent tool actions (including allow/deny and expanded approval options), plus “Awaiting approval” badges and updated chat/sidebar indicators while approval is pending.
  • Bug Fixes
    • Improved reliability for approval-session recovery, cancellation cleanup, and token refresh.
    • Fixed sidebar selection after regeneration.
    • Improved streaming stability for approval updates and reasoning sequence handling.

@vercel

vercel Bot commented Jul 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hackerai Ready Ready Preview, Comment Jul 13, 2026 2:11pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds agent permission modes and approval-gated tool execution. It persists permission preferences, creates approval sessions, transports approval requests, blocks terminal and file actions until decisions, and adds approval prompts, status indicators, token refresh, cleanup, and validation.

Changes

Agent approval and permission flow

Layer / File(s) Summary
Contracts and permission state
types/*, lib/chat/agent-approval-grants.ts, app/contexts/*, lib/utils/client-storage.ts
Defines approval contracts, permission modes, target-grant matching, persisted preferences, and approval-session state.
Permission and approval UI
app/components/AgentPermissionSelector.tsx, app/components/ChatInput/*, app/components/tools/*, app/components/ChatItem.tsx, app/components/SidebarHistory.tsx
Adds permission selectors, approval prompts, approval-requested tool rendering, and awaiting-approval indicators.
Chat and request wiring
app/components/chat.tsx, app/hooks/*, lib/system-prompt.ts, lib/utils/sidebar-utils.ts
Propagates permission mode, restores stored requests, handles approval-session stream data, and reconciles sidebar state.
Persistence and lifecycle
convex/*, lib/db/actions.ts, lib/api/agent-*.ts
Stores approval-session state and bounded grants, starts and resumes approval sessions, and clears state on cancellation and terminal runs.
Transport and Trigger execution
lib/chat/*, trigger/agent-long.ts, lib/ai/tools/*
Adds session input, token refresh, SSE metadata, runtime budgeting, approval queuing, and terminal/file execution gates.
Validation and integration coverage
app/**/__tests__/*, convex/__tests__/*, lib/**/__tests__/*
Tests approval UI, state transitions, grants, token refresh, runtime behavior, stream recovery, schemas, and route contracts.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Chat
  participant TriggerAgentLong
  participant ApprovalSession
  participant Tool
  User->>Chat: select ask_approval mode
  Chat->>TriggerAgentLong: start agent run with approval session
  TriggerAgentLong->>Tool: request approval-gated action
  Tool->>TriggerAgentLong: requestToolApproval(...)
  TriggerAgentLong->>ApprovalSession: wait for approval input
  ApprovalSession-->>Chat: stream approval request
  User->>Chat: approve or deny
  Chat->>ApprovalSession: submit agent-tool-approval input
  ApprovalSession-->>TriggerAgentLong: approval decision
  TriggerAgentLong-->>Tool: continue or return denial
Loading

Possibly related PRs

Suggested labels: codex

Suggested reviewers: rossmanko

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding an agent permission approval flow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/agent-permission-selector

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (5)
app/components/AgentPermissionSelector.tsx (1)

75-101: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider exposing selection state to assistive tech.

The option buttons rely solely on a visual checkmark to indicate the selected mode; screen reader users get no indication of which option is currently selected.

♿ Optional a11y improvement
-          {options.map((option) => {
+          {options.map((option) => {
             const OptionIcon = option.icon;
             const selected = option.id === agentPermissionMode;
             return (
               <button
                 key={option.id}
                 type="button"
+                role="option"
+                aria-selected={selected}
                 onClick={() => {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/components/AgentPermissionSelector.tsx` around lines 75 - 101, The option
buttons in AgentPermissionSelector rely only on the visual checkmark to show the
current mode, so expose the selected state to assistive tech. Update the button
in the options map to reflect selection semantically, such as by adding the
appropriate pressed/selected state and ensuring the control communicates the
active option alongside the existing Check icon. Keep the change localized to
the option rendering logic that uses option.id, selected, and
setAgentPermissionMode.
lib/api/__tests__/agent-long-contracts.test.ts (2)

472-474: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Tighten the approval-token assertion to scope it inside the response object.

The check at Line 474 only verifies approvalSessionPublicAccessToken appears somewhere in resumeSrc, decoupled from the NextResponse.json({...}) match at Lines 472-473. This weakens the contract test versus the prior single regex — a stray reference to approvalSessionPublicAccessToken anywhere else in the file (e.g. in a comment or unrelated object) would still pass, without verifying it's actually part of the JSON response payload asserted by this test.

🔧 Suggested tightening
-    expect(resumeSrc).toMatch(
-      /NextResponse\.json\(\{[\s\S]*runId,[\s\S]*publicAccessToken,[\s\S]*chatId,/,
-    );
-    expect(resumeSrc).toMatch(/approvalSessionPublicAccessToken/);
+    expect(resumeSrc).toMatch(
+      /NextResponse\.json\(\{[\s\S]*runId,[\s\S]*publicAccessToken,[\s\S]*chatId,[\s\S]*approvalSessionPublicAccessToken/,
+    );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/api/__tests__/agent-long-contracts.test.ts` around lines 472 - 474, The
contract test in the agent-long response assertion is too loose because
`approvalSessionPublicAccessToken` is checked separately from the
`NextResponse.json(...)` payload match. Update the test around the `resumeSrc`
expectation so the token is asserted inside the same regex that matches the
response object, using the existing `NextResponse.json`/`resumeSrc` check as the
single source of truth. Keep the assertion scoped to the JSON payload rather
than any standalone occurrence in the file.

559-560: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Same scoping concern as the resume-route assertion.

This assertion, like Lines 472-474, only checks runId/publicAccessToken/chatId are present in the same NextResponse.json call but doesn't tie approvalSessionPublicAccessToken to it for the start route response. If that field is expected here too, consider extending this regex similarly for consistency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/api/__tests__/agent-long-contracts.test.ts` around lines 559 - 560, The
start-route response assertion in the test is too loose because it only scopes
`runId`, `publicAccessToken`, and `chatId` to the same `NextResponse.json` call;
update the regex in `agent-long-contracts.test.ts` near the existing start-route
expectation so it also requires `approvalSessionPublicAccessToken` in the same
response, matching the scoping used by the resume-route assertion and keeping
the coverage consistent.
app/api/agent-long/route.ts (1)

66-76: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Sessions is GA in @trigger.dev/sdk@4.5.0, so the triggerSdk as unknown as { sessions?: ... } feature-detection cast and the runtime "unavailable" throw can likely be replaced with a direct typed import. Optional cleanup; the current defensive approach is functionally fine.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/agent-long/route.ts` around lines 66 - 76, The sessions API is now
GA, so remove the feature-detection cast around triggerSdk.sessions in the route
handler and switch to using the SDK’s direct typed sessions import/API instead.
Update the TriggerSessionsApi/triggerSessions usage in this file so the code no
longer relies on "as unknown as" or an optional sessions property, and delete
the runtime "unavailable" fallback throw if it becomes unnecessary.
lib/ai/tools/index.ts (1)

64-64: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

createTools now has 18 positional parameters.

Pre-existing debt, but this PR adds one more. Consider migrating to a single options object in a future refactor to reduce call-site error risk (easy to swap adjacent same-typed params).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/ai/tools/index.ts` at line 64, createTools is now taking too many
positional parameters, increasing the risk of call-site mistakes in adjacent
same-typed arguments. Update the createTools API in index.ts to accept a single
options object instead of the long positional list, and adjust the function
signature and all internal references accordingly so future call sites can pass
named fields safely.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/api/agent-long/cancel/route.ts`:
- Around line 47-52: The cancel flow in setActiveTriggerRun only clears the
stored approvalSessionId pointer, but it does not close the underlying Trigger
session. Update the cancel handler in the route that processes the run
cancellation to also close the approval session (or enqueue the same cleanup)
alongside clearing triggerRunId and approvalSessionId, using the existing
chatId/runId context so abandoned sessions are not left open.

In `@app/api/agent-long/route.ts`:
- Around line 295-338: The approval-session branch in the agent-long route is
not forwarding the trigger region, so the `sessions.start` path behaves
differently from `tasks.trigger`. Update the `triggerConfig` passed to
`triggerSessions.start` in the `approvalSessionId` flow to include `region`
alongside `basePayload` and `tags`, using the existing `triggerRegion` value so
ask_approval preserves routing.

In `@app/contexts/AgentApprovalContext.tsx`:
- Around line 63-68: The sendTriggerSessionInput call in AgentApprovalContext is
missing an abort/timeout, which can leave ToolApprovalControls stuck in the
sending state indefinitely. Update the approval submission flow around
sendTriggerSessionInput to use a timeout or abort signal, and ensure the
existing session.sessionId, session.publicAccessToken, and approvalId-based
request path still work while failing cleanly if the request hangs.

In `@lib/chat/trigger-browser-realtime.ts`:
- Around line 253-279: `sendTriggerSessionInput` can hang forever because it
only respects a caller-provided signal, and
`AgentApprovalProvider.sendToolApproval` does not pass one. Add an internal
default timeout/abort path inside `sendTriggerSessionInput` (or in the approval
call site) so the POST is automatically canceled after a reasonable duration,
and make sure the existing fetch call uses that timeout signal when no external
signal is supplied.

In `@trigger/agent-long.ts`:
- Around line 217-234: The approval wait in buildAgentToolApprovalRequester
still blocks on session.in.wait without being tied to the AbortSignal, so
approvals can continue after the run is stopped. Update the waiting logic in
buildAgentToolApprovalRequester (and the related approval handling block around
the aborted cleanup path) to race the wait against signal.aborted or otherwise
short-circuit immediately when the signal fires, following the same pattern used
elsewhere in the agent-long transport flow. Make sure the blocked approval
promise is cancelled/rejected on abort so the cleanup branch becomes reachable.
- Around line 279-300: requestToolApproval currently shares one
approvalSessionId across concurrent tool calls, so a decision for one call can
be consumed and discarded by another waiter. Fix this in trigger/agent-long.ts
by serializing approval handling per tool call or giving each invocation its own
isolated session listener in requestToolApproval/open session flow, and ensure
the approvalId/toolCallId matching logic cannot cause a valid approval to be
lost before the intended waiter receives it.

---

Nitpick comments:
In `@app/api/agent-long/route.ts`:
- Around line 66-76: The sessions API is now GA, so remove the feature-detection
cast around triggerSdk.sessions in the route handler and switch to using the
SDK’s direct typed sessions import/API instead. Update the
TriggerSessionsApi/triggerSessions usage in this file so the code no longer
relies on "as unknown as" or an optional sessions property, and delete the
runtime "unavailable" fallback throw if it becomes unnecessary.

In `@app/components/AgentPermissionSelector.tsx`:
- Around line 75-101: The option buttons in AgentPermissionSelector rely only on
the visual checkmark to show the current mode, so expose the selected state to
assistive tech. Update the button in the options map to reflect selection
semantically, such as by adding the appropriate pressed/selected state and
ensuring the control communicates the active option alongside the existing Check
icon. Keep the change localized to the option rendering logic that uses
option.id, selected, and setAgentPermissionMode.

In `@lib/ai/tools/index.ts`:
- Line 64: createTools is now taking too many positional parameters, increasing
the risk of call-site mistakes in adjacent same-typed arguments. Update the
createTools API in index.ts to accept a single options object instead of the
long positional list, and adjust the function signature and all internal
references accordingly so future call sites can pass named fields safely.

In `@lib/api/__tests__/agent-long-contracts.test.ts`:
- Around line 472-474: The contract test in the agent-long response assertion is
too loose because `approvalSessionPublicAccessToken` is checked separately from
the `NextResponse.json(...)` payload match. Update the test around the
`resumeSrc` expectation so the token is asserted inside the same regex that
matches the response object, using the existing `NextResponse.json`/`resumeSrc`
check as the single source of truth. Keep the assertion scoped to the JSON
payload rather than any standalone occurrence in the file.
- Around line 559-560: The start-route response assertion in the test is too
loose because it only scopes `runId`, `publicAccessToken`, and `chatId` to the
same `NextResponse.json` call; update the regex in
`agent-long-contracts.test.ts` near the existing start-route expectation so it
also requires `approvalSessionPublicAccessToken` in the same response, matching
the scoping used by the resume-route assertion and keeping the coverage
consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fc6cdf14-4094-468e-b09a-fe3e3d364054

📥 Commits

Reviewing files that changed from the base of the PR and between 5a49e2f and 57ca797.

📒 Files selected for processing (33)
  • app/api/agent-long/cancel/route.ts
  • app/api/agent-long/resume/route.ts
  • app/api/agent-long/route.ts
  • app/components/AgentPermissionSelector.tsx
  • app/components/AgentsTab.tsx
  • app/components/ChatInput/ChatInputToolbar.tsx
  • app/components/ChatInput/__tests__/ChatInputToolbar.test.tsx
  • app/components/MessagePartHandler.tsx
  • app/components/chat.tsx
  • app/components/tools/FileHandler.tsx
  • app/components/tools/TerminalToolHandler.tsx
  • app/components/tools/ToolApprovalControls.tsx
  • app/contexts/AgentApprovalContext.tsx
  • app/contexts/GlobalState.tsx
  • app/hooks/__tests__/useAutoContinue.test.ts
  • app/hooks/useAutoContinue.ts
  • app/hooks/useChatHandlers.ts
  • app/layout.tsx
  • convex/chats.ts
  • convex/schema.ts
  • lib/ai/tools/file.ts
  • lib/ai/tools/index.ts
  • lib/ai/tools/interact-terminal-session.ts
  • lib/ai/tools/run-terminal-cmd.ts
  • lib/api/__tests__/agent-long-contracts.test.ts
  • lib/chat/agent-long-transport.ts
  • lib/chat/trigger-browser-realtime.ts
  • lib/db/actions.ts
  • lib/utils/accumulate-ui-chunks.ts
  • lib/utils/client-storage.ts
  • trigger/agent-long.ts
  • types/agent.ts
  • types/chat.ts

Comment thread app/api/agent-long/cancel/route.ts Outdated
Comment thread app/api/agent-long/route.ts Outdated
Comment thread app/contexts/AgentApprovalContext.tsx Outdated
Comment thread lib/chat/trigger-browser-realtime.ts
Comment thread trigger/agent-long.ts
Comment thread trigger/agent-long.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/api/agent-long/cancel/route.ts (1)

43-52: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Close the approval session before the early return. runId can be missing while chat.active_agent_approval_session_id is still set, so this branch skips both triggerSessions.close(...) and the approvalSessionId: null update. That leaves the Trigger session open and the chat record pointing at a stale session. Move the cleanup ahead of the !runId return, or run the same cleanup in that branch too.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/agent-long/cancel/route.ts` around lines 43 - 52, The early return in
the cancel route leaves `chat.active_agent_approval_session_id` uncleared and
skips `triggerSessions.close(...)` when `getActiveTriggerRun` returns no
`runId`. Update the cancel flow in the route handler so the approval-session
cleanup runs before returning, or duplicate the same cleanup in the `!runId`
branch, using `approvalSessionId`, `triggerSessions.close`, and the
`approvalSessionId: null` update to ensure the stored session is always closed
and cleared.
🧹 Nitpick comments (2)
app/api/agent-long/cancel/route.ts (2)

2-3: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant dual import from the same module.

triggerSdk (namespace) and runs (named) are both imported from @trigger.dev/sdk; runs.cancel could just be triggerSdk.runs.cancel to avoid two import statements for one module.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/agent-long/cancel/route.ts` around lines 2 - 3, There is a redundant
dual import from `@trigger.dev/sdk` in the cancel route. Remove the separate named
import of runs and use the existing triggerSdk namespace in the route handler,
updating any runs.cancel usage to triggerSdk.runs.cancel so the module is only
imported once.

15-21: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Import sessions directly and share the typed helper
trigger/agent-long.ts, app/api/agent-long/route.ts, and app/api/agent-long/cancel/route.ts all repeat the same triggerSdk as unknown as { sessions?: ... } shim. Import sessions directly, or centralize a typed helper, so the close call stays typed and the SDK shape can’t drift silently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/api/agent-long/cancel/route.ts` around lines 15 - 21, The session client
typing is duplicated across the agent-long route handlers, which makes the SDK
access brittle and prone to drifting. Replace the repeated `triggerSdk as
unknown as { sessions?: ... }` shim in `app/api/agent-long/cancel/route.ts` and
the related `trigger/agent-long.ts` and `app/api/agent-long/route.ts` usage with
a shared typed helper or a direct `sessions` import, and update the `close` call
to use that centralized typed reference so the SDK shape is enforced in one
place.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@app/api/agent-long/cancel/route.ts`:
- Around line 43-52: The early return in the cancel route leaves
`chat.active_agent_approval_session_id` uncleared and skips
`triggerSessions.close(...)` when `getActiveTriggerRun` returns no `runId`.
Update the cancel flow in the route handler so the approval-session cleanup runs
before returning, or duplicate the same cleanup in the `!runId` branch, using
`approvalSessionId`, `triggerSessions.close`, and the `approvalSessionId: null`
update to ensure the stored session is always closed and cleared.

---

Nitpick comments:
In `@app/api/agent-long/cancel/route.ts`:
- Around line 2-3: There is a redundant dual import from `@trigger.dev/sdk` in the
cancel route. Remove the separate named import of runs and use the existing
triggerSdk namespace in the route handler, updating any runs.cancel usage to
triggerSdk.runs.cancel so the module is only imported once.
- Around line 15-21: The session client typing is duplicated across the
agent-long route handlers, which makes the SDK access brittle and prone to
drifting. Replace the repeated `triggerSdk as unknown as { sessions?: ... }`
shim in `app/api/agent-long/cancel/route.ts` and the related
`trigger/agent-long.ts` and `app/api/agent-long/route.ts` usage with a shared
typed helper or a direct `sessions` import, and update the `close` call to use
that centralized typed reference so the SDK shape is enforced in one place.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c606347e-2aca-446a-abc1-a7bc813290f1

📥 Commits

Reviewing files that changed from the base of the PR and between 57ca797 and 717c59e.

📒 Files selected for processing (6)
  • app/api/agent-long/cancel/route.ts
  • app/api/agent-long/route.ts
  • app/components/AgentPermissionSelector.tsx
  • lib/api/__tests__/agent-long-contracts.test.ts
  • lib/chat/trigger-browser-realtime.ts
  • trigger/agent-long.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • lib/chat/trigger-browser-realtime.ts
  • app/api/agent-long/route.ts
  • app/components/AgentPermissionSelector.tsx
  • lib/api/tests/agent-long-contracts.test.ts
  • trigger/agent-long.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/api/agent-trigger-route.ts`:
- Around line 405-446: The approval-session branch in agent-trigger-route.ts is
generating a fresh externalId with randomUUID(), which breaks deduplication
across retries. Update the sessions.start call in the approvalSessionId path to
use the same deterministic turn key used elsewhere in this flow, so the
externalId remains stable and retries reuse the existing session/run. Keep the
change localized around sessions.start and the approvalSessionPublicAccessToken
handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5dd31572-59bc-4062-8038-95690bb96ef8

📥 Commits

Reviewing files that changed from the base of the PR and between 3cb7dd6 and 7c4554d.

📒 Files selected for processing (11)
  • app/components/chat.tsx
  • app/hooks/useChatHandlers.ts
  • convex/chats.ts
  • convex/schema.ts
  • lib/api/__tests__/agent-long-contracts.test.ts
  • lib/api/agent-cancel-route.ts
  • lib/api/agent-resume-route.ts
  • lib/api/agent-trigger-route.ts
  • lib/chat/agent-long-transport.ts
  • lib/db/actions.ts
  • trigger/agent-long.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • convex/schema.ts
  • lib/chat/agent-long-transport.ts
  • trigger/agent-long.ts
  • app/hooks/useChatHandlers.ts
  • convex/chats.ts

Comment thread lib/api/agent-trigger-route.ts
…rmission-selector

# Conflicts:
#	lib/api/agent-trigger-route.ts
#	trigger/agent-long.ts
ross0x01 added 2 commits July 12, 2026 16:28
… into codex/pr-826-agent-permission-selector

# Conflicts:
#	app/hooks/__tests__/useChatHandlers.regenerate-model.test.tsx
@ross0x01
ross0x01 merged commit 1251771 into main Jul 13, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant