@yiyi_zhang/reactflow-ui 0.3.0 → 0.5.0-beta.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 (110) hide show
  1. package/README.md +61 -22
  2. package/dist/AiWorkflowIDE.d.ts +217 -0
  3. package/dist/WorkflowIDE.d.ts +22 -3
  4. package/dist/ai-BJwQZcGK.js +15168 -0
  5. package/dist/ai.d.ts +30 -0
  6. package/dist/arc-BUGZGgtu.js +83 -0
  7. package/dist/architectureDiagram-3BPJPVTR-ZcgvTwSO.js +4692 -0
  8. package/dist/blockDiagram-GPEHLZMM-DtVtOBbH.js +2418 -0
  9. package/dist/c4Diagram-AAUBKEIU-tBS5Rcvm.js +1577 -0
  10. package/dist/channel-CURI9jmI.js +5 -0
  11. package/dist/chunk-2J33WTMH-D7gashNz.js +19 -0
  12. package/dist/chunk-4BX2VUAB-DE3VjyiZ.js +8 -0
  13. package/dist/chunk-55IACEB6-GYZ_m2MY.js +8 -0
  14. package/dist/chunk-727SXJPM-D4WVyvOg.js +1528 -0
  15. package/dist/chunk-AQP2D5EJ-Os2Uwqya.js +1387 -0
  16. package/dist/chunk-FMBD7UC4-B3CSVzS4.js +19 -0
  17. package/dist/chunk-ND2GUHAM-CNj_s1aK.js +68 -0
  18. package/dist/chunk-QZHKN3VN-DoV8iUKo.js +15 -0
  19. package/dist/classDiagram-4FO5ZUOK-Dr9C18x4.js +16 -0
  20. package/dist/classDiagram-v2-Q7XG4LA2-Dr9C18x4.js +16 -0
  21. package/dist/components/AiNative/AgentTimeline.d.ts +18 -0
  22. package/dist/components/AiNative/AiCommandCenter.d.ts +40 -0
  23. package/dist/components/AiNative/AiConfigPanel.d.ts +9 -0
  24. package/dist/components/AiNative/BusinessCanvas.d.ts +15 -0
  25. package/dist/components/AiNative/CanvasPreview.d.ts +16 -0
  26. package/dist/components/AiNative/ClarificationCard.d.ts +9 -0
  27. package/dist/components/AiNative/FailureSummaryCard.d.ts +20 -0
  28. package/dist/components/AiNative/LibraryPanel.d.ts +9 -0
  29. package/dist/components/AiNative/MermaidBlock.d.ts +6 -0
  30. package/dist/components/AiNative/PlanCard.d.ts +15 -0
  31. package/dist/components/AiNative/ProposalPreviewCard.d.ts +21 -0
  32. package/dist/components/AiNative/RecommendationCard.d.ts +10 -0
  33. package/dist/components/AiNative/RepairCard.d.ts +17 -0
  34. package/dist/components/AiNative/ReviewBar.d.ts +21 -0
  35. package/dist/components/AiNative/WorkflowRunCard.d.ts +14 -0
  36. package/dist/components/Controls/ModeSlider.d.ts +2 -0
  37. package/dist/components/ExecutionSummaryPanel.d.ts +4 -0
  38. package/dist/components/WorkflowRunPanel.d.ts +12 -0
  39. package/dist/components/nodes/NodeWrapper.d.ts +2 -1
  40. package/dist/cose-bilkent-S5V4N54A-CgQlI-io.js +2609 -0
  41. package/dist/cytoscape.esm-kVAWcYoG.js +18755 -0
  42. package/dist/dagre-BM42HDAG-CFMIuOmS.js +445 -0
  43. package/dist/defaultLocale-BgPVtth8.js +171 -0
  44. package/dist/diagram-2AECGRRQ-C5jZp2YX.js +217 -0
  45. package/dist/diagram-5GNKFQAL-DRUVcHpp.js +123 -0
  46. package/dist/diagram-KO2AKTUF-BOl4aaej.js +461 -0
  47. package/dist/diagram-LMA3HP47-ZeckPR2Q.js +142 -0
  48. package/dist/diagram-OG6HWLK6-qUWeLfa-.js +528 -0
  49. package/dist/erDiagram-TEJ5UH35-Bw_CWS13.js +899 -0
  50. package/dist/flowDiagram-I6XJVG4X-D3xEvQA-.js +1628 -0
  51. package/dist/ganttDiagram-6RSMTGT7-D8GvenY3.js +2707 -0
  52. package/dist/gitGraphDiagram-PVQCEYII-BWrN_HOm.js +815 -0
  53. package/dist/graph-BRoPeNF3.js +1545 -0
  54. package/dist/hooks/useNodeExecution.d.ts +1 -1
  55. package/dist/hooks/useNodeLayout.d.ts +1 -1
  56. package/dist/index.d.ts +3 -2
  57. package/dist/infoDiagram-5YYISTIA-Da8FG5tB.js +24 -0
  58. package/dist/init-DjUOC4st.js +16 -0
  59. package/dist/ishikawaDiagram-YF4QCWOH-Bg2_mKEc.js +621 -0
  60. package/dist/journeyDiagram-JHISSGLW-sFIxGfua.js +834 -0
  61. package/dist/kanban-definition-UN3LZRKU-CGmopzHd.js +724 -0
  62. package/dist/katex-DoRnZ_sp.js +11682 -0
  63. package/dist/layout-D9EpM4Fg.js +1728 -0
  64. package/dist/linear-BA49eco4.js +259 -0
  65. package/dist/mermaid.core-XSpZEAKP.js +16137 -0
  66. package/dist/mindmap-definition-RKZ34NQL-Bqf76QGB.js +827 -0
  67. package/dist/ordinal-B6-f3MAq.js +61 -0
  68. package/dist/pieDiagram-4H26LBE5-hHiP8HzL.js +163 -0
  69. package/dist/quadrantDiagram-W4KKPZXB-DSccwH8B.js +1024 -0
  70. package/dist/reactflow-ui-ai.es.js +12 -0
  71. package/dist/reactflow-ui.css +1 -1
  72. package/dist/reactflow-ui.es.js +8198 -7039
  73. package/dist/reactflow-ui.umd.js +52 -17
  74. package/dist/requirementDiagram-4Y6WPE33-DIpyoYZ_.js +882 -0
  75. package/dist/sankeyDiagram-5OEKKPKP-DsaPqq8D.js +847 -0
  76. package/dist/sequenceDiagram-3UESZ5HK-BNg7orie.js +2891 -0
  77. package/dist/services/ai/agentRunner.d.ts +51 -0
  78. package/dist/services/ai/contextEngine.d.ts +83 -0
  79. package/dist/services/ai/draftPersistence.d.ts +22 -0
  80. package/dist/services/ai/errorMessages.d.ts +16 -0
  81. package/dist/services/ai/intentClassifier.d.ts +17 -0
  82. package/dist/services/ai/protocolAdapter.d.ts +114 -0
  83. package/dist/services/ai/ruleEngine.d.ts +57 -0
  84. package/dist/services/ai/schemaRegistry.d.ts +51 -0
  85. package/dist/services/ai/systemPrompt.d.ts +30 -0
  86. package/dist/services/ai/toolDefs.d.ts +9 -0
  87. package/dist/services/ai/toolExecutor.d.ts +83 -0
  88. package/dist/services/ai/toolRegistry.d.ts +38 -0
  89. package/dist/services/ai/transport.d.ts +58 -0
  90. package/dist/services/aiService.d.ts +27 -5
  91. package/dist/stateDiagram-AJRCARHV-Rv1mSmnJ.js +263 -0
  92. package/dist/stateDiagram-v2-BHNVJYJU-BME16k02.js +16 -0
  93. package/dist/store/aiStore.d.ts +199 -0
  94. package/dist/store/ideStoresContext.d.ts +39 -0
  95. package/dist/store/libraryStore.d.ts +25 -0
  96. package/dist/timeline-definition-PNZ67QCA-CmmzdVk-.js +1055 -0
  97. package/dist/types/aiEvents.d.ts +38 -0
  98. package/dist/types/conductor.d.ts +23 -2
  99. package/dist/types/workflow.d.ts +36 -0
  100. package/dist/types/workflowLibrary.d.ts +27 -0
  101. package/dist/utils/executionAnalyzer.d.ts +32 -0
  102. package/dist/utils/nodeMeta.d.ts +6 -0
  103. package/dist/utils/proposalPreview.d.ts +19 -0
  104. package/dist/utils/taskTypeMeta.d.ts +18 -0
  105. package/dist/utils/workflowToMermaid.d.ts +7 -0
  106. package/dist/vennDiagram-CIIHVFJN-BQt00w9Q.js +1557 -0
  107. package/dist/wardley-L42UT6IY-D7b2ujEZ.js +22512 -0
  108. package/dist/wardleyDiagram-YWT4CUSO-LZpiODGN.js +675 -0
  109. package/dist/xychartDiagram-2RQKCTM6-BpJlv_mc.js +1342 -0
  110. package/package.json +14 -4
@@ -0,0 +1,51 @@
1
+ /**
2
+ * AgentRunner — the AI agentic loop, extracted from AiCommandCenter (M2.1)
3
+ *
4
+ * Owns the entire multi-step tool-calling loop that used to live inline in a
5
+ * 300-line useCallback: streaming the model, dispatching tool calls, self-healing
6
+ * invalid proposals, and committing results (messages/proposal/plan/repair/
7
+ * clarification/recommendation) to aiStore. This makes the orchestration logic
8
+ * testable headlessly (see agentRunner.test.ts) and keeps AiCommandCenter as a
9
+ * thin renderer of store state.
10
+ *
11
+ * Store access: this is the ONE place in the AI stack allowed to read
12
+ * workflowStore/libraryStore/aiStore directly (via getState()) and call aiStore
13
+ * actions to commit results — everything it calls into (toolExecutor,
14
+ * systemPrompt, contextEngine) is a pure function that receives that state
15
+ * explicitly, so those modules stay unit-testable without a store.
16
+ *
17
+ * Instancing (M3.2): `aiStore`/`libraryStore`/`toolRegistry` are injected via the
18
+ * constructor rather than imported as module singletons, so each `<AiWorkflowIDE>`
19
+ * mount gets its own isolated runner talking to its own store/registry instances
20
+ * (see store/ideStoresContext.tsx). `workflowStore` remains a shared singleton for
21
+ * now — see the architecture review's M3.2 note on that being a larger follow-up.
22
+ */
23
+ import type { AiStore } from '../../store/aiStore';
24
+ import type { LibraryStore } from '../../store/libraryStore';
25
+ import type { ToolRegistry } from './toolRegistry';
26
+ import type { AiEvent } from '../../types/aiEvents';
27
+ import type { UseBoundStore, StoreApi } from 'zustand';
28
+ export interface AgentRunnerOptions {
29
+ systemPrompt?: string;
30
+ systemPromptExtra?: string;
31
+ aiPermissions?: {
32
+ canEdit?: boolean;
33
+ canRepair?: boolean;
34
+ };
35
+ onAiEvent?: (event: AiEvent) => void;
36
+ }
37
+ export interface AgentRunnerStores {
38
+ aiStore: UseBoundStore<StoreApi<AiStore>>;
39
+ libraryStore: UseBoundStore<StoreApi<LibraryStore>>;
40
+ toolRegistry: ToolRegistry;
41
+ }
42
+ export declare class AgentRunner {
43
+ private getOptions;
44
+ private stores;
45
+ private controller;
46
+ constructor(getOptions: () => AgentRunnerOptions, stores: AgentRunnerStores);
47
+ abort(): void;
48
+ private toolExecutionContext;
49
+ private buildHistory;
50
+ send(text: string): Promise<void>;
51
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * AI Context Engine — 从工作流快照构建 AI 上下文
3
+ *
4
+ * 生成精简的结构化上下文,避免全量 JSON dump 消耗过多 token。
5
+ * 不直接依赖 workflowStore——调用方(AgentRunner)读取实时 store 状态后
6
+ * 以 WorkflowSnapshot 形式传入,使本模块保持纯函数、可脱离 store 单测。
7
+ */
8
+ import type { Edge } from 'reactflow';
9
+ import type { WorkflowDef, TaskDef, WorkflowInstance } from '../../types/conductor';
10
+ import type { EditorMode, TaskExecutionData, ValidationResults } from '../../types/workflow';
11
+ /** 调用方(AgentRunner)从 workflowStore 读取的实时状态快照 */
12
+ export interface WorkflowSnapshot {
13
+ workflowDef: WorkflowDef | null;
14
+ edges: Edge[];
15
+ selectedTask: TaskDef | null;
16
+ executionData: Record<string, TaskExecutionData> | null;
17
+ mode: EditorMode;
18
+ workflowInstance: WorkflowInstance | null;
19
+ taskMap: Record<string, TaskDef>;
20
+ validationResults: ValidationResults;
21
+ }
22
+ export interface ExecutionContext {
23
+ /** 实例 ID(截短) */
24
+ instanceId?: string;
25
+ /** 工作流整体状态 */
26
+ workflowStatus?: string;
27
+ /** 失败任务 */
28
+ failedTasks: Array<{
29
+ ref: string;
30
+ type: string;
31
+ reason?: string;
32
+ }>;
33
+ /** 进行中的任务 */
34
+ inProgressTasks: string[];
35
+ /** 已完成任务数 */
36
+ completedCount: number;
37
+ /** 总任务数 */
38
+ totalCount: number;
39
+ }
40
+ export interface WorkflowContext {
41
+ /** 一句话摘要 */
42
+ summary: string;
43
+ /** 拓扑关系(文字表达) */
44
+ topology: string;
45
+ /** 任务列表摘要 */
46
+ tasks: Array<{
47
+ ref: string;
48
+ name: string;
49
+ type: string;
50
+ }>;
51
+ /** 当前选中任务的上下文 */
52
+ focusTask?: FocusTaskContext;
53
+ /** 校验问题 */
54
+ validationIssues: string[];
55
+ /** 运行态执行上下文(run 模式下注入) */
56
+ execution?: ExecutionContext;
57
+ /** 完整工作流 JSON (仅在需要全量信息时提供) */
58
+ fullDef?: any;
59
+ }
60
+ interface FocusTaskContext {
61
+ task: {
62
+ ref: string;
63
+ name: string;
64
+ type: string;
65
+ inputParameters?: any;
66
+ };
67
+ upstreamRefs: string[];
68
+ downstreamRefs: string[];
69
+ /** 运行态:该任务的执行状态和失败原因 */
70
+ executionStatus?: string;
71
+ executionFailureReason?: string;
72
+ }
73
+ /**
74
+ * 构建工作流上下文摘要
75
+ */
76
+ export declare function buildContext(snapshot: WorkflowSnapshot, options?: {
77
+ includeFull?: boolean;
78
+ }): WorkflowContext;
79
+ /**
80
+ * 将 WorkflowContext 格式化为 system prompt 中的上下文段落
81
+ */
82
+ export declare function formatContextForPrompt(ctx: WorkflowContext): string;
83
+ export {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Draft Persistence — 刷新不丢工作(M1.4)
3
+ *
4
+ * AiWorkflowIDE 默认所有状态存于内存,刷新页面即丢失全部编辑。这里提供一个
5
+ * 可选的、集成方显式开启的 localStorage 草稿机制:workflowDef + 对话 + 待确认
6
+ * 提案定期写入本地存储,挂载时检测到草稿则恢复现场。
7
+ *
8
+ * 默认不开启(`draftPersist={false}`)——是否写宿主页面的 localStorage 由集成方决定。
9
+ */
10
+ import type { WorkflowDef } from '../../types/conductor';
11
+ import type { AiChatMessage, ProposedChange } from '../../store/aiStore';
12
+ export interface IdeDraft {
13
+ workflowDef: WorkflowDef | null;
14
+ messages: AiChatMessage[];
15
+ pendingProposal: ProposedChange | null;
16
+ savedAt: number;
17
+ }
18
+ /** 判断草稿是否包含有意义的内容(避免刚挂载、仅有欢迎语时就落一份空草稿) */
19
+ export declare function isMeaningfulDraft(workflowDef: WorkflowDef | null, messages: AiChatMessage[], pendingProposal: ProposedChange | null): boolean;
20
+ export declare function loadDraft(key: string): IdeDraft | null;
21
+ export declare function saveDraft(key: string, draft: IdeDraft): void;
22
+ export declare function clearDraft(key: string): void;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Error Messages — 面向业务用户的两段式错误文案(M1.5)
3
+ *
4
+ * 原始错误(HTTP 状态码、provider 报错原文、网络异常类名等)对不熟悉 Conductor/LLM
5
+ * 的业务用户没有意义,且直接把它们塞进聊天气泡会让人不知道发生了什么、更不知道怎么办。
6
+ *
7
+ * 这里把常见错误模式翻译成"发生了什么 + 你能做什么"的中文提示;原始文本只通过
8
+ * `onAiEvent({ type: 'ai:error', rawMessage })` 提供给审计/日志,绝不进入聊天 UI。
9
+ */
10
+ export interface HumanizedError {
11
+ /** 展示给用户的两段式文案(发生了什么 + 能做什么) */
12
+ display: string;
13
+ /** 原始错误文本,仅用于审计事件,不展示给用户 */
14
+ raw: string;
15
+ }
16
+ export declare function humanizeAiError(rawMessage: string | undefined | null): HumanizedError;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * AI Intent Classifier — 本地规则快速分类用户意图
3
+ *
4
+ * 不消耗 AI token,通过关键词匹配快速判断用户输入的意图类型,
5
+ * 用于动态调整上下文注入粒度和 prompt 模板。
6
+ */
7
+ export type Intent = 'CREATE' | 'ADD' | 'MODIFY' | 'DELETE' | 'REFACTOR' | 'EXPLAIN' | 'DEBUG' | 'OPTIMIZE' | 'VISUALIZE' | 'GENERAL' | 'VAGUE';
8
+ /**
9
+ * 对用户输入进行意图分类
10
+ */
11
+ export declare function classifyIntent(input: string): Intent;
12
+ /**
13
+ * 根据意图决定上下文注入粒度
14
+ */
15
+ export declare function getContextOptions(intent: Intent): {
16
+ includeFull: boolean;
17
+ };
@@ -0,0 +1,114 @@
1
+ /**
2
+ * AI Protocol Adapter — OpenAI / Anthropic 双协议统一适配
3
+ *
4
+ * 支持的协议:
5
+ * - OpenAI Chat Completions API(/chat/completions)
6
+ * 兼容提供商:OpenAI、Mistral、DeepSeek、Groq、Together.ai、Azure OpenAI、
7
+ * Ollama、LM Studio、vLLM 等任意 OpenAI 兼容服务
8
+ * - Anthropic Messages API(/messages)
9
+ *
10
+ * baseUrl 和 model 均为可选,不填时自动使用各提供商默认值。
11
+ *
12
+ * 传输模式:`config.transport` 未设置时,以下 provider/apiKey/baseUrl/model 字段
13
+ * 生效为 **direct 模式**——浏览器直连模型服务商,API Key 留存于终端用户浏览器,
14
+ * 仅建议用于开发调试。生产环境请通过 `transport: { type: 'endpoint', url }` 配置
15
+ * 集成方自己的后端代理,详见 `./transport.ts`。
16
+ */
17
+ import type { AiTransport } from './transport';
18
+ export type { AiTransport, AgentRequest } from './transport';
19
+ export interface AiConfig {
20
+ /**
21
+ * 协议类型:
22
+ * - 'openai' — OpenAI Chat Completions 协议(Mistral/Groq/DeepSeek 等兼容服务也选此项)
23
+ * - 'anthropic' — Anthropic Messages 协议
24
+ * - 'auto' — 根据 baseUrl 自动判断(包含 anthropic.com → Anthropic,其余 → OpenAI)
25
+ * @default 'auto'
26
+ */
27
+ provider?: 'openai' | 'anthropic' | 'auto';
28
+ /** API Key(仅 direct 模式需要;使用 endpoint/custom 传输时可留空字符串) */
29
+ apiKey: string;
30
+ /**
31
+ * API 基础 URL(不含路径,仅 direct 模式生效)。
32
+ * 留空时使用各提供商标准地址:
33
+ * - OpenAI: https://api.openai.com/v1
34
+ * - Anthropic: https://api.anthropic.com
35
+ *
36
+ * 常见第三方示例:
37
+ * - Mistral: https://api.mistral.ai/v1
38
+ * - DeepSeek: https://api.deepseek.com/v1
39
+ * - Groq: https://api.groq.com/openai/v1
40
+ * - Ollama: http://localhost:11434/v1
41
+ * - Azure: https://{resource}.openai.azure.com/openai/deployments/{deploy}
42
+ */
43
+ baseUrl?: string;
44
+ /**
45
+ * 模型名称(仅 direct 模式生效)。留空时使用各提供商默认模型:
46
+ * - OpenAI: gpt-4o
47
+ * - Anthropic: claude-sonnet-4-6
48
+ */
49
+ model?: string;
50
+ /**
51
+ * 传输模式(可选)。设置后优先于上述 direct 字段生效:
52
+ * - `{ type: 'endpoint', url }` — 请求转发至集成方自己的后端代理(**生产环境推荐**)
53
+ * - `{ type: 'custom', stream }` — 完全自定义的流式实现
54
+ *
55
+ * 不设置时回退为 direct 模式(浏览器直连模型服务商,仅限开发调试)。
56
+ */
57
+ transport?: AiTransport;
58
+ }
59
+ export interface ToolCallRef {
60
+ id: string;
61
+ name: string;
62
+ args: Record<string, any>;
63
+ }
64
+ export interface Message {
65
+ role: 'system' | 'user' | 'assistant' | 'tool';
66
+ content: string;
67
+ tool_call_id?: string;
68
+ /** For assistant turns that issued tool calls — used to build the agentic history */
69
+ tool_calls?: ToolCallRef[];
70
+ }
71
+ export interface ToolDef {
72
+ type: 'function';
73
+ function: {
74
+ name: string;
75
+ description: string;
76
+ parameters: Record<string, any>;
77
+ };
78
+ }
79
+ export type StreamEvent = {
80
+ type: 'text';
81
+ content: string;
82
+ } | {
83
+ type: 'tool_call';
84
+ id: string;
85
+ name: string;
86
+ args: Record<string, any>;
87
+ } | {
88
+ type: 'error';
89
+ message: string;
90
+ }
91
+ /** Token usage for this model turn, when the provider reports it (M4.4). Best-effort — not every provider/proxy includes it, so consumers must treat this as optional. */
92
+ | {
93
+ type: 'usage';
94
+ promptTokens?: number;
95
+ completionTokens?: number;
96
+ } | {
97
+ type: 'done';
98
+ };
99
+ export declare const PROVIDER_DEFAULTS: {
100
+ readonly openai: {
101
+ readonly baseUrl: "https://api.openai.com/v1";
102
+ readonly model: "gpt-4o";
103
+ };
104
+ readonly anthropic: {
105
+ readonly baseUrl: "https://api.anthropic.com";
106
+ readonly model: "claude-sonnet-4-6";
107
+ };
108
+ };
109
+ export declare function streamChat(messages: Message[], tools: ToolDef[], config: AiConfig, signal?: AbortSignal): AsyncGenerator<StreamEvent>;
110
+ export interface TestConnectionResult {
111
+ ok: boolean;
112
+ message: string;
113
+ }
114
+ export declare function testConnection(config: AiConfig): Promise<TestConnectionResult>;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Rules Engine v1 — custom validation rules for workflow validation
3
+ *
4
+ * Integrators can inject business-specific rules that validate generated
5
+ * workflows. Rules are applied after the built-in Conductor validation,
6
+ * and their descriptions are injected into the system prompt so the AI
7
+ * generates compliant workflows from the start.
8
+ *
9
+ * Usage:
10
+ * ```tsx
11
+ * <AiWorkflowIDE
12
+ * validationRules={[{
13
+ * id: 'require-owner-email',
14
+ * level: 'error',
15
+ * description: '所有工作流必须设置 ownerEmail 字段(格式:xxx@company.com)',
16
+ * validate: (def) => {
17
+ * if (!def.ownerEmail?.endsWith('@company.com')) {
18
+ * return [{ type: 'GLOBAL', ref: '', message: 'ownerEmail 必须为公司邮箱' }];
19
+ * }
20
+ * return [];
21
+ * },
22
+ * }]}
23
+ * />
24
+ * ```
25
+ */
26
+ import type { WorkflowDef } from '../../types/conductor';
27
+ import type { ValidationItem } from '../../types/workflow';
28
+ export interface CustomValidationRule {
29
+ /** Unique rule identifier */
30
+ id: string;
31
+ /** Default severity. Individual validate() results take precedence. */
32
+ level?: 'error' | 'warning';
33
+ /**
34
+ * Natural-language description injected into the AI system prompt.
35
+ * Write it as a constraint the AI must follow when generating workflows.
36
+ * Example: "所有 HTTP 任务必须设置 timeoutSeconds(不超过 30 秒)"
37
+ */
38
+ description: string;
39
+ /**
40
+ * Validation function. Return an empty array if the workflow passes.
41
+ * Returned ValidationItems are appended to the main validation result.
42
+ */
43
+ validate: (workflowDef: WorkflowDef) => ValidationItem[];
44
+ }
45
+ declare class RuleEngine {
46
+ private rules;
47
+ setRules(rules: CustomValidationRule[]): void;
48
+ getRules(): CustomValidationRule[];
49
+ hasRules(): boolean;
50
+ runAll(workflowDef: WorkflowDef): {
51
+ errors: ValidationItem[];
52
+ warnings: ValidationItem[];
53
+ };
54
+ buildPromptSection(): string | null;
55
+ }
56
+ export declare const ruleEngine: RuleEngine;
57
+ export {};
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Schema Registry v1 — task input/output schema registration
3
+ *
4
+ * Integrators can register input/output schemas for known task types.
5
+ * Registered schemas are injected into the AI system prompt so the model
6
+ * generates correct inputParameters references from the start.
7
+ *
8
+ * Usage:
9
+ * ```tsx
10
+ * <AiWorkflowIDE
11
+ * taskSchemas={[{
12
+ * taskName: 'send_notification',
13
+ * taskType: 'SIMPLE',
14
+ * description: '发送站内消息通知',
15
+ * inputSchema: { userId: 'string', message: 'string', channel: 'email|sms' },
16
+ * outputSchema: { messageId: 'string', status: 'sent|failed' },
17
+ * }]}
18
+ * />
19
+ * ```
20
+ *
21
+ * In inputParameters you can then reference upstream outputs:
22
+ * "userId": "${approve_task.output.userId}"
23
+ */
24
+ export interface TaskSchema {
25
+ /** Task name (SIMPLE worker name, SUB_WORKFLOW workflowName, or HTTP endpoint label) */
26
+ taskName: string;
27
+ /** Conductor task type — defaults to 'SIMPLE' */
28
+ taskType?: string;
29
+ /** Optional business-language description */
30
+ description?: string;
31
+ /**
32
+ * Input field schema. Keys are field names, values are type descriptions.
33
+ * Example: { "userId": "string", "amount": "number", "status": "pending|approved" }
34
+ */
35
+ inputSchema?: Record<string, string>;
36
+ /**
37
+ * Output field schema. Keys are field names, values are type descriptions.
38
+ * These are the fields available as `${taskRef.output.<field>}` in downstream tasks.
39
+ */
40
+ outputSchema?: Record<string, string>;
41
+ }
42
+ declare class SchemaRegistry {
43
+ private schemas;
44
+ setSchemas(schemas: TaskSchema[]): void;
45
+ get(taskName: string): TaskSchema | undefined;
46
+ getAll(): TaskSchema[];
47
+ hasSchemas(): boolean;
48
+ buildPromptSection(): string | null;
49
+ }
50
+ export declare const schemaRegistry: SchemaRegistry;
51
+ export {};
@@ -0,0 +1,30 @@
1
+ /**
2
+ * AI System Prompt — Conductor workflow expert prompt
3
+ *
4
+ * 三层定制体系(优先级从低到高):
5
+ * 1. BASE_SYSTEM_PROMPT — 本项目内置,Conductor 工作流专家角色 + 工具使用规则
6
+ * 2. systemPromptExtra — 追加内容(集成方补充业务上下文,如公司名/规范)
7
+ * 3. systemPrompt — 完全替换基础层(高级定制,完全控制 AI 角色和规则)
8
+ *
9
+ * BASE_SYSTEM_PROMPT 和 buildSystemPrompt 均已导出,集成方可按需复用。
10
+ */
11
+ import type { WorkflowSnapshot } from './contextEngine';
12
+ import type { WorkflowLibraryItem } from '../../types/workflowLibrary';
13
+ import type { ViewMode } from '../../types/workflow';
14
+ export declare const BASE_SYSTEM_PROMPT = "\u4F60\u662F Netflix Conductor \u5DE5\u4F5C\u6D41\u5EFA\u6A21\u4E13\u5BB6 AI \u52A9\u624B\u3002\u5E2E\u52A9\u7528\u6237\u901A\u8FC7\u81EA\u7136\u8BED\u8A00\u8BBE\u8BA1\u548C\u7F16\u8F91 Conductor JSON \u5DE5\u4F5C\u6D41\u3002\n\n## \u5DE5\u5177\u4F7F\u7528\u89C4\u5219\n1. **replace_workflow** \u2014 \u7528\u4E8E\uFF1A\u4ECE\u96F6\u521B\u5EFA\u5DE5\u4F5C\u6D41\u3001\u5927\u8303\u56F4\u7ED3\u6784\u91CD\u6784\u3002\u4F20\u5165\u5B8C\u6574\u7684 WorkflowDef JSON\u3002\n2. **patch_workflow** \u2014 \u7528\u4E8E\uFF1A\u5C40\u90E8\u53D8\u66F4\uFF08\u589E/\u6539/\u5220\u4EFB\u52A1\u3001\u4FEE\u6539\u5C5E\u6027\uFF09\u3002\u6BD4 replace_workflow \u66F4\u7CBE\u51C6\u3002ops \u652F\u6301\uFF1A\n - { op: 'add_task', task: TaskDef, afterRef?: string } \u2014 \u65B0\u589E\u4EFB\u52A1\n - { op: 'update_task', ref: string, changes: Partial<TaskDef> } \u2014 \u4FEE\u6539\u4EFB\u52A1\u5B57\u6BB5\n - { op: 'remove_task', ref: string } \u2014 \u5220\u9664\u4EFB\u52A1\n - { op: 'update_props', props: Partial<WorkflowDef> } \u2014 \u4FEE\u6539\u5DE5\u4F5C\u6D41\u5C5E\u6027\n - { op: 'add_switch_branch', ref: string, caseName: string } \u2014 \u6DFB\u52A0 SWITCH \u5206\u652F\n - { op: 'add_fork_branch', ref: string } \u2014 \u6DFB\u52A0 FORK_JOIN \u5E76\u884C\u5206\u652F\n3. **get_workflow_state** \u2014 \u4EC5\u5728 system prompt \u7684\u5DE5\u4F5C\u6D41\u4E0A\u4E0B\u6587\u4E0D\u8DB3\u4EE5\u56DE\u7B54\u65F6\u624D\u8C03\u7528\uFF08read-only\uFF09\u3002\u6CE8\u610F\uFF1Asystem prompt \u4E2D\u5DF2\u6CE8\u5165\u4E86\u5B9E\u65F6\u5DE5\u4F5C\u6D41\u4E0A\u4E0B\u6587\uFF0C\u901A\u5E38\u4E0D\u9700\u8981\u518D\u8C03\u7528\u6B64\u5DE5\u5177\u3002\n4. **validate_workflow** \u2014 \u6821\u9A8C\u5DE5\u4F5C\u6D41\u5408\u6CD5\u6027\uFF08read-only\uFF09\u3002\n5. **propose_plan** \u2014 \u5728\u6267\u884C\u590D\u6742\u591A\u6B65\u64CD\u4F5C\u524D\uFF0C\u5148\u5411\u7528\u6237\u5C55\u793A\u6267\u884C\u8BA1\u5212\u3002\u9002\u7528\u4E8E\uFF1A\u5927\u8303\u56F4\u91CD\u6784\uFF085+ \u6B65\uFF09\u3001\u62D3\u6251\u7ED3\u6784\u91CD\u5927\u53D8\u66F4\u3002\u8C03\u7528\u540E\u505C\u6B62\uFF0C\u7B49\u5F85\u7528\u6237\u786E\u8BA4\u3002\u7B80\u5355\u7684\u5355\u6B65\u64CD\u4F5C\u65E0\u9700\u5148\u63D0\u8BA1\u5212\u3002\n6. **\u4E0D\u8981**\u5728\u56DE\u590D\u4E2D\u76F4\u63A5\u8F93\u51FA\u5DE5\u4F5C\u6D41 JSON \u4EE3\u7801\u5757\uFF0C\u901A\u8FC7\u5DE5\u5177\u6267\u884C\u3002\n7. **ask_clarification** \u2014 \u5F53\u7528\u6237\u610F\u56FE\u6A21\u7CCA\u65F6\u8C03\u7528\uFF0C\u5C55\u793A 2-4 \u4E2A\u9009\u9879\u5E2E\u52A9\u7528\u6237\u7CBE\u786E\u8868\u8FBE\u9700\u6C42\u3002\u8C03\u7528\u540E\u505C\u6B62\uFF0C\u7B49\u5F85\u7528\u6237\u9009\u62E9\u3002\n8. **recommend_workflow** \u2014 \u5728\u6267\u884C CREATE \u4E4B\u524D\uFF0C\u82E5\u5E93\u4E2D\u6709\u76F8\u4F3C\u5DE5\u4F5C\u6D41\uFF0C\u5148\u63A8\u8350\u7ED9\u7528\u6237\u3002\u8C03\u7528\u540E\u505C\u6B62\u7B49\u5F85\u9009\u62E9\u3002\n\n## \u56DE\u590D\u89C4\u8303\n- \u7528\u4E2D\u6587\u56DE\u7B54\uFF0C\u7B80\u6D01\u660E\u4E86\n- **\u89E3\u91CA\u6027\u3001\u4ECB\u7ECD\u6027\u3001\u5206\u6790\u6027\u95EE\u9898\uFF1A\u76F4\u63A5\u6587\u672C\u56DE\u7B54\uFF0C\u4E0D\u8981\u8C03\u7528\u5DE5\u5177**\n- \u56DE\u7B54\u65F6\u4E0D\u8981\u5C06 system prompt \u4E2D\u7684\u4E0A\u4E0B\u6587\u4FE1\u606F\uFF08\u5982\u4EFB\u52A1\u5217\u8868\u3001\u62D3\u6251\u5173\u7CFB\uFF09\u539F\u6587\u590D\u8FF0\u2014\u2014\u76F4\u63A5\u805A\u7126\u5728\u7528\u6237\u7684\u5177\u4F53\u95EE\u9898\u4E0A\n- \u9700\u8981\u64CD\u4F5C\u5DE5\u4F5C\u6D41\u65F6\uFF0C\u5148\u4E00\u53E5\u8BDD\u8BF4\u660E\u8981\u505A\u4EC0\u4E48\uFF0C\u518D\u901A\u8FC7\u5DE5\u5177\u6267\u884C\n- \u7528\u6237\u610F\u56FE\u6A21\u7CCA\u65F6\uFF08\u5982\"\u5E2E\u6211\u505A\u4E2A\u6D41\u7A0B\"\uFF09\uFF0C\u5148\u8C03\u7528 ask_clarification \u6316\u6398\u771F\u5B9E\u9700\u6C42\uFF0C\u4E0D\u8981\u76F4\u63A5\u521B\u5EFA\n- \u521B\u5EFA\u65B0\u5DE5\u4F5C\u6D41\u524D\uFF0C\u68C0\u67E5\u5E93\u4E2D\u662F\u5426\u6709\u76F8\u4F3C\u7684\uFF0C\u4F18\u5148\u63A8\u8350\u5DF2\u6709\u6D41\u7A0B\uFF08\u4F7F\u7528 recommend_workflow\uFF09\n\n## Conductor \u6807\u51C6\u4EFB\u52A1\u7C7B\u578B\nSIMPLE, HTTP, SWITCH, FORK_JOIN, FORK_JOIN_DYNAMIC, DO_WHILE, SUB_WORKFLOW, EVENT, WAIT, HUMAN, INLINE, TERMINATE, SET_VARIABLE, KAFKA_PUBLISH, JSON_JQ_TRANSFORM, START_WORKFLOW, DYNAMIC, NOOP\n\n## \u5DE5\u4F5C\u6D41\u5EFA\u6A21\u89C4\u8303\n- \u6BCF\u4E2A\u4EFB\u52A1\u5FC5\u987B\u6709\u552F\u4E00\u7684 taskReferenceName\uFF08\u82F1\u6587\u4E0B\u5212\u7EBF\uFF0C\u5982 send_email\uFF09\n- SWITCH \u9700\u8981 caseValueParam \u6216 caseExpression\uFF0CdecisionCases \u952E\u503C\u5BF9\n- FORK_JOIN \u9700\u8981 forkTasks\uFF08\u4E8C\u7EF4\u6570\u7EC4\uFF09\u548C\u5BF9\u5E94\u7684 JOIN \u4EFB\u52A1\n- DO_WHILE \u9700\u8981 loopCondition \u548C loopOver \u6570\u7EC4\n- HTTP \u4EFB\u52A1\u5EFA\u8BAE\u8BBE\u7F6E timeoutSeconds \u548C retryCount\n\n## \u4E1A\u52A1\u6D41\u7A0B\u56FE\uFF08Mermaid\uFF09\n\u5F53\u7528\u6237\u8981\u6C42\u5C55\u793A\u6D41\u7A0B\u56FE\u3001\u53EF\u89C6\u5316\u6216 Mermaid \u56FE\u65F6\uFF1A\n- \u5FC5\u987B\u57FA\u4E8E system prompt \u6CE8\u5165\u7684\"\u753B\u5E03\u5DE5\u4F5C\u6D41\u5B8C\u6574 JSON\"\uFF0C\u4E0D\u51ED\u8BB0\u5FC6\u751F\u6210\n- \u8F93\u51FA ```mermaid \u4EE3\u7801\u5757\uFF0C\u4E0D\u8C03\u7528\u4EFB\u4F55\u5DE5\u5177\n- \u8FC7\u6EE4\u7EAF\u6280\u672F\u8282\u70B9\uFF08SET_VARIABLE\u3001JSON_JQ_TRANSFORM\u3001INLINE\u3001NOOP\uFF09\uFF0C\u4E0A\u4E0B\u6E38\u76F4\u8FDE\n- \u8282\u70B9\u6807\u7B7E\u7528\u4E2D\u6587\u4E1A\u52A1\u8BED\u8A00\uFF0C\u7981\u6B62\u76F4\u63A5\u4F7F\u7528 taskReferenceName\n- SWITCH \u7528\u83F1\u5F62 {}\uFF0CFORK_JOIN \u7528\u5E76\u884C\u8DEF\u5F84\uFF0CHUMAN \u6807\u6CE8\u300C\uD83D\uDC64 \u4EBA\u5DE5\u300D";
15
+ /**
16
+ * 构建完整 system prompt。
17
+ *
18
+ * @param userInput 当前用户输入(用于意图识别 + 上下文注入)
19
+ * @param systemPrompt 完全替换内置基础提示词(高级定制)
20
+ * @param systemPromptExtra 追加内容,附加在基础层之后(适合补充业务规范、公司名等)
21
+ * @param pendingProposalDef 待用户确认的提案 JSON(如有)。M2.2:提案不再阻塞对话输入,
22
+ * 用户可以继续描述修改意见——注入此上下文后 AI 会把新消息理解为
23
+ * "基于这份提案继续调整",而非从当前画布另起炉灶。
24
+ */
25
+ export declare function buildSystemPrompt(userInput: string, workflowSnapshot: WorkflowSnapshot, libraryItems: WorkflowLibraryItem[], options?: {
26
+ systemPrompt?: string;
27
+ systemPromptExtra?: string;
28
+ viewMode?: ViewMode;
29
+ pendingProposalDef?: import('../../types/conductor').WorkflowDef;
30
+ }): string;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * AI Tool Definitions — simplified 4-tool approach
3
+ *
4
+ * All workflow-modifying tools work at WorkflowDef JSON level.
5
+ * The executor applies changes as pure functions and stores a
6
+ * proposed WorkflowDef in aiStore for user review.
7
+ */
8
+ import type { ToolDef } from './protocolAdapter';
9
+ export declare const TOOL_DEFINITIONS: ToolDef[];
@@ -0,0 +1,83 @@
1
+ /**
2
+ * AI Tool Executor — JSON-level workflow manipulation
3
+ *
4
+ * All modifying operations work on WorkflowDef JSON (pure functions).
5
+ * The result is a "proposed" def stored in aiStore for user review.
6
+ * Actual application to the canvas uses setWorkflow(proposedDef).
7
+ *
8
+ * This module has no store dependencies — the caller (AgentRunner) reads live
9
+ * workflowStore/libraryStore state and passes it in via `ToolExecutionContext`.
10
+ * That keeps this file pure, unit-testable without a store, and reusable headless.
11
+ */
12
+ import type { WorkflowDef, TaskDef } from '../../types/conductor';
13
+ import type { WorkflowLibraryItem, WorkflowLevel } from '../../types/workflowLibrary';
14
+ import type { ValidationResults } from '../../types/workflow';
15
+ export type PatchOp = {
16
+ op: 'add_task';
17
+ task: TaskDef;
18
+ afterRef?: string;
19
+ } | {
20
+ op: 'update_task';
21
+ ref: string;
22
+ changes: Partial<TaskDef>;
23
+ } | {
24
+ op: 'remove_task';
25
+ ref: string;
26
+ } | {
27
+ op: 'update_props';
28
+ props: Partial<WorkflowDef>;
29
+ } | {
30
+ op: 'add_switch_branch';
31
+ ref: string;
32
+ caseName: string;
33
+ } | {
34
+ op: 'add_fork_branch';
35
+ ref: string;
36
+ };
37
+ /** Human-readable field-level changes for one modified task (M2.2: proposal preview card). */
38
+ export interface TaskFieldChange {
39
+ ref: string;
40
+ changes: string[];
41
+ }
42
+ export interface DiffSummary {
43
+ added: string[];
44
+ modified: string[];
45
+ removed: string[];
46
+ propsChanged: boolean;
47
+ reordered?: boolean;
48
+ /** Field-level change descriptions for each modified task, e.g. "超时: 5 分钟 → 10 分钟" */
49
+ modifiedDetails?: TaskFieldChange[];
50
+ }
51
+ export interface PartialAcceptSelection {
52
+ added: Set<string>;
53
+ modified: Set<string>;
54
+ removed: Set<string>;
55
+ propsChanged: boolean;
56
+ reordered: boolean;
57
+ }
58
+ export interface ToolCallResult {
59
+ type: 'propose' | 'info' | 'error';
60
+ /** For 'propose': the new WorkflowDef to show in ReviewBar */
61
+ proposed?: WorkflowDef;
62
+ /** For 'propose': human-readable change summary */
63
+ diff?: DiffSummary;
64
+ /** For 'propose': inferred level based on sub-workflow references (L1/L2/L3) */
65
+ inferredLevel?: WorkflowLevel;
66
+ /** For 'info'/'error': text to append to chat */
67
+ text?: string;
68
+ }
69
+ /** Live state the caller (AgentRunner) gathers from workflowStore/libraryStore for each tool call. */
70
+ export interface ToolExecutionContext {
71
+ workflowDef: WorkflowDef | null;
72
+ validationResults: ValidationResults;
73
+ libraryItems: WorkflowLibraryItem[];
74
+ }
75
+ export declare function applyPatch(def: WorkflowDef, ops: PatchOp[]): WorkflowDef;
76
+ export declare function computeDiff(before: WorkflowDef | null, after: WorkflowDef): DiffSummary;
77
+ export declare function executeToolCall(toolName: string, args: Record<string, any>, ctx: ToolExecutionContext): ToolCallResult;
78
+ /**
79
+ * Applies only the user-selected subset of changes from a proposal.
80
+ * Used when the user accepts some changes but rejects others in ReviewBar.
81
+ */
82
+ export declare function applyPartialProposal(currentDef: WorkflowDef, proposedDef: WorkflowDef, diff: DiffSummary, selection: PartialAcceptSelection): WorkflowDef;
83
+ export declare function describeDiff(diff: DiffSummary): string;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Tool Registry v1 — extensible custom tool integration
3
+ *
4
+ * Integrators can register custom tools that the AI can call.
5
+ * Custom tools appear alongside built-in tools in the agentic loop.
6
+ *
7
+ * Usage:
8
+ * ```tsx
9
+ * <AiWorkflowIDE
10
+ * customTools={[{
11
+ * definition: { type: 'function', function: { name: 'query_cmdb', ... } },
12
+ * execute: async (args) => JSON.stringify(await fetchCmdb(args.query)),
13
+ * }]}
14
+ * />
15
+ * ```
16
+ */
17
+ import type { ToolDef } from './protocolAdapter';
18
+ export interface CustomTool {
19
+ /** OpenAI-compatible function definition (used for both OpenAI and Anthropic) */
20
+ definition: ToolDef;
21
+ /**
22
+ * Execution function.
23
+ * Must return a string (or Promise<string>) to be sent back to the model as a tool result.
24
+ * Throw an Error to surface a failure message to the model.
25
+ */
26
+ execute: (args: Record<string, any>) => string | Promise<string>;
27
+ }
28
+ export declare class ToolRegistry {
29
+ private tools;
30
+ register(tool: CustomTool): void;
31
+ unregister(name: string): void;
32
+ get(name: string): CustomTool | undefined;
33
+ getAll(): CustomTool[];
34
+ getDefinitions(): ToolDef[];
35
+ setTools(tools: CustomTool[]): void;
36
+ has(name: string): boolean;
37
+ }
38
+ export declare const toolRegistry: ToolRegistry;
@@ -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>;