Files
PRA-only-demo/src/shared/types.ts
T

289 lines
5.9 KiB
TypeScript

export type CatalogWidget =
| "text"
| "textarea"
| "number"
| "select"
| "radio"
| "boolean"
| "file"
| "folder"
| "element"
| "code"
| "secret"
| "region"
| "hidden";
export interface CatalogField {
key: string;
label: string;
widget: CatalogWidget;
type: "string" | "number" | "boolean" | "object";
displayType: string;
required: boolean;
defaultValue: string;
placeholder: string;
description: string;
advanced: boolean;
valueTypes: string[];
/** 下拉/单选选项:字符串(显示=存储值)或 { label, value }(显示与存储分离) */
options?: Array<string | { label: string; value: string }>;
unit?: string;
}
export interface CatalogOutput {
label: string;
key: string;
suggestedName: string;
valueTypes: string[];
fields: Array<{ key: string; label: string; defaultValue: string; valueTypes: string[] }>;
}
export interface CatalogComponent {
id: string;
name: string;
kind: "vendor" | "native" | "trigger";
group: string;
categories: string[];
categorySignature: string;
description: string;
messageTemplate: string;
baseType: string;
functionName: string;
functionCalls: Array<{ function: string; args: string[]; assignTo: string }>;
version: string;
tags: string[];
platformTag: string | null;
icon: string;
risk: "low" | "high";
fields: CatalogField[];
output: CatalogOutput;
slots: string[];
nodeKind?: string;
/** 同名旧版本 / 重复别名指向的保留能力 ID。 */
duplicateOf?: string;
}
export interface CatalogGroup {
id: string;
label: string;
icon: string;
count: number;
}
export interface Catalog {
schemaVersion: number;
generatedAt: string;
counts: {
total: number;
vendor: number;
native: number;
triggers: number;
fields: number;
};
groups: CatalogGroup[];
components: CatalogComponent[];
}
export interface FlowVariable {
name: string;
type: string;
defaultValue?: string;
description?: string;
scope?: "flow" | "local";
}
export interface FlowNodeOptions {
outputVar?: string;
delayBeforeMs?: number;
delayAfterMs?: number;
timeoutMs?: number;
retryCount?: number;
retryIntervalMs?: number;
skipOnError?: boolean;
logException?: boolean;
errorRouteEnabled?: boolean;
}
export interface FlowNode {
id: string;
componentId: string;
label?: string;
position: { x: number; y: number };
values: Record<string, unknown>;
options: FlowNodeOptions;
parentId?: string | null;
slot?: string;
enabled?: boolean;
width?: number;
height?: number;
}
export interface FlowEdge {
id: string;
source: string;
target: string;
sourceHandle?: string | null;
targetHandle?: string | null;
label?: string;
}
export interface FlowDefinition {
schemaVersion: 1;
id: string;
name: string;
description?: string;
enabled?: boolean;
trigger?: {
type: "manual" | "schedule" | "file";
label: string;
};
variables: FlowVariable[];
nodes: FlowNode[];
edges: FlowEdge[];
meta: {
createdAt: string;
updatedAt: string;
appVersion: string;
};
}
export interface FlowSaveOptions {
/** 编辑器加载任务时磁盘上的 updatedAt,用于外部修改冲突检测 */
expectedUpdatedAt?: string;
/** 为 true 时跳过冲突检测,强制覆盖磁盘 */
force?: boolean;
}
export type FlowSaveResult =
| { conflict: false; flow: FlowDefinition }
| { conflict: true; diskFlow: FlowDefinition };
export interface FlowSummary {
id: string;
name: string;
updatedAt: string;
nodeCount: number;
enabled?: boolean;
triggerLabel?: string;
lastRunAt?: string;
lastRunStatus?: "succeeded" | "failed" | "cancelled" | "never";
lastRunDurationMs?: number;
lastRunError?: string;
}
export interface AppInfo {
version: string;
electron: string;
chrome: string;
node: string;
userData: string;
catalogPath: string;
packaged: boolean;
fixtureUrl?: string;
}
export interface AiServiceConfig {
baseUrl: string;
apiKey: string;
model: string;
/** 桌面 AI 拾取使用的视觉模型;留空时复用 model。 */
visionModel?: string;
}
export interface AppSettings {
browserElementWaitMs: number;
aiConfig: AiServiceConfig;
}
export interface ElementPickResult {
selector: string;
tag: string;
id?: string;
className?: string;
name?: string;
type?: string;
placeholder?: string;
label?: string;
text?: string;
value?: string;
url: string;
}
export interface RunNodeState {
nodeId: string;
status: "idle" | "running" | "succeeded" | "failed" | "skipped" | "cancelled";
startedAt?: string;
finishedAt?: string;
durationMs?: number;
output?: unknown;
error?: RunError;
evidence?: string[];
attempt?: number;
}
export interface RunError {
code: string;
reason: string;
recommendation?: string;
location?: { flowId?: string; nodeId?: string; componentId?: string; arg?: string };
detail?: string;
}
export interface RunEvent {
type:
| "run.started"
| "node.started"
| "node.log"
| "node.finished"
| "run.finished"
| "run.total";
runId: string;
nodeId?: string;
level?: "info" | "warn" | "error";
message?: string;
status?: string;
output?: unknown;
error?: RunError;
durationMs?: number;
evidence?: string[];
attempt?: number;
startedAt?: string;
nodeLabel?: string;
total?: number;
}
export interface VisionLabSource {
id: string;
kind: "window" | "screen";
name: string;
thumbnail: string;
icon?: string;
}
export interface VisionLabBox {
x: number;
y: number;
width: number;
height: number;
category: string;
confidence: number;
}
export interface VisionLabDetectRequest {
sourceId: string;
modelPath?: string;
scoreThreshold?: number;
iouThreshold?: number;
}
export interface VisionLabDetection {
image: string;
width: number;
height: number;
boxes: VisionLabBox[];
captureMs: number;
detectMs: number;
modelPath: string;
sourceName: string;
}