@empiricalrun/test-gen 0.72.0 → 0.73.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.
Files changed (123) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/agent/chat/index.d.ts.map +1 -1
  3. package/dist/agent/chat/index.js +12 -22
  4. package/dist/agent/chat/prompt/index.d.ts.map +1 -1
  5. package/dist/agent/chat/prompt/index.js +3 -2
  6. package/dist/agent/code-review/prompt.d.ts +2 -0
  7. package/dist/agent/code-review/prompt.d.ts.map +1 -0
  8. package/dist/agent/code-review/prompt.js +19 -0
  9. package/dist/agent/codegen/create-test-block.d.ts.map +1 -1
  10. package/dist/agent/codegen/create-test-block.js +0 -10
  11. package/dist/agent/diagnosis-agent/index.d.ts.map +1 -1
  12. package/dist/agent/diagnosis-agent/index.js +0 -9
  13. package/dist/agent/master/execute-browser-action.d.ts +1 -1
  14. package/dist/agent/master/execute-browser-action.d.ts.map +1 -1
  15. package/dist/agent/master/execute-skill-action.d.ts +1 -1
  16. package/dist/agent/master/execute-skill-action.d.ts.map +1 -1
  17. package/dist/agent/master/run.d.ts.map +1 -1
  18. package/dist/agent/master/run.js +0 -74
  19. package/dist/artifacts/index.d.ts.map +1 -1
  20. package/dist/artifacts/index.js +18 -6
  21. package/dist/artifacts/utils.d.ts +2 -2
  22. package/dist/artifacts/utils.d.ts.map +1 -1
  23. package/dist/artifacts/utils.js +16 -5
  24. package/dist/auth/cli-auth.d.ts.map +1 -1
  25. package/dist/auth/cli-auth.js +3 -7
  26. package/dist/auth/index.d.ts +1 -2
  27. package/dist/auth/index.d.ts.map +1 -1
  28. package/dist/auth/index.js +2 -4
  29. package/dist/auth/token-store.d.ts +1 -1
  30. package/dist/auth/token-store.d.ts.map +1 -1
  31. package/dist/auth/token-store.js +3 -3
  32. package/dist/bin/environments.d.ts +5 -1
  33. package/dist/bin/environments.d.ts.map +1 -1
  34. package/dist/bin/environments.js +9 -11
  35. package/dist/bin/index.js +33 -74
  36. package/dist/bin/setup.d.ts +3 -1
  37. package/dist/bin/setup.d.ts.map +1 -1
  38. package/dist/bin/setup.js +6 -10
  39. package/dist/dashboard/client.d.ts +26 -0
  40. package/dist/dashboard/client.d.ts.map +1 -0
  41. package/dist/dashboard/client.js +185 -0
  42. package/dist/dashboard/index.d.ts +2 -20
  43. package/dist/dashboard/index.d.ts.map +1 -1
  44. package/dist/dashboard/index.js +7 -81
  45. package/dist/dashboard/totp.d.ts +1 -1
  46. package/dist/dashboard/totp.d.ts.map +1 -1
  47. package/dist/dashboard/totp.js +2 -6
  48. package/dist/dashboard/types.d.ts +9 -0
  49. package/dist/dashboard/types.d.ts.map +1 -0
  50. package/dist/dashboard/types.js +17 -0
  51. package/dist/file-info/github.d.ts +2 -2
  52. package/dist/file-info/github.d.ts.map +1 -1
  53. package/dist/file-info/github.js +9 -10
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +0 -9
  56. package/dist/recorder/env-variables.d.ts.map +1 -1
  57. package/dist/recorder/env-variables.js +3 -7
  58. package/dist/recorder/index.js +5 -5
  59. package/dist/recorder/request.js +4 -9
  60. package/dist/recorder/upload.d.ts +3 -2
  61. package/dist/recorder/upload.d.ts.map +1 -1
  62. package/dist/recorder/upload.js +20 -22
  63. package/dist/tools/commit-and-create-pr.d.ts.map +1 -1
  64. package/dist/tools/commit-and-create-pr.js +42 -35
  65. package/dist/tools/delete-file.d.ts +3 -0
  66. package/dist/tools/delete-file.d.ts.map +1 -0
  67. package/dist/tools/delete-file.js +83 -0
  68. package/dist/tools/diagnosis-fetcher.d.ts.map +1 -1
  69. package/dist/tools/diagnosis-fetcher.js +3 -7
  70. package/dist/tools/executor/index.d.ts +6 -9
  71. package/dist/tools/executor/index.d.ts.map +1 -1
  72. package/dist/tools/executor/index.js +23 -29
  73. package/dist/tools/executor/utils/checkpoint.d.ts +2 -2
  74. package/dist/tools/executor/utils/checkpoint.d.ts.map +1 -1
  75. package/dist/tools/executor/utils/checkpoint.js +6 -5
  76. package/dist/tools/executor/utils/git.d.ts +7 -12
  77. package/dist/tools/executor/utils/git.d.ts.map +1 -1
  78. package/dist/tools/executor/utils/git.js +11 -36
  79. package/dist/tools/executor/utils/index.d.ts +37 -21
  80. package/dist/tools/executor/utils/index.d.ts.map +1 -1
  81. package/dist/tools/executor/utils/index.js +57 -58
  82. package/dist/tools/executor/utils/pr-description.d.ts +4 -0
  83. package/dist/tools/executor/utils/pr-description.d.ts.map +1 -0
  84. package/dist/tools/executor/utils/pr-description.js +24 -0
  85. package/dist/tools/fetch-image/index.d.ts +3 -0
  86. package/dist/tools/fetch-image/index.d.ts.map +1 -0
  87. package/dist/tools/fetch-image/index.js +56 -0
  88. package/dist/tools/grep/index.d.ts.map +1 -1
  89. package/dist/tools/grep/index.js +1 -1
  90. package/dist/tools/index.d.ts +4 -0
  91. package/dist/tools/index.d.ts.map +1 -0
  92. package/dist/tools/index.js +60 -0
  93. package/dist/tools/list-environments.d.ts.map +1 -1
  94. package/dist/tools/list-environments.js +2 -5
  95. package/dist/tools/merge-conflicts.d.ts +3 -0
  96. package/dist/tools/merge-conflicts.d.ts.map +1 -0
  97. package/dist/tools/merge-conflicts.js +107 -0
  98. package/dist/tools/run-test.d.ts.map +1 -1
  99. package/dist/tools/run-test.js +2 -2
  100. package/dist/tools/test-run-fetcher/index.d.ts.map +1 -1
  101. package/dist/tools/test-run-fetcher/index.js +2 -6
  102. package/dist/tools/upgrade-packages/index.d.ts.map +1 -1
  103. package/dist/tools/upgrade-packages/index.js +10 -11
  104. package/dist/tools/upgrade-packages/utils.d.ts +3 -2
  105. package/dist/tools/upgrade-packages/utils.d.ts.map +1 -1
  106. package/dist/tools/upgrade-packages/utils.js +5 -8
  107. package/dist/tools/utils/queue.d.ts +5 -0
  108. package/dist/tools/utils/queue.d.ts.map +1 -0
  109. package/dist/tools/utils/queue.js +41 -0
  110. package/package.json +5 -5
  111. package/tsconfig.tsbuildinfo +1 -1
  112. package/dist/auth/api-client.d.ts +0 -13
  113. package/dist/auth/api-client.d.ts.map +0 -1
  114. package/dist/auth/api-client.js +0 -107
  115. package/dist/session/index.d.ts +0 -20
  116. package/dist/session/index.d.ts.map +0 -1
  117. package/dist/session/index.js +0 -104
  118. package/dist/tools/definitions/index.d.ts +0 -22
  119. package/dist/tools/definitions/index.d.ts.map +0 -1
  120. package/dist/tools/definitions/index.js +0 -61
  121. package/dist/tools/definitions/utils/queue.d.ts +0 -8
  122. package/dist/tools/definitions/utils/queue.d.ts.map +0 -1
  123. package/dist/tools/definitions/utils/queue.js +0 -58
@@ -1,46 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GITHUB_API_BASE = void 0;
4
- exports.makeDashboardRequest = makeDashboardRequest;
5
- exports.callGitHubProxy = callGitHubProxy;
6
3
  exports.parseGitHubUrl = parseGitHubUrl;
7
- exports.findExistingPR = findExistingPR;
4
+ exports.getExistingPR = getExistingPR;
5
+ exports.getMergeableState = getMergeableState;
6
+ exports.getMergeableStateDescription = getMergeableStateDescription;
8
7
  exports.createPullRequest = createPullRequest;
9
8
  exports.updatePullRequest = updatePullRequest;
10
9
  exports.findOrCreatePullRequest = findOrCreatePullRequest;
11
- async function makeDashboardRequest({ path, method = "GET", body, apiKey, }) {
12
- const requestHeaders = {
13
- "Content-Type": "application/json",
14
- Authorization: `Bearer ${apiKey}`,
15
- "User-Agent": "empiricalrun/test-gen",
16
- };
17
- const baseUrl = process.env.DASHBOARD_DOMAIN || "https://dash.empirical.run";
18
- const response = await fetch(`${baseUrl}${path}`, {
19
- method,
20
- headers: requestHeaders,
21
- ...(body && { body: JSON.stringify(body) }),
22
- });
23
- if (!response.ok) {
24
- const errorBody = await response.text();
25
- throw new Error(`API request failed for ${method} ${path} (Status: ${response.status}). Body: ${errorBody}`);
26
- }
27
- return await response.json();
28
- }
29
- async function callGitHubProxy({ method, url, body, apiKey, }) {
30
- const githubApiPath = url.replace("https://api.github.com", "");
31
- return makeDashboardRequest({
32
- path: "/api/github/proxy",
33
- method: "POST",
34
- body: {
35
- method,
36
- url: githubApiPath,
37
- body,
38
- },
39
- apiKey,
40
- });
41
- }
42
- // Common GitHub constants
43
- exports.GITHUB_API_BASE = "https://api.github.com/repos/empirical-run";
44
10
  function parseGitHubUrl(url) {
45
11
  const githubIndex = url.indexOf("github.com");
46
12
  if (githubIndex === -1) {
@@ -55,19 +21,56 @@ function parseGitHubUrl(url) {
55
21
  }
56
22
  return { owner, repo };
57
23
  }
58
- async function findExistingPR({ owner, repo, branchName, apiKey, }) {
59
- const prs = (await callGitHubProxy({
24
+ async function getExistingPR({ owner, repo, branchName, apiClient, }) {
25
+ const prs = await apiClient.callGitHubProxy({
60
26
  method: "GET",
61
- url: `https://api.github.com/repos/${owner}/${repo}/pulls`,
27
+ url: `/repos/${owner}/${repo}/pulls`,
62
28
  body: {
63
29
  head: `${owner}:${branchName}`,
64
30
  state: "open",
65
31
  },
66
- apiKey,
67
- }));
32
+ });
68
33
  return prs?.find((pr) => pr.head.ref === branchName) || null;
69
34
  }
70
- async function createPullRequest({ owner, repo, title, head, base = "main", body, labels, apiKey, }) {
35
+ async function getMergeableState({ owner, repo, pullRequest, apiClient, }) {
36
+ if (pullRequest.mergeable_state !== "unknown") {
37
+ return pullRequest.mergeable_state;
38
+ }
39
+ const maxAttempts = 10;
40
+ let attempts = 0;
41
+ while (attempts < maxAttempts) {
42
+ await new Promise((resolve) => setTimeout(resolve, 5_000));
43
+ attempts++;
44
+ try {
45
+ const updatedPR = await apiClient.callGitHubProxy({
46
+ method: "GET",
47
+ url: `/repos/${owner}/${repo}/pulls/${pullRequest.number}`,
48
+ });
49
+ if (updatedPR.mergeable_state !== "unknown") {
50
+ return updatedPR.mergeable_state;
51
+ }
52
+ }
53
+ catch (error) {
54
+ console.warn(`Failed to fetch PR mergeable state (attempt ${attempts}):`, error);
55
+ }
56
+ }
57
+ return "unknown";
58
+ }
59
+ function getMergeableStateDescription(state) {
60
+ switch (state) {
61
+ case "clean":
62
+ return "The pull request is mergeable without conflicts.";
63
+ case "dirty":
64
+ return "The pull request has merge conflicts that must be resolved.";
65
+ case "unstable":
66
+ return "The pull request has failing or pending required status checks.";
67
+ case "unknown":
68
+ return "The mergeability of the pull request is still being calculated.";
69
+ default:
70
+ return `The pull request has mergeable state: ${state}.`;
71
+ }
72
+ }
73
+ async function createPullRequest({ owner, repo, title, head, base = "main", body, labels, apiClient, }) {
71
74
  const createPrBody = {
72
75
  title,
73
76
  head,
@@ -75,40 +78,36 @@ async function createPullRequest({ owner, repo, title, head, base = "main", body
75
78
  body,
76
79
  ...(labels && { labels }),
77
80
  };
78
- const pr = (await callGitHubProxy({
81
+ const pr = await apiClient.callGitHubProxy({
79
82
  method: "POST",
80
- url: `https://api.github.com/repos/${owner}/${repo}/pulls`,
83
+ url: `/repos/${owner}/${repo}/pulls`,
81
84
  body: createPrBody,
82
- apiKey,
83
- }));
85
+ });
84
86
  if (!pr || !("number" in pr)) {
85
87
  throw new Error(`Failed to create PR or PR number missing in response.`);
86
88
  }
87
89
  return pr;
88
90
  }
89
- async function updatePullRequest({ owner, repo, prNumber, body, apiKey, }) {
91
+ async function updatePullRequest({ owner, repo, prNumber, body, apiClient, }) {
90
92
  const updateBody = {};
91
93
  if (body)
92
94
  updateBody.body = body;
93
- return (await callGitHubProxy({
95
+ return await apiClient.callGitHubProxy({
94
96
  method: "PATCH",
95
- url: `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}`,
97
+ url: `/repos/${owner}/${repo}/pulls/${prNumber}`,
96
98
  body: updateBody,
97
- apiKey,
98
- }));
99
+ });
99
100
  }
100
- async function findOrCreatePullRequest({ owner, repo, branchName, title, body, labels, apiKey, }) {
101
- // Check for existing PR
102
- const existingPR = await findExistingPR({
101
+ async function findOrCreatePullRequest({ owner, repo, branchName, title, body, labels, apiClient, }) {
102
+ const existingPR = await getExistingPR({
103
103
  owner,
104
104
  repo,
105
105
  branchName,
106
- apiKey,
106
+ apiClient,
107
107
  });
108
108
  if (existingPR) {
109
109
  return { pr: existingPR, isNew: false };
110
110
  }
111
- // Create new PR
112
111
  const newPR = await createPullRequest({
113
112
  owner,
114
113
  repo,
@@ -116,7 +115,7 @@ async function findOrCreatePullRequest({ owner, repo, branchName, title, body, l
116
115
  head: branchName,
117
116
  body,
118
117
  labels,
119
- apiKey,
118
+ apiClient,
120
119
  });
121
120
  return { pr: newPR, isNew: true };
122
121
  }
@@ -0,0 +1,4 @@
1
+ import type { ChatSessionInfo } from "@empiricalrun/shared-types";
2
+ export declare function generateSessionMetadata(chatSession: ChatSessionInfo | null): string;
3
+ export declare function addMetadataToPRDescription(description: string, chatSession: ChatSessionInfo | null): string;
4
+ //# sourceMappingURL=pr-description.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr-description.d.ts","sourceRoot":"","sources":["../../../../src/tools/executor/utils/pr-description.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,eAAe,GAAG,IAAI,GAClC,MAAM,CASR;AAED,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,eAAe,GAAG,IAAI,GAClC,MAAM,CAWR"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSessionMetadata = generateSessionMetadata;
4
+ exports.addMetadataToPRDescription = addMetadataToPRDescription;
5
+ function generateSessionMetadata(chatSession) {
6
+ if (!chatSession) {
7
+ return "";
8
+ }
9
+ let userInfo = "";
10
+ if (chatSession.createdBy) {
11
+ userInfo = ` by ${chatSession.createdBy}`;
12
+ }
13
+ return `PR created from [session #${chatSession.id}](${chatSession.url})${userInfo}`;
14
+ }
15
+ function addMetadataToPRDescription(description, chatSession) {
16
+ const timestamp = new Date()
17
+ .toISOString()
18
+ .replace("T", " ")
19
+ .replace("Z", " UTC");
20
+ const sessionInfo = chatSession
21
+ ? `\n\n${generateSessionMetadata(chatSession)}`
22
+ : "";
23
+ return `${description}${sessionInfo}\n\n<sup>Updated at ${timestamp}</sup>`;
24
+ }
@@ -0,0 +1,3 @@
1
+ import { Tool } from "@empiricalrun/shared-types";
2
+ export declare const fetchImageTool: Tool;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/fetch-image/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA8B,MAAM,4BAA4B,CAAC;AAS9E,eAAO,MAAM,cAAc,EAAE,IAiD5B,CAAC"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchImageTool = void 0;
4
+ const zod_1 = require("zod");
5
+ const SUPPORTED_CONTENT_TYPES = ["image/png", "image/jpeg"];
6
+ const fetchImageSchema = zod_1.z.object({
7
+ url: zod_1.z.string(),
8
+ });
9
+ exports.fetchImageTool = {
10
+ schema: {
11
+ name: "fetchImage",
12
+ description: "Use this tool to fetch image data from any valid URL. It takes an image URL as input and returns the image in base64 format. Automatically call this tool when a user provides an image link or message containing a URL pointing to an image, so that you can view or analyze the image content effectively",
13
+ parameters: fetchImageSchema,
14
+ },
15
+ needsBrowser: false,
16
+ execute: async ({ input }) => {
17
+ const { url } = input;
18
+ try {
19
+ const response = await fetch(url);
20
+ if (!response.ok) {
21
+ console.error(`Failed to fetch image from ${url}: ${response.statusText}`);
22
+ return {
23
+ result: `Failed to fetch image from ${url}: ${response.statusText}`,
24
+ isError: true,
25
+ };
26
+ }
27
+ const contentType = response.headers.get("content-type");
28
+ if (!contentType || !SUPPORTED_CONTENT_TYPES.includes(contentType)) {
29
+ const errorMessage = `Invalid content type: ${contentType}. URL must return an image.`;
30
+ console.error(errorMessage);
31
+ return {
32
+ result: errorMessage,
33
+ isError: true,
34
+ };
35
+ }
36
+ const buffer = await response.arrayBuffer();
37
+ const base64 = Buffer.from(buffer).toString("base64");
38
+ return {
39
+ result: [
40
+ {
41
+ type: contentType,
42
+ base64Data: base64,
43
+ },
44
+ ],
45
+ isError: false,
46
+ };
47
+ }
48
+ catch (error) {
49
+ console.error("Error fetching image", error);
50
+ return {
51
+ result: `Error fetching image: ${error}`,
52
+ isError: true,
53
+ };
54
+ }
55
+ },
56
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/grep/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EAGL,MAAM,4BAA4B,CAAC;AA8HpC,eAAO,MAAM,QAAQ,EAAE,IA4BtB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/grep/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,4BAA4B,CAAC;AA8HnE,eAAO,MAAM,QAAQ,EAAE,IAkBtB,CAAC"}
@@ -125,7 +125,7 @@ Search is case insensitive and regex patterns are not supported.`,
125
125
  parameters: GrepInputSchema,
126
126
  },
127
127
  needsBrowser: false,
128
- execute: async ({ input, repoPath, }) => {
128
+ execute: async ({ input, repoPath }) => {
129
129
  if ((0, ripgrep_1.isRgAvailable)()) {
130
130
  return usingRipgrep(input, repoPath);
131
131
  }
@@ -0,0 +1,4 @@
1
+ import { ServicePayload, SupportedChatModels } from "@empiricalrun/shared-types";
2
+ export declare function availableTools(model?: SupportedChatModels): import("@empiricalrun/shared-types").ToolDefinition[];
3
+ export declare function sendToolRequestToRemoteQueue(payload: ServicePayload): Promise<void>;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,cAAc,EACd,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAkBpC,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,mBAAmB,yDAoBzD;AAUD,wBAAsB,4BAA4B,CAAC,OAAO,EAAE,cAAc,iBAoBzE"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.availableTools = availableTools;
4
+ exports.sendToolRequestToRemoteQueue = sendToolRequestToRemoteQueue;
5
+ const chat_1 = require("@empiricalrun/llm/chat");
6
+ const SQSClient_1 = require("../utils/SQSClient");
7
+ const commit_and_create_pr_1 = require("./commit-and-create-pr");
8
+ const run_test_1 = require("./definitions/run-test");
9
+ const str_replace_editor_1 = require("./definitions/str_replace_editor");
10
+ const test_gen_browser_1 = require("./definitions/test-gen-browser");
11
+ const delete_file_1 = require("./delete-file");
12
+ const diagnosis_fetcher_1 = require("./diagnosis-fetcher");
13
+ const download_build_1 = require("./download-build");
14
+ const fetch_image_1 = require("./fetch-image");
15
+ const grep_1 = require("./grep");
16
+ const list_environments_1 = require("./list-environments");
17
+ const merge_conflicts_1 = require("./merge-conflicts");
18
+ const test_run_fetcher_1 = require("./test-run-fetcher");
19
+ const upgrade_packages_1 = require("./upgrade-packages");
20
+ const queue_1 = require("./utils/queue");
21
+ function availableTools(model) {
22
+ // TODO: Keep this list in sync with the ToolExecutor
23
+ const tools = [
24
+ run_test_1.runTestTool,
25
+ test_gen_browser_1.generateTestWithBrowserAgent,
26
+ grep_1.grepTool,
27
+ test_run_fetcher_1.fetchTestRunReportTool,
28
+ diagnosis_fetcher_1.fetchDiagnosisReportTool,
29
+ commit_and_create_pr_1.createPullRequestTool,
30
+ merge_conflicts_1.mergeConflictsTool,
31
+ list_environments_1.listEnvironmentsTool,
32
+ download_build_1.downloadBuildTool,
33
+ upgrade_packages_1.upgradePackagesTool,
34
+ fetch_image_1.fetchImageTool,
35
+ delete_file_1.deleteFileTool,
36
+ ];
37
+ if (model && (0, chat_1.getProviderForModel)(model) !== "claude") {
38
+ tools.push(...Object.values(str_replace_editor_1.textEditorTools));
39
+ }
40
+ return tools;
41
+ }
42
+ function toolsNeedBrowser(toolCalls) {
43
+ const allTools = availableTools();
44
+ return toolCalls.some((toolCall) => allTools.find((t) => t.schema.name === toolCall.name)?.needsBrowser);
45
+ }
46
+ async function sendToolRequestToRemoteQueue(payload) {
47
+ const needsBrowser = toolsNeedBrowser(payload.toolCalls);
48
+ const queueUrl = (0, queue_1.getQueueUrl)(payload.toolCalls, needsBrowser);
49
+ if (!queueUrl) {
50
+ throw new Error(`queueUrl is required for remote execution.`);
51
+ }
52
+ const region = process.env.AWS_REGION;
53
+ const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
54
+ const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
55
+ if (!region || !accessKeyId || !secretAccessKey) {
56
+ throw new Error("AWS_REGION, AWS_ACCESS_KEY_ID, and AWS_SECRET_ACCESS_KEY must be set");
57
+ }
58
+ const sqs = new SQSClient_1.SQSClient(region, accessKeyId, secretAccessKey);
59
+ await sqs.sendMessage(queueUrl, payload);
60
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"list-environments.d.ts","sourceRoot":"","sources":["../../src/tools/list-environments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EAEL,MAAM,4BAA4B,CAAC;AAKpC,eAAO,MAAM,oBAAoB,EAAE,IAsDlC,CAAC"}
1
+ {"version":3,"file":"list-environments.d.ts","sourceRoot":"","sources":["../../src/tools/list-environments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAGvD,eAAO,MAAM,oBAAoB,EAAE,IA2ClC,CAAC"}
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.listEnvironmentsTool = void 0;
4
4
  const zod_1 = require("zod");
5
- const utils_1 = require("./executor/utils");
6
5
  exports.listEnvironmentsTool = {
7
6
  schema: {
8
7
  name: "listEnvironments",
@@ -10,13 +9,11 @@ exports.listEnvironmentsTool = {
10
9
  parameters: zod_1.z.object({}),
11
10
  },
12
11
  needsBrowser: false,
13
- execute: async ({ apiKey, }) => {
12
+ execute: async ({ apiClient }) => {
14
13
  let response;
15
14
  try {
16
- response = await (0, utils_1.makeDashboardRequest)({
17
- path: `/api/environments/list`,
15
+ response = await apiClient.request(`/api/environments/list`, {
18
16
  method: "GET",
19
- apiKey,
20
17
  });
21
18
  }
22
19
  catch (error) {
@@ -0,0 +1,3 @@
1
+ import type { Tool } from "@empiricalrun/shared-types";
2
+ export declare const mergeConflictsTool: Tool;
3
+ //# sourceMappingURL=merge-conflicts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-conflicts.d.ts","sourceRoot":"","sources":["../../src/tools/merge-conflicts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AA6CvD,eAAO,MAAM,kBAAkB,EAAE,IAgEhC,CAAC"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.mergeConflictsTool = void 0;
7
+ const child_process_1 = require("child_process");
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const zod_1 = require("zod");
11
+ const git_1 = require("./executor/utils/git");
12
+ function runMergeMain(repoPath) {
13
+ try {
14
+ (0, child_process_1.execSync)("git merge --no-ff origin/main", { stdio: "pipe", cwd: repoPath });
15
+ return "CLEAN";
16
+ }
17
+ catch (error) {
18
+ // Check if it's a merge conflict (exit code 1) vs other errors
19
+ if (error.status === 1) {
20
+ return "CONFLICTS";
21
+ }
22
+ throw error;
23
+ }
24
+ }
25
+ function getConflictedFilesWithContents(repoPath) {
26
+ const output = (0, child_process_1.execSync)("git diff --name-only --diff-filter=U", {
27
+ encoding: "utf8",
28
+ stdio: "pipe",
29
+ cwd: repoPath,
30
+ });
31
+ const fileNames = output
32
+ .trim()
33
+ .split("\n")
34
+ .filter((file) => file.length > 0);
35
+ const filesWithContents = {};
36
+ fileNames.forEach((fileName) => {
37
+ const fullPath = path_1.default.join(repoPath, fileName);
38
+ const content = fs_1.default.readFileSync(fullPath, "utf8");
39
+ filesWithContents[fileName] = content;
40
+ });
41
+ return filesWithContents;
42
+ }
43
+ const mergeConflictsToolScheme = zod_1.z.object({});
44
+ exports.mergeConflictsTool = {
45
+ schema: {
46
+ name: "checkForMergeConflicts",
47
+ description: `This tool runs the git merge command to merge main into your
48
+ current working branch with the following command.
49
+
50
+ \`\`\`
51
+ git merge --no-ff origin/main
52
+ \`\`\`
53
+
54
+ If this commands fails with merge conflicts, it will still create a dirty commit
55
+ that has merge conflicts, which can be resolved with the file editing tools that you are
56
+ provided with.
57
+ `,
58
+ parameters: mergeConflictsToolScheme,
59
+ },
60
+ needsBrowser: false,
61
+ execute: async ({ repoPath }) => {
62
+ try {
63
+ // Fetch main branch (git clone runs --single-branch), and then run merge
64
+ (0, child_process_1.execSync)("git remote set-branches --add origin main", { cwd: repoPath });
65
+ (0, child_process_1.execSync)("git fetch origin main", { cwd: repoPath });
66
+ // Run merge command and commit (with or without conflict)
67
+ const mergeResult = runMergeMain(repoPath);
68
+ const branchName = await (0, git_1.getCurrentBranchName)(repoPath);
69
+ if (mergeResult === "CLEAN") {
70
+ (0, child_process_1.execSync)(`git push origin ${branchName}`, { cwd: repoPath });
71
+ return {
72
+ isError: false,
73
+ result: `Merge from main was successful, without any conflicts.`,
74
+ };
75
+ }
76
+ else if (mergeResult === "CONFLICTS") {
77
+ const files = getConflictedFilesWithContents(repoPath);
78
+ (0, git_1.commitFilesAsBotUser)({
79
+ commitMessage: "Merge from main with conflicts",
80
+ files: Object.keys(files),
81
+ repoPath,
82
+ });
83
+ (0, child_process_1.execSync)(`git push origin ${branchName}`, { cwd: repoPath });
84
+ // TODO: This can be same as file view result
85
+ const filesResult = Object.entries(files)
86
+ .map(([fileName, content]) => `File: ${fileName}\n\n\`\`\`\n${content}\n\`\`\``)
87
+ .join("\n\n");
88
+ return {
89
+ isError: false,
90
+ result: `Merge from main is committed, with conflicts. Use text edit tools to resolve them.\n\n${filesResult}`,
91
+ };
92
+ }
93
+ else {
94
+ return {
95
+ isError: true,
96
+ result: `An unknown error has occured.`,
97
+ };
98
+ }
99
+ }
100
+ catch (error) {
101
+ return {
102
+ isError: true,
103
+ result: `Failed to run merge conflicts tool: ${error instanceof Error ? error.message : String(error)}`,
104
+ };
105
+ }
106
+ },
107
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"run-test.d.ts","sourceRoot":"","sources":["../../src/tools/run-test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,4BAA4B,CAAC;AA0CnE,eAAO,MAAM,WAAW,EAAE,IAgFzB,CAAC"}
1
+ {"version":3,"file":"run-test.d.ts","sourceRoot":"","sources":["../../src/tools/run-test.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,4BAA4B,CAAC;AA0CnE,eAAO,MAAM,WAAW,EAAE,IAiFzB,CAAC"}
@@ -68,8 +68,8 @@ exports.runTestTool = {
68
68
  projects: [input.project],
69
69
  envOverrides,
70
70
  });
71
- const attachments = (0, utils_1.extractAttachmentsFromPlaywrightJSONReport)(result.summaryJson);
72
- void collectArtifacts?.(attachments);
71
+ const artifacts = (0, utils_1.extractAttachmentsFromPlaywrightJSONReport)(result.summaryJson);
72
+ void collectArtifacts?.(artifacts);
73
73
  return {
74
74
  isError: false,
75
75
  result: buildResult({
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/test-run-fetcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAcvD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED,eAAO,MAAM,sBAAsB,EAAE,IAgIpC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/test-run-fetcher/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAavD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOnE;AAED,eAAO,MAAM,sBAAsB,EAAE,IA0HpC,CAAC"}
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fetchTestRunReportTool = void 0;
4
4
  exports.extractPathAfterSourceRepo = extractPathAfterSourceRepo;
5
5
  const zod_1 = require("zod");
6
- const utils_1 = require("../executor/utils");
7
6
  const TestRunSchema = zod_1.z.object({
8
7
  testRunUrl: zod_1.z
9
8
  .string()
@@ -25,7 +24,7 @@ exports.fetchTestRunReportTool = {
25
24
  parameters: TestRunSchema,
26
25
  },
27
26
  needsBrowser: false,
28
- execute: async ({ input, apiKey, }) => {
27
+ execute: async ({ input, apiClient }) => {
29
28
  const { testRunUrl } = input;
30
29
  // Remove query parameters if they exist
31
30
  const urlWithoutParams = testRunUrl.split("?")[0] || testRunUrl;
@@ -41,10 +40,7 @@ exports.fetchTestRunReportTool = {
41
40
  }
42
41
  let data = null;
43
42
  try {
44
- data = await (0, utils_1.makeDashboardRequest)({
45
- path: `/api/test-runs/${runId}?repo_name=${repoName}`,
46
- apiKey,
47
- });
43
+ data = await apiClient.request(`/api/test-runs/${runId}?repo_name=${repoName}`, { method: "GET" });
48
44
  }
49
45
  catch (error) {
50
46
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/upgrade-packages/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAuBvD,eAAO,MAAM,mBAAmB,EAAE,IAwIjC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/upgrade-packages/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAyBvD,eAAO,MAAM,mBAAmB,EAAE,IA2HjC,CAAC"}
@@ -4,11 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.upgradePackagesTool = void 0;
7
+ const child_process_1 = require("child_process");
7
8
  const fs_1 = __importDefault(require("fs"));
8
9
  const path_1 = __importDefault(require("path"));
9
10
  const zod_1 = require("zod");
10
11
  const utils_1 = require("../executor/utils");
11
12
  const git_1 = require("../executor/utils/git");
13
+ const pr_description_1 = require("../executor/utils/pr-description");
12
14
  const utils_2 = require("./utils");
13
15
  const packageSpecSchema = zod_1.z.object({
14
16
  name: zod_1.z.string(),
@@ -25,7 +27,7 @@ This tool handles the entire workflow: editing the package.json file, running "n
25
27
  parameters: upgradePackagesSchema,
26
28
  },
27
29
  needsBrowser: false,
28
- execute: async ({ input, repoPath, apiKey, chatSessionId, }) => {
30
+ execute: async ({ input, repoPath, apiClient, chatSession }) => {
29
31
  const { packages: packagesToUpdate } = input;
30
32
  try {
31
33
  const repoName = path_1.default.basename(repoPath);
@@ -52,7 +54,7 @@ This tool handles the entire workflow: editing the package.json file, running "n
52
54
  };
53
55
  }
54
56
  }
55
- const filesChanged = await (0, git_1.getFilesChanged)(repoPath);
57
+ const filesChanged = (0, git_1.getFilesChanged)(repoPath);
56
58
  const hasChanges = filesChanged.length > 0;
57
59
  if (!hasChanges) {
58
60
  return {
@@ -61,17 +63,14 @@ This tool handles the entire workflow: editing the package.json file, running "n
61
63
  };
62
64
  }
63
65
  const updateMessage = `upgrade ${changes.length} package${changes.length === 1 ? "" : "s"}`;
64
- await (0, git_1.commitFilesAndPushBranch)({
66
+ (0, git_1.commitFilesAsBotUser)({
65
67
  commitMessage: `[upgrade-packages] ${updateMessage}`,
66
- branchName,
67
68
  files: ["package.json", "package-lock.json"],
68
69
  repoPath,
69
70
  });
71
+ (0, child_process_1.execSync)(`git push origin ${branchName}`, { cwd: repoPath });
70
72
  await new Promise((resolve) => setTimeout(resolve, 5_000));
71
73
  const prBody = `Upgraded the following packages:\n\n${changes.map((c) => `- \`${c.name}\` → ${c.version ? c.version : "latest"}`).join("\n")}`;
72
- const sessionMetadata = chatSessionId
73
- ? `PR created from session #${chatSessionId}`
74
- : ``;
75
74
  const prTitle = `chore: ${updateMessage}`;
76
75
  let shouldMerge = false;
77
76
  let prNumber = null;
@@ -80,23 +79,23 @@ This tool handles the entire workflow: editing the package.json file, running "n
80
79
  const { pr } = await (0, utils_1.findOrCreatePullRequest)({
81
80
  owner: "empirical-run",
82
81
  repo: repoName,
83
- apiKey,
82
+ apiClient,
84
83
  branchName,
85
84
  title: prTitle,
86
- body: `${prBody}\n\n${sessionMetadata}`,
85
+ body: (0, pr_description_1.addMetadataToPRDescription)(prBody, chatSession),
87
86
  labels: ["automated"],
88
87
  });
89
88
  prNumber = pr.number;
90
89
  if (!pr.number) {
91
90
  throw new Error("Failed to create PR");
92
91
  }
93
- shouldMerge = await (0, utils_2.shouldMergePR)({ repoName, prNumber, apiKey });
92
+ shouldMerge = await (0, utils_2.shouldMergePR)({ repoName, prNumber, apiClient });
94
93
  if (shouldMerge) {
95
94
  console.log("All changes are patch updates, proceeding with merge");
96
95
  merged = await (0, git_1.mergePullRequest)({
97
96
  repoName,
98
97
  prNumber,
99
- apiKey,
98
+ apiClient,
100
99
  });
101
100
  }
102
101
  else {
@@ -1,3 +1,4 @@
1
+ import { IDashboardAPIClient } from "@empiricalrun/shared-types";
1
2
  export declare function getLatestVersion(packageName: string): Promise<any>;
2
3
  export declare function parsePackageJsonDiff({ diff, }: {
3
4
  diff: string;
@@ -5,10 +6,10 @@ export declare function parsePackageJsonDiff({ diff, }: {
5
6
  old?: string;
6
7
  new?: string;
7
8
  }>;
8
- export declare function shouldMergePR({ repoName, prNumber, apiKey, }: {
9
+ export declare function shouldMergePR({ repoName, prNumber, apiClient, }: {
9
10
  repoName: string;
10
11
  prNumber: number;
11
- apiKey: string;
12
+ apiClient: IDashboardAPIClient;
12
13
  }): Promise<boolean>;
13
14
  export declare function upgradeAndStagePackage({ repoPath, pkgName, version, isDevDep, }: {
14
15
  repoPath: string;