import { useCallback, useEffect, useRef, useState } from 'react'; import { ArrowDown, ArrowRight, ArrowUp, ChevronDown, Download, FileText, Globe, Hand, LoaderCircle, PanelRight, Pencil, Plus, Radar, Search, Settings, Sparkles, Square, ThumbsDown, ThumbsUp, X, Zap } from 'lucide-react'; import { api, errorText } from './api'; import { BrowserPanel } from './components/BrowserPanel'; import { SettingsDialog } from './components/SettingsDialog'; import { OutreachPlan, type OutreachRequest } from './components/OutreachPlan'; import { SparkMark, ParticleCompanion } from './components/ParticleCompanion'; import { MotionAssembly } from './components/MotionAssembly'; import { ConversationParticles } from './components/ConversationParticles'; import { ClarificationCard, ClarificationHistory, DeliveryFilesCard, DeliveryStatusCard, LeadResults, PhaseCard, RecoveryCard, UsageCard } from './components/SceneCards'; import { KnowledgePanel } from './components/KnowledgePanel'; import { WindowTitleBar } from './components/WindowTitleBar'; import { type BrowserViewState, type BusinessOutcomeValue, type ChatMessage, type KnowledgeMethods, type Meta, type ExportFile, type RecoveryRoute, type Task, type TaskSummary } from './types'; import { displayTime, feedbackOf, messagesOf, statusLabel, stopReasonText } from './taskView'; const KNOWLEDGE_ID = 'xiaohongshu_prospecting'; const ACTIVE = new Set(['running', 'paused']); const STAGE_LABEL: Record = { brief: '理解你的目标', intent: '理解你的目标', model_setup: '等待模型配置', waiting: '等待浏览器', search_read: '搜索与阅读', source_capture: '保存页面来源', login_or_question: '等待登录或回答', analyze: '分析需求', results: '阶段结果', partial_results: '阶段结果', stage_result: '阶段结果', stage_results: '阶段结果', stopped: '已停止', interrupted: '执行中断', budget: '历史任务中断', export: '整理名单', follow: '核对关注状态', message: '跟进消息', learning: '整理操作经验', outreach_authorization: '核对跟进范围', export_ready: '名单已就绪', checkpoint: '核对执行进度', }; const SUGGESTIONS = [ '我做杭州装修,帮我找最近准备装修的人,整理一份名单。', '帮我分析一篇小红书笔记和评论里的真实需求。', '继续之前的线索,先核对账号信息,再整理导出。', ]; function asText(value: unknown): string { return typeof value === 'string' ? value : ''; } function stringList(value: unknown): string[] { return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : []; } function PlanCard({ task, onEdit }: { task: Task; onEdit: () => void }) { const plan = task.artifacts.plan; const keywords = stringList(task.inputs.keywords); const stages = stringList(plan?.stages); const missing = task.ui?.clarification ? [] : stringList(plan?.missing); const assumptions = stringList(plan?.assumptions); return
我理解的目标

{asText(plan?.summary) || asText(task.inputs.goal) || '查看已有任务条件'}

{task.ui?.goal_progress?.target != null &&

本次目标:整理 {task.ui.goal_progress.target} 位满足必要条件的去重候选。字段证据分别说明。

} {stages.length > 0 &&
    {stages.map((stage, index) =>
  1. {index + 1}{stage}
  2. )}
} {(keywords.length > 0 || asText(task.inputs.region)) &&
{keywords.map(keyword => {keyword})}{asText(task.inputs.region) && {asText(task.inputs.region)}}
} {assumptions.length > 0 &&

待核实的理解:{assumptions.join(';')}

} {missing.length > 0 &&

还需要了解:{missing.join(';')}

}
; } function TaskFeedback({ task, busy, onFeedback }: { task: Task; busy: boolean; onFeedback: (rating: 'up' | 'down', reason?: string) => Promise }) { const current = feedbackOf(task); const [showReason, setShowReason] = useState(false); const [reason, setReason] = useState(''); const [sent, setSent] = useState(false); const reasons = ['人群不对', '没有真实需求', '任务没完成', '过程太慢']; return
这次结果有帮助吗? {current && 已记录评价}

评价记录本次结果的满意度,不自动增加方法的技术成功次数。

{showReason &&
{reasons.map(value => )}