nolo-cli 0.1.10 → 0.1.11

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 (240) hide show
  1. package/README.md +0 -32
  2. package/agentRuntimeCommands.ts +3 -3
  3. package/commandRegistry.ts +2 -2
  4. package/machineCommands.ts +31 -6
  5. package/package.json +6 -22
  6. package/ai/agent/_executeModel.ts +0 -118
  7. package/ai/agent/agentSlice.ts +0 -525
  8. package/ai/agent/appWorkingMemory.ts +0 -126
  9. package/ai/agent/avatarUtils.ts +0 -24
  10. package/ai/agent/buildEditingContext.ts +0 -373
  11. package/ai/agent/buildSystemPrompt.ts +0 -532
  12. package/ai/agent/cleanAgentMessages.ts +0 -140
  13. package/ai/agent/cliChatClient.ts +0 -119
  14. package/ai/agent/cliExecutor.ts +0 -733
  15. package/ai/agent/cliPrompt.ts +0 -10
  16. package/ai/agent/contextCompiler.ts +0 -107
  17. package/ai/agent/contextLayerContract.ts +0 -44
  18. package/ai/agent/createAgentSchema.ts +0 -234
  19. package/ai/agent/executeToolCall.ts +0 -58
  20. package/ai/agent/fetchAgentContexts.ts +0 -42
  21. package/ai/agent/generatePrompt.ts +0 -3
  22. package/ai/agent/getFullChatContextKeys.ts +0 -168
  23. package/ai/agent/hooks/fetchPublicAgents.ts +0 -133
  24. package/ai/agent/hooks/useAgentConfig.ts +0 -61
  25. package/ai/agent/hooks/useAgentDialog.ts +0 -35
  26. package/ai/agent/hooks/useAgentFormValidation.ts +0 -202
  27. package/ai/agent/hooks/usePublicAgents.ts +0 -473
  28. package/ai/agent/machineRunPermissions.ts +0 -95
  29. package/ai/agent/persistMessageWithFixedId.ts +0 -37
  30. package/ai/agent/planSlice.ts +0 -259
  31. package/ai/agent/referenceUtils.ts +0 -229
  32. package/ai/agent/runAgentBackground.ts +0 -238
  33. package/ai/agent/runAgentClientLoop.ts +0 -138
  34. package/ai/agent/runtimeGuidance.ts +0 -97
  35. package/ai/agent/runtimeServerBase.ts +0 -37
  36. package/ai/agent/server/fetchPublicAgents.ts +0 -128
  37. package/ai/agent/startParallelAgentStreams.ts +0 -424
  38. package/ai/agent/startupProtocol.ts +0 -53
  39. package/ai/agent/streamAgentChatTurn.ts +0 -1278
  40. package/ai/agent/streamAgentChatTurnUtils.ts +0 -738
  41. package/ai/agent/types.ts +0 -71
  42. package/ai/agent/utils/imageOutput.ts +0 -33
  43. package/ai/agent/utils/sortUtils.ts +0 -250
  44. package/ai/agent/web/referencePickerUtils.ts +0 -146
  45. package/ai/ai.locale.ts +0 -1079
  46. package/ai/chat/accumulateToolCallChunks.ts +0 -95
  47. package/ai/chat/fetchUtils.native.ts +0 -276
  48. package/ai/chat/fetchUtils.ts +0 -153
  49. package/ai/chat/parseApiError.ts +0 -64
  50. package/ai/chat/parseMultilineSSE.ts +0 -95
  51. package/ai/chat/sendOpenAICompletionsRequest.native.ts +0 -682
  52. package/ai/chat/sendOpenAICompletionsRequest.ts +0 -703
  53. package/ai/chat/sendOpenAIResponseRequest.ts +0 -491
  54. package/ai/chat/shouldUseServerProxy.ts +0 -18
  55. package/ai/chat/sseClient.native.ts +0 -91
  56. package/ai/chat/sseClient.ts +0 -67
  57. package/ai/chat/streamReader.native.ts +0 -31
  58. package/ai/chat/streamReader.ts +0 -62
  59. package/ai/chat/updateTotalUsage.ts +0 -72
  60. package/ai/context/buildReferenceContext.ts +0 -437
  61. package/ai/context/calculateContextUsage.ts +0 -133
  62. package/ai/context/retention.ts +0 -165
  63. package/ai/context/tokenUtils.ts +0 -78
  64. package/ai/index.ts +0 -1
  65. package/ai/llm/calculateGeminiImageTokens.ts +0 -57
  66. package/ai/llm/deepinfra.ts +0 -28
  67. package/ai/llm/fireworks.ts +0 -50
  68. package/ai/llm/generateRequestBody.ts +0 -165
  69. package/ai/llm/getModelContextWindow.ts +0 -84
  70. package/ai/llm/getNoloKey.ts +0 -31
  71. package/ai/llm/getPricing.ts +0 -199
  72. package/ai/llm/hooks/useModelPricing.ts +0 -75
  73. package/ai/llm/imagePricing.ts +0 -40
  74. package/ai/llm/isResponseAPIModel.ts +0 -13
  75. package/ai/llm/mimo.ts +0 -71
  76. package/ai/llm/mistral.ts +0 -22
  77. package/ai/llm/modelAvatar.ts +0 -427
  78. package/ai/llm/models.ts +0 -45
  79. package/ai/llm/openrouterModels.ts +0 -269
  80. package/ai/llm/providers.ts +0 -306
  81. package/ai/llm/reasoningModels.ts +0 -28
  82. package/ai/llm/types.ts +0 -59
  83. package/ai/llm/usageRequestOptions.ts +0 -59
  84. package/ai/memory/capture.ts +0 -148
  85. package/ai/memory/consolidate.ts +0 -104
  86. package/ai/memory/delete.ts +0 -147
  87. package/ai/memory/overlay.ts +0 -84
  88. package/ai/memory/query.ts +0 -38
  89. package/ai/memory/queryShared.ts +0 -160
  90. package/ai/memory/rank.ts +0 -105
  91. package/ai/memory/recentRelationshipRecap.ts +0 -249
  92. package/ai/memory/remember.ts +0 -167
  93. package/ai/memory/runtime.ts +0 -76
  94. package/ai/memory/store.ts +0 -20
  95. package/ai/memory/storeShared.ts +0 -76
  96. package/ai/memory/types.ts +0 -46
  97. package/ai/memory/understanding.ts +0 -349
  98. package/ai/memory/understandingGreeting.ts +0 -264
  99. package/ai/messages/type.ts +0 -20
  100. package/ai/policy/personalizationDialog.ts +0 -333
  101. package/ai/policy/runtimePolicy.ts +0 -440
  102. package/ai/policy/selfUpdateFields.ts +0 -48
  103. package/ai/policy/types.ts +0 -64
  104. package/ai/skills/referenceRuntime.ts +0 -274
  105. package/ai/skills/skillDiagnostics.ts +0 -251
  106. package/ai/skills/skillDocBuilder.ts +0 -139
  107. package/ai/skills/skillDocProtocol.ts +0 -434
  108. package/ai/skills/skillReferenceSummary.ts +0 -63
  109. package/ai/skills/skillSummaryMarker.ts +0 -26
  110. package/ai/token/calculatePrice.ts +0 -544
  111. package/ai/token/db.ts +0 -98
  112. package/ai/token/externalToolCost.ts +0 -330
  113. package/ai/token/hooks/useRecords.ts +0 -65
  114. package/ai/token/missingUsageEstimate.ts +0 -42
  115. package/ai/token/modelUsageQuery.ts +0 -252
  116. package/ai/token/normalizeUsage.ts +0 -84
  117. package/ai/token/openaiImageGenerationUsage.ts +0 -56
  118. package/ai/token/prepareTokenUsageData.ts +0 -88
  119. package/ai/token/query.ts +0 -88
  120. package/ai/token/queryUserTokens.ts +0 -59
  121. package/ai/token/resolveBillingTarget.ts +0 -52
  122. package/ai/token/saveTokenRecord.ts +0 -53
  123. package/ai/token/serverDialogProjection.ts +0 -78
  124. package/ai/token/serverTokenWriter.ts +0 -143
  125. package/ai/token/stats.ts +0 -21
  126. package/ai/token/tokenThunks.ts +0 -24
  127. package/ai/token/types.ts +0 -93
  128. package/ai/tools/agent/agentTools.ts +0 -176
  129. package/ai/tools/agent/agentUpdateShared.ts +0 -311
  130. package/ai/tools/agent/callAgentTool.ts +0 -139
  131. package/ai/tools/agent/createAgentTool.ts +0 -512
  132. package/ai/tools/agent/createDialogTool.ts +0 -69
  133. package/ai/tools/agent/createSkillAgentTool.ts +0 -62
  134. package/ai/tools/agent/parallelBudget.ts +0 -221
  135. package/ai/tools/agent/presets/appBuilderPreset.ts +0 -145
  136. package/ai/tools/agent/runLlmTool.ts +0 -96
  137. package/ai/tools/agent/runStreamingAgentTool.ts +0 -73
  138. package/ai/tools/agent/skillAgentArgs.ts +0 -106
  139. package/ai/tools/agent/skillAgentPreset.ts +0 -89
  140. package/ai/tools/agent/streamParallelAgentsTool.ts +0 -122
  141. package/ai/tools/agent/updateAgentTool.ts +0 -96
  142. package/ai/tools/agent/updateSelfTool.ts +0 -113
  143. package/ai/tools/amazonProductScraperTool.ts +0 -86
  144. package/ai/tools/apifyActorClient.ts +0 -45
  145. package/ai/tools/appEditGuard.ts +0 -372
  146. package/ai/tools/appReadSnapshot.ts +0 -153
  147. package/ai/tools/appTools.ts +0 -1549
  148. package/ai/tools/applyEditTool.ts +0 -256
  149. package/ai/tools/applyLineEditsTool.ts +0 -312
  150. package/ai/tools/browserTools/click.ts +0 -33
  151. package/ai/tools/browserTools/closeSession.ts +0 -29
  152. package/ai/tools/browserTools/common.ts +0 -27
  153. package/ai/tools/browserTools/openSession.ts +0 -48
  154. package/ai/tools/browserTools/readContent.ts +0 -38
  155. package/ai/tools/browserTools/selectOption.ts +0 -46
  156. package/ai/tools/browserTools/typeText.ts +0 -42
  157. package/ai/tools/category/createCategoryTool.ts +0 -66
  158. package/ai/tools/category/queryContentsByCategoryTool.ts +0 -69
  159. package/ai/tools/category/updateContentCategoryTool.ts +0 -75
  160. package/ai/tools/cfBrowserTools.ts +0 -319
  161. package/ai/tools/cfSpeechToTextTool.ts +0 -49
  162. package/ai/tools/checkEnvTool.ts +0 -65
  163. package/ai/tools/cloudflareCrawlTool.ts +0 -289
  164. package/ai/tools/codeSearchTool.ts +0 -111
  165. package/ai/tools/codeTools.ts +0 -101
  166. package/ai/tools/createDocTool.ts +0 -132
  167. package/ai/tools/createPlanTool.ts +0 -999
  168. package/ai/tools/createSkillDocTool.ts +0 -155
  169. package/ai/tools/createWorkflowTool.ts +0 -154
  170. package/ai/tools/deepseekOcrTool.ts +0 -34
  171. package/ai/tools/delayTool.ts +0 -31
  172. package/ai/tools/deleteSpacesTool.ts +0 -325
  173. package/ai/tools/deleteSpacesToolModel.ts +0 -159
  174. package/ai/tools/devReloadUtils.ts +0 -29
  175. package/ai/tools/dialogMessageSearch.ts +0 -137
  176. package/ai/tools/doctorSkillTool.ts +0 -72
  177. package/ai/tools/ecommerceScraperTool.ts +0 -86
  178. package/ai/tools/emailTools.ts +0 -549
  179. package/ai/tools/evalSkillTool.ts +0 -92
  180. package/ai/tools/exaSearchTool.ts +0 -64
  181. package/ai/tools/execBashTool.ts +0 -379
  182. package/ai/tools/executeSqlTool.ts +0 -192
  183. package/ai/tools/fetchWebpageSupport.ts +0 -309
  184. package/ai/tools/fetchWebpageTool.ts +0 -84
  185. package/ai/tools/geminiImagePreviewTool.ts +0 -361
  186. package/ai/tools/generateDocxTool.ts +0 -215
  187. package/ai/tools/googleSearchScraperTool.ts +0 -106
  188. package/ai/tools/importDataTool.ts +0 -133
  189. package/ai/tools/importSkillTool.ts +0 -162
  190. package/ai/tools/index.ts +0 -1858
  191. package/ai/tools/listFilesTool.ts +0 -82
  192. package/ai/tools/listUserSpacesTool.ts +0 -113
  193. package/ai/tools/modelUsageTools.ts +0 -142
  194. package/ai/tools/olmOcrTool.ts +0 -34
  195. package/ai/tools/openaiImageTool.ts +0 -218
  196. package/ai/tools/paddleOcrTool.ts +0 -34
  197. package/ai/tools/prepareTools.ts +0 -23
  198. package/ai/tools/readDocTool.ts +0 -84
  199. package/ai/tools/readFileTool.ts +0 -211
  200. package/ai/tools/readTool.ts +0 -163
  201. package/ai/tools/readXPostTool.ts +0 -233
  202. package/ai/tools/rememberMemoryTool.ts +0 -84
  203. package/ai/tools/remotionVideoTool.ts +0 -151
  204. package/ai/tools/searchDialogMessagesTool.ts +0 -222
  205. package/ai/tools/searchRepoTool.ts +0 -115
  206. package/ai/tools/searchWorkspaceTool.ts +0 -259
  207. package/ai/tools/skillFollowup.ts +0 -86
  208. package/ai/tools/surfWeatherTool.ts +0 -169
  209. package/ai/tools/table/addTableRowTool.ts +0 -217
  210. package/ai/tools/table/createTableTool.ts +0 -315
  211. package/ai/tools/table/rowTools.ts +0 -366
  212. package/ai/tools/table/schemaTools.ts +0 -244
  213. package/ai/tools/table/shareTableTool.ts +0 -148
  214. package/ai/tools/table/toolShared.ts +0 -129
  215. package/ai/tools/toolApiClient.ts +0 -198
  216. package/ai/tools/toolNameAliases.ts +0 -57
  217. package/ai/tools/toolResultError.ts +0 -42
  218. package/ai/tools/toolRunSlice.ts +0 -303
  219. package/ai/tools/toolSchemaCompatibility.ts +0 -53
  220. package/ai/tools/toolVisibility.ts +0 -4
  221. package/ai/tools/types.ts +0 -20
  222. package/ai/tools/uiAskChoiceTool.ts +0 -104
  223. package/ai/tools/updateContentTitleTool.ts +0 -84
  224. package/ai/tools/updateDocTool.ts +0 -105
  225. package/ai/tools/updateUserPreferenceProfileTool.ts +0 -145
  226. package/ai/tools/whisperTool.ts +0 -77
  227. package/ai/tools/writeFileTool.ts +0 -210
  228. package/ai/tools/youtubeScraperTool.ts +0 -116
  229. package/ai/tools/ziweiChartTool.ts +0 -678
  230. package/ai/types.ts +0 -55
  231. package/ai/workflow/workflowExecutor.ts +0 -323
  232. package/ai/workflow/workflowSlice.ts +0 -73
  233. package/ai/workflow/workflowTypes.ts +0 -106
  234. package/client/compactDialog.ts +0 -222
  235. package/connector-experimental/capabilities.ts +0 -73
  236. package/connector-experimental/codexBinary.ts +0 -41
  237. package/connector-experimental/heartbeatLoop.ts +0 -22
  238. package/connector-experimental/index.ts +0 -5
  239. package/connector-experimental/machineInfo.ts +0 -46
  240. package/connector-experimental/protocol.ts +0 -54
package/ai/types.ts DELETED
@@ -1,55 +0,0 @@
1
- // packages/ai/types.ts
2
-
3
- export type ModeType =
4
- | "text"
5
- | "image"
6
- | "stream"
7
- | "audio"
8
- | "speech"
9
- | "surf"
10
- | "vision";
11
-
12
- export interface PromptFormData {
13
- name: string;
14
- content: string;
15
- category?: string;
16
- tags?: string[];
17
- }
18
-
19
- export interface Contexts {
20
- // High priority: context from the user's current input for this request.
21
- currentInputContext?: string | null;
22
-
23
- // Medium priority: references from past conversation messages.
24
- historyContext?: string | null;
25
-
26
- // Specific rules and processes for the bot/agent.
27
- botInstructionsContext?: string | null;
28
-
29
- // General knowledge base documents for lookup.
30
- botKnowledgeContext?: string | null;
31
-
32
- // 🔹 新增:用户级通用提示词
33
- userGlobalPrompt?: string;
34
-
35
- /** 当前正在编辑的对象描述(表格 / 页面 / 文章等),由 buildEditingContextSummary 构造 */
36
- editingContext?: string | null;
37
-
38
- /** 当前对话里最近一次 app 相关工具调用提炼出的工作记忆,不依赖右侧 editing target */
39
- appWorkingMemory?: string | null;
40
-
41
- /** 当前所在的 Space 信息(Agent 所处的工作台),包含标题、描述等 */
42
- spaceContext?: string | null;
43
-
44
- /** 用户偏好与自动化边界(tone / capture / read policy) */
45
- userPolicyContext?: string | null;
46
-
47
- /** 对话增量摘要:已压缩的历史消息概要 */
48
- dialogSummary?: string | null;
49
-
50
- /** 主动工作摘要:阶段性沉淀,不代表原始消息已被裁剪 */
51
- proactiveSummary?: string | null;
52
-
53
- /** 压缩消息中提取的引用 Key */
54
- referenceKeys?: string[];
55
- }
@@ -1,323 +0,0 @@
1
- /**
2
- * Workflow Executor
3
- *
4
- * Deterministic execution engine — zero LLM orchestration tokens.
5
- * Each step runs directly without asking LLM "what to do next".
6
- * Only "llm" type steps call the model (single call, no tool loop).
7
- */
8
-
9
- import { createAsyncThunk } from "@reduxjs/toolkit";
10
- import type { RootState } from "app/store";
11
- import { runLlm } from "ai/agent/agentSlice";
12
- import { toolExecutors } from "ai/tools";
13
- import {
14
- setWorkflow,
15
- updateStep,
16
- incrementStepsExecuted,
17
- incrementFailedSteps,
18
- } from "./workflowSlice";
19
- import type {
20
- WorkflowDefinition,
21
- WorkflowStep,
22
- WorkflowToolStep,
23
- WorkflowLlmStep,
24
- WorkflowParallelStep,
25
- WorkflowStepState,
26
- WorkflowResult,
27
- } from "./workflowTypes";
28
-
29
- // --- Template Resolution ---
30
-
31
- /**
32
- * Resolves {{steps.<id>.result}} and {{steps.<id>.result[N]}} templates.
33
- * Walks nested objects/arrays recursively.
34
- */
35
- function resolveTemplates(
36
- value: any,
37
- results: Record<string, any>
38
- ): any {
39
- if (typeof value === "string") {
40
- return value.replace(
41
- /\{\{steps\.([^.}\s]+)\.result(\[\d+\])?\}\}/g,
42
- (match, stepId, indexPart) => {
43
- const stepResult = results[stepId];
44
- if (stepResult === undefined) {
45
- console.warn(`Workflow: cannot resolve {{steps.${stepId}.result}} — step not completed yet`);
46
- return match;
47
- }
48
- let resolved = stepResult;
49
- if (indexPart) {
50
- const idx = parseInt(indexPart.slice(1, -1), 10);
51
- if (Array.isArray(resolved) && idx < resolved.length) {
52
- resolved = resolved[idx];
53
- } else {
54
- console.warn(`Workflow: index ${idx} out of range for steps.${stepId}.result`);
55
- return match;
56
- }
57
- }
58
- return typeof resolved === "object" ? JSON.stringify(resolved) : String(resolved);
59
- }
60
- );
61
- }
62
- if (Array.isArray(value)) {
63
- return value.map((v) => resolveTemplates(v, results));
64
- }
65
- if (value !== null && typeof value === "object") {
66
- return Object.fromEntries(
67
- Object.entries(value).map(([k, v]) => [k, resolveTemplates(v, results)])
68
- );
69
- }
70
- return value;
71
- }
72
-
73
- // --- Condition Evaluation (safe allowlist interpreter) ---
74
-
75
- /**
76
- * Validates that an expression contains ONLY:
77
- * - steps.<identifier> property paths
78
- * - comparison operators: === !== > < >= <=
79
- * - logical operators: && || !
80
- * - string literals, number literals, boolean/null keywords
81
- * - parentheses and whitespace
82
- *
83
- * Strategy: substitute every safe token with a placeholder, then assert
84
- * nothing else remains. This allowlist approach is far more robust than a
85
- * blocklist, which can be bypassed with Unicode escapes or bracket notation.
86
- */
87
- function isSafeConditionExpression(expr: string): boolean {
88
- let s = expr.trim();
89
- if (!s) return false;
90
-
91
- // 1. Replace double/single-quoted string literals (no newlines inside)
92
- s = s.replace(/"[^"\n\\]*(?:\\.[^"\n\\]*)*"/g, "0");
93
- s = s.replace(/'[^'\n\\]*(?:\\.[^'\n\\]*)*/g, "0");
94
-
95
- // 2. Replace number literals (int / float)
96
- s = s.replace(/\b\d+(?:\.\d+)?\b/g, "0");
97
-
98
- // 3. Replace allowed keywords
99
- s = s.replace(/\b(true|false|null|undefined)\b/g, "0");
100
-
101
- // 4. Replace steps.<dotted-path> (e.g. steps.fetchData.output)
102
- s = s.replace(/\bsteps\.[a-zA-Z_][a-zA-Z0-9_.]*\b/g, "0");
103
-
104
- // 5. What's left should only be operators, parens, whitespace
105
- // Allowed characters: 0 (placeholder) space ( ) ! & | = < >
106
- return /^[0\s()!&|=<>]+$/.test(s);
107
- }
108
-
109
- /**
110
- * Safely resolves a dotted property path like "steps.fetchData.output"
111
- * against the given results object. Returns undefined for any unknown path.
112
- */
113
- function resolvePath(path: string, results: Record<string, any>): unknown {
114
- // path must be "steps.<segment>[.<segment>...]"
115
- const parts = path.split(".");
116
- if (parts[0] !== "steps" || parts.length < 2) return undefined;
117
- let cur: any = results;
118
- for (let i = 1; i < parts.length; i++) {
119
- if (cur === null || cur === undefined || typeof cur !== "object") return undefined;
120
- cur = cur[parts[i]];
121
- }
122
- return cur;
123
- }
124
-
125
- /**
126
- * Evaluates a condition expression against step results.
127
- *
128
- * Uses an allowlist validator to guarantee the expression contains nothing
129
- * but property lookups, comparison/logical operators, and literals before
130
- * delegating to the JS engine. This eliminates the code-execution surface
131
- * that a keyword blocklist cannot reliably close.
132
- */
133
- function evaluateCondition(
134
- expression: string,
135
- results: Record<string, any>
136
- ): boolean {
137
- if (!isSafeConditionExpression(expression)) {
138
- console.warn(
139
- `Workflow: condition expression rejected by allowlist: "${expression}"`
140
- );
141
- return false;
142
- }
143
- try {
144
- // At this point the expression has been validated to contain only safe
145
- // tokens. We substitute all steps.* paths with their runtime values so
146
- // the final eval string never needs to reference external globals.
147
- const resolved = expression.replace(
148
- /\bsteps\.[a-zA-Z_][a-zA-Z0-9_.]*\b/g,
149
- (match) => JSON.stringify(resolvePath(match, results))
150
- );
151
- // eslint-disable-next-line no-new-func
152
- const fn = new Function(`"use strict"; return !!(${resolved})`);
153
- return fn();
154
- } catch (e) {
155
- console.warn(`Workflow: condition eval failed: "${expression}"`, e);
156
- return false;
157
- }
158
- }
159
-
160
-
161
-
162
- /**
163
- * Executes `fn` up to `maxRetries + 1` times total.
164
- * Throws the last error if all attempts fail.
165
- */
166
- async function executeWithRetry<T>(
167
- fn: () => Promise<T>,
168
- maxRetries: number
169
- ): Promise<T> {
170
- let lastError: any;
171
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
172
- try {
173
- return await fn();
174
- } catch (err) {
175
- lastError = err;
176
- }
177
- }
178
- throw lastError;
179
- }
180
-
181
- // --- Single Step Executors ---
182
-
183
- async function executeToolStep(
184
- step: WorkflowToolStep,
185
- results: Record<string, any>,
186
- thunkApi: any
187
- ): Promise<any> {
188
- const executor = toolExecutors[step.tool];
189
- if (!executor) throw new Error(`Workflow: unknown tool "${step.tool}"`);
190
- const resolvedArgs = resolveTemplates(step.args, results);
191
- const result = await executor(resolvedArgs, thunkApi);
192
- return result?.rawData ?? result;
193
- }
194
-
195
- async function executeLlmStep(
196
- step: WorkflowLlmStep,
197
- results: Record<string, any>,
198
- thunkApi: any
199
- ): Promise<any> {
200
- const { dispatch } = thunkApi;
201
- const resolvedPrompt = resolveTemplates(step.prompt, results);
202
- const result = await dispatch(
203
- runLlm({
204
- content: resolvedPrompt,
205
- isStreaming: false,
206
- ...(step.model && { modelOverride: step.model }),
207
- })
208
- ).unwrap();
209
- return result;
210
- }
211
-
212
- async function executeParallelStep(
213
- step: WorkflowParallelStep,
214
- results: Record<string, any>,
215
- thunkApi: any
216
- ): Promise<Record<string, any>> {
217
- const subResults = await Promise.all(
218
- step.steps.map(async (sub) => {
219
- const subResult =
220
- sub.type === "tool"
221
- ? await executeToolStep(sub as WorkflowToolStep, results, thunkApi)
222
- : await executeLlmStep(sub as WorkflowLlmStep, results, thunkApi);
223
- return [sub.id, subResult] as [string, any];
224
- })
225
- );
226
- return Object.fromEntries(subResults);
227
- }
228
-
229
- // --- Main Executor Thunk ---
230
-
231
- export const runWorkflow = createAsyncThunk<
232
- WorkflowResult,
233
- { definition: WorkflowDefinition; dialogKey?: string },
234
- { state: RootState }
235
- >("workflow/run", async ({ definition }, thunkApi) => {
236
- const { dispatch } = thunkApi;
237
-
238
- // Initialize Redux state for UI visibility
239
- const initialStepStates: WorkflowStepState[] = definition.steps.map((s) => ({
240
- id: s.id,
241
- title: s.title,
242
- type: s.type,
243
- status: "pending",
244
- }));
245
- dispatch(setWorkflow({ title: definition.title, steps: initialStepStates }));
246
-
247
- const results: Record<string, any> = {};
248
- // Set of step IDs to skip (controlled by condition steps)
249
- const skippedIds = new Set<string>();
250
-
251
- for (const step of definition.steps) {
252
- if (skippedIds.has(step.id)) {
253
- dispatch(updateStep({ id: step.id, updates: { status: "skipped" } }));
254
- continue;
255
- }
256
-
257
- dispatch(updateStep({ id: step.id, updates: { status: "in-progress" } }));
258
-
259
- try {
260
- let result: any;
261
-
262
- if (step.type === "tool" || step.type === "llm") {
263
- const retryable = step as WorkflowToolStep | WorkflowLlmStep;
264
- const policy = retryable.onError ?? "stop";
265
- const maxRetries =
266
- policy === "retry" ? ((retryable as WorkflowToolStep).retryCount ?? 1) : 0;
267
-
268
- result = await executeWithRetry(
269
- () =>
270
- step.type === "tool"
271
- ? executeToolStep(step as WorkflowToolStep, results, thunkApi)
272
- : executeLlmStep(step as WorkflowLlmStep, results, thunkApi),
273
- maxRetries
274
- );
275
-
276
- } else if (step.type === "parallel") {
277
- result = await executeParallelStep(step, results, thunkApi);
278
- // Flatten sub-step results into the top-level map so subsequent steps
279
- // can reference them directly via {{steps.<subId>.result}}.
280
- for (const [subId, subResult] of Object.entries(
281
- result as Record<string, any>
282
- )) {
283
- results[subId] = subResult;
284
- }
285
-
286
- } else if (step.type === "condition") {
287
- const passed = evaluateCondition(step.check, results);
288
- result = { passed, check: step.check };
289
- const active = passed ? step.ifTrue : step.ifFalse;
290
- const inactive = passed ? step.ifFalse : step.ifTrue;
291
- // Mark steps not on the active branch as skipped
292
- if (inactive) inactive.forEach((id) => skippedIds.add(id));
293
- // Steps on the active branch are explicitly NOT skipped
294
- if (active) active.forEach((id) => skippedIds.delete(id));
295
- }
296
-
297
- results[step.id] = result;
298
- dispatch(updateStep({ id: step.id, updates: { status: "completed", result } }));
299
- dispatch(incrementStepsExecuted());
300
-
301
- } catch (err: any) {
302
- dispatch(incrementFailedSteps());
303
- dispatch(
304
- updateStep({ id: step.id, updates: { status: "failed", error: err?.message ?? String(err) } })
305
- );
306
-
307
- const policy = (step as WorkflowToolStep | WorkflowLlmStep).onError ?? "stop";
308
-
309
- if (policy === "stop") {
310
- return {
311
- success: false,
312
- results,
313
- failedStep: step.id,
314
- error: err?.message ?? String(err),
315
- };
316
- }
317
- // skip / retry-exhausted: record null and continue
318
- results[step.id] = null;
319
- }
320
- }
321
-
322
- return { success: true, results };
323
- });
@@ -1,73 +0,0 @@
1
- import { type PayloadAction, createSlice } from "@reduxjs/toolkit";
2
- import type { RootState } from "app/store";
3
- import type {
4
- WorkflowStepState,
5
- WorkflowExecutionStats,
6
- } from "./workflowTypes";
7
-
8
- interface WorkflowSliceState {
9
- title: string | null;
10
- steps: WorkflowStepState[];
11
- stats: WorkflowExecutionStats;
12
- }
13
-
14
- const initialState: WorkflowSliceState = {
15
- title: null,
16
- steps: [],
17
- stats: {
18
- startTime: null,
19
- totalStepsExecuted: 0,
20
- failedSteps: 0,
21
- },
22
- };
23
-
24
- const workflowSlice = createSlice({
25
- name: "workflow",
26
- initialState,
27
- reducers: {
28
- setWorkflow: (
29
- state,
30
- action: PayloadAction<{ title: string; steps: WorkflowStepState[] }>
31
- ) => {
32
- state.title = action.payload.title;
33
- state.steps = action.payload.steps;
34
- state.stats = { startTime: Date.now(), totalStepsExecuted: 0, failedSteps: 0 };
35
- },
36
-
37
- updateStep: (
38
- state,
39
- action: PayloadAction<{ id: string; updates: Partial<WorkflowStepState> }>
40
- ) => {
41
- const step = state.steps.find((s) => s.id === action.payload.id);
42
- if (step) Object.assign(step, action.payload.updates);
43
- },
44
-
45
- incrementStepsExecuted: (state) => {
46
- state.stats.totalStepsExecuted += 1;
47
- },
48
-
49
- incrementFailedSteps: (state) => {
50
- state.stats.failedSteps += 1;
51
- },
52
-
53
- clearWorkflow: () => initialState,
54
- },
55
- });
56
-
57
- export const {
58
- setWorkflow,
59
- updateStep,
60
- incrementStepsExecuted,
61
- incrementFailedSteps,
62
- clearWorkflow,
63
- } = workflowSlice.actions;
64
-
65
- export const selectWorkflowSteps = (state: RootState) => state.workflow.steps;
66
- export const selectWorkflowTitle = (state: RootState) => state.workflow.title;
67
- export const selectWorkflowStats = (state: RootState) => state.workflow.stats;
68
- export const selectPendingSteps = (state: RootState) =>
69
- state.workflow.steps.filter((s) => s.status === "pending");
70
- export const selectCompletedSteps = (state: RootState) =>
71
- state.workflow.steps.filter((s) => s.status === "completed");
72
-
73
- export default workflowSlice.reducer;
@@ -1,106 +0,0 @@
1
- // Workflow: deterministic execution engine, zero LLM orchestration tokens.
2
- // LLM calls createWorkflow once to define steps; engine executes without further LLM involvement.
3
- // Only "llm" type steps invoke the model; all others run as pure tool calls.
4
-
5
- export type WorkflowStepStatus = "pending" | "in-progress" | "completed" | "failed" | "skipped";
6
-
7
- export type OnErrorPolicy = "stop" | "skip" | "retry";
8
-
9
- // --- Step Types ---
10
-
11
- export interface WorkflowToolStep {
12
- id: string;
13
- type: "tool";
14
- title?: string;
15
- /** Registered tool name */
16
- tool: string;
17
- /** Args supporting {{steps.<id>.result}} and {{steps.<id>.result[N]}} templates */
18
- args: Record<string, any>;
19
- onError?: OnErrorPolicy;
20
- retryCount?: number;
21
- }
22
-
23
- export interface WorkflowLlmStep {
24
- id: string;
25
- type: "llm";
26
- title?: string;
27
- /** Prompt supporting {{steps.<id>.result}} templates */
28
- prompt: string;
29
- model?: string;
30
- onError?: OnErrorPolicy;
31
- }
32
-
33
- /** All steps inside run concurrently via Promise.all */
34
- export interface WorkflowParallelStep {
35
- id: string;
36
- type: "parallel";
37
- title?: string;
38
- steps: (WorkflowToolStep | WorkflowLlmStep)[];
39
- }
40
-
41
- /**
42
- * Pure JS condition check — no LLM.
43
- * `check` is a JS expression string evaluated with step results in scope.
44
- *
45
- * Supported syntax (allowlist):
46
- * - Dotted property access: `steps.<stepId>.<property>[.<nested>...]`
47
- * - Comparison operators: === !== > < >= <=
48
- * - Logical operators: && || !
49
- * - String / number / boolean / null literals
50
- * - Parentheses for grouping
51
- *
52
- * Note: bracket notation (`steps['id']`) and `.result` wrappers are NOT supported.
53
- * The value stored for each step is the raw executor return value, accessed directly:
54
- * e.g. `"steps.validate.isValid === true"`
55
- * `"steps.score.value >= 80 && steps.flag.ok !== false"`
56
- */
57
- export interface WorkflowConditionStep {
58
- id: string;
59
- type: "condition";
60
- title?: string;
61
- check: string;
62
- /** Step IDs to execute when check is truthy (skip others) */
63
- ifTrue?: string[];
64
- /** Step IDs to execute when check is falsy (skip others) */
65
- ifFalse?: string[];
66
- }
67
-
68
- export type WorkflowStep =
69
- | WorkflowToolStep
70
- | WorkflowLlmStep
71
- | WorkflowParallelStep
72
- | WorkflowConditionStep;
73
-
74
- // --- Workflow Definition ---
75
-
76
- export interface WorkflowDefinition {
77
- title: string;
78
- steps: WorkflowStep[];
79
- }
80
-
81
- // --- Execution State (stored in Redux) ---
82
-
83
- export interface WorkflowStepState {
84
- id: string;
85
- title?: string;
86
- type: WorkflowStep["type"];
87
- status: WorkflowStepStatus;
88
- result?: any;
89
- error?: string;
90
- }
91
-
92
- export interface WorkflowExecutionStats {
93
- startTime: number | null;
94
- totalStepsExecuted: number;
95
- failedSteps: number;
96
- }
97
-
98
- // --- Result ---
99
-
100
- export interface WorkflowResult {
101
- success: boolean;
102
- /** Results keyed by step id */
103
- results: Record<string, any>;
104
- failedStep?: string;
105
- error?: string;
106
- }