Skip to content

feat: Add AI debug session view - #729

Merged
ilyabo merged 17 commits into
mainfrom
add-ai-debug-session-view
Jun 18, 2026
Merged

feat: Add AI debug session view#729
ilyabo merged 17 commits into
mainfrom
add-ai-debug-session-view

Conversation

@ilyabo

@ilyabo ilyabo commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator
image

Summary

  • Add a new AI debug session view for inspecting chat session state and transport details
  • Wire the debug UI into the CLI app and shared AI packages
  • Update schemas, exports, and Python CLI docs to support the new debugging flow
  • Add tests covering the session debug model and CLI launcher behavior

Testing

  • Unit tests added for the session debug model and CLI launcher
  • UI integration testing performed for the assistant panel and debug session view

Summary by CodeRabbit

  • New Features
    • Added an AI session devtools inspector with session summary, timeline (including tool calls and nested agent work), registered tools, run context, and raw session JSON.
    • Added an in-UI devtools toggle with a resizable split view when a session is active.
    • Introduced optional agent snapshot capture for devtools (with size limits).
  • Documentation
    • Documented devtools usage and agent snapshot configuration; updated CodeMirror folding helper notes.
  • Tests
    • Added devtools debug model tests and updated CLI/API config tests for the devtools flag.
  • Chores
    • Added explicit package entrypoints/exports and tightened import restrictions.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@ilyabo, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 15 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 11ce8f5b-b584-4909-8c6d-2e9231050a62

📥 Commits

Reviewing files that changed from the base of the PR and between a2f2538 and 93992ab.

📒 Files selected for processing (3)
  • packages/ai-config/README.md
  • packages/ai-core/__tests__/chatSessionForking.test.ts
  • packages/ai-core/src/chatSessionForking.ts
📝 Walkthrough

Walkthrough

Adds an opt-in AI session devtools system. A new serializable AgentSnapshot type is defined and persisted through AiSlice, chatTransport, and ChatSessionSchema. A sessionDebugModel layer derives structured debug data, consumed by a new ChatSessionDebugView multi-tab UI. The devtools subpath is exposed as @sqlrooms/ai/devtools. The CLI UI and Python server are wired to enable the feature via a flag.

Changes

AI Session Devtools

Layer / File(s) Summary
AgentSnapshot type and AiStateForTransport extension
packages/ai-core/src/types.ts, packages/ai-core/src/index.ts, packages/ai/src/index.ts
Defines the serializable AgentSnapshot type for agent metadata (name, tools, settings, start time) and extends AiStateForTransport with devtools: AiDevtoolsState containing snapshot storage keyed by parentToolCallId, capture/persist decision methods, snapshot write and clear operations.
ChatSessionSchema agentSnapshots field
packages/ai-config/src/schema/ChatSessionSchema.ts
Adds AgentSnapshotSchema Zod definition and the optional persisted agentSnapshots record field to ChatSessionBaseSchema so snapshots are stored alongside each session.
AiSlice snapshot state, rehydration, and enforcement
packages/ai-core/src/AiSlice.ts
Extends AiSliceState.ai with devtools: AiDevtoolsState storage; adds devtools config block to AiSliceOptions (capture/persist toggles, byte limits); rehydrates snapshots from persisted sessions; implements writeAgentSnapshot with JSON cloning and byte-size enforcement via TextEncoder, and clearAgentSnapshots.
Bounded agent snapshot cloning
packages/ai-core/src/devtools/agentSnapshots.ts
Implements cloneBoundedAgentSnapshot helper that JSON-serializes a snapshot, enforces a byte-size limit via TextEncoder, and returns undefined on serialization failure or size violation.
Agent snapshot capture at sub-agent start
packages/ai-core/src/agents/AgentUtils.ts
Extends AgentStreamStore contract with optional shouldCaptureAgentSnapshots() and writeAgentSnapshot() hooks; adds getAgentAvailableTools to extract per-tool metadata (description, hasExecute, hasRenderer, needsApproval); writes initial AgentSnapshot at streamSubAgent start when capture is enabled.
Chat transport snapshot and progress persistence
packages/ai-core/src/chatTransport.ts
Introduces writeAgentDebugStateToSession helper that (1) derives reachable tool call IDs from session.uiMessages, (2) traverses state.ai.agentProgress to add nested agent tool calls, (3) filters and deep-clones agentProgress to reachable IDs, (4) conditionally persists or deletes session.agentSnapshots based on shouldPersistAgentSnapshots(). Updates onChatFinish (both branches) and onChatError to use this unified approach.
Session forking with snapshots
packages/ai-core/src/chatSessionForking.ts
Adds getForkedAgentSnapshots helper to filter snapshots to retained tool-call IDs; threads agentSnapshots into createForkedChatSessionFromMessage alongside existing agentProgress.
CodeMirror foldAllExceptFirstFoldableRange utility
packages/codemirror/src/utils/folding.ts, packages/codemirror/src/index.ts, packages/codemirror/README.md
Adds foldAllExceptFirstFoldableRange to collapse all but the first (root) foldable range, used by DebugJsonBlock for read-only JSON inspection; exported publicly and documented in README.
Session debug model types and query functions
packages/ai-core/src/devtools/sessionDebugModel.ts
Defines eight exported debug types and seven query functions (getSessionDebugSummary, getSessionDebugMessages, getSessionDebugToolCalls, getSessionDebugAgentProgress, getSessionDebugAgentSnapshots, getSessionDebugTimeline, getAvailableToolDebugInfo) that derive UI-friendly debug data from ChatSessionSchema with support for live-override agent progress/snapshots.
Session debug model test suite
packages/ai-core/__tests__/sessionDebugModel.test.ts
Comprehensive test coverage for all debug model functions, including summary counts, message previews with truncation, tool-call progress linking, timeline chronology with agent work attachment, live-override precedence for progress and snapshots, and tool metadata extraction.
DebugJsonBlock and ChatSessionDebugView components
packages/ai-core/src/devtools/DebugJsonBlock.tsx, packages/ai-core/src/devtools/ChatSessionDebugView.tsx
Implements DebugJsonBlock collapsible JSON viewer with copy-to-clipboard and foldAllExceptFirstFoldableRange integration; implements the 779-line ChatSessionDebugView multi-tab inspector (Summary, Tools, Context, Timeline, Raw) with state management, memoization, agent tool-call tree rendering, and timeline filtering by message/tool/agent categories.
Devtools barrel exports and package entry points
packages/ai-core/src/devtools/index.ts, packages/ai-core/package.json, packages/ai/src/devtools.ts, packages/ai/package.json, packages/ai-core/README.md, packages/ai/README.md
Creates barrel modules for devtools exporting ChatSessionDebugView, all debug model functions, and all debug types; adds exports field to both packages for the ./devtools subpath; documents the devtools API in README.
ESLint import rule for subpath exports
packages/preset-eslint/base.js
Introduces restrictedSqlroomsSubpathPatterns constant to allow one-level public subexports (e.g., @sqlrooms/ai/devtools) while blocking src, dist, and deeper arbitrary subpaths; updates both no-restricted-imports rules with this pattern.
Runtime config and store-level devtools enablement
apps/sqlrooms-cli-ui/src/runtimeConfig.ts, apps/sqlrooms-cli-ui/src/store.ts
Adds aiDevtools optional field to RuntimeConfig; derives aiDevtoolsEnabled export in store (enabled via Vite DEV mode or runtimeConfig.aiDevtools); wires capture/persist options into AI slice devtools config.
ChatHeader beforeCreateSessionAction prop
packages/ai-core/src/components/ChatHeader.tsx
Extends ChatHeaderProps with optional beforeCreateSessionAction prop; destructures and renders it after SessionActionsMenu to allow debug button injection.
AssistantPanel debug UI integration
apps/sqlrooms-cli-ui/src/components/AssistantPanel.tsx
Adds debugOpen state and effect to clear it when devtools disabled or no session; lazy-loads ChatSessionDebugView with Suspense boundary and loading fallback; adds AssistantDebugButton toggle; conditionally wires beforeCreateSessionAction (debug button) and debugPanel (wrapped view) into AssistantChatContainer.
AssistantChatContainer resizable split layout
apps/sqlrooms-cli-ui/src/components/AssistantChatContainer.tsx
Extends props with beforeCreateSessionAction and debugPanel optional nodes; centralizes message rendering in messagesPane JSX; renders ResizablePanelGroup split layout when debug active, otherwise single pane; adjusts Chat.Header bottom-margin class based on debugPanel presence.
Python CLI and server runtime config wiring
python/sqlrooms-cli/sqlrooms/cli.py, python/sqlrooms-cli/sqlrooms/web/launcher.py, python/sqlrooms-cli/README.md, python/sqlrooms-cli/tests/*
Adds --ai-devtools CLI flag (with SQLROOMS_AI_DEVTOOLS env var) to main command; propagates through SqlroomsHttpServer constructor and _runtime_config() to /api/config as aiDevtools boolean; documents flag and updates tests to strip ANSI styling and verify the new field.

Sequence Diagram(s)

sequenceDiagram
  participant PythonCLI as sqlrooms CLI
  participant Launcher as SqlroomsHttpServer
  participant Config as /api/config
  participant Store as CLI UI Store
  participant AiSlice as AiSlice
  participant SubAgent as Sub-agent<br/>Execution
  participant ChatTransport as Chat Transport
  participant ChatSessionDebugView as Debug View

  PythonCLI->>Launcher: --ai-devtools flag
  Launcher->>Launcher: ai_devtools = True
  Config<<->>Launcher: aiDevtools: true
  Store->>Store: aiDevtoolsEnabled = true
  Store->>AiSlice: createAiSlice({<br/>devtools: {<br/>captureAgentSnapshots: true,<br/>persistAgentSnapshots: true<br/>}})
  SubAgent->>AiSlice: streamSubAgent starts
  AiSlice->>AiSlice: shouldCaptureAgentSnapshots() → true
  SubAgent->>AiSlice: writeAgentSnapshot(id, {<br/>parentToolCallId,<br/>agentName, availableTools,<br/>startedAt})
  SubAgent-->>AiSlice: agent completes
  ChatTransport->>ChatTransport: onChatFinish/onChatError
  ChatTransport->>AiSlice: state.ai.devtools.agentSnapshots
  ChatTransport->>ChatTransport: writeAgentDebugStateToSession
  ChatTransport-->>ChatSessionSchema: session.agentSnapshots persisted
  Store->>ChatSessionDebugView: open (via AssistantPanel)
  ChatSessionDebugView->>ChatSessionDebugView: sessionDebugModel.<br/>getSessionDebugTimeline
  ChatSessionDebugView-->>Store: render multi-tab UI
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • sqlrooms/sqlrooms#561: Both PRs touch packages/ai-core/src/agents/AgentUtils.ts and the streamSubAgent logic; this PR adds agent snapshot capture at sub-agent start, while that PR addresses abort handling for tool states.
  • sqlrooms/sqlrooms#721: Both PRs modify packages/ai-core/src/chatSessionForking.ts to carry derived agent data into forked sessions — this PR adds agentSnapshots filtering via getForkedAgentSnapshots, while that PR refactored the agentProgress forking helpers.

Suggested reviewers

  • lixun910

Poem

🐇✨ A devtools tab unfolds with care,
Snapshots of agents floating there.
Tool calls in timelines, progress tracked true,
JSON trees fold—the root shines through!
Session debug magic, layer by layer,
The rabbit debugs like a seasoned player. 🔍

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.00% 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 PR title 'feat: Add AI debug session view' directly and clearly summarizes the main change—adding a new debug session view component for inspecting AI chat sessions.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-ai-debug-session-view

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@ilyabo ilyabo changed the title Add AI debug session view feat: Add AI debug session view Jun 18, 2026
@ilyabo
ilyabo marked this pull request as ready for review June 18, 2026 14:39

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 397a6c29e8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +121 to +123
session.agentSnapshots = structuredClone(
state.ai.agentSnapshots,
) as ChatSessionSchema['agentSnapshots'];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Persist only snapshots for this session

When agent snapshot persistence is enabled, this writes the slice-wide state.ai.agentSnapshots map into whichever session just finished. That map is populated globally across sessions, so after running an agent in session A and then completing a chat in session B, B's persisted agentSnapshots will include A's debug metadata even though B has no matching tool calls; this pollutes saved workspace state and can expose another session's tool names/descriptions in the raw debug view. Filter snapshots to toolCallIds present in session.uiMessages before assigning them here.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 9

Caution

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

⚠️ Outside diff range comments (1)
packages/ai-core/src/components/ChatHeader.tsx (1)

25-31: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add TSDoc for exported ChatHeader.

Line 25 exports a package API but there’s no TSDoc in the touched segment. Please document the component and the new beforeCreateSessionAction prop contract.

As per coding guidelines, "packages/**/*.{ts,tsx}: Add tsdoc to exported types and functions".

Suggested patch
+/**
+ * Header controls for chat sessions.
+ *
+ * `@param` onHistoryClick Opens session history.
+ * `@param` onCreateSession Optional override for creating a session.
+ * `@param` createSessionDisabled Disables create action.
+ * `@param` historyIsRunning Shows running indicator for background sessions.
+ * `@param` beforeCreateSessionAction Optional custom action rendered before the create-session button.
+ * `@param` className Optional container className.
+ */
 export const ChatHeader: React.FC<ChatHeaderProps> = ({
🤖 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 `@packages/ai-core/src/components/ChatHeader.tsx` around lines 25 - 31, The
exported ChatHeader component is missing TSDoc documentation as required by the
coding guidelines. Add a TSDoc comment block above the ChatHeader component
export that documents the component's purpose and functionality. Additionally,
ensure the ChatHeaderProps interface (which defines the props including the new
beforeCreateSessionAction property) has proper TSDoc documentation that clearly
describes the contract for each prop, particularly the beforeCreateSessionAction
prop that handles the action to be executed before creating a new session.

Source: Coding guidelines

🧹 Nitpick comments (2)
packages/codemirror/README.md (1)

320-321: ⚡ Quick win

Show concrete usage for the folding helper in the example.

The snippet imports foldAllExceptFirstFoldableRange but doesn’t call it. Either remove the import or add a minimal onMount usage so readers can apply it directly.

Also applies to: 346-350

🤖 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 `@packages/codemirror/README.md` around lines 320 - 321, The README.md example
imports the helper function foldAllExceptFirstFoldableRange but never
demonstrates its actual usage in the code example, making it unclear how readers
should apply it. Either remove the unused import of
foldAllExceptFirstFoldableRange from the import statement at the top of the
example, or add a concrete call to foldAllExceptFirstFoldableRange inside the
onMount hook to show how it should be invoked with the editor instance. Ensure
the example demonstrates practical usage so readers can directly apply the
pattern.
packages/codemirror/src/utils/folding.ts (1)

10-37: ⚡ Quick win

Add a focused test for the “skip first foldable range” contract.

This utility changes folding semantics; a small test asserting “root stays open, nested ranges fold” would prevent regressions.

As per coding guidelines, **/*.test.{ts,tsx,js,jsx}: Add or update tests when changing behavior or public API, when practical.

🤖 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 `@packages/codemirror/src/utils/folding.ts` around lines 10 - 37, Add a focused
test file (following the naming convention *.test.ts) for the
foldAllExceptFirstFoldableRange function to prevent regressions. The test should
verify that the function correctly implements its contract: the first foldable
range in the document remains unfolded while all subsequent nested or sibling
foldable ranges are folded. Create a test that sets up an EditorView with
multiple foldable ranges at different nesting levels and assert that after
calling foldAllExceptFirstFoldableRange, only the first range is left open and
all others are folded.

Source: Coding guidelines

🤖 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 `@packages/ai-config/src/schema/ChatSessionSchema.ts`:
- Around line 166-167: The agentSnapshots field in ChatSessionSchema uses
z.unknown() for its values, which allows malformed data that can crash
downstream code expecting structured AgentSnapshot objects. Replace the
z.unknown() schema validator in the agentSnapshots field definition with a
proper schema that validates the AgentSnapshot structure, ensuring that required
properties like availableTools are properly typed as arrays instead of accepting
arbitrary unknown values.

In `@packages/ai-core/src/AiSlice.ts`:
- Around line 533-535: The length check for the serialized snapshot is using
`serialized.length` which counts UTF-16 code units, not actual bytes, allowing
multibyte characters to bypass the byte limit. Replace the length comparison in
the condition that checks against `devtoolsOptions.maxAgentSnapshotBytes` to use
`Buffer.byteLength(serialized, 'utf8')` instead of `serialized.length` to
properly enforce the byte limit.

In `@packages/ai-core/src/chatSessionForking.ts`:
- Around line 82-101: The exported function getForkedAgentSnapshots is missing a
TSDoc comment block required by coding guidelines for exported functions in the
packages directory. Add a TSDoc comment block above the function definition that
includes a brief description of what the function does, `@param` tags documenting
the sourceSession and targetMessages parameters, and a `@returns` tag documenting
the return value. This will ensure the exported API is properly documented for
consistency with other exported types and functions in the package.

In `@packages/ai-core/src/chatTransport.ts`:
- Around line 112-127: The function writeAgentDebugStateToSession is currently
copying the entire global agentProgress and agentSnapshots maps from state.ai
into the session, which causes unrelated debug metadata to leak between
sessions. Modify the function to filter and persist only the debug state entries
that are scoped to the current session, rather than copying all global entries.
This requires identifying which entries in agentProgress and agentSnapshots
belong to the specific session being updated, and only cloning those relevant
entries into session.agentProgress and session.agentSnapshots respectively.

In `@packages/ai-core/src/devtools/ChatSessionDebugView.tsx`:
- Around line 27-38: Add TSDoc documentation to the exported
`ChatSessionDebugViewProps` type definition. Include a brief description
explaining the purpose of this props type for the debug view component above the
type export statement. Additionally, add similar TSDoc documentation to the
`ChatSessionDebugView` component export (referenced in the also applies to
section at lines 372-377) to describe what the component does and how it should
be used. Follow the existing TSDoc pattern already used in the individual
property comments within the type definition.
- Around line 679-683: The timing calculation in ChatSessionDebugView.tsx
subtracts startedAt from completedAt without verifying that both values exist.
Currently, the condition only checks if completedAt is present, but startedAt
could be undefined, resulting in NaN. Update the ternary operator to ensure both
toolTimings[toolCall.toolCallId]?.completedAt and
toolTimings[toolCall.toolCallId]?.startedAt exist before performing the
subtraction. If either value is missing, display 'n/a' instead.

In `@packages/ai-core/src/devtools/DebugJsonBlock.tsx`:
- Around line 16-22: Add TSDoc comments to document the exported
`DebugJsonBlockProps` type and the `DebugJsonBlock` component. For the
`DebugJsonBlockProps` type definition, add a JSDoc comment block above the type
that describes its purpose and briefly documents each property (title, value,
defaultOpen, className, editorClassName) to explain their semantics. For the
`DebugJsonBlock` component function (lines 33-79), add a JSDoc comment block
above the function declaration that explains its intended usage, describes what
it does, and documents any relevant behavior. Ensure all TSDoc comments follow
the project's coding guidelines for exported APIs.

In `@packages/ai-core/src/devtools/sessionDebugModel.ts`:
- Around line 10-26: Add TSDoc documentation comments above the
SessionDebugSummary exported type and all other exported types and functions in
the ranges 28-95 and 192-407 of this file. Each export should have a clear,
concise JSDoc/TSDoc comment block (/** */) that describes its purpose and usage
intent so that consumers get proper IntelliSense support and understand the API
surface of this debug-model module.

In `@packages/preset-eslint/base.js`:
- Around line 7-14: The pattern `@sqlrooms/*/*/**` in the
restrictedSqlroomsSubpathPatterns array is too broad and incorrectly blocks
valid one-level subexports like `@sqlrooms/ai/devtools`. Replace this pattern
with patterns that only block imports with 2 or more levels of nesting depth,
allowing single-level subexports. Apply the same fix to the equivalent patterns
appearing in the other restricted path arrays in this file (also present in the
sections around lines 39-42 and 51-54).

---

Outside diff comments:
In `@packages/ai-core/src/components/ChatHeader.tsx`:
- Around line 25-31: The exported ChatHeader component is missing TSDoc
documentation as required by the coding guidelines. Add a TSDoc comment block
above the ChatHeader component export that documents the component's purpose and
functionality. Additionally, ensure the ChatHeaderProps interface (which defines
the props including the new beforeCreateSessionAction property) has proper TSDoc
documentation that clearly describes the contract for each prop, particularly
the beforeCreateSessionAction prop that handles the action to be executed before
creating a new session.

---

Nitpick comments:
In `@packages/codemirror/README.md`:
- Around line 320-321: The README.md example imports the helper function
foldAllExceptFirstFoldableRange but never demonstrates its actual usage in the
code example, making it unclear how readers should apply it. Either remove the
unused import of foldAllExceptFirstFoldableRange from the import statement at
the top of the example, or add a concrete call to
foldAllExceptFirstFoldableRange inside the onMount hook to show how it should be
invoked with the editor instance. Ensure the example demonstrates practical
usage so readers can directly apply the pattern.

In `@packages/codemirror/src/utils/folding.ts`:
- Around line 10-37: Add a focused test file (following the naming convention
*.test.ts) for the foldAllExceptFirstFoldableRange function to prevent
regressions. The test should verify that the function correctly implements its
contract: the first foldable range in the document remains unfolded while all
subsequent nested or sibling foldable ranges are folded. Create a test that sets
up an EditorView with multiple foldable ranges at different nesting levels and
assert that after calling foldAllExceptFirstFoldableRange, only the first range
is left open and all others are folded.
🪄 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

Run ID: 70fb9e12-613e-4dc1-a503-9c9c82fe3d32

📥 Commits

Reviewing files that changed from the base of the PR and between dcb1a51 and 397a6c2.

📒 Files selected for processing (31)
  • apps/sqlrooms-cli-ui/src/components/AssistantChatContainer.tsx
  • apps/sqlrooms-cli-ui/src/components/AssistantPanel.tsx
  • apps/sqlrooms-cli-ui/src/runtimeConfig.ts
  • apps/sqlrooms-cli-ui/src/store.ts
  • packages/ai-config/src/schema/ChatSessionSchema.ts
  • packages/ai-core/__tests__/sessionDebugModel.test.ts
  • packages/ai-core/package.json
  • packages/ai-core/src/AiSlice.ts
  • packages/ai-core/src/agents/AgentUtils.ts
  • packages/ai-core/src/chatSessionForking.ts
  • packages/ai-core/src/chatTransport.ts
  • packages/ai-core/src/components/ChatHeader.tsx
  • packages/ai-core/src/devtools/ChatSessionDebugView.tsx
  • packages/ai-core/src/devtools/DebugJsonBlock.tsx
  • packages/ai-core/src/devtools/index.ts
  • packages/ai-core/src/devtools/sessionDebugModel.ts
  • packages/ai-core/src/index.ts
  • packages/ai-core/src/types.ts
  • packages/ai/README.md
  • packages/ai/package.json
  • packages/ai/src/devtools.ts
  • packages/ai/src/index.ts
  • packages/codemirror/README.md
  • packages/codemirror/src/index.ts
  • packages/codemirror/src/utils/folding.ts
  • packages/preset-eslint/base.js
  • python/sqlrooms-cli/README.md
  • python/sqlrooms-cli/sqlrooms/cli.py
  • python/sqlrooms-cli/sqlrooms/web/launcher.py
  • python/sqlrooms-cli/tests/test_cli.py
  • python/sqlrooms-cli/tests/test_launcher.py

Comment thread packages/ai-config/src/schema/ChatSessionSchema.ts Outdated
Comment thread packages/ai-core/src/AiSlice.ts Outdated
Comment thread packages/ai-core/src/chatSessionForking.ts
Comment thread packages/ai-core/src/chatTransport.ts
Comment thread packages/ai-core/src/devtools/ChatSessionDebugView.tsx
Comment thread packages/ai-core/src/devtools/ChatSessionDebugView.tsx Outdated
Comment thread packages/ai-core/src/devtools/DebugJsonBlock.tsx
Comment thread packages/ai-core/src/devtools/sessionDebugModel.ts
Comment thread packages/preset-eslint/base.js

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89017ed31a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +18 to +22
"./devtools": {
"types": "./dist/devtools/index.d.ts",
"import": "./dist/devtools/index.js",
"default": "./dist/devtools/index.js"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Document the public ai-core devtools API

The root AGENTS.md says that when a public API is added or changed in an @sqlrooms/* package, that package's README.md must be updated. This new @sqlrooms/ai-core/devtools subexport and the related createAiSlice({ devtools }) snapshot controls are public ai-core APIs, but packages/ai-core/README.md still omits them from its setup/useful-exports docs, so lower-level @sqlrooms/ai-core consumers have no package-local documentation for enabling or importing the new debug surface.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
packages/ai-core/src/AiSlice.ts (1)

332-337: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Apply the snapshot size gate during rehydration too.

writeAgentSnapshot enforces maxAgentSnapshotBytes, but persisted session.agentSnapshots are copied straight into live devtools state here. A stale/imported config with an oversized snapshot can still populate ai.devtools.agentSnapshots and freeze the debug view despite the configured cap.

🛡️ Proposed fix
+    function cloneAgentSnapshotWithinLimit(
+      snapshot: AgentSnapshot,
+    ): AgentSnapshot | undefined {
+      try {
+        const serialized = JSON.stringify(snapshot);
+        const byteLength = new TextEncoder().encode(serialized).byteLength;
+        if (byteLength > devtoolsOptions.maxAgentSnapshotBytes) {
+          return undefined;
+        }
+        return JSON.parse(serialized) as AgentSnapshot;
+      } catch {
+        return undefined;
+      }
+    }
+
     function rehydrateFromSessions(config: AiSliceConfig) {
       const timings: Record<string, ToolTimingEntry> = {};
       const progress: Record<string, AgentToolCall[]> = {};
       const snapshots: Record<string, AgentSnapshot> = {};
@@
         if (session.agentSnapshots) {
-          Object.assign(
-            snapshots,
-            session.agentSnapshots as Record<string, AgentSnapshot>,
-          );
+          for (const [parentToolCallId, snapshot] of Object.entries(
+            session.agentSnapshots as Record<string, AgentSnapshot>,
+          )) {
+            const clonedSnapshot = cloneAgentSnapshotWithinLimit(snapshot);
+            if (clonedSnapshot) {
+              snapshots[parentToolCallId] = clonedSnapshot;
+            }
+          }
         }

Then reuse the helper in writeAgentSnapshot:

           writeAgentSnapshot: (
             parentToolCallId: string,
             snapshot: AgentSnapshot,
           ) => {
             if (!devtoolsOptions.captureAgentSnapshots) return;
-            let clonedSnapshot: AgentSnapshot;
-            try {
-              const serialized = JSON.stringify(snapshot);
-              const byteLength = new TextEncoder().encode(
-                serialized,
-              ).byteLength;
-              if (byteLength > devtoolsOptions.maxAgentSnapshotBytes) {
-                return;
-              }
-              clonedSnapshot = JSON.parse(serialized) as AgentSnapshot;
-            } catch {
-              return;
-            }
+            const clonedSnapshot = cloneAgentSnapshotWithinLimit(snapshot);
+            if (!clonedSnapshot) return;
 
             set((state) =>
🤖 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 `@packages/ai-core/src/AiSlice.ts` around lines 332 - 337, The rehydration
logic in the session.agentSnapshots block is copying persisted snapshots
directly into live devtools state without enforcing the maxAgentSnapshotBytes
size limit that is already validated in writeAgentSnapshot. Extract the snapshot
size validation logic from writeAgentSnapshot into a reusable helper function,
then apply that helper to filter or validate each snapshot in
session.agentSnapshots before they are merged into the snapshots object via
Object.assign. This ensures that oversized snapshots from stale or imported
configs cannot populate the live devtools state and cause performance issues.
🤖 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 `@packages/ai-core/src/AiSlice.ts`:
- Around line 332-337: The rehydration logic in the session.agentSnapshots block
is copying persisted snapshots directly into live devtools state without
enforcing the maxAgentSnapshotBytes size limit that is already validated in
writeAgentSnapshot. Extract the snapshot size validation logic from
writeAgentSnapshot into a reusable helper function, then apply that helper to
filter or validate each snapshot in session.agentSnapshots before they are
merged into the snapshots object via Object.assign. This ensures that oversized
snapshots from stale or imported configs cannot populate the live devtools state
and cause performance issues.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9bbf4333-2358-484c-a07d-88757e237c7f

📥 Commits

Reviewing files that changed from the base of the PR and between 89017ed and 7a10154.

📒 Files selected for processing (6)
  • packages/ai-core/README.md
  • packages/ai-core/src/AiSlice.ts
  • packages/ai-core/src/agents/AgentUtils.ts
  • packages/ai-core/src/chatTransport.ts
  • packages/ai-core/src/devtools/ChatSessionDebugView.tsx
  • packages/ai-core/src/types.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/ai-core/README.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/ai-core/src/agents/AgentUtils.ts
  • packages/ai-core/src/chatTransport.ts
  • packages/ai-core/src/devtools/ChatSessionDebugView.tsx

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a2f2538049

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +190 to +191
/** Optional persisted agent devtools snapshots, keyed by parent toolCallId */
agentSnapshots: z.record(z.string(), AgentSnapshotSchema).optional(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Document the ai-config snapshot field

The root AGENTS.md says that public API changes in @sqlrooms/* packages must update that package's README.md. This adds agentSnapshots to the exported @sqlrooms/ai-config ChatSessionSchema, but packages/ai-config/README.md still only documents the older session shape, so consumers of the schema do not get package-local docs for the new persisted devtools field.

Useful? React with 👍 / 👎.

Comment on lines +98 to +101
const copiedToolCallIds = getToolCallIdsFromMessages(targetMessages);
const agentSnapshots = Object.fromEntries(
Object.entries(sourceSession.agentSnapshots).filter(([toolCallId]) =>
copiedToolCallIds.has(toolCallId),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve nested agent snapshots when forking

When a retained top-level agent call has nested sub-agent calls, writeAgentDebugStateToSession persists snapshots for all reachable toolCallIds, but this fork helper recomputes IDs only from top-level targetMessages parts. The fork can still keep the parent agentProgress tree, so the nested calls render, but their matching agentSnapshots are dropped and the debug view loses the child agent tool metadata after forking such a session; include reachable IDs from sourceSession.agentProgress before filtering snapshots.

Useful? React with 👍 / 👎.

@ilyabo
ilyabo merged commit ed64d40 into main Jun 18, 2026
4 checks passed
@ilyabo
ilyabo deleted the add-ai-debug-session-view branch June 18, 2026 16:56
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