mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-13 03:52:00 +00:00
fix(tui): render MEDIA: as a clickable file chip, drop audio directive
The agent emits `MEDIA:<path>` to signal file delivery to the gateway, and `[[audio_as_voice]]` as a voice-delivery hint. The gateway strips both before sending to Telegram/Discord/Slack, but the TUI was rendering them raw through markdown — which is also how the intraword underscore bug originally surfaced (`browser_screenshot_ecc…`). At the `Md` layer, detect both sentinels on their own line: - `MEDIA:<path>` → `▸ <path>` with the path rendered literal and wrapped in a `Link` for OSC 8 hyperlink support (absolute paths get a `file://` URL, so modern terminals make them click-to-open). - `[[audio_as_voice]]` → dropped silently; it has no meaning in TUI. Covers tests for quoted/backticked MEDIA variants, Windows drive paths, whitespace, and the inline-in-prose case (left untouched — still protected by the intraword-underscore guard).
This commit is contained in:
parent
b17eb94907
commit
97c2da2112
2 changed files with 55 additions and 1 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { INLINE_RE, stripInlineMarkup } from '../components/markdown.js'
|
||||
import { AUDIO_DIRECTIVE_RE, INLINE_RE, MEDIA_LINE_RE, stripInlineMarkup } from '../components/markdown.js'
|
||||
|
||||
const matches = (text: string) => [...text.matchAll(INLINE_RE)].map(m => m[0])
|
||||
|
||||
|
|
@ -32,3 +32,25 @@ describe('stripInlineMarkup', () => {
|
|||
expect(stripInlineMarkup('__bold__ and foo__bar__')).toBe('bold and foo__bar__')
|
||||
})
|
||||
})
|
||||
|
||||
describe('protocol sentinels', () => {
|
||||
it('captures MEDIA: paths with surrounding quotes or backticks', () => {
|
||||
expect('MEDIA:/tmp/a.png'.match(MEDIA_LINE_RE)?.[1]).toBe('/tmp/a.png')
|
||||
expect(' MEDIA: /home/me/.hermes/cache/screenshots/browser_screenshot_ecc.png '.match(MEDIA_LINE_RE)?.[1]).toBe(
|
||||
'/home/me/.hermes/cache/screenshots/browser_screenshot_ecc.png'
|
||||
)
|
||||
expect('`MEDIA:/tmp/a.png`'.match(MEDIA_LINE_RE)?.[1]).toBe('/tmp/a.png')
|
||||
expect('"MEDIA:C:\\files\\a.png"'.match(MEDIA_LINE_RE)?.[1]).toBe('C:\\files\\a.png')
|
||||
})
|
||||
|
||||
it('ignores MEDIA: tokens embedded in prose', () => {
|
||||
expect('here is MEDIA:/tmp/a.png for you'.match(MEDIA_LINE_RE)).toBeNull()
|
||||
expect('the media: section is empty'.match(MEDIA_LINE_RE)).toBeNull()
|
||||
})
|
||||
|
||||
it('matches the [[audio_as_voice]] directive', () => {
|
||||
expect(AUDIO_DIRECTIVE_RE.test('[[audio_as_voice]]')).toBe(true)
|
||||
expect(AUDIO_DIRECTIVE_RE.test(' [[audio_as_voice]] ')).toBe(true)
|
||||
expect(AUDIO_DIRECTIVE_RE.test('audio_as_voice')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue