feat: W7 功能標籤分類、對白檢索與注入 (#8)
用 $.model.complete(Haiku)判斷回應的功能標籤,從角色索引取同標籤對白, 以只增不改的訊息附在使用者訊息之前;失敗一律退回不注入。 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
1c4e0c5d98
commit
d9e50d196b
@@ -0,0 +1,62 @@
|
||||
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()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user