@shenghuabi/workflow 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 (70) hide show
  1. package/index.d.ts +14 -0
  2. package/index.js +2078 -0
  3. package/index.js.map +7 -0
  4. package/index.mjs +2035 -0
  5. package/index.mjs.map +7 -0
  6. package/inline/inline.service.d.ts +8 -0
  7. package/inline/node/chat/chat.node.define.d.ts +185 -0
  8. package/inline/node/chat/common.d.ts +2 -0
  9. package/inline/node/chat/main/index.d.ts +209 -0
  10. package/inline/node/chat/main/llm.runner.d.ts +41 -0
  11. package/inline/node/chat/util.d.ts +8 -0
  12. package/inline/node/chat/webview/index.d.ts +2 -0
  13. package/inline/node/index.browser.d.ts +2 -0
  14. package/inline/node/index.node.d.ts +2 -0
  15. package/inline/node/text/common.d.ts +2 -0
  16. package/inline/node/text/main/index.d.ts +30 -0
  17. package/inline/node/text/main/textarea.runner.d.ts +7 -0
  18. package/inline/node/text/text.node.define.d.ts +6 -0
  19. package/inline/node/text/webview/index.d.ts +2 -0
  20. package/module.d.ts +23 -0
  21. package/package.json +52 -0
  22. package/plugin/plugin.service.d.ts +7 -0
  23. package/preset/context-build.service.d.ts +102 -0
  24. package/preset/inline-build.service.d.ts +11 -0
  25. package/preset/inline-runner.service.d.ts +16 -0
  26. package/runner/define.d.ts +12 -0
  27. package/runner/inline-input-item.runner.d.ts +8 -0
  28. package/runner/input-params.runner.d.ts +7 -0
  29. package/runner/iteration-start.runner.d.ts +7 -0
  30. package/runner/iteration.runner.d.ts +7 -0
  31. package/runner/parameters.runner.d.ts +10 -0
  32. package/runner/runner-error.d.ts +12 -0
  33. package/runner/runner-item.d.ts +35 -0
  34. package/runner/workflow-runner.service.d.ts +35 -0
  35. package/share/common/const.d.ts +2 -0
  36. package/share/common/define.d.ts +71 -0
  37. package/share/common/examples.define.d.ts +53 -0
  38. package/share/common/handle.define.d.ts +5 -0
  39. package/share/common/index.d.ts +5 -0
  40. package/share/common/inline-template.define.d.ts +15 -0
  41. package/share/common/llm.define.d.ts +29 -0
  42. package/share/const.d.ts +5 -0
  43. package/share/handle-node.d.ts +60 -0
  44. package/share/index.d.ts +8 -0
  45. package/share/index.js +336 -0
  46. package/share/index.js.map +7 -0
  47. package/share/index.mjs +296 -0
  48. package/share/index.mjs.map +7 -0
  49. package/share/type.d.ts +89 -0
  50. package/share/type2.d.ts +132 -0
  51. package/share/util/layout.d.ts +2 -0
  52. package/share/util.d.ts +5 -0
  53. package/share/workflow.const.d.ts +8 -0
  54. package/share/workflow.emit.d.ts +9 -0
  55. package/template-format.service.d.ts +29 -0
  56. package/test/chat.spec.d.ts +1 -0
  57. package/test/file.spec.d.ts +1 -0
  58. package/test/hello.spec.d.ts +1 -0
  59. package/test/plugin.spec.d.ts +1 -0
  60. package/token.d.ts +68 -0
  61. package/type/type.d.ts +5 -0
  62. package/webview/index.d.ts +1 -0
  63. package/webview/index.js +399 -0
  64. package/webview/index.js.map +7 -0
  65. package/webview/index.mjs +388 -0
  66. package/webview/index.mjs.map +7 -0
  67. package/workflow-exec.service.d.ts +41 -0
  68. package/workflow-file.service.d.ts +9 -0
  69. package/workflow-parser.service.d.ts +24 -0
  70. package/workflow-select.service.d.ts +13 -0
package/index.mjs ADDED
@@ -0,0 +1,2035 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // packages/workflow/workflow-parser.service.ts
8
+ import {
9
+ computed as computed3,
10
+ createInjector,
11
+ inject as inject4,
12
+ InjectionToken as InjectionToken2,
13
+ Injector as Injector2
14
+ } from "static-injector";
15
+ import Graph from "graphology";
16
+ import {
17
+ getConnectedEdges,
18
+ getIncomers,
19
+ getOutgoers
20
+ } from "@xyflow/react";
21
+
22
+ // packages/workflow/share/workflow.const.ts
23
+ var WorkflowNodeType = /* @__PURE__ */ ((WorkflowNodeType2) => {
24
+ WorkflowNodeType2["iteration"] = "iteration";
25
+ WorkflowNodeType2["iterationStart"] = "iteration-start";
26
+ WorkflowNodeType2["inputParams"] = "input-params";
27
+ WorkflowNodeType2["serialize"] = "serialize";
28
+ WorkflowNodeType2["parameters"] = "parameters";
29
+ WorkflowNodeType2["inlineInputItem"] = "inlineInputItem";
30
+ return WorkflowNodeType2;
31
+ })(WorkflowNodeType || {});
32
+
33
+ // packages/workflow/workflow-parser.service.ts
34
+ import { uniqBy as uniqBy3 } from "es-toolkit";
35
+
36
+ // packages/workflow/share/handle-node.ts
37
+ function flatFilterHandleList(list) {
38
+ if (!list) {
39
+ return [];
40
+ }
41
+ return list.flat().filter(Boolean);
42
+ }
43
+
44
+ // packages/workflow/inline/inline.service.ts
45
+ var InlineNodeService = class {
46
+ inlineList = [];
47
+ register(obj) {
48
+ Object.values(obj).forEach((item) => {
49
+ this.inlineList.push(item);
50
+ });
51
+ }
52
+ getInlineList() {
53
+ return this.inlineList;
54
+ }
55
+ conditionNodeList() {
56
+ return this.inlineList.filter((item) => item.nodeMode === "condition").reduce(
57
+ (obj, item) => {
58
+ obj[item.type] = true;
59
+ return obj;
60
+ },
61
+ {}
62
+ );
63
+ }
64
+ // todo 类型
65
+ getNodeRunner(type) {
66
+ return this.inlineList.find((item) => item.type === type)?.runner;
67
+ }
68
+ };
69
+
70
+ // packages/workflow/plugin/plugin.service.ts
71
+ import { computed, signal } from "static-injector";
72
+ var WorkflowPluginService = class {
73
+ nodeList = signal([]);
74
+ setNodeObject(obj) {
75
+ this.nodeList.set(obj);
76
+ }
77
+ conditionNodeList$$ = computed(
78
+ () => this.nodeList().filter((item) => item.nodeMode === "condition").reduce(
79
+ (obj, item) => {
80
+ obj[item.type] = true;
81
+ return obj;
82
+ },
83
+ {}
84
+ )
85
+ );
86
+ // todo 类型
87
+ getNodeRunner(type) {
88
+ return this.nodeList().find((item) => item.type === type).runner;
89
+ }
90
+ };
91
+
92
+ // packages/workflow/inline/node/index.node.ts
93
+ var index_node_exports = {};
94
+ __export(index_node_exports, {
95
+ ChatMainConfig: () => ChatMainConfig,
96
+ TextMainConfig: () => TextMainConfig
97
+ });
98
+
99
+ // packages/workflow/share/const.ts
100
+ var DEFAULT_INPUT_KEY = `[INPUT]`;
101
+ var HelpObj = {
102
+ templateVarLine: `- 变量定义格式: {{xx}},{{xx.yy}}`,
103
+ pathTodoLine: `- **TODO** 接收传入路径而不是指定`
104
+ };
105
+
106
+ // packages/workflow/share/util.ts
107
+ import { v5 } from "uuid";
108
+ var UUID_NS = "404cfae8-94e7-41a6-acec-1037dd1fdaad";
109
+ function generateHandle(value, label = value) {
110
+ return { id: v5(value, UUID_NS), label, value };
111
+ }
112
+
113
+ // packages/workflow/share/common/examples.define.ts
114
+ import {
115
+ condition,
116
+ patchWrappers,
117
+ renderConfig,
118
+ topClass
119
+ } from "@piying/view-angular-core";
120
+ import * as v from "valibot";
121
+
122
+ // packages/workflow/share/util/layout.ts
123
+ import { componentClass } from "@piying/view-angular-core";
124
+ function asColumn() {
125
+ return componentClass("grid gap-2");
126
+ }
127
+
128
+ // packages/workflow/share/common/examples.define.ts
129
+ var EXAMPLES_DEFINE = v.pipe(
130
+ v.optional(
131
+ v.array(
132
+ v.pipe(
133
+ v.object({
134
+ input: v.pipe(
135
+ v.object({
136
+ format: v.pipe(
137
+ v.optional(v.boolean(), false),
138
+ v.description(
139
+ "选中后会尝试使用yaml解析为对象,再序列化为对应的响应类型"
140
+ ),
141
+ patchWrappers(["tooltip"])
142
+ ),
143
+ value: v.pipe(v.string(), v.title("问题"), topClass("flex-1"))
144
+ }),
145
+ // todo 待修复
146
+ topClass("flex gap-2 items-center")
147
+ ),
148
+ output: v.pipe(
149
+ v.object({
150
+ format: v.pipe(
151
+ v.optional(v.boolean(), false),
152
+ v.description("是否需要格式化"),
153
+ patchWrappers(["tooltip"])
154
+ ),
155
+ value: v.pipe(v.string(), v.title("回答"), topClass("flex-1"))
156
+ }),
157
+ topClass("flex gap-2 items-center")
158
+ )
159
+ }),
160
+ asColumn()
161
+ )
162
+ ),
163
+ []
164
+ ),
165
+ v.title("用例"),
166
+ v.description("回答问题之前,会参考定义的用例格式进行回复,用于规范回答"),
167
+ condition({
168
+ environments: ["display"],
169
+ actions: [
170
+ renderConfig({
171
+ hidden: true
172
+ })
173
+ ]
174
+ })
175
+ );
176
+
177
+ // packages/workflow/share/common/handle.define.ts
178
+ import * as v2 from "valibot";
179
+ import { renderConfig as renderConfig2, setComponent } from "@piying/view-angular-core";
180
+ import { condition as condition2 } from "@piying/valibot-visit";
181
+ var HiddenAction = condition2({
182
+ environments: ["display", "default"],
183
+ actions: [setComponent(""), renderConfig2({ hidden: true })]
184
+ });
185
+ var AnyHiddenList = v2.pipe(
186
+ v2.array(v2.pipe(v2.optional(v2.any()), HiddenAction)),
187
+ setComponent(""),
188
+ renderConfig2({ hidden: true })
189
+ );
190
+ var HandleDataDefine = v2.pipe(
191
+ v2.optional(
192
+ v2.object({
193
+ output: AnyHiddenList,
194
+ input: AnyHiddenList
195
+ })
196
+ ),
197
+ HiddenAction
198
+ );
199
+
200
+ // packages/workflow/share/common/inline-template.define.ts
201
+ import {
202
+ componentClass as componentClass2,
203
+ disableWhen,
204
+ setWrappers,
205
+ topClass as topClass2
206
+ } from "@piying/view-angular-core";
207
+ import { map } from "rxjs";
208
+ import * as v3 from "valibot";
209
+ var INLINE_Template = v3.pipe(
210
+ v3.object({
211
+ enable: v3.optional(v3.boolean(), true),
212
+ // 经用条件
213
+ value: v3.pipe(
214
+ v3.optional(v3.string(), "{{NODE.description}}"),
215
+ v3.title("模板"),
216
+ v3.description("允许使用变量:{{NODE.xxx}}(参考节点帮助)"),
217
+ setWrappers(["tooltip", "form-field"]),
218
+ topClass2("flex-1"),
219
+ disableWhen({
220
+ listen: (fn) => fn({
221
+ list: [["..", "enable"]]
222
+ }).pipe(map(({ list }) => !list[0]))
223
+ })
224
+ )
225
+ }),
226
+ componentClass2("flex gap-2")
227
+ );
228
+ var INLINE_Template2 = v3.pipe(
229
+ v3.object({
230
+ enable: v3.optional(v3.boolean(), false),
231
+ // 经用条件
232
+ value: v3.pipe(
233
+ v3.optional(v3.string()),
234
+ v3.title("模板"),
235
+ v3.description("允许使用变量:{{ENTRY.xxx}}(参考节点帮助)"),
236
+ setWrappers(["tooltip", "form-field"]),
237
+ topClass2("flex-1"),
238
+ disableWhen({
239
+ listen: (fn) => fn({
240
+ list: [["..", "enable"]]
241
+ }).pipe(map(({ list }) => !list[0]))
242
+ })
243
+ )
244
+ }),
245
+ componentClass2("flex gap-2 items-center")
246
+ );
247
+
248
+ // packages/workflow/share/common/llm.define.ts
249
+ import {
250
+ asVirtualGroup,
251
+ patchAsyncInputs,
252
+ setComponent as setComponent2
253
+ } from "@piying/view-angular-core";
254
+ import { condition as condition3 } from "@piying/valibot-visit";
255
+ import * as v4 from "valibot";
256
+ function llmModelConfig(item) {
257
+ return v4.pipe(
258
+ v4.intersect([
259
+ v4.pipe(
260
+ v4.intersect([
261
+ v4.pipe(
262
+ v4.object({
263
+ name: v4.pipe(
264
+ v4.optional(v4.string()),
265
+ v4.title("预定义模型配置"),
266
+ setComponent2("select"),
267
+ patchAsyncInputs({
268
+ options: (field) => field.context.getModelList()
269
+ })
270
+ ),
271
+ model: v4.pipe(v4.optional(v4.string()), v4.title("模型")),
272
+ // todo 配置变化configuration层被去掉.这里应该更详细支持更多参数
273
+ baseURL: v4.pipe(v4.optional(v4.string()), v4.title("地址"))
274
+ }),
275
+ asColumn()
276
+ )
277
+ ]),
278
+ v4.title(item?.label ?? "对话模型"),
279
+ condition3({
280
+ environments: ["display", "config"],
281
+ actions: [asVirtualGroup()]
282
+ })
283
+ )
284
+ ]),
285
+ condition3({
286
+ environments: ["display", "config"],
287
+ actions: [asVirtualGroup()]
288
+ }),
289
+ setComponent2("accordion")
290
+ );
291
+ }
292
+
293
+ // packages/workflow/share/common/const.ts
294
+ var DEFAULT_CHAT_SCHEMA_KEY = `[JsonSchema]`;
295
+ var RUNNER_ORIGIN_OUTPUT_KEY = `[Origin]`;
296
+
297
+ // packages/workflow/share/type2.ts
298
+ import { v4 as v42 } from "uuid";
299
+ import * as v6 from "valibot";
300
+ var extraData = v6.looseObject({
301
+ references: v6.optional(v6.array(v6.custom(Boolean)))
302
+ });
303
+ var baseDataDefine = v6.object({
304
+ node: v6.object({ type: v6.string(), id: v6.string() }),
305
+ nodeResult: v6.pipe(v6.optional(v6.boolean(), false)),
306
+ dataId: v6.optional(v6.string(), () => v42()),
307
+ extra: v6.optional(extraData)
308
+ });
309
+ var CommonDataDefine = v6.object({
310
+ ...baseDataDefine.entries,
311
+ value: v6.any()
312
+ });
313
+ var LLMDataDefine = v6.object({
314
+ ...baseDataDefine.entries,
315
+ type: v6.optional(v6.literal("chat-stream"), "chat-stream"),
316
+ // 用来进行普通查询
317
+ value: v6.string(),
318
+ extra: v6.object({
319
+ ...extraData.entries,
320
+ content: v6.string(),
321
+ thinkContent: v6.optional(v6.string()),
322
+ isThinking: v6.optional(v6.boolean()),
323
+ delta: v6.string(),
324
+ historyList: v6.custom(Boolean)
325
+ })
326
+ });
327
+ function createLLMData(data) {
328
+ return v6.parse(LLMDataDefine, data);
329
+ }
330
+ function createResultData(data) {
331
+ const result = v6.parse(CommonDataDefine, data);
332
+ result.nodeResult = true;
333
+ return result;
334
+ }
335
+ function isChatStream(data) {
336
+ return !!data.extra && "content" in data.extra && "thinkContent" in data.extra;
337
+ }
338
+
339
+ // packages/workflow/share/workflow.emit.ts
340
+ var WorkflowEmitter = class {
341
+ #ob;
342
+ setObserver(ob) {
343
+ this.#ob = ob;
344
+ }
345
+ getObserver() {
346
+ return this.#ob;
347
+ }
348
+ createLLMData = createLLMData;
349
+ send(data) {
350
+ if (this.#ob) {
351
+ this.#ob.next(data);
352
+ }
353
+ }
354
+ };
355
+
356
+ // packages/workflow/inline/node/chat/common.ts
357
+ var NODE_COMMON = {
358
+ priority: -100,
359
+ type: "chat",
360
+ label: `对话`,
361
+ icon: { fontIcon: "chat" },
362
+ disableHead: false,
363
+ disableConnect: false,
364
+ color: "accent",
365
+ help: [
366
+ `- 点击输入框左侧图标可以切换或添加新行`,
367
+ `${HelpObj.templateVarLine}`,
368
+ "### 指定类型输出",
369
+ "- `JsonSchema`为可选输入,需要使用`代码`节点生成",
370
+ "> 设置后响应类型会自动变为json",
371
+ "> 也可以使用任何符合`ChatJsonSchema`类型的数据结构传入(`代码`节点编辑时有声明)",
372
+ "- 原始输出: 不进行任何格式化处理的输出",
373
+ "### 定义图片变量",
374
+ "- 只有支持图片传入的大语言模型才支持此选项",
375
+ "> 如`minicpm-v:8b`",
376
+ "- 定义后在对话中可以传入图片",
377
+ "- 或者可以使用`图片输入`节点手动指定一张图片",
378
+ "- 只有`用户提示词`可以使用图片输入",
379
+ "> 不清楚是否所有模型都遵循此规则,所以并没有限制输入"
380
+ ].join("\n"),
381
+ // config: defineConfig,
382
+ inputs: [
383
+ [],
384
+ [
385
+ {
386
+ label: "JsonSchema",
387
+ value: DEFAULT_CHAT_SCHEMA_KEY,
388
+ inputType: "schema",
389
+ optional: true
390
+ }
391
+ ]
392
+ ],
393
+ outputs: [[{ label: "原始输出", value: RUNNER_ORIGIN_OUTPUT_KEY }]]
394
+ };
395
+
396
+ // packages/workflow/inline/node/chat/chat.node.define.ts
397
+ import * as v7 from "valibot";
398
+ import {
399
+ componentClass as componentClass3,
400
+ condition as condition4,
401
+ patchInputs,
402
+ setComponent as setComponent3,
403
+ valueChange
404
+ } from "@piying/view-angular-core";
405
+ var ResponseList = ["json", "markdown", "yaml"];
406
+ var ResponseFormat = ["text", "json_object", "json_schema"];
407
+ var CHAT_NODE_DEFINE = v7.looseObject({
408
+ data: v7.looseObject({
409
+ config: v7.pipe(
410
+ v7.object({
411
+ llm: v7.optional(llmModelConfig()),
412
+ /** 处理时解析 */
413
+ responseFormat: v7.pipe(
414
+ v7.optional(v7.picklist(ResponseFormat)),
415
+ patchInputs({
416
+ options: [
417
+ // 有输入json时
418
+ {
419
+ label: "自动",
420
+ value: void 0,
421
+ description: `传入JsonSchema时为[json_schema],否则为[text]`
422
+ },
423
+ { label: "文本", value: "text" },
424
+ {
425
+ label: "JSON对象",
426
+ value: "json_object",
427
+ description: "只限制返回类型为JSON对象,不对字段进行限制"
428
+ },
429
+ {
430
+ label: "JSON格式定义",
431
+ value: "json_schema",
432
+ description: "限制返回类型为JSON对象,同时限制字段,不建议手动指定,传入JsonSchema后自动启用"
433
+ }
434
+ ]
435
+ }),
436
+ v7.title("响应格式")
437
+ ),
438
+ /** 处理后解析 */
439
+ parseBy: v7.pipe(
440
+ v7.optional(v7.picklist(ResponseList)),
441
+ patchInputs({
442
+ options: [
443
+ { label: "直接返回", value: void 0 },
444
+ {
445
+ label: "json",
446
+ value: "json",
447
+ description: `将返回的json代码块内容或原始内容解析为对象`
448
+ },
449
+ {
450
+ label: "markdown",
451
+ value: "markdown",
452
+ description: `[需要提示词约束]将返回其中的markdown代码块内容或原始内容`
453
+ },
454
+ {
455
+ label: "yaml",
456
+ value: "yaml",
457
+ description: `[需要提示词约束]将返回的yaml代码块内容或原始内容解析为对象`
458
+ }
459
+ ]
460
+ }),
461
+ v7.title("返回解析"),
462
+ valueChange((fn) => {
463
+ fn({ list: [["..", "responseFormat"]] }).subscribe(
464
+ ({ list: [value], field }) => {
465
+ if ((value ?? "").startsWith("json")) {
466
+ if (!field.form.control.value) {
467
+ field.form.control.updateValue("json");
468
+ }
469
+ }
470
+ }
471
+ );
472
+ })
473
+ ),
474
+ examples: EXAMPLES_DEFINE
475
+ }),
476
+ componentClass3("grid auto-rows-auto gap-2")
477
+ ),
478
+ value: v7.pipe(
479
+ v7.custom(Boolean),
480
+ setComponent3(""),
481
+ condition4({
482
+ environments: ["display"],
483
+ actions: [
484
+ setComponent3("prompt-list"),
485
+ valueChange((fn) => {
486
+ fn({ list: [void 0] }).subscribe(({ list: [value], field }) => {
487
+ if (!Array.isArray(value)) {
488
+ return;
489
+ }
490
+ const inputValue = value ?? [];
491
+ field.context.parseTemplate(
492
+ inputValue.flatMap(
493
+ (item) => item.content.map(
494
+ (item2) => item2.type === "text" ? item2.text : ""
495
+ )
496
+ )
497
+ ).then((value2) => {
498
+ if (!value2) {
499
+ return;
500
+ }
501
+ field.context.changeHandleData(field, "input", 1, value2);
502
+ });
503
+ const list = inputValue.flatMap(
504
+ (item) => item.content.map(
505
+ (item2) => item2.type === "image_url" ? item2.image_url.url : void 0
506
+ )
507
+ ).filter(Boolean).map((item) => ({
508
+ value: `${item}`,
509
+ label: `${item}`,
510
+ inputType: `image`
511
+ }));
512
+ field.context.changeHandleData(field, "input", 3, list ?? []);
513
+ });
514
+ })
515
+ ]
516
+ })
517
+ )
518
+ })
519
+ });
520
+
521
+ // packages/workflow/inline/node/chat/main/llm.runner.ts
522
+ import { inject as inject2 } from "static-injector";
523
+ import { parse as parse2 } from "yaml";
524
+ import { uniqBy as uniqBy2 } from "es-toolkit";
525
+
526
+ // packages/openai/chat/util/create.ts
527
+ function createAssistantMessage(text = "") {
528
+ return {
529
+ role: "assistant",
530
+ content: [{ type: "text", text }]
531
+ };
532
+ }
533
+
534
+ // packages/workflow/inline/node/chat/main/llm.runner.ts
535
+ import { LogService } from "@cyia/external-call";
536
+
537
+ // packages/workflow/runner/runner-item.ts
538
+ import { computed as computed2, inject, Injector } from "static-injector";
539
+
540
+ // packages/workflow/token.ts
541
+ import { InjectionToken } from "static-injector";
542
+ var CurrentWorkflowToken = new InjectionToken(
543
+ "CurrentWorkflow"
544
+ );
545
+ var InputsToken = new InjectionToken("Input");
546
+ var CurrentNodeToken = new InjectionToken("CurrentNode");
547
+ var CurrentCallNodeToken = new InjectionToken(
548
+ "CurrentCallNode"
549
+ );
550
+ var CurrentContextToken = new InjectionToken(
551
+ "CurrentContext"
552
+ );
553
+ var InputParamsToken = new InjectionToken(
554
+ "InputParams"
555
+ );
556
+ var ParentContextToken = new InjectionToken("ParentContext");
557
+ var UseInputToken = new InjectionToken("UseInput");
558
+ var AbortSignalToken = new InjectionToken(
559
+ "AbortSignal"
560
+ );
561
+ var EnviromentParametersToken = new InjectionToken("EnviromentParameters");
562
+ var ModelOptionsToken = new InjectionToken(
563
+ "ModelOptions"
564
+ );
565
+ var WorkflowConfigToken = new InjectionToken("WorkflowConfig");
566
+ var ChatServiceToken = new InjectionToken("ChatServiceToken");
567
+
568
+ // packages/workflow/runner/runner-item.ts
569
+ import * as v8 from "valibot";
570
+ import { isEmptyInput, isStringArray } from "@cyia/util";
571
+ import { omitBy } from "es-toolkit";
572
+ import { defaultsDeep } from "es-toolkit/compat";
573
+ var NodeRunnerBase = class {
574
+ node = inject(CurrentNodeToken);
575
+ callNode = inject(CurrentCallNodeToken);
576
+ context = inject(CurrentContextToken);
577
+ // protected useInput = inject(UseInputToken);
578
+ inputParams = inject(InputParamsToken);
579
+ injector = inject(Injector);
580
+ emitter = inject(WorkflowEmitter);
581
+ abortSignal = inject(AbortSignalToken);
582
+ async run() {
583
+ throw new Error("待实现");
584
+ }
585
+ inputs$$ = computed2(() => {
586
+ const obj = {};
587
+ for (const input of this.node.inputs) {
588
+ if (!input.type) {
589
+ const data = this.inputParams.get(input.value);
590
+ if (!data) {
591
+ if (input.optional) {
592
+ continue;
593
+ } else {
594
+ throw new Error(`缺少输入参数: ${input.value}`);
595
+ }
596
+ }
597
+ obj[input.value] = data;
598
+ }
599
+ }
600
+ return obj;
601
+ });
602
+ inputValueObject$$ = computed2(
603
+ () => Object.entries(this.inputs$$()).reduce(
604
+ (obj, item) => {
605
+ obj[item[0]] = item[1].value;
606
+ return obj;
607
+ },
608
+ {}
609
+ )
610
+ );
611
+ inputMetadataList$$ = computed2(
612
+ () => Object.values(this.inputs$$()).map((item) => item.extra?.metadata)
613
+ );
614
+ getInputMetadata(input) {
615
+ return this.inputs$$()[input].extra?.metadata;
616
+ }
617
+ async getInputChat() {
618
+ const metadataList = [];
619
+ const obj = {};
620
+ const errorList = [];
621
+ for (const input of this.node.inputs) {
622
+ if (!input.type) {
623
+ const data = this.inputParams.get(input.value);
624
+ if (!data) {
625
+ if (input.optional) {
626
+ continue;
627
+ } else {
628
+ errorList.push(input.value);
629
+ continue;
630
+ }
631
+ }
632
+ if (input.inputType === "image") {
633
+ obj[input.value] = data?.value;
634
+ } else if (isStringArray(data?.value)) {
635
+ obj[input.value] = data.value.join("\n");
636
+ } else {
637
+ obj[input.value] = data?.value ?? "";
638
+ }
639
+ const extra = data?.extra;
640
+ if (extra) {
641
+ if (Array.isArray(extra)) {
642
+ for (const { metadata } of extra) {
643
+ if (!metadata) {
644
+ continue;
645
+ }
646
+ metadataList.push(metadata);
647
+ }
648
+ } else {
649
+ if (extra.metadata) {
650
+ metadataList.push(extra.metadata);
651
+ }
652
+ }
653
+ }
654
+ }
655
+ }
656
+ if (errorList.length) {
657
+ throw new Error(`缺少输入参数: ${errorList.join(",")}`);
658
+ }
659
+ return { metadataList, obj };
660
+ }
661
+ #modelConfig = inject(ModelOptionsToken);
662
+ mergeChatModel(input) {
663
+ let chatService = this.injector.get(ChatServiceToken);
664
+ let presetConfig = {};
665
+ if (input?.name) {
666
+ presetConfig = chatService.getModelConfig(input.name) ?? {};
667
+ }
668
+ return input ? defaultsDeep(
669
+ omitBy(
670
+ {
671
+ model: input.model,
672
+ baseURL: input?.baseURL
673
+ },
674
+ isEmptyInput
675
+ ),
676
+ omitBy(presetConfig, isEmptyInput),
677
+ omitBy(this.#modelConfig ?? {}, isEmptyInput)
678
+ ) : this.#modelConfig;
679
+ }
680
+ getParsedNode(schema) {
681
+ const result = v8.safeParse(schema, this.node);
682
+ if (result.success) {
683
+ return result.output;
684
+ }
685
+ if (!PROD_ENV) {
686
+ console.log(result.issues);
687
+ }
688
+ throw new Error(JSON.stringify(result.issues));
689
+ }
690
+ };
691
+
692
+ // packages/workflow/template-format.service.ts
693
+ import hbs1 from "handlebars";
694
+ import { RootStaticInjectOptions } from "static-injector";
695
+ import { uniqBy } from "es-toolkit";
696
+ import { Liquid } from "liquidjs";
697
+ var engine = new Liquid({ jsTruthy: true });
698
+ var TemplateFormatService = class extends RootStaticInjectOptions {
699
+ interpolate(input, value) {
700
+ return hbs1.compile(input, { noEscape: true, preventIndent: true })(value, {
701
+ allowProtoPropertiesByDefault: true
702
+ });
703
+ }
704
+ entryInterpolate(payload, knowledge, content, embedingTemplate) {
705
+ return embedingTemplate?.enable ? this.interpolate(embedingTemplate.value ?? "", {
706
+ ENTRY: { ...payload, knowledge }
707
+ }) : content;
708
+ }
709
+ /** 用于模板格式化 */
710
+ parse(input) {
711
+ let list;
712
+ try {
713
+ list = hbs1.parse(input).body;
714
+ } catch (error) {
715
+ return { list: [], error: true };
716
+ }
717
+ const result = this.#getActionInputVariable(list, /* @__PURE__ */ new Set());
718
+ return {
719
+ list: [...result.set].map((item) => {
720
+ if (result.object.has(item)) {
721
+ return { inputType: "object", value: item };
722
+ }
723
+ return { inputType: "string", value: item };
724
+ }),
725
+ error: false
726
+ };
727
+ }
728
+ // 只有条件用,没太大用途
729
+ async parserJs(input) {
730
+ const { createCssSelectorForTs } = await import("@cyia/code-util/selector/ts");
731
+ try {
732
+ const selector = createCssSelectorForTs(input, { scriptKind: 1 });
733
+ const objectList = selector.queryAll(
734
+ `:not(DotToken)+Identifier,*::children(0)[tag=Identifier]`
735
+ );
736
+ return {
737
+ list: uniqBy(objectList, (item) => item.value).map((item) => ({
738
+ inputType: "object",
739
+ value: item.value
740
+ })),
741
+ error: false
742
+ };
743
+ } catch (error) {
744
+ return {
745
+ error: true,
746
+ list: []
747
+ };
748
+ }
749
+ }
750
+ async parserLiquid(input) {
751
+ try {
752
+ const result = engine.parse(input);
753
+ const varList = /* @__PURE__ */ new Set();
754
+ const proxyObj = new Proxy(
755
+ {},
756
+ {
757
+ getOwnPropertyDescriptor(target, p) {
758
+ return void 0;
759
+ },
760
+ has(target, p) {
761
+ varList.add(p);
762
+ return true;
763
+ }
764
+ }
765
+ );
766
+ await engine.render(result, proxyObj);
767
+ return {
768
+ list: [...varList].map((item) => ({
769
+ inputType: "object",
770
+ value: item
771
+ })),
772
+ error: false
773
+ };
774
+ } catch (error) {
775
+ return { error: true, list: [] };
776
+ }
777
+ }
778
+ #getActionInputVariable(body, nowSet) {
779
+ const obj = {
780
+ set: /* @__PURE__ */ new Set(),
781
+ block: {},
782
+ object: /* @__PURE__ */ new Set()
783
+ };
784
+ for (const item of body) {
785
+ if (item.type === "MustacheStatement") {
786
+ if (item.path.type === "PathExpression") {
787
+ const path3 = item.path;
788
+ obj.set.add(path3.parts[0]);
789
+ if (path3.parts.length > 1) {
790
+ obj.object.add(path3.parts[0]);
791
+ }
792
+ } else {
793
+ }
794
+ } else {
795
+ }
796
+ }
797
+ return obj;
798
+ }
799
+ };
800
+
801
+ // packages/workflow/inline/node/chat/main/llm.runner.ts
802
+ import { jsonParse, yamlParse, markdownParse, isChatSchema } from "@cyia/util";
803
+ var LlmRunner = class extends NodeRunnerBase {
804
+ #format = inject2(TemplateFormatService);
805
+ #chatService = inject2(ChatServiceToken);
806
+ #abort = inject2(AbortSignalToken);
807
+ #channel = inject2(LogService).getToken("chat");
808
+ async run() {
809
+ const { metadataList, obj } = await this.getInputChat();
810
+ const inputJsonSchema = this.inputParams.get(DEFAULT_CHAT_SCHEMA_KEY);
811
+ const nodeResult = this.getParsedNode(CHAT_NODE_DEFINE);
812
+ const config = nodeResult.data.config;
813
+ const examples = config.examples;
814
+ const list = nodeResult.data.value;
815
+ const historyList = list.map((item) => {
816
+ const content = this.#format.interpolate(
817
+ item.content.map((item2) => item2.type === "text" ? item2.text : "").join("\n"),
818
+ obj
819
+ );
820
+ return {
821
+ role: item.role,
822
+ content: [
823
+ { type: "text", text: content },
824
+ ...item.content.filter((item2) => item2.type === "image_url").flatMap((item2) => {
825
+ if (item2.type === "image_url") {
826
+ return obj[item2.image_url.url].map((item3) => ({
827
+ type: "image_url",
828
+ image_url: { url: item3.data }
829
+ }));
830
+ }
831
+ return item2;
832
+ })
833
+ ]
834
+ };
835
+ });
836
+ const schema = isChatSchema(inputJsonSchema?.value);
837
+ if (inputJsonSchema?.value && !schema) {
838
+ throw new Error(
839
+ `JsonSchema传入格式异常,需要: {name:string,schema:object},传入: ${JSON.stringify(inputJsonSchema.value)}`
840
+ );
841
+ } else if (schema) {
842
+ config.parseBy ??= "json";
843
+ config.responseFormat ??= "json_schema";
844
+ }
845
+ if (examples.length) {
846
+ const examplesTemplate = examples.filter((item) => item.input.value && item.output.value).flatMap((item) => [
847
+ {
848
+ role: "user",
849
+ content: [
850
+ {
851
+ type: "text",
852
+ text: this.#exampleFormat(item.input, config.parseBy)
853
+ }
854
+ ]
855
+ },
856
+ {
857
+ role: "assistant",
858
+ content: [
859
+ {
860
+ type: "text",
861
+ text: this.#exampleFormat(item.output, config.parseBy)
862
+ }
863
+ ]
864
+ }
865
+ ]);
866
+ let index = historyList.findIndex((item) => item.role === "system");
867
+ index = index === -1 ? 0 : index + 1;
868
+ historyList.splice(index, 0, ...examplesTemplate);
869
+ }
870
+ this.#channel?.info("节点对话配置", config.llm);
871
+ const llm = await this.#chatService.chat(this.mergeChatModel(config.llm));
872
+ const result = await llm.stream(
873
+ {
874
+ messages: historyList,
875
+ response_format: config.responseFormat === "json_schema" ? { type: "json_schema", json_schema: inputJsonSchema?.value } : config.responseFormat === "json_object" ? { type: "json_object" } : void 0
876
+ },
877
+ { signal: this.#abort }
878
+ );
879
+ const streamData = createLLMData({
880
+ node: this.node,
881
+ value: "",
882
+ extra: {
883
+ references: uniqBy2(
884
+ metadataList,
885
+ (item) => item.type + item.description + item.tooltip || ""
886
+ ),
887
+ historyList: [],
888
+ delta: "",
889
+ content: ""
890
+ }
891
+ });
892
+ const endRef = this.#chatService.getMetadataEndRef(
893
+ streamData.extra.references
894
+ );
895
+ for await (const item of result) {
896
+ const value = endRef ? item.content + endRef : item.content;
897
+ streamData.value = value;
898
+ streamData.extra = { ...streamData.extra, ...item, content: value };
899
+ this.emitter.send(streamData);
900
+ }
901
+ const resultContent = streamData.value;
902
+ streamData.extra.delta = "";
903
+ historyList.push(createAssistantMessage(resultContent));
904
+ streamData.extra.historyList = historyList;
905
+ this.emitter.send(streamData);
906
+ return async (outputName) => {
907
+ if (outputName === RUNNER_ORIGIN_OUTPUT_KEY) {
908
+ return {
909
+ value: streamData.value,
910
+ dataId: streamData.dataId,
911
+ extra: streamData.extra
912
+ };
913
+ }
914
+ let value;
915
+ switch (config.parseBy) {
916
+ case "markdown":
917
+ value = markdownParse(resultContent);
918
+ break;
919
+ case "json":
920
+ value = jsonParse(resultContent);
921
+ break;
922
+ case "yaml":
923
+ value = yamlParse(resultContent);
924
+ break;
925
+ default:
926
+ value = resultContent;
927
+ break;
928
+ }
929
+ if (typeof value === "undefined") {
930
+ throw new Error(`解析${config.parseBy}失败`);
931
+ }
932
+ return { value, dataId: streamData.dataId, extra: streamData.extra };
933
+ };
934
+ }
935
+ #exampleFormat(data, format) {
936
+ if (data.format) {
937
+ if (format === "json") {
938
+ return JSON.stringify(parse2(data.value));
939
+ }
940
+ return data.value;
941
+ } else {
942
+ return data.value;
943
+ }
944
+ }
945
+ };
946
+
947
+ // packages/workflow/inline/node/chat/main/index.ts
948
+ var ChatMainConfig = {
949
+ ...NODE_COMMON,
950
+ runner: LlmRunner,
951
+ define: CHAT_NODE_DEFINE
952
+ };
953
+
954
+ // packages/workflow/inline/node/text/common.ts
955
+ var NODE_COMMON2 = {
956
+ type: "textarea",
957
+ label: `文本模板`,
958
+ icon: { fontIcon: "text_snippet" },
959
+ disableHead: false,
960
+ disableConnect: false,
961
+ color: "primary",
962
+ help: `${HelpObj.templateVarLine}`,
963
+ priority: -98
964
+ };
965
+
966
+ // packages/workflow/inline/node/text/main/textarea.runner.ts
967
+ import { inject as inject3 } from "static-injector";
968
+ var TextareaRunner = class extends NodeRunnerBase {
969
+ #format = inject3(TemplateFormatService);
970
+ async run() {
971
+ const obj = this.inputValueObject$$();
972
+ const str = this.node.data.value;
973
+ return async () => ({ value: this.#format.interpolate(str, obj) });
974
+ }
975
+ };
976
+
977
+ // packages/workflow/inline/node/text/main/index.ts
978
+ var TextMainConfig = {
979
+ ...NODE_COMMON2,
980
+ runner: TextareaRunner
981
+ };
982
+
983
+ // packages/workflow/workflow-parser.service.ts
984
+ var WorkflowParserContext = class _WorkflowParserContext {
985
+ constructor(list, subObject, data, parentNode, userInputParams = [], parent) {
986
+ this.list = list;
987
+ this.subObject = subObject;
988
+ this.data = data;
989
+ this.parentNode = parentNode;
990
+ this.userInputParams = userInputParams;
991
+ this.parent = parent;
992
+ }
993
+ list;
994
+ subObject;
995
+ data;
996
+ parentNode;
997
+ userInputParams;
998
+ parent;
999
+ // fixme 或许可以分离,单独调用,然后加上children查找,不过那样就太慢了
1000
+ #childUseNodeSet = /* @__PURE__ */ new Set();
1001
+ /** 只能子级在本级找不到节点时调用父级使用 */
1002
+ childUseDefine(id, parentId) {
1003
+ const define = this.list.find((item) => item.id === id);
1004
+ if (!define) {
1005
+ return this.parent?.childUseDefine(id, parentId);
1006
+ }
1007
+ if (id !== parentId) {
1008
+ this.#childUseNodeSet.add(id);
1009
+ }
1010
+ return define;
1011
+ }
1012
+ #getParentNodeDefine(id) {
1013
+ return this.parent?.childUseDefine(id, this.parentNode?.id);
1014
+ }
1015
+ parseItem() {
1016
+ const graph = new Graph({ multi: true });
1017
+ const { nodes, edges } = this.data.flow;
1018
+ const nodeData = { nodes: {}, end: void 0 };
1019
+ this.list.forEach((node) => {
1020
+ graph.addNode(node.id);
1021
+ });
1022
+ for (const node of this.list) {
1023
+ const handle = {
1024
+ output: flatFilterHandleList(node.data.handle?.output)
1025
+ };
1026
+ const cEdges = getConnectedEdges([node], edges);
1027
+ const inputNodes = getIncomers(node, nodes, cEdges);
1028
+ const inputHandleList = flatFilterHandleList(node.data.handle?.input);
1029
+ const inputParams = [];
1030
+ for (const item of inputHandleList) {
1031
+ const targetHandle = item.id;
1032
+ const linkedEdges = cEdges.filter(
1033
+ (item2) => item2.targetHandle === targetHandle && item2.target === node.id
1034
+ );
1035
+ if (linkedEdges.length > 1) {
1036
+ return {
1037
+ error: {
1038
+ message: `${node.id}:不支持多个节点连接一个输入点`,
1039
+ nodeId: node.id
1040
+ }
1041
+ };
1042
+ }
1043
+ if (linkedEdges.length === 1) {
1044
+ const linkedEdge = linkedEdges[0];
1045
+ const linkedNode = inputNodes.find(
1046
+ (item2) => item2.id === linkedEdge.source
1047
+ );
1048
+ const linkedOuput = flatFilterHandleList(
1049
+ linkedNode.data.handle?.output
1050
+ ).find((item2) => item2.id === linkedEdge.sourceHandle);
1051
+ inputParams.push({
1052
+ ...item,
1053
+ nodeId: linkedNode.id,
1054
+ outputName: linkedOuput.value
1055
+ });
1056
+ if (!graph.hasNode(linkedNode.id)) {
1057
+ if (!this.#getParentNodeDefine(linkedNode.id)) {
1058
+ return {
1059
+ error: {
1060
+ message: `${linkedNode.id}:未找到连接节点,只能读取到当前及祖先范围内的节点`,
1061
+ nodeId: linkedNode.id
1062
+ }
1063
+ };
1064
+ }
1065
+ graph.addNode(linkedNode.id);
1066
+ }
1067
+ graph.addEdge(linkedNode.id, node.id);
1068
+ } else {
1069
+ inputParams.push({ ...item });
1070
+ if (item.type) {
1071
+ continue;
1072
+ }
1073
+ this.userInputParams.push(item);
1074
+ }
1075
+ }
1076
+ nodeData.nodes[node.id] = {
1077
+ data: node.data,
1078
+ //输入用
1079
+ inputs: inputParams,
1080
+ outputs: handle.output,
1081
+ type: node.type,
1082
+ id: node.id
1083
+ };
1084
+ if (this.subObject[node.id]) {
1085
+ for (let index = 0; index < this.subObject[node.id].length; index++) {
1086
+ const { key, startId, nodeList } = this.subObject[node.id][index];
1087
+ const instance = new _WorkflowParserContext(
1088
+ nodeList,
1089
+ this.subObject,
1090
+ this.data,
1091
+ node,
1092
+ this.userInputParams,
1093
+ this
1094
+ );
1095
+ const result = instance.parseItem();
1096
+ if (result.error) {
1097
+ return { error: { ...result.error } };
1098
+ }
1099
+ nodeData.nodes[node.id].subFlowList ??= [];
1100
+ nodeData.nodes[node.id].subFlowList.push({
1101
+ key,
1102
+ flow: result.data,
1103
+ startId
1104
+ });
1105
+ }
1106
+ }
1107
+ }
1108
+ const outList = [];
1109
+ graph.forEachNode((node) => {
1110
+ if (!this.#childUseNodeSet.has(node) && graph.outDegree(node) === 0) {
1111
+ outList.push(node);
1112
+ }
1113
+ });
1114
+ if (outList.length > 1) {
1115
+ return { error: { message: `计算时存在多个出口` } };
1116
+ } else if (outList.length === 0) {
1117
+ return { error: { message: `可能出现循环依赖,没有出口` } };
1118
+ } else {
1119
+ nodeData.end = outList[0];
1120
+ nodeData.inputList = uniqBy3(
1121
+ this.userInputParams,
1122
+ (item) => `${item.inputType || "string"}|${item.value}`
1123
+ ).map((item) => ({
1124
+ inputType: item.inputType || "string",
1125
+ value: item.value,
1126
+ label: item.label || item.value,
1127
+ optional: item.optional
1128
+ }));
1129
+ return { data: nodeData };
1130
+ }
1131
+ }
1132
+ };
1133
+ var NodeGroup = class {
1134
+ #group = /* @__PURE__ */ new Map();
1135
+ #iterationMap = /* @__PURE__ */ new Map();
1136
+ addContainerStart(node) {
1137
+ this.#iterationMap.set(node.parentId, node);
1138
+ }
1139
+ getContainerStart(node) {
1140
+ return this.#iterationMap.get(node.id);
1141
+ }
1142
+ add(node) {
1143
+ const nodeMap = this.#group.get(node.type) || [];
1144
+ nodeMap.push(node);
1145
+ this.#group.set(node.type, nodeMap);
1146
+ }
1147
+ getList(type) {
1148
+ return this.#group.get(type) || [];
1149
+ }
1150
+ };
1151
+ var WorkflowDataToken = new InjectionToken2(
1152
+ "WorkflowData"
1153
+ );
1154
+ var WorkflowPreParser = class {
1155
+ /**
1156
+ * 迭代块:直接找父级parentid就行了
1157
+ * 分类块:所有后面的都算他的
1158
+ * 重构,所有节点进行迭代
1159
+ * 找迭代快,找到后找子级item块,找到后进行output查找+parent==迭代快
1160
+ * 找分类,找到后output查找
1161
+ * 所有独立块都是找到独立节点后终止
1162
+ */
1163
+ #nodeGroup = new NodeGroup();
1164
+ #data = inject4(WorkflowDataToken);
1165
+ #plugin = inject4(WorkflowPluginService);
1166
+ #inlineNodeService = inject4(InlineNodeService);
1167
+ #fullBlockObject$$ = computed3(
1168
+ () => ({
1169
+ ...this.#inlineNodeService.conditionNodeList(),
1170
+ ...this.#plugin.conditionNodeList$$(),
1171
+ ["iteration" /* iteration */]: true
1172
+ })
1173
+ );
1174
+ #conditionBlockObject$$ = computed3(
1175
+ () => ({
1176
+ ...this.#inlineNodeService.conditionNodeList(),
1177
+ ...this.#plugin.conditionNodeList$$()
1178
+ })
1179
+ );
1180
+ parse() {
1181
+ const { nodes, edges } = this.#data.flow;
1182
+ const mainList = [];
1183
+ const subObjectGroup = {};
1184
+ const excludeSet = /* @__PURE__ */ new Set();
1185
+ const isBlock = (item) => this.#fullBlockObject$$()[item.type];
1186
+ const removedList = /* @__PURE__ */ new Set();
1187
+ const getSubNode = (node, subNodeList) => {
1188
+ subNodeList.push(node);
1189
+ excludeSet.add(node.id);
1190
+ if (!isBlock(node)) {
1191
+ getOutgoers(node, nodes, edges).forEach((item) => {
1192
+ getSubNode(item, subNodeList);
1193
+ });
1194
+ }
1195
+ };
1196
+ let manualInput = false;
1197
+ for (let i = 0; i < nodes.length; i++) {
1198
+ const node = nodes[i];
1199
+ if (node.data.excludeUsage) {
1200
+ removedList.add(node.id);
1201
+ nodes.splice(i, 1);
1202
+ i--;
1203
+ continue;
1204
+ }
1205
+ if (node.type === "input-params") {
1206
+ manualInput ||= !!node.data.config?.["manualInput"];
1207
+ } else if (isBlock(node)) {
1208
+ this.#nodeGroup.add(node);
1209
+ } else if (node.type === "iteration-start" /* iterationStart */) {
1210
+ this.#nodeGroup.addContainerStart(node);
1211
+ }
1212
+ }
1213
+ Object.keys(this.#fullBlockObject$$()).flatMap((key) => this.#nodeGroup.getList(key)).forEach((node) => {
1214
+ const outputList = subObjectGroup[node.id] || [];
1215
+ subObjectGroup[node.id] = outputList;
1216
+ if (node.type === "iteration" /* iteration */) {
1217
+ const subNodeList = [];
1218
+ const startNode = this.#nodeGroup.getContainerStart(node);
1219
+ getSubNode(startNode, subNodeList);
1220
+ outputList.push({
1221
+ nodeList: uniqBy3(subNodeList, (item) => item.id),
1222
+ startId: startNode.id,
1223
+ key: `[default]`
1224
+ });
1225
+ } else if (this.#conditionBlockObject$$()[node.type]) {
1226
+ const cEdges = getConnectedEdges([node], edges);
1227
+ const children = getOutgoers(node, nodes, cEdges);
1228
+ const outputHandleList = flatFilterHandleList(
1229
+ node.data.handle.output
1230
+ );
1231
+ for (const outputHandle of outputHandleList) {
1232
+ const outputEdgeList = cEdges.filter(
1233
+ (edge) => edge.sourceHandle === outputHandle.id
1234
+ );
1235
+ if (!outputEdgeList.length) {
1236
+ throw new Error(`[${node.data.title || ""}]节点上发现未连接出口`);
1237
+ }
1238
+ for (const childNode of children.filter(
1239
+ ({ id }) => outputEdgeList.some(({ target }) => target === id)
1240
+ )) {
1241
+ const subNodeList = [];
1242
+ getSubNode(childNode, subNodeList);
1243
+ outputList.push({
1244
+ nodeList: uniqBy3(subNodeList, (item) => item.id),
1245
+ startId: childNode.id,
1246
+ key: outputHandle.value
1247
+ });
1248
+ }
1249
+ }
1250
+ }
1251
+ });
1252
+ for (const node of nodes) {
1253
+ if (excludeSet.has(node.id)) {
1254
+ continue;
1255
+ }
1256
+ mainList.push(node);
1257
+ }
1258
+ return {
1259
+ list: mainList,
1260
+ subObjectGroup,
1261
+ manualInput,
1262
+ edges: edges.filter(
1263
+ (edge) => !removedList.has(edge.source) && !removedList.has(edge.target)
1264
+ )
1265
+ };
1266
+ }
1267
+ };
1268
+ var WorkflowParserService = class {
1269
+ #injector = inject4(Injector2);
1270
+ #inlineNode = inject4(InlineNodeService);
1271
+ constructor() {
1272
+ this.#inlineNode.register(index_node_exports);
1273
+ }
1274
+ /**
1275
+ * 1.如果出现孤立节点,那么需要判断是不是子级引用
1276
+ * 2.子级引用本级别找不到,那么需要找父级
1277
+ */
1278
+ /**
1279
+ * 边有id,通过source 找到连接的节点
1280
+ *
1281
+ */
1282
+ parse(data) {
1283
+ const injector = createInjector({
1284
+ providers: [
1285
+ WorkflowPreParser,
1286
+ { provide: WorkflowDataToken, useValue: data }
1287
+ ],
1288
+ parent: this.#injector
1289
+ });
1290
+ const preInstance = injector.get(WorkflowPreParser);
1291
+ const result = preInstance.parse();
1292
+ if (!result.list.length) {
1293
+ return {
1294
+ error: {
1295
+ message: "无可用节点"
1296
+ }
1297
+ };
1298
+ }
1299
+ const instance = new WorkflowParserContext(
1300
+ result.list,
1301
+ result.subObjectGroup,
1302
+ { ...data, flow: { ...data.flow, edges: result.edges } }
1303
+ );
1304
+ return { ...instance.parseItem(), manualInput: result.manualInput };
1305
+ }
1306
+ };
1307
+
1308
+ // packages/workflow/workflow-exec.service.ts
1309
+ import { inject as inject11 } from "static-injector";
1310
+
1311
+ // packages/workflow/preset/inline-runner.service.ts
1312
+ import { inject as inject9 } from "static-injector";
1313
+
1314
+ // packages/workflow/preset/inline-build.service.ts
1315
+ import { inject as inject5 } from "static-injector";
1316
+
1317
+ // packages/workflow/runner/parameters.runner.ts
1318
+ var ParametersRunner = class extends NodeRunnerBase {
1319
+ static runnerName = "parameters";
1320
+ async run() {
1321
+ return async () => ({ value: this.inputs$$() });
1322
+ }
1323
+ };
1324
+
1325
+ // packages/workflow/preset/inline-build.service.ts
1326
+ var InlineBuilderService = class {
1327
+ template = inject5(TemplateFormatService);
1328
+ parser = inject5(WorkflowParserService);
1329
+ #createLLMNode(input) {
1330
+ return {
1331
+ id: "1",
1332
+ data: {
1333
+ handle: {
1334
+ input: [
1335
+ Object.keys({ ...input.input, ...input.context }).map(
1336
+ (value, i) => ({
1337
+ id: `${i}`,
1338
+ value,
1339
+ label: ``
1340
+ })
1341
+ )
1342
+ ],
1343
+ output: [
1344
+ [
1345
+ {
1346
+ id: "1",
1347
+ label: "",
1348
+ value: "输出"
1349
+ }
1350
+ ]
1351
+ ]
1352
+ }
1353
+ },
1354
+ type: ParametersRunner.runnerName
1355
+ };
1356
+ }
1357
+ #createEdge(llmNode, context) {
1358
+ const edgeList = [];
1359
+ const addEdge = (node) => {
1360
+ const inputHandleList = node.data.handle?.input.flat() || [];
1361
+ for (const inputHandle of inputHandleList) {
1362
+ const item = context[inputHandle.value];
1363
+ if (!item) {
1364
+ continue;
1365
+ }
1366
+ const sourceHandle = item.data.handle.output[0][0];
1367
+ edgeList.push({
1368
+ source: item.id,
1369
+ sourceHandle: sourceHandle.id,
1370
+ // 自身
1371
+ target: node.id,
1372
+ targetHandle: inputHandle.id
1373
+ });
1374
+ }
1375
+ };
1376
+ for (const ctxKey in context) {
1377
+ const node = context[ctxKey];
1378
+ addEdge(node);
1379
+ }
1380
+ addEdge(llmNode);
1381
+ return edgeList;
1382
+ }
1383
+ #createWorkflow(input) {
1384
+ const chatNode = this.#createLLMNode(input);
1385
+ const edges = this.#createEdge(chatNode, input.context);
1386
+ return {
1387
+ nodes: [chatNode, ...Object.values(input.context)],
1388
+ edges
1389
+ };
1390
+ }
1391
+ createDefine(input) {
1392
+ return this.parser.parse({ flow: this.#createWorkflow(input) });
1393
+ }
1394
+ };
1395
+
1396
+ // packages/workflow/runner/workflow-runner.service.ts
1397
+ import { createInjector as createInjector2, inject as inject8, Injector as Injector3 } from "static-injector";
1398
+
1399
+ // packages/workflow/runner/inline-input-item.runner.ts
1400
+ import { inject as inject6 } from "static-injector";
1401
+ var InlineInputItemRunner = class extends NodeRunnerBase {
1402
+ static runnerName = "inlineInputItem";
1403
+ #env = inject6(EnviromentParametersToken);
1404
+ async run() {
1405
+ return async () => {
1406
+ const key = this.node.inputs[0].value;
1407
+ const result = this.#env;
1408
+ if (!result) {
1409
+ throw new Error(`读取上下文参数[${key}]失败`);
1410
+ }
1411
+ return { value: result[key] };
1412
+ };
1413
+ }
1414
+ };
1415
+
1416
+ // packages/workflow/runner/input-params.runner.ts
1417
+ import { inject as inject7 } from "static-injector";
1418
+ var InputParamsRunner = class extends NodeRunnerBase {
1419
+ #env = inject7(EnviromentParametersToken);
1420
+ async run() {
1421
+ return async () => {
1422
+ const value = this.#env;
1423
+ if (!value) {
1424
+ throw new Error(`读取上下文失败`);
1425
+ }
1426
+ return {
1427
+ value
1428
+ };
1429
+ };
1430
+ }
1431
+ };
1432
+
1433
+ // packages/workflow/runner/iteration-start.runner.ts
1434
+ var IterationStartRunner = class extends NodeRunnerBase {
1435
+ async run() {
1436
+ return async () => this.inputParams.get(ITERATION_ITEM_SYMBOL);
1437
+ }
1438
+ };
1439
+
1440
+ // packages/workflow/runner/iteration.runner.ts
1441
+ import { isIterable } from "@cyia/util";
1442
+ var IterationRunner = class extends NodeRunnerBase {
1443
+ async run() {
1444
+ const data = this.inputParams.get(this.node.inputs[0].value);
1445
+ if (!data) {
1446
+ throw new Error("输入节点为空");
1447
+ }
1448
+ const extra = data.extra;
1449
+ const value = data.value;
1450
+ if (!isIterable(value)) {
1451
+ throw new Error(`输入值不是可迭代(数组)类型: ${JSON.stringify(value)}`);
1452
+ }
1453
+ const resultList = [];
1454
+ let index = 0;
1455
+ for (const item of value) {
1456
+ const newInputs = new Map(this.inputParams);
1457
+ newInputs.set(ITERATION_ITEM_SYMBOL, {
1458
+ value: item,
1459
+ extra: extra?.[index]
1460
+ });
1461
+ try {
1462
+ resultList.push(
1463
+ await this.injector.get(WorkflowRunnerService).createContext(
1464
+ //迭代只有一个子流
1465
+ this.node.subFlowList[0].flow,
1466
+ newInputs,
1467
+ this.context,
1468
+ this.injector
1469
+ ).run()
1470
+ );
1471
+ } catch (error) {
1472
+ throw new Error(`执行第${index}出现异常`, { cause: error });
1473
+ }
1474
+ index++;
1475
+ }
1476
+ const list = resultList.reduce(
1477
+ (obj, item) => {
1478
+ obj.value.push(item.value);
1479
+ obj.extra.push(item.extra);
1480
+ return obj;
1481
+ },
1482
+ { value: [], extra: [] }
1483
+ );
1484
+ return async (outputName) => {
1485
+ if (outputName === "flat") {
1486
+ return { value: list.value.flat(999), extra: list.extra.flat(999) };
1487
+ }
1488
+ return list;
1489
+ };
1490
+ }
1491
+ };
1492
+
1493
+ // packages/workflow/runner/define.ts
1494
+ var ItemRunnerObject = {
1495
+ ["iteration" /* iteration */]: IterationRunner,
1496
+ ["iteration-start" /* iterationStart */]: IterationStartRunner,
1497
+ ["input-params" /* inputParams */]: InputParamsRunner,
1498
+ ["parameters" /* parameters */]: ParametersRunner,
1499
+ ["inlineInputItem" /* inlineInputItem */]: InlineInputItemRunner
1500
+ };
1501
+
1502
+ // packages/workflow/runner/runner-error.ts
1503
+ var RunnerError = class _RunnerError extends Error {
1504
+ #origin;
1505
+ #list;
1506
+ constructor(origin, list) {
1507
+ super(
1508
+ `${list.map(
1509
+ (item) => `[${item.title}]${item.message ? ": " + item.message : ""}`
1510
+ ).join("<-")}`,
1511
+ { cause: origin }
1512
+ );
1513
+ this.#origin = origin;
1514
+ this.#list = list;
1515
+ delete this.stack;
1516
+ this.name = `节点运行异常`;
1517
+ }
1518
+ create(item) {
1519
+ this.#list.push(item);
1520
+ return new _RunnerError(this.#origin, this.#list);
1521
+ }
1522
+ };
1523
+ var AbortSignalError = class extends Error {
1524
+ };
1525
+
1526
+ // packages/workflow/runner/workflow-runner.service.ts
1527
+ import { LogService as LogService2 } from "@cyia/external-call";
1528
+ var ITERATION_ITEM_SYMBOL = /* @__PURE__ */ Symbol("ITERATION_ITEM");
1529
+ var WorkflowRunnerContext = class {
1530
+ #injector = inject8(Injector3);
1531
+ data = inject8(CurrentWorkflowToken);
1532
+ parent = inject8(ParentContextToken);
1533
+ #callCache = /* @__PURE__ */ new Map();
1534
+ #outputCache = /* @__PURE__ */ new Map();
1535
+ inputs = inject8(InputsToken);
1536
+ #plugin = inject8(WorkflowPluginService);
1537
+ #emitter = inject8(WorkflowEmitter);
1538
+ #inlineNode = inject8(InlineNodeService);
1539
+ async #getNodeRunner(type) {
1540
+ return this.#inlineNode.getNodeRunner(type) ?? ItemRunnerObject[type] ?? await this.#plugin.getNodeRunner(type);
1541
+ }
1542
+ getNodeById(id) {
1543
+ const result = this.data.nodes[id];
1544
+ if (!result) {
1545
+ return this.parent?.getNodeById(id);
1546
+ }
1547
+ return result;
1548
+ }
1549
+ /** 调用缓存,同一个上下文内容不可能变化 */
1550
+ #getCallCache(id) {
1551
+ if (this.#callCache.has(id)) {
1552
+ return { result: this.#callCache.get(id) };
1553
+ }
1554
+ return this.parent ? this.parent.#getCallCache(id) : void 0;
1555
+ }
1556
+ #getOuputCache(id) {
1557
+ if (this.#outputCache.has(id)) {
1558
+ return { result: this.#outputCache.get(id) };
1559
+ }
1560
+ return this.parent ? this.parent.#getOuputCache(id) : void 0;
1561
+ }
1562
+ async startRun() {
1563
+ const node = this.getNodeById(this.data.end);
1564
+ return this.#runItem(node);
1565
+ }
1566
+ async run() {
1567
+ const node = this.getNodeById(this.data.end);
1568
+ return this.#runItem(node);
1569
+ }
1570
+ // 当前node 调用 node context
1571
+ async #createNodeRunner(item, inputParams, callNode, input) {
1572
+ const define = await this.#getNodeRunner(item.type);
1573
+ return createInjector2({
1574
+ providers: [
1575
+ define,
1576
+ { provide: CurrentNodeToken, useValue: item },
1577
+ { provide: CurrentCallNodeToken, useValue: callNode },
1578
+ { provide: CurrentContextToken, useValue: this },
1579
+ { provide: UseInputToken, useValue: input },
1580
+ { provide: InputParamsToken, useValue: inputParams }
1581
+ ],
1582
+ parent: this.#injector
1583
+ }).get(define);
1584
+ }
1585
+ #abort = inject8(AbortSignalToken);
1586
+ async #runItem(node, callNode, input) {
1587
+ try {
1588
+ if (this.#abort?.aborted) {
1589
+ throw new AbortSignalError();
1590
+ }
1591
+ const inputParams = new Map(this.inputs);
1592
+ for (const input2 of node.inputs) {
1593
+ if (input2.nodeId) {
1594
+ const inputNode = this.getNodeById(input2.nodeId);
1595
+ if (inputNode.subFlowList?.some(
1596
+ (subItem) => subItem.startId === node.id
1597
+ )) {
1598
+ continue;
1599
+ }
1600
+ const result = await this.#runItem(inputNode, node, input2);
1601
+ inputParams.set(input2.value, result);
1602
+ }
1603
+ }
1604
+ const nodeRunner = await this.#createNodeRunner(
1605
+ node,
1606
+ inputParams,
1607
+ callNode,
1608
+ input
1609
+ );
1610
+ const outputList = node.outputs;
1611
+ const outputName = input?.outputName ?? node.data.outputName ?? outputList[0].value;
1612
+ let dataResult = this.#getCallCache(node.id);
1613
+ if (dataResult === void 0) {
1614
+ {
1615
+ const res = await nodeRunner.run();
1616
+ dataResult = { result: res };
1617
+ this.#callCache.set(node.id, res);
1618
+ }
1619
+ }
1620
+ const outputKey = `${node.id}|${outputName}`;
1621
+ const outputResult = this.#getOuputCache(outputKey);
1622
+ let returnData;
1623
+ if (outputResult === void 0) {
1624
+ const res = await dataResult.result(outputName);
1625
+ this.#outputCache.set(outputKey, res);
1626
+ returnData = res;
1627
+ } else {
1628
+ returnData = outputResult.result;
1629
+ }
1630
+ this.#emitter.send(
1631
+ createResultData({
1632
+ ...returnData,
1633
+ node
1634
+ })
1635
+ );
1636
+ return returnData;
1637
+ } catch (error) {
1638
+ if (error instanceof Error && error.message === "Request was aborted." || error instanceof AbortSignalError) {
1639
+ return { value: void 0 };
1640
+ }
1641
+ const item = { title: node.data.title || "" };
1642
+ if (error instanceof RunnerError) {
1643
+ throw error.create(item);
1644
+ } else {
1645
+ if (error instanceof Error && error.message === "Connection error.") {
1646
+ const newError = new RunnerError(error.cause, [
1647
+ { ...item, message: "接口请求失败" }
1648
+ ]);
1649
+ delete newError.stack;
1650
+ throw newError;
1651
+ }
1652
+ throw new RunnerError(error, [item]);
1653
+ }
1654
+ }
1655
+ }
1656
+ };
1657
+ var WorkflowRunnerService = class {
1658
+ #injector = inject8(Injector3);
1659
+ /** 自己使用
1660
+ * @internal
1661
+ */
1662
+ createContext(data, inputs, parent, parentInjector) {
1663
+ return createInjector2({
1664
+ providers: [
1665
+ WorkflowRunnerContext,
1666
+ { provide: CurrentWorkflowToken, useValue: data },
1667
+ { provide: InputsToken, useValue: inputs },
1668
+ { provide: ParentContextToken, useValue: parent }
1669
+ ],
1670
+ parent: parentInjector ?? this.#injector
1671
+ }).get(WorkflowRunnerContext);
1672
+ }
1673
+ #log;
1674
+ get log() {
1675
+ return this.#log ?? (this.#log = this.#injector.get(LogService2, void 0, { optional: true })?.getToken("workflow"));
1676
+ }
1677
+ /** 入口 */
1678
+ run(data, input, ob, signal2) {
1679
+ this.log?.info("工作流默认对话配置", input.modelOptions);
1680
+ const injector = createInjector2({
1681
+ providers: [
1682
+ WorkflowEmitter,
1683
+ { provide: AbortSignalToken, useValue: signal2 },
1684
+ {
1685
+ provide: EnviromentParametersToken,
1686
+ useValue: input.environmentParameters
1687
+ },
1688
+ { provide: ModelOptionsToken, useValue: input.modelOptions }
1689
+ ],
1690
+ parent: this.#injector
1691
+ });
1692
+ const runner = this.createContext(data, input.input, void 0, injector);
1693
+ if (ob) {
1694
+ injector.get(WorkflowEmitter).setObserver(ob);
1695
+ }
1696
+ return runner.startRun();
1697
+ }
1698
+ };
1699
+
1700
+ // packages/workflow/preset/inline-runner.service.ts
1701
+ var InlineParametersService = class {
1702
+ #inlineBuild = inject9(InlineBuilderService);
1703
+ #workflowRunner = inject9(WorkflowRunnerService);
1704
+ async run(input) {
1705
+ const define = this.#inlineBuild.createDefine({
1706
+ ...input,
1707
+ input: input.input ?? {},
1708
+ context: input.context ?? {}
1709
+ });
1710
+ const result2 = await this.#workflowRunner.run(define.data, {
1711
+ input: new Map(
1712
+ Object.entries(input.input || {}).map(([key, value]) => [
1713
+ key,
1714
+ { value }
1715
+ ])
1716
+ ),
1717
+ environmentParameters: input.environmentParameters,
1718
+ modelOptions: input.modelOptions
1719
+ });
1720
+ return result2;
1721
+ }
1722
+ };
1723
+
1724
+ // packages/workflow/workflow-exec.service.ts
1725
+ import { Subject } from "rxjs";
1726
+
1727
+ // packages/workflow/preset/context-build.service.ts
1728
+ import { inject as inject10 } from "static-injector";
1729
+ import { uniq } from "es-toolkit";
1730
+ var ContextBuildService = class {
1731
+ template = inject10(TemplateFormatService);
1732
+ parser = inject10(WorkflowParserService);
1733
+ createWorkflow(input, inlineMode) {
1734
+ const result = this.template.parse(
1735
+ input.template.flatMap(
1736
+ (item) => item.content.map((item2) => item2.type === "text" ? item2.text : "")
1737
+ ).join("\n")
1738
+ ).list.map((item) => item.value);
1739
+ const inputList = [
1740
+ uniq([
1741
+ ...Object.keys({ ...input.input, ...input.context }),
1742
+ ...result
1743
+ ]).map((value, i) => ({
1744
+ id: `${i}`,
1745
+ value,
1746
+ label: ``
1747
+ }))
1748
+ ];
1749
+ const chatNode = {
1750
+ id: "2",
1751
+ data: {
1752
+ title: "对话",
1753
+ handle: {
1754
+ input: inputList,
1755
+ output: [
1756
+ [
1757
+ {
1758
+ id: "1",
1759
+ label: "",
1760
+ value: "输出"
1761
+ }
1762
+ ]
1763
+ ]
1764
+ },
1765
+ value: input.template,
1766
+ config: {}
1767
+ },
1768
+ type: "chat"
1769
+ };
1770
+ if (!inlineMode) {
1771
+ return {
1772
+ nodes: [chatNode],
1773
+ edges: []
1774
+ };
1775
+ }
1776
+ const inputParamsNode = {
1777
+ id: "1",
1778
+ type: "input-params" /* inputParams */,
1779
+ data: {
1780
+ handle: {
1781
+ input: [
1782
+ [
1783
+ {
1784
+ ...generateHandle(DEFAULT_INPUT_KEY, ""),
1785
+ inputType: "object"
1786
+ }
1787
+ ]
1788
+ ],
1789
+ output: [[{ id: "1", value: "default", label: "" }]]
1790
+ }
1791
+ }
1792
+ };
1793
+ const bridgeNodeList = inputList.flat().map((item, i) => ({
1794
+ id: `${InlineInputItemRunner.runnerName}-${i}`,
1795
+ type: InlineInputItemRunner.runnerName,
1796
+ data: {
1797
+ handle: {
1798
+ input: [[{ id: "1", value: item.value, label: "" }]],
1799
+ output: [
1800
+ [
1801
+ {
1802
+ id: "1",
1803
+ label: "",
1804
+ value: "输出"
1805
+ }
1806
+ ]
1807
+ ]
1808
+ }
1809
+ }
1810
+ }));
1811
+ const bridgeEdgeList1 = inputList.flat().map((item, i) => ({
1812
+ source: inputParamsNode.id,
1813
+ sourceHandle: "1",
1814
+ target: `${InlineInputItemRunner.runnerName}-${i}`,
1815
+ targetHandle: "1"
1816
+ }));
1817
+ const bridgeEdgeList2 = inputList.flat().map((item, i) => ({
1818
+ source: `${InlineInputItemRunner.runnerName}-${i}`,
1819
+ sourceHandle: "1",
1820
+ target: chatNode.id,
1821
+ targetHandle: item.id
1822
+ }));
1823
+ return {
1824
+ nodes: [inputParamsNode, chatNode, ...bridgeNodeList],
1825
+ edges: [...bridgeEdgeList1, ...bridgeEdgeList2]
1826
+ };
1827
+ }
1828
+ };
1829
+
1830
+ // packages/workflow/workflow-exec.service.ts
1831
+ var WorkflowExecService = class {
1832
+ #parser = inject11(WorkflowParserService);
1833
+ #parameterResolve = inject11(InlineParametersService);
1834
+ #runner = inject11(WorkflowRunnerService);
1835
+ parse(data) {
1836
+ return this.#parser.parse(data);
1837
+ }
1838
+ async runParse(define, input, ob, abortSignal) {
1839
+ const parameters = await this.#parameterResolve.run(input);
1840
+ return this.#runner.run(
1841
+ define,
1842
+ {
1843
+ input: new Map(
1844
+ Object.entries(parameters.value).map(([key, value]) => [key, value])
1845
+ ),
1846
+ environmentParameters: input.environmentParameters,
1847
+ modelOptions: input.modelOptions
1848
+ },
1849
+ ob,
1850
+ abortSignal
1851
+ );
1852
+ }
1853
+ async exec(data, input, options, ob, abortSignal) {
1854
+ let define;
1855
+ if (data.define) {
1856
+ define = data.define;
1857
+ } else {
1858
+ const res = this.#parser.parse(data);
1859
+ if (res.error) {
1860
+ throw res.error;
1861
+ }
1862
+ define = res.data;
1863
+ }
1864
+ try {
1865
+ return await this.runParse(define, input, ob, abortSignal);
1866
+ } catch (error) {
1867
+ if (options.showError) {
1868
+ }
1869
+ throw error;
1870
+ }
1871
+ }
1872
+ #contextBuild = inject11(ContextBuildService);
1873
+ async agentChat(input, fn, abort) {
1874
+ const workflow = this.#contextBuild.createWorkflow(input, input.inlineMode);
1875
+ const subject = new Subject();
1876
+ subject.subscribe({
1877
+ next: (value) => {
1878
+ fn(value);
1879
+ }
1880
+ });
1881
+ const result2 = await this.exec(
1882
+ { flow: workflow },
1883
+ {
1884
+ ...input
1885
+ },
1886
+ { showError: true },
1887
+ subject,
1888
+ abort
1889
+ );
1890
+ return result2;
1891
+ }
1892
+ };
1893
+
1894
+ // packages/workflow/workflow-select.service.ts
1895
+ import { computed as computed4, inject as inject13 } from "static-injector";
1896
+ import { createNormalizeVfs, path as path2 } from "@cyia/vfs2";
1897
+
1898
+ // packages/workflow/workflow-file.service.ts
1899
+ import { inject as inject12 } from "static-injector";
1900
+ import { path } from "@cyia/vfs2";
1901
+ import { RawFile } from "@cyia/bundle-file";
1902
+ var WorkflowFileService = class {
1903
+ #config = inject12(WorkflowConfigToken);
1904
+ #fileMap = /* @__PURE__ */ new Map();
1905
+ getFile(filePath) {
1906
+ const nFilePath = path.normalize(filePath);
1907
+ let file = this.#fileMap.get(nFilePath);
1908
+ if (!file) {
1909
+ file = new RawFile(nFilePath);
1910
+ this.#fileMap.set(nFilePath, file);
1911
+ }
1912
+ return file;
1913
+ }
1914
+ /** 关闭已打开的默认工作流文件 */
1915
+ async closeDefulatFile() {
1916
+ const dir = path.join(this.#config().dir, "default");
1917
+ for (const [filePath, file] of this.#fileMap) {
1918
+ if (filePath.startsWith(dir)) {
1919
+ await file.close();
1920
+ this.#fileMap.delete(filePath);
1921
+ }
1922
+ }
1923
+ }
1924
+ async remove(filePath) {
1925
+ const nFilePath = path.normalize(filePath);
1926
+ const file = this.#fileMap.get(nFilePath);
1927
+ if (!file) {
1928
+ return;
1929
+ }
1930
+ await file.close();
1931
+ this.#fileMap.delete(nFilePath);
1932
+ }
1933
+ };
1934
+
1935
+ // packages/workflow/workflow-select.service.ts
1936
+ var WorkflowSelectService = class {
1937
+ #fileService = inject13(WorkflowFileService);
1938
+ #config = inject13(WorkflowConfigToken);
1939
+ #vfs = computed4(
1940
+ () => createNormalizeVfs({
1941
+ dir: this.#config().dir
1942
+ })
1943
+ );
1944
+ async get({ workflowName }) {
1945
+ const wfPath = path2.join(this.#config().dir, `${workflowName}.workflow`);
1946
+ if (!await this.#vfs().exists(wfPath)) {
1947
+ const isDefulat = workflowName.startsWith("default/");
1948
+ throw new Error(
1949
+ `工作流: [${workflowName}] 不存在;${isDefulat ? "您可以尝试[同步内置工作流]更新" : ""}`
1950
+ );
1951
+ }
1952
+ const file = this.#fileService.getFile(wfPath);
1953
+ return await file.readOriginData();
1954
+ }
1955
+ async getList() {
1956
+ const rootDir = this.#config().dir;
1957
+ const list = [];
1958
+ const listG = this.#vfs().glob("**/*.workflow", { cwd: rootDir });
1959
+ for await (const item of listG) {
1960
+ const relFilePath = item.replace(/\.workflow$/, "");
1961
+ list.push({
1962
+ relPath: relFilePath,
1963
+ name: path2.basename(relFilePath),
1964
+ stat: await this.#vfs().stat(item)
1965
+ });
1966
+ }
1967
+ return list;
1968
+ }
1969
+ };
1970
+
1971
+ // packages/workflow/module.ts
1972
+ var WORKFLOW_MODULE = {
1973
+ provider: [
1974
+ WorkflowExecService,
1975
+ WorkflowParserService,
1976
+ WorkflowSelectService,
1977
+ WorkflowFileService,
1978
+ ContextBuildService,
1979
+ InlineBuilderService,
1980
+ WorkflowRunnerService,
1981
+ InlineParametersService,
1982
+ WorkflowPluginService,
1983
+ InlineNodeService
1984
+ ],
1985
+ token: {
1986
+ ChatServiceToken,
1987
+ WorkflowConfigToken
1988
+ }
1989
+ };
1990
+ export {
1991
+ AbortSignalToken,
1992
+ ChatServiceToken,
1993
+ CommonDataDefine,
1994
+ CurrentCallNodeToken,
1995
+ CurrentContextToken,
1996
+ CurrentNodeToken,
1997
+ CurrentWorkflowToken,
1998
+ DEFAULT_CHAT_SCHEMA_KEY,
1999
+ DEFAULT_INPUT_KEY,
2000
+ EXAMPLES_DEFINE,
2001
+ EnviromentParametersToken,
2002
+ HandleDataDefine,
2003
+ HelpObj,
2004
+ INLINE_Template,
2005
+ INLINE_Template2,
2006
+ ITERATION_ITEM_SYMBOL,
2007
+ InlineNodeService,
2008
+ InputParamsToken,
2009
+ InputsToken,
2010
+ LLMDataDefine,
2011
+ ModelOptionsToken,
2012
+ NodeRunnerBase,
2013
+ ParentContextToken,
2014
+ RUNNER_ORIGIN_OUTPUT_KEY,
2015
+ TemplateFormatService,
2016
+ UseInputToken,
2017
+ WORKFLOW_MODULE,
2018
+ WorkflowConfigToken,
2019
+ WorkflowEmitter,
2020
+ WorkflowExecService,
2021
+ WorkflowFileService,
2022
+ WorkflowNodeType,
2023
+ WorkflowParserService,
2024
+ WorkflowPluginService,
2025
+ WorkflowRunnerContext,
2026
+ WorkflowRunnerService,
2027
+ WorkflowSelectService,
2028
+ createLLMData,
2029
+ createResultData,
2030
+ flatFilterHandleList,
2031
+ generateHandle,
2032
+ isChatStream,
2033
+ llmModelConfig
2034
+ };
2035
+ //# sourceMappingURL=index.mjs.map