mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-29 18:46:59 +00:00
fix(tui,desktop): let authored link text outrank the fetched page title
Both chat renderers resolve link titles over the network and render them in place of the link's text, unconditionally — so they also replaced text the agent deliberately wrote. `[#71706](url)` rendered as the whole GitHub page title, and prose labels were swapped out mid-sentence. The TUI ordered `fetched || label` and always passed the URL to useLinkTitle. Desktop looked guarded but wasn't: chat markdown hands authored text to PrettyLink as `fallbackLabel`, not `label`, so `useLinkTitle(label ? null : target)` never skipped the fetch and `fetched || label || fallbackLabel` still let the title win. Treat an authored label as the intent: it wins, and it skips the fetch. A label that is just the URL still resolves, since `[url](url)` and `<url>` are bare links wearing markdown syntax — desktop already applied that same URL-equality rule before handing the label over. Co-authored-by: Kinkoolino-Hermes <297364961+Kinkoolino-Hermes@users.noreply.github.com>
This commit is contained in:
parent
6c9718151c
commit
f244deffee
2 changed files with 18 additions and 13 deletions
|
|
@ -251,10 +251,13 @@ interface PrettyLinkProps extends Omit<ComponentProps<'a'>, 'href' | 'target'> {
|
|||
fallbackLabel?: string
|
||||
}
|
||||
|
||||
// Title resolution is a fallback, not an override. Both props carry authored
|
||||
// text — chat markdown passes `fallbackLabel` — so either one skips the fetch.
|
||||
export function PrettyLink({ className, fallbackLabel, href, label, ...rest }: PrettyLinkProps) {
|
||||
const target = useMemo(() => normalizeExternalUrl(href), [href])
|
||||
const fetched = useLinkTitle(label ? null : target)
|
||||
const display = fetched || label?.trim() || fallbackLabel?.trim() || urlSlugTitleLabel(target)
|
||||
const authoredLabel = label?.trim() || fallbackLabel?.trim()
|
||||
const fetched = useLinkTitle(authoredLabel ? null : target)
|
||||
const display = authoredLabel || fetched || urlSlugTitleLabel(target)
|
||||
|
||||
return (
|
||||
<ExternalLink className={cn('wrap-break-word', className)} href={target} title={target} {...rest}>
|
||||
|
|
|
|||
|
|
@ -153,25 +153,27 @@ const autolinkUrl = (raw: string) =>
|
|||
const defaultLinkLabel = (url: string) =>
|
||||
url.startsWith('mailto:') ? url.replace(/^mailto:/, '') : /^https?:\/\//i.test(url) ? urlSlugTitleLabel(url) : url
|
||||
|
||||
const pickFallbackLabel = (label: string | undefined, target: string): string | undefined => {
|
||||
// A label only counts as authored if it says something the URL doesn't:
|
||||
// `[https://example.com](https://example.com)` and `<https://example.com>`
|
||||
// are bare links wearing markdown syntax, so they still want a page title.
|
||||
const pickAuthoredLabel = (label: string | undefined, target: string): string | undefined => {
|
||||
const trimmed = label?.trim()
|
||||
|
||||
if (!trimmed) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return normalizeExternalUrl(trimmed) === target ? undefined : trimmed
|
||||
return trimmed && normalizeExternalUrl(trimmed) !== target ? trimmed : undefined
|
||||
}
|
||||
|
||||
interface ResolvedLinkProps {
|
||||
fallbackLabel?: string
|
||||
authoredLabel?: string
|
||||
t: Theme
|
||||
url: string
|
||||
}
|
||||
|
||||
function ResolvedLink({ fallbackLabel, t, url }: ResolvedLinkProps) {
|
||||
const fetched = useLinkTitle(url)
|
||||
const display = fetched || fallbackLabel || defaultLinkLabel(url)
|
||||
// Title resolution is a fallback for links with no text of their own, not an
|
||||
// override — replacing `[Read the RFC](url)` with the page title throws away
|
||||
// better wording than we can derive, and mangles labels like `#71706`.
|
||||
function ResolvedLink({ authoredLabel, t, url }: ResolvedLinkProps) {
|
||||
const fetched = useLinkTitle(authoredLabel ? null : url)
|
||||
const display = authoredLabel || fetched || defaultLinkLabel(url)
|
||||
|
||||
return (
|
||||
<Link url={url}>
|
||||
|
|
@ -185,7 +187,7 @@ function ResolvedLink({ fallbackLabel, t, url }: ResolvedLinkProps) {
|
|||
const renderResolvedLink = (k: number, t: Theme, rawUrl: string, label?: string) => {
|
||||
const target = normalizeExternalUrl(rawUrl)
|
||||
|
||||
return <ResolvedLink fallbackLabel={pickFallbackLabel(label, target)} key={k} t={t} url={target} />
|
||||
return <ResolvedLink authoredLabel={pickAuthoredLabel(label, target)} key={k} t={t} url={target} />
|
||||
}
|
||||
|
||||
export const stripInlineMarkup = (v: string) =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue