Backend:
- config.ts: unified startup env validation (throw on missing critical vars)
- tool-executor: structured logToolCall() JSON, ToolStatus enum (success/partial_success/fallback_success/error), preValidateToolCall() hardcoded guards for ticket_detail/chart_generate, durationMs/inputSummary/resultCount on all execution log entries
- agent.ts: tool selection decision tree, chart-as-default-path prompt rules, source labels [知识库][工单][网络][推断]
- tool-defs.ts: applicable/not-applicable guidance on all 4 tools
- soc-client.ts: sandbox hardening (10k char limit, 15s timeout, output truncation, error classification), config.* accessors
- router.ts: preCheckRoute() rules — TK-xxx/工单/知识库 → enterprise direct; greetings → generalInput
- supervisor/types.ts: removed dead config fields (model/temperature/maxTokens/systemPrompt)
- Remove chat-agent (legacy entry point)
Frontend:
- MessageBubble: source badge rendering [知识库][工单][网络][推断], CitationChip [1][2] → clickable chips
- ThreadSidebar: auto-title from first message, collapsible search, long title truncation
- ToolCallStatus: tool-specific loading labels, collapse-all toggle for multi-tool
- main.tsx: conclusion-first layout (AI text above artifacts), draft persistence, IME fix, auto chip, multi-tool AnalysisBlock container, sort_key ordering, retry via soc:retry-tool
- chart-result: empty guard, chart/table toggle, multi-chart format support
- ticket-summary/knowledge-result: work-card quick actions (prefill with context)
- ActionBar: structured payload {text, taskType, sourceCardId}, source label UI
- index.css: card-enter slide animation, dot-bounce loading
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
27 lines
1.4 KiB
TypeScript
27 lines
1.4 KiB
TypeScript
|
|
const SOURCE_CONFIG: Record<string, { label: string; className: string }> = {
|
|
internal_kb: { label: "内部知识库", className: "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400" },
|
|
ticket_system: { label: "工单系统", className: "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400" },
|
|
external_web: { label: "外部搜索", className: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400" },
|
|
code_execution: { label: "代码执行", className: "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400" },
|
|
generated_doc: { label: "生成文档", className: "bg-cyan-100 text-cyan-700 dark:bg-cyan-900/30 dark:text-cyan-400" },
|
|
inferred: { label: "模型推断", className: "bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-400" },
|
|
};
|
|
|
|
const CONFIDENCE_ICON: Record<string, string> = { high: "●", medium: "○", low: "!" };
|
|
|
|
interface SourceBadgeProps {
|
|
sourceType?: string;
|
|
confidence?: "high" | "medium" | "low";
|
|
}
|
|
|
|
export function SourceBadge({ sourceType = "inferred", confidence = "high" }: SourceBadgeProps) {
|
|
const config = SOURCE_CONFIG[sourceType] ?? SOURCE_CONFIG.inferred;
|
|
return (
|
|
<span className={`inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded font-medium ${config.className}`}>
|
|
<span className="opacity-60 text-[10px]">{CONFIDENCE_ICON[confidence]}</span>
|
|
{config.label}
|
|
</span>
|
|
);
|
|
}
|