feat(desktop): resolve @session links to titles you can click - #71162
Merged
Conversation
Contributor
૮ >ﻌ< ა ci reviewran on efe4491 all good! |
OutThisLife
force-pushed
the
bb/session-link-titles
branch
from
July 25, 2026 03:16
f6dde67 to
f9d3992
Compare
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
force-pushed
the
bb/session-link-titles
branch
from
July 25, 2026 03:54
f9d3992 to
92439be
Compare
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
force-pushed
the
bb/session-link-titles
branch
from
July 25, 2026 17:09
14cbf74 to
efe4491
Compare
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
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
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 inMarkdownLinkalongside 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_searchresults carry a ready-to-pastelinkfield 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)