mirror of
https://github.com/EKKOLearnAI/hermes-web-ui.git
synced 2026-05-25 21:40:13 +00:00
9a9416c99c
* feat: support profile-aware group chat bridge flows * feat: route cron jobs through hermes cli * Fix group chat routing and isolate bridge tests * Add Grok image-to-video media skill * Default Grok videos to media directory * Fix bridge profile fallback and cron repeat clearing * Refine bridge chat and gateway platform handling * Filter bridge tool-call text deltas * Preserve structured bridge chat history * Prepare beta release build artifacts * Fix Windows run profile resolution * Fix Windows path compatibility checks * Fix profile-scoped model page display * Hide Windows subprocess windows for jobs and updates * Hide Windows file backend subprocess windows * Avoid Windows gateway restart lock conflicts * Treat Windows gateway lock as running on startup * Force release Windows gateway lock on restart * Tighten Windows gateway lock cleanup * Update chat e2e source expectation * Bump package version to 0.5.30 --------- Co-authored-by: Codex <codex@openai.com>
53 lines
2.0 KiB
TypeScript
53 lines
2.0 KiB
TypeScript
import { mkdtemp, rm, writeFile } from 'fs/promises'
|
|
import { join } from 'path'
|
|
import { tmpdir } from 'os'
|
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
import { convertContentBlocks, convertContentBlocksForAgent } from '../../packages/server/src/services/hermes/run-chat/content-blocks'
|
|
|
|
let tempDir = ''
|
|
|
|
describe('run chat content blocks', () => {
|
|
beforeEach(async () => {
|
|
tempDir = await mkdtemp(join(tmpdir(), 'hermes-content-blocks-'))
|
|
})
|
|
|
|
afterEach(async () => {
|
|
if (tempDir) await rm(tempDir, { recursive: true, force: true })
|
|
})
|
|
|
|
it('keeps API image conversion as base64 input_image only', async () => {
|
|
const imagePath = join(tempDir, 'image.png')
|
|
await writeFile(imagePath, Buffer.from([1, 2, 3]))
|
|
|
|
const parts = await convertContentBlocks([
|
|
{ type: 'text', text: 'animate this' },
|
|
{ type: 'image', name: 'image.png', path: imagePath, media_type: 'image/png' },
|
|
])
|
|
|
|
expect(parts).toHaveLength(2)
|
|
expect(parts[0]).toEqual({ type: 'input_text', text: 'animate this' })
|
|
expect(parts[1].type).toBe('input_image')
|
|
expect(parts[1].image_url).toMatch(/^data:image\/png;base64,/)
|
|
expect(JSON.stringify(parts)).not.toContain('Local image path for tools')
|
|
})
|
|
|
|
it('adds local file path text for bridge agents while preserving the image data', async () => {
|
|
const imagePath = join(tempDir, 'image.png')
|
|
await writeFile(imagePath, Buffer.from([1, 2, 3]))
|
|
|
|
const parts = await convertContentBlocksForAgent([
|
|
{ type: 'text', text: 'animate this' },
|
|
{ type: 'image', name: 'image.png', path: imagePath, media_type: 'image/png' },
|
|
])
|
|
|
|
expect(parts).toHaveLength(3)
|
|
expect(parts[0]).toEqual({ type: 'text', text: 'animate this' })
|
|
expect(parts[1]).toEqual({
|
|
type: 'text',
|
|
text: `[Attached image: image.png]\nLocal image path for tools: ${imagePath}`,
|
|
})
|
|
expect(parts[2].type).toBe('image_url')
|
|
expect(parts[2].image_url?.url).toMatch(/^data:image\/png;base64,/)
|
|
})
|
|
})
|