Files
X-Financial/web/tests/workbench-ai-command-intent-model.test.mjs

105 lines
3.9 KiB
JavaScript
Raw Normal View History

import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
import { fileURLToPath } from 'node:url'
import {
buildWorkbenchDraftDeletionGuidance,
isWorkbenchDraftDeletionIntent,
resolveLatestWorkbenchDraftPayload
} from '../src/composables/workbenchAiMode/workbenchAiCommandIntentModel.js'
const personalWorkbenchAiModeScript = readFileSync(
fileURLToPath(new URL('../src/composables/workbenchAiMode/usePersonalWorkbenchAiMode.js', import.meta.url)),
'utf8'
)
const commandIntentsScript = readFileSync(
fileURLToPath(new URL('../src/composables/workbenchAiMode/useWorkbenchAiCommandIntents.js', import.meta.url)),
'utf8'
)
test('workbench command intent detects draft deletion phrases without broad delete matching', () => {
assert.equal(isWorkbenchDraftDeletionIntent('删除草稿'), true)
assert.equal(isWorkbenchDraftDeletionIntent('把刚才保存的草稿删掉'), true)
assert.equal(isWorkbenchDraftDeletionIntent('删除这个申请单'), true)
assert.equal(isWorkbenchDraftDeletionIntent('删除附件'), false)
assert.equal(isWorkbenchDraftDeletionIntent('草稿还要补什么'), false)
})
test('workbench command intent resolves latest draft payload from conversation context', () => {
const payload = resolveLatestWorkbenchDraftPayload([
{
role: 'assistant',
draftPayload: {
claim_id: 'old-draft',
claim_no: 'AOLD001',
status: 'draft'
}
},
{
role: 'assistant',
suggestedActions: [{
action_type: 'open_application_detail',
payload: {
claim_id: 'latest-draft',
claim_no: 'ALATEST1',
status: 'draft'
}
}]
}
])
assert.deepEqual(payload, {
claimId: 'latest-draft',
claimNo: 'ALATEST1',
status: 'draft',
documentType: 'application'
})
})
test('workbench command intent skips submitted documents when deleting draft', () => {
const payload = resolveLatestWorkbenchDraftPayload([
{
role: 'assistant',
draftPayload: {
claim_id: 'submitted-application',
claim_no: 'ASUBMIT1',
status: 'submitted'
}
}
])
assert.equal(payload, null)
})
test('workbench draft deletion guidance opens detail instead of deleting directly', () => {
const guidance = buildWorkbenchDraftDeletionGuidance({
claimId: 'latest-draft',
claimNo: 'ALATEST1',
documentType: 'application'
})
assert.match(guidance.content, /已识别到您想删除草稿/)
assert.match(guidance.content, /不会直接替您删除/)
assert.equal(guidance.suggestedActions.length, 1)
assert.equal(guidance.suggestedActions[0].action_type, 'open_application_detail')
assert.equal(guidance.suggestedActions[0].payload.claim_id, 'latest-draft')
assert.equal(guidance.suggestedActions[0].payload.claim_no, 'ALATEST1')
})
test('workbench draft deletion intent is wired before draft slot continuation', () => {
assert.match(commandIntentsScript, /isWorkbenchDraftDeletionIntent/)
assert.match(commandIntentsScript, /function handleInlineDraftDeletionIntent\(cleanPrompt, entry = \{\}\)/)
assert.match(commandIntentsScript, /resolveLatestWorkbenchDraftPayload\(conversationMessages\.value\)/)
assert.match(commandIntentsScript, /buildWorkbenchDraftDeletionGuidance\(draftPayload\)/)
assert.match(personalWorkbenchAiModeScript, /useWorkbenchAiCommandIntents/)
const startIndex = personalWorkbenchAiModeScript.indexOf('function startInlineConversation')
const startBlock = personalWorkbenchAiModeScript.slice(startIndex)
const deleteIntentIndex = startBlock.indexOf('if (commandIntents.handleInlineDraftDeletionIntent(cleanPrompt, entry))')
const draftContinuationIndex = startBlock.indexOf('if (aiExpenseDraft.value && !isAiExpenseDraftComplete(aiExpenseDraft.value))')
assert.ok(deleteIntentIndex >= 0)
assert.ok(draftContinuationIndex > deleteIntentIndex)
})