@yiyi_zhang/reactflow-ui 0.4.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +140 -101
  2. package/dist/AiWorkflowIDE.d.ts +219 -0
  3. package/dist/WorkflowIDE.d.ts +4 -4
  4. package/dist/ai.d.ts +34 -0
  5. package/dist/components/AICopilot/ParameterSuggester.d.ts +9 -0
  6. package/dist/components/AiNative/AgentTimeline.d.ts +23 -0
  7. package/dist/components/AiNative/AiCommandCenter.d.ts +40 -0
  8. package/dist/components/AiNative/AiConfigPanel.d.ts +9 -0
  9. package/dist/components/AiNative/BusinessCanvas.d.ts +15 -0
  10. package/dist/components/AiNative/CanvasPreview.d.ts +16 -0
  11. package/dist/components/AiNative/ClarificationCard.d.ts +9 -0
  12. package/dist/components/AiNative/FailureSummaryCard.d.ts +20 -0
  13. package/dist/components/AiNative/InlineCanvasCopilot.d.ts +7 -0
  14. package/dist/components/AiNative/LibraryPanel.d.ts +9 -0
  15. package/dist/components/AiNative/MermaidBlock.d.ts +6 -0
  16. package/dist/components/AiNative/PlanCard.d.ts +15 -0
  17. package/dist/components/AiNative/ProposalPreviewCard.d.ts +21 -0
  18. package/dist/components/AiNative/RecommendationCard.d.ts +10 -0
  19. package/dist/components/AiNative/RepairCard.d.ts +17 -0
  20. package/dist/components/AiNative/ReviewBar.d.ts +21 -0
  21. package/dist/components/AiNative/WorkflowRunCard.d.ts +14 -0
  22. package/dist/components/BrandLogo.d.ts +13 -0
  23. package/dist/components/Controls/ModeSlider.d.ts +2 -0
  24. package/dist/components/ExecutionWaterfallPanel.d.ts +3 -0
  25. package/dist/components/SandboxConfigModal.d.ts +7 -0
  26. package/dist/components/StructuredJsonViewer.d.ts +11 -0
  27. package/dist/components/nodes/NodeLayout.d.ts +3 -1
  28. package/dist/components/nodes/NodeWrapper.d.ts +2 -1
  29. package/dist/hooks/useNodeExecution.d.ts +5 -2
  30. package/dist/hooks/useNodeLayout.d.ts +1 -1
  31. package/dist/index.d.ts +5 -1
  32. package/dist/logo.svg +37 -0
  33. package/dist/product-launch.html +1400 -0
  34. package/dist/reactflow-ui-ai.es.js +21433 -0
  35. package/dist/reactflow-ui.css +1 -1
  36. package/dist/reactflow-ui.es.js +12482 -8252
  37. package/dist/reactflow-ui.umd.js +38 -20
  38. package/dist/services/ai/agentRunner.d.ts +55 -0
  39. package/dist/services/ai/contextEngine.d.ts +83 -0
  40. package/dist/services/ai/draftPersistence.d.ts +23 -0
  41. package/dist/services/ai/errorMessages.d.ts +16 -0
  42. package/dist/services/ai/intentClassifier.d.ts +17 -0
  43. package/dist/services/ai/protocolAdapter.d.ts +114 -0
  44. package/dist/services/ai/ruleEngine.d.ts +57 -0
  45. package/dist/services/ai/schemaRegistry.d.ts +51 -0
  46. package/dist/services/ai/systemPrompt.d.ts +30 -0
  47. package/dist/services/ai/toolDefs.d.ts +9 -0
  48. package/dist/services/ai/toolExecutor.d.ts +96 -0
  49. package/dist/services/ai/toolRegistry.d.ts +38 -0
  50. package/dist/services/ai/transport.d.ts +58 -0
  51. package/dist/services/ai/workflowSynthesizer.d.ts +118 -0
  52. package/dist/services/aiService.d.ts +7 -5
  53. package/dist/services/wlsp/workflowLsp.d.ts +101 -0
  54. package/dist/store/aiStore.d.ts +230 -0
  55. package/dist/store/ideStoresContext.d.ts +39 -0
  56. package/dist/store/libraryStore.d.ts +25 -0
  57. package/dist/types/aiEvents.d.ts +40 -0
  58. package/dist/types/conductor.d.ts +6 -1
  59. package/dist/types/workflow.d.ts +43 -0
  60. package/dist/types/workflowLibrary.d.ts +27 -0
  61. package/dist/utils/localSandboxEngine.d.ts +49 -0
  62. package/dist/utils/nodeMeta.d.ts +6 -0
  63. package/dist/utils/proposalPreview.d.ts +19 -0
  64. package/dist/utils/taskTypeMeta.d.ts +18 -0
  65. package/dist/utils/workflowToMermaid.d.ts +7 -0
  66. package/package.json +19 -6
@@ -0,0 +1,58 @@
1
+ /**
2
+ * AI Transport — 传输层反转
3
+ *
4
+ * 背景:默认的 direct 模式让 API Key 直接留存在终端用户浏览器中,直连大模型服务商
5
+ * (参见 protocolAdapter.ts 的 streamOpenAI/streamAnthropic)。这仅适合开发调试,
6
+ * 生产环境应通过集成方自己的后端转发模型请求,密钥、计费、限流、审计都留在后端完成。
7
+ *
8
+ * 本文件提供两种反转方案:
9
+ * - `endpoint`:把统一的 AgentRequest POST 给集成方后端,后端以 SSE 帧协议回传 StreamEvent。
10
+ * 后端参考实现(Node/Express,约 30 行):
11
+ *
12
+ * ```js
13
+ * app.post('/api/ai/chat', async (req, res) => {
14
+ * res.setHeader('Content-Type', 'text/event-stream');
15
+ * res.setHeader('Cache-Control', 'no-cache');
16
+ * res.setHeader('Connection', 'keep-alive');
17
+ * // req.body = { messages, tools, meta } —— 按需转发给 OpenAI/Anthropic,
18
+ * // 或直接复用本仓库的 streamOpenAI/streamAnthropic 实现(Node 端可直接 import 使用)。
19
+ * for await (const event of callYourLlmProvider(req.body)) {
20
+ * res.write(`data: ${JSON.stringify(event)}\n\n`);
21
+ * }
22
+ * res.end();
23
+ * });
24
+ * ```
25
+ *
26
+ * - `custom`:完全自定义的流式函数,适合已有网关/SDK 的集成方直接接入。
27
+ *
28
+ * 不设置 `transport` 时,AiConfig 的 provider/apiKey/baseUrl/model 视为 direct 模式
29
+ * (向后兼容现状),仅建议用于开发调试或内部可信环境。
30
+ */
31
+ import type { Message, ToolDef, StreamEvent } from './protocolAdapter';
32
+ /** endpoint / custom 传输统一入参:与 direct 模式内部构造的请求体等价 */
33
+ export interface AgentRequest {
34
+ messages: Message[];
35
+ tools: ToolDef[];
36
+ meta?: {
37
+ sessionId?: string;
38
+ };
39
+ }
40
+ export type AiTransport = {
41
+ type: 'endpoint';
42
+ /** 集成方后端代理地址,POST AgentRequest,响应为 `data: <JSON StreamEvent>\n\n` 的 SSE 流 */
43
+ url: string;
44
+ /** 附加请求头(如后端会话鉴权 Cookie/Token 之外的自定义头) */
45
+ headers?: Record<string, string>;
46
+ } | {
47
+ type: 'custom';
48
+ /** 完全自定义的流式实现,直接产出统一的 StreamEvent */
49
+ stream: (req: AgentRequest, signal: AbortSignal) => AsyncIterable<StreamEvent>;
50
+ };
51
+ /**
52
+ * endpoint 模式:POST AgentRequest,解析 SSE 帧(`data: <JSON>\n\n`)为 StreamEvent。
53
+ * 帧解析逻辑与 protocolAdapter 的 OpenAI/Anthropic 流解析一致地处理跨 chunk 边界,
54
+ * 避免 JSON 被截断在两次 read() 之间。
55
+ */
56
+ export declare function streamEndpoint(transport: Extract<AiTransport, {
57
+ type: 'endpoint';
58
+ }>, req: AgentRequest, signal?: AbortSignal): AsyncGenerator<StreamEvent>;
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Workflow Synthesizer & Deep Semantic Verifier
3
+ *
4
+ * Implements the 4-phase progressive workflow generation strategy:
5
+ * Phase 1 (blueprint): init_workflow_blueprint — Define workflow metadata, input/output contracts, timeout & resilience policy
6
+ * Phase 2 (topology): scaffold_workflow_topology — Design overall task orchestration topology & control flow (SWITCH/FORK_JOIN/DO_WHILE)
7
+ * Phase 3 (configure): configure_workflow_tasks — Enrich individual tasks with detailed parameters, HTTP/SubWorkflow configs & data-flow wiring
8
+ * Phase 4 (verify): commit_workflow_proposal — Holistic semantic, control-flow, and data-flow verification before committing proposal
9
+ */
10
+ import type { WorkflowDef, TaskDef } from '../../types/conductor';
11
+ import type { ValidationItem } from '../../types/workflow';
12
+ export type SynthesisPhase = 'idle' | 'blueprint' | 'topology' | 'configure' | 'verify' | 'completed';
13
+ export interface BlueprintArgs {
14
+ name: string;
15
+ description?: string;
16
+ version?: number;
17
+ ownerEmail?: string;
18
+ timeoutPolicy?: 'TIME_OUT_WF' | 'ALERT_ONLY';
19
+ timeoutSeconds?: number;
20
+ failureWorkflow?: string;
21
+ inputParameters?: string[];
22
+ outputParameters?: Record<string, any>;
23
+ }
24
+ export interface TopologyArgs {
25
+ tasks: TaskDef[];
26
+ }
27
+ export interface TaskConfigurationItem {
28
+ /** Target taskReferenceName */
29
+ ref: string;
30
+ name?: string;
31
+ description?: string;
32
+ inputParameters?: Record<string, any>;
33
+ httpRequest?: Record<string, any>;
34
+ subWorkflowParam?: {
35
+ name: string;
36
+ version?: number;
37
+ taskToDomain?: Record<string, string>;
38
+ };
39
+ timeoutSeconds?: number;
40
+ retryCount?: number;
41
+ retryLogic?: 'FIXED' | 'EXPONENTIAL_BACKOFF' | 'LINEAR_BACKOFF';
42
+ retryDelaySeconds?: number;
43
+ optional?: boolean;
44
+ caseValueParam?: string;
45
+ caseExpression?: string;
46
+ loopCondition?: string;
47
+ joinOn?: string[];
48
+ dynamicForkTasksParam?: string;
49
+ dynamicForkTasksInputParamName?: string;
50
+ }
51
+ export interface ConfigureTasksArgs {
52
+ configurations: TaskConfigurationItem[];
53
+ outputParameters?: Record<string, any>;
54
+ inputParameters?: string[];
55
+ }
56
+ export interface VerificationSummary {
57
+ isValid: boolean;
58
+ totalTasks: number;
59
+ configuredTasks: number;
60
+ dataFlowLinks: number;
61
+ autoFixed: string[];
62
+ errors: ValidationItem[];
63
+ warnings: ValidationItem[];
64
+ }
65
+ /**
66
+ * Collects all tasks in execution order (pre-order traversal of top-level and nested tasks).
67
+ */
68
+ export declare function collectAllTasksInOrder(tasks?: TaskDef[]): TaskDef[];
69
+ /**
70
+ * Normalizes a single task's structure to prevent common LLM schema mismatches:
71
+ * - Ensures `name` and `taskReferenceName` and `type` exist
72
+ * - Normalizes `HTTP` task `httpRequest` / `inputParameters.uri` into `inputParameters.http_request`
73
+ * - Normalizes `SUB_WORKFLOW` `workflowName` into `subWorkflowParam.name`
74
+ * - Normalizes `TERMINATE` `terminationStatus` into `inputParameters.terminationStatus`
75
+ */
76
+ export declare function normalizeTaskDef(task: TaskDef, autoFixed?: string[]): TaskDef;
77
+ /**
78
+ * Extracts all `${...}` expressions from an arbitrary JSON value.
79
+ */
80
+ export declare function extractExpressions(value: any): string[];
81
+ /**
82
+ * Normalizes an entire WorkflowDef:
83
+ * - Ensures `version: 1`, `schemaVersion: 2`, `timeoutPolicy`
84
+ * - Normalizes all tasks and FORK_JOIN <-> JOIN pairings
85
+ * - Auto-collects `${workflow.input.xxx}` into `workflow.inputParameters` if missing
86
+ */
87
+ export declare function normalizeWorkflowDef(def: WorkflowDef): {
88
+ workflow: WorkflowDef;
89
+ autoFixed: string[];
90
+ };
91
+ /**
92
+ * Phase 1: Initializes the workflow blueprint (metadata + input/output contract).
93
+ */
94
+ export declare function applyBlueprint(currentDraft: WorkflowDef | null, args: BlueprintArgs): WorkflowDef;
95
+ /**
96
+ * Phase 2: Scaffolds the task orchestration topology on top of the blueprint.
97
+ */
98
+ export declare function applyTopologyScaffold(currentDraft: WorkflowDef | null, args: TopologyArgs): {
99
+ workflow: WorkflowDef;
100
+ autoFixed: string[];
101
+ };
102
+ /**
103
+ * Phase 3: Enriches individual tasks in the working draft with detailed configurations.
104
+ */
105
+ export declare function applyTaskConfigurations(currentDraft: WorkflowDef, args: ConfigureTasksArgs): {
106
+ workflow: WorkflowDef;
107
+ configuredRefs: string[];
108
+ missingRefs: string[];
109
+ autoFixed: string[];
110
+ };
111
+ /**
112
+ * Performs comprehensive verification of a workflow definition:
113
+ * 1. Built-in structural & task-type rules (`validateWorkflow`)
114
+ * 2. Data-flow reference integrity (`${taskRef.output.*}` must reference an existing upstream task)
115
+ * 3. Control-flow completeness (FORK_JOIN <-> JOIN joinOn validity, non-empty branches)
116
+ * 4. Task configuration completeness metrics
117
+ */
118
+ export declare function verifyWorkflowSemantics(def: WorkflowDef, autoFixedPrior?: string[]): VerificationSummary;
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * AI Interaction Service (OpenAI Standard)
3
+ *
4
+ * @deprecated 这是 WorkflowIDE 内置 AI Copilot 的遗留实现(仅 OpenAI 协议、文本解析 diff)。
5
+ * 新代码请使用 `AiConfig` + `services/ai/protocolAdapter`(双协议、原生 tool-call、
6
+ * 传输层反转)。两套实现将在后续版本收敛为一套,详见 `docs/design/` 下的架构规划。
3
7
  */
4
- export interface AIServiceConfig {
5
- apiKey: string;
6
- baseUrl: string;
7
- model: string;
8
- }
8
+ import type { AiConfig } from './ai/protocolAdapter';
9
+ /** @deprecated 使用 `AiConfig`(从 `services/ai/protocolAdapter` 或 `/ai` 入口导入)代替。保留为类型别名以避免破坏现有集成代码。 */
10
+ export type AIServiceConfig = AiConfig;
9
11
  export interface ChatMessage {
10
12
  role: 'system' | 'user' | 'assistant';
11
13
  content: string;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Workflow Language Server (W-LSP)
3
+ *
4
+ * 提供工业级工作流静态分析、DAG 上游作用域推导、多源 Schema 自动推断、
5
+ * 零延迟确定性变量补全(Intellisense)、数据血缘图(DFG)构建与全图引用重构(Auto-Refactor)。
6
+ */
7
+ import { WorkflowDef, TaskDef } from '../../types/conductor';
8
+ import { TaskExecutionData } from '../../types/workflow';
9
+ export type ValueType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'any';
10
+ export interface InferredField {
11
+ /** 字段相对路径,如 "response.body.id" 或 "result" */
12
+ path: string;
13
+ /** 完整 Conductor 引用表达式,如 "${http_get.output.response.body.id}" */
14
+ expression: string;
15
+ /** 推导出的字段类型 */
16
+ valueType: ValueType;
17
+ /** 运行态真实样本值预览(若存在) */
18
+ sampleValue?: string;
19
+ /** 描述说明 */
20
+ description?: string;
21
+ /** Schema 来源 */
22
+ source: 'runtime_sample' | 'schema_registry' | 'task_type_contract';
23
+ }
24
+ export interface WlspCompletionItem {
25
+ /** 展示名称 */
26
+ label: string;
27
+ /** 插入的完整表达式,如 "${fetch_user.output.userId}" */
28
+ value: string;
29
+ /** 分类 */
30
+ category: 'upstream' | 'workflow_input' | 'variable' | 'system';
31
+ /** 数据类型 */
32
+ valueType: ValueType;
33
+ /** 来源任务引用名或分组名 */
34
+ sourceRef: string;
35
+ /** 来源任务显示名称 */
36
+ sourceLabel: string;
37
+ /** 详细描述 */
38
+ description: string;
39
+ /** 运行态或默认值样本预览 */
40
+ sampleValue?: string;
41
+ /** 是否来自条件分支(可能未执行) */
42
+ isConditional?: boolean;
43
+ }
44
+ export interface DataFlowEdge {
45
+ id: string;
46
+ sourceRef: string;
47
+ targetRef: string;
48
+ fieldPath: string;
49
+ expression: string;
50
+ sourceType: 'task_output' | 'workflow_variable';
51
+ isValidUpstream: boolean;
52
+ issue?: 'undefined_ref' | 'forward_ref' | 'sibling_branch_ref';
53
+ }
54
+ export interface DataFlowGraph {
55
+ edges: DataFlowEdge[];
56
+ diagnostics: Array<{
57
+ taskRef: string;
58
+ expression: string;
59
+ issue: 'undefined_ref' | 'forward_ref' | 'sibling_branch_ref';
60
+ message: string;
61
+ }>;
62
+ }
63
+ export interface UpstreamTaskInfo {
64
+ task: TaskDef;
65
+ /** 是否位于条件分支内部(非必经路径) */
66
+ isConditional: boolean;
67
+ }
68
+ /**
69
+ * 精确计算在 targetTaskRef 执行前所有合法的上游祖先节点
70
+ */
71
+ export declare function getUpstreamAncestorsWithMeta(workflowDef: WorkflowDef | null | undefined, targetTaskRef: string): UpstreamTaskInfo[];
72
+ export declare function getUpstreamAncestors(workflowDef: WorkflowDef | null | undefined, targetTaskRef: string): TaskDef[];
73
+ /**
74
+ * 推导单个任务的输出 Schema 字段列表
75
+ */
76
+ export declare function inferTaskOutputSchema(task: TaskDef, executionData?: Record<string, TaskExecutionData> | null): InferredField[];
77
+ /**
78
+ * 为指定目标任务生成零延迟确定性上下文补全项列表
79
+ */
80
+ export declare function getCompletionItems(workflowDef: WorkflowDef | null | undefined, targetTaskRef: string, executionData?: Record<string, TaskExecutionData> | null, workflowInputSample?: Record<string, any> | null): WlspCompletionItem[];
81
+ /**
82
+ * 扁平化获取工作流中的所有任务列表
83
+ */
84
+ export declare function getAllTasksFlat(tasks: TaskDef[] | undefined, acc?: TaskDef[]): TaskDef[];
85
+ /**
86
+ * 构建全图数据血缘依赖图 (DFG) 与编译期静态数据流诊断
87
+ */
88
+ export declare function buildDataFlowGraph(workflowDef: WorkflowDef | null | undefined): DataFlowGraph;
89
+ /**
90
+ * 全图级联重构任务引用名 (Auto-Refactor TaskReferenceName)
91
+ *
92
+ * 当用户在属性面板修改某个节点的 taskReferenceName 时,自动扫描并更新:
93
+ * 1. 所有任务的 inputParameters / httpRequest / expression / loopCondition 中的 ${oldRef.xxx} 和 $.oldRef
94
+ * 2. 所有 JOIN 节点的 joinOn / defaultExclusiveJoinTask 列表
95
+ * 3. 工作流级别的 outputParameters
96
+ */
97
+ export declare function refactorTaskReferenceName(workflowDef: WorkflowDef, oldRef: string, newRef: string): {
98
+ updatedDef: WorkflowDef;
99
+ replacedCount: number;
100
+ affectedTaskRefs: string[];
101
+ };
@@ -0,0 +1,230 @@
1
+ /**
2
+ * AI Store — state management for AI workflow assistant
3
+ *
4
+ * Manages: conversation history, proposed workflow (for review),
5
+ * AI configuration, and usage metrics.
6
+ *
7
+ * Exposed as both a factory (`createAiStore`, for per-`<AiWorkflowIDE>`-instance
8
+ * isolation via IdeStoresContext — see store/ideStoresContext.tsx) and a default
9
+ * singleton (for callers outside that context, e.g. WorkflowIDE's shared canvas).
10
+ */
11
+ import type { AiConfig, Message } from '../services/ai/protocolAdapter';
12
+ import type { WorkflowDef } from '../types/conductor';
13
+ import type { DiffSummary } from '../services/ai/toolExecutor';
14
+ import type { SynthesisPhase, VerificationSummary } from '../services/ai/workflowSynthesizer';
15
+ import type { WorkflowLevel } from '../types/workflowLibrary';
16
+ export interface AiChatMessage {
17
+ id: string;
18
+ role: 'user' | 'assistant';
19
+ content: string;
20
+ /** If this message triggered a proposal, link it here */
21
+ proposalId?: string;
22
+ timestamp: number;
23
+ }
24
+ export interface ProposedChange {
25
+ id: string;
26
+ proposedDef: WorkflowDef;
27
+ diff: DiffSummary;
28
+ /** Inferred workflow level based on sub-workflow references */
29
+ inferredLevel?: WorkflowLevel;
30
+ /** Holistic semantic & data-flow verification summary */
31
+ verification?: VerificationSummary;
32
+ /** Message that triggered this proposal */
33
+ messageId: string;
34
+ /**
35
+ * JSON snapshot of the canvas workflowDef at the moment the proposal was created.
36
+ * Used to detect stale proposals when the user has edited the canvas during review.
37
+ */
38
+ baselineHash: string;
39
+ }
40
+ /**
41
+ * PI-style Durable Execution Checkpoint.
42
+ * Captures the complete state of an in-flight or interrupted multi-phase agent session
43
+ * so it can be resumed (`runner.resume()`) or committed (`runner.commitDraftNow()`)
44
+ * without re-running completed phases.
45
+ */
46
+ export interface DurableSessionCheckpoint {
47
+ sessionId: string;
48
+ userPrompt: string;
49
+ assistantMsgId: string;
50
+ phase: SynthesisPhase;
51
+ workingDraft: WorkflowDef | null;
52
+ agentHistory: Message[];
53
+ stepIndex: number;
54
+ selfHealCount: number;
55
+ status: 'running' | 'paused' | 'failed' | 'completed';
56
+ lastError?: string;
57
+ updatedAt: number;
58
+ }
59
+ export interface RepairAction {
60
+ id: string;
61
+ label: string;
62
+ type: 'rerun_from' | 'skip' | 'retry_workflow' | 'modify_def';
63
+ taskRef?: string;
64
+ risk?: 'low' | 'medium' | 'high';
65
+ description?: string;
66
+ }
67
+ export interface RepairProposal {
68
+ id: string;
69
+ diagnosis: string;
70
+ actions: RepairAction[];
71
+ messageId: string;
72
+ }
73
+ export interface PlanStep {
74
+ step: number;
75
+ action: string;
76
+ tool?: string;
77
+ }
78
+ export interface PendingPlan {
79
+ id: string;
80
+ title: string;
81
+ steps: PlanStep[];
82
+ summary?: string;
83
+ messageId: string;
84
+ }
85
+ export interface AiMetrics {
86
+ totalProposals: number;
87
+ acceptedProposals: number;
88
+ rejectedProposals: number;
89
+ /** Cumulative token usage for this session (M4.4). Only incremented when the
90
+ * provider reports usage — best-effort, not every provider/proxy includes it. */
91
+ totalPromptTokens: number;
92
+ totalCompletionTokens: number;
93
+ }
94
+ export interface ClarificationOption {
95
+ id: string;
96
+ label: string;
97
+ description: string;
98
+ icon?: string;
99
+ }
100
+ export interface PendingClarification {
101
+ id: string;
102
+ question: string;
103
+ context?: string;
104
+ options: ClarificationOption[];
105
+ messageId: string;
106
+ }
107
+ export interface WorkflowRecommendation {
108
+ workflowName: string;
109
+ matchReason: string;
110
+ matchScore: 'exact' | 'partial' | 'similar';
111
+ }
112
+ export interface PendingRecommendation {
113
+ id: string;
114
+ userIntent: string;
115
+ recommendations: WorkflowRecommendation[];
116
+ messageId: string;
117
+ }
118
+ interface AiState {
119
+ config: AiConfig;
120
+ messages: AiChatMessage[];
121
+ isStreaming: boolean;
122
+ streamingText: string;
123
+ chatPanelOpen: boolean;
124
+ /** The current pending proposal (only one at a time) */
125
+ pendingProposal: ProposedChange | null;
126
+ /** AI-generated multi-step plan awaiting user approval */
127
+ pendingPlan: PendingPlan | null;
128
+ /** AI-generated repair proposal for run-mode failures */
129
+ pendingRepair: RepairProposal | null;
130
+ metrics: AiMetrics;
131
+ /** Context-aware chips shown after the user accepts a proposal */
132
+ followUpChips: string[] | null;
133
+ /** Undo stack: previous WorkflowDef snapshots (max 5, oldest first) */
134
+ undoStack: WorkflowDef[];
135
+ /** Pending clarification question awaiting user selection */
136
+ pendingClarification: PendingClarification | null;
137
+ /** Pending workflow recommendation awaiting user selection */
138
+ pendingRecommendation: PendingRecommendation | null;
139
+ /**
140
+ * Message queued for the AI pipeline from outside AiCommandCenter
141
+ * (e.g. proposal acceptance, canvas node click). AiCommandCenter
142
+ * picks this up via useEffect and calls runner.send(), then clears it.
143
+ */
144
+ pendingAutoSend: string | null;
145
+ /** Current in-flight step label (e.g. "正在搜索工作流库…"), set by AgentRunner */
146
+ toolStatus: string;
147
+ /** Last message that failed to send, offered back via a retry button */
148
+ retryInput: string | null;
149
+ /**
150
+ * Append-only log of completed steps for the current agent turn (M2.2 AgentTimeline).
151
+ * Cleared at the start of each `send()`. Self-heal retries log their own entry so
152
+ * the correction is visible rather than silent.
153
+ */
154
+ timelineEntries: TimelineEntry[];
155
+ /** Current progressive workflow synthesis phase ('idle' | 'blueprint' | 'topology' | 'configure' | 'verify' | 'completed') */
156
+ synthesisPhase: SynthesisPhase;
157
+ /** In-progress workflow draft accumulated across progressive synthesis stages */
158
+ workingDraft: WorkflowDef | null;
159
+ /** PI-style durable session checkpoint for pause/resume/fault-recovery */
160
+ durableCheckpoint: DurableSessionCheckpoint | null;
161
+ }
162
+ export interface TimelineEntry {
163
+ id: string;
164
+ label: string;
165
+ icon: 'done' | 'warning';
166
+ }
167
+ interface AiActions {
168
+ setConfig: (config: Partial<AiConfig>) => void;
169
+ addMessage: (msg: Omit<AiChatMessage, 'id' | 'timestamp'>) => string;
170
+ updateMessage: (id: string, content: string) => void;
171
+ setStreaming: (isStreaming: boolean) => void;
172
+ setStreamingText: (text: string) => void;
173
+ appendStreamingText: (delta: string) => void;
174
+ clearMessages: () => void;
175
+ setChatPanelOpen: (open: boolean) => void;
176
+ toggleChatPanel: () => void;
177
+ setProposal: (proposal: Omit<ProposedChange, 'id' | 'baselineHash'>) => string;
178
+ clearProposal: () => void;
179
+ recordAccept: () => void;
180
+ recordReject: () => void;
181
+ getMetrics: () => AiMetrics;
182
+ /** Accumulates token usage reported by the provider for one model turn (M4.4) */
183
+ recordUsage: (usage: {
184
+ promptTokens?: number;
185
+ completionTokens?: number;
186
+ }) => void;
187
+ setFollowUpChips: (chips: string[]) => void;
188
+ clearFollowUpChips: () => void;
189
+ setPlan: (plan: Omit<PendingPlan, 'id'>) => string;
190
+ clearPlan: () => void;
191
+ setRepair: (repair: Omit<RepairProposal, 'id'>) => string;
192
+ clearRepair: () => void;
193
+ /** Push the given def onto the undo stack (called before applying a proposal) */
194
+ pushUndo: (def: WorkflowDef) => void;
195
+ /** Pop and return the most recent undo snapshot, or null if stack is empty */
196
+ popUndo: () => WorkflowDef | null;
197
+ clearUndo: () => void;
198
+ canUndo: () => boolean;
199
+ setClarification: (c: Omit<PendingClarification, 'id'>) => string;
200
+ clearClarification: () => void;
201
+ setRecommendation: (r: Omit<PendingRecommendation, 'id'>) => string;
202
+ clearRecommendation: () => void;
203
+ /** Queue a message to be sent through the AI pipeline by AiCommandCenter */
204
+ setPendingAutoSend: (msg: string | null) => void;
205
+ /** Restore conversation + pending proposal + optional durable checkpoint from a persisted draft (M1.4) */
206
+ hydrateFromDraft: (messages: AiChatMessage[], pendingProposal: ProposedChange | null, durableCheckpoint?: DurableSessionCheckpoint | null) => void;
207
+ setToolStatus: (status: string) => void;
208
+ setRetryInput: (input: string | null) => void;
209
+ addTimelineEntry: (label: string, icon?: 'done' | 'warning') => void;
210
+ clearTimeline: () => void;
211
+ setSynthesisStage: (phase: SynthesisPhase, draft?: WorkflowDef | null) => void;
212
+ saveCheckpoint: (checkpoint: DurableSessionCheckpoint | null) => void;
213
+ clearCheckpoint: () => void;
214
+ }
215
+ export type AiStore = AiState & AiActions;
216
+ /**
217
+ * Creates an independent AiStore instance.
218
+ *
219
+ * @param persistKey localStorage key for provider/baseUrl/model + metrics (never
220
+ * the apiKey or conversation itself). Pass `false` to keep this
221
+ * instance fully in-memory — no localStorage writes at all.
222
+ * Defaults to a stable shared key so existing single-instance
223
+ * integrations keep their persisted config across reloads;
224
+ * pass a unique key per instance when embedding multiple
225
+ * `<AiWorkflowIDE>` on the same page to avoid them clobbering
226
+ * each other's persisted config.
227
+ */
228
+ export declare function createAiStore(persistKey?: string | false): import("zustand").UseBoundStore<import("zustand").StoreApi<AiStore>>;
229
+ declare const useAiStore: import("zustand").UseBoundStore<import("zustand").StoreApi<AiStore>>;
230
+ export default useAiStore;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * IdeStoresContext — per-`<AiWorkflowIDE>`-instance state isolation (M3.2)
3
+ *
4
+ * Before this, aiStore/libraryStore/toolRegistry were module-level singletons:
5
+ * two `<AiWorkflowIDE>` mounted on the same page shared one conversation, one
6
+ * pending proposal, one workflow library, one set of custom tools — the second
7
+ * instance would silently stomp the first. AiWorkflowIDE now creates a fresh
8
+ * set of these per mount (via createAiStore/createLibraryStore/new ToolRegistry)
9
+ * and provides them through this context; every AiNative component and the
10
+ * AgentRunner it constructs read from `useIdeStores()` instead of importing the
11
+ * default singletons directly.
12
+ *
13
+ * `workflowStore` (the canvas/task-graph state) is NOT part of this context yet —
14
+ * it remains a shared singleton because it's also consumed by WorkflowIDE's much
15
+ * larger component tree (nodes, panels) that this pass didn't migrate. That's a
16
+ * documented follow-up, not an oversight: see docs/design/双IDE组件架构审查.md §2.
17
+ */
18
+ import type { ReactNode } from 'react';
19
+ import type { UseBoundStore, StoreApi } from 'zustand';
20
+ import type { AiStore } from './aiStore';
21
+ import type { LibraryStore } from './libraryStore';
22
+ import type { ToolRegistry } from '../services/ai/toolRegistry';
23
+ export interface IdeStores {
24
+ aiStore: UseBoundStore<StoreApi<AiStore>>;
25
+ libraryStore: UseBoundStore<StoreApi<LibraryStore>>;
26
+ toolRegistry: ToolRegistry;
27
+ }
28
+ export declare function IdeStoresProvider({ stores, children }: {
29
+ stores: IdeStores;
30
+ children: ReactNode;
31
+ }): import("react/jsx-runtime").JSX.Element;
32
+ /** Reads the per-instance stores. Throws if used outside `<AiWorkflowIDE>` — every AiNative component is always rendered under it. */
33
+ export declare function useIdeStores(): IdeStores;
34
+ /**
35
+ * Non-throwing variant for components shared with WorkflowIDE (e.g. WorkflowDesigner),
36
+ * which renders both under `<AiWorkflowIDE>` (provider present) and standalone under
37
+ * `<WorkflowIDE>` (no provider — falls back to the module singleton there instead).
38
+ */
39
+ export declare function useIdeStoresOptional(): IdeStores | null;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Library Store — sub-workflow catalog state
3
+ *
4
+ * Kept separate from aiStore to avoid circular dependencies (aiStore imports
5
+ * types from toolExecutor, which used to read this store directly; since M2.1
6
+ * toolExecutor is pure and AgentRunner passes library items in explicitly, but
7
+ * the separate store is still worth keeping for its narrow, focused shape).
8
+ *
9
+ * Populated by AiWorkflowIDE when the workflowLibrary prop changes.
10
+ * Read by AgentRunner (search_workflow_library / system prompt catalog) via
11
+ * whichever instance the owning `<AiWorkflowIDE>` created — see createLibraryStore.
12
+ */
13
+ import type { WorkflowLibraryItem } from '../types/workflowLibrary';
14
+ interface LibraryState {
15
+ items: WorkflowLibraryItem[];
16
+ }
17
+ interface LibraryActions {
18
+ setLibrary: (items: WorkflowLibraryItem[]) => void;
19
+ clearLibrary: () => void;
20
+ }
21
+ export type LibraryStore = LibraryState & LibraryActions;
22
+ /** Creates an independent LibraryStore instance (no persistence — populated fresh from props each mount). */
23
+ export declare function createLibraryStore(): import("zustand").UseBoundStore<import("zustand").StoreApi<LibraryStore>>;
24
+ declare const useLibraryStore: import("zustand").UseBoundStore<import("zustand").StoreApi<LibraryStore>>;
25
+ export default useLibraryStore;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * AI Event types for audit logging and analytics.
3
+ *
4
+ * Pass an `onAiEvent` callback to <AiWorkflowIDE> to receive all AI lifecycle events.
5
+ *
6
+ * ```tsx
7
+ * <AiWorkflowIDE
8
+ * onAiEvent={(event) => auditLog.record(event)}
9
+ * />
10
+ * ```
11
+ */
12
+ export type AiEventType = 'proposal:created' | 'proposal:accepted' | 'proposal:accepted:partial' | 'proposal:rejected' | 'stage:completed' | 'session:resumed' | 'plan:created' | 'plan:executed' | 'plan:cancelled' | 'repair:proposed'
13
+ /** User clicked the inline second-click confirmation before a runtime-mutating repair action fires */
14
+ | 'repair:confirmed' | 'repair:executed' | 'repair:dismissed' | 'tool:called' | 'undo:applied'
15
+ /** AI request failed (network/HTTP/provider error). The user only ever sees a humanized
16
+ * message — the raw diagnostic text is only available here, via `rawMessage`. */
17
+ | 'ai:error';
18
+ export interface AiEvent {
19
+ type: AiEventType;
20
+ timestamp: number;
21
+ /** For tool:called events */
22
+ tool?: string;
23
+ /** For stage:completed events */
24
+ phase?: string;
25
+ /** For repair:executed / repair:confirmed events */
26
+ repairActionType?: string;
27
+ /** For proposal events: change counts */
28
+ diff?: {
29
+ added: number;
30
+ modified: number;
31
+ removed: number;
32
+ };
33
+ /** For proposal:accepted:partial: selected vs total change count */
34
+ selectedCount?: number;
35
+ totalCount?: number;
36
+ /** Inferred workflow level (L1/L2/L3) for proposal events */
37
+ inferredLevel?: string;
38
+ /** For ai:error events: the raw underlying error text (HTTP status, provider message, etc.) — not shown to the user */
39
+ rawMessage?: string;
40
+ }
@@ -54,7 +54,9 @@ export interface TaskDef {
54
54
  };
55
55
  sink?: string;
56
56
  evaluatorType?: 'graaljs' | 'javascript' | 'value-param' | 'python';
57
+ expression?: string;
57
58
  caseExpression?: string;
59
+ defaultExclusiveJoinTask?: string[];
58
60
  keepLastN?: number;
59
61
  forkTaskType?: string;
60
62
  forkTaskName?: string;
@@ -168,7 +170,7 @@ export interface TaskInstance {
168
170
  executed?: boolean;
169
171
  callbackFromWorker?: boolean;
170
172
  responseTimeoutSeconds?: number;
171
- workflowInstanceId: string;
173
+ workflowInstanceId?: string;
172
174
  workflowType?: string;
173
175
  taskId: string;
174
176
  reasonForIncompletion?: string;
@@ -176,6 +178,7 @@ export interface TaskInstance {
176
178
  workerId?: string;
177
179
  externalInputPayloadStoragePath?: string;
178
180
  externalOutputPayloadStoragePath?: string;
181
+ workflowTask?: TaskDef;
179
182
  }
180
183
  /**
181
184
  * Conductor 工作流实例 (运行时)
@@ -184,6 +187,8 @@ export interface WorkflowInstance {
184
187
  status: 'RUNNING' | 'COMPLETED' | 'FAILED' | 'TIMED_OUT' | 'TERMINATED' | 'PAUSED';
185
188
  endTime?: number;
186
189
  workflowId: string;
190
+ workflowName?: string;
191
+ workflowVersion?: number;
187
192
  parentWorkflowId?: string;
188
193
  parentWorkflowTaskId?: string;
189
194
  tasks: TaskInstance[];