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:
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
buildApplicationTemplatePreview,
|
||||
buildLocalApplicationPreview,
|
||||
buildModelRefinedApplicationPreview,
|
||||
normalizeApplicationPreview
|
||||
} from '../../utils/expenseApplicationPreview.js'
|
||||
import {
|
||||
@@ -187,11 +188,74 @@ export function normalizeInlineApplicationTypeLabel(expenseTypeLabel, fallback =
|
||||
return `${label}申请`
|
||||
}
|
||||
|
||||
export function buildInlineApplicationPreview(expenseTypeLabel, sourceText = '', currentUser = {}) {
|
||||
function buildOntologyTimeRangeFromCanonical(value = '') {
|
||||
const raw = String(value || '').trim()
|
||||
if (!raw) {
|
||||
return {}
|
||||
}
|
||||
const normalized = raw.replace(/\s+/g, ' ')
|
||||
const [startDate, endDate] = normalized
|
||||
.split(/\s*(?:至|到|~|--|—)\s*/)
|
||||
.map((item) => item.trim())
|
||||
.filter(Boolean)
|
||||
if (/^20\d{2}-\d{1,2}-\d{1,2}$/.test(startDate || '')) {
|
||||
return {
|
||||
raw,
|
||||
start_date: startDate,
|
||||
end_date: /^20\d{2}-\d{1,2}-\d{1,2}$/.test(endDate || '') ? endDate : startDate
|
||||
}
|
||||
}
|
||||
return { raw }
|
||||
}
|
||||
|
||||
function buildEntityFromCanonicalField(type, value) {
|
||||
const normalizedValue = String(value || '').trim()
|
||||
if (!type || !normalizedValue) {
|
||||
return null
|
||||
}
|
||||
return {
|
||||
type,
|
||||
value: normalizedValue,
|
||||
normalized_value: normalizedValue
|
||||
}
|
||||
}
|
||||
|
||||
function buildApplicationOntologyFromCanonicalFields(fields = {}) {
|
||||
const source = fields && typeof fields === 'object' ? fields : {}
|
||||
const entityKeys = [
|
||||
'expense_type',
|
||||
'location',
|
||||
'reason',
|
||||
'amount',
|
||||
'transport_mode',
|
||||
'customer_name',
|
||||
'merchant_name',
|
||||
'department_name',
|
||||
'employee_name',
|
||||
'employee_no'
|
||||
]
|
||||
return {
|
||||
parse_strategy: 'llm_primary',
|
||||
time_range: buildOntologyTimeRangeFromCanonical(source.time_range),
|
||||
entities: entityKeys
|
||||
.map((key) => buildEntityFromCanonicalField(key, source[key]))
|
||||
.filter(Boolean)
|
||||
}
|
||||
}
|
||||
|
||||
export function buildInlineApplicationPreview(expenseTypeLabel, sourceText = '', currentUser = {}, options = {}) {
|
||||
const rawText = String(sourceText || '').trim()
|
||||
const preview = rawText
|
||||
const basePreview = rawText
|
||||
? buildLocalApplicationPreview(rawText, currentUser)
|
||||
: buildApplicationTemplatePreview(currentUser)
|
||||
const preview = options.ontologyFields && typeof options.ontologyFields === 'object'
|
||||
? buildModelRefinedApplicationPreview(
|
||||
basePreview,
|
||||
buildApplicationOntologyFromCanonicalFields(options.ontologyFields),
|
||||
rawText,
|
||||
currentUser
|
||||
)
|
||||
: basePreview
|
||||
const normalized = normalizeApplicationPreview(preview)
|
||||
return normalizeApplicationPreview({
|
||||
...normalized,
|
||||
|
||||
Reference in New Issue
Block a user