donobu 3.5.4 → 3.6.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.
- package/dist/apis/GptConfigsApi.d.ts.map +1 -1
- package/dist/apis/GptConfigsApi.js +0 -2
- package/dist/apis/GptConfigsApi.js.map +1 -1
- package/dist/assets/generated/version +1 -1
- package/dist/envVars.d.ts +0 -2
- package/dist/envVars.d.ts.map +1 -1
- package/dist/envVars.js +0 -4
- package/dist/envVars.js.map +1 -1
- package/dist/esm/apis/GptConfigsApi.d.ts.map +1 -1
- package/dist/esm/apis/GptConfigsApi.js +0 -2
- package/dist/esm/apis/GptConfigsApi.js.map +1 -1
- package/dist/esm/assets/generated/version +1 -1
- package/dist/esm/envVars.d.ts +0 -2
- package/dist/esm/envVars.d.ts.map +1 -1
- package/dist/esm/envVars.js +0 -4
- package/dist/esm/envVars.js.map +1 -1
- package/dist/esm/lib/PageAi.d.ts +1 -1
- package/dist/esm/lib/PageAi.js +1 -1
- package/dist/esm/lib/PageAi.js.map +1 -1
- package/dist/esm/lib/createDonobuExtendedPage.js +1 -1
- package/dist/esm/lib/createDonobuExtendedPage.js.map +1 -1
- package/dist/esm/lib/fixtures/gptClients.d.ts +7 -61
- package/dist/esm/lib/fixtures/gptClients.d.ts.map +1 -1
- package/dist/esm/lib/fixtures/gptClients.js +48 -160
- package/dist/esm/lib/fixtures/gptClients.js.map +1 -1
- package/dist/esm/lib/utils/donobuTestStack.d.ts +4 -2
- package/dist/esm/lib/utils/donobuTestStack.d.ts.map +1 -1
- package/dist/esm/lib/utils/donobuTestStack.js +1 -1
- package/dist/esm/lib/utils/donobuTestStack.js.map +1 -1
- package/dist/esm/managers/AdminApiController.d.ts +1 -1
- package/dist/esm/managers/AdminApiController.d.ts.map +1 -1
- package/dist/esm/managers/AdminApiController.js.map +1 -1
- package/dist/esm/managers/AgentsManager.d.ts +1 -17
- package/dist/esm/managers/AgentsManager.d.ts.map +1 -1
- package/dist/esm/managers/AgentsManager.js +1 -64
- package/dist/esm/managers/AgentsManager.js.map +1 -1
- package/dist/esm/managers/DonobuFlowsManager.d.ts +13 -40
- package/dist/esm/managers/DonobuFlowsManager.d.ts.map +1 -1
- package/dist/esm/managers/DonobuFlowsManager.js +45 -316
- package/dist/esm/managers/DonobuFlowsManager.js.map +1 -1
- package/dist/esm/managers/DonobuStack.d.ts +4 -2
- package/dist/esm/managers/DonobuStack.d.ts.map +1 -1
- package/dist/esm/managers/DonobuStack.js +3 -3
- package/dist/esm/managers/DonobuStack.js.map +1 -1
- package/dist/esm/managers/EnvDataManager.d.ts +11 -0
- package/dist/esm/managers/EnvDataManager.d.ts.map +1 -1
- package/dist/esm/managers/EnvDataManager.js +20 -0
- package/dist/esm/managers/EnvDataManager.js.map +1 -1
- package/dist/esm/managers/FlowCatalog.d.ts +29 -0
- package/dist/esm/managers/FlowCatalog.d.ts.map +1 -0
- package/dist/esm/managers/FlowCatalog.js +153 -0
- package/dist/esm/managers/FlowCatalog.js.map +1 -0
- package/dist/esm/managers/FlowDependencyResolver.d.ts +20 -0
- package/dist/esm/managers/FlowDependencyResolver.d.ts.map +1 -0
- package/dist/esm/managers/FlowDependencyResolver.js +101 -0
- package/dist/esm/managers/FlowDependencyResolver.js.map +1 -0
- package/dist/esm/managers/FlowRuntime.d.ts +18 -0
- package/dist/esm/managers/FlowRuntime.d.ts.map +1 -0
- package/dist/esm/managers/FlowRuntime.js +33 -0
- package/dist/esm/managers/FlowRuntime.js.map +1 -0
- package/dist/esm/managers/GptConfigsManager.d.ts +1 -8
- package/dist/esm/managers/GptConfigsManager.d.ts.map +1 -1
- package/dist/esm/managers/GptConfigsManager.js +1 -177
- package/dist/esm/managers/GptConfigsManager.js.map +1 -1
- package/dist/esm/models/FlowHandle.d.ts +12 -0
- package/dist/esm/models/FlowHandle.d.ts.map +1 -0
- package/dist/esm/models/FlowHandle.js +3 -0
- package/dist/esm/models/FlowHandle.js.map +1 -0
- package/dist/esm/tools/AssertPageTool.d.ts +2 -2
- package/dist/esm/tools/InputRandomizedEmailAddressTool.js +2 -2
- package/dist/esm/tools/RememberPageTextTool.d.ts +5 -0
- package/dist/esm/tools/RememberPageTextTool.d.ts.map +1 -1
- package/dist/esm/tools/RememberPageTextTool.js +5 -0
- package/dist/esm/tools/RememberPageTextTool.js.map +1 -1
- package/dist/lib/PageAi.d.ts +1 -1
- package/dist/lib/PageAi.js +1 -1
- package/dist/lib/PageAi.js.map +1 -1
- package/dist/lib/createDonobuExtendedPage.js +1 -1
- package/dist/lib/createDonobuExtendedPage.js.map +1 -1
- package/dist/lib/fixtures/gptClients.d.ts +7 -61
- package/dist/lib/fixtures/gptClients.d.ts.map +1 -1
- package/dist/lib/fixtures/gptClients.js +48 -160
- package/dist/lib/fixtures/gptClients.js.map +1 -1
- package/dist/lib/utils/donobuTestStack.d.ts +4 -2
- package/dist/lib/utils/donobuTestStack.d.ts.map +1 -1
- package/dist/lib/utils/donobuTestStack.js +1 -1
- package/dist/lib/utils/donobuTestStack.js.map +1 -1
- package/dist/managers/AdminApiController.d.ts +1 -1
- package/dist/managers/AdminApiController.d.ts.map +1 -1
- package/dist/managers/AdminApiController.js.map +1 -1
- package/dist/managers/AgentsManager.d.ts +1 -17
- package/dist/managers/AgentsManager.d.ts.map +1 -1
- package/dist/managers/AgentsManager.js +1 -64
- package/dist/managers/AgentsManager.js.map +1 -1
- package/dist/managers/DonobuFlowsManager.d.ts +13 -40
- package/dist/managers/DonobuFlowsManager.d.ts.map +1 -1
- package/dist/managers/DonobuFlowsManager.js +45 -316
- package/dist/managers/DonobuFlowsManager.js.map +1 -1
- package/dist/managers/DonobuStack.d.ts +4 -2
- package/dist/managers/DonobuStack.d.ts.map +1 -1
- package/dist/managers/DonobuStack.js +3 -3
- package/dist/managers/DonobuStack.js.map +1 -1
- package/dist/managers/EnvDataManager.d.ts +11 -0
- package/dist/managers/EnvDataManager.d.ts.map +1 -1
- package/dist/managers/EnvDataManager.js +20 -0
- package/dist/managers/EnvDataManager.js.map +1 -1
- package/dist/managers/FlowCatalog.d.ts +29 -0
- package/dist/managers/FlowCatalog.d.ts.map +1 -0
- package/dist/managers/FlowCatalog.js +153 -0
- package/dist/managers/FlowCatalog.js.map +1 -0
- package/dist/managers/FlowDependencyResolver.d.ts +20 -0
- package/dist/managers/FlowDependencyResolver.d.ts.map +1 -0
- package/dist/managers/FlowDependencyResolver.js +101 -0
- package/dist/managers/FlowDependencyResolver.js.map +1 -0
- package/dist/managers/FlowRuntime.d.ts +18 -0
- package/dist/managers/FlowRuntime.d.ts.map +1 -0
- package/dist/managers/FlowRuntime.js +33 -0
- package/dist/managers/FlowRuntime.js.map +1 -0
- package/dist/managers/GptConfigsManager.d.ts +1 -8
- package/dist/managers/GptConfigsManager.d.ts.map +1 -1
- package/dist/managers/GptConfigsManager.js +1 -177
- package/dist/managers/GptConfigsManager.js.map +1 -1
- package/dist/models/FlowHandle.d.ts +12 -0
- package/dist/models/FlowHandle.d.ts.map +1 -0
- package/dist/models/FlowHandle.js +3 -0
- package/dist/models/FlowHandle.js.map +1 -0
- package/dist/tools/AssertPageTool.d.ts +2 -2
- package/dist/tools/InputRandomizedEmailAddressTool.js +2 -2
- package/dist/tools/RememberPageTextTool.d.ts +5 -0
- package/dist/tools/RememberPageTextTool.d.ts.map +1 -1
- package/dist/tools/RememberPageTextTool.js +5 -0
- package/dist/tools/RememberPageTextTool.js.map +1 -1
- package/package.json +8 -2
|
@@ -11,6 +11,7 @@ import type { ControlPanelFactory } from '../models/ControlPanel';
|
|
|
11
11
|
import type { CreateDonobuFlow } from '../models/CreateDonobuFlow';
|
|
12
12
|
import type { DonobuAgent } from '../models/DonobuAgentType';
|
|
13
13
|
import type { DonobuDeploymentEnvironment } from '../models/DonobuDeploymentEnvironment';
|
|
14
|
+
import type { FlowHandle } from '../models/FlowHandle';
|
|
14
15
|
import type { FlowMetadata } from '../models/FlowMetadata';
|
|
15
16
|
import type { FlowsQuery } from '../models/FlowMetadata';
|
|
16
17
|
import type { PaginatedResult } from '../models/PaginatedResult';
|
|
@@ -24,10 +25,7 @@ import type { GptConfigsManager } from './GptConfigsManager';
|
|
|
24
25
|
/**
|
|
25
26
|
* Response wrapper for `createFlow` calls.
|
|
26
27
|
*/
|
|
27
|
-
export
|
|
28
|
-
donobuFlow: DonobuFlow;
|
|
29
|
-
job: Promise<Record<string, unknown> | null>;
|
|
30
|
-
}
|
|
28
|
+
export type { FlowHandle };
|
|
31
29
|
export declare class DonobuFlowsManager {
|
|
32
30
|
private readonly deploymentEnvironment;
|
|
33
31
|
private readonly gptClientFactory;
|
|
@@ -40,8 +38,10 @@ export declare class DonobuFlowsManager {
|
|
|
40
38
|
static readonly DEFAULT_MESSAGE_DURATION = 2247;
|
|
41
39
|
static readonly DEFAULT_MAX_TOOL_CALLS = 50;
|
|
42
40
|
static readonly DEFAULT_BROWSER_STATE_FILENAME = "browserstate.json";
|
|
43
|
-
private readonly
|
|
44
|
-
|
|
41
|
+
private readonly flowRuntime;
|
|
42
|
+
private readonly flowCatalog;
|
|
43
|
+
private readonly flowDependencyResolver;
|
|
44
|
+
constructor(deploymentEnvironment: DonobuDeploymentEnvironment, gptClientFactory: GptClientFactory, gptConfigsManager: GptConfigsManager, agentsManager: AgentsManager, flowsPersistenceFactory: FlowsPersistenceFactory, envDataManager: EnvDataManager, controlPanelFactory: ControlPanelFactory, environ: EnvPick<typeof env, 'ANTHROPIC_API_KEY' | 'ANTHROPIC_MODEL_NAME' | 'AWS_ACCESS_KEY_ID' | 'AWS_BEDROCK_MODEL_NAME' | 'AWS_SECRET_ACCESS_KEY' | 'BASE64_GPT_CONFIG' | 'BROWSERBASE_API_KEY' | 'BROWSERBASE_PROJECT_ID' | 'DONOBU_API_KEY' | 'GOOGLE_GENERATIVE_AI_API_KEY' | 'GOOGLE_GENERATIVE_AI_MODEL_NAME' | 'OPENAI_API_KEY' | 'OPENAI_API_MODEL_NAME'>);
|
|
45
45
|
/**
|
|
46
46
|
* Create a flow with the given parameters and invoke its `DonobuFlow#run`
|
|
47
47
|
* method, adding it to list of active flows.
|
|
@@ -110,14 +110,15 @@ export declare class DonobuFlowsManager {
|
|
|
110
110
|
*/
|
|
111
111
|
getFlowsAsPlaywrightProject(flowIds: string[], options: CodeGenerationOptions): Promise<GeneratedProject>;
|
|
112
112
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
113
|
+
* Resolves a GPT client using the provided GPT configuration name, falling back
|
|
114
|
+
* to environment-provided configs (BASE64_GPT_CONFIG, DONOBU_API_KEY,
|
|
115
|
+
* AWS_BEDROCK_MODEL_NAME, ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY,
|
|
116
|
+
* OPENAI_API_KEY) and finally the config bound to the 'flow-runner' agent.
|
|
117
|
+
* Returns a null client if no configuration source is available.
|
|
117
118
|
*
|
|
118
|
-
*
|
|
119
|
+
* Public for testing only.
|
|
119
120
|
**/
|
|
120
|
-
createGptClient(gptConfigName
|
|
121
|
+
createGptClient(gptConfigName?: string): Promise<{
|
|
121
122
|
gptConfigName: string | null;
|
|
122
123
|
agentName: DonobuAgent | null;
|
|
123
124
|
gptClient: GptClient | null;
|
|
@@ -127,34 +128,6 @@ export declare class DonobuFlowsManager {
|
|
|
127
128
|
* {@link BrowserStateNotFoundException} if it is not found.
|
|
128
129
|
*/
|
|
129
130
|
getBrowserStorageState(browserStateRef: BrowserStateReference): Promise<BrowserStorageState>;
|
|
130
|
-
/**
|
|
131
|
-
* Creates a dictionary of environment variables from allowed variable names.
|
|
132
|
-
*
|
|
133
|
-
* This method retrieves environment variable values for each of the provided names
|
|
134
|
-
* from the environment data manager. Only environment variables that exist in
|
|
135
|
-
* the environment data manager will be included in the result.
|
|
136
|
-
*
|
|
137
|
-
* @param allowedEnvVarsByName - Array of environment variable names that are allowed to be accessed.
|
|
138
|
-
* @returns A record mapping environment variable names to their values.
|
|
139
|
-
*
|
|
140
|
-
* @example
|
|
141
|
-
* // Returns { "API_KEY": "abc123", "BASE_URL": "https://example.com" }
|
|
142
|
-
* await buildEnvData(["API_KEY", "BASE_URL", "MISSING_VAR"]);
|
|
143
|
-
*/
|
|
144
|
-
buildEnvData(allowedEnvVarsByName: string[]): Promise<Record<string, string>>;
|
|
145
|
-
/**
|
|
146
|
-
* Extracts dependencies for a single flow by analyzing its browser.initialState
|
|
147
|
-
*/
|
|
148
|
-
private extractFlowDependencies;
|
|
149
|
-
/**
|
|
150
|
-
* Resolves the complete set of flow IDs including all transitive dependencies.
|
|
151
|
-
* Uses breadth-first search to discover all dependencies recursively.
|
|
152
|
-
*/
|
|
153
|
-
private resolveFlowDependencies;
|
|
154
|
-
/**
|
|
155
|
-
* Determines if a new flow ID should replace an existing flow ID in the name mapping.
|
|
156
|
-
*/
|
|
157
|
-
private shouldReplaceFlowMapping;
|
|
158
131
|
private isLocallyRunning;
|
|
159
132
|
}
|
|
160
133
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DonobuFlowsManager.d.ts","sourceRoot":"","sources":["../../../src/managers/DonobuFlowsManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAMjE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAStC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AACzF,OAAO,KAAK,EAAE,YAAY,EAAW,MAAM,wBAAwB,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8CAA8C,CAAC;AAkB5F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"DonobuFlowsManager.d.ts","sourceRoot":"","sources":["../../../src/managers/DonobuFlowsManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,7 +66,9 @@ const Logger_1 = require("../utils/Logger");
|
|
|
66
66
|
const MiscUtils_1 = require("../utils/MiscUtils");
|
|
67
67
|
const TemplateInterpolator_1 = require("../utils/TemplateInterpolator");
|
|
68
68
|
const DonobuFlow_1 = require("./DonobuFlow");
|
|
69
|
-
const
|
|
69
|
+
const FlowCatalog_1 = require("./FlowCatalog");
|
|
70
|
+
const FlowDependencyResolver_1 = require("./FlowDependencyResolver");
|
|
71
|
+
const FlowRuntime_1 = require("./FlowRuntime");
|
|
70
72
|
const InteractionVisualizer_1 = require("./InteractionVisualizer");
|
|
71
73
|
const ToolManager_1 = require("./ToolManager");
|
|
72
74
|
class DonobuFlowsManager {
|
|
@@ -79,7 +81,9 @@ class DonobuFlowsManager {
|
|
|
79
81
|
this.envDataManager = envDataManager;
|
|
80
82
|
this.controlPanelFactory = controlPanelFactory;
|
|
81
83
|
this.environ = environ;
|
|
82
|
-
this.
|
|
84
|
+
this.flowRuntime = new FlowRuntime_1.FlowRuntime();
|
|
85
|
+
this.flowCatalog = new FlowCatalog_1.FlowCatalog(this.flowsPersistenceFactory, this.flowRuntime, this.deploymentEnvironment);
|
|
86
|
+
this.flowDependencyResolver = new FlowDependencyResolver_1.FlowDependencyResolver(this.flowCatalog);
|
|
83
87
|
}
|
|
84
88
|
/**
|
|
85
89
|
* Create a flow with the given parameters and invoke its `DonobuFlow#run`
|
|
@@ -101,7 +105,7 @@ class DonobuFlowsManager {
|
|
|
101
105
|
agentName: null,
|
|
102
106
|
gptClient: gptClient,
|
|
103
107
|
}
|
|
104
|
-
: await this.createGptClient(flowParams.gptConfigNameOverride ??
|
|
108
|
+
: await this.createGptClient(flowParams.gptConfigNameOverride ?? undefined);
|
|
105
109
|
const initialRunMode = flowParams.initialRunMode ??
|
|
106
110
|
(gptClientData.gptClient ? 'AUTONOMOUS' : 'INSTRUCT');
|
|
107
111
|
const browserConfig = flowParams.browser ?? getDefaultBrowserConfig(this.environ);
|
|
@@ -162,7 +166,7 @@ class DonobuFlowsManager {
|
|
|
162
166
|
: await createTempDirectoryForFlow(flowMetadata.id);
|
|
163
167
|
try {
|
|
164
168
|
const flowsPersistence = await this.flowsPersistenceFactory.createPersistenceLayer();
|
|
165
|
-
const envData = await this.
|
|
169
|
+
const envData = await this.envDataManager.getByNames(flowMetadata.envVars ?? []);
|
|
166
170
|
const browserContext = browserContextOverride
|
|
167
171
|
? browserContextOverride
|
|
168
172
|
: await BrowserUtils_1.BrowserUtils.create(browserConfig, tempVideoDir, flowParams.browser?.initialState
|
|
@@ -176,17 +180,15 @@ class DonobuFlowsManager {
|
|
|
176
180
|
current: null,
|
|
177
181
|
}, flowMetadata, controlPanel);
|
|
178
182
|
await flowsPersistence.setFlowMetadata(flowMetadata);
|
|
179
|
-
// Add to activeFlows BEFORE starting the job so that if a flow
|
|
180
|
-
// immediately completes (perhaps due to an error), it will still be
|
|
181
|
-
// cleaned up correctly.
|
|
182
183
|
const flowHandle = {
|
|
183
184
|
donobuFlow: donobuFlow,
|
|
184
185
|
job: Promise.resolve(null), // Temporary placeholder.
|
|
185
186
|
};
|
|
186
|
-
|
|
187
|
+
// Register BEFORE starting the job so cleanup always runs.
|
|
188
|
+
this.flowRuntime.register(flowHandle);
|
|
187
189
|
flowHandle.job = donobuFlow.run().finally(async () => {
|
|
188
190
|
try {
|
|
189
|
-
this.
|
|
191
|
+
this.flowRuntime.remove(donobuFlow.metadata.id);
|
|
190
192
|
}
|
|
191
193
|
catch (error) {
|
|
192
194
|
Logger_1.appLogger.error('Failed to delete active flow:', error);
|
|
@@ -223,7 +225,7 @@ class DonobuFlowsManager {
|
|
|
223
225
|
async renameFlow(flowId, name) {
|
|
224
226
|
validateFlowName(name);
|
|
225
227
|
const activeFlowHandle = this.isLocallyRunning()
|
|
226
|
-
? this.
|
|
228
|
+
? this.flowRuntime.get(flowId)
|
|
227
229
|
: null;
|
|
228
230
|
// If the flow is active, we need to rename it at both its in-memory location
|
|
229
231
|
// and its persisted location.
|
|
@@ -278,7 +280,7 @@ class DonobuFlowsManager {
|
|
|
278
280
|
/** Add a proposed tool call the tool call queue for the given flow by ID. */
|
|
279
281
|
async proposeToolCall(flowId, toolName, parameters) {
|
|
280
282
|
const activeFlowHandle = this.isLocallyRunning()
|
|
281
|
-
? this.
|
|
283
|
+
? this.flowRuntime.get(flowId)
|
|
282
284
|
: null;
|
|
283
285
|
if (!activeFlowHandle) {
|
|
284
286
|
throw new ActiveFlowNotFoundException_1.ActiveFlowNotFoundException(flowId);
|
|
@@ -303,7 +305,7 @@ class DonobuFlowsManager {
|
|
|
303
305
|
if (!this.isLocallyRunning()) {
|
|
304
306
|
throw new ActiveFlowNotFoundException_1.ActiveFlowNotFoundException(flowId);
|
|
305
307
|
}
|
|
306
|
-
const activeFlowHandle = this.
|
|
308
|
+
const activeFlowHandle = this.flowRuntime.get(flowId);
|
|
307
309
|
if (!activeFlowHandle) {
|
|
308
310
|
throw new ActiveFlowNotFoundException_1.ActiveFlowNotFoundException(flowId);
|
|
309
311
|
}
|
|
@@ -313,70 +315,7 @@ class DonobuFlowsManager {
|
|
|
313
315
|
* Get flows metadata across multiple persistence layers with pagination and filtering.
|
|
314
316
|
*/
|
|
315
317
|
async getFlows(query) {
|
|
316
|
-
|
|
317
|
-
const paginationState = parseCompositePageToken(query.pageToken);
|
|
318
|
-
const requestedLimit = Math.min(Math.max(1, query.limit || 100), 100);
|
|
319
|
-
// Results container.
|
|
320
|
-
const combinedResults = [];
|
|
321
|
-
// Get all persistence layers.
|
|
322
|
-
const persistenceLayers = await this.flowsPersistenceFactory.createPersistenceLayers();
|
|
323
|
-
// Query each persistence layer with its own pagination.
|
|
324
|
-
for (let i = 0; i < persistenceLayers.length; i++) {
|
|
325
|
-
// Skip layers we've already exhausted.
|
|
326
|
-
if (paginationState.exhaustedSources.includes(i)) {
|
|
327
|
-
continue;
|
|
328
|
-
}
|
|
329
|
-
// Calculate per-source limit - we need more than requested to merge
|
|
330
|
-
// properly.
|
|
331
|
-
//
|
|
332
|
-
// Double the limit to ensure we have enough data for sorting/merging.
|
|
333
|
-
const sourceLimit = Math.min(requestedLimit * 2, 100);
|
|
334
|
-
// Create a source-specific query, preserving all filter params
|
|
335
|
-
const sourceQuery = {
|
|
336
|
-
...query,
|
|
337
|
-
limit: sourceLimit,
|
|
338
|
-
pageToken: paginationState.sourceTokens[i],
|
|
339
|
-
};
|
|
340
|
-
const sourceResult = await persistenceLayers[i].getFlowsMetadata(sourceQuery);
|
|
341
|
-
// Wrap each item with its source index.
|
|
342
|
-
const itemsWithSource = sourceResult.items.map((flow) => ({
|
|
343
|
-
flow,
|
|
344
|
-
sourceIndex: i,
|
|
345
|
-
}));
|
|
346
|
-
// Add to combined results.
|
|
347
|
-
combinedResults.push(...itemsWithSource);
|
|
348
|
-
// Update pagination state.
|
|
349
|
-
if (sourceResult.nextPageToken) {
|
|
350
|
-
paginationState.sourceTokens[i] = sourceResult.nextPageToken;
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
// Mark this source as exhausted.
|
|
354
|
-
paginationState.exhaustedSources.push(i);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
// Sort all results by creation date (newest first).
|
|
358
|
-
combinedResults.sort((a, b) => {
|
|
359
|
-
return (b.flow.startedAt || 0) - (a.flow.startedAt || 0);
|
|
360
|
-
});
|
|
361
|
-
// Take only the requested limit.
|
|
362
|
-
const limitedResults = combinedResults.slice(0, requestedLimit);
|
|
363
|
-
// Get the last timestamp for cursor-based continuation.
|
|
364
|
-
const lastTimestamp = limitedResults.length > 0
|
|
365
|
-
? limitedResults[limitedResults.length - 1].flow.startedAt
|
|
366
|
-
: null;
|
|
367
|
-
// Update the cursor timestamp in pagination state.
|
|
368
|
-
paginationState.cursorTimestamp = lastTimestamp;
|
|
369
|
-
// Are there more results?
|
|
370
|
-
const hasMore = combinedResults.length > requestedLimit ||
|
|
371
|
-
paginationState.exhaustedSources.length < persistenceLayers.length;
|
|
372
|
-
// Extract just the flow metadata objects for return.
|
|
373
|
-
const cleanResults = limitedResults.map((item) => item.flow);
|
|
374
|
-
return {
|
|
375
|
-
items: cleanResults,
|
|
376
|
-
nextPageToken: hasMore
|
|
377
|
-
? createCompositePageToken(paginationState)
|
|
378
|
-
: undefined,
|
|
379
|
-
};
|
|
318
|
+
return this.flowCatalog.getFlows(query);
|
|
380
319
|
}
|
|
381
320
|
/**
|
|
382
321
|
* Returns the metadata for the given flow by ID. If the flow is active, the
|
|
@@ -385,60 +324,17 @@ class DonobuFlowsManager {
|
|
|
385
324
|
* not active, a copy of the persisted metadata is returned.
|
|
386
325
|
*/
|
|
387
326
|
async getFlowById(flowId) {
|
|
388
|
-
|
|
389
|
-
? this.activeFlows.get(flowId)
|
|
390
|
-
: null;
|
|
391
|
-
if (activeFlowHandle) {
|
|
392
|
-
return activeFlowHandle.donobuFlow.metadata;
|
|
393
|
-
}
|
|
394
|
-
for (const persistence of await this.flowsPersistenceFactory.createPersistenceLayers()) {
|
|
395
|
-
try {
|
|
396
|
-
return await persistence.getFlowMetadataById(flowId);
|
|
397
|
-
}
|
|
398
|
-
catch (error) {
|
|
399
|
-
if (!(error instanceof FlowNotFoundException_1.FlowNotFoundException)) {
|
|
400
|
-
throw error;
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
throw FlowNotFoundException_1.FlowNotFoundException.forId(flowId);
|
|
327
|
+
return this.flowCatalog.getFlowById(flowId);
|
|
405
328
|
}
|
|
406
329
|
/**
|
|
407
330
|
* Returns the metadata for the given flow by name.
|
|
408
331
|
*/
|
|
409
332
|
async getFlowByName(flowName) {
|
|
410
|
-
|
|
411
|
-
try {
|
|
412
|
-
return await persistence.getFlowMetadataByName(flowName);
|
|
413
|
-
}
|
|
414
|
-
catch (error) {
|
|
415
|
-
if (!(error instanceof FlowNotFoundException_1.FlowNotFoundException)) {
|
|
416
|
-
throw error;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
throw FlowNotFoundException_1.FlowNotFoundException.forName(flowName);
|
|
333
|
+
return this.flowCatalog.getFlowByName(flowName);
|
|
421
334
|
}
|
|
422
335
|
/** Returns all the tool calls made by the given flow by ID. */
|
|
423
336
|
async getToolCalls(flowId) {
|
|
424
|
-
|
|
425
|
-
? this.activeFlows.get(flowId)
|
|
426
|
-
: null;
|
|
427
|
-
if (activeFlowHandle) {
|
|
428
|
-
return [...activeFlowHandle.donobuFlow.invokedToolCalls].sort((a, b) => new Date(a.startedAt).getTime() - new Date(b.startedAt).getTime());
|
|
429
|
-
}
|
|
430
|
-
const persistenceLayers = await this.flowsPersistenceFactory.createPersistenceLayers();
|
|
431
|
-
for (const persistence of persistenceLayers) {
|
|
432
|
-
try {
|
|
433
|
-
return await persistence.getToolCalls(flowId);
|
|
434
|
-
}
|
|
435
|
-
catch (error) {
|
|
436
|
-
if (!(error instanceof FlowNotFoundException_1.FlowNotFoundException)) {
|
|
437
|
-
throw error;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
throw FlowNotFoundException_1.FlowNotFoundException.forId(flowId);
|
|
337
|
+
return this.flowCatalog.getToolCalls(flowId);
|
|
442
338
|
}
|
|
443
339
|
/**
|
|
444
340
|
* Attempts to delete a flow by ID. If the flow is active, then
|
|
@@ -447,14 +343,12 @@ class DonobuFlowsManager {
|
|
|
447
343
|
*/
|
|
448
344
|
async deleteFlowById(flowId) {
|
|
449
345
|
const activeFlow = this.isLocallyRunning()
|
|
450
|
-
? this.
|
|
346
|
+
? this.flowRuntime.get(flowId)
|
|
451
347
|
: null;
|
|
452
348
|
if (activeFlow) {
|
|
453
349
|
throw new CannotDeleteRunningFlowException_1.CannotDeleteRunningFlowException(flowId);
|
|
454
350
|
}
|
|
455
|
-
|
|
456
|
-
await persistence.deleteFlow(flowId);
|
|
457
|
-
}
|
|
351
|
+
await this.flowCatalog.deleteFlow(flowId);
|
|
458
352
|
}
|
|
459
353
|
/**
|
|
460
354
|
* Attempts to cancel a flow by ID. If the flow is active, the flow is ended
|
|
@@ -463,7 +357,7 @@ class DonobuFlowsManager {
|
|
|
463
357
|
*/
|
|
464
358
|
async cancelFlow(flowId) {
|
|
465
359
|
const activeFlowHandle = this.isLocallyRunning()
|
|
466
|
-
? this.
|
|
360
|
+
? this.flowRuntime.get(flowId)
|
|
467
361
|
: null;
|
|
468
362
|
if (activeFlowHandle) {
|
|
469
363
|
activeFlowHandle.donobuFlow.metadata.nextState = 'FAILED';
|
|
@@ -499,7 +393,7 @@ class DonobuFlowsManager {
|
|
|
499
393
|
*/
|
|
500
394
|
async getFlowsAsPlaywrightProject(flowIds, options) {
|
|
501
395
|
// First, resolve the complete set of flows including all dependencies
|
|
502
|
-
const completeFlowIds = await this.resolveFlowDependencies(flowIds);
|
|
396
|
+
const completeFlowIds = await this.flowDependencyResolver.resolveFlowDependencies(flowIds);
|
|
503
397
|
// Fetch all flows and their tool calls
|
|
504
398
|
const flowsWithToolCalls = await Promise.all(completeFlowIds.map(async (flowId) => {
|
|
505
399
|
const metadata = await this.getFlowById(flowId);
|
|
@@ -525,12 +419,13 @@ class DonobuFlowsManager {
|
|
|
525
419
|
return await (0, CodeGenerator_1.generateProject)(flowsWithToolCalls, defaultGptConfig, options);
|
|
526
420
|
}
|
|
527
421
|
/**
|
|
528
|
-
*
|
|
529
|
-
*
|
|
530
|
-
*
|
|
531
|
-
*
|
|
422
|
+
* Resolves a GPT client using the provided GPT configuration name, falling back
|
|
423
|
+
* to environment-provided configs (BASE64_GPT_CONFIG, DONOBU_API_KEY,
|
|
424
|
+
* AWS_BEDROCK_MODEL_NAME, ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY,
|
|
425
|
+
* OPENAI_API_KEY) and finally the config bound to the 'flow-runner' agent.
|
|
426
|
+
* Returns a null client if no configuration source is available.
|
|
532
427
|
*
|
|
533
|
-
*
|
|
428
|
+
* Public for testing only.
|
|
534
429
|
**/
|
|
535
430
|
async createGptClient(gptConfigName) {
|
|
536
431
|
if (gptConfigName) {
|
|
@@ -544,9 +439,14 @@ class DonobuFlowsManager {
|
|
|
544
439
|
};
|
|
545
440
|
}
|
|
546
441
|
catch (_error) {
|
|
547
|
-
Logger_1.appLogger.warn(`Failed to find GPT configuration: ${gptConfigName}, will default to the 'flow-runner' agent config (if it exists).`);
|
|
442
|
+
Logger_1.appLogger.warn(`Failed to find GPT configuration: ${gptConfigName}, will default to a GPT configuration set via environment variables, or the 'flow-runner' agent config (if it exists).`);
|
|
548
443
|
}
|
|
549
444
|
}
|
|
445
|
+
const envModelDefaults = {
|
|
446
|
+
anthropic: this.environ.data.ANTHROPIC_MODEL_NAME || 'claude-sonnet-4-5',
|
|
447
|
+
googleGemini: this.environ.data.GOOGLE_GENERATIVE_AI_MODEL_NAME || 'gemini-2.5-flash',
|
|
448
|
+
openAi: this.environ.data.OPENAI_API_MODEL_NAME || 'gpt-5.1',
|
|
449
|
+
};
|
|
550
450
|
let gptConfigFromEnv = null;
|
|
551
451
|
if (this.environ.data.BASE64_GPT_CONFIG) {
|
|
552
452
|
let json;
|
|
@@ -569,35 +469,28 @@ class DonobuFlowsManager {
|
|
|
569
469
|
gptConfigFromEnv = {
|
|
570
470
|
type: 'ANTHROPIC_AWS_BEDROCK',
|
|
571
471
|
modelName: this.environ.data.AWS_BEDROCK_MODEL_NAME,
|
|
472
|
+
accessKeyId: this.environ.data.AWS_ACCESS_KEY_ID,
|
|
473
|
+
secretAccessKey: this.environ.data.AWS_SECRET_ACCESS_KEY,
|
|
572
474
|
};
|
|
573
475
|
}
|
|
574
|
-
else if (this.environ.data.
|
|
575
|
-
if (!this.environ.meta.ANTHROPIC_API_KEY) {
|
|
576
|
-
throw new InvalidParamValueException_1.InvalidParamValueException(this.environ.keys.ANTHROPIC_API_KEY, undefined, `the ${this.environ.keys.ANTHROPIC_MODEL_NAME} environment variable is set but the ${this.environ.keys.ANTHROPIC_API_KEY} is not`);
|
|
577
|
-
}
|
|
476
|
+
else if (this.environ.data.ANTHROPIC_API_KEY) {
|
|
578
477
|
gptConfigFromEnv = {
|
|
579
478
|
type: 'ANTHROPIC',
|
|
580
|
-
modelName:
|
|
479
|
+
modelName: envModelDefaults.anthropic,
|
|
581
480
|
apiKey: this.environ.data.ANTHROPIC_API_KEY,
|
|
582
481
|
};
|
|
583
482
|
}
|
|
584
|
-
else if (this.environ.data.
|
|
585
|
-
if (!this.environ.data.GOOGLE_GENERATIVE_AI_API_KEY) {
|
|
586
|
-
throw new InvalidParamValueException_1.InvalidParamValueException(this.environ.keys.GOOGLE_GENERATIVE_AI_API_KEY, undefined, `the ${this.environ.keys.GOOGLE_GENERATIVE_AI_MODEL_NAME} environment variable is set but the ${this.environ.keys.GOOGLE_GENERATIVE_AI_API_KEY} is not`);
|
|
587
|
-
}
|
|
483
|
+
else if (this.environ.data.GOOGLE_GENERATIVE_AI_API_KEY) {
|
|
588
484
|
gptConfigFromEnv = {
|
|
589
485
|
type: 'GOOGLE_GEMINI',
|
|
590
|
-
modelName:
|
|
486
|
+
modelName: envModelDefaults.googleGemini,
|
|
591
487
|
apiKey: this.environ.data.GOOGLE_GENERATIVE_AI_API_KEY,
|
|
592
488
|
};
|
|
593
489
|
}
|
|
594
|
-
else if (this.environ.data.
|
|
595
|
-
if (!this.environ.data.OPENAI_API_KEY) {
|
|
596
|
-
throw new InvalidParamValueException_1.InvalidParamValueException(this.environ.keys.OPENAI_API_KEY, undefined, `the ${this.environ.keys.OPENAI_API_MODEL_NAME} environment variable is set but the ${this.environ.keys.OPENAI_API_KEY} is not`);
|
|
597
|
-
}
|
|
490
|
+
else if (this.environ.data.OPENAI_API_KEY) {
|
|
598
491
|
gptConfigFromEnv = {
|
|
599
492
|
type: 'OPENAI',
|
|
600
|
-
modelName:
|
|
493
|
+
modelName: envModelDefaults.openAi,
|
|
601
494
|
apiKey: this.environ.data.OPENAI_API_KEY,
|
|
602
495
|
};
|
|
603
496
|
}
|
|
@@ -643,147 +536,12 @@ class DonobuFlowsManager {
|
|
|
643
536
|
default:
|
|
644
537
|
throw new InvalidParamValueException_1.InvalidParamValueException('type', browserStateRef.type);
|
|
645
538
|
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
if (browserState) {
|
|
650
|
-
return browserState;
|
|
651
|
-
}
|
|
652
|
-
else {
|
|
653
|
-
throw new BrowserStateNotFoundException_1.BrowserStateNotFoundException(flowMetadata.id);
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
catch (error) {
|
|
657
|
-
if (!(error instanceof FlowNotFoundException_1.FlowNotFoundException)) {
|
|
658
|
-
throw error;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
539
|
+
const browserState = await this.flowCatalog.getBrowserState(flowMetadata.id);
|
|
540
|
+
if (browserState) {
|
|
541
|
+
return browserState;
|
|
661
542
|
}
|
|
662
543
|
throw new BrowserStateNotFoundException_1.BrowserStateNotFoundException(flowMetadata.id);
|
|
663
544
|
}
|
|
664
|
-
/**
|
|
665
|
-
* Creates a dictionary of environment variables from allowed variable names.
|
|
666
|
-
*
|
|
667
|
-
* This method retrieves environment variable values for each of the provided names
|
|
668
|
-
* from the environment data manager. Only environment variables that exist in
|
|
669
|
-
* the environment data manager will be included in the result.
|
|
670
|
-
*
|
|
671
|
-
* @param allowedEnvVarsByName - Array of environment variable names that are allowed to be accessed.
|
|
672
|
-
* @returns A record mapping environment variable names to their values.
|
|
673
|
-
*
|
|
674
|
-
* @example
|
|
675
|
-
* // Returns { "API_KEY": "abc123", "BASE_URL": "https://example.com" }
|
|
676
|
-
* await buildEnvData(["API_KEY", "BASE_URL", "MISSING_VAR"]);
|
|
677
|
-
*/
|
|
678
|
-
async buildEnvData(allowedEnvVarsByName) {
|
|
679
|
-
const result = {};
|
|
680
|
-
for (const envVarName of allowedEnvVarsByName) {
|
|
681
|
-
const envVarValue = await this.envDataManager.getEnvironmentDatum(envVarName);
|
|
682
|
-
if (envVarValue) {
|
|
683
|
-
result[envVarName] = envVarValue;
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
return result;
|
|
687
|
-
}
|
|
688
|
-
/**
|
|
689
|
-
* Extracts dependencies for a single flow by analyzing its browser.initialState
|
|
690
|
-
*/
|
|
691
|
-
async extractFlowDependencies(flow, nameToIdMap) {
|
|
692
|
-
const initialState = flow.browser?.initialState;
|
|
693
|
-
if (!initialState) {
|
|
694
|
-
return [];
|
|
695
|
-
}
|
|
696
|
-
switch (initialState.type) {
|
|
697
|
-
case 'id':
|
|
698
|
-
// Direct flow ID reference
|
|
699
|
-
try {
|
|
700
|
-
await this.getFlowById(initialState.value);
|
|
701
|
-
return [initialState.value];
|
|
702
|
-
}
|
|
703
|
-
catch (_error) {
|
|
704
|
-
Logger_1.appLogger.warn(`Flow dependency not found: flow with ID "${initialState.value}" does not exist`);
|
|
705
|
-
return [];
|
|
706
|
-
}
|
|
707
|
-
case 'name':
|
|
708
|
-
// Flow name reference - resolve to ID
|
|
709
|
-
const flowId = nameToIdMap.get(initialState.value);
|
|
710
|
-
if (flowId) {
|
|
711
|
-
return [flowId];
|
|
712
|
-
}
|
|
713
|
-
// If not in our current map, try to find it by querying all flows
|
|
714
|
-
try {
|
|
715
|
-
const dependentFlow = await this.getFlowByName(initialState.value);
|
|
716
|
-
nameToIdMap.set(initialState.value, dependentFlow.id);
|
|
717
|
-
return [dependentFlow.id];
|
|
718
|
-
}
|
|
719
|
-
catch (_error) {
|
|
720
|
-
Logger_1.appLogger.warn(`Flow dependency not found: flow with name "${initialState.value}" does not exist`);
|
|
721
|
-
return [];
|
|
722
|
-
}
|
|
723
|
-
case 'json':
|
|
724
|
-
// Direct JSON state - no dependencies
|
|
725
|
-
return [];
|
|
726
|
-
default:
|
|
727
|
-
Logger_1.appLogger.warn(`Unknown browser state reference type: ${initialState.type}`);
|
|
728
|
-
return [];
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
/**
|
|
732
|
-
* Resolves the complete set of flow IDs including all transitive dependencies.
|
|
733
|
-
* Uses breadth-first search to discover all dependencies recursively.
|
|
734
|
-
*/
|
|
735
|
-
async resolveFlowDependencies(initialFlowIds) {
|
|
736
|
-
const resolvedFlowIds = new Set();
|
|
737
|
-
const flowsToProcess = [...initialFlowIds];
|
|
738
|
-
const nameToIdMap = new Map();
|
|
739
|
-
// Process flows in breadth-first order to discover all dependencies
|
|
740
|
-
while (flowsToProcess.length > 0) {
|
|
741
|
-
const currentFlowId = flowsToProcess.shift();
|
|
742
|
-
// Skip if we've already processed this flow
|
|
743
|
-
if (resolvedFlowIds.has(currentFlowId)) {
|
|
744
|
-
continue;
|
|
745
|
-
}
|
|
746
|
-
try {
|
|
747
|
-
const flowMetadata = await this.getFlowById(currentFlowId);
|
|
748
|
-
resolvedFlowIds.add(currentFlowId);
|
|
749
|
-
// Update name-to-ID mapping for dependency resolution
|
|
750
|
-
if (flowMetadata.name) {
|
|
751
|
-
const existingFlowId = nameToIdMap.get(flowMetadata.name);
|
|
752
|
-
if (!existingFlowId ||
|
|
753
|
-
(await this.shouldReplaceFlowMapping(existingFlowId, currentFlowId))) {
|
|
754
|
-
nameToIdMap.set(flowMetadata.name, currentFlowId);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
// Extract dependencies from browser state
|
|
758
|
-
const dependencies = await this.extractFlowDependencies(flowMetadata, nameToIdMap);
|
|
759
|
-
// Add discovered dependencies to the processing queue
|
|
760
|
-
dependencies.forEach((depId) => {
|
|
761
|
-
if (!resolvedFlowIds.has(depId)) {
|
|
762
|
-
flowsToProcess.push(depId);
|
|
763
|
-
}
|
|
764
|
-
});
|
|
765
|
-
}
|
|
766
|
-
catch (_error) {
|
|
767
|
-
// If a flow doesn't exist, skip it but continue processing
|
|
768
|
-
Logger_1.appLogger.warn(`Flow ${currentFlowId} not found, skipping dependency resolution for this flow`);
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
return Array.from(resolvedFlowIds);
|
|
772
|
-
}
|
|
773
|
-
/**
|
|
774
|
-
* Determines if a new flow ID should replace an existing flow ID in the name mapping.
|
|
775
|
-
*/
|
|
776
|
-
async shouldReplaceFlowMapping(existingFlowId, newFlowId) {
|
|
777
|
-
try {
|
|
778
|
-
const existingFlow = await this.getFlowById(existingFlowId);
|
|
779
|
-
const newFlow = await this.getFlowById(newFlowId);
|
|
780
|
-
return FlowDependencyAnalyzer_1.FlowDependencyAnalyzer.shouldReplaceFlow(existingFlow, newFlow);
|
|
781
|
-
}
|
|
782
|
-
catch (_error) {
|
|
783
|
-
// If we can't get one of the flows, prefer the new one
|
|
784
|
-
return true;
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
545
|
isLocallyRunning() {
|
|
788
546
|
return this.deploymentEnvironment === 'LOCAL';
|
|
789
547
|
}
|
|
@@ -879,12 +637,6 @@ function parseUrl(url) {
|
|
|
879
637
|
return null;
|
|
880
638
|
}
|
|
881
639
|
}
|
|
882
|
-
/**
|
|
883
|
-
* Create a composite page token from pagination state
|
|
884
|
-
*/
|
|
885
|
-
function createCompositePageToken(state) {
|
|
886
|
-
return Buffer.from(JSON.stringify(state)).toString('base64');
|
|
887
|
-
}
|
|
888
640
|
function validateFlowName(flowName) {
|
|
889
641
|
if (flowName && flowName.length > 255) {
|
|
890
642
|
throw new InvalidParamValueException_1.InvalidParamValueException('name', flowName, 'the value cannot be longer than 255 characters');
|
|
@@ -1040,29 +792,6 @@ async function throwIfAnyToolsRequireGpt(requestedTools, toolCallsOnStart) {
|
|
|
1040
792
|
throw new ToolRequiresGptException_1.ToolRequiresGptException(toolCallsRequiringGpt[0].name);
|
|
1041
793
|
}
|
|
1042
794
|
}
|
|
1043
|
-
/**
|
|
1044
|
-
* Parse a composite page token into pagination state
|
|
1045
|
-
*/
|
|
1046
|
-
function parseCompositePageToken(token) {
|
|
1047
|
-
if (!token) {
|
|
1048
|
-
return {
|
|
1049
|
-
sourceTokens: {},
|
|
1050
|
-
exhaustedSources: [],
|
|
1051
|
-
cursorTimestamp: null,
|
|
1052
|
-
};
|
|
1053
|
-
}
|
|
1054
|
-
try {
|
|
1055
|
-
return JSON.parse(Buffer.from(token, 'base64').toString('utf8'));
|
|
1056
|
-
}
|
|
1057
|
-
catch (_error) {
|
|
1058
|
-
// If token parsing fails, start fresh
|
|
1059
|
-
return {
|
|
1060
|
-
sourceTokens: {},
|
|
1061
|
-
exhaustedSources: [],
|
|
1062
|
-
cursorTimestamp: null,
|
|
1063
|
-
};
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
795
|
/**
|
|
1067
796
|
* Convert an *executed* list of {@link ToolCall}s into a list of
|
|
1068
797
|
* {@link ProposedToolCall}s that can be replayed in a fresh browser
|