import { describe, expect, it } from 'vitest';
import type { ContextMessage } from '@moonshot-ai/agent-core-v2';
import { projectPromptContentParts, toProtocolMessage } from '../../../src/services/messages/messageProjection';
const SESSION_ID = 'session_1';
const CREATED_AT = 1_700_000_000_000;
function userText(text: string): ContextMessage {
return { role: 'user', content: [{ type: 'text', text }], toolCalls: [] };
}
describe('toProtocolMessage', () => {
it('maps text/think/image/audio/video content parts', () => {
const msg: ContextMessage = {
role: 'user',
content: [
{ type: 'text', text: 'hello' },
{ type: 'think', think: 'hmm', encrypted: 'sig-1' },
{ type: 'image_url', imageUrl: { url: 'https://example.com/a.png' } },
{ type: 'audio_url', audioUrl: { url: 'https://example.com/a.mp3' } },
{ type: 'video_url', videoUrl: { url: 'https://example.com/a.mp4' } },
],
toolCalls: [],
};
expect(toProtocolMessage(SESSION_ID, 0, msg, CREATED_AT).content).toEqual([
{ type: 'text', text: 'hello' },
{ type: 'thinking', thinking: 'hmm', signature: 'sig-1' },
{ type: 'image', source: { kind: 'url', url: 'https://example.com/a.png' } },
{ type: 'text', text: '[audio:https://example.com/a.mp3]' },
{ type: 'video', source: { kind: 'url', url: 'https://example.com/a.mp4' } },
]);
});
it('projects a daemon-ref image part to a session_media source', () => {
const msg: ContextMessage = {
role: 'user',
content: [
{ type: 'text', text: 'what is this?' },
{ type: 'image_url', imageUrl: { url: 'kimi-file://file_9?path=%2Fcache%2Fpic.png' } },
],
toolCalls: [],
};
expect(toProtocolMessage(SESSION_ID, 0, msg, CREATED_AT).content).toEqual([
{ type: 'text', text: 'what is this?' },
{ type: 'image', source: { kind: 'session_media', file_id: 'file_9' } },
]);
});
it('preserves media names in live and prompt projections', () => {
const part = {
type: 'image_url' as const,
imageUrl: { url: 'kimi-file://file_9', id: 'file_9', name: 'photo.png' },
};
const msg: ContextMessage = { role: 'user', content: [part], toolCalls: [] };
expect(toProtocolMessage(SESSION_ID, 0, msg, CREATED_AT).content).toEqual([
{ type: 'image', source: { kind: 'session_media', file_id: 'file_9' }, name: 'photo.png' },
]);
expect(projectPromptContentParts([part])).toEqual([
{ type: 'image', source: { kind: 'session_media', file_id: 'file_9' }, name: 'photo.png' },
]);
});
it('keeps a legacy tag+ref pair as text plus the ref projection', () => {
const msg: ContextMessage = {
role: 'user',
content: [
{ type: 'text', text: '' },
{ type: 'image_url', imageUrl: { url: 'kimi-file://file_9?path=%2Fcache%2Fpic.png' } },
],
toolCalls: [],
};
expect(toProtocolMessage(SESSION_ID, 0, msg, CREATED_AT).content).toEqual([
{ type: 'text', text: '' },
{ type: 'image', source: { kind: 'session_media', file_id: 'file_9' } },
]);
});
it('keeps a bare tag as text in user messages', () => {
const msg: ContextMessage = {
role: 'user',
content: [
{ type: 'text', text: '