@empiricalrun/test-gen 0.70.1 → 0.71.1

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,35 @@
1
1
  # @empiricalrun/test-gen
2
2
 
3
+ ## 0.71.1
4
+
5
+ ### Patch Changes
6
+
7
+ - ebafc76: chore: new commits to trigger publish
8
+ - Updated dependencies [ebafc76]
9
+ - @empiricalrun/llm@0.19.4
10
+
11
+ ## 0.71.0
12
+
13
+ ### Minor Changes
14
+
15
+ - c2bcc63: feat: github cred to be always alive in cli
16
+
17
+ ### Patch Changes
18
+
19
+ - d326e62: feat: create draft request from cli
20
+ - 6d5a283: fix: pw project resolution in dirs with spaces
21
+ - fc5469c: fix: commit message duplicate skip ci
22
+ - 64f4323: feat: tool call telemetry with posthog
23
+ - Updated dependencies [6d5a283]
24
+ - @empiricalrun/test-run@0.10.7
25
+
26
+ ## 0.70.2
27
+
28
+ ### Patch Changes
29
+
30
+ - 2b0a5ec: feat: add session id to pr description
31
+ - @empiricalrun/llm@0.19.3
32
+
3
33
  ## 0.70.1
4
34
 
5
35
  ### Patch Changes
@@ -1,10 +1,10 @@
1
1
  import { TraceClient } from "@empiricalrun/llm";
2
2
  import { IChatModel } from "@empiricalrun/llm/chat";
3
- import { SupportedChatModels } from "@empiricalrun/shared-types";
3
+ import { PendingToolCall, SupportedChatModels } from "@empiricalrun/shared-types";
4
4
  import { ToolCallService } from "../../tool-call-service";
5
5
  import { FileInfo } from "../../types";
6
6
  import { ReporterFunction } from "./types";
7
- export declare function chatAgentLoop({ chatModel, selectedModel, reporter, trace, toolCallService, fileInfo, isToolExecutionRemote, }: {
7
+ export declare function chatAgentLoop({ chatModel, selectedModel, reporter, trace, toolCallService, fileInfo, isToolExecutionRemote, onToolCallQueued, }: {
8
8
  chatModel: IChatModel<any>;
9
9
  selectedModel: SupportedChatModels;
10
10
  toolCallService: ToolCallService;
@@ -12,5 +12,6 @@ export declare function chatAgentLoop({ chatModel, selectedModel, reporter, trac
12
12
  trace?: TraceClient;
13
13
  fileInfo: FileInfo;
14
14
  isToolExecutionRemote: boolean;
15
+ onToolCallQueued?: (requestId: string, toolCalls: PendingToolCall[]) => void;
15
16
  }): Promise<void>;
16
17
  //# sourceMappingURL=agent-loop.d.ts.map
@@ -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,EAAE,UAAU,EAAmB,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C,wBAAsB,aAAa,CAAC,EAClC,SAAS,EACT,aAAa,EACb,QAAQ,EACR,KAAK,EACL,eAAe,EACf,QAAQ,EACR,qBAAqB,GACtB,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;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,qBAAqB,EAAE,OAAO,CAAC;CAChC,iBAqDA"}
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;AACrE,OAAO,EACL,eAAe,EACf,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C,wBAAsB,aAAa,CAAC,EAClC,SAAS,EACT,aAAa,EACb,QAAQ,EACR,KAAK,EACL,eAAe,EACf,QAAQ,EACR,qBAAqB,EACrB,gBAAgB,GACjB,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;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CAC9E,iBAwDA"}
@@ -5,15 +5,17 @@ const chat_1 = require("@empiricalrun/llm/chat");
5
5
  const prompt_1 = require("./prompt");
6
6
  const state_1 = require("./state");
7
7
  const utils_1 = require("./utils");
8
- async function chatAgentLoop({ chatModel, selectedModel, reporter, trace, toolCallService, fileInfo, isToolExecutionRemote, }) {
8
+ async function chatAgentLoop({ chatModel, selectedModel, reporter, trace, toolCallService, fileInfo, isToolExecutionRemote, onToolCallQueued, }) {
9
9
  const systemPrompt = await (0, prompt_1.buildSystemPrompt)(fileInfo);
10
10
  trace?.update({ input: { systemPrompt } });
11
11
  while (!chatModel.askUserForInput) {
12
12
  try {
13
13
  const toolCalls = chatModel.getPendingToolCalls();
14
- if (toolCalls.length) {
14
+ if (toolCalls.length > 0) {
15
15
  if (isToolExecutionRemote) {
16
- await toolCallService.sendToQueue(toolCalls);
16
+ const requestId = toolCalls[0].id;
17
+ await toolCallService.sendToQueue(requestId, toolCalls);
18
+ onToolCallQueued?.(requestId, toolCalls);
17
19
  (0, utils_1.log)(`Tool call remote execution in progress`);
18
20
  break;
19
21
  }
@@ -30,8 +30,10 @@ export declare function loadChatState(): ChatState | undefined;
30
30
  export declare function migrateChatState(oldState: any): ChatState;
31
31
  export declare function saveToDisk<T>(messages: Array<T>, selectedModel: SupportedChatModels, askUserForInput: boolean, error: ChatStateError | null): void;
32
32
  export declare function getLatestDownloadBuildUrl(messages: CanonicalMessage[]): string | null;
33
- export declare function fetchToolCallAvailability(toolRequestId: String, messages: CanonicalMessage[]): {
33
+ export declare function fetchToolCallAvailability(toolCallId: String, messages: CanonicalMessage[]): {
34
34
  hasToolRequest: boolean;
35
35
  hasToolResponse: boolean;
36
+ toolCallName: string;
37
+ toolCallQueuedAt: Date | undefined;
36
38
  };
37
39
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,UAAU,EACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AA+BpC,eAAO,MAAM,kCAAkC,EAAE,MAAM,CACrD,MAAM,EACN,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAIpB,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,eAAO,MAAM,eAAe,QAI3B,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,UAAU,EAAE,EACzB,aAAa,EAAE,mBAAmB,GACjC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAMhC;AAED,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,KAAK,GACN,EAAE;IACD,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC;IACrC,aAAa,EAAE,mBAAmB,CAAC;IACnC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9B,aAYA;AAED,wBAAgB,0BAA0B,CAAC,EACzC,QAAQ,EACR,aAAa,EACb,eAAe,EACf,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,GAAG,CAAC;IACd,aAAa,EAAE,mBAAmB,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9B,GAAG,SAAS,CASZ;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,EACpC,SAAS,EACT,aAAa,EACb,KAAK,GACN,EAAE;IACD,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACzB,aAAa,EAAE,mBAAmB,CAAC;IACnC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9B,aAOA;AAED,wBAAgB,aAAa,IAAI,SAAS,GAAG,SAAS,CAarD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,SAAS,CAqBzD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAC1B,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAClB,aAAa,EAAE,mBAAmB,EAClC,eAAe,EAAE,OAAO,EACxB,KAAK,EAAE,cAAc,GAAG,IAAI,QAgB7B;AA2BD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,gBAAgB,EAAE;;;EAe7B"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,UAAU,EACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EAEpB,MAAM,4BAA4B,CAAC;AA+BpC,eAAO,MAAM,kCAAkC,EAAE,MAAM,CACrD,MAAM,EACN,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAIpB,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAAQ,CAAC;AAE/C,eAAO,MAAM,eAAe,QAI3B,CAAC;AAEF,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,UAAU,EAAE,EACzB,aAAa,EAAE,mBAAmB,GACjC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAMhC;AAED,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,KAAK,GACN,EAAE;IACD,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,aAAa,EAAE,SAAS,GAAG,SAAS,CAAC;IACrC,aAAa,EAAE,mBAAmB,CAAC;IACnC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9B,aAYA;AAED,wBAAgB,0BAA0B,CAAC,EACzC,QAAQ,EACR,aAAa,EACb,eAAe,EACf,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,GAAG,CAAC;IACd,aAAa,EAAE,mBAAmB,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9B,GAAG,SAAS,CASZ;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,EACpC,SAAS,EACT,aAAa,EACb,KAAK,GACN,EAAE;IACD,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACzB,aAAa,EAAE,mBAAmB,CAAC;IACnC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9B,aAOA;AAED,wBAAgB,aAAa,IAAI,SAAS,GAAG,SAAS,CAarD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,GAAG,SAAS,CAqBzD;AAED,wBAAgB,UAAU,CAAC,CAAC,EAC1B,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAClB,aAAa,EAAE,mBAAmB,EAClC,eAAe,EAAE,OAAO,EACxB,KAAK,EAAE,cAAc,GAAG,IAAI,QAgB7B;AA2BD,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,gBAAgB,EAAE;;;;;EA2B7B"}
@@ -162,18 +162,21 @@ function getLatestDownloadBuildUrl(messages) {
162
162
  const input = toolCallPart.toolCall.input;
163
163
  return input.buildUrl;
164
164
  }
165
- function fetchToolCallAvailability(toolRequestId, messages) {
166
- let hasToolRequest = false;
167
- let hasToolResponse = false;
168
- messages.forEach((message) => {
169
- message.parts.forEach((part) => {
170
- if ("toolCall" in part && part.toolCall?.id === toolRequestId) {
171
- hasToolRequest = true;
172
- }
173
- if ("toolResult" in part && part.toolCallId === toolRequestId) {
174
- hasToolResponse = true;
175
- }
176
- });
177
- });
178
- return { hasToolRequest, hasToolResponse };
165
+ function fetchToolCallAvailability(toolCallId, messages) {
166
+ const toolCallMessage = messages.find((message) => message.parts.some((part) => {
167
+ return "toolCall" in part && part.toolCallId === toolCallId;
168
+ }));
169
+ const messageTimestampIso = toolCallMessage?.timestamp;
170
+ const toolCallPart = toolCallMessage?.parts.find((part) => "toolCall" in part && part.toolCallId === toolCallId);
171
+ const toolResponseMessage = messages.find((message) => message.parts.some((part) => {
172
+ return "toolResult" in part && part.toolCallId === toolCallId;
173
+ }));
174
+ return {
175
+ hasToolRequest: !!toolCallMessage,
176
+ hasToolResponse: !!toolResponseMessage,
177
+ toolCallName: toolCallPart?.toolCall?.name || "",
178
+ toolCallQueuedAt: messageTimestampIso
179
+ ? new Date(messageTimestampIso)
180
+ : undefined,
181
+ };
179
182
  }
@@ -1 +1 @@
1
- {"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../../src/bin/environments.ts"],"names":[],"mappings":"AAQA,wBAAsB,gBAAgB,kBAiErC"}
1
+ {"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../../src/bin/environments.ts"],"names":[],"mappings":"AASA,wBAAsB,gBAAgB,kBAiErC"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.listEnvironments = listEnvironments;
4
4
  const api_client_1 = require("../auth/api-client");
5
5
  const validation_1 = require("../recorder/validation");
6
+ // TODO: Match against playwright project names - show that to the user
6
7
  async function listEnvironments() {
7
8
  try {
8
9
  let repoName = await (0, validation_1.validatePackageJson)(process.cwd());
package/dist/bin/index.js CHANGED
@@ -20,6 +20,7 @@ const run_3 = require("../agent/planner/run");
20
20
  const auth_1 = require("../auth");
21
21
  const api_client_1 = require("../auth/api-client");
22
22
  const recorder_1 = require("../recorder");
23
+ const validation_1 = require("../recorder/validation");
23
24
  const reporter_1 = require("../reporter");
24
25
  const session_1 = require("../session");
25
26
  const test_build_1 = require("../test-build");
@@ -187,7 +188,10 @@ async function runAgentsWorkflow(testGenConfig, testGenToken) {
187
188
  return agent;
188
189
  }
189
190
  async function main() {
190
- await (0, utils_2.printBanner)();
191
+ const rawMode = process.argv.includes("--raw");
192
+ if (!rawMode) {
193
+ await (0, utils_2.printBanner)();
194
+ }
191
195
  const program = new commander_1.Command();
192
196
  program
193
197
  .command("login")
@@ -350,6 +354,36 @@ async function main() {
350
354
  }
351
355
  process.exit(0);
352
356
  });
357
+ program
358
+ .command("github-token")
359
+ .description("Fetch GitHub token for a repository")
360
+ .option("--raw", "Print only the token with no additional output")
361
+ .action(async (opts) => {
362
+ const options = await (0, utils_2.validateAndCompleteCliOptions)(opts, ["raw"]);
363
+ let repoName = await (0, validation_1.validatePackageJson)(process.cwd());
364
+ if (!repoName) {
365
+ console.error("❌ Not a valid git repo with package.json. Run this command inside a project directory.");
366
+ process.exit(1);
367
+ }
368
+ const response = await api_client_1.apiClient.request(`/api/projects/clone?project_repo_name=${repoName}`);
369
+ const json = await response.json();
370
+ if (!response.ok || !json.data || !json.data.access_token) {
371
+ const errorMsg = json?.error ||
372
+ response.statusText ||
373
+ "Failed to fetch GitHub token for the repository";
374
+ throw new Error(errorMsg);
375
+ }
376
+ const { access_token } = json.data;
377
+ if (options.raw) {
378
+ console.log("username=x-access-token");
379
+ console.log(`password=${access_token}`);
380
+ }
381
+ else {
382
+ console.log(`🔐 GitHub token for ${repoName}:`);
383
+ console.log(access_token);
384
+ }
385
+ process.exit(0);
386
+ });
353
387
  program
354
388
  .command("legacy")
355
389
  .description("Run the legacy workflows")
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/bin/setup.ts"],"names":[],"mappings":"AA+EA,wBAAsB,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,iBA2BhE"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/bin/setup.ts"],"names":[],"mappings":"AAmIA,wBAAsB,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,iBA4BhE"}
package/dist/bin/setup.js CHANGED
@@ -9,6 +9,7 @@ const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const util_1 = require("util");
11
11
  const api_client_1 = require("../auth/api-client");
12
+ const utils_1 = require("./utils");
12
13
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
13
14
  async function cloneRepository(cloneUrl, repoName) {
14
15
  const targetDir = path_1.default.join(process.cwd(), repoName);
@@ -61,6 +62,45 @@ async function installPlaywrightBrowser(targetDir) {
61
62
  process.exit(1);
62
63
  }
63
64
  }
65
+ async function cleanUpRepoCredSetup(repoPath) {
66
+ const currentUrl = await execAsync(`git config --get remote.origin.url`, {
67
+ cwd: repoPath,
68
+ });
69
+ const cleanUrl = (0, utils_1.cleanUpGithubUrl)(currentUrl.stdout);
70
+ await execAsync(`git config remote.origin.url "${cleanUrl}"`, {
71
+ cwd: repoPath,
72
+ });
73
+ }
74
+ async function setupRepoCredentials(repoPath) {
75
+ console.log(`🔑 Setting up repository credentials...`);
76
+ const helperCommand = `!npx @empiricalrun/test-gen github-token --raw`;
77
+ await execAsync(`git config credential."https://github.com".helper '${helperCommand}'`, { cwd: repoPath });
78
+ console.log(`✅ Repository credentials configured`);
79
+ }
80
+ async function validateAndSetupRepo(repoPath) {
81
+ const gitDir = path_1.default.join(repoPath, ".git");
82
+ try {
83
+ await fs_1.default.promises.access(gitDir, fs_1.default.constants.F_OK);
84
+ }
85
+ catch {
86
+ throw new Error("Not a git repository");
87
+ }
88
+ const configPath = path_1.default.join(gitDir, "config");
89
+ const config = await fs_1.default.promises.readFile(configPath, "utf8");
90
+ if (config.includes('[credential "https://github.com"]')) {
91
+ console.log("⚠️ GitHub App credentials already configured");
92
+ return;
93
+ }
94
+ await setupRepoCredentials(repoPath);
95
+ await cleanUpRepoCredSetup(repoPath);
96
+ try {
97
+ await execAsync("git ls-remote origin", { cwd: repoPath });
98
+ console.log("✅ Authentication test successful");
99
+ }
100
+ catch (error) {
101
+ console.error("⚠️ Authentication test failed:", error.message);
102
+ }
103
+ }
64
104
  async function runSetup({ repoName }) {
65
105
  try {
66
106
  console.log(`🔍 Fetching details for repository: ${repoName}`);
@@ -73,8 +113,9 @@ async function runSetup({ repoName }) {
73
113
  }
74
114
  const { data: repoDetails } = await response.json();
75
115
  const { clone_url } = repoDetails;
76
- console.log(`📂 Clone URL: ${clone_url}`);
116
+ console.log(`📂 Clone URL: ${(0, utils_1.cleanUpGithubUrl)(clone_url)}`);
77
117
  const targetDir = await cloneRepository(clone_url, repoName);
118
+ await validateAndSetupRepo(targetDir);
78
119
  await installDependencies(targetDir);
79
120
  await installPlaywrightBrowser(targetDir);
80
121
  console.log(`\n🎉 Setup complete! Repository is ready at ./${repoName}`);
@@ -7,7 +7,9 @@ export interface CLIOptions {
7
7
  prompt?: string;
8
8
  suites?: string;
9
9
  repoName?: string;
10
+ raw?: boolean;
10
11
  }
11
12
  export declare function validateAndCompleteCliOptions(options: CLIOptions, requiredFields?: string[]): Promise<CLIOptions>;
12
13
  export declare function printBanner(): Promise<void>;
14
+ export declare function cleanUpGithubUrl(url: string): string;
13
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKjE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAgBjE,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAQD,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,UAAU,EACnB,cAAc,GAAE,MAAM,EAA+B,GACpD,OAAO,CAAC,UAAU,CAAC,CAqDrB;AAeD,wBAAsB,WAAW,kBAgDhC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bin/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAKjE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAgBjE,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAQD,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,UAAU,EACnB,cAAc,GAAE,MAAM,EAA+B,GACpD,OAAO,CAAC,UAAU,CAAC,CAqDrB;AAeD,wBAAsB,WAAW,kBAgDhC;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,UAQ3C"}
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ARGS_TO_MODEL_MAP = void 0;
7
7
  exports.validateAndCompleteCliOptions = validateAndCompleteCliOptions;
8
8
  exports.printBanner = printBanner;
9
+ exports.cleanUpGithubUrl = cleanUpGithubUrl;
9
10
  const inquirer_1 = __importDefault(require("inquirer"));
10
11
  const PACKAGE_NAME = "@empiricalrun/test-gen";
11
12
  exports.ARGS_TO_MODEL_MAP = {
@@ -132,3 +133,9 @@ async function printBanner() {
132
133
  });
133
134
  console.log(""); // Bottom padding
134
135
  }
136
+ function cleanUpGithubUrl(url) {
137
+ return url
138
+ .trim()
139
+ .replace(/https:\/\/[^@]+@github\.com\//, "https://github.com/")
140
+ .replace(/https:\/\/x-access-token:[^@]+@github\.com\//, "https://github.com/");
141
+ }
@@ -182,6 +182,8 @@ async function createRequest({ repoName, title, description, }) {
182
182
  title,
183
183
  description,
184
184
  project_repo_name: repoName,
185
+ // TODO: Enable draft requests when we have UX on dashboard sorted
186
+ // status: "draft",
185
187
  }),
186
188
  });
187
189
  if (!response.ok) {
@@ -25,7 +25,7 @@ export declare class ToolCallService {
25
25
  featureFlags: string[];
26
26
  environmentOverrides?: Record<string, string>;
27
27
  });
28
- sendToQueue(toolCalls: PendingToolCall[]): Promise<void>;
28
+ sendToQueue(requestId: string, toolCalls: PendingToolCall[]): Promise<void>;
29
29
  execute(toolCalls: PendingToolCall[]): Promise<ToolResult[]>;
30
30
  }
31
31
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool-call-service/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAEL,eAAe,EACf,UAAU,EACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,mBAAmB,EACnB,IAAI,EACJ,WAAW,EACZ,MAAM,4BAA4B,CAAC;AAmBpC,KAAK,aAAa,GAAG;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;CAC5B,CAAC;AAEF,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;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAEjC,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,QAAQ,EACR,MAAM,EACN,KAAK,EACL,YAAY,EACZ,oBAAyB,GAC1B,EAAE;QACD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,EAAE,mBAAmB,CAAC;QACnC,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,KAAK,CAAC,EAAE,WAAW,CAAC;QACpB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC/C;IAoCK,WAAW,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxD,OAAO,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAwEnE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tool-call-service/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAEL,eAAe,EACf,UAAU,EACX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,mBAAmB,EACnB,IAAI,EACJ,WAAW,EACZ,MAAM,4BAA4B,CAAC;AAmBpC,KAAK,aAAa,GAAG;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;CAC5B,CAAC;AAEF,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;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAEjC,EACV,aAAa,EACb,aAAa,EACb,UAAU,EACV,QAAQ,EACR,MAAM,EACN,KAAK,EACL,YAAY,EACZ,oBAAyB,GAC1B,EAAE;QACD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,aAAa,EAAE,mBAAmB,CAAC;QACnC,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,KAAK,CAAC,EAAE,WAAW,CAAC;QACpB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC/C;IAoCK,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC;IAcV,OAAO,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CAyEnE"}
@@ -61,11 +61,7 @@ class ToolCallService {
61
61
  };
62
62
  }
63
63
  }
64
- async sendToQueue(toolCalls) {
65
- const requestId = toolCalls[0]?.id;
66
- if (!requestId) {
67
- throw new Error("Could not find an id for the tool call.");
68
- }
64
+ async sendToQueue(requestId, toolCalls) {
69
65
  const queueUrl = (0, utils_1.getQueueUrl)(toolCalls, this.tools);
70
66
  if (!queueUrl) {
71
67
  throw new Error(`queueUrl is required for remote execution.`);
@@ -116,6 +112,7 @@ class ToolCallService {
116
112
  repoPath: this.repoPath,
117
113
  apiKey: this.apiKey,
118
114
  trace: this.trace,
115
+ chatSessionId: this.chatSessionId,
119
116
  collectArtifacts: collectArtifactsFn,
120
117
  environmentOverrides: this.environmentOverrides,
121
118
  featureFlags: this.featureFlags,
@@ -50,8 +50,8 @@ async function sendToolRequestToRemoteQueue(queueUrl, payload) {
50
50
  });
51
51
  await sqs.send(new client_sqs_1.SendMessageCommand({
52
52
  QueueUrl: queueUrl,
53
- MessageBody: JSON.stringify(payload),
54
53
  MessageGroupId: payload.requestId,
55
- MessageDeduplicationId: payload.requestId, // unique id for the tool request
54
+ MessageDeduplicationId: payload.requestId,
55
+ MessageBody: JSON.stringify(payload),
56
56
  }));
57
57
  }
@@ -1 +1 @@
1
- {"version":3,"file":"commit-and-create-pr.d.ts","sourceRoot":"","sources":["../../src/tools/commit-and-create-pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EAEL,MAAM,4BAA4B,CAAC;AAoCpC,eAAO,MAAM,qBAAqB,EAAE,IAkFnC,CAAC"}
1
+ {"version":3,"file":"commit-and-create-pr.d.ts","sourceRoot":"","sources":["../../src/tools/commit-and-create-pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,IAAI,EAEL,MAAM,4BAA4B,CAAC;AA0CpC,eAAO,MAAM,qBAAqB,EAAE,IAoFnC,CAAC"}
@@ -16,12 +16,15 @@ For example, if you used the test run tool, you should include the results (and
16
16
  videos and other artifacts that help the reviewer gain more context and confidence in the changes. If tests pass, reviewer will see the video and merge the PR.
17
17
  If tests fail, reviewer will see the video and the test artifacts, and will be able to help you debug the issue.`),
18
18
  });
19
- function descriptionWithTimestamp(description) {
19
+ function descriptionWithMetadata(chatSessionId, description) {
20
20
  const timestamp = new Date()
21
21
  .toISOString()
22
22
  .replace("T", " ")
23
23
  .replace("Z", " UTC");
24
- return `${description}\n\n<sup>Updated at ${timestamp}</sup>`;
24
+ const sessionInfo = chatSessionId
25
+ ? `\n\nPR created from session #${chatSessionId}`
26
+ : ``;
27
+ return `${description}${sessionInfo}\n\n<sup>Updated at ${timestamp}</sup>`;
25
28
  }
26
29
  exports.createPullRequestTool = {
27
30
  schema: {
@@ -37,7 +40,7 @@ Don't ask the user for this information, just come up with it yourself.
37
40
  parameters: createPullRequestSchema,
38
41
  },
39
42
  needsBrowser: false,
40
- execute: async ({ input, repoPath, apiKey, }) => {
43
+ execute: async ({ input, repoPath, apiKey, chatSessionId, }) => {
41
44
  try {
42
45
  const { pullRequestTitle, pullRequestDescription } = input;
43
46
  const branchName = await (0, git_1.getCurrentBranchName)(repoPath);
@@ -61,7 +64,7 @@ Don't ask the user for this information, just come up with it yourself.
61
64
  owner,
62
65
  repo,
63
66
  prNumber: existingPR.number,
64
- body: descriptionWithTimestamp(pullRequestDescription),
67
+ body: descriptionWithMetadata(chatSessionId, pullRequestDescription),
65
68
  apiKey,
66
69
  });
67
70
  return {
@@ -75,7 +78,7 @@ Don't ask the user for this information, just come up with it yourself.
75
78
  title: pullRequestTitle,
76
79
  head: branchName,
77
80
  base: "main",
78
- body: descriptionWithTimestamp(pullRequestDescription),
81
+ body: descriptionWithMetadata(chatSessionId, pullRequestDescription),
79
82
  apiKey,
80
83
  });
81
84
  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,IAmIjC,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;AAuBvD,eAAO,MAAM,mBAAmB,EAAE,IAwIjC,CAAC"}
@@ -25,7 +25,7 @@ This tool handles the entire workflow: editing the package.json file, running "n
25
25
  parameters: upgradePackagesSchema,
26
26
  },
27
27
  needsBrowser: false,
28
- execute: async ({ input, repoPath, apiKey, }) => {
28
+ execute: async ({ input, repoPath, apiKey, chatSessionId, }) => {
29
29
  const { packages: packagesToUpdate } = input;
30
30
  try {
31
31
  const repoName = path_1.default.basename(repoPath);
@@ -62,13 +62,16 @@ This tool handles the entire workflow: editing the package.json file, running "n
62
62
  }
63
63
  const updateMessage = `upgrade ${changes.length} package${changes.length === 1 ? "" : "s"}`;
64
64
  await (0, git_1.commitFilesAndPushBranch)({
65
- commitMessage: `[upgrade-packages] ${updateMessage} [skip ci]`,
65
+ commitMessage: `[upgrade-packages] ${updateMessage}`,
66
66
  branchName,
67
67
  files: ["package.json", "package-lock.json"],
68
68
  repoPath,
69
69
  });
70
70
  await new Promise((resolve) => setTimeout(resolve, 5_000));
71
71
  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
+ : ``;
72
75
  const prTitle = `chore: ${updateMessage}`;
73
76
  let shouldMerge = false;
74
77
  let prNumber = null;
@@ -80,7 +83,7 @@ This tool handles the entire workflow: editing the package.json file, running "n
80
83
  apiKey,
81
84
  branchName,
82
85
  title: prTitle,
83
- body: prBody,
86
+ body: `${prBody}\n\n${sessionMetadata}`,
84
87
  labels: ["automated"],
85
88
  });
86
89
  prNumber = pr.number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@empiricalrun/test-gen",
3
- "version": "0.70.1",
3
+ "version": "0.71.1",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"
@@ -64,9 +64,9 @@
64
64
  "tsx": "^4.16.2",
65
65
  "typescript": "^5.3.3",
66
66
  "zod": "^3.23.8",
67
- "@empiricalrun/llm": "^0.19.3",
67
+ "@empiricalrun/llm": "^0.19.4",
68
68
  "@empiricalrun/r2-uploader": "^0.3.9",
69
- "@empiricalrun/test-run": "^0.10.6"
69
+ "@empiricalrun/test-run": "^0.10.7"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@playwright/test": "1.53.0",
@@ -82,7 +82,7 @@
82
82
  "playwright": "1.53.0",
83
83
  "serve-handler": "^6.1.6",
84
84
  "ts-patch": "^3.3.0",
85
- "@empiricalrun/shared-types": "0.6.2"
85
+ "@empiricalrun/shared-types": "0.6.3"
86
86
  },
87
87
  "scripts": {
88
88
  "dev": "tspc --build --watch",