export type TaskStatus = | 'collecting' | 'running' | 'paused' | 'submitted' | 'completed' | 'failed' | 'blocked' | 'rejected' | 'cancelled'; export const STATUS_LABEL: Record = { collecting: '等待补充信息', running: '正在执行', paused: '等待你的回答', submitted: '已提交', completed: '已完成', failed: '未完成', blocked: '需要处理', rejected: '已驳回', cancelled: '已停止', }; export const TERMINAL_STATUSES: TaskStatus[] = ['submitted', 'completed', 'failed', 'blocked', 'rejected', 'cancelled']; export interface TaskSummary { id: string; status: TaskStatus; current_step: string | null; goal: string; business_name: string | null; created_at: string; updated_at: string; next_check_at: string | null; } export interface PendingBlocker { id: string; title?: string; resolution?: string; message?: string; advice?: string; } export interface TrackingEntry { at: string; status: string; verdict: string; note: string; } export interface TrackingState { checks: number; history: TrackingEntry[]; max_checks?: number; } export interface TaskInputs { goal?: string; business_id?: string; pending_blocker?: PendingBlocker; [key: string]: unknown; } export interface TaskArtifacts { summary?: string; tracking?: TrackingState; leads?: ProspectLead[]; coverage_note?: string; browser_summary?: string; messages?: ChatMessage[]; plan?: { summary?: string; stages?: string[]; missing?: string[]; assumptions?: string[] }; stop_reason?: string | { code?: string; message?: string }; stop_detail?: string; feedback?: TaskFeedbackValue | TaskFeedbackValue[]; business_outcomes?: BusinessOutcomeEvent[]; alternatives?: (string | RecoveryRoute)[]; exports?: ExportFile[]; [key: string]: unknown; } export interface TaskFeedbackValue { rating: 'up' | 'down'; reason?: string; at?: string; result_version?: string | number; } export type BusinessOutcomeValue = 'replied' | 'need_confirmed' | 'cooperated' | 'no_reply' | 'not_relevant'; export interface BusinessOutcomeEvent { id: string; source_id: string; outcome: BusinessOutcomeValue; note?: string; at?: string; source: 'user'; attribution?: string; } export interface Task { id: string; status: TaskStatus; current_step: string | null; inputs: TaskInputs; artifacts: TaskArtifacts; pause_reason: string | null; next_check_at: string | null; created_at: string; updated_at: string; business_name?: string | null; reply?: string | null; latest_screenshot?: string | null; live_session?: boolean; takeover?: boolean; progress_doc_path?: string | null; needs_input?: string[]; ui?: TaskUi; } export interface ClarificationField { id: string; key: 'product' | 'target_customer' | 'region' | 'action_scope' | 'message_text' | 'target_candidates' | 'context'; label: string; input_kind: 'text' | 'textarea' | 'number'; required: boolean; prefill: string; options: string[]; min?: number; step?: number; } export interface Clarification { id: string; goal_version: number; status: 'active'; fields: ClarificationField[]; } export interface PhaseState { id: string; title: string; status: TaskStatus; current_step: string; detail: string; counts: { notes: number; comments: number; replies: number; profiles: number; leads: number }; events: { id: string; title: string; status: string; detail: string; at: string | null }[]; coverage: { observed_keywords: string[]; pending_keywords: string[] }; stages: string[]; } export interface ExportFile { id: string; path: string; filename: string; count: number; format: 'csv'; generated_at: string; result_version: string; goal_version: number; download_url: string; is_current: boolean; available?: boolean; } export interface RecoveryRoute { id?: 'review' | 'export'; title: string; reason?: string; description?: string; deliverable?: string; status?: string; action?: 'review_saved' | 'export'; enabled?: boolean; disabled_reason?: string; message?: string; prompt?: string; } export interface TaskUi { version: 1; goal_version: number; result_version: string; clarification: Clarification | null; phase: PhaseState; delivery: { result_version: string; goal_version: number; lead_count: number; source_count: number; exports: ExportFile[] }; recovery: { reason: string; detail: string; routes: RecoveryRoute[]; underlying_reason?: string; underlying_detail?: string } | null; goal_progress?: GoalProgress; delivery_status?: DeliveryStatus; usage?: ModelUsage; } export interface EvidenceBadge { status: string; label: string; detail?: string; evidence?: { source_id?: string; quote?: string }[]; source_ids?: string[]; } export interface CandidateBadges { demand: EvidenceBadge; identity: EvidenceBadge; region: EvidenceBadge; account: EvidenceBadge; outreach: EvidenceBadge; business?: EvidenceBadge; } export interface CandidateMissingField { key: string; label: string; required?: boolean; } export interface DeliveryPerson { person_key: string; eligible: boolean; group: 'eligible' | 'supplemental' | 'unresolved'; badges: CandidateBadges; missing: (string | CandidateMissingField)[]; } export interface PreflightSummary { version: 1; completed: boolean; run_available: boolean; recorded: boolean; visited_known: boolean; inspected_notes: number; visited_notes: number; checked_count: number; eligible_count: number; classification_counts: { unique_dom_deep_reply: number; needs_native_identity: number; ambiguous: number; unknown: number }; not_in_view_notes: number; unknown_notes: number; folded_notes: number; folded_unknown_notes: number; scope_passed: boolean | null; history_truncated: boolean; max_notes: number | null; unknown_click_blocked_count: number; headline: string; detail: string; notes: { ordinal: number; inspected: boolean; status: 'inspected' | 'not_in_view' | 'unknown'; checked_count: number; eligible_count: number; has_unexpanded_replies: boolean | null }[]; } export interface DeliveryStatus { version: 1; status: 'fulfilled' | 'partial' | 'in_progress' | 'no_evidence' | 'no_matches' | 'unknown'; headline: string; runtime: { status: string; step?: string; stop_reason?: unknown; stop_detail?: string; raw_browser_success?: boolean | null }; fulfillment: { scope_met: boolean; requirements_met: boolean; complete: boolean; assessment_current: boolean; target: number | null; current: number; remaining: number | null }; artifacts: { list_available: boolean; file_required: boolean; file_available: boolean; delivered: boolean; export_count: number }; counts: { eligible: number; known_identity: number; supplemental: number; unresolved: number; signals: number; verified_accounts: number }; conditions: { key: string; label: string; required: boolean; met: boolean; current?: number | null; target?: number | null }[]; people: DeliveryPerson[]; preflight?: PreflightSummary; } export interface CandidateGroup { person_key: string; source_ids: string[]; representative: ProspectLead; evidence: ProspectLead[]; identity_status: 'source_link' | 'profile_verified' | 'unresolved'; account_verified: boolean; eligible?: boolean; group?: DeliveryPerson['group']; badges?: CandidateBadges; missing?: DeliveryPerson['missing']; } export interface GoalProgress { scope: 'candidate_count' | 'route_pass'; target: number | null; current: number; remaining: number | null; reached: boolean; scope_note?: string; assessment_current?: boolean; groups: CandidateGroup[]; counts: { candidates: number; signals: number; unresolved_sources: number; verified_accounts: number; eligible?: number; supplemental?: number }; } export interface ModelUsageTotals { requests: number; input_tokens: number | null; output_tokens: number | null; total_tokens: number | null; cache_hit_tokens: number | null; cache_miss_tokens: number | null; unknown_usage_requests: number; incomplete_usage_requests: number; parse_failed_requests: number; failed_requests: number; pending_requests: number; } export interface ModelUsage extends ModelUsageTotals { version: 1; legacy_incomplete: boolean; recorded_since: string | null; coverage: 'recorded_calls_only'; ledger_error?: boolean; models?: string[]; phases: (ModelUsageTotals & { phase: string })[]; } export interface LearnedEntry { id: number; key: string; value: string; category: string; observations: number; status: string; } export type KnowledgeMethodStatus = 'preferred' | 'trial' | 'exploration' | 'paused' | 'legacy'; export interface KnowledgeMethod { id: string; key: string; title: string; version: string | number; kind: string; status: KnowledgeMethodStatus; capability?: string; source_kind?: string; platform?: string; stage?: string; page_variant?: string; match_reasons: string[]; applicability: boolean; stats: Partial>; last_validation: { at?: string; outcome?: string; reason?: string; verifier?: string; event_id?: string; task_id?: string } | null; evidence_refs: { task_id?: string; event_id?: string; pre?: string | string[]; post?: string | string[]; action_id?: string }[]; provenance: string; steps?: unknown; expected_result?: unknown; recovery?: unknown; dependencies?: (string | { id?: string; key?: string; version?: string | number })[]; preconditions?: unknown; parameters?: unknown; historical_unverified?: boolean; } export interface KnowledgeMethods { methods: KnowledgeMethod[]; selected_ids: string[]; policy: { version?: string; [key: string]: unknown }; } export interface ValidationProof { id: string; capability: string; outcome: string; verifier: string; observed_at: string; pre: unknown; post: unknown; } export interface LlmStatus { provider: string; model: string; api_key_set: boolean; fallback_configured: boolean; using_fallback: boolean; primary_exhausted_at: string | null; retry_hours: number; } export interface Meta { pid: number; version: string; operator_mode: boolean; embedded: boolean; school_id: string; tracking: { enabled: boolean; poll_seconds: number }; llm?: LlmStatus; product?: string; } export interface ProspectLead { id?: string; source_id?: string; source_type: 'note' | 'comment' | 'reply'; source_url: string; quote: string; reason: string; author?: string; profile_url?: string; xiaohongshu_id?: string; account_id?: string; correction?: string | { text: string }; observed_at?: string; seeking_service?: 'yes' | 'no' | 'unknown'; region_match?: 'yes' | 'no' | 'unknown'; region_quote?: string; status: 'pending'; } export interface ProspectingInputs { product: string; target_customer: string; keywords: string[]; region: string | null; max_notes?: number | null; max_comments_per_note?: number | null; use_web_search: boolean; user_notes: string; } export interface SettingsInfo { llm_provider: string; llm_api_key_set: boolean; fallback_key_set?: boolean; using_fallback?: boolean; llm_model: string; llm_base_url: string; providers: string[]; models_by_provider: Record; } export type MessageRole = 'user' | 'assistant' | 'system'; export interface ChatMessage { id: string; role: MessageRole; text: string; } export interface BrowserViewState { taskId: string; url: string; title: string; loading: boolean; mode: 'agent' | 'user'; } export const CATEGORY_LABEL: Record = { control_tip: '控件技巧', path: '入口路径', rule: '系统规则', note: '其他', };