[AGE-4112] feat(frontend): Deep-link and share agent sessions - #6252
[AGE-4112] feat(frontend): Deep-link and share agent sessions#6252ardaerzin wants to merge 4 commits into
Conversation
An agent session had no address of its own: the playground read the target from client state, so the URL stayed /apps/<appId>/playground for every session. A link could not name one, and a reload came back on whichever session the last visit left open. Encode it as ?session_id=, owned by @agenta/sessions/link so every surface that builds or reads the link agrees on it. Not ?session=, which the observability drawer already owns app-wide and strips off the playground. The panel adopts the linked session on arrival and keeps the param pointed at the tab in front of you, and the sidebar's session rows now link to the session rather than to its agent.
Reaching for the address bar is the only way to hand someone a session. Add the verb to the shared session menu, so the sessions list, the sidebar rows and the open conversation's kebab all offer it from one definition. The link builder is the host's: an app whose sessions have no URL (mobile opens them by route) passes none and the entry never appears.
Mobile already gives a session a page of its own, so the link existed — it just took selecting the address bar to get at it. Bind the shared verb here too, and the same menu on the sessions list, Home, the agent overview, the sessions pane and the open session's tab all offer it. Both link shapes now live in @agenta/sessions/link: the desktop opens a session as a tab on its agent's playground, this app routes to it.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
💤 Files with no reviewable changes (1)
Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review. 📝 WalkthroughSummary by CodeRabbit
WalkthroughSession deep links now identify sessions in playground URLs. The application adopts linked sessions on load, keeps the active session in the URL, and adds conditional “Copy share link” actions to desktop and mobile session menus. ChangesSession deep-linking and sharing
Estimated code review effort: 4 (Complex) | ~45 minutes Merge Risk: ⚪ Minimal · up to The PR adds session-specific URLs and share-link behavior across desktop and mobile. No actionable merge-blocking risk remains, so it is merge-ready after normal checks and review. Sequence Diagram(s)sequenceDiagram
participant Browser
participant AgentChatPanel
participant pendingSessionOpenAtom
participant history.replaceState
Browser->>AgentChatPanel: Open URL with session_id
AgentChatPanel->>pendingSessionOpenAtom: Adopt linked session
AgentChatPanel->>history.replaceState: Write active session_id
history.replaceState-->>Browser: Update address bar
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
web/packages/agenta-sessions/tests/unit/sessionDeepLink.test.ts (1)
3-10: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTest the public subpath export.
Line 10 imports internal source files. This bypasses the new
@agenta/sessions/linkexport and does not validate the consumer import path.Proposed change
} from "../../src/link/sessionDeepLink" +} from "`@agenta/sessions/link`"As per coding guidelines, workspace packages must “use exported subpath imports for tree-shaking”.
Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro Plus
Run ID: f0686e75-a68c-4a66-951d-ba9fc77d0d5a
📒 Files selected for processing (11)
web/mobile/src/features/sessions/useSessionRowMenu.tsweb/oss/src/components/AgentChatSlice/AgentChatPanel.tsxweb/oss/src/components/AgentChatSlice/hooks/useOpenAgentSession.tsweb/oss/src/components/AgentChatSlice/hooks/useSessionActions.tsxweb/oss/src/components/pages/sessions/SessionsPage.tsxweb/packages/agenta-navigation/src/dynamic/registry.tsweb/packages/agenta-sessions-ui/src/useSessionActions.tsxweb/packages/agenta-sessions/package.jsonweb/packages/agenta-sessions/src/link/index.tsweb/packages/agenta-sessions/src/link/sessionDeepLink.tsweb/packages/agenta-sessions/tests/unit/sessionDeepLink.test.ts
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.
Railway Preview Environment
|
…graph Two problems in the share-link wiring, both from building an absolute URL where a path would do. useSessionActions runs once per SIDEBAR ROW, so subscribing it to urlAtom re-rendered the whole session list on every route change (urlAtom recomputes from the app-state snapshot and returns a fresh object each time). Read it through the store instead, the way the hook already reads its local cache. The menu asks on every render whether a session can be linked, and that answer reached for window.location.origin. Hosts now supply sharePathFor, a pure path, and the hook absolutizes it on the copy itself. shareUrl is the one place that touches window. Both path builders now return "" when they have no base or no target, so a caller that asks before the project resolves gets nothing instead of a path missing its middle, and the menu entry disables itself.
Closes #5990.
Context
Opening an agent session left the URL at
/apps/<appId>/playground. The session you were looking at was held in client state only, so nothing in the address bar named it. You could not send a teammate a link to a session, and a reload came back on whichever session the last visit left open instead of the one you had open.Mobile was better off, since a session already has a page of its own at
/w/<ws>/p/<proj>/sessions/<sessionId>. Getting that link still meant selecting the address bar by hand.Changes
The playground URL names the open session.
useOpenAgentSessionnow navigates to/apps/<appId>/playground?session_id=<id>,AgentChatPaneladopts the linked session on arrival, and the param follows the tab you switch to.The param is
session_idrather than the more obvioussession, because?session=is already taken.oss/src/state/url/session.tsowns it for the observability session drawer and runs on every route change, stripping it from any route that is not/observabilityor/sessions. The playground is one of those routes, so a?session=link there would be deleted from the URL before it could be read. Adding/playgroundto that matcher is not the fix either: it would open the trace drawer on top of the playground.Both link shapes live in one new package subpath,
@agenta/sessions/link, so no surface hand-rolls the string:"Copy share link" in the session menu. Added to the shared verb set in
@agenta/sessions-ui, gated on a host-supplied link builder. Both apps supply one, so the entry shows up everywhere the menu already does: the sessions list, the sidebar rows, the open conversation's kebab, Home, the agent overview and the sessions pane. A host whose sessions have no URL passes nothing and the entry never appears.One difference between the apps. Mobile can link any session, because the route is project-scoped. The desktop can only link at an agent's playground, so a session with no resolved agent (one with no turns yet) has nothing to link at and the entry disables itself.
Sidebar session rows are real links now. They pointed at
/apps/<appId>/playground, with a comment explaining that the playground had no way to read the session from the route. They now carry the session, so middle-click and "copy link address" work. Highlighting still matches on the bare playground path, which required wiringchildMatchPaths. It was declared inSidebarEntityConfigbut never mapped throughdefineSidebarEntity.Tests
tsc --noEmitclean on oss, ee, mobile,@agenta/sessions,@agenta/sessions-ui,@agenta/navigation.What to QA
?session_id=<id>. Reload. You land back on that session, not on the agent's default one.session_idin the address bar follows the active tab./sessions/<id>./observability. The session drawer still opens off?session=and closing it still clears the param.session_idat all. You get one blank tab, not two, and no stray empty session in history.