mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-12 13:52:15 +00:00
Bring apps/desktop and ui-tui to a clean state for typecheck, eslint,
and prettier:
- Run prettier across both trees (printWidth/wrap drift; prettier is not
CI-enforced for these JS projects, so main had accumulated drift).
- Apply eslint --fix for padding-line-between-statements and perfectionist
import/export sorting.
- Manual fixes for non-auto-fixable rules:
- remove unused node:net import in electron/main.cjs (uses Electron net)
- replace inline `typeof import(...)` annotations with top-level
`import type * as EnvModule` in two ui-tui test files
- scoped eslint-disable no-control-regex on intentional sentinel/ANSI
regexes (mathUnicode.ts, text.ts)
- resolve react-hooks/exhaustive-deps per-case: correct swapped/missing
deps, collapse redundant session.* members, and justified disables on
settings mount-only data-load effects to preserve run-once behavior
No behavior changes; test pass/fail counts are unchanged from the main
baseline.
120 lines
3.5 KiB
TypeScript
120 lines
3.5 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
dedupeGeneratedImageEchoesInParts,
|
|
generatedImageEchoSources,
|
|
generatedImageFromResult,
|
|
stripGeneratedImageEchoes
|
|
} from './generated-images'
|
|
|
|
describe('generatedImageFromResult', () => {
|
|
it('prefers the host-visible image path', () => {
|
|
expect(
|
|
generatedImageFromResult({
|
|
agent_visible_image: '/container/cache/cat.png',
|
|
host_image: '/Users/me/.hermes/cache/images/cat.png',
|
|
image: '/Users/me/.hermes/cache/images/cat.png',
|
|
success: true
|
|
})
|
|
).toBe('/Users/me/.hermes/cache/images/cat.png')
|
|
})
|
|
|
|
it('ignores failed image generation results', () => {
|
|
expect(generatedImageFromResult({ image: 'https://cdn.example/cat.png', success: false })).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('stripGeneratedImageEchoes', () => {
|
|
it('removes repeated generated image markdown without removing prose', () => {
|
|
expect(
|
|
stripGeneratedImageEchoes('Here you go.\n\n', [
|
|
'https://cdn.example/cat.png'
|
|
])
|
|
).toBe('Here you go.')
|
|
})
|
|
|
|
it('removes media links for generated local image paths', () => {
|
|
expect(stripGeneratedImageEchoes('Saved image: [Image: cat.png](#media:%2Ftmp%2Fcat.png)', ['/tmp/cat.png'])).toBe(
|
|
'Saved image:'
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('generatedImageEchoSources', () => {
|
|
it('collects every path variant the model might restate', () => {
|
|
expect(
|
|
generatedImageEchoSources([
|
|
{
|
|
result: {
|
|
agent_visible_image: '/sandbox/cat.png',
|
|
host_image: '/host/cat.png',
|
|
image: '/host/cat.png',
|
|
success: true
|
|
},
|
|
toolName: 'image_generate',
|
|
type: 'tool-call'
|
|
}
|
|
])
|
|
).toEqual(['/host/cat.png', '/sandbox/cat.png'])
|
|
})
|
|
})
|
|
|
|
describe('dedupeGeneratedImageEchoesInParts', () => {
|
|
it('keeps the agent prose while removing the duplicated image', () => {
|
|
expect(
|
|
dedupeGeneratedImageEchoesInParts([
|
|
{ text: 'Here is your peacock!  Enjoy.', type: 'text' },
|
|
{
|
|
result: { host_image: '/host/p.png', image: '/host/p.png', success: true },
|
|
toolName: 'image_generate',
|
|
type: 'tool-call'
|
|
}
|
|
])
|
|
).toEqual([
|
|
{ text: 'Here is your peacock! Enjoy.', type: 'text' },
|
|
{
|
|
result: { host_image: '/host/p.png', image: '/host/p.png', success: true },
|
|
toolName: 'image_generate',
|
|
type: 'tool-call'
|
|
}
|
|
])
|
|
})
|
|
|
|
it('strips a sandbox path the model restated instead of the host path', () => {
|
|
expect(
|
|
dedupeGeneratedImageEchoesInParts([
|
|
{ text: '', type: 'text' },
|
|
{
|
|
result: {
|
|
agent_visible_image: '/sandbox/cat.png',
|
|
host_image: '/host/cat.png',
|
|
image: '/host/cat.png',
|
|
success: true
|
|
},
|
|
toolName: 'image_generate',
|
|
type: 'tool-call'
|
|
}
|
|
])
|
|
).toEqual([
|
|
{
|
|
result: {
|
|
agent_visible_image: '/sandbox/cat.png',
|
|
host_image: '/host/cat.png',
|
|
image: '/host/cat.png',
|
|
success: true
|
|
},
|
|
toolName: 'image_generate',
|
|
type: 'tool-call'
|
|
}
|
|
])
|
|
})
|
|
|
|
it('leaves pending generations untouched so the agent prose survives', () => {
|
|
const parts = [
|
|
{ text: 'Another peacock, coming up!', type: 'text' },
|
|
{ result: undefined, toolName: 'image_generate', type: 'tool-call' }
|
|
]
|
|
|
|
expect(dedupeGeneratedImageEchoesInParts(parts)).toEqual(parts)
|
|
})
|
|
})
|