Skip to content

feat(desktop): resolve @session links to titles you can click - #71162

Merged
OutThisLife merged 6 commits into
mainfrom
bb/session-link-titles
Jul 25, 2026
Merged

feat(desktop): resolve @session links to titles you can click#71162
OutThisLife merged 6 commits into
mainfrom
bb/session-link-titles

Conversation

@OutThisLife

@OutThisLife OutThisLife commented Jul 25, 2026

Copy link
Copy Markdown
Collaborator

Session references now read as the conversation they point at, and open it. A @session:<profile>/<id> reference resolves to the session's title in both directions — a session the user drags into the composer, and a session an agent links to in its reply — and clicking one opens that session as a tab, the way its sidebar row does.

The two surfaces render differently on purpose. In the user's own message the reference is a chip, matching the file and folder chips the composer already inserts. In agent prose it is an ordinary inline link with a small funnel icon leading the title, because the agent wrote it mid-sentence and a pill breaks the line.

Titles resolve through a small resolver modeled on the existing external-link title resolver: the in-memory sidebar list answers most lookups for free, an unknown id costs one GET /api/sessions/{id}, and a cache plus in-flight dedupe means every reference pointing at the same session repaints off a single lookup. Until a title is known (or when the id isn't on this backend) the label is a short, still-identifying id rather than the full opaque one.

Agent-authored references travel the markdown path rather than the directive path — assistant text renders through Streamdown, so a bare reference used to come out as literal text. They are now rewritten into #session/<value> links during markdown preprocessing and dispatched in MarkdownLink alongside the existing media and preview hrefs. Preprocessing already protects code fences and inline code, so a reference being discussed in code stays literal.

For an agent to write one at all it has to know the syntax, so session_search results carry a ready-to-paste link field and the tool description says to drop it inline as a noun — not alone on its own line, and not beside the title spelled out, which showed the user the same session twice.

Test plan

  • npm run check:lint --workspace=apps/desktop (typecheck + eslint, 0 errors)
  • npm run check:test:ui --workspace=apps/desktop (256 files, 2194 tests)
  • scripts/run_tests.sh tests/tools/test_session_search.py (92 tests)
  • Render tests: an agent-written reference resolves to a link showing the session title, falls back to a short id for an unknown session, stays literal inside inline code, and opens the session on click from either surface
  • Manual: drag a session from the sidebar into the composer, send, confirm the chip reads as the title and opens the session
  • Manual: ask an agent to link a session, confirm the reply weaves one inline link into the sentence

@github-actions

github-actions Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on efe4491

all good!

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/desktop Electron desktop app (apps/desktop/*) area/sessions Session lifecycle, resume, persistence, history labels Jul 25, 2026
@OutThisLife
OutThisLife force-pushed the bb/session-link-titles branch from f6dde67 to f9d3992 Compare July 25, 2026 03:16
Resolve @session:<profile>/<id> reference values to the session's title:
the in-memory sidebar list answers most lookups, and an unknown id falls
back to GET /api/sessions/{id}. Cache, in-flight dedupe, and subscriber
fan-out mirror the external-link title resolver.

An untitled row resolves to empty rather than "Untitled session" so the
caller's short-id fallback stays the chip label.
Route session refs in the transcript through the title resolver so a
dropped session reads as its title instead of a truncated id, and use
Tabler's funnel for the session chip icon.
Assistant text goes through the markdown renderer, not DirectiveContent,
so a session reference an agent wrote came out as literal text. Rewrite
bare refs into `#session/<value>` links during markdown preprocessing and
dispatch that href to the shared chip in MarkdownLink, alongside the
existing media and preview hrefs.

Preprocessing already skips code fences and inline code, so a ref being
discussed in code stays literal. The pure parsing/href helpers move to
session-refs.ts to keep the resolver's React and API imports out of the
per-flush preprocess path.
@OutThisLife
OutThisLife force-pushed the bb/session-link-titles branch from f9d3992 to 92439be Compare July 25, 2026 03:54
@OutThisLife OutThisLife changed the title feat(desktop): resolve @session chip titles in transcript feat(desktop): resolve @session links to session titles Jul 25, 2026
Asked to link to a session, the agent had no way to know the @session
reference syntax exists — every mention in the tool schema described
consuming a link the user dropped, never writing one — so it answered
with the title and timestamp as prose and the desktop had nothing to
render.

Every result now carries a ready-to-copy `link`, and the schema says to
write it inline instead of restating the title around it. The profile
segment is omitted when the active profile can't be named confidently;
a bare id still resolves.

Also skip linkifying a ref a model already wrapped in a markdown link,
which would otherwise rewrite into a nested link.
An agent-written ref rendered as a chip that went nowhere on click. It now
renders as an ordinary inline link — the agent wrote it mid-sentence, so it
should read like one — with the funnel icon leading the resolved title.
Clicking either surface (that link, or the chip in the user's own message)
opens the session as a tab, the way its sidebar row does.

The tile store loads on click rather than at import: the composer's rich
editor pulls this module in, so a static import would boot the profile store
and its REST routing along with every transcript render.
The old wording ("no need to also spell out the title") left the model free
to write the link on its own line and then repeat the title in the sentence,
showing the user the same session twice. Say plainly that the link IS the
title and belongs mid-sentence as a noun.
@OutThisLife
OutThisLife force-pushed the bb/session-link-titles branch from 14cbf74 to efe4491 Compare July 25, 2026 17:09
@OutThisLife OutThisLife changed the title feat(desktop): resolve @session links to session titles feat(desktop): resolve @session links to titles you can click Jul 25, 2026
@OutThisLife
OutThisLife merged commit 5349c7c into main Jul 25, 2026
47 checks passed
@OutThisLife
OutThisLife deleted the bb/session-link-titles branch July 25, 2026 19:03
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…nk-titles

feat(desktop): resolve @session links to titles you can click
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants