@empiricalrun/test-gen 0.56.0 → 0.56.2

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,28 @@
1
1
  # @empiricalrun/test-gen
2
2
 
3
+ ## 0.56.2
4
+
5
+ ### Patch Changes
6
+
7
+ - d5828e1: feat: including toolCalling in langfuse trace
8
+ - eb84f66: fix: Update environment variable handling
9
+ - 40f6470: feat: added tool execution service
10
+ - f49b645: feat: Add tool response API endpoint
11
+ - Updated dependencies [f8cc82d]
12
+ - Updated dependencies [f49b645]
13
+ - @empiricalrun/llm@0.15.2
14
+ - @empiricalrun/test-run@0.8.3
15
+
16
+ ## 0.56.1
17
+
18
+ ### Patch Changes
19
+
20
+ - d05bb69: chore: remove fs-extra
21
+ - e1e2564: fix: avoid global promisify calls
22
+ - 803f61f: fix: run type checks for file inserts in text editor tools
23
+ - Updated dependencies [d05bb69]
24
+ - @empiricalrun/test-run@0.8.2
25
+
3
26
  ## 0.56.0
4
27
 
5
28
  ### Minor Changes
@@ -5,13 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generateTestsUsingMasterAgent = void 0;
7
7
  const detect_port_1 = __importDefault(require("detect-port"));
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const fs_1 = __importDefault(require("fs"));
9
9
  const web_1 = require("../../bin/utils/platform/web");
10
10
  const server_1 = require("../../file/server");
11
11
  const exec_1 = require("../../utils/exec");
12
12
  const utils_1 = require("./utils");
13
13
  async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, pwProjectsFilter, testGenToken, repoDir, editFileWithGeneratedCode, }) {
14
- if (!fs_extra_1.default.existsSync(testFilePath)) {
14
+ if (!fs_1.default.existsSync(testFilePath)) {
15
15
  throw new Error(`File for master agent to run not found: ${testFilePath}`);
16
16
  }
17
17
  const pm = new exec_1.ProcessManager();
@@ -69,9 +69,9 @@ async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, p
69
69
  // clean up the file if there is any error
70
70
  if (isError) {
71
71
  try {
72
- const fileContent = await fs_extra_1.default.readFile(filePathToUpdate, "utf-8");
72
+ const fileContent = fs_1.default.readFileSync(filePathToUpdate, "utf-8");
73
73
  const updatedContent = (0, web_1.replaceCreateTestWithNewCode)(filePathToUpdate, fileContent, "");
74
- await fs_extra_1.default.writeFile(filePathToUpdate, updatedContent, "utf-8");
74
+ fs_1.default.writeFileSync(filePathToUpdate, updatedContent, "utf-8");
75
75
  await (0, web_1.lintErrors)(filePathToUpdate);
76
76
  }
77
77
  catch (e) {
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAIxE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAwBvD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAiFD,wBAAsB,yBAAyB,CAAC,EAC9C,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,iBA2BA;AAED,wBAAsB,cAAc,CAAC,EACnC,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB,iBAoBA;AAED,wBAAsB,yBAAyB,CAAC,EAC9C,QAAQ,EACR,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDlB;AAyBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBA2HxD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,CA0B/B;AAWD,wBAAsB,oBAAoB,CACxC,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,EACtC,gBAAgB,GAAE,MAAM,EAAU,GACjC,OAAO,CAAC,MAAM,CAAC,CA+CjB;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM;IACrC,OAAO,CAAC,aAAa,CAAqB;YAE5B,mBAAmB;YAUnB,gBAAgB;IAsBjB,OAAO;IAoBb,SAAS;CAKjB"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAIxE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAwBvD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,MAAM,CAKhD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,UAIvD;AAiFD,wBAAsB,yBAAyB,CAAC,EAC9C,YAAY,EACZ,YAAY,EACZ,cAAc,GACf,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,iBA2BA;AAED,wBAAsB,cAAc,CAAC,EACnC,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB,iBAoBA;AAED,wBAAsB,yBAAyB,CAAC,EAC9C,QAAQ,EACR,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDlB;AAyBD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,IAAI,iBA2HxD;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,CAAC,CA2B/B;AAWD,wBAAsB,oBAAoB,CACxC,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,oBAAoB,EACtC,gBAAgB,GAAE,MAAM,EAAU,GACjC,OAAO,CAAC,MAAM,CAAC,CA+CjB;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM;IACrC,OAAO,CAAC,aAAa,CAAqB;YAE5B,mBAAmB;YAUnB,gBAAgB;IAsBjB,OAAO;IAoBb,SAAS;CAKjB"}
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TeardownManager = exports.detectProjectName = exports.getValidProjectNames = exports.readPlaywrightConfig = exports.injectPwLocatorGenerator = exports.prepareFileForMasterAgent = exports.markTestAsOnly = exports.replaceTodoWithCreateTest = exports.prepareBrowsingAgentTask = exports.isRegExp = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
7
+ const fs_1 = __importDefault(require("fs"));
8
8
  const minimatch_1 = require("minimatch");
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const ts_morph_1 = require("ts-morph");
@@ -12,7 +12,7 @@ const ts_morph_1 = require("ts-morph");
12
12
  let tsxImport = null;
13
13
  const logger_1 = require("../../bin/logger");
14
14
  const context_1 = require("../../bin/utils/context");
15
- const fs_1 = require("../../bin/utils/fs");
15
+ const fs_2 = require("../../bin/utils/fs");
16
16
  const web_1 = require("../../bin/utils/platform/web");
17
17
  const create_test_block_1 = require("../codegen/create-test-block");
18
18
  const fix_ts_errors_1 = require("../codegen/fix-ts-errors");
@@ -33,10 +33,10 @@ async function addImportForCreateTest(testFilePath) {
33
33
  // Instead of using "@empiricalrun/test-gen", we use the local dist file
34
34
  // This is to avoid assuming that the test-gen package is installed in the project
35
35
  const importSource = path_1.default.join(__dirname, "../../../dist/index.js");
36
- if (!fs_extra_1.default.existsSync(importSource)) {
36
+ if (!fs_1.default.existsSync(importSource)) {
37
37
  throw new Error(`createTest import source not found at ${importSource}`);
38
38
  }
39
- await fs_extra_1.default.writeFile(testFilePath, (0, web_1.addNewImport)(await fs_extra_1.default.readFile(testFilePath, "utf-8"), ["createTest"], importSource));
39
+ fs_1.default.writeFileSync(testFilePath, (0, web_1.addNewImport)(fs_1.default.readFileSync(testFilePath, "utf-8"), ["createTest"], importSource));
40
40
  }
41
41
  async function prepareFileForUpdateScenario({ testCase, specPath, trace, }) {
42
42
  const { name, suites } = testCase;
@@ -62,7 +62,7 @@ async function prepareFileForUpdateScenario({ testCase, specPath, trace, }) {
62
62
  },
63
63
  });
64
64
  const scopeVariables = await (0, lexical_scoped_vars_1.getLexicalScopedVars)({
65
- file: await fs_extra_1.default.readFile(createTestFilePath, "utf-8"),
65
+ file: fs_1.default.readFileSync(createTestFilePath, "utf-8"),
66
66
  referencePoint: "await createTest",
67
67
  trace: fetchScopeVariablesSpan,
68
68
  });
@@ -92,7 +92,7 @@ async function prepareFileForUpdateScenario({ testCase, specPath, trace, }) {
92
92
  async function replaceTodoWithCreateTest({ testFilePath, testCaseName, testCaseSuites, }) {
93
93
  // This method is an alternative to prepareFileForUpdateScenario
94
94
  // TODO: Does not support scoped variables and updates in POM files
95
- const fileContent = await fs_extra_1.default.readFile(testFilePath, "utf-8");
95
+ const fileContent = fs_1.default.readFileSync(testFilePath, "utf-8");
96
96
  const todoRegex = /\/\/ TODO\(agent(?:\s+on\s+(\w+))?\):\s*(.*)/;
97
97
  const todoMatch = fileContent.match(todoRegex);
98
98
  if (!todoMatch) {
@@ -100,7 +100,7 @@ async function replaceTodoWithCreateTest({ testFilePath, testCaseName, testCaseS
100
100
  }
101
101
  const [, pageVarName] = todoMatch;
102
102
  const pageVariable = pageVarName || "page"; // Default to "page" if not specified
103
- await fs_extra_1.default.writeFile(testFilePath, fileContent.replace(todoRegex, (_, __, todoText) => `await createTest("${todoText.replace(/"/g, '\\"')}", ${pageVariable});`));
103
+ fs_1.default.writeFileSync(testFilePath, fileContent.replace(todoRegex, (_, __, todoText) => `await createTest("${todoText.replace(/"/g, '\\"')}", ${pageVariable});`));
104
104
  await addImportForCreateTest(testFilePath);
105
105
  await markTestAsOnly({
106
106
  testCaseName,
@@ -110,7 +110,7 @@ async function replaceTodoWithCreateTest({ testFilePath, testCaseName, testCaseS
110
110
  }
111
111
  exports.replaceTodoWithCreateTest = replaceTodoWithCreateTest;
112
112
  async function markTestAsOnly({ testCaseName, testCaseSuites, specPath, }) {
113
- const testFileContent = await fs_extra_1.default.readFile(specPath, "utf-8");
113
+ const testFileContent = fs_1.default.readFileSync(specPath, "utf-8");
114
114
  const { testBlock, testNode } = (0, web_1.getTypescriptTestBlock)({
115
115
  scenarioName: testCaseName,
116
116
  content: testFileContent,
@@ -121,7 +121,7 @@ async function markTestAsOnly({ testCaseName, testCaseSuites, specPath, }) {
121
121
  // add test.only / describe.only to the spec file so that only that block is executed
122
122
  if (!isFileMarkedSerial) {
123
123
  const updatedTestFileContent = newContentsWithTestOnly(testFileContent, testBlock, testBlock, parentDescribe?.getText() || "");
124
- await fs_extra_1.default.writeFile(specPath, updatedTestFileContent);
124
+ fs_1.default.writeFileSync(specPath, updatedTestFileContent);
125
125
  }
126
126
  }
127
127
  exports.markTestAsOnly = markTestAsOnly;
@@ -133,17 +133,17 @@ async function prepareFileForMasterAgent({ testCase, specPath, trace, }) {
133
133
  const { name, suites } = testCase;
134
134
  // check if the spec file exists
135
135
  // if no then create a new file with test and expect imports
136
- if (!fs_extra_1.default.existsSync(specPath)) {
136
+ if (!fs_1.default.existsSync(specPath)) {
137
137
  const fileCreateSpan = prepareFileSpan?.span({
138
138
  name: "create-file",
139
139
  input: { specPath },
140
140
  });
141
- await fs_extra_1.default.createFile(specPath);
141
+ fs_1.default.writeFileSync(specPath, "");
142
142
  const fileContentWithImports = (0, web_1.addNewImport)("", ["test", "expect"], (0, web_1.getFixtureImportPath)(specPath));
143
- await fs_extra_1.default.writeFile(specPath, fileContentWithImports, "utf-8");
143
+ fs_1.default.writeFileSync(specPath, fileContentWithImports, "utf-8");
144
144
  fileCreateSpan?.end({ output: { specPath, fileContentWithImports } });
145
145
  }
146
- const existingContents = await fs_extra_1.default.readFile(specPath, "utf-8");
146
+ const existingContents = fs_1.default.readFileSync(specPath, "utf-8");
147
147
  const { testBlock } = (0, web_1.getTypescriptTestBlock)({
148
148
  scenarioName: name,
149
149
  suites,
@@ -155,13 +155,13 @@ async function prepareFileForMasterAgent({ testCase, specPath, trace, }) {
155
155
  testCase,
156
156
  file: specPath,
157
157
  });
158
- await fs_extra_1.default.writeFile(specPath, `${existingContents} \n\n ${newTestBlock}`, "utf-8");
158
+ fs_1.default.writeFileSync(specPath, `${existingContents} \n\n ${newTestBlock}`, "utf-8");
159
159
  const updatedContent = (0, web_1.injectCodeSnippetBySuiteChain)({
160
160
  testFileContent: existingContents,
161
161
  suites: testCase.suites,
162
162
  codeSnippet: `\n\n${newTestBlock}`,
163
163
  });
164
- await fs_extra_1.default.writeFile(specPath, updatedContent, "utf-8");
164
+ fs_1.default.writeFileSync(specPath, updatedContent, "utf-8");
165
165
  }
166
166
  const updatePath = await prepareFileForUpdateScenario({
167
167
  testCase,
@@ -190,7 +190,7 @@ async function injectPwLocatorGenerator(page) {
190
190
  pathToInstalledTestGen = process.cwd();
191
191
  }
192
192
  const annotateElementPath = path_1.default.join(pathToInstalledTestGen, "dist", "browser-injected-scripts", "annotate-elements.js");
193
- if (!fs_extra_1.default.existsSync(annotateElementPath)) {
193
+ if (!fs_1.default.existsSync(annotateElementPath)) {
194
194
  throw new Error(`annotate-elements.js not found at path: ${annotateElementPath}`);
195
195
  }
196
196
  const remoteScriptResponses = await Promise.all([
@@ -199,7 +199,7 @@ async function injectPwLocatorGenerator(page) {
199
199
  ].map((url) => fetch(url)));
200
200
  const scripts = await Promise.all([
201
201
  ...remoteScriptResponses.map((r) => r.text()),
202
- fs_extra_1.default.readFile(annotateElementPath, "utf-8"),
202
+ fs_1.default.readFileSync(annotateElementPath, "utf-8"),
203
203
  ]);
204
204
  page.on("load", async () => {
205
205
  try {
@@ -307,11 +307,12 @@ async function readPlaywrightConfig(repoDir) {
307
307
  tsxImport = module;
308
308
  })
309
309
  .catch((err) => {
310
- console.error("Failed to import tsx:", err);
310
+ console.error("Failed to import tsx: --->", err.message);
311
311
  });
312
312
  }
313
313
  if (!tsxImport) {
314
- throw new Error("tsx module not available");
314
+ console.error("tsx module not available");
315
+ return {};
315
316
  }
316
317
  const [lastDir] = repoDir.split("/").reverse();
317
318
  const playwrightConfig = (await tsxImport.require("./playwright.config.ts", `${repoDir}/${lastDir}`)).default;
@@ -395,7 +396,7 @@ class TeardownManager {
395
396
  teardownFiles = [];
396
397
  async getAllTeardownFiles() {
397
398
  const teardownFileRegex = /.*\.teardown\.ts/;
398
- const teardownFiles = await (0, fs_1.readFilesInDirectory)(this.directory, (fileName) => teardownFileRegex.test(fileName));
399
+ const teardownFiles = await (0, fs_2.readFilesInDirectory)(this.directory, (fileName) => teardownFileRegex.test(fileName));
399
400
  return teardownFiles;
400
401
  }
401
402
  async skipTeardownFile(filePath) {
@@ -431,7 +432,7 @@ class TeardownManager {
431
432
  }
432
433
  unskipAll() {
433
434
  this.teardownFiles.forEach(({ filePath, content }) => {
434
- fs_extra_1.default.writeFileSync(filePath, content, "utf-8");
435
+ fs_1.default.writeFileSync(filePath, content, "utf-8");
435
436
  });
436
437
  }
437
438
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/agent-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EACL,UAAU,EAIX,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAgBhE,wBAAsB,aAAa,CAAC,EAClC,SAAS,EACT,aAAa,EACb,QAAQ,EACR,KAAK,EACL,eAAe,GAChB,EAAE;IACD,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;IAC3B,aAAa,EAAE,mBAAmB,CAAC;IACnC,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,iBAoCA"}
1
+ {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/agent-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAmB,MAAM,wBAAwB,CAAC;AAGrE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAgBhE,wBAAsB,aAAa,CAAC,EAClC,SAAS,EACT,aAAa,EACb,QAAQ,EACR,KAAK,EACL,eAAe,GAChB,EAAE;IACD,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;IAC3B,aAAa,EAAE,mBAAmB,CAAC;IACnC,eAAe,EAAE,eAAe,CAAC;IACjC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,iBAoCA"}
@@ -24,9 +24,8 @@ async function chatAgentLoop({ chatModel, selectedModel, reporter, trace, toolCa
24
24
  const { tools } = await toolCallService.getTools();
25
25
  while (!chatModel.askUserForInput) {
26
26
  const toolCalls = chatModel.getPendingToolCalls();
27
- console.log("toolCalls", toolCalls);
28
27
  if (toolCalls.length) {
29
- const toolResults = await toolCallService.execute(toolCalls, isRemote);
28
+ const toolResults = await toolCallService.execute(toolCalls, isRemote, trace);
30
29
  if (isRemote) {
31
30
  log(`Tool call remote execution in progress`);
32
31
  break;
@@ -1,8 +1,10 @@
1
1
  import { IChatModel } from "@empiricalrun/llm/chat";
2
2
  import { chatAgentLoop } from "./agent-loop";
3
3
  import { createChatModel } from "./model";
4
+ import * as State from "./state";
4
5
  import { ChatStateOnDisk } from "./state";
5
6
  import { ReporterFunction, SupportedChatModels } from "./types";
6
- export { chatAgentLoop, createChatModel };
7
+ declare const createChatState: typeof State.createChatState, createChatStateForMessages: typeof State.createChatStateForMessages, chatStateFromModel: typeof State.chatStateFromModel, loadChatState: typeof State.loadChatState, saveToDisk: typeof State.saveToDisk, CURRENT_CHAT_STATE_VERSION: string;
8
+ export { chatAgentLoop, chatStateFromModel, createChatModel, createChatState, createChatStateForMessages, CURRENT_CHAT_STATE_VERSION, loadChatState, saveToDisk, };
7
9
  export type { ChatStateOnDisk, IChatModel, ReporterFunction, SupportedChatModels, };
8
10
  //# sourceMappingURL=exports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/exports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEhE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC;AAE1C,YAAY,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,mBAAmB,GACpB,CAAC"}
1
+ {"version":3,"file":"exports.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/exports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,KAAK,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEhE,QAAA,MACE,eAAe,gCACf,0BAA0B,2CAC1B,kBAAkB,mCAClB,aAAa,8BACb,UAAU,2BACV,0BAA0B,QACnB,CAAC;AAEV,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,0BAA0B,EAC1B,0BAA0B,EAC1B,aAAa,EACb,UAAU,GACX,CAAC;AAEF,YAAY,EACV,eAAe,EACf,UAAU,EACV,gBAAgB,EAChB,mBAAmB,GACpB,CAAC"}
@@ -1,7 +1,38 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createChatModel = exports.chatAgentLoop = void 0;
26
+ exports.saveToDisk = exports.loadChatState = exports.CURRENT_CHAT_STATE_VERSION = exports.createChatStateForMessages = exports.createChatState = exports.createChatModel = exports.chatStateFromModel = exports.chatAgentLoop = void 0;
4
27
  const agent_loop_1 = require("./agent-loop");
5
28
  Object.defineProperty(exports, "chatAgentLoop", { enumerable: true, get: function () { return agent_loop_1.chatAgentLoop; } });
6
29
  const model_1 = require("./model");
7
30
  Object.defineProperty(exports, "createChatModel", { enumerable: true, get: function () { return model_1.createChatModel; } });
31
+ const State = __importStar(require("./state"));
32
+ const { createChatState, createChatStateForMessages, chatStateFromModel, loadChatState, saveToDisk, CURRENT_CHAT_STATE_VERSION, } = State;
33
+ exports.createChatState = createChatState;
34
+ exports.createChatStateForMessages = createChatStateForMessages;
35
+ exports.chatStateFromModel = chatStateFromModel;
36
+ exports.loadChatState = loadChatState;
37
+ exports.saveToDisk = saveToDisk;
38
+ exports.CURRENT_CHAT_STATE_VERSION = CURRENT_CHAT_STATE_VERSION;
@@ -4,22 +4,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getRepoContext = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
7
+ const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const repo_tree_1 = require("../../utils/repo-tree");
10
10
  const utils_1 = require("../browsing/utils");
11
11
  async function getAllMarkdownFiles() {
12
12
  const dir = path_1.default.join(process.cwd(), ".empiricalrun");
13
- if (!fs_extra_1.default.existsSync(dir)) {
13
+ if (!fs_1.default.existsSync(dir)) {
14
14
  return [];
15
15
  }
16
- const files = await fs_extra_1.default.readdir(dir);
16
+ const files = fs_1.default.readdirSync(dir);
17
17
  return files
18
18
  .filter((file) => file.endsWith(".md"))
19
19
  .map((file) => {
20
20
  return {
21
21
  name: file,
22
- content: fs_extra_1.default.readFileSync(path_1.default.join(dir, file), "utf8"),
22
+ content: fs_1.default.readFileSync(path_1.default.join(dir, file), "utf8"),
23
23
  };
24
24
  });
25
25
  }
@@ -3,7 +3,7 @@ import { SupportedChatModels } from "./types";
3
3
  export declare const CURRENT_CHAT_STATE_VERSION = "20250327.1";
4
4
  export declare const CHAT_STATE_PATH: string;
5
5
  export type ChatStateOnDisk<T> = {
6
- version: typeof CURRENT_CHAT_STATE_VERSION;
6
+ version: string;
7
7
  model: SupportedChatModels;
8
8
  messages: T[];
9
9
  };
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,eAAO,MAAM,0BAA0B,eAAe,CAAC;AAEvD,eAAO,MAAM,eAAe,QAI3B,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAC/B,OAAO,EAAE,OAAO,0BAA0B,CAAC;IAC3C,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,CAAC,EAAE,CAAC;CACf,CAAC;AAEF,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,eAAe,CAAC,GAAG,CAAC,EACnC,aAAa,EAAE,mBAAmB,4BAMnC;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAC1C,QAAQ,EAAE,GAAG,EACb,aAAa,EAAE,mBAAmB,GACjC,eAAe,CAAC,CAAC,CAAC,CAOpB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EACxB,aAAa,EAAE,mBAAmB,4BAGnC;AAED,wBAAgB,aAAa,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,CAajE;AAED,wBAAgB,UAAU,CAAC,CAAC,EAC1B,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAClB,aAAa,EAAE,mBAAmB,QAsBnC"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,eAAO,MAAM,0BAA0B,eAAe,CAAC;AAEvD,eAAO,MAAM,eAAe,QAI3B,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,QAAQ,EAAE,CAAC,EAAE,CAAC;CACf,CAAC;AAEF,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,eAAe,CAAC,GAAG,CAAC,EACnC,aAAa,EAAE,mBAAmB,4BAMnC;AAED,wBAAgB,0BAA0B,CAAC,CAAC,EAC1C,QAAQ,EAAE,GAAG,EACb,aAAa,EAAE,mBAAmB,GACjC,eAAe,CAAC,CAAC,CAAC,CAOpB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,EACxB,aAAa,EAAE,mBAAmB,4BAGnC;AAED,wBAAgB,aAAa,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,GAAG,SAAS,CAajE;AAED,wBAAgB,UAAU,CAAC,CAAC,EAC1B,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAClB,aAAa,EAAE,mBAAmB,QAsBnC"}
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.validateAndFixTypescriptErrors = void 0;
7
7
  const llm_1 = require("@empiricalrun/llm");
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const fs_1 = __importDefault(require("fs"));
9
9
  const logger_1 = require("../../bin/logger");
10
10
  const web_1 = require("../../bin/utils/platform/web");
11
11
  const constants_1 = require("../../constants");
@@ -21,7 +21,7 @@ async function validateAndFixTypescriptErrors({ trace, logger = new logger_1.Cus
21
21
  const maxIteration = 2;
22
22
  let counter = 0;
23
23
  while (errors.length > 0) {
24
- const fileContent = await fs_extra_1.default.readFile(file, "utf-8");
24
+ const fileContent = fs_1.default.readFileSync(file, "utf-8");
25
25
  counter += 1;
26
26
  if (counter > maxIteration) {
27
27
  trace?.event({ name: "code-fix-iteration-max-out" });
@@ -58,7 +58,7 @@ async function validateAndFixTypescriptErrors({ trace, logger = new logger_1.Cus
58
58
  });
59
59
  const response = message?.content || "";
60
60
  const readWriteFileSpan = trace?.span({ name: "write-to-file" });
61
- await fs_extra_1.default.writeFile(file, response, "utf-8");
61
+ fs_1.default.writeFileSync(file, response, "utf-8");
62
62
  readWriteFileSpan?.end({ output: { response } });
63
63
  trace?.event({ name: "lint-file" });
64
64
  await (0, web_1.lintErrors)(file);
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generateCodeAndApplyChanges = exports.systemPromptBuilderForRepoEdit = void 0;
7
7
  const llm_1 = require("@empiricalrun/llm");
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = require("path");
10
10
  const constants_1 = require("../../constants");
11
11
  const types_1 = require("./types");
@@ -348,8 +348,8 @@ async function generateCodeAndApplyChanges({ task, trace, logger, getRelevantFil
348
348
  newCode: args.code,
349
349
  reason: args.reason,
350
350
  });
351
- await fs_extra_1.default.mkdir((0, path_1.dirname)(args.filePath), { recursive: true });
352
- await fs_extra_1.default.writeFile(args.filePath, args.code, "utf-8");
351
+ fs_1.default.mkdirSync((0, path_1.dirname)(args.filePath), { recursive: true });
352
+ fs_1.default.writeFileSync(args.filePath, args.code, "utf-8");
353
353
  console.log(`Created file: ${args.filePath}`);
354
354
  })();
355
355
  }));
@@ -360,7 +360,7 @@ async function generateCodeAndApplyChanges({ task, trace, logger, getRelevantFil
360
360
  // Filter out the tool calls which are for replacing code in existing files
361
361
  const fileChanges = strReplaceToolCalls
362
362
  .map((toolCall) => JSON.parse(toolCall.function.arguments))
363
- .filter((f) => f.filePath && fs_extra_1.default.existsSync(f.filePath));
363
+ .filter((f) => f.filePath && fs_1.default.existsSync(f.filePath));
364
364
  // We add all the suggested changes to the updatedFiles array
365
365
  // This is used to validate and format files later
366
366
  updatedFiles.push(...fileChanges);
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.repoEditAgent = exports.generateCodeUsingRepoAgent = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
7
+ const fs_1 = __importDefault(require("fs"));
8
8
  const context_1 = require("../../bin/utils/context");
9
9
  const web_1 = require("../../bin/utils/platform/web");
10
10
  const reporter_1 = require("../../reporter");
@@ -75,7 +75,7 @@ async function repoEditAgent({ trace, task, logger, }) {
75
75
  });
76
76
  await Promise.all(updates.map((f) => {
77
77
  return (async () => {
78
- if (fs_extra_1.default.existsSync(f.filePath)) {
78
+ if (fs_1.default.existsSync(f.filePath)) {
79
79
  await (0, web_1.lintErrors)(f.filePath);
80
80
  }
81
81
  })();
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generateTestWithCodegen = exports.createTestWithCodeAgent = void 0;
7
7
  const llm_1 = require("@empiricalrun/llm");
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const fs_1 = __importDefault(require("fs"));
9
9
  const logger_1 = require("../../bin/logger");
10
10
  const context_1 = require("../../bin/utils/context");
11
11
  const web_1 = require("../../bin/utils/platform/web");
@@ -67,9 +67,9 @@ ${testCase.steps.join("\n")}`;
67
67
  exports.createTestWithCodeAgent = createTestWithCodeAgent;
68
68
  async function generateTestWithCodegen({ testCase, file, trace, }) {
69
69
  const logger = new logger_1.CustomLogger();
70
- if (!fs_extra_1.default.existsSync(file)) {
70
+ if (!fs_1.default.existsSync(file)) {
71
71
  logger.log(`Creating a new spec file: ${file}`);
72
- fs_extra_1.default.createFileSync(file);
72
+ fs_1.default.writeFileSync(file, "");
73
73
  }
74
74
  const context = await (0, context_1.contextForGeneration)(file);
75
75
  const { testFileContent } = context;
@@ -112,7 +112,7 @@ async function generateTestWithCodegen({ testCase, file, trace, }) {
112
112
  });
113
113
  await Promise.all(updates.fileChanges.map((f) => {
114
114
  return (async () => {
115
- if (fs_extra_1.default.existsSync(f.filePath)) {
115
+ if (fs_1.default.existsSync(f.filePath)) {
116
116
  await (0, web_1.lintErrors)(f.filePath);
117
117
  }
118
118
  })();
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.appendCreateTestBlock = exports.getAppendCreateTestBlockCompletion = exports.updateTest = exports.getUpdateTestCodeCompletion = void 0;
7
7
  const llm_1 = require("@empiricalrun/llm");
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const fs_1 = __importDefault(require("fs"));
9
9
  const logger_1 = require("../../bin/logger");
10
10
  const context_1 = require("../../bin/utils/context");
11
- const fs_1 = require("../../bin/utils/fs");
11
+ const fs_2 = require("../../bin/utils/fs");
12
12
  const web_1 = require("../../bin/utils/platform/web");
13
13
  const constants_1 = require("../../constants");
14
14
  const promptTemplate_0 = "{{#section \"system\"}}\n\nYou are a software test engineer who is given a task to update a test case. You will be provided with steps of a test\ncase scenario and you are given a snippet with interface await createTest(task, playwright_page_instance).\n\nYou need to analyze the request and place createTest snippet at the correct position and pass on the steps to this\n`createTest` method with the correct page instance.\n\nYou will be provided with current tests, fixtures and page object models for you to use and update code as per the\ntask provided to you.\nYou need to respond with file path and updated code block inside the file.\n\nHere is the list of current tests and fixtures:\n\n{{testFiles}}\n\n\nHere is the list of current page object models:\n\n{{pageFiles}}\n{{/section}}\n\n\n{{#section \"user\"}}\nFollowing is the test scenario for which you need to update the test:\n\ntest name:\n{{scenarioName}}\n\nTask:\n{{scenarioSteps}}\n\nFollow these steps to complete the task:\n\n1. Determine the task's intent:\n- The default intent is **\"add steps\"**.\n- If the task explicitly mentions (using words like \"replace\", \"remove\", \"delete\") that existing test steps should\nbe replaced or deleted, the intent is **\"update steps\"**. Identify the specific steps to be replaced or removed.\n- Do not assume that providing new or different steps implies an intent to update or replace existing steps. Unless\nthe task explicitly instructs to replace or remove existing code, interpret the intent as adding new steps to the\nexisting test.\n\n2. Identify the test block that requires updating.\n\n3. Place the `createTest` snippet:\n- Insert the `createTest` snippet at the location determined by the task, and pass the Playwright page instance.\n- If the intent is \"add\", do not alter the existing test code; simply append the `createTest` snippet based on any\nprovided location hints.\n- If the task includes location hints that don't match steps within the test, check dependent methods called from\nthe test for the update.\n- If no location hint is provided, place the `createTest` snippet at the end of the test block.\n- Even if the task includes steps that overlap with or are similar to existing steps, do not modify the existing\ncode. Unless the task explicitly instructs to replace or remove existing code, interpret the intent as adding new\nsteps to the existing test.\n\n4. Strip location hints from the task:\n- Remove any location hints (e.g., \"replace the current assertion and\") before passing the task to the `createTest`\nmethod.\n- The task passed into `createTest` should not contain any location hints. It should only contain actions that\nare required to be performed.\n- For example, if the original task: \"replace the current assertion and add a new assertion\" should be transformed to\n\"add a new assertion\" before passing it to the `createTest` method. This is the \"task_without_location_hints\"\n\nSubmission Guidelines:\n\n- Focus only on the provided test case and any related page object model methods used in the test.\n- Do not modify or add code within the `createTest` snippet.\n- Do not update or modify any other code apart from adding `createTest` code snippet.\n- Since the response will be used for search-and-replace operations, always provide the immediate parent AST node\nfor any code updates.\n- Include the full test block if any part of it is updated, preserving all unchanged code.\n- Do not use markdown syntax or backticks.\n- Respond using the following XML format:\n<reason_for_intent></reason_for_intent>\n<intent></intent>\n<location_of_update></location_of_update>\n<task_without_location_hints></task_without_location_hints>\n<file_path></file_path>\n<old_code_block></old_code_block>\n<new_code_block></new_code_block>\n<change></change>\n\n- Each `<old_code_block>` and `<new_code_block>` should contain only one test block or page object model method\n definition. Provide separate blocks for multiple updates.\n- The `<change></change>` tag should also mention the file path being updated.\n- There should be only one `createTest` block in the `new_code_block`. The `createTest` method should be passed\nwith entire task. Do not split the task while forwarding it to `createTest`.\n- `<new_code_block>` code snippet should be syntactically correct.\n - The code_block should not contain any import statements.\n{{/section}}";
@@ -214,8 +214,8 @@ async function appendCreateTestBlock({ testCase, file, trace, validateTypes = tr
214
214
  const logger = new logger_1.CustomLogger({ useReporter: false });
215
215
  logger.log("Appending create test block");
216
216
  const context = await (0, context_1.contextForGeneration)(file);
217
- const scenarioFileContent = await fs_extra_1.default.readFile(file, "utf-8");
218
- const testCodePrompt = (0, fs_1.convertFileContentsToString)([
217
+ const scenarioFileContent = fs_1.default.readFileSync(file, "utf-8");
218
+ const testCodePrompt = (0, fs_2.convertFileContentsToString)([
219
219
  {
220
220
  filePath: file,
221
221
  content: scenarioFileContent,
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.applyFileChanges = exports.searchAndReplaceCode = exports.applyFileChangesForCreateTest = exports.applyFileChangesUsingStrReplace = exports.validateTypesAndFormatCode = exports.extractTestStepsSuggestions = exports.extractAppendTestUpdates = exports.extractCreateTestUpdates = exports.extractTestUpdates = void 0;
7
7
  const llm_1 = require("@empiricalrun/llm");
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const fs_1 = __importDefault(require("fs"));
9
9
  const ts_morph_1 = require("ts-morph");
10
10
  const web_1 = require("../../bin/utils/platform/web");
11
11
  const fix_ts_errors_1 = require("./fix-ts-errors");
@@ -178,7 +178,7 @@ async function applyFileChangesUsingStrReplace({ trace, fileChanges, logger, })
178
178
  logger?.error(`Unable to find the code to update in ${result.filePath}, full error:`, result);
179
179
  }
180
180
  else {
181
- await fs_extra_1.default.writeFile(fileChange.filePath, updatedContent, "utf-8");
181
+ fs_1.default.writeFileSync(fileChange.filePath, updatedContent, "utf-8");
182
182
  readWriteFileSpan?.end({ output: { updatedContent } });
183
183
  }
184
184
  results.push(result);
@@ -213,13 +213,13 @@ async function applyFileChangesForCreateTest({ trace, fileChanges, testgenUpdate
213
213
  },
214
214
  });
215
215
  if (fileChange.code) {
216
- const currentContent = fs_extra_1.default.existsSync(fileChange.filePath)
217
- ? await fs_extra_1.default.readFile(fileChange.filePath, "utf-8")
216
+ const currentContent = fs_1.default.existsSync(fileChange.filePath)
217
+ ? fs_1.default.readFileSync(fileChange.filePath, "utf-8")
218
218
  : "";
219
- await fs_extra_1.default.writeFile(fileChange.filePath, currentContent
219
+ fs_1.default.writeFileSync(fileChange.filePath, currentContent
220
220
  ? `${currentContent}\n\n${fileChange.code}`
221
221
  : fileChange.code, "utf-8");
222
- const updatedFileContent = await fs_extra_1.default.readFile(fileChange.filePath, "utf-8");
222
+ const updatedFileContent = fs_1.default.readFileSync(fileChange.filePath, "utf-8");
223
223
  readWriteFileSpan?.end({
224
224
  output: { fileChange, updatedFile: updatedFileContent },
225
225
  });
@@ -240,7 +240,7 @@ async function applyFileChangesForCreateTest({ trace, fileChanges, testgenUpdate
240
240
  }
241
241
  exports.applyFileChangesForCreateTest = applyFileChangesForCreateTest;
242
242
  async function searchAndReplaceCode({ logger, fileChange, }) {
243
- let contents = await fs_extra_1.default.readFile(fileChange.filePath, "utf-8");
243
+ let contents = fs_1.default.readFileSync(fileChange.filePath, "utf-8");
244
244
  // since we dont know what is getting updated,
245
245
  // we believe that the patch is correct and contains few before and after lines
246
246
  // to make the change unique for search & replace
@@ -292,7 +292,7 @@ async function applyFileChanges({ trace, testCase, fileChanges, logger, }) {
292
292
  // assuming the test case getting updated
293
293
  // maintaining the previous accuracy of the test case update
294
294
  const readWriteFileSpan = trace?.span({ name: "write-to-file" });
295
- let contents = await fs_extra_1.default.readFile(fileChange.filePath, "utf-8");
295
+ let contents = fs_1.default.readFileSync(fileChange.filePath, "utf-8");
296
296
  const [prependContent, strippedContent] = await (0, web_1.stripAndPrependImports)(fileChange.newCode, testCase?.name);
297
297
  let updatedContent = prependContent + contents + `\n\n${strippedContent}`;
298
298
  const { testBlock } = (0, web_1.getTypescriptTestBlock)({
@@ -302,12 +302,12 @@ async function applyFileChanges({ trace, testCase, fileChanges, logger, }) {
302
302
  });
303
303
  contents = contents.replace(testBlock, `\n\n${strippedContent}`);
304
304
  updatedContent = prependContent + contents;
305
- await fs_extra_1.default.writeFile(fileChange.filePath, updatedContent, "utf-8");
305
+ fs_1.default.writeFileSync(fileChange.filePath, updatedContent, "utf-8");
306
306
  readWriteFileSpan?.end({ output: { updatedContent } });
307
307
  }
308
308
  else {
309
309
  const readWriteFileSpan = trace?.span({ name: "write-to-file" });
310
- let contents = await fs_extra_1.default.readFile(fileChange.filePath, "utf-8");
310
+ let contents = fs_1.default.readFileSync(fileChange.filePath, "utf-8");
311
311
  const project = new ts_morph_1.Project();
312
312
  const sourceFile = project.createSourceFile("updated-code.ts", fileChange.newCode);
313
313
  const functions = sourceFile.getFunctions();
@@ -353,7 +353,7 @@ async function applyFileChanges({ trace, testCase, fileChanges, logger, }) {
353
353
  contents = updatedContent;
354
354
  }
355
355
  }
356
- await fs_extra_1.default.writeFile(fileChange.filePath, contents, "utf-8");
356
+ fs_1.default.writeFileSync(fileChange.filePath, contents, "utf-8");
357
357
  readWriteFileSpan?.end({ output: { contents } });
358
358
  results.push({
359
359
  filePath: fileChange.filePath,
@@ -4,14 +4,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.fetchAppKnowledge = exports.generateTxtForRepository = exports.createRepoEditFilter = exports.contextForGeneration = exports.createGitIgnoreFileFilter = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
7
+ const fs_1 = __importDefault(require("fs"));
8
8
  const ignore_1 = __importDefault(require("ignore"));
9
- const fs_1 = require("./fs");
9
+ const fs_2 = require("./fs");
10
10
  async function createGitIgnoreFileFilter() {
11
11
  const ignoreFn = (0, ignore_1.default)();
12
- if (fs_extra_1.default.existsSync(".gitignore")) {
12
+ if (fs_1.default.existsSync(".gitignore")) {
13
13
  // Not checking for nested gitignore
14
- let gitignore = (await fs_extra_1.default.readFile(".gitignore")).toString();
14
+ let gitignore = fs_1.default.readFileSync(".gitignore").toString();
15
15
  gitignore = `
16
16
  ${gitignore}
17
17
  .git/
@@ -27,10 +27,10 @@ exports.createGitIgnoreFileFilter = createGitIgnoreFileFilter;
27
27
  async function contextForGeneration(file) {
28
28
  const filter = await createGitIgnoreFileFilter();
29
29
  return {
30
- codePrompt: await (0, fs_1.generatePromptFromDirectory)("./tests", filter),
31
- pomPrompt: await (0, fs_1.generatePromptFromDirectory)("./pages", filter),
32
- nonSpecFilePrompt: await (0, fs_1.generatePromptFromNonSpecFiles)("./tests", filter),
33
- testFileContent: file ? await fs_extra_1.default.readFile(file, "utf-8") : "",
30
+ codePrompt: await (0, fs_2.generatePromptFromDirectory)("./tests", filter),
31
+ pomPrompt: await (0, fs_2.generatePromptFromDirectory)("./pages", filter),
32
+ nonSpecFilePrompt: await (0, fs_2.generatePromptFromNonSpecFiles)("./tests", filter),
33
+ testFileContent: file ? fs_1.default.readFileSync(file, "utf-8") : "",
34
34
  };
35
35
  }
36
36
  exports.contextForGeneration = contextForGeneration;
@@ -39,14 +39,14 @@ async function createRepoEditFilter() {
39
39
  const gitIgnoreFilter = await createGitIgnoreFileFilter();
40
40
  return (filePath) => {
41
41
  return (gitIgnoreFilter(filePath) &&
42
- (fs_extra_1.default.statSync(filePath).isDirectory() || allowedExtensions.test(filePath)));
42
+ (fs_1.default.statSync(filePath).isDirectory() || allowedExtensions.test(filePath)));
43
43
  };
44
44
  }
45
45
  exports.createRepoEditFilter = createRepoEditFilter;
46
46
  async function generateTxtForRepository() {
47
47
  const filter = await createRepoEditFilter();
48
48
  return {
49
- prompt: await (0, fs_1.generatePromptFromDirectory)(".", filter),
49
+ prompt: await (0, fs_2.generatePromptFromDirectory)(".", filter),
50
50
  };
51
51
  }
52
52
  exports.generateTxtForRepository = generateTxtForRepository;
@@ -54,7 +54,7 @@ async function fetchAppKnowledge() {
54
54
  let fileExists = true;
55
55
  const appKnowledgePath = "./app_knowledge.md";
56
56
  try {
57
- await fs_extra_1.default.access(appKnowledgePath);
57
+ fs_1.default.accessSync(appKnowledgePath);
58
58
  }
59
59
  catch (e) {
60
60
  fileExists = false;
@@ -62,6 +62,6 @@ async function fetchAppKnowledge() {
62
62
  if (!fileExists) {
63
63
  return "";
64
64
  }
65
- return await fs_extra_1.default.readFile(appKnowledgePath, "utf-8");
65
+ return fs_1.default.readFileSync(appKnowledgePath, "utf-8");
66
66
  }
67
67
  exports.fetchAppKnowledge = fetchAppKnowledge;
@@ -4,19 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.generatePromptFromNonSpecFiles = exports.generatePromptFromDirectory = exports.convertFileContentsToString = exports.readFilesInDirectory = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
7
+ const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  async function readFilesInDirectory(dir = "", filterFunc) {
10
10
  let files = [];
11
- const items = await fs_extra_1.default.readdir(dir);
11
+ const items = fs_1.default.readdirSync(dir);
12
12
  const filteredItems = items.map((i) => path_1.default.join(dir, i)).filter(filterFunc);
13
13
  for (const item of filteredItems) {
14
- const stat = await fs_extra_1.default.stat(item);
14
+ const stat = fs_1.default.statSync(item);
15
15
  if (stat.isDirectory()) {
16
16
  files = files.concat(await readFilesInDirectory(item, filterFunc));
17
17
  }
18
18
  else if (stat.isFile()) {
19
- const content = await fs_extra_1.default.readFile(item, "utf-8");
19
+ const content = fs_1.default.readFileSync(item, "utf-8");
20
20
  files.push({ filePath: item, content });
21
21
  }
22
22
  }
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.isSyntaxValid = exports.getVariableDeclarationsFromCode = exports.buildTestNamePrompt = exports.isTestPresent = exports.appendScopeToCreateTest = exports.addUserContextFixture = exports.importAllExportsStmtFromFilePaths = exports.injectCodeSnippetBySuiteChain = exports.replaceCreateTestWithNewCode = exports.getPageVariableNameFromCreateTest = exports.getFixtureImportPath = exports.removeTestOnly = exports.addNewImport = exports.formatCode = exports.lintErrors = exports.stripAndPrependImports = exports.validateTypescript = exports.appendToTestBlock = exports.findFirstSerialDescribeBlock = exports.hasTopLevelDescribeConfigureWithSerialMode = exports.hasTestBlock = exports.getTypescriptTestBlock = exports.getTestModuleAliasFromSourceFile = void 0;
7
7
  const parser_1 = require("@babel/parser");
8
8
  const eslint_1 = require("eslint");
9
- const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const fs_1 = __importDefault(require("fs"));
10
10
  const path_1 = __importDefault(require("path"));
11
11
  const prettier_1 = __importDefault(require("prettier"));
12
12
  const ts_morph_1 = require("ts-morph");
@@ -73,12 +73,12 @@ function getTypescriptTestBlock({ scenarioName, suites, content, }) {
73
73
  }
74
74
  exports.getTypescriptTestBlock = getTypescriptTestBlock;
75
75
  function hasTestBlock({ testName, testSuites, filePath, }) {
76
- if (!fs_extra_1.default.existsSync(filePath)) {
76
+ if (!fs_1.default.existsSync(filePath)) {
77
77
  return false;
78
78
  }
79
79
  const { testBlock } = getTypescriptTestBlock({
80
80
  scenarioName: testName,
81
- content: fs_extra_1.default.readFileSync(filePath, "utf-8"),
81
+ content: fs_1.default.readFileSync(filePath, "utf-8"),
82
82
  suites: testSuites,
83
83
  });
84
84
  return Boolean(testBlock);
@@ -107,7 +107,7 @@ function getParentDescribeNames(node) {
107
107
  }
108
108
  async function hasTopLevelDescribeConfigureWithSerialMode(filePath) {
109
109
  const project = new ts_morph_1.Project();
110
- const content = await fs_extra_1.default.readFile(filePath, "utf-8");
110
+ const content = fs_1.default.readFileSync(filePath, "utf-8");
111
111
  const sourceFile = project.createSourceFile("test.ts", content);
112
112
  const statements = sourceFile.getStatements();
113
113
  for (const statement of statements) {
@@ -188,7 +188,7 @@ exports.appendToTestBlock = appendToTestBlock;
188
188
  function validateTypescript(filePath) {
189
189
  // Create a compiler host to read files
190
190
  const compilerHost = typescript_1.default.createCompilerHost({});
191
- compilerHost.readFile = (file) => fs_extra_1.default.readFileSync(file, "utf8");
191
+ compilerHost.readFile = (file) => fs_1.default.readFileSync(file, "utf8");
192
192
  // Create a program with a single source file
193
193
  const program = typescript_1.default.createProgram([filePath], {
194
194
  esModuleInterop: true,
@@ -245,12 +245,12 @@ async function lintErrors(filePath) {
245
245
  });
246
246
  const [result] = await eslint.lintFiles(filePath);
247
247
  if (result?.output) {
248
- await fs_extra_1.default.writeFile(filePath, result.output);
248
+ fs_1.default.writeFileSync(filePath, result.output);
249
249
  }
250
250
  }
251
251
  exports.lintErrors = lintErrors;
252
252
  async function formatCode(filePath, trace) {
253
- const fileContent = fs_extra_1.default.readFileSync(filePath, "utf8");
253
+ const fileContent = fs_1.default.readFileSync(filePath, "utf8");
254
254
  if (!fileContent) {
255
255
  trace?.span({
256
256
  name: "prettier-format-output",
@@ -264,7 +264,7 @@ async function formatCode(filePath, trace) {
264
264
  filepath: filePath,
265
265
  });
266
266
  trace?.span({ name: "prettier-format-output", output: formattedContent });
267
- await fs_extra_1.default.writeFile(filePath, formattedContent);
267
+ fs_1.default.writeFileSync(filePath, formattedContent);
268
268
  }
269
269
  exports.formatCode = formatCode;
270
270
  function addNewImport(contents, modules, pkg) {
@@ -272,11 +272,11 @@ function addNewImport(contents, modules, pkg) {
272
272
  }
273
273
  exports.addNewImport = addNewImport;
274
274
  async function removeTestOnly(filePath) {
275
- const contents = await fs_extra_1.default.readFile(filePath, "utf8");
275
+ const contents = fs_1.default.readFileSync(filePath, "utf8");
276
276
  const updatedContent = contents
277
277
  .replace("test.only(", "test(")
278
278
  .replace("test.describe.only(", "test.describe(");
279
- return fs_extra_1.default.writeFile(filePath, updatedContent);
279
+ fs_1.default.writeFileSync(filePath, updatedContent);
280
280
  }
281
281
  exports.removeTestOnly = removeTestOnly;
282
282
  function getFixtureImportPath(filePath) {
@@ -296,7 +296,7 @@ function getFixtureImportPath(filePath) {
296
296
  }
297
297
  exports.getFixtureImportPath = getFixtureImportPath;
298
298
  async function getPageVariableNameFromCreateTest(filePath) {
299
- const contents = await fs_extra_1.default.readFile(filePath, "utf-8");
299
+ const contents = fs_1.default.readFileSync(filePath, "utf-8");
300
300
  const project = new ts_morph_1.Project();
301
301
  const sourceFile = project.createSourceFile("test.ts", contents);
302
302
  const createTestNode = sourceFile.getFirstDescendant((node) => !!(node.isKind(ts_morph_1.SyntaxKind.CallExpression) &&
@@ -418,7 +418,7 @@ const importAllExportsStmtFromFilePaths = async (repoDir, filePaths, testFilePat
418
418
  if (!importPath.startsWith(".")) {
419
419
  importPath = "./" + importPath;
420
420
  }
421
- const file = await fs_extra_1.default.readFile(fullPath, "utf-8");
421
+ const file = fs_1.default.readFileSync(fullPath, "utf-8");
422
422
  const project = new ts_morph_1.Project();
423
423
  const sourceFile = project.createSourceFile("index.ts", file);
424
424
  const exportedFunctions = sourceFile
@@ -440,7 +440,7 @@ async function addUserContextFixture({ scenarioName, filePath, suites, }) {
440
440
  // TODO: remove this check when we support user context across repos
441
441
  let fixtureContent = "";
442
442
  try {
443
- fixtureContent = await fs_extra_1.default.readFile("./tests/fixtures.ts", "utf-8");
443
+ fixtureContent = fs_1.default.readFileSync("./tests/fixtures.ts", "utf-8");
444
444
  }
445
445
  catch (e) {
446
446
  // do nothing
@@ -448,7 +448,7 @@ async function addUserContextFixture({ scenarioName, filePath, suites, }) {
448
448
  if (!fixtureContent || !fixtureContent.includes("userContext")) {
449
449
  return;
450
450
  }
451
- const fileContent = await fs_extra_1.default.readFile(filePath, "utf-8");
451
+ const fileContent = fs_1.default.readFileSync(filePath, "utf-8");
452
452
  const { testNode } = getTypescriptTestBlock({
453
453
  scenarioName,
454
454
  content: fileContent,
@@ -469,14 +469,14 @@ async function addUserContextFixture({ scenarioName, filePath, suites, }) {
469
469
  .replace(",}", "}") // Remove any trailing commas
470
470
  .replace("}", ", userContext }");
471
471
  destructuringParam.replaceWithText(updatedImport);
472
- await fs_extra_1.default.writeFile(filePath, fileContent.replace(currentBlock, testNode.getText()), "utf-8");
472
+ fs_1.default.writeFileSync(filePath, fileContent.replace(currentBlock, testNode.getText()), "utf-8");
473
473
  }
474
474
  }
475
475
  }
476
476
  }
477
477
  exports.addUserContextFixture = addUserContextFixture;
478
478
  async function appendScopeToCreateTest(filePath, scopeVariables) {
479
- const contents = await fs_extra_1.default.readFile(filePath, "utf-8");
479
+ const contents = fs_1.default.readFileSync(filePath, "utf-8");
480
480
  const project = new ts_morph_1.Project();
481
481
  const sourceFile = project.createSourceFile("test.ts", contents);
482
482
  const createTestNode = sourceFile
@@ -491,17 +491,17 @@ async function appendScopeToCreateTest(filePath, scopeVariables) {
491
491
  const args = createTestNode.getArguments();
492
492
  const scopeArgStr = `{ ${scopeVariables.join(", ")} }`;
493
493
  createTestNode.insertArgument(args.length, scopeArgStr);
494
- await fs_extra_1.default.writeFile(filePath, sourceFile.getFullText());
494
+ fs_1.default.writeFileSync(filePath, sourceFile.getFullText());
495
495
  }
496
496
  exports.appendScopeToCreateTest = appendScopeToCreateTest;
497
497
  function isTestPresent({ specPath, testCase, }) {
498
498
  let isTestPresent = true;
499
- isTestPresent = fs_extra_1.default.existsSync(specPath);
499
+ isTestPresent = fs_1.default.existsSync(specPath);
500
500
  if (isTestPresent) {
501
501
  const { testBlock } = getTypescriptTestBlock({
502
502
  suites: testCase.suites,
503
503
  scenarioName: testCase.name,
504
- content: fs_extra_1.default.readFileSync(specPath, "utf-8"),
504
+ content: fs_1.default.readFileSync(specPath, "utf-8"),
505
505
  });
506
506
  isTestPresent = Boolean(testBlock);
507
507
  }
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TestGenUpdatesReporter = exports.setReporterConfig = exports.getReporter = void 0;
7
7
  const r2_uploader_1 = require("@empiricalrun/r2-uploader");
8
- const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const logger_1 = require("../bin/logger");
11
11
  const uploader_1 = require("../uploader");
@@ -93,10 +93,10 @@ class TestGenUpdatesReporter {
93
93
  }
94
94
  try {
95
95
  // upload current screenshot to r2 and report it to reporter
96
- if (!fs_extra_1.default.existsSync(path_1.default.join(this.repoDir, "gen-assets"))) {
97
- await fs_extra_1.default.mkdir(path_1.default.join(this.repoDir, "gen-assets"));
96
+ if (!fs_1.default.existsSync(path_1.default.join(this.repoDir, "gen-assets"))) {
97
+ fs_1.default.mkdirSync(path_1.default.join(this.repoDir, "gen-assets"));
98
98
  }
99
- await fs_extra_1.default.writeFile(path_1.default.join(this.repoDir, "gen-assets", `current-view-${Date.now()}.png`), buffer);
99
+ fs_1.default.writeFileSync(path_1.default.join(this.repoDir, "gen-assets", `current-view-${Date.now()}.png`), buffer);
100
100
  const uploadDir = (0, uploader_1.getUploadPathForRun)(reporterConfig?.projectRepoName);
101
101
  const files = await (0, r2_uploader_1.uploadDirectory)({
102
102
  sourceDir: path_1.default.join(this.repoDir, "gen-assets"),
@@ -110,7 +110,7 @@ class TestGenUpdatesReporter {
110
110
  type: "current-snapshot",
111
111
  message: JSON.stringify({ type: "current-view", url }),
112
112
  }));
113
- await fs_extra_1.default.rmdir(path_1.default.join(this.repoDir, "gen-assets"), {
113
+ fs_1.default.rmdirSync(path_1.default.join(this.repoDir, "gen-assets"), {
114
114
  recursive: true,
115
115
  });
116
116
  }
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.downloadBuild = exports.hasDownloadScript = void 0;
7
- const fs_extra_1 = __importDefault(require("fs-extra"));
7
+ const fs_1 = __importDefault(require("fs"));
8
8
  const logger_1 = require("../bin/logger");
9
9
  const exec_1 = require("../utils/exec");
10
10
  async function getPackageJSON() {
11
11
  const packageJSONPath = "package.json";
12
- const packageJsonStr = await fs_extra_1.default.readFile(packageJSONPath, "utf-8");
12
+ const packageJsonStr = fs_1.default.readFileSync(packageJSONPath, "utf-8");
13
13
  return JSON.parse(packageJsonStr);
14
14
  }
15
15
  async function hasDownloadScript() {
@@ -1,3 +1,4 @@
1
+ import { TraceClient } from "@empiricalrun/llm";
1
2
  import { PendingToolCall, Tool, ToolResult } from "@empiricalrun/llm/chat";
2
3
  import { SupportedChatModels } from "../agent/chat/types";
3
4
  export type { SupportedChatModels };
@@ -13,6 +14,6 @@ export declare class ToolCallService {
13
14
  getTools(): Promise<{
14
15
  tools: Tool[];
15
16
  }>;
16
- execute(toolCalls: PendingToolCall[], isRemote: boolean): Promise<ToolResult[]>;
17
+ execute(toolCalls: PendingToolCall[], isRemote: boolean, trace?: TraceClient): Promise<ToolResult[]>;
17
18
  }
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool-call-service/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAE3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAa1D,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,KAAK,aAAa,GAAG;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACpD,CAAC;AAyBF,qBAAa,eAAe;IAC1B,KAAK,EAAE,IAAI,EAAE,CAAM;IACnB,aAAa,EAAE,aAAa,CAAM;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,mBAAmB,CAAC;gBAGjC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,aAAa,EAAE,mBAAmB;IAgB9B,QAAQ;;;IAaR,OAAO,CACX,SAAS,EAAE,eAAe,EAAE,EAC5B,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,UAAU,EAAE,CAAC;CAqCzB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool-call-service/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAE3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAa1D,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,KAAK,aAAa,GAAG;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACpD,CAAC;AA4BF,qBAAa,eAAe;IAC1B,KAAK,EAAE,IAAI,EAAE,CAAM;IACnB,aAAa,EAAE,aAAa,CAAM;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,mBAAmB,CAAC;gBAGjC,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,aAAa,EAAE,mBAAmB;IAgB9B,QAAQ;;;IAaR,OAAO,CACX,SAAS,EAAE,eAAe,EAAE,EAC5B,QAAQ,EAAE,OAAO,EACjB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,EAAE,CAAC;CAgDzB"}
@@ -19,7 +19,10 @@ async function sendToolRequestToRemoteQueue(payload) {
19
19
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
20
20
  },
21
21
  });
22
- const queueUrl = process.env.TOOL_REQUEST_QUEUE_URL;
22
+ const queueUrl = process.env.TOOL_EXECUTION_SQS_URL;
23
+ if (!queueUrl) {
24
+ throw new Error("TOOL_EXECUTION_SQS_URL is required for remote execution.");
25
+ }
23
26
  await sqs.send(new client_sqs_1.SendMessageCommand({
24
27
  QueueUrl: queueUrl,
25
28
  MessageBody: JSON.stringify(payload),
@@ -58,9 +61,8 @@ class ToolCallService {
58
61
  }
59
62
  return { tools: this.tools };
60
63
  }
61
- async execute(toolCalls, isRemote) {
64
+ async execute(toolCalls, isRemote, trace) {
62
65
  if (isRemote && this.chatSessionId) {
63
- console.log("Executing tool remotely", toolCalls);
64
66
  await sendToolRequestToRemoteQueue({
65
67
  toolCalls,
66
68
  requestId: crypto.randomUUID(),
@@ -75,23 +77,32 @@ class ToolCallService {
75
77
  else {
76
78
  const toolResults = [];
77
79
  for (const toolCall of toolCalls) {
80
+ const span = trace?.span({
81
+ name: `tool: ${toolCall.name}`,
82
+ input: toolCall.input,
83
+ });
78
84
  const toolExecutor = this.toolExecutors[toolCall.name];
79
85
  if (!toolExecutor) {
80
- toolResults.push({
86
+ const errorResult = {
81
87
  isError: true,
82
88
  result: `Invalid function/tool call: invalid_tool_call not found`,
83
- });
89
+ };
90
+ toolResults.push(errorResult);
91
+ span?.end({ output: errorResult });
84
92
  continue;
85
93
  }
86
94
  try {
87
95
  const result = await toolExecutor(toolCall.input);
88
96
  toolResults.push(result);
97
+ span?.end({ output: result });
89
98
  }
90
99
  catch (error) {
91
- toolResults.push({
100
+ const errorResult = {
92
101
  isError: true,
93
102
  result: error instanceof Error ? error.message : String(error),
94
- });
103
+ };
104
+ toolResults.push(errorResult);
105
+ span?.end({ output: errorResult });
95
106
  }
96
107
  }
97
108
  return toolResults;
@@ -1 +1 @@
1
- {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../src/tools/grep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,wBAAwB,CAAC;AAqB/D,eAAO,MAAM,QAAQ,EAAE,IA+CtB,CAAC"}
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../src/tools/grep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,wBAAwB,CAAC;AAmB/D,eAAO,MAAM,QAAQ,EAAE,IAiDtB,CAAC"}
@@ -5,7 +5,6 @@ const child_process_1 = require("child_process");
5
5
  const util_1 = require("util");
6
6
  const zod_1 = require("zod");
7
7
  const repo_tree_1 = require("../utils/repo-tree");
8
- const execAsync = (0, util_1.promisify)(child_process_1.exec);
9
8
  const GrepInputSchema = zod_1.z.object({
10
9
  pattern: zod_1.z.string().describe("The pattern to search for"),
11
10
  directory: zod_1.z
@@ -40,6 +39,7 @@ exports.grepTool = {
40
39
  // Using -n to show line numbers and removed -l to show actual matches
41
40
  cmd = `find ${dir} ${excludeFind} -name "${input.filePattern}" -exec grep -rin "${input.pattern}" {} \\;`;
42
41
  }
42
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
43
43
  const { stdout, stderr } = await execAsync(cmd);
44
44
  if (stdout) {
45
45
  return {
@@ -53,6 +53,7 @@ exports.grepTool = {
53
53
  };
54
54
  }
55
55
  catch (error) {
56
+ console.error("Error executing grep", error);
56
57
  return {
57
58
  isError: true,
58
59
  result: error instanceof Error ? error.message : String(error),
@@ -1 +1 @@
1
- {"version":3,"file":"str_replace_editor.d.ts","sourceRoot":"","sources":["../../src/tools/str_replace_editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA2B1D,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwC1D;AAMD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,UAAU,CAAC,CAwIrB;AA+FD,eAAO,MAAM,eAAe,EAAE,IAAI,EAKjC,CAAC"}
1
+ {"version":3,"file":"str_replace_editor.d.ts","sourceRoot":"","sources":["../../src/tools/str_replace_editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AA2B1D,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAwC1D;AAMD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,UAAU,CAAC,CAmJrB;AA+FD,eAAO,MAAM,eAAe,EAAE,IAAI,EAKjC,CAAC"}
@@ -86,6 +86,7 @@ async function strReplaceEditorExecutor(input) {
86
86
  let content;
87
87
  let lines;
88
88
  let newContent;
89
+ let typeCheckErrors;
89
90
  switch (input.command) {
90
91
  case "view":
91
92
  // TODO: This assumes repoDir is process.cwd()
@@ -150,6 +151,7 @@ async function strReplaceEditorExecutor(input) {
150
151
  const escapedOldStr = escapeRegExp(input.old_str);
151
152
  const occurences = content.match(new RegExp(escapedOldStr, "g"));
152
153
  if (occurences && occurences.length > 1) {
154
+ // TODO: Help find unique matches
153
155
  return {
154
156
  result: `Error: old_str found ${occurences.length} times in file: ${filePath}. Please provide more context to make a unique match.`,
155
157
  isError: true,
@@ -157,10 +159,10 @@ async function strReplaceEditorExecutor(input) {
157
159
  }
158
160
  newContent = content.replace(input.old_str, input.new_str);
159
161
  fs_1.default.writeFileSync(filePath, newContent);
160
- const errors = (0, web_1.validateTypescript)(filePath);
161
- if (errors.length > 0) {
162
+ typeCheckErrors = (0, web_1.validateTypescript)(filePath);
163
+ if (typeCheckErrors.length > 0) {
162
164
  return {
163
- result: `Edits to file ${filePath} have been applied. However, type checks are failing with errors:\n${errors.join("\n")}`,
165
+ result: `Edits to file ${filePath} have been applied. However, type checks are failing with errors:\n${typeCheckErrors.join("\n")}`,
164
166
  isError: true,
165
167
  };
166
168
  }
@@ -180,20 +182,29 @@ async function strReplaceEditorExecutor(input) {
180
182
  lines = content.split("\n");
181
183
  lines.splice(input.insert_line, 0, input.new_str);
182
184
  fs_1.default.writeFileSync(filePath, lines.join("\n"));
183
- return {
184
- result: "Success",
185
- isError: false,
186
- };
185
+ typeCheckErrors = (0, web_1.validateTypescript)(filePath);
186
+ if (typeCheckErrors.length > 0) {
187
+ return {
188
+ result: `Insertion in file ${filePath} was applied. However, type checks are failing with errors:\n${typeCheckErrors.join("\n")}`,
189
+ isError: true,
190
+ };
191
+ }
192
+ else {
193
+ return {
194
+ result: `Insertion in file ${filePath} was applied. Type checks have also passed.`,
195
+ isError: false,
196
+ };
197
+ }
187
198
  case "undo_edit":
188
199
  if (hasBackup(filePath)) {
189
200
  restoreBackup(filePath);
190
201
  return {
191
- result: "Success",
202
+ result: `Successfully restored ${filePath} from backup`,
192
203
  isError: false,
193
204
  };
194
205
  }
195
206
  return {
196
- result: "No backup file found",
207
+ result: `No backup file found for ${filePath}`,
197
208
  isError: true,
198
209
  };
199
210
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-gen",
3
- "version": "0.56.0",
3
+ "version": "0.56.2",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -14,10 +14,6 @@
14
14
  "types": "./dist/agent/master/run.d.ts",
15
15
  "default": "./dist/agent/master/run.js"
16
16
  },
17
- "./chat/state": {
18
- "types": "./dist/agent/chat/state.d.ts",
19
- "default": "./dist/agent/chat/state.js"
20
- },
21
17
  "./chat": {
22
18
  "types": "./dist/agent/chat/exports.d.ts",
23
19
  "default": "./dist/agent/chat/exports.js"
@@ -50,7 +46,6 @@
50
46
  "dotenv": "^16.4.5",
51
47
  "eslint": "^8.57.0",
52
48
  "express": "^4.19.2",
53
- "fs-extra": "^11.2.0",
54
49
  "ignore": "^5.3.1",
55
50
  "inquirer": "^12.4.2",
56
51
  "jsdom": "^26.0.0",
@@ -65,16 +60,15 @@
65
60
  "tsx": "^4.16.2",
66
61
  "typescript": "^5.3.3",
67
62
  "zod": "^3.23.8",
68
- "@empiricalrun/llm": "^0.15.1",
63
+ "@empiricalrun/llm": "^0.15.2",
69
64
  "@empiricalrun/r2-uploader": "^0.3.8",
70
- "@empiricalrun/test-run": "^0.8.1"
65
+ "@empiricalrun/test-run": "^0.8.3"
71
66
  },
72
67
  "devDependencies": {
73
68
  "@playwright/test": "1.47.1",
74
69
  "@types/async-retry": "^1.4.8",
75
70
  "@types/detect-port": "^1.3.5",
76
71
  "@types/express": "^4.17.21",
77
- "@types/fs-extra": "^11.0.4",
78
72
  "@types/js-levenshtein": "^1.1.3",
79
73
  "@types/jsdom": "^21.1.7",
80
74
  "@types/serve-handler": "^6.1.4",