448 lines
12 KiB
TypeScript
448 lines
12 KiB
TypeScript
export type TaskStatus =
|
|
| 'collecting'
|
|
| 'running'
|
|
| 'paused'
|
|
| 'submitted'
|
|
| 'completed'
|
|
| 'failed'
|
|
| 'blocked'
|
|
| 'rejected'
|
|
| 'cancelled';
|
|
|
|
export const STATUS_LABEL: Record<TaskStatus, string> = {
|
|
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<Record<'success' | 'contradiction' | 'blocked' | 'program_error' | 'unknown' | 'unused' | 'independent_tasks' | 'independent_objects' | 'coverage_tasks' | 'coverage_objects', number | null>>;
|
|
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<string, string[]>;
|
|
}
|
|
|
|
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<string, string> = {
|
|
control_tip: '控件技巧',
|
|
path: '入口路径',
|
|
rule: '系统规则',
|
|
note: '其他',
|
|
};
|