donobu 5.25.5 → 5.26.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/esm/lib/ai/PageAi.d.ts +1 -0
- package/dist/esm/lib/ai/PageAi.js +2 -1
- package/dist/esm/main.d.ts +1 -1
- package/dist/esm/main.js +2 -1
- package/dist/esm/managers/DonobuFlowsManager.d.ts +11 -23
- package/dist/esm/managers/DonobuFlowsManager.js +29 -67
- package/dist/esm/targets/TargetRuntimePlugin.d.ts +0 -10
- package/dist/esm/targets/WebTargetRuntime.js +0 -43
- package/dist/esm/tools/ReplayableInteraction.d.ts +1 -1
- package/dist/esm/tools/ReplayableInteraction.js +1 -1
- package/dist/esm/tools/Tool.d.ts +14 -0
- package/dist/esm/tools/Tool.js +16 -0
- package/dist/lib/ai/PageAi.d.ts +1 -0
- package/dist/lib/ai/PageAi.js +2 -1
- package/dist/main.d.ts +1 -1
- package/dist/main.js +2 -1
- package/dist/managers/DonobuFlowsManager.d.ts +11 -23
- package/dist/managers/DonobuFlowsManager.js +29 -67
- package/dist/targets/TargetRuntimePlugin.d.ts +0 -10
- package/dist/targets/WebTargetRuntime.js +0 -43
- package/dist/tools/ReplayableInteraction.d.ts +1 -1
- package/dist/tools/ReplayableInteraction.js +1 -1
- package/dist/tools/Tool.d.ts +14 -0
- package/dist/tools/Tool.js +16 -0
- package/package.json +1 -1
|
@@ -139,6 +139,7 @@ export declare class PageAiRunner {
|
|
|
139
139
|
export declare class PageAi {
|
|
140
140
|
private readonly cache;
|
|
141
141
|
private readonly runner;
|
|
142
|
+
private readonly donobu;
|
|
142
143
|
/**
|
|
143
144
|
* @param donobu Donobu stack providing flow managers and shared services.
|
|
144
145
|
* @param gptClient GPT client used for autonomous reasoning.
|
|
@@ -133,6 +133,7 @@ class PageAi {
|
|
|
133
133
|
*/
|
|
134
134
|
constructor(donobu, gptClient, cache) {
|
|
135
135
|
this.cache = cache;
|
|
136
|
+
this.donobu = donobu;
|
|
136
137
|
this.runner = new PageAiRunner(donobu, gptClient);
|
|
137
138
|
}
|
|
138
139
|
/**
|
|
@@ -188,7 +189,7 @@ class PageAi {
|
|
|
188
189
|
}), {
|
|
189
190
|
areElementIdsVolatile: options?.volatileElementIds,
|
|
190
191
|
disableSelectorFailover: options?.noSelectorFailover,
|
|
191
|
-
});
|
|
192
|
+
}, this.donobu.toolRegistry);
|
|
192
193
|
const cacheEntry = cacheEntryBuilder_1.PageAiCacheEntryBuilder.fromMetadata(descriptor.key.pageUrl, runResult.donobuFlow.metadata, preparedToolCalls);
|
|
193
194
|
await this.cache.put(cacheEntry);
|
|
194
195
|
}
|
package/dist/esm/main.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export * from './lib/test/fixtures/gptClients';
|
|
|
22
22
|
export * from './lib/test/testExtension';
|
|
23
23
|
export * from './lib/test/utils/donobuTestStack';
|
|
24
24
|
export { DonobuFlow } from './managers/DonobuFlow';
|
|
25
|
-
export { distillAllowedEnvVariableNames, DonobuFlowsManager, } from './managers/DonobuFlowsManager';
|
|
25
|
+
export { distillAllowedEnvVariableNames, DonobuFlowsManager, prepareToolCallsForRerun, } from './managers/DonobuFlowsManager';
|
|
26
26
|
export { type DonobuStack, setupDonobuStack } from './managers/DonobuStack';
|
|
27
27
|
export { InteractionVisualizer } from './managers/InteractionVisualizer';
|
|
28
28
|
export { type LoadedPlugins, type PluginDependencies, PluginLoader, } from './managers/PluginLoader';
|
package/dist/esm/main.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.TargetRuntimePluginRegistry = exports.PersistencePluginRegistry = exports.createDefaultToolRegistry = exports.ToolManager = exports.PluginLoader = exports.InteractionVisualizer = exports.setupDonobuStack = exports.DonobuFlowsManager = exports.distillAllowedEnvVariableNames = exports.DonobuFlow = exports.env = exports.runGenerateSiteTests = exports.VercelAiGptClient = exports.OpenAiGptClient = exports.GptClientPluginRegistry = exports.GptClient = exports.GoogleGenerativeAiGptClient = exports.fixAssertFields = exports.DonobuGptClient = exports.AnthropicGptClient = void 0;
|
|
17
|
+
exports.TargetRuntimePluginRegistry = exports.PersistencePluginRegistry = exports.createDefaultToolRegistry = exports.ToolManager = exports.PluginLoader = exports.InteractionVisualizer = exports.setupDonobuStack = exports.prepareToolCallsForRerun = exports.DonobuFlowsManager = exports.distillAllowedEnvVariableNames = exports.DonobuFlow = exports.env = exports.runGenerateSiteTests = exports.VercelAiGptClient = exports.OpenAiGptClient = exports.GptClientPluginRegistry = exports.GptClient = exports.GoogleGenerativeAiGptClient = exports.fixAssertFields = exports.DonobuGptClient = exports.AnthropicGptClient = void 0;
|
|
18
18
|
exports.startDonobuServer = startDonobuServer;
|
|
19
19
|
const commander_1 = require("commander");
|
|
20
20
|
const v4_1 = require("zod/v4");
|
|
@@ -61,6 +61,7 @@ Object.defineProperty(exports, "DonobuFlow", { enumerable: true, get: function (
|
|
|
61
61
|
var DonobuFlowsManager_1 = require("./managers/DonobuFlowsManager");
|
|
62
62
|
Object.defineProperty(exports, "distillAllowedEnvVariableNames", { enumerable: true, get: function () { return DonobuFlowsManager_1.distillAllowedEnvVariableNames; } });
|
|
63
63
|
Object.defineProperty(exports, "DonobuFlowsManager", { enumerable: true, get: function () { return DonobuFlowsManager_1.DonobuFlowsManager; } });
|
|
64
|
+
Object.defineProperty(exports, "prepareToolCallsForRerun", { enumerable: true, get: function () { return DonobuFlowsManager_1.prepareToolCallsForRerun; } });
|
|
64
65
|
var DonobuStack_1 = require("./managers/DonobuStack");
|
|
65
66
|
Object.defineProperty(exports, "setupDonobuStack", { enumerable: true, get: function () { return DonobuStack_1.setupDonobuStack; } });
|
|
66
67
|
var InteractionVisualizer_1 = require("./managers/InteractionVisualizer");
|
|
@@ -209,32 +209,20 @@ export declare function distillAllowedEnvVariableNames(overallObjective: string
|
|
|
209
209
|
export declare function setupAllowedTools(flowParams: Pick<CreateDonobuFlow, 'customTools' | 'toolCallsOnStart' | 'allowedTools'>, hasGptClient: boolean, targetType: string, toolRegistry: ToolRegistry): Promise<Tool<z.ZodObject, z.ZodObject>[]>;
|
|
210
210
|
/**
|
|
211
211
|
* Convert an *executed* list of {@link ToolCall}s into a list of
|
|
212
|
-
* {@link ProposedToolCall}s that can be replayed in a fresh
|
|
213
|
-
* session.
|
|
212
|
+
* {@link ProposedToolCall}s that can be replayed in a fresh session.
|
|
214
213
|
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
* 2. **Attempt remap with {@link ReplayableInteraction.prepareToolCallForRerun}.**
|
|
221
|
-
* If a call belongs to that set, we delegate to
|
|
222
|
-
* `ReplayableInteraction.remapForRerun` to inject the stored selector and
|
|
223
|
-
* strip any transient GPT-only fields.
|
|
224
|
-
* 3. **Pass through other calls unchanged.**
|
|
225
|
-
* Tools that have no UI footprint (e.g. navigation helpers, assertions)
|
|
226
|
-
* are copied verbatim.
|
|
227
|
-
* 4. **Error handling.**
|
|
228
|
-
* When remapping fails (e.g. selector metadata missing) we *skip* the
|
|
229
|
-
* offending call, emit a warning via `appLogger`, and continue processing
|
|
230
|
-
* the remainder so that a “best-effort” replay is still possible.
|
|
214
|
+
* For each call, we look up the {@link Tool} in the given registry and
|
|
215
|
+
* delegate to its `prepareForRerun` override. Tools that need selector
|
|
216
|
+
* remapping (e.g. {@link ClickTool}, {@link InputTextTool}, the mobile
|
|
217
|
+
* interaction tools) each own their own logic; tools with no replay-
|
|
218
|
+
* specific needs inherit the passthrough default from {@link Tool}.
|
|
231
219
|
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
220
|
+
* When a tool is not registered (stale flow, removed tool) or
|
|
221
|
+
* `prepareForRerun` throws (e.g. missing selector metadata), the call
|
|
222
|
+
* is passed through or skipped with an `appLogger.warn` — "best-effort
|
|
223
|
+
* replay" behavior is preserved.
|
|
234
224
|
*
|
|
235
|
-
* @param toolCalls – The chronologically ordered list of executed
|
|
236
|
-
* {@link ToolCall}s.
|
|
237
225
|
* @returns A list of {@link ProposedToolCall}s ready for replay.
|
|
238
226
|
*/
|
|
239
|
-
export declare function prepareToolCallsForRerun(toolCalls: ToolCall[], options: CodeGenerationOptions): Promise<ProposedToolCall[]>;
|
|
227
|
+
export declare function prepareToolCallsForRerun(toolCalls: ToolCall[], options: CodeGenerationOptions, toolRegistry: ToolRegistry): Promise<ProposedToolCall[]>;
|
|
240
228
|
//# sourceMappingURL=DonobuFlowsManager.d.ts.map
|
|
@@ -51,18 +51,7 @@ const ToolRequiresGptException_1 = require("../exceptions/ToolRequiresGptExcepti
|
|
|
51
51
|
const UnknownToolException_1 = require("../exceptions/UnknownToolException");
|
|
52
52
|
const GptConfig_1 = require("../models/GptConfig");
|
|
53
53
|
const resolveTargetRuntime_1 = require("../targets/resolveTargetRuntime");
|
|
54
|
-
const ChooseSelectOptionTool_1 = require("../tools/ChooseSelectOptionTool");
|
|
55
|
-
const ClickTool_1 = require("../tools/ClickTool");
|
|
56
54
|
const CustomToolRunnerTool_1 = require("../tools/CustomToolRunnerTool");
|
|
57
|
-
const DoubleClickTool_1 = require("../tools/DoubleClickTool");
|
|
58
|
-
const HoverOverElementTool_1 = require("../tools/HoverOverElementTool");
|
|
59
|
-
const InputFakerTool_1 = require("../tools/InputFakerTool");
|
|
60
|
-
const InputRandomizedEmailAddressTool_1 = require("../tools/InputRandomizedEmailAddressTool");
|
|
61
|
-
const InputTextTool_1 = require("../tools/InputTextTool");
|
|
62
|
-
const PressKeyTool_1 = require("../tools/PressKeyTool");
|
|
63
|
-
const RememberPageTextTool_1 = require("../tools/RememberPageTextTool");
|
|
64
|
-
const ReplayableInteraction_1 = require("../tools/ReplayableInteraction");
|
|
65
|
-
const ScrollPageTool_1 = require("../tools/ScrollPageTool");
|
|
66
55
|
const FlowLogBuffer_1 = require("../utils/FlowLogBuffer");
|
|
67
56
|
const Logger_1 = require("../utils/Logger");
|
|
68
57
|
const MiscUtils_1 = require("../utils/MiscUtils");
|
|
@@ -291,11 +280,9 @@ class DonobuFlowsManager {
|
|
|
291
280
|
async getToolCallsForRerun(priorFlowMetadata, options) {
|
|
292
281
|
const originalToolCalls = await this.getToolCalls(priorFlowMetadata.id);
|
|
293
282
|
// Delegate tool call preparation to the target runtime plugin so that
|
|
294
|
-
// rerun logic is fully target-agnostic
|
|
295
|
-
|
|
296
|
-
return
|
|
297
|
-
? await plugin.prepareToolCallsForRerun(originalToolCalls, options)
|
|
298
|
-
: await prepareToolCallsForRerun(originalToolCalls, options);
|
|
283
|
+
// rerun logic is fully target-agnostic — it dispatches per tool via
|
|
284
|
+
// the tool's own `prepareForRerun` override.
|
|
285
|
+
return prepareToolCallsForRerun(originalToolCalls, options, this.toolRegistry);
|
|
299
286
|
}
|
|
300
287
|
/**
|
|
301
288
|
* Loads the given flow by ID and returns a `CreateDonobuFlow` object that can be passed to `createFlow`
|
|
@@ -460,7 +447,7 @@ class DonobuFlowsManager {
|
|
|
460
447
|
const flowMetadata = await this.getFlowById(flowId);
|
|
461
448
|
// Do not generate code for non-successful tool calls.
|
|
462
449
|
const originalToolCalls = (await this.getToolCalls(flowId)).filter((tc) => tc.outcome?.isSuccessful);
|
|
463
|
-
const proposedToolCalls = await prepareToolCallsForRerun(originalToolCalls, effectiveOptions);
|
|
450
|
+
const proposedToolCalls = await prepareToolCallsForRerun(originalToolCalls, effectiveOptions, this.toolRegistry);
|
|
464
451
|
const scriptVariant = effectiveOptions.playwrightScriptVariant === 'classic' ? 'classic' : 'ai';
|
|
465
452
|
if (scriptVariant === 'classic') {
|
|
466
453
|
return (0, CodeGenerator_1.getFlowAsPlaywrightScript)(flowMetadata, proposedToolCalls, effectiveOptions, this.toolRegistry);
|
|
@@ -478,9 +465,9 @@ class DonobuFlowsManager {
|
|
|
478
465
|
const flowsWithToolCalls = await Promise.all(flowIds.map(async (flowId) => {
|
|
479
466
|
const metadata = await this.getFlowById(flowId);
|
|
480
467
|
const toolCalls = await this.getToolCalls(flowId);
|
|
481
|
-
// Filter out unsuccessful tool calls and prepare them for replay
|
|
468
|
+
// Filter out unsuccessful tool calls and prepare them for replay.
|
|
482
469
|
const successfulToolCalls = toolCalls.filter((tc) => tc.outcome?.isSuccessful);
|
|
483
|
-
const proposedToolCalls = await prepareToolCallsForRerun(successfulToolCalls, options);
|
|
470
|
+
const proposedToolCalls = await prepareToolCallsForRerun(successfulToolCalls, options, this.toolRegistry);
|
|
484
471
|
return {
|
|
485
472
|
metadata,
|
|
486
473
|
toolCalls: proposedToolCalls,
|
|
@@ -866,65 +853,40 @@ async function throwIfAnyToolsRequireGpt(requestedTools, toolCallsOnStart, toolR
|
|
|
866
853
|
}
|
|
867
854
|
/**
|
|
868
855
|
* Convert an *executed* list of {@link ToolCall}s into a list of
|
|
869
|
-
* {@link ProposedToolCall}s that can be replayed in a fresh
|
|
870
|
-
* session.
|
|
856
|
+
* {@link ProposedToolCall}s that can be replayed in a fresh session.
|
|
871
857
|
*
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
877
|
-
* 2. **Attempt remap with {@link ReplayableInteraction.prepareToolCallForRerun}.**
|
|
878
|
-
* If a call belongs to that set, we delegate to
|
|
879
|
-
* `ReplayableInteraction.remapForRerun` to inject the stored selector and
|
|
880
|
-
* strip any transient GPT-only fields.
|
|
881
|
-
* 3. **Pass through other calls unchanged.**
|
|
882
|
-
* Tools that have no UI footprint (e.g. navigation helpers, assertions)
|
|
883
|
-
* are copied verbatim.
|
|
884
|
-
* 4. **Error handling.**
|
|
885
|
-
* When remapping fails (e.g. selector metadata missing) we *skip* the
|
|
886
|
-
* offending call, emit a warning via `appLogger`, and continue processing
|
|
887
|
-
* the remainder so that a “best-effort” replay is still possible.
|
|
858
|
+
* For each call, we look up the {@link Tool} in the given registry and
|
|
859
|
+
* delegate to its `prepareForRerun` override. Tools that need selector
|
|
860
|
+
* remapping (e.g. {@link ClickTool}, {@link InputTextTool}, the mobile
|
|
861
|
+
* interaction tools) each own their own logic; tools with no replay-
|
|
862
|
+
* specific needs inherit the passthrough default from {@link Tool}.
|
|
888
863
|
*
|
|
889
|
-
*
|
|
890
|
-
*
|
|
864
|
+
* When a tool is not registered (stale flow, removed tool) or
|
|
865
|
+
* `prepareForRerun` throws (e.g. missing selector metadata), the call
|
|
866
|
+
* is passed through or skipped with an `appLogger.warn` — "best-effort
|
|
867
|
+
* replay" behavior is preserved.
|
|
891
868
|
*
|
|
892
|
-
* @param toolCalls – The chronologically ordered list of executed
|
|
893
|
-
* {@link ToolCall}s.
|
|
894
869
|
* @returns A list of {@link ProposedToolCall}s ready for replay.
|
|
895
870
|
*/
|
|
896
|
-
async function prepareToolCallsForRerun(toolCalls, options) {
|
|
897
|
-
|
|
898
|
-
const toolsThatNeedRemappedInputs = new Set([
|
|
899
|
-
ChooseSelectOptionTool_1.ChooseSelectOptionTool.NAME,
|
|
900
|
-
ClickTool_1.ClickTool.NAME,
|
|
901
|
-
DoubleClickTool_1.DoubleClickTool.NAME,
|
|
902
|
-
HoverOverElementTool_1.HoverOverElementTool.NAME,
|
|
903
|
-
InputFakerTool_1.InputFakerTool.NAME,
|
|
904
|
-
InputRandomizedEmailAddressTool_1.InputRandomizedEmailAddressTool.NAME,
|
|
905
|
-
InputTextTool_1.InputTextTool.NAME,
|
|
906
|
-
PressKeyTool_1.PressKeyTool.NAME,
|
|
907
|
-
RememberPageTextTool_1.RememberPageTextTool.NAME,
|
|
908
|
-
ScrollPageTool_1.ScrollPageTool.NAME,
|
|
909
|
-
]);
|
|
871
|
+
async function prepareToolCallsForRerun(toolCalls, options, toolRegistry) {
|
|
872
|
+
const toolsByName = new Map(toolRegistry.allTools().map((tool) => [tool.name, tool]));
|
|
910
873
|
const proposedToolCalls = [];
|
|
911
874
|
for (const toolCall of toolCalls) {
|
|
912
|
-
const
|
|
913
|
-
if (
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
}
|
|
917
|
-
catch (e) {
|
|
918
|
-
// Skip.
|
|
919
|
-
Logger_1.appLogger.warn(`Failed to prepare tool call for rerun: ${JSON.stringify(toolCall)}`, e);
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
else {
|
|
923
|
-
// This is just a normal tool then.
|
|
875
|
+
const tool = toolsByName.get(toolCall.toolName);
|
|
876
|
+
if (!tool) {
|
|
877
|
+
// Tool no longer registered (e.g. stale flow referencing a removed
|
|
878
|
+
// tool). Passthrough so we don't silently drop the call.
|
|
924
879
|
proposedToolCalls.push({
|
|
925
880
|
name: toolCall.toolName,
|
|
926
881
|
parameters: toolCall.parameters,
|
|
927
882
|
});
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
try {
|
|
886
|
+
proposedToolCalls.push(tool.prepareForRerun(toolCall, options));
|
|
887
|
+
}
|
|
888
|
+
catch (e) {
|
|
889
|
+
Logger_1.appLogger.warn(`Failed to prepare tool call for rerun: ${JSON.stringify(toolCall)}`, e);
|
|
928
890
|
}
|
|
929
891
|
}
|
|
930
892
|
return proposedToolCalls;
|
|
@@ -4,11 +4,8 @@ import type { env } from '../envVars';
|
|
|
4
4
|
import type { InteractionVisualizer } from '../managers/InteractionVisualizer';
|
|
5
5
|
import type { BrowserStateReference } from '../models/BrowserStateFlowReference';
|
|
6
6
|
import type { BrowserStorageState } from '../models/BrowserStorageState';
|
|
7
|
-
import type { CodeGenerationOptions } from '../models/CodeGenerationOptions';
|
|
8
7
|
import type { ControlPanelFactory } from '../models/ControlPanel';
|
|
9
8
|
import type { CreateDonobuFlow } from '../models/CreateDonobuFlow';
|
|
10
|
-
import type { ProposedToolCall } from '../models/ProposedToolCall';
|
|
11
|
-
import type { ToolCall } from '../models/ToolCall';
|
|
12
9
|
import type { TargetRuntime } from './TargetRuntime';
|
|
13
10
|
/**
|
|
14
11
|
* Parameters passed to {@link TargetRuntimePlugin.createRuntime}.
|
|
@@ -80,13 +77,6 @@ export interface TargetRuntimePlugin {
|
|
|
80
77
|
* the flow completes or errors.
|
|
81
78
|
*/
|
|
82
79
|
createRuntime(params: TargetRuntimeParams): Promise<TargetRuntime>;
|
|
83
|
-
/**
|
|
84
|
-
* Prepare tool calls from a prior flow for deterministic replay.
|
|
85
|
-
*
|
|
86
|
-
* Each target provides its own replay logic. For example, the web target
|
|
87
|
-
* uses {@link ReplayableInteraction.prepareToolCallForRerun}.
|
|
88
|
-
*/
|
|
89
|
-
prepareToolCallsForRerun(toolCalls: ToolCall[], options: CodeGenerationOptions): Promise<ProposedToolCall[]>;
|
|
90
80
|
}
|
|
91
81
|
/**
|
|
92
82
|
* An immutable registry of target runtime plugins, keyed by target type.
|
|
@@ -40,18 +40,7 @@ const path = __importStar(require("path"));
|
|
|
40
40
|
const InvalidParamValueException_1 = require("../exceptions/InvalidParamValueException");
|
|
41
41
|
const WebTargetInspector_1 = require("../managers/WebTargetInspector");
|
|
42
42
|
const ControlPanel_1 = require("../models/ControlPanel");
|
|
43
|
-
const ChooseSelectOptionTool_1 = require("../tools/ChooseSelectOptionTool");
|
|
44
|
-
const ClickTool_1 = require("../tools/ClickTool");
|
|
45
|
-
const DoubleClickTool_1 = require("../tools/DoubleClickTool");
|
|
46
43
|
const GoToWebpageTool_1 = require("../tools/GoToWebpageTool");
|
|
47
|
-
const HoverOverElementTool_1 = require("../tools/HoverOverElementTool");
|
|
48
|
-
const InputFakerTool_1 = require("../tools/InputFakerTool");
|
|
49
|
-
const InputRandomizedEmailAddressTool_1 = require("../tools/InputRandomizedEmailAddressTool");
|
|
50
|
-
const InputTextTool_1 = require("../tools/InputTextTool");
|
|
51
|
-
const PressKeyTool_1 = require("../tools/PressKeyTool");
|
|
52
|
-
const RememberPageTextTool_1 = require("../tools/RememberPageTextTool");
|
|
53
|
-
const ReplayableInteraction_1 = require("../tools/ReplayableInteraction");
|
|
54
|
-
const ScrollPageTool_1 = require("../tools/ScrollPageTool");
|
|
55
44
|
const BrowserUtils_1 = require("../utils/BrowserUtils");
|
|
56
45
|
const Logger_1 = require("../utils/Logger");
|
|
57
46
|
const PlaywrightUtils_1 = require("../utils/PlaywrightUtils");
|
|
@@ -263,37 +252,5 @@ exports.webTargetRuntimePlugin = {
|
|
|
263
252
|
async createRuntime(params) {
|
|
264
253
|
return WebTargetRuntime.create(params);
|
|
265
254
|
},
|
|
266
|
-
async prepareToolCallsForRerun(toolCalls, options) {
|
|
267
|
-
const toolsThatNeedRemappedInputs = new Set([
|
|
268
|
-
ChooseSelectOptionTool_1.ChooseSelectOptionTool.NAME,
|
|
269
|
-
ClickTool_1.ClickTool.NAME,
|
|
270
|
-
DoubleClickTool_1.DoubleClickTool.NAME,
|
|
271
|
-
HoverOverElementTool_1.HoverOverElementTool.NAME,
|
|
272
|
-
InputFakerTool_1.InputFakerTool.NAME,
|
|
273
|
-
InputRandomizedEmailAddressTool_1.InputRandomizedEmailAddressTool.NAME,
|
|
274
|
-
InputTextTool_1.InputTextTool.NAME,
|
|
275
|
-
PressKeyTool_1.PressKeyTool.NAME,
|
|
276
|
-
RememberPageTextTool_1.RememberPageTextTool.NAME,
|
|
277
|
-
ScrollPageTool_1.ScrollPageTool.NAME,
|
|
278
|
-
]);
|
|
279
|
-
const proposedToolCalls = [];
|
|
280
|
-
for (const toolCall of toolCalls) {
|
|
281
|
-
if (toolsThatNeedRemappedInputs.has(toolCall.toolName)) {
|
|
282
|
-
try {
|
|
283
|
-
proposedToolCalls.push(ReplayableInteraction_1.ReplayableInteraction.prepareToolCallForRerun(toolCall, options));
|
|
284
|
-
}
|
|
285
|
-
catch (e) {
|
|
286
|
-
Logger_1.appLogger.warn(`Failed to prepare tool call for rerun: ${JSON.stringify(toolCall)}`, e);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
else {
|
|
290
|
-
proposedToolCalls.push({
|
|
291
|
-
name: toolCall.toolName,
|
|
292
|
-
parameters: toolCall.parameters,
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
return proposedToolCalls;
|
|
297
|
-
},
|
|
298
255
|
};
|
|
299
256
|
//# sourceMappingURL=WebTargetRuntime.js.map
|
|
@@ -180,7 +180,7 @@ export declare abstract class ReplayableInteraction<CoreSchema extends z.ZodObje
|
|
|
180
180
|
* @returns A {@link ProposedToolCall} that can be executed in a fresh run.
|
|
181
181
|
* @throws Error if the original call lacks selector metadata.
|
|
182
182
|
*/
|
|
183
|
-
|
|
183
|
+
prepareForRerun(toolCall: ToolCall, options: CodeGenerationOptions): ProposedToolCall;
|
|
184
184
|
}
|
|
185
185
|
export {};
|
|
186
186
|
//# sourceMappingURL=ReplayableInteraction.d.ts.map
|
|
@@ -590,7 +590,7 @@ class ReplayableInteraction extends Tool_1.Tool {
|
|
|
590
590
|
* @returns A {@link ProposedToolCall} that can be executed in a fresh run.
|
|
591
591
|
* @throws Error if the original call lacks selector metadata.
|
|
592
592
|
*/
|
|
593
|
-
|
|
593
|
+
prepareForRerun(toolCall, options) {
|
|
594
594
|
// If the tool call is from a GPT, we need the result metadata to continue.
|
|
595
595
|
if (!('selector' in toolCall.parameters)) {
|
|
596
596
|
if (!toolCall.outcome.metadata) {
|
package/dist/esm/tools/Tool.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { z } from 'zod/v4';
|
|
2
|
+
import type { CodeGenerationOptions } from '../models/CodeGenerationOptions';
|
|
3
|
+
import type { ProposedToolCall } from '../models/ProposedToolCall';
|
|
4
|
+
import type { ToolCall } from '../models/ToolCall';
|
|
2
5
|
import type { ToolCallContext } from '../models/ToolCallContext';
|
|
3
6
|
import type { ToolCallResult } from '../models/ToolCallResult';
|
|
4
7
|
/** Represents a tool call to be invoked by a DonobuFlow. */
|
|
@@ -33,5 +36,16 @@ export declare abstract class Tool<CallSchema extends z.ZodObject, CallFromGptSc
|
|
|
33
36
|
* Invoke the tool as made from a GPT with the given context and parameters.
|
|
34
37
|
*/
|
|
35
38
|
abstract callFromGpt(context: ToolCallContext, parameters: z.infer<CallFromGptSchema>): Promise<ToolCallResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Transform a completed tool call into a {@link ProposedToolCall} suitable
|
|
41
|
+
* for deterministic replay / code generation.
|
|
42
|
+
*
|
|
43
|
+
* The default implementation is a passthrough — `{ name, parameters }` —
|
|
44
|
+
* which is correct for tools that have no replay-specific logic
|
|
45
|
+
* (waits, assertions, markers, etc.). Tools that need to hoist
|
|
46
|
+
* selector metadata out of their outcome, strip LLM-only fields, or
|
|
47
|
+
* otherwise rewrite themselves override this method.
|
|
48
|
+
*/
|
|
49
|
+
prepareForRerun(toolCall: ToolCall, _options: CodeGenerationOptions): ProposedToolCall;
|
|
36
50
|
}
|
|
37
51
|
//# sourceMappingURL=Tool.d.ts.map
|
package/dist/esm/tools/Tool.js
CHANGED
|
@@ -27,6 +27,22 @@ class Tool {
|
|
|
27
27
|
this.controlPanelMessage = controlPanelMessage;
|
|
28
28
|
this.supportedTargets = supportedTargets;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Transform a completed tool call into a {@link ProposedToolCall} suitable
|
|
32
|
+
* for deterministic replay / code generation.
|
|
33
|
+
*
|
|
34
|
+
* The default implementation is a passthrough — `{ name, parameters }` —
|
|
35
|
+
* which is correct for tools that have no replay-specific logic
|
|
36
|
+
* (waits, assertions, markers, etc.). Tools that need to hoist
|
|
37
|
+
* selector metadata out of their outcome, strip LLM-only fields, or
|
|
38
|
+
* otherwise rewrite themselves override this method.
|
|
39
|
+
*/
|
|
40
|
+
prepareForRerun(toolCall, _options) {
|
|
41
|
+
return {
|
|
42
|
+
name: toolCall.toolName,
|
|
43
|
+
parameters: toolCall.parameters,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
30
46
|
}
|
|
31
47
|
exports.Tool = Tool;
|
|
32
48
|
//# sourceMappingURL=Tool.js.map
|
package/dist/lib/ai/PageAi.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ export declare class PageAiRunner {
|
|
|
139
139
|
export declare class PageAi {
|
|
140
140
|
private readonly cache;
|
|
141
141
|
private readonly runner;
|
|
142
|
+
private readonly donobu;
|
|
142
143
|
/**
|
|
143
144
|
* @param donobu Donobu stack providing flow managers and shared services.
|
|
144
145
|
* @param gptClient GPT client used for autonomous reasoning.
|
package/dist/lib/ai/PageAi.js
CHANGED
|
@@ -133,6 +133,7 @@ class PageAi {
|
|
|
133
133
|
*/
|
|
134
134
|
constructor(donobu, gptClient, cache) {
|
|
135
135
|
this.cache = cache;
|
|
136
|
+
this.donobu = donobu;
|
|
136
137
|
this.runner = new PageAiRunner(donobu, gptClient);
|
|
137
138
|
}
|
|
138
139
|
/**
|
|
@@ -188,7 +189,7 @@ class PageAi {
|
|
|
188
189
|
}), {
|
|
189
190
|
areElementIdsVolatile: options?.volatileElementIds,
|
|
190
191
|
disableSelectorFailover: options?.noSelectorFailover,
|
|
191
|
-
});
|
|
192
|
+
}, this.donobu.toolRegistry);
|
|
192
193
|
const cacheEntry = cacheEntryBuilder_1.PageAiCacheEntryBuilder.fromMetadata(descriptor.key.pageUrl, runResult.donobuFlow.metadata, preparedToolCalls);
|
|
193
194
|
await this.cache.put(cacheEntry);
|
|
194
195
|
}
|
package/dist/main.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export * from './lib/test/fixtures/gptClients';
|
|
|
22
22
|
export * from './lib/test/testExtension';
|
|
23
23
|
export * from './lib/test/utils/donobuTestStack';
|
|
24
24
|
export { DonobuFlow } from './managers/DonobuFlow';
|
|
25
|
-
export { distillAllowedEnvVariableNames, DonobuFlowsManager, } from './managers/DonobuFlowsManager';
|
|
25
|
+
export { distillAllowedEnvVariableNames, DonobuFlowsManager, prepareToolCallsForRerun, } from './managers/DonobuFlowsManager';
|
|
26
26
|
export { type DonobuStack, setupDonobuStack } from './managers/DonobuStack';
|
|
27
27
|
export { InteractionVisualizer } from './managers/InteractionVisualizer';
|
|
28
28
|
export { type LoadedPlugins, type PluginDependencies, PluginLoader, } from './managers/PluginLoader';
|
package/dist/main.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.TargetRuntimePluginRegistry = exports.PersistencePluginRegistry = exports.createDefaultToolRegistry = exports.ToolManager = exports.PluginLoader = exports.InteractionVisualizer = exports.setupDonobuStack = exports.DonobuFlowsManager = exports.distillAllowedEnvVariableNames = exports.DonobuFlow = exports.env = exports.runGenerateSiteTests = exports.VercelAiGptClient = exports.OpenAiGptClient = exports.GptClientPluginRegistry = exports.GptClient = exports.GoogleGenerativeAiGptClient = exports.fixAssertFields = exports.DonobuGptClient = exports.AnthropicGptClient = void 0;
|
|
17
|
+
exports.TargetRuntimePluginRegistry = exports.PersistencePluginRegistry = exports.createDefaultToolRegistry = exports.ToolManager = exports.PluginLoader = exports.InteractionVisualizer = exports.setupDonobuStack = exports.prepareToolCallsForRerun = exports.DonobuFlowsManager = exports.distillAllowedEnvVariableNames = exports.DonobuFlow = exports.env = exports.runGenerateSiteTests = exports.VercelAiGptClient = exports.OpenAiGptClient = exports.GptClientPluginRegistry = exports.GptClient = exports.GoogleGenerativeAiGptClient = exports.fixAssertFields = exports.DonobuGptClient = exports.AnthropicGptClient = void 0;
|
|
18
18
|
exports.startDonobuServer = startDonobuServer;
|
|
19
19
|
const commander_1 = require("commander");
|
|
20
20
|
const v4_1 = require("zod/v4");
|
|
@@ -61,6 +61,7 @@ Object.defineProperty(exports, "DonobuFlow", { enumerable: true, get: function (
|
|
|
61
61
|
var DonobuFlowsManager_1 = require("./managers/DonobuFlowsManager");
|
|
62
62
|
Object.defineProperty(exports, "distillAllowedEnvVariableNames", { enumerable: true, get: function () { return DonobuFlowsManager_1.distillAllowedEnvVariableNames; } });
|
|
63
63
|
Object.defineProperty(exports, "DonobuFlowsManager", { enumerable: true, get: function () { return DonobuFlowsManager_1.DonobuFlowsManager; } });
|
|
64
|
+
Object.defineProperty(exports, "prepareToolCallsForRerun", { enumerable: true, get: function () { return DonobuFlowsManager_1.prepareToolCallsForRerun; } });
|
|
64
65
|
var DonobuStack_1 = require("./managers/DonobuStack");
|
|
65
66
|
Object.defineProperty(exports, "setupDonobuStack", { enumerable: true, get: function () { return DonobuStack_1.setupDonobuStack; } });
|
|
66
67
|
var InteractionVisualizer_1 = require("./managers/InteractionVisualizer");
|
|
@@ -209,32 +209,20 @@ export declare function distillAllowedEnvVariableNames(overallObjective: string
|
|
|
209
209
|
export declare function setupAllowedTools(flowParams: Pick<CreateDonobuFlow, 'customTools' | 'toolCallsOnStart' | 'allowedTools'>, hasGptClient: boolean, targetType: string, toolRegistry: ToolRegistry): Promise<Tool<z.ZodObject, z.ZodObject>[]>;
|
|
210
210
|
/**
|
|
211
211
|
* Convert an *executed* list of {@link ToolCall}s into a list of
|
|
212
|
-
* {@link ProposedToolCall}s that can be replayed in a fresh
|
|
213
|
-
* session.
|
|
212
|
+
* {@link ProposedToolCall}s that can be replayed in a fresh session.
|
|
214
213
|
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
* 2. **Attempt remap with {@link ReplayableInteraction.prepareToolCallForRerun}.**
|
|
221
|
-
* If a call belongs to that set, we delegate to
|
|
222
|
-
* `ReplayableInteraction.remapForRerun` to inject the stored selector and
|
|
223
|
-
* strip any transient GPT-only fields.
|
|
224
|
-
* 3. **Pass through other calls unchanged.**
|
|
225
|
-
* Tools that have no UI footprint (e.g. navigation helpers, assertions)
|
|
226
|
-
* are copied verbatim.
|
|
227
|
-
* 4. **Error handling.**
|
|
228
|
-
* When remapping fails (e.g. selector metadata missing) we *skip* the
|
|
229
|
-
* offending call, emit a warning via `appLogger`, and continue processing
|
|
230
|
-
* the remainder so that a “best-effort” replay is still possible.
|
|
214
|
+
* For each call, we look up the {@link Tool} in the given registry and
|
|
215
|
+
* delegate to its `prepareForRerun` override. Tools that need selector
|
|
216
|
+
* remapping (e.g. {@link ClickTool}, {@link InputTextTool}, the mobile
|
|
217
|
+
* interaction tools) each own their own logic; tools with no replay-
|
|
218
|
+
* specific needs inherit the passthrough default from {@link Tool}.
|
|
231
219
|
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
220
|
+
* When a tool is not registered (stale flow, removed tool) or
|
|
221
|
+
* `prepareForRerun` throws (e.g. missing selector metadata), the call
|
|
222
|
+
* is passed through or skipped with an `appLogger.warn` — "best-effort
|
|
223
|
+
* replay" behavior is preserved.
|
|
234
224
|
*
|
|
235
|
-
* @param toolCalls – The chronologically ordered list of executed
|
|
236
|
-
* {@link ToolCall}s.
|
|
237
225
|
* @returns A list of {@link ProposedToolCall}s ready for replay.
|
|
238
226
|
*/
|
|
239
|
-
export declare function prepareToolCallsForRerun(toolCalls: ToolCall[], options: CodeGenerationOptions): Promise<ProposedToolCall[]>;
|
|
227
|
+
export declare function prepareToolCallsForRerun(toolCalls: ToolCall[], options: CodeGenerationOptions, toolRegistry: ToolRegistry): Promise<ProposedToolCall[]>;
|
|
240
228
|
//# sourceMappingURL=DonobuFlowsManager.d.ts.map
|
|
@@ -51,18 +51,7 @@ const ToolRequiresGptException_1 = require("../exceptions/ToolRequiresGptExcepti
|
|
|
51
51
|
const UnknownToolException_1 = require("../exceptions/UnknownToolException");
|
|
52
52
|
const GptConfig_1 = require("../models/GptConfig");
|
|
53
53
|
const resolveTargetRuntime_1 = require("../targets/resolveTargetRuntime");
|
|
54
|
-
const ChooseSelectOptionTool_1 = require("../tools/ChooseSelectOptionTool");
|
|
55
|
-
const ClickTool_1 = require("../tools/ClickTool");
|
|
56
54
|
const CustomToolRunnerTool_1 = require("../tools/CustomToolRunnerTool");
|
|
57
|
-
const DoubleClickTool_1 = require("../tools/DoubleClickTool");
|
|
58
|
-
const HoverOverElementTool_1 = require("../tools/HoverOverElementTool");
|
|
59
|
-
const InputFakerTool_1 = require("../tools/InputFakerTool");
|
|
60
|
-
const InputRandomizedEmailAddressTool_1 = require("../tools/InputRandomizedEmailAddressTool");
|
|
61
|
-
const InputTextTool_1 = require("../tools/InputTextTool");
|
|
62
|
-
const PressKeyTool_1 = require("../tools/PressKeyTool");
|
|
63
|
-
const RememberPageTextTool_1 = require("../tools/RememberPageTextTool");
|
|
64
|
-
const ReplayableInteraction_1 = require("../tools/ReplayableInteraction");
|
|
65
|
-
const ScrollPageTool_1 = require("../tools/ScrollPageTool");
|
|
66
55
|
const FlowLogBuffer_1 = require("../utils/FlowLogBuffer");
|
|
67
56
|
const Logger_1 = require("../utils/Logger");
|
|
68
57
|
const MiscUtils_1 = require("../utils/MiscUtils");
|
|
@@ -291,11 +280,9 @@ class DonobuFlowsManager {
|
|
|
291
280
|
async getToolCallsForRerun(priorFlowMetadata, options) {
|
|
292
281
|
const originalToolCalls = await this.getToolCalls(priorFlowMetadata.id);
|
|
293
282
|
// Delegate tool call preparation to the target runtime plugin so that
|
|
294
|
-
// rerun logic is fully target-agnostic
|
|
295
|
-
|
|
296
|
-
return
|
|
297
|
-
? await plugin.prepareToolCallsForRerun(originalToolCalls, options)
|
|
298
|
-
: await prepareToolCallsForRerun(originalToolCalls, options);
|
|
283
|
+
// rerun logic is fully target-agnostic — it dispatches per tool via
|
|
284
|
+
// the tool's own `prepareForRerun` override.
|
|
285
|
+
return prepareToolCallsForRerun(originalToolCalls, options, this.toolRegistry);
|
|
299
286
|
}
|
|
300
287
|
/**
|
|
301
288
|
* Loads the given flow by ID and returns a `CreateDonobuFlow` object that can be passed to `createFlow`
|
|
@@ -460,7 +447,7 @@ class DonobuFlowsManager {
|
|
|
460
447
|
const flowMetadata = await this.getFlowById(flowId);
|
|
461
448
|
// Do not generate code for non-successful tool calls.
|
|
462
449
|
const originalToolCalls = (await this.getToolCalls(flowId)).filter((tc) => tc.outcome?.isSuccessful);
|
|
463
|
-
const proposedToolCalls = await prepareToolCallsForRerun(originalToolCalls, effectiveOptions);
|
|
450
|
+
const proposedToolCalls = await prepareToolCallsForRerun(originalToolCalls, effectiveOptions, this.toolRegistry);
|
|
464
451
|
const scriptVariant = effectiveOptions.playwrightScriptVariant === 'classic' ? 'classic' : 'ai';
|
|
465
452
|
if (scriptVariant === 'classic') {
|
|
466
453
|
return (0, CodeGenerator_1.getFlowAsPlaywrightScript)(flowMetadata, proposedToolCalls, effectiveOptions, this.toolRegistry);
|
|
@@ -478,9 +465,9 @@ class DonobuFlowsManager {
|
|
|
478
465
|
const flowsWithToolCalls = await Promise.all(flowIds.map(async (flowId) => {
|
|
479
466
|
const metadata = await this.getFlowById(flowId);
|
|
480
467
|
const toolCalls = await this.getToolCalls(flowId);
|
|
481
|
-
// Filter out unsuccessful tool calls and prepare them for replay
|
|
468
|
+
// Filter out unsuccessful tool calls and prepare them for replay.
|
|
482
469
|
const successfulToolCalls = toolCalls.filter((tc) => tc.outcome?.isSuccessful);
|
|
483
|
-
const proposedToolCalls = await prepareToolCallsForRerun(successfulToolCalls, options);
|
|
470
|
+
const proposedToolCalls = await prepareToolCallsForRerun(successfulToolCalls, options, this.toolRegistry);
|
|
484
471
|
return {
|
|
485
472
|
metadata,
|
|
486
473
|
toolCalls: proposedToolCalls,
|
|
@@ -866,65 +853,40 @@ async function throwIfAnyToolsRequireGpt(requestedTools, toolCallsOnStart, toolR
|
|
|
866
853
|
}
|
|
867
854
|
/**
|
|
868
855
|
* Convert an *executed* list of {@link ToolCall}s into a list of
|
|
869
|
-
* {@link ProposedToolCall}s that can be replayed in a fresh
|
|
870
|
-
* session.
|
|
856
|
+
* {@link ProposedToolCall}s that can be replayed in a fresh session.
|
|
871
857
|
*
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
877
|
-
* 2. **Attempt remap with {@link ReplayableInteraction.prepareToolCallForRerun}.**
|
|
878
|
-
* If a call belongs to that set, we delegate to
|
|
879
|
-
* `ReplayableInteraction.remapForRerun` to inject the stored selector and
|
|
880
|
-
* strip any transient GPT-only fields.
|
|
881
|
-
* 3. **Pass through other calls unchanged.**
|
|
882
|
-
* Tools that have no UI footprint (e.g. navigation helpers, assertions)
|
|
883
|
-
* are copied verbatim.
|
|
884
|
-
* 4. **Error handling.**
|
|
885
|
-
* When remapping fails (e.g. selector metadata missing) we *skip* the
|
|
886
|
-
* offending call, emit a warning via `appLogger`, and continue processing
|
|
887
|
-
* the remainder so that a “best-effort” replay is still possible.
|
|
858
|
+
* For each call, we look up the {@link Tool} in the given registry and
|
|
859
|
+
* delegate to its `prepareForRerun` override. Tools that need selector
|
|
860
|
+
* remapping (e.g. {@link ClickTool}, {@link InputTextTool}, the mobile
|
|
861
|
+
* interaction tools) each own their own logic; tools with no replay-
|
|
862
|
+
* specific needs inherit the passthrough default from {@link Tool}.
|
|
888
863
|
*
|
|
889
|
-
*
|
|
890
|
-
*
|
|
864
|
+
* When a tool is not registered (stale flow, removed tool) or
|
|
865
|
+
* `prepareForRerun` throws (e.g. missing selector metadata), the call
|
|
866
|
+
* is passed through or skipped with an `appLogger.warn` — "best-effort
|
|
867
|
+
* replay" behavior is preserved.
|
|
891
868
|
*
|
|
892
|
-
* @param toolCalls – The chronologically ordered list of executed
|
|
893
|
-
* {@link ToolCall}s.
|
|
894
869
|
* @returns A list of {@link ProposedToolCall}s ready for replay.
|
|
895
870
|
*/
|
|
896
|
-
async function prepareToolCallsForRerun(toolCalls, options) {
|
|
897
|
-
|
|
898
|
-
const toolsThatNeedRemappedInputs = new Set([
|
|
899
|
-
ChooseSelectOptionTool_1.ChooseSelectOptionTool.NAME,
|
|
900
|
-
ClickTool_1.ClickTool.NAME,
|
|
901
|
-
DoubleClickTool_1.DoubleClickTool.NAME,
|
|
902
|
-
HoverOverElementTool_1.HoverOverElementTool.NAME,
|
|
903
|
-
InputFakerTool_1.InputFakerTool.NAME,
|
|
904
|
-
InputRandomizedEmailAddressTool_1.InputRandomizedEmailAddressTool.NAME,
|
|
905
|
-
InputTextTool_1.InputTextTool.NAME,
|
|
906
|
-
PressKeyTool_1.PressKeyTool.NAME,
|
|
907
|
-
RememberPageTextTool_1.RememberPageTextTool.NAME,
|
|
908
|
-
ScrollPageTool_1.ScrollPageTool.NAME,
|
|
909
|
-
]);
|
|
871
|
+
async function prepareToolCallsForRerun(toolCalls, options, toolRegistry) {
|
|
872
|
+
const toolsByName = new Map(toolRegistry.allTools().map((tool) => [tool.name, tool]));
|
|
910
873
|
const proposedToolCalls = [];
|
|
911
874
|
for (const toolCall of toolCalls) {
|
|
912
|
-
const
|
|
913
|
-
if (
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
}
|
|
917
|
-
catch (e) {
|
|
918
|
-
// Skip.
|
|
919
|
-
Logger_1.appLogger.warn(`Failed to prepare tool call for rerun: ${JSON.stringify(toolCall)}`, e);
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
else {
|
|
923
|
-
// This is just a normal tool then.
|
|
875
|
+
const tool = toolsByName.get(toolCall.toolName);
|
|
876
|
+
if (!tool) {
|
|
877
|
+
// Tool no longer registered (e.g. stale flow referencing a removed
|
|
878
|
+
// tool). Passthrough so we don't silently drop the call.
|
|
924
879
|
proposedToolCalls.push({
|
|
925
880
|
name: toolCall.toolName,
|
|
926
881
|
parameters: toolCall.parameters,
|
|
927
882
|
});
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
try {
|
|
886
|
+
proposedToolCalls.push(tool.prepareForRerun(toolCall, options));
|
|
887
|
+
}
|
|
888
|
+
catch (e) {
|
|
889
|
+
Logger_1.appLogger.warn(`Failed to prepare tool call for rerun: ${JSON.stringify(toolCall)}`, e);
|
|
928
890
|
}
|
|
929
891
|
}
|
|
930
892
|
return proposedToolCalls;
|
|
@@ -4,11 +4,8 @@ import type { env } from '../envVars';
|
|
|
4
4
|
import type { InteractionVisualizer } from '../managers/InteractionVisualizer';
|
|
5
5
|
import type { BrowserStateReference } from '../models/BrowserStateFlowReference';
|
|
6
6
|
import type { BrowserStorageState } from '../models/BrowserStorageState';
|
|
7
|
-
import type { CodeGenerationOptions } from '../models/CodeGenerationOptions';
|
|
8
7
|
import type { ControlPanelFactory } from '../models/ControlPanel';
|
|
9
8
|
import type { CreateDonobuFlow } from '../models/CreateDonobuFlow';
|
|
10
|
-
import type { ProposedToolCall } from '../models/ProposedToolCall';
|
|
11
|
-
import type { ToolCall } from '../models/ToolCall';
|
|
12
9
|
import type { TargetRuntime } from './TargetRuntime';
|
|
13
10
|
/**
|
|
14
11
|
* Parameters passed to {@link TargetRuntimePlugin.createRuntime}.
|
|
@@ -80,13 +77,6 @@ export interface TargetRuntimePlugin {
|
|
|
80
77
|
* the flow completes or errors.
|
|
81
78
|
*/
|
|
82
79
|
createRuntime(params: TargetRuntimeParams): Promise<TargetRuntime>;
|
|
83
|
-
/**
|
|
84
|
-
* Prepare tool calls from a prior flow for deterministic replay.
|
|
85
|
-
*
|
|
86
|
-
* Each target provides its own replay logic. For example, the web target
|
|
87
|
-
* uses {@link ReplayableInteraction.prepareToolCallForRerun}.
|
|
88
|
-
*/
|
|
89
|
-
prepareToolCallsForRerun(toolCalls: ToolCall[], options: CodeGenerationOptions): Promise<ProposedToolCall[]>;
|
|
90
80
|
}
|
|
91
81
|
/**
|
|
92
82
|
* An immutable registry of target runtime plugins, keyed by target type.
|
|
@@ -40,18 +40,7 @@ const path = __importStar(require("path"));
|
|
|
40
40
|
const InvalidParamValueException_1 = require("../exceptions/InvalidParamValueException");
|
|
41
41
|
const WebTargetInspector_1 = require("../managers/WebTargetInspector");
|
|
42
42
|
const ControlPanel_1 = require("../models/ControlPanel");
|
|
43
|
-
const ChooseSelectOptionTool_1 = require("../tools/ChooseSelectOptionTool");
|
|
44
|
-
const ClickTool_1 = require("../tools/ClickTool");
|
|
45
|
-
const DoubleClickTool_1 = require("../tools/DoubleClickTool");
|
|
46
43
|
const GoToWebpageTool_1 = require("../tools/GoToWebpageTool");
|
|
47
|
-
const HoverOverElementTool_1 = require("../tools/HoverOverElementTool");
|
|
48
|
-
const InputFakerTool_1 = require("../tools/InputFakerTool");
|
|
49
|
-
const InputRandomizedEmailAddressTool_1 = require("../tools/InputRandomizedEmailAddressTool");
|
|
50
|
-
const InputTextTool_1 = require("../tools/InputTextTool");
|
|
51
|
-
const PressKeyTool_1 = require("../tools/PressKeyTool");
|
|
52
|
-
const RememberPageTextTool_1 = require("../tools/RememberPageTextTool");
|
|
53
|
-
const ReplayableInteraction_1 = require("../tools/ReplayableInteraction");
|
|
54
|
-
const ScrollPageTool_1 = require("../tools/ScrollPageTool");
|
|
55
44
|
const BrowserUtils_1 = require("../utils/BrowserUtils");
|
|
56
45
|
const Logger_1 = require("../utils/Logger");
|
|
57
46
|
const PlaywrightUtils_1 = require("../utils/PlaywrightUtils");
|
|
@@ -263,37 +252,5 @@ exports.webTargetRuntimePlugin = {
|
|
|
263
252
|
async createRuntime(params) {
|
|
264
253
|
return WebTargetRuntime.create(params);
|
|
265
254
|
},
|
|
266
|
-
async prepareToolCallsForRerun(toolCalls, options) {
|
|
267
|
-
const toolsThatNeedRemappedInputs = new Set([
|
|
268
|
-
ChooseSelectOptionTool_1.ChooseSelectOptionTool.NAME,
|
|
269
|
-
ClickTool_1.ClickTool.NAME,
|
|
270
|
-
DoubleClickTool_1.DoubleClickTool.NAME,
|
|
271
|
-
HoverOverElementTool_1.HoverOverElementTool.NAME,
|
|
272
|
-
InputFakerTool_1.InputFakerTool.NAME,
|
|
273
|
-
InputRandomizedEmailAddressTool_1.InputRandomizedEmailAddressTool.NAME,
|
|
274
|
-
InputTextTool_1.InputTextTool.NAME,
|
|
275
|
-
PressKeyTool_1.PressKeyTool.NAME,
|
|
276
|
-
RememberPageTextTool_1.RememberPageTextTool.NAME,
|
|
277
|
-
ScrollPageTool_1.ScrollPageTool.NAME,
|
|
278
|
-
]);
|
|
279
|
-
const proposedToolCalls = [];
|
|
280
|
-
for (const toolCall of toolCalls) {
|
|
281
|
-
if (toolsThatNeedRemappedInputs.has(toolCall.toolName)) {
|
|
282
|
-
try {
|
|
283
|
-
proposedToolCalls.push(ReplayableInteraction_1.ReplayableInteraction.prepareToolCallForRerun(toolCall, options));
|
|
284
|
-
}
|
|
285
|
-
catch (e) {
|
|
286
|
-
Logger_1.appLogger.warn(`Failed to prepare tool call for rerun: ${JSON.stringify(toolCall)}`, e);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
else {
|
|
290
|
-
proposedToolCalls.push({
|
|
291
|
-
name: toolCall.toolName,
|
|
292
|
-
parameters: toolCall.parameters,
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
return proposedToolCalls;
|
|
297
|
-
},
|
|
298
255
|
};
|
|
299
256
|
//# sourceMappingURL=WebTargetRuntime.js.map
|
|
@@ -180,7 +180,7 @@ export declare abstract class ReplayableInteraction<CoreSchema extends z.ZodObje
|
|
|
180
180
|
* @returns A {@link ProposedToolCall} that can be executed in a fresh run.
|
|
181
181
|
* @throws Error if the original call lacks selector metadata.
|
|
182
182
|
*/
|
|
183
|
-
|
|
183
|
+
prepareForRerun(toolCall: ToolCall, options: CodeGenerationOptions): ProposedToolCall;
|
|
184
184
|
}
|
|
185
185
|
export {};
|
|
186
186
|
//# sourceMappingURL=ReplayableInteraction.d.ts.map
|
|
@@ -590,7 +590,7 @@ class ReplayableInteraction extends Tool_1.Tool {
|
|
|
590
590
|
* @returns A {@link ProposedToolCall} that can be executed in a fresh run.
|
|
591
591
|
* @throws Error if the original call lacks selector metadata.
|
|
592
592
|
*/
|
|
593
|
-
|
|
593
|
+
prepareForRerun(toolCall, options) {
|
|
594
594
|
// If the tool call is from a GPT, we need the result metadata to continue.
|
|
595
595
|
if (!('selector' in toolCall.parameters)) {
|
|
596
596
|
if (!toolCall.outcome.metadata) {
|
package/dist/tools/Tool.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { z } from 'zod/v4';
|
|
2
|
+
import type { CodeGenerationOptions } from '../models/CodeGenerationOptions';
|
|
3
|
+
import type { ProposedToolCall } from '../models/ProposedToolCall';
|
|
4
|
+
import type { ToolCall } from '../models/ToolCall';
|
|
2
5
|
import type { ToolCallContext } from '../models/ToolCallContext';
|
|
3
6
|
import type { ToolCallResult } from '../models/ToolCallResult';
|
|
4
7
|
/** Represents a tool call to be invoked by a DonobuFlow. */
|
|
@@ -33,5 +36,16 @@ export declare abstract class Tool<CallSchema extends z.ZodObject, CallFromGptSc
|
|
|
33
36
|
* Invoke the tool as made from a GPT with the given context and parameters.
|
|
34
37
|
*/
|
|
35
38
|
abstract callFromGpt(context: ToolCallContext, parameters: z.infer<CallFromGptSchema>): Promise<ToolCallResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Transform a completed tool call into a {@link ProposedToolCall} suitable
|
|
41
|
+
* for deterministic replay / code generation.
|
|
42
|
+
*
|
|
43
|
+
* The default implementation is a passthrough — `{ name, parameters }` —
|
|
44
|
+
* which is correct for tools that have no replay-specific logic
|
|
45
|
+
* (waits, assertions, markers, etc.). Tools that need to hoist
|
|
46
|
+
* selector metadata out of their outcome, strip LLM-only fields, or
|
|
47
|
+
* otherwise rewrite themselves override this method.
|
|
48
|
+
*/
|
|
49
|
+
prepareForRerun(toolCall: ToolCall, _options: CodeGenerationOptions): ProposedToolCall;
|
|
36
50
|
}
|
|
37
51
|
//# sourceMappingURL=Tool.d.ts.map
|
package/dist/tools/Tool.js
CHANGED
|
@@ -27,6 +27,22 @@ class Tool {
|
|
|
27
27
|
this.controlPanelMessage = controlPanelMessage;
|
|
28
28
|
this.supportedTargets = supportedTargets;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Transform a completed tool call into a {@link ProposedToolCall} suitable
|
|
32
|
+
* for deterministic replay / code generation.
|
|
33
|
+
*
|
|
34
|
+
* The default implementation is a passthrough — `{ name, parameters }` —
|
|
35
|
+
* which is correct for tools that have no replay-specific logic
|
|
36
|
+
* (waits, assertions, markers, etc.). Tools that need to hoist
|
|
37
|
+
* selector metadata out of their outcome, strip LLM-only fields, or
|
|
38
|
+
* otherwise rewrite themselves override this method.
|
|
39
|
+
*/
|
|
40
|
+
prepareForRerun(toolCall, _options) {
|
|
41
|
+
return {
|
|
42
|
+
name: toolCall.toolName,
|
|
43
|
+
parameters: toolCall.parameters,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
30
46
|
}
|
|
31
47
|
exports.Tool = Tool;
|
|
32
48
|
//# sourceMappingURL=Tool.js.map
|