46 lines
1.6 KiB
TypeScript
46 lines
1.6 KiB
TypeScript
import {
|
|
hasAssistantText,
|
|
LlmRequestError,
|
|
parseLlmRequest,
|
|
} from './llm-contract.ts'
|
|
|
|
function assert(condition: boolean, message: string): void {
|
|
if (!condition) throw new Error(message)
|
|
}
|
|
|
|
Deno.test('llm request normalization accepts a bounded conversation', () => {
|
|
const parsed = parseLlmRequest({
|
|
messages: [{ role: 'user', content: ' hello ' }],
|
|
max_tokens: 512,
|
|
stream: false,
|
|
})
|
|
assert(parsed.messages[0].content === 'hello', 'content should be trimmed')
|
|
assert(parsed.max_tokens === 512, 'max_tokens should be preserved')
|
|
})
|
|
|
|
Deno.test('llm request rejects empty, oversized, and malformed input', () => {
|
|
const invalid: unknown[] = [
|
|
{},
|
|
{ messages: [] },
|
|
{ messages: [{ role: 'system', content: 'x' }] },
|
|
{ messages: [{ role: 'user', content: '' }] },
|
|
{ messages: [{ role: 'user', content: 'x'.repeat(8_001) }] },
|
|
{ messages: [{ role: 'user', content: 'x' }], max_tokens: 0 },
|
|
{ messages: [{ role: 'user', content: 'x' }], stream: 'yes' },
|
|
]
|
|
for (const value of invalid) {
|
|
let rejected = false
|
|
try {
|
|
parseLlmRequest(value)
|
|
} catch (error) {
|
|
rejected = error instanceof LlmRequestError
|
|
}
|
|
assert(rejected, `expected rejection for ${JSON.stringify(value).slice(0, 80)}`)
|
|
}
|
|
})
|
|
|
|
Deno.test('assistant response must contain non-empty text', () => {
|
|
assert(hasAssistantText({ content: [{ type: 'text', text: 'answer' }] }), 'valid text missing')
|
|
assert(!hasAssistantText({ content: [{ type: 'tool_use', input: {} }] }), 'tool-only response accepted')
|
|
assert(!hasAssistantText({ content: [{ type: 'text', text: ' ' }] }), 'blank response accepted')
|
|
})
|