@empiricalrun/test-gen 0.20.4 → 0.21.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/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @empiricalrun/test-gen
2
2
 
3
+ ## 0.21.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 3c714f7: feat: add master agent support
8
+
9
+ ### Patch Changes
10
+
11
+ - d7a24f0: fix: add lint rule for no floating promises
12
+ - d1a1ff2: fix: restrict usage of llm basis token usage
13
+ - Updated dependencies [3c714f7]
14
+ - Updated dependencies [d1a1ff2]
15
+ - @empiricalrun/llm@0.4.3
16
+
17
+ ## 0.20.5
18
+
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies [a9423b7]
22
+ - @empiricalrun/llm@0.4.2
23
+
3
24
  ## 0.20.4
4
25
 
5
26
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"done.d.ts","sourceRoot":"","sources":["../../src/actions/done.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAErD,eAAO,MAAM,2BAA2B,cAAc,CAAC;AAEvD,eAAO,MAAM,mBAAmB,EAAE,yBAyBjC,CAAC"}
1
+ {"version":3,"file":"done.d.ts","sourceRoot":"","sources":["../../src/actions/done.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAErD,eAAO,MAAM,2BAA2B,cAAc,CAAC;AAEvD,eAAO,MAAM,mBAAmB,EAAE,yBAuBjC,CAAC"}
@@ -2,11 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.doneActionGenerator = exports.PLAYWRIGHT_DONE_ACTION_NAME = void 0;
4
4
  exports.PLAYWRIGHT_DONE_ACTION_NAME = "task_done";
5
- const doneActionGenerator = (page) => {
5
+ const doneActionGenerator = () => {
6
6
  return {
7
- execute: async () => {
8
- await page.close();
9
- },
7
+ execute: async () => { },
10
8
  template: () => ``,
11
9
  name: exports.PLAYWRIGHT_DONE_ACTION_NAME,
12
10
  schema: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGlC,OAAO,EAAU,YAAY,EAAE,MAAM,UAAU,CAAC;AAQhD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,eAAe,CAAmC;gBAC9C,IAAI,EAAE,IAAI;IAYhB,aAAa,CAAC,IAAI,oBAAa,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAqBhE,gBAAgB,IAAI,YAAY,EAAE;IAIlC,YAAY;IAIZ,UAAU;CAMX"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGlC,OAAO,EAAU,YAAY,EAAE,MAAM,UAAU,CAAC;AAQhD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,eAAe,CAAmC;gBAC9C,IAAI,EAAE,IAAI;IAYhB,aAAa,CAAC,IAAI,oBAAa,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAqBhE,gBAAgB,IAAI,YAAY,EAAE;IAIlC,YAAY;IAIZ,UAAU;CASX"}
@@ -51,6 +51,7 @@ class PlaywrightActions {
51
51
  }
52
52
  isComplete() {
53
53
  const [doneAction] = this.recordedActions.filter((a) => a.name === done_1.PLAYWRIGHT_DONE_ACTION_NAME);
54
+ this.recordedActions = this.recordedActions.filter((a) => a.name !== done_1.PLAYWRIGHT_DONE_ACTION_NAME);
54
55
  return !!doneAction;
55
56
  }
56
57
  }
@@ -0,0 +1,26 @@
1
+ export declare const NEXT_TASK = "next_task";
2
+ export declare const NextTaskAction: {
3
+ name: string;
4
+ schema: {
5
+ type: string;
6
+ function: {
7
+ name: string;
8
+ description: string;
9
+ parameters: {
10
+ type: string;
11
+ properties: {
12
+ action: {
13
+ type: string;
14
+ description: string;
15
+ };
16
+ reason: {
17
+ type: string;
18
+ description: string;
19
+ };
20
+ };
21
+ required: string[];
22
+ };
23
+ };
24
+ };
25
+ };
26
+ //# sourceMappingURL=next-task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next-task.d.ts","sourceRoot":"","sources":["../../src/actions/next-task.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,cAAc,CAAC;AAErC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;CA0B1B,CAAC"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NextTaskAction = exports.NEXT_TASK = void 0;
4
+ exports.NEXT_TASK = "next_task";
5
+ exports.NextTaskAction = {
6
+ name: exports.NEXT_TASK,
7
+ schema: {
8
+ type: "function",
9
+ function: {
10
+ name: exports.NEXT_TASK,
11
+ description: "take the next action base on the provided task",
12
+ parameters: {
13
+ type: "object",
14
+ properties: {
15
+ action: {
16
+ type: "string",
17
+ description: `explain the next action in natural language.
18
+ The next action should be as atomic as possible. E.g. each click, key press, input should be a separate action.
19
+ Each action should take the task to completion, if not the action is invalid.`,
20
+ },
21
+ reason: {
22
+ type: "string",
23
+ description: "explain how this action will help to complete the task",
24
+ },
25
+ },
26
+ required: ["action", "reason"],
27
+ },
28
+ },
29
+ },
30
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"reload-page.d.ts","sourceRoot":"","sources":["../../src/actions/reload-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAErD,eAAO,MAAM,6BAA6B,gBAAgB,CAAC;AAE3D,eAAO,MAAM,qBAAqB,EAAE,yBA8BnC,CAAC"}
1
+ {"version":3,"file":"reload-page.d.ts","sourceRoot":"","sources":["../../src/actions/reload-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAErD,eAAO,MAAM,6BAA6B,gBAAgB,CAAC;AAE3D,eAAO,MAAM,qBAAqB,EAAE,yBA+BnC,CAAC"}
@@ -19,7 +19,7 @@ const reloadActionGenerator = (page) => {
19
19
  type: "function",
20
20
  function: {
21
21
  name: exports.PLAYWRIGHT_RELOAD_ACTION_NAME,
22
- description: "reload the page by calling this method",
22
+ description: "reload the page by calling this method. Call this method only when a page reload is requested in the task.",
23
23
  parameters: {
24
24
  type: "object",
25
25
  properties: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/actions/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,EAAE,GAAG,CAAC;QAChB,MAAM,EAAE,GAAG,CAAC;KACb;CACF;AAED,wBAAsB,oCAAoC,CACxD,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,IAAI,gBAmBX"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/actions/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,EAAE,GAAG,CAAC;QAChB,MAAM,EAAE,GAAG,CAAC;KACb;CACF;AAED,wBAAsB,oCAAoC,CACxD,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,IAAI,gBAkBX"}
@@ -4,7 +4,9 @@ exports.getPlaywrightLocatorUsingCssSelector = void 0;
4
4
  async function getPlaywrightLocatorUsingCssSelector(cssSelector, page) {
5
5
  // TODO: analyse other solutions than just css. Also find other solutions to support :has-text -> prompting ?
6
6
  // jquery doesnt support :has-text. neither css. Only playwright locator supports this selector though.
7
- const sanitizedCssSelectorForJQuery = cssSelector.replaceAll(":has-text", ":contains");
7
+ const sanitizedCssSelectorForJQuery = cssSelector
8
+ .replaceAll(":has-text", ":contains")
9
+ .replaceAll(":text", ":contains");
8
10
  return await page.evaluate((locator) => {
9
11
  const elements = window.jQuery(locator.cssForJq);
10
12
  let selectedElem = elements[0];
@@ -5,6 +5,7 @@ type BrowsingAgentOptions = Partial<TestGenConfigOptions> & {
5
5
  disallowedStrings?: string[];
6
6
  };
7
7
  };
8
+ export declare function browsingAgentUsingMasterAgent(task: string, page: Page, options: BrowsingAgentOptions): Promise<string>;
8
9
  export declare function browsingAgent(task: string, page: Page, options: BrowsingAgentOptions): Promise<string>;
9
10
  export {};
10
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAWlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAInD,KAAK,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,GAAG;IAC1D,YAAY,CAAC,EAAE;QACb,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,oBAAoB,mBAkG9B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAWlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAMnD,KAAK,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,GAAG;IAC1D,YAAY,CAAC,EAAE;QACb,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,wBAAsB,6BAA6B,CACjD,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,oBAAoB,mBAiK9B;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,oBAAoB,mBAqG9B"}
@@ -1,13 +1,159 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.browsingAgent = void 0;
3
+ exports.browsingAgent = exports.browsingAgentUsingMasterAgent = void 0;
4
4
  const llm_1 = require("@empiricalrun/llm");
5
5
  const actions_1 = require("../../actions");
6
6
  const logger_1 = require("../../bin/logger");
7
7
  const constants_1 = require("../../constants");
8
8
  const session_1 = require("../../session");
9
9
  const html_1 = require("../../utils/html");
10
+ const run_1 = require("../master/run");
11
+ const verification_1 = require("../verification");
10
12
  const utils_1 = require("./utils");
13
+ async function browsingAgentUsingMasterAgent(task, page, options) {
14
+ const logger = new logger_1.CustomLogger();
15
+ const trace = llm_1.langfuseInstance.trace({
16
+ name: "test-generator",
17
+ ...(0, session_1.getSessionDetails)(),
18
+ tags: [
19
+ options.metadata?.projectName,
20
+ options.metadata?.environment,
21
+ ].filter((s) => !!s),
22
+ });
23
+ const llm = new llm_1.LLM({
24
+ trace,
25
+ provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
26
+ defaultModel: options.model || constants_1.DEFAULT_MODEL,
27
+ providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
28
+ });
29
+ const actions = new actions_1.PlaywrightActions(page);
30
+ const tools = actions.getActionSchemas();
31
+ await (0, utils_1.injectPwLocatorGenerator)(page);
32
+ trace.update({ input: { task } });
33
+ let lastActionExecTrace = "";
34
+ let isGivenTaskDone = false;
35
+ const masterAgentActions = [];
36
+ while (!isGivenTaskDone) {
37
+ const masterAgentSpan = trace.span({ name: "master-agent" });
38
+ if (masterAgentActions.length > 0) {
39
+ const verificationAgentResp = await (0, verification_1.verificationAgent)({
40
+ llm,
41
+ trace: masterAgentSpan,
42
+ task,
43
+ conversation: ["Successful actions", ...masterAgentActions],
44
+ });
45
+ isGivenTaskDone = verificationAgentResp.isDone;
46
+ if (isGivenTaskDone) {
47
+ logger.log(`Master agent task is done: ${verificationAgentResp.reason}`);
48
+ break;
49
+ }
50
+ }
51
+ const { action, reason } = await (0, run_1.masterAgent)(task, page, masterAgentActions, masterAgentSpan, llm, options);
52
+ logger.log(`Next action: ${action} \n reason: ${reason}`);
53
+ if (isGivenTaskDone) {
54
+ break;
55
+ }
56
+ let isTaskDone = false;
57
+ const executedActions = [];
58
+ while (!isTaskDone) {
59
+ const browsingAgentSpan = masterAgentSpan.span({
60
+ name: `browsing-agent`,
61
+ });
62
+ const pageContentSpan = browsingAgentSpan.span({ name: "page-content" });
63
+ const pageContent = await page.content();
64
+ pageContentSpan.end({ output: { pageContent } });
65
+ const sanitizationSpan = browsingAgentSpan.span({
66
+ name: "page-sanitization",
67
+ });
68
+ const pageSnapshot = (0, html_1.sanitizeHtml)(pageContent, options.htmlSanitize);
69
+ sanitizationSpan.end({ output: { pageSnapshot } });
70
+ const promptSpan = browsingAgentSpan.span({ name: "page-prompt" });
71
+ // extract all successful actions
72
+ const successfulActions = executedActions
73
+ .filter((a) => !a.isError)
74
+ .map((a) => a.action);
75
+ if (successfulActions.length > 0) {
76
+ const verificationAgentResp = await (0, verification_1.verificationAgent)({
77
+ llm,
78
+ trace: browsingAgentSpan,
79
+ task: action,
80
+ conversation: ["Successful actions", ...successfulActions],
81
+ });
82
+ isTaskDone = verificationAgentResp.isDone;
83
+ if (isTaskDone) {
84
+ browsingAgentSpan.event({ name: "task-done" });
85
+ browsingAgentSpan.end({
86
+ output: { taskDone: true, reason: verificationAgentResp.reason },
87
+ });
88
+ break;
89
+ }
90
+ }
91
+ const messages = await (0, utils_1.getPromptForNextAction)({
92
+ pageSnapshot,
93
+ previousActions: successfulActions,
94
+ task: action,
95
+ lastActionErrors: lastActionExecTrace ? [lastActionExecTrace] : [],
96
+ promptType: "browsing-agent-as-tool",
97
+ });
98
+ promptSpan.end({ output: { messages } });
99
+ const completion = await llm.createChatCompletion({
100
+ messages,
101
+ tools,
102
+ trace: browsingAgentSpan,
103
+ model: options.model || constants_1.DEFAULT_MODEL,
104
+ modelParameters: {
105
+ ...constants_1.DEFAULT_MODEL_PARAMETERS,
106
+ ...options.modelParameters,
107
+ tool_choice: "required",
108
+ },
109
+ });
110
+ const toolCalls = completion?.tool_calls || [];
111
+ const toolCallsSpan = browsingAgentSpan.span({ name: "tool-calls" });
112
+ for (const i in toolCalls) {
113
+ const toolCall = toolCalls[i];
114
+ try {
115
+ await actions.executeAction(toolCall.function.name, JSON.parse(toolCall.function.arguments));
116
+ executedActions.push({
117
+ isError: false,
118
+ action: JSON.stringify(toolCall),
119
+ });
120
+ lastActionExecTrace = "";
121
+ }
122
+ catch (e) {
123
+ // TODO: implement feedback loop to llm
124
+ executedActions.push({
125
+ isError: true,
126
+ action: JSON.stringify(toolCall.function.arguments)
127
+ ?.reason,
128
+ });
129
+ lastActionExecTrace = e.message;
130
+ logger.error(lastActionExecTrace, e);
131
+ }
132
+ }
133
+ toolCallsSpan.end({ output: { toolCalls } });
134
+ // mark task as done if llm is stuck in loop
135
+ if (executedActions.length > 4) {
136
+ const lastThreeActions = executedActions.slice(-4);
137
+ const lastThreeActionsFailed = lastThreeActions.every((a) => a.isError);
138
+ if (lastThreeActionsFailed) {
139
+ // TODO: this should be sent to dashboard
140
+ logger.error("Agent is not able to figure out next action, marking task as done");
141
+ isTaskDone = true;
142
+ break;
143
+ }
144
+ }
145
+ }
146
+ masterAgentSpan.end({ output: { action, reason } });
147
+ masterAgentActions.push(action);
148
+ }
149
+ await page.close();
150
+ const code = actions.generateCode();
151
+ trace.update({ input: { task }, output: { code } });
152
+ logger.success("Successfully generated code for the given task");
153
+ logger.log(`Trace: ${trace.getTraceUrl()}`);
154
+ return code;
155
+ }
156
+ exports.browsingAgentUsingMasterAgent = browsingAgentUsingMasterAgent;
11
157
  async function browsingAgent(task, page, options) {
12
158
  const logger = new logger_1.CustomLogger();
13
159
  const session = (0, session_1.getSessionDetails)();
@@ -27,6 +173,12 @@ async function browsingAgent(task, page, options) {
27
173
  await (0, utils_1.injectPwLocatorGenerator)(page);
28
174
  trace.update({ input: { task } });
29
175
  let lastActionExecTrace = "";
176
+ const llm = new llm_1.LLM({
177
+ trace,
178
+ provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
179
+ defaultModel: options.model || constants_1.DEFAULT_MODEL,
180
+ providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
181
+ });
30
182
  while (!isTaskDone) {
31
183
  const pageContentSpan = trace.span({ name: "page-content" });
32
184
  const pageContent = await page.content();
@@ -46,13 +198,9 @@ async function browsingAgent(task, page, options) {
46
198
  lastActionErrors: lastActionExecTrace ? [lastActionExecTrace] : [],
47
199
  });
48
200
  promptSpan.end({ output: { messages } });
49
- const completion = await (0, llm_1.getLLMResult)({
201
+ const completion = await llm.createChatCompletion({
50
202
  messages,
51
203
  tools,
52
- trace,
53
- model: options.model || constants_1.DEFAULT_MODEL,
54
- provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
55
- providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
56
204
  modelParameters: {
57
205
  ...constants_1.DEFAULT_MODEL_PARAMETERS,
58
206
  ...options.modelParameters,
@@ -92,6 +240,7 @@ async function browsingAgent(task, page, options) {
92
240
  }
93
241
  }
94
242
  }
243
+ await page.close();
95
244
  const code = actions.generateCode();
96
245
  trace.update({ input: { task }, output: { code } });
97
246
  logger.success("Successfully generated code for the given task");
@@ -14,10 +14,11 @@ export declare function readPlaywrightConfig(): Promise<PlaywrightTestConfig>;
14
14
  * @returns
15
15
  */
16
16
  export declare function detectProjectName(testFilePath: string, playwrightConfig: PlaywrightTestConfig): Promise<string>;
17
- export declare function getPromptForNextAction({ pageSnapshot, task, previousActions, lastActionErrors, }: {
17
+ export declare function getPromptForNextAction({ pageSnapshot, task, previousActions, lastActionErrors, promptType, }: {
18
18
  pageSnapshot: string;
19
19
  task: string;
20
20
  previousActions: string[];
21
21
  lastActionErrors: string[];
22
+ promptType?: string;
22
23
  }): Promise<import("openai/resources/index.mjs").ChatCompletionMessageParam[]>;
23
24
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AASvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAED,wBAAsB,2BAA2B,CAAC,SAAS,EAAE,aAAa,iBAqCzE;AAiBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBASxD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,QA4BnD;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAM1E;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CAkDjB;AAED,wBAAsB,sBAAsB,CAAC,EAC3C,YAAiB,EACjB,IAAS,EACT,eAAoB,EACpB,gBAAqB,GACtB,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B,8EASA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AASvD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAED,wBAAsB,2BAA2B,CAAC,SAAS,EAAE,aAAa,iBAqCzE;AAiBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBASxD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,QA4BnD;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAM1E;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CAkDjB;AAED,wBAAsB,sBAAsB,CAAC,EAC3C,YAAiB,EACjB,IAAS,EACT,eAAoB,EACpB,gBAAqB,EACrB,UAAyC,GAC1C,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,8EASA"}
@@ -155,9 +155,9 @@ async function detectProjectName(testFilePath, playwrightConfig) {
155
155
  return project;
156
156
  }
157
157
  exports.detectProjectName = detectProjectName;
158
- async function getPromptForNextAction({ pageSnapshot = "", task = "", previousActions = [], lastActionErrors = [], }) {
158
+ async function getPromptForNextAction({ pageSnapshot = "", task = "", previousActions = [], lastActionErrors = [], promptType = "browsing-agent-next-action", }) {
159
159
  const previousActionsStr = previousActions.join("\n\n ---- \n\n");
160
- const prompt = await (0, llm_1.getPrompt)("browsing-agent-next-action", {
160
+ const prompt = await (0, llm_1.getPrompt)(promptType, {
161
161
  pageSnapshot,
162
162
  previousActionsStr,
163
163
  task,
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/run.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,EAAE,CAAC,CAmJrB"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/codegen/run.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE7D,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,QAAQ,EAAE,CAAC,CAgJrB"}
@@ -50,12 +50,14 @@ async function generateTest(testCase, file, options) {
50
50
  scenarioFile: file,
51
51
  });
52
52
  promptSpan.end({ output: { instruction } });
53
- const firstShotMessage = await (0, llm_1.getLLMResult)({
54
- messages: instruction,
53
+ const llm = new llm_1.LLM({
55
54
  trace,
56
- model: options.model || constants_1.DEFAULT_MODEL,
57
55
  provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
56
+ defaultModel: options.model || constants_1.DEFAULT_MODEL,
58
57
  providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
58
+ });
59
+ const firstShotMessage = await llm.createChatCompletion({
60
+ messages: instruction,
59
61
  modelParameters: {
60
62
  ...constants_1.DEFAULT_MODEL_PARAMETERS,
61
63
  ...options.modelParameters,
@@ -112,12 +114,8 @@ async function generateTest(testCase, file, options) {
112
114
  scenaioName: testCase.name,
113
115
  });
114
116
  promptSpan.end({ output: { instruction } });
115
- const message = await (0, llm_1.getLLMResult)({
117
+ const message = await llm.createChatCompletion({
116
118
  messages: instruction,
117
- trace,
118
- model: options.model || constants_1.DEFAULT_MODEL,
119
- provider: options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER,
120
- providerApiKey: constants_1.MODEL_API_KEYS[options.modelProvider || constants_1.DEFAULT_MODEL_PROVIDER],
121
119
  modelParameters: {
122
120
  ...constants_1.DEFAULT_MODEL_PARAMETERS,
123
121
  ...options.modelParameters,
@@ -0,0 +1,7 @@
1
+ import { LLM, TraceClient } from "@empiricalrun/llm";
2
+ import { Page } from "playwright";
3
+ import { TestGenConfigOptions } from "../../types";
4
+ type BrowsingAgentOptions = Partial<TestGenConfigOptions>;
5
+ export declare function masterAgent(task: string, page: Page, executedActions: string[], trace: TraceClient, llm: LLM, options: BrowsingAgentOptions): Promise<any>;
6
+ export {};
7
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/master/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAKlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnD,KAAK,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAE1D,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,eAAe,EAAE,MAAM,EAAE,EACzB,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,EAAE,oBAAoB,gBAgE9B"}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.masterAgent = void 0;
4
+ const llm_1 = require("@empiricalrun/llm");
5
+ const done_1 = require("../../actions/done");
6
+ const next_task_1 = require("../../actions/next-task");
7
+ const constants_1 = require("../../constants");
8
+ async function masterAgent(task, page, executedActions, trace, llm, options) {
9
+ trace.update({ input: { task } });
10
+ const promptSpan = trace.span({ name: "page-prompt" });
11
+ const buffer = await page.screenshot({ fullPage: true });
12
+ const pageScreenshot = `data:image/png;base64,${buffer.toString("base64")}`;
13
+ const promptMessages = await (0, llm_1.getPrompt)("test-gen", {
14
+ task,
15
+ executedActions: executedActions.map((a) => a).join("\n"),
16
+ pageUrl: page.url(),
17
+ });
18
+ // assuming there is only one user message in the prompt. if there is a change in langfuse prompt format, this will need to be updated
19
+ const userMessage = promptMessages.filter((m) => m.role === "user")[0];
20
+ const systemMessage = promptMessages.filter((m) => m.role === "system")[0];
21
+ userMessage.content = [
22
+ {
23
+ type: "text",
24
+ text: userMessage.content,
25
+ },
26
+ {
27
+ type: "image_url",
28
+ image_url: {
29
+ url: pageScreenshot,
30
+ },
31
+ },
32
+ ];
33
+ const messages = [
34
+ systemMessage,
35
+ userMessage,
36
+ ];
37
+ const tools = [next_task_1.NextTaskAction.schema, (0, done_1.doneActionGenerator)(page).schema];
38
+ promptSpan.end({ output: { messages } });
39
+ const completion = await llm.createChatCompletion({
40
+ messages,
41
+ modelParameters: {
42
+ ...constants_1.DEFAULT_MODEL_PARAMETERS,
43
+ ...options.modelParameters,
44
+ tool_choice: "required",
45
+ },
46
+ trace,
47
+ // @ts-ignore
48
+ tools,
49
+ });
50
+ let output;
51
+ const toolCall = completion?.tool_calls?.[0];
52
+ if (toolCall) {
53
+ if (toolCall.function.name === "task_done") {
54
+ output = {
55
+ action: "",
56
+ isDone: true,
57
+ reason: JSON.parse(toolCall.function.arguments).reason,
58
+ };
59
+ }
60
+ else {
61
+ output = {
62
+ isDone: false,
63
+ action: JSON.parse(toolCall.function.arguments).action,
64
+ reason: JSON.parse(toolCall.function.arguments).reason,
65
+ };
66
+ }
67
+ }
68
+ trace.update({ input: { task }, output: { output } });
69
+ return output;
70
+ }
71
+ exports.masterAgent = masterAgent;
@@ -0,0 +1,14 @@
1
+ import { LLM, TraceClient } from "@empiricalrun/llm";
2
+ /**
3
+ * This agent is used to verify whether the task is done basis the conversation history
4
+ */
5
+ export declare function verificationAgent({ llm, trace, task, conversation, }: {
6
+ llm: LLM;
7
+ trace?: TraceClient;
8
+ conversation: string[];
9
+ task: string;
10
+ }): Promise<{
11
+ isDone: boolean;
12
+ reason: string;
13
+ }>;
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/verification/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,GAAG,EACH,KAAK,EACL,IAAI,EACJ,YAAY,GACb,EAAE;IACD,GAAG,EAAE,GAAG,CAAC;IACT,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;;;GA4DA"}
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verificationAgent = void 0;
4
+ /**
5
+ * This agent is used to verify whether the task is done basis the conversation history
6
+ */
7
+ async function verificationAgent({ llm, trace, task, conversation, }) {
8
+ const response = await llm.createChatCompletion({
9
+ trace,
10
+ messages: [
11
+ {
12
+ role: "system",
13
+ content: "Given a conversation and a task, your task is to analyse the conversation and tell if the task is completed. If not, you need to tell what is not completed and suggest next steps to complete the task.",
14
+ },
15
+ {
16
+ role: "user",
17
+ content: `
18
+ Task: ${task}
19
+
20
+ Conversation:
21
+ ${conversation.join("\n")}
22
+ `,
23
+ },
24
+ ],
25
+ tools: [
26
+ {
27
+ type: "function",
28
+ function: {
29
+ name: "task_done",
30
+ description: "end the task by calling this method",
31
+ parameters: {
32
+ type: "object",
33
+ properties: {
34
+ isDone: {
35
+ type: "boolean",
36
+ description: "whether the task is done",
37
+ },
38
+ reason: {
39
+ type: "string",
40
+ description: "reason for declaring the task is complete",
41
+ },
42
+ },
43
+ required: ["isDone", "reason"],
44
+ },
45
+ },
46
+ },
47
+ ],
48
+ model: "gpt-4o",
49
+ modelParameters: {
50
+ tool_choice: "required",
51
+ },
52
+ });
53
+ const toolCallResp = (response?.tool_calls || [])[0];
54
+ if (toolCallResp) {
55
+ const toolCall = JSON.parse(toolCallResp.function.arguments);
56
+ return {
57
+ isDone: toolCall.isDone,
58
+ reason: toolCall.reason,
59
+ };
60
+ }
61
+ return {
62
+ isDone: false,
63
+ reason: "LLM failed to generate a valid response",
64
+ };
65
+ }
66
+ exports.verificationAgent = verificationAgent;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/logger/index.ts"],"names":[],"mappings":"AAKA,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAkB;gBACzB,EAAE,WAAkB,EAAE;;KAAK;IAIvC,OAAO,CAAC,aAAa;IAKrB,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAK9C,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAK/C,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAKlD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAKhD,YAAY;CAGb"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/logger/index.ts"],"names":[],"mappings":"AAKA,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAkB;gBACzB,EAAE,WAAkB,EAAE;;KAAK;IAIvC,OAAO,CAAC,aAAa;IASrB,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAK9C,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAK/C,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAKlD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAKhD,YAAY;CAGb"}
@@ -11,7 +11,9 @@ class CustomLogger {
11
11
  }
12
12
  logToReporter(message) {
13
13
  if (this.useReporter) {
14
- (0, reporter_2.getReporter)()?.report(new reporter_1.ProcessLogMessageBuilder({ message: message }));
14
+ (async () => {
15
+ await (0, reporter_2.getReporter)()?.report(new reporter_1.ProcessLogMessageBuilder({ message: message }));
16
+ })();
15
17
  }
16
18
  }
17
19
  log(message, ...optionalParams) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAWlC,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,iBAsBnE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAWlC,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,iBA0BnE"}
package/dist/index.js CHANGED
@@ -24,7 +24,10 @@ async function createTest(task, page, test) {
24
24
  });
25
25
  const fileService = new client_1.default(Number(port));
26
26
  test.setTimeout(900000);
27
- const code = await (0, browsing_1.browsingAgent)(task, page, {
27
+ const agent = testGenConfig.options?.agent === "browser"
28
+ ? browsing_1.browsingAgent
29
+ : browsing_1.browsingAgentUsingMasterAgent;
30
+ const code = await agent(task, page, {
28
31
  htmlSanitize: {
29
32
  disallowedStrings: ["v-data-table__td v-data-table-column--align-start"],
30
33
  },
@@ -6,7 +6,7 @@ export type FileContent = {
6
6
  content: string;
7
7
  };
8
8
  export type TestGenConfigOptions = {
9
- agent: "code" | "browser";
9
+ agent: "code" | "browser" | "master";
10
10
  model: LLMModel;
11
11
  modelProvider: LLMProvider;
12
12
  modelParameters?: ModelParameters;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,aAAa,GAAG,YAAY,CAAC;KAC3C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;AAE/D,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAEtE,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC/E,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACrC,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,EAAE,WAAW,CAAC;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,QAAQ,EAAE;QACR,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,aAAa,GAAG,YAAY,CAAC;KAC3C,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;AAE/D,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC;AAEtE,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC;CAC/E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,QAClB,MAAM,YACF;IACP,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B,WAuBF,CAAC"}
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/utils/html.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,QAClB,MAAM,YACF;IACP,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B,WAwBF,CAAC"}
@@ -18,6 +18,7 @@ const sanitizeHtml = (str, options = {}) => {
18
18
  "h1",
19
19
  "h2",
20
20
  "h3",
21
+ "label",
21
22
  ]),
22
23
  allowedAttributes: false,
23
24
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-gen",
3
- "version": "0.20.4",
3
+ "version": "0.21.0",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -40,7 +40,7 @@
40
40
  "slugify": "^1.6.6",
41
41
  "tsx": "^4.16.2",
42
42
  "typescript": "^5.3.3",
43
- "@empiricalrun/llm": "^0.4.1",
43
+ "@empiricalrun/llm": "^0.4.3",
44
44
  "@empiricalrun/reporter": "^0.14.1"
45
45
  },
46
46
  "devDependencies": {