Download packages/acp-server/test/convert.test.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 6.08 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/acp-server/test/convert.test.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/acp-server/test/convert.test.ts
-
curl -L -o convert.test.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/acp-server/test/convert.test.ts
6.08 kB
| import { mkdtemp, readdir, readFile, rm } from 'node:fs/promises'; | |
| import { tmpdir } from 'node:os'; | |
| import { join } from 'node:path'; | |
| import type { McpServer } from '@agentclientprotocol/sdk'; | |
| import type { ContentPart } from '@moonshot-ai/agent-core-v2'; | |
| import { afterEach, describe, expect, it } from 'vitest'; | |
| import { | |
| acpBlocksToContentParts, | |
| acpMcpServersToConfigRecord, | |
| compressPromptImageParts, | |
| } from '../src/convert'; | |
| import { solidPng, solidPngBase64 } from './_helpers/png'; | |
| describe('acpMcpServersToConfigRecord', () => { | |
| it('returns undefined for an absent or empty list', () => { | |
| expect(acpMcpServersToConfigRecord(undefined)).toBeUndefined(); | |
| expect(acpMcpServersToConfigRecord([])).toBeUndefined(); | |
| }); | |
| it('maps stdio servers (no type field) to local stdio configs', () => { | |
| const servers: McpServer[] = [ | |
| { | |
| name: 'fs', | |
| command: '/usr/local/bin/mcp-fs', | |
| args: ['--root', '/tmp'], | |
| env: [ | |
| { name: 'API_KEY', value: 'secret' }, | |
| { name: 'DEBUG', value: '1' }, | |
| ], | |
| }, | |
| ]; | |
| expect(acpMcpServersToConfigRecord(servers)).toEqual({ | |
| fs: { | |
| transport: 'stdio', | |
| command: '/usr/local/bin/mcp-fs', | |
| args: ['--root', '/tmp'], | |
| env: { API_KEY: 'secret', DEBUG: '1' }, | |
| runtime_id: 'local', | |
| }, | |
| }); | |
| }); | |
| it('maps http and sse servers with header pairs as a record', () => { | |
| const servers: McpServer[] = [ | |
| { | |
| type: 'http', | |
| name: 'web', | |
| url: 'https://example.com/mcp', | |
| headers: [{ name: 'Authorization', value: 'Bearer x' }], | |
| }, | |
| { type: 'sse', name: 'events', url: 'https://example.com/sse', headers: [] }, | |
| ]; | |
| expect(acpMcpServersToConfigRecord(servers)).toEqual({ | |
| web: { | |
| transport: 'http', | |
| url: 'https://example.com/mcp', | |
| headers: { Authorization: 'Bearer x' }, | |
| }, | |
| events: { transport: 'sse', url: 'https://example.com/sse', headers: undefined }, | |
| }); | |
| }); | |
| it('drops the unstable acp transport and returns undefined when nothing survives', () => { | |
| const servers = [{ type: 'acp', name: 'nested', serverId: 'srv-1' } as unknown as McpServer]; | |
| expect(acpMcpServersToConfigRecord(servers)).toBeUndefined(); | |
| }); | |
| }); | |
| describe('acpBlocksToContentParts', () => { | |
| it('projects file links and embedded text resources with provenance', () => { | |
| const parts = acpBlocksToContentParts([ | |
| { type: 'resource_link', uri: 'file:///tmp/example.ts#L2-L4', name: 'example.ts' }, | |
| { type: 'resource_link', uri: 'https://example.test/doc', name: 'remote doc' }, | |
| { | |
| type: 'resource', | |
| resource: { uri: 'memory://note/1', text: 'remember this' }, | |
| }, | |
| ] as never); | |
| expect(parts).toEqual([ | |
| { type: 'text', text: '/tmp/example.ts:2-4' }, | |
| { | |
| type: 'text', | |
| text: '<resource_link uri="https://example.test/doc" name="remote doc" />', | |
| }, | |
| { type: 'text', text: '<resource uri="memory://note/1">remember this</resource>' }, | |
| ]); | |
| }); | |
| }); | |
| describe('compressPromptImageParts', () => { | |
| const trash: string[] = []; | |
| afterEach(async () => { | |
| await Promise.all(trash.splice(0).map((dir) => rm(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }))); | |
| }); | |
| async function tempOriginalsDir(): Promise<string> { | |
| const dir = await mkdtemp(join(tmpdir(), 'acp-originals-')); | |
| trash.push(dir); | |
| return dir; | |
| } | |
| function imagePart(url: string): ContentPart { | |
| return { type: 'image_url', imageUrl: { url } }; | |
| } | |
| it('leaves format judgment to the engine: a format it cannot re-encode passes through', async () => { | |
| // Which formats are acceptable depends on the provider the agent is | |
| // bound to, which this edge does not know; the engine's prompt gate | |
| // decides. So neither a HEIC payload nor a MIME alias is rewritten here. | |
| const heic = `data:image/heic;base64,${Buffer.alloc(32).toString('base64')}`; | |
| const alias = `data:IMAGE/PNG;base64,${solidPngBase64(8, 8)}`; | |
| const out = await compressPromptImageParts([ | |
| { type: 'text', text: 'look' }, | |
| imagePart(heic), | |
| imagePart(alias), | |
| ]); | |
| expect(out).toEqual([{ type: 'text', text: 'look' }, imagePart(heic), imagePart(alias)]); | |
| }); | |
| it('passes an under-limit image through unchanged and persists nothing', async () => { | |
| const originalsDir = await tempOriginalsDir(); | |
| const url = `data:image/png;base64,${solidPngBase64(32, 32)}`; | |
| const out = await compressPromptImageParts([imagePart(url)], { | |
| originalsDir, | |
| maxImageEdgePx: 64, | |
| }); | |
| expect(out).toHaveLength(1); | |
| expect(out[0]).toEqual(imagePart(url)); | |
| // No compression happened, so no original was persisted. | |
| expect(await readdir(originalsDir)).toEqual([]); | |
| }); | |
| it('compresses an over-edge image, prefixes a caption, and persists the original', async () => { | |
| const originalsDir = await tempOriginalsDir(); | |
| const original = solidPng(128, 128); | |
| const url = `data:image/png;base64,${original.toString('base64')}`; | |
| const out = await compressPromptImageParts([imagePart(url)], { | |
| originalsDir, | |
| maxImageEdgePx: 64, | |
| }); | |
| // caption text part immediately precedes the re-encoded image part. | |
| expect(out).toHaveLength(2); | |
| const caption = out[0] as { text: string }; | |
| const image = out[1] as { imageUrl: { url: string } }; | |
| expect(caption.text).toContain('Image compressed to fit model limits'); | |
| expect(caption.text).toContain('128x128'); | |
| expect(caption.text).toContain(originalsDir); | |
| expect(image.imageUrl.url).not.toBe(url); | |
| expect(image.imageUrl.url.startsWith('data:image/')).toBe(true); | |
| // The original bytes landed in the session media-originals dir so the | |
| // model can read fine detail back from the captioned path. | |
| const files = await readdir(originalsDir); | |
| expect(files).toHaveLength(1); | |
| expect(caption.text).toContain(files[0]!); | |
| expect(await readFile(join(originalsDir, files[0]!))).toEqual(original); | |
| }); | |
| }); | |