@mablhq/mabl-cli 2.105.4 → 2.105.14
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/execution/index.js +1 -1
- package/index.d.ts +12 -0
- package/mablscript/MablStep.js +3 -1
- package/mablscript/MablStepV2.js +4 -2
- package/mablscript/actions/FindAction.js +4 -1
- package/package.json +1 -1
- package/trainer/cli/runAgenticGeneration.js +1 -0
- package/trainer/generation/AgenticGenerationRunner.js +44 -1
- package/trainer/sharedUtils/mablscript/MablscriptImporter.js +5 -1
- package/trainer/sharedUtils/mablscript/stepSerialization.js +1 -0
package/index.d.ts
CHANGED
|
@@ -2,6 +2,12 @@ import {BrowserContext, Locator, Page, Frame} from 'playwright-core';
|
|
|
2
2
|
import {TestType, Download} from '@playwright/test';
|
|
3
3
|
|
|
4
4
|
declare module '@mablhq/mabl-cli' {
|
|
5
|
+
export type SnippetLogLevel = 'info' | 'warn' | 'error';
|
|
6
|
+
export interface SnippetLogLine {
|
|
7
|
+
message: string;
|
|
8
|
+
level: SnippetLogLevel;
|
|
9
|
+
}
|
|
10
|
+
|
|
5
11
|
export type AuthServerPolicy = 'off' | 'none' | 'all';
|
|
6
12
|
export enum TestResultStatus {
|
|
7
13
|
passed = 'passed',
|
|
@@ -299,6 +305,12 @@ export type AgenticGenerationOptions =
|
|
|
299
305
|
export interface AgenticGenerationResult {
|
|
300
306
|
success: boolean;
|
|
301
307
|
error?: string;
|
|
308
|
+
/**
|
|
309
|
+
* The original error when an unexpected infrastructure failure occurred
|
|
310
|
+
* (e.g., browser failed to launch, API returned 5xx during setup).
|
|
311
|
+
* Callers can rethrow this to signal a fatal job failure for monitoring.
|
|
312
|
+
*/
|
|
313
|
+
fatalError?: Error;
|
|
302
314
|
steps: string[];
|
|
303
315
|
trainingSessionId: string;
|
|
304
316
|
rawSteps: any[];
|
package/mablscript/MablStep.js
CHANGED
|
@@ -119,7 +119,9 @@ class MablStep extends MablAction_1.MablAction {
|
|
|
119
119
|
}
|
|
120
120
|
toLineDiffFormat(_omitStepId = false) {
|
|
121
121
|
const lineDiffProperties = {
|
|
122
|
-
annotation: this.annotation
|
|
122
|
+
annotation: this.annotation && Object.keys(this.annotation).length > 0
|
|
123
|
+
? this.annotation
|
|
124
|
+
: undefined,
|
|
123
125
|
disabled: this.isDisabled(),
|
|
124
126
|
mablscript: this.toMablscript(),
|
|
125
127
|
};
|
package/mablscript/MablStepV2.js
CHANGED
|
@@ -85,7 +85,7 @@ class MablStepV2 extends MablStep_1.MablStep {
|
|
|
85
85
|
return false;
|
|
86
86
|
}
|
|
87
87
|
getResolvedDescription() {
|
|
88
|
-
return this.annotation?.description
|
|
88
|
+
return this.annotation?.description || this.getDescription();
|
|
89
89
|
}
|
|
90
90
|
toLineDiffFormat(omitStepId = false) {
|
|
91
91
|
const descriptor = { ...this.toStepDescriptor() };
|
|
@@ -93,7 +93,9 @@ class MablStepV2 extends MablStep_1.MablStep {
|
|
|
93
93
|
delete descriptor.id;
|
|
94
94
|
}
|
|
95
95
|
const lineDiffProperties = {
|
|
96
|
-
annotation: this.annotation
|
|
96
|
+
annotation: this.annotation && Object.keys(this.annotation).length > 0
|
|
97
|
+
? this.annotation
|
|
98
|
+
: undefined,
|
|
97
99
|
disabled: this.isDisabled(),
|
|
98
100
|
descriptor,
|
|
99
101
|
};
|
|
@@ -130,8 +130,11 @@ class FindAction extends MablAction_1.MablAction {
|
|
|
130
130
|
if (findType === 'find_cookie') {
|
|
131
131
|
return new FindAction(findType, [findTarget]);
|
|
132
132
|
}
|
|
133
|
+
const primarySelector = findTarget && typeof findTarget === 'object' && 'selector' in findTarget
|
|
134
|
+
? findTarget.selector
|
|
135
|
+
: findTarget;
|
|
133
136
|
return new FindAction(findType, [
|
|
134
|
-
|
|
137
|
+
primarySelector,
|
|
135
138
|
stepArgs.find.foundElementSelectors,
|
|
136
139
|
findOptions,
|
|
137
140
|
]);
|
package/package.json
CHANGED
|
@@ -110,7 +110,7 @@ class AgenticGenerationRunner {
|
|
|
110
110
|
}
|
|
111
111
|
: undefined;
|
|
112
112
|
if (!pendingToolCall) {
|
|
113
|
-
this.
|
|
113
|
+
await this.resolveOrphanedToolCalls(sessionId, loopResult, saveResult);
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
116
|
const savedSuccessfully = saveResult?.success && saveResult.testId;
|
|
@@ -148,6 +148,48 @@ class AgenticGenerationRunner {
|
|
|
148
148
|
this.logger.error('Failed to finalize agent session', error instanceof Error ? error : undefined);
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
|
+
async resolveOrphanedToolCalls(sessionId, loopResult, saveResult) {
|
|
152
|
+
const session = await this.config.apiClient.getAgentSession(sessionId);
|
|
153
|
+
const allToolCalls = (0, messageConversion_1.extractToolCallsFromMessages)(session.messages, this.logger);
|
|
154
|
+
const clientToolCalls = (0, messageConversion_1.filterClientSideToolCalls)(allToolCalls);
|
|
155
|
+
const unansweredToolCalls = (0, messageConversion_1.filterToolCallsWithoutOutputs)(clientToolCalls, session.messages);
|
|
156
|
+
const savedSuccessfully = saveResult?.success && saveResult.testId;
|
|
157
|
+
const artifacts = [];
|
|
158
|
+
if (savedSuccessfully) {
|
|
159
|
+
artifacts.push({
|
|
160
|
+
artifact_type: 'remote',
|
|
161
|
+
entity_kind: mablApi_1.ArtifactEntityKind.Test,
|
|
162
|
+
entity_id: saveResult.testId,
|
|
163
|
+
entity_name: saveResult.savedTest?.name,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (unansweredToolCalls.length > 0) {
|
|
167
|
+
this.logger.info(`Found ${unansweredToolCalls.length} unanswered tool call(s) in session — responding with error`);
|
|
168
|
+
const errorMessage = savedSuccessfully
|
|
169
|
+
? 'Test saved'
|
|
170
|
+
: loopResult.failureReason ?? 'Generation failed';
|
|
171
|
+
const toolOutputParts = unansweredToolCalls.map((tc) => (0, messageConversion_1.createToolOutputMessagePart)({
|
|
172
|
+
toolCallId: tc.id,
|
|
173
|
+
toolName: tc.name,
|
|
174
|
+
result: {
|
|
175
|
+
success: !!savedSuccessfully,
|
|
176
|
+
testId: saveResult?.testId,
|
|
177
|
+
testUrl: saveResult?.testUrl,
|
|
178
|
+
message: errorMessage,
|
|
179
|
+
},
|
|
180
|
+
}));
|
|
181
|
+
const toolOutputMessage = (0, messageConversion_1.createToolOutputMessage)(toolOutputParts);
|
|
182
|
+
await this.config.apiClient.appendAgentSessionMessage(sessionId, toolOutputMessage, artifacts.length > 0 ? artifacts : undefined);
|
|
183
|
+
}
|
|
184
|
+
else if (artifacts.length > 0) {
|
|
185
|
+
this.logger.info(`No pending tool calls — associating saved test ${saveResult.testId} with session ${sessionId}`);
|
|
186
|
+
const message = (0, messageConversion_1.createErrorTextMessage)(loopResult.failureReason ?? 'Generation ended');
|
|
187
|
+
await this.config.apiClient.appendAgentSessionMessage(sessionId, message, artifacts);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
this.logger.info('No pending tool calls to finalize — session may have ended cleanly');
|
|
191
|
+
}
|
|
192
|
+
}
|
|
151
193
|
async createBrowserAndNavigate() {
|
|
152
194
|
this.logger.info('Creating browser and navigating to URL');
|
|
153
195
|
const { testContext, accountFeatures } = await (0, createTrainingTestContext_1.createTrainingTestContext)({
|
|
@@ -339,6 +381,7 @@ class AgenticGenerationRunner {
|
|
|
339
381
|
return {
|
|
340
382
|
success: false,
|
|
341
383
|
error: errorMessage,
|
|
384
|
+
fatalError: error instanceof Error ? error : new Error(errorMessage),
|
|
342
385
|
steps: [],
|
|
343
386
|
trainingSessionId: this.state?.getTrainingSessionId() ?? '',
|
|
344
387
|
status: generation_types_1.TestGenerationStatus.Failed,
|
|
@@ -425,7 +425,11 @@ class MablscriptImporter {
|
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
427
|
convertStepGroupStep(mablStepGroup, isMobileFlow) {
|
|
428
|
-
const convertedSteps = mablStepGroup.steps.map((nestedMablStep) =>
|
|
428
|
+
const convertedSteps = mablStepGroup.steps.map((nestedMablStep) => {
|
|
429
|
+
const step = this.convertMablStepToTrainerStep(nestedMablStep, isMobileFlow);
|
|
430
|
+
step.setDisabled(nestedMablStep.isDisabled());
|
|
431
|
+
return step;
|
|
432
|
+
});
|
|
429
433
|
const intentDescription = mablStepGroup.intent?.description;
|
|
430
434
|
const stepGroup = new ExecuteStepGroupStep_1.default(convertedSteps, intentDescription);
|
|
431
435
|
const existingStepId = mablStepGroup.stepId();
|