Files
Jeffery (jiantw83)andClaude Sonnet 5.5 d9e50d196b feat: W7 功能標籤分類、對白檢索與注入 (#8)
用 $.model.complete(Haiku)判斷回應的功能標籤,從角色索引取同標籤對白,
以只增不改的訊息附在使用者訊息之前;失敗一律退回不注入。

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 17:44:09 +00:00

63 lines
2.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, test } from 'claude-code/testing'
import { buildClassifyPrompt, classify, parseFunction, type Complete } from './classify'
import { FUNCTIONS } from './tags'
describe('parseFunction', () => {
test('白名單內的代號', () => {
expect(parseFunction('comfort')).toBe('comfort')
expect(parseFunction(' Report_Fail\n')).toBe('report_fail')
expect(parseFunction('tease。')).toBe('tease')
})
test('白名單外或空回覆視為失敗', () => {
expect(parseFunction('flirt')).toBeNull()
expect(parseFunction('')).toBeNull()
expect(parseFunction('我覺得是安慰')).toBeNull()
})
test('只認開頭第一個詞', () => {
expect(parseFunction('comfort or tease')).toBe('comfort')
expect(parseFunction('他說 comfort')).toBeNull()
})
})
describe('buildClassifyPrompt', () => {
test('列出所有功能代號(other 除外)並包住使用者的話', () => {
const p = buildClassifyPrompt('測試失敗了')
for (const key of Object.keys(FUNCTIONS).filter(k => k !== 'other')) expect(p).toContain(`${key}:`)
expect(p).toContain('<使用者的話>\n測試失敗了\n</使用者的話>')
})
test('過長的使用者輸入截斷', () => {
expect(buildClassifyPrompt('字'.repeat(5000)).length).toBeLessThan(1500)
})
})
describe('classify', () => {
const ok = (text: string): Complete => async () => ({ isAnswered: true, text })
test('成功回傳標籤,並用 haiku、低 effort、有逾時', async () => {
let seen: Parameters<Complete>[0] | undefined
const r = await classify(async req => ((seen = req), { isAnswered: true, text: 'comfort' }), '好累')
expect(r).toBe('comfort')
expect(seen?.model).toBe('haiku')
expect(seen?.effort).toBe('low')
expect(seen?.timeoutMs).toBeGreaterThan(0)
})
test('未回答、空回覆、白名單外都回傳 null', async () => {
expect(await classify(async () => ({ isAnswered: false }), 'x')).toBeNull()
expect(await classify(ok(''), 'x')).toBeNull()
expect(await classify(ok('flirt'), 'x')).toBeNull()
})
test('呼叫丟出例外也回傳 null', async () => {
expect(
await classify(async () => {
throw new Error('blocked model')
}, 'x'),
).toBeNull()
})
})