feat(web): AI 工作台意图规划与规划思考模型
- 新增 workbenchAiIntentPlannerModel,基于 LLM function_call 解析建单/草稿/提交意图,区分 model 与 rule_fallback 来源 - 新增 workbenchAiPlanningThinkingModel 合并规划思考事件流,按 eventId 去重合并 - application gate/preview 模型接入意图规划,usePersonalWorkbenchAiMode/useWorkbenchAiStewardFlow/useWorkbenchAiActionRouter 链路适配,支持上下文提交 - steward 服务与 stewardPlanModel 适配新动作结构,receipt-folder-view 微调样式 - 新增 intent-planner-model/application-context-submit/steward-actions-service 测试,更新 gate-model/action-router/plan-message-copy/fast-preview 测试
This commit is contained in:
@@ -51,6 +51,9 @@ import {
|
||||
import {
|
||||
shouldUseBudgetCompileReport
|
||||
} from '../src/views/scripts/budgetAssistantReportModel.js'
|
||||
import {
|
||||
buildInlineApplicationPreview
|
||||
} from '../src/composables/workbenchAiMode/workbenchAiApplicationPreviewModel.js'
|
||||
import { resolveStewardTypewriterNextIndex } from '../src/views/scripts/stewardTypewriter.js'
|
||||
import {
|
||||
ASSISTANT_SCOPE_ACTION_SWITCH,
|
||||
@@ -140,6 +143,14 @@ const flowScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/views/scripts/useTravelReimbursementFlow.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const personalWorkbenchAiModeScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/composables/workbenchAiMode/usePersonalWorkbenchAiMode.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
const applicationPreviewFlowScript = readFileSync(
|
||||
fileURLToPath(new URL('../src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js', import.meta.url)),
|
||||
'utf8'
|
||||
)
|
||||
|
||||
function createFlowHarness() {
|
||||
return useTravelReimbursementFlow({
|
||||
@@ -241,6 +252,32 @@ test('application intent uses local preview instead of immediate orchestrator ca
|
||||
assert.match(buildLocalApplicationPreviewMessage(preview), /点击对应行即可直接编辑/)
|
||||
})
|
||||
|
||||
test('AI workbench routes compact travel direct-submit planner into application preview auto submit', () => {
|
||||
assert.match(personalWorkbenchAiModeScript, /buildRuleFallbackWorkbenchAiIntentPlan/)
|
||||
assert.match(personalWorkbenchAiModeScript, /normalizeWorkbenchAiIntentPlan/)
|
||||
assert.match(personalWorkbenchAiModeScript, /resolveExecutableTravelApplicationPlan/)
|
||||
assert.match(
|
||||
personalWorkbenchAiModeScript,
|
||||
/async function executeModelPlannedWorkbenchIntent\(cleanPrompt, entry = \{\}, files = \[\]\)/
|
||||
)
|
||||
assert.match(
|
||||
personalWorkbenchAiModeScript,
|
||||
/modelPlan = await stewardFlow\.resolveInlineExecutionPlan\(cleanPrompt, entry, files\)/
|
||||
)
|
||||
assert.match(
|
||||
personalWorkbenchAiModeScript,
|
||||
/const rulePlan = buildRuleFallbackWorkbenchAiIntentPlan\(cleanPrompt\)/
|
||||
)
|
||||
assert.match(
|
||||
personalWorkbenchAiModeScript,
|
||||
/applicationFlow\.startAiApplicationPreview\([\s\S]*travelApplicationRequest\.expenseType[\s\S]*travelApplicationRequest\.expenseTypeLabel[\s\S]*travelApplicationRequest\.sourceText[\s\S]*ontologyFields:\s*travelApplicationRequest\.ontologyFields[\s\S]*autoSubmit:\s*travelApplicationRequest\.autoSubmit/
|
||||
)
|
||||
assert.doesNotMatch(personalWorkbenchAiModeScript, /fallbackIntentPlan/)
|
||||
assert.match(applicationPreviewFlowScript, /if \(options\.autoSubmit && normalizeApplicationPreview\(preview\)\.readyToSubmit\)/)
|
||||
assert.match(applicationPreviewFlowScript, /confirmed:\s*true/)
|
||||
assert.match(applicationPreviewFlowScript, /skipUserMessage:\s*true/)
|
||||
})
|
||||
|
||||
test('unsupported business guidance opens in assistant conversation form', () => {
|
||||
const conversation = buildUnsupportedBusinessScopeConversation('你好')
|
||||
|
||||
@@ -366,6 +403,20 @@ test('application preview renders ordered editable rows and submit text uses edi
|
||||
assert.match(buildApplicationPreviewSubmitText(editedPreview), /系统预估费用:1900元/)
|
||||
})
|
||||
|
||||
test('application preview keeps compact direct-submit command out of business reason', () => {
|
||||
const preview = buildInlineApplicationPreview(
|
||||
'差旅费',
|
||||
'去上海出差,辅助国网仿生产服务器部署,交通火车,直接提交',
|
||||
{ grade: 'P5' }
|
||||
)
|
||||
|
||||
assert.equal(preview.fields.location, '上海')
|
||||
assert.equal(preview.fields.reason, '辅助国网仿生产服务器部署')
|
||||
assert.equal(preview.fields.transportMode, '火车')
|
||||
assert.equal(preview.readyToSubmit, false)
|
||||
assert.deepEqual(preview.missingFields, ['出发时间', '天数'])
|
||||
})
|
||||
|
||||
test('application estimate builds deterministic mock transport amount and total', () => {
|
||||
const trainEstimate = buildMockApplicationTransportEstimate({ transportMode: '高铁', location: '上海' })
|
||||
const datedTrainEstimate = buildMockApplicationTransportEstimate({
|
||||
|
||||
Reference in New Issue
Block a user