@empiricalrun/test-gen 0.53.8 → 0.53.10
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 +17 -0
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/browsing/run.js +6 -5
- package/dist/agent/chat/agent-loop.js +1 -1
- package/dist/agent/chat/index.d.ts.map +1 -1
- package/dist/agent/chat/index.js +5 -5
- package/dist/agent/chat/state.d.ts +4 -3
- package/dist/agent/chat/state.d.ts.map +1 -1
- package/dist/agent/chat/state.js +8 -5
- package/dist/file/server.d.ts +3 -1
- package/dist/file/server.d.ts.map +1 -1
- package/dist/file/server.js +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/tools/commit-and-create-pr.d.ts.map +1 -1
- package/dist/tools/commit-and-create-pr.js +29 -2
- package/dist/tools/grep.js +5 -5
- package/dist/tools/test-run.d.ts.map +1 -1
- package/dist/tools/test-run.js +42 -7
- package/dist/utils/exec.d.ts +8 -0
- package/dist/utils/exec.d.ts.map +1 -1
- package/dist/utils/exec.js +63 -33
- package/dist/utils/pw-test.d.ts +0 -1
- package/dist/utils/pw-test.d.ts.map +1 -1
- package/dist/utils/pw-test.js +1 -13
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @empiricalrun/test-gen
|
|
2
2
|
|
|
3
|
+
## 0.53.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 088545c: feat: upload test reports from run-test tool calls
|
|
8
|
+
- d003ea8: feat: add description to PRs created by chat agent
|
|
9
|
+
- Updated dependencies [088545c]
|
|
10
|
+
- @empiricalrun/test-run@0.7.7
|
|
11
|
+
|
|
12
|
+
## 0.53.9
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- 2e5d412: fix: grep tool should first return stdout, not stderr
|
|
17
|
+
- 2619c58: fix: add selected model info to chat state
|
|
18
|
+
- 58d170d: fix: skip all serial tests after browser agent is done
|
|
19
|
+
|
|
3
20
|
## 0.53.8
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/run.ts"],"names":[],"mappings":"AAiBA,KAAK,iBAAiB,GAAG;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB,EAAE,OAAO,CAAC;CACpC,CAAC;AAEF,wBAAsB,6BAA6B,CAAC,EAClD,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,OAAO,EACP,yBAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/agent/browsing/run.ts"],"names":[],"mappings":"AAiBA,KAAK,iBAAiB,GAAG;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB,EAAE,OAAO,CAAC;CACpC,CAAC;AAEF,wBAAsB,6BAA6B,CAAC,EAClD,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,OAAO,EACP,yBAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC,CAsFD"}
|
|
@@ -14,14 +14,15 @@ async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, p
|
|
|
14
14
|
if (!fs_extra_1.default.existsSync(testFilePath)) {
|
|
15
15
|
throw new Error(`File for master agent to run not found: ${testFilePath}`);
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
const
|
|
17
|
+
const pm = new exec_1.ProcessManager();
|
|
18
|
+
const availablePort = await (0, detect_port_1.default)(3030);
|
|
19
19
|
// start a file service to handle file updates from agent
|
|
20
20
|
// - also update the file path with updates when agent is done spitting out code
|
|
21
21
|
const fileServer = new server_1.FileServiceServer({
|
|
22
|
-
port,
|
|
22
|
+
port: availablePort,
|
|
23
23
|
repoDir,
|
|
24
24
|
updateFile: editFileWithGeneratedCode,
|
|
25
|
+
onComplete: () => pm.terminate(),
|
|
25
26
|
});
|
|
26
27
|
await fileServer.startFileService();
|
|
27
28
|
fileServer.setFilePath(filePathToUpdate);
|
|
@@ -44,9 +45,9 @@ async function generateTestsUsingMasterAgent({ testFilePath, filePathToUpdate, p
|
|
|
44
45
|
if (!isTestRunTriggeredForTeardown) {
|
|
45
46
|
removeListeners = await teardowns.skipAll();
|
|
46
47
|
}
|
|
47
|
-
await
|
|
48
|
+
await pm.execute(command.split(" "), {
|
|
48
49
|
env: {
|
|
49
|
-
IPC_FILE_SERVICE_PORT:
|
|
50
|
+
IPC_FILE_SERVICE_PORT: availablePort.toString(),
|
|
50
51
|
PW_TEST_HTML_REPORT_OPEN: "never",
|
|
51
52
|
// pass the test gen token so that the agent has the same configuration as cli
|
|
52
53
|
TEST_GEN_TOKEN: testGenToken,
|
|
@@ -84,7 +84,7 @@ async function chatAgentLoop({ chatModel, selectedModel, reporter, trace, }) {
|
|
|
84
84
|
}
|
|
85
85
|
chatModel.pushMessage(response);
|
|
86
86
|
const latest = chatModel.getHumanReadableLatestMessage();
|
|
87
|
-
await reporter((0, state_1.chatStateFromModel)(chatModel), latest);
|
|
87
|
+
await reporter((0, state_1.chatStateFromModel)(chatModel, selectedModel), latest);
|
|
88
88
|
}
|
|
89
89
|
(0, chat_1.cleanupBackupFiles)(process.cwd());
|
|
90
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAoB,mBAAmB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agent/chat/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAoB,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAiBhE,wBAAsB,kBAAkB,CAAC,EACvC,mBAAmB,EACnB,aAAa,EACb,oBAAoB,GACrB,EAAE;IACD,aAAa,EAAE,mBAAmB,CAAC;IACnC,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C,iBAoFA;AAqBD,wBAAsB,wBAAwB,CAAC,EAC7C,aAAa,EACb,aAAa,GACd,EAAE;IACD,aAAa,EAAE,mBAAmB,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,iBA+BA"}
|
package/dist/agent/chat/index.js
CHANGED
|
@@ -11,10 +11,10 @@ const state_1 = require("./state");
|
|
|
11
11
|
function stopCriteria(userPrompt) {
|
|
12
12
|
return userPrompt?.toLowerCase() === "stop";
|
|
13
13
|
}
|
|
14
|
-
function concludeAgent(chatModel, useDiskForChatState) {
|
|
14
|
+
function concludeAgent(chatModel, useDiskForChatState, selectedModel) {
|
|
15
15
|
console.log(`\n${(0, picocolors_1.gray)("Usage summary -> " + chatModel.getUsageSummary())}`);
|
|
16
16
|
if (useDiskForChatState) {
|
|
17
|
-
(0, state_1.saveToDisk)(chatModel.messages);
|
|
17
|
+
(0, state_1.saveToDisk)(chatModel.messages, selectedModel);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialPromptContent, }) {
|
|
@@ -39,7 +39,7 @@ async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialP
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
const handleSigInt = () => {
|
|
42
|
-
concludeAgent(chatModel, useDiskForChatState);
|
|
42
|
+
concludeAgent(chatModel, useDiskForChatState, selectedModel);
|
|
43
43
|
process.exit(0);
|
|
44
44
|
};
|
|
45
45
|
process.once("SIGINT", handleSigInt);
|
|
@@ -47,7 +47,7 @@ async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialP
|
|
|
47
47
|
let userPrompt;
|
|
48
48
|
let reporterFunc = async (chatState, latest) => {
|
|
49
49
|
if (useDiskForChatState) {
|
|
50
|
-
(0, state_1.saveToDisk)(chatState.messages);
|
|
50
|
+
(0, state_1.saveToDisk)(chatState.messages, selectedModel);
|
|
51
51
|
}
|
|
52
52
|
if (latest) {
|
|
53
53
|
console.log(`${(0, picocolors_1.blue)(latest.role)}: ${latest.textMessage}`);
|
|
@@ -72,7 +72,7 @@ async function runChatAgentForCLI({ useDiskForChatState, selectedModel, initialP
|
|
|
72
72
|
catch (e) {
|
|
73
73
|
// https://github.com/SBoudrias/Inquirer.js/issues/1502#issuecomment-2275991680
|
|
74
74
|
if (e instanceof Error && e.name === "ExitPromptError") {
|
|
75
|
-
concludeAgent(chatModel, useDiskForChatState);
|
|
75
|
+
concludeAgent(chatModel, useDiskForChatState, selectedModel);
|
|
76
76
|
process.exit(0);
|
|
77
77
|
}
|
|
78
78
|
throw e;
|
|
@@ -4,11 +4,12 @@ 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
6
|
version: typeof CURRENT_CHAT_STATE_VERSION;
|
|
7
|
+
model: SupportedChatModels;
|
|
7
8
|
messages: T[];
|
|
8
9
|
};
|
|
9
10
|
export declare function createChatState(userPrompt: string, existingState: ChatStateOnDisk<any>, selectedModel: SupportedChatModels): ChatStateOnDisk<unknown>;
|
|
10
|
-
export declare function createChatStateForMessages<T>(messages: any): ChatStateOnDisk<T>;
|
|
11
|
-
export declare function chatStateFromModel<T>(chatModel: IChatModel<T
|
|
11
|
+
export declare function createChatStateForMessages<T>(messages: any, selectedModel: SupportedChatModels): ChatStateOnDisk<T>;
|
|
12
|
+
export declare function chatStateFromModel<T>(chatModel: IChatModel<T>, selectedModel: SupportedChatModels): ChatStateOnDisk<unknown>;
|
|
12
13
|
export declare function loadChatState<T>(): ChatStateOnDisk<T> | undefined;
|
|
13
|
-
export declare function saveToDisk<T>(messages: Array<T
|
|
14
|
+
export declare function saveToDisk<T>(messages: Array<T>, selectedModel: SupportedChatModels): void;
|
|
14
15
|
//# 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,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,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,
|
|
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"}
|
package/dist/agent/chat/state.js
CHANGED
|
@@ -13,19 +13,20 @@ function createChatState(userPrompt, existingState, selectedModel) {
|
|
|
13
13
|
const messages = existingState.messages || [];
|
|
14
14
|
const chatModel = (0, model_1.createChatModel)(messages, selectedModel);
|
|
15
15
|
chatModel.pushUserMessage(userPrompt);
|
|
16
|
-
return createChatStateForMessages(chatModel.messages);
|
|
16
|
+
return createChatStateForMessages(chatModel.messages, selectedModel);
|
|
17
17
|
}
|
|
18
18
|
exports.createChatState = createChatState;
|
|
19
|
-
function createChatStateForMessages(messages) {
|
|
19
|
+
function createChatStateForMessages(messages, selectedModel) {
|
|
20
20
|
// TODO: Add better types for messages
|
|
21
21
|
return {
|
|
22
22
|
version: exports.CURRENT_CHAT_STATE_VERSION,
|
|
23
|
+
model: selectedModel,
|
|
23
24
|
messages: messages,
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
27
|
exports.createChatStateForMessages = createChatStateForMessages;
|
|
27
|
-
function chatStateFromModel(chatModel) {
|
|
28
|
-
return createChatStateForMessages(chatModel.messages);
|
|
28
|
+
function chatStateFromModel(chatModel, selectedModel) {
|
|
29
|
+
return createChatStateForMessages(chatModel.messages, selectedModel);
|
|
29
30
|
}
|
|
30
31
|
exports.chatStateFromModel = chatStateFromModel;
|
|
31
32
|
function loadChatState() {
|
|
@@ -40,10 +41,11 @@ function loadChatState() {
|
|
|
40
41
|
return state;
|
|
41
42
|
}
|
|
42
43
|
exports.loadChatState = loadChatState;
|
|
43
|
-
function saveToDisk(messages) {
|
|
44
|
+
function saveToDisk(messages, selectedModel) {
|
|
44
45
|
const statePath = exports.CHAT_STATE_PATH;
|
|
45
46
|
let existingState = {
|
|
46
47
|
version: exports.CURRENT_CHAT_STATE_VERSION,
|
|
48
|
+
model: selectedModel,
|
|
47
49
|
messages: [],
|
|
48
50
|
};
|
|
49
51
|
// Ensure directory exists before trying to read/write
|
|
@@ -57,6 +59,7 @@ function saveToDisk(messages) {
|
|
|
57
59
|
const newState = {
|
|
58
60
|
...existingState,
|
|
59
61
|
messages: messages,
|
|
62
|
+
model: selectedModel,
|
|
60
63
|
};
|
|
61
64
|
fs_1.default.writeFileSync(statePath, JSON.stringify(newState, null, 2));
|
|
62
65
|
}
|
package/dist/file/server.d.ts
CHANGED
|
@@ -5,10 +5,12 @@ export declare class FileServiceServer {
|
|
|
5
5
|
private server;
|
|
6
6
|
private actionsSummary;
|
|
7
7
|
private updateFile;
|
|
8
|
-
|
|
8
|
+
private onComplete?;
|
|
9
|
+
constructor({ port, repoDir, updateFile, onComplete, }: {
|
|
9
10
|
port: number;
|
|
10
11
|
repoDir: string;
|
|
11
12
|
updateFile: boolean;
|
|
13
|
+
onComplete?: () => void;
|
|
12
14
|
});
|
|
13
15
|
getActionsSummary(): string | undefined;
|
|
14
16
|
setFilePath(filePath: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/file/server.ts"],"names":[],"mappings":"AAWA,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,MAAM,CAA4C;IAC1D,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,UAAU,CAAkB;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/file/server.ts"],"names":[],"mappings":"AAWA,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,MAAM,CAA4C;IAC1D,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,UAAU,CAAC,CAAa;gBAEpB,EACV,IAAI,EACJ,OAAO,EACP,UAAU,EACV,UAAU,GACX,EAAE;QACD,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,OAAO,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;KACzB;IAOD,iBAAiB;IAIjB,WAAW,CAAC,QAAQ,EAAE,MAAM;IAItB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IAmDnC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAgB5B;AAED,wBAAsB,gBAAgB,kBAAK"}
|
package/dist/file/server.js
CHANGED
|
@@ -16,10 +16,12 @@ class FileServiceServer {
|
|
|
16
16
|
server;
|
|
17
17
|
actionsSummary;
|
|
18
18
|
updateFile = false;
|
|
19
|
-
|
|
19
|
+
onComplete;
|
|
20
|
+
constructor({ port, repoDir, updateFile, onComplete, }) {
|
|
20
21
|
this.port = port;
|
|
21
22
|
this.repoDir = repoDir;
|
|
22
23
|
this.updateFile = updateFile;
|
|
24
|
+
this.onComplete = onComplete;
|
|
23
25
|
}
|
|
24
26
|
getActionsSummary() {
|
|
25
27
|
return this.actionsSummary;
|
|
@@ -35,6 +37,9 @@ class FileServiceServer {
|
|
|
35
37
|
const { generatedCode, importPaths, actionsSummary } = req.body;
|
|
36
38
|
this.actionsSummary = actionsSummary;
|
|
37
39
|
if (!this.updateFile) {
|
|
40
|
+
// Not updating the file in this scenario
|
|
41
|
+
if (this.onComplete)
|
|
42
|
+
this.onComplete();
|
|
38
43
|
return res.send({ success: true });
|
|
39
44
|
}
|
|
40
45
|
try {
|
|
@@ -45,6 +50,8 @@ class FileServiceServer {
|
|
|
45
50
|
const importStatements = await (0, web_1.importAllExportsStmtFromFilePaths)(this.repoDir, importPaths, this.filePath);
|
|
46
51
|
fs_1.default.writeFileSync(testFilePath, `${importStatements.join("\n")}\n${newContents}`, "utf-8");
|
|
47
52
|
await (0, web_1.lintErrors)(testFilePath);
|
|
53
|
+
if (this.onComplete)
|
|
54
|
+
this.onComplete();
|
|
48
55
|
return res.send({ success: true });
|
|
49
56
|
}
|
|
50
57
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAQlC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAQlC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAoBpC,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,SAAS,iBAsD3E"}
|
package/dist/index.js
CHANGED
|
@@ -11,7 +11,6 @@ const scenarios_1 = require("./bin/utils/scenarios");
|
|
|
11
11
|
const client_1 = __importDefault(require("./file/client"));
|
|
12
12
|
const reporter_1 = require("./reporter");
|
|
13
13
|
const session_1 = require("./session");
|
|
14
|
-
const pw_test_1 = require("./utils/pw-test");
|
|
15
14
|
const flushEvents = async () => {
|
|
16
15
|
await (0, llm_1.flushAllTraces)();
|
|
17
16
|
};
|
|
@@ -68,8 +67,6 @@ async function createTest(task, page, scope) {
|
|
|
68
67
|
importPaths,
|
|
69
68
|
actionsSummary,
|
|
70
69
|
});
|
|
71
|
-
// skip the rest of the test once generation is over
|
|
72
|
-
await (0, pw_test_1.skipTest)();
|
|
73
70
|
}
|
|
74
71
|
finally {
|
|
75
72
|
// Ensure listeners are removed even if an error occurs
|
|
@@ -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,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAQnD,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAiB1D;
|
|
1
|
+
{"version":3,"file":"commit-and-create-pr.d.ts","sourceRoot":"","sources":["../../src/tools/commit-and-create-pr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAQnD,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAiB1D;AA2CD,eAAO,MAAM,wBAAwB,EAAE,IA8FtC,CAAC"}
|
|
@@ -28,7 +28,24 @@ const CommitAndPushChangesSchema = zod_1.z.object({
|
|
|
28
28
|
commitMessage: zod_1.z
|
|
29
29
|
.string()
|
|
30
30
|
.describe("A short message to use for the commit. Should not be more than 8 words. Should follow conventional commit format."),
|
|
31
|
+
description: zod_1.z.string().describe(`A longer description of the changes you made. This will be used as the description of a pull request on GitHub, and so you should follow markdown formatting.
|
|
32
|
+
Your code will be reviewed by a human, and you should include everything that will provide context and improve the reviewer's confidence in the changes.
|
|
33
|
+
|
|
34
|
+
For example, if you used the test run tool, you should include the results (and the report URL if available). Report URL is especially important, because it contains
|
|
35
|
+
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.
|
|
36
|
+
If tests fail, reviewer will see the video and the test artifacts, and will be able to help you debug the issue.`),
|
|
31
37
|
});
|
|
38
|
+
function formatDescriptionWithTimestamp(description, existingBody, type = "create") {
|
|
39
|
+
const timestamp = new Date()
|
|
40
|
+
.toISOString()
|
|
41
|
+
.replace("T", " ")
|
|
42
|
+
.replace("Z", " UTC");
|
|
43
|
+
const timestampText = `<sup>${type === "create" ? "Created" : "Updated"} at ${timestamp}</sup>`;
|
|
44
|
+
if (existingBody) {
|
|
45
|
+
return `${existingBody}\n\n---\n${description}\n\n${timestampText}`;
|
|
46
|
+
}
|
|
47
|
+
return `${description}\n\n${timestampText}`;
|
|
48
|
+
}
|
|
32
49
|
exports.commitAndPushChangesTool = {
|
|
33
50
|
schema: {
|
|
34
51
|
name: "commitAndPushChanges",
|
|
@@ -41,7 +58,7 @@ Returns the URL of the created or updated pull request.`,
|
|
|
41
58
|
},
|
|
42
59
|
execute: async (input) => {
|
|
43
60
|
try {
|
|
44
|
-
const { commitMessage } = input;
|
|
61
|
+
const { commitMessage, description } = input;
|
|
45
62
|
const currentBranch = (0, child_process_1.execSync)("git rev-parse --abbrev-ref HEAD")
|
|
46
63
|
.toString()
|
|
47
64
|
.trim();
|
|
@@ -82,11 +99,21 @@ Returns the URL of the created or updated pull request.`,
|
|
|
82
99
|
(0, child_process_1.execSync)(`git push origin ${branchName} --set-upstream`);
|
|
83
100
|
const existingPR = existingPRs?.find((pr) => pr.head.ref === branchName);
|
|
84
101
|
if (existingPR) {
|
|
102
|
+
// Append the new description to the existing PR description
|
|
103
|
+
const updatedDescription = formatDescriptionWithTimestamp(description, existingPR.body, "update");
|
|
104
|
+
await (0, utils_1.callGitHubProxy)({
|
|
105
|
+
method: "PATCH",
|
|
106
|
+
url: `https://api.github.com/repos/${owner}/${repo}/pulls/${existingPR.number}`,
|
|
107
|
+
body: {
|
|
108
|
+
body: updatedDescription,
|
|
109
|
+
},
|
|
110
|
+
});
|
|
85
111
|
return {
|
|
86
112
|
isError: false,
|
|
87
113
|
result: `Committed and pushed changes to existing PR: ${existingPR.html_url}`,
|
|
88
114
|
};
|
|
89
115
|
}
|
|
116
|
+
const initialDescription = formatDescriptionWithTimestamp(description);
|
|
90
117
|
const pr = (await (0, utils_1.callGitHubProxy)({
|
|
91
118
|
method: "POST",
|
|
92
119
|
url: `https://api.github.com/repos/${owner}/${repo}/pulls`,
|
|
@@ -94,7 +121,7 @@ Returns the URL of the created or updated pull request.`,
|
|
|
94
121
|
title: commitMessage,
|
|
95
122
|
head: branchName,
|
|
96
123
|
base: "main",
|
|
97
|
-
body:
|
|
124
|
+
body: initialDescription,
|
|
98
125
|
},
|
|
99
126
|
}));
|
|
100
127
|
return {
|
package/dist/tools/grep.js
CHANGED
|
@@ -41,15 +41,15 @@ exports.grepTool = {
|
|
|
41
41
|
cmd = `find ${dir} ${excludeFind} -name "${input.filePattern}" -exec grep -rin "${input.pattern}" {} \\;`;
|
|
42
42
|
}
|
|
43
43
|
const { stdout, stderr } = await execAsync(cmd);
|
|
44
|
-
if (
|
|
44
|
+
if (stdout) {
|
|
45
45
|
return {
|
|
46
|
-
isError:
|
|
47
|
-
result:
|
|
46
|
+
isError: false,
|
|
47
|
+
result: stdout,
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
return {
|
|
51
|
-
isError:
|
|
52
|
-
result:
|
|
51
|
+
isError: true,
|
|
52
|
+
result: stderr,
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-run.d.ts","sourceRoot":"","sources":["../../src/tools/test-run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"test-run.d.ts","sourceRoot":"","sources":["../../src/tools/test-run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAgDnD,eAAO,MAAM,WAAW,EAAE,IAuDzB,CAAC"}
|
package/dist/tools/test-run.js
CHANGED
|
@@ -12,11 +12,25 @@ const RunTestSchema = zod_1.z.object({
|
|
|
12
12
|
.string()
|
|
13
13
|
.describe("The name of the file where the test is located. File name must end with .spec.ts"),
|
|
14
14
|
project: zod_1.z.string().describe("The project to run the test on"),
|
|
15
|
-
headed: zod_1.z
|
|
16
|
-
.boolean()
|
|
17
|
-
.describe("Whether to run the test in headed mode (default is false, which is headless)")
|
|
18
|
-
.optional(),
|
|
19
15
|
});
|
|
16
|
+
function hasCloudflareCredentials() {
|
|
17
|
+
return (process.env.R2_ACCOUNT_ID &&
|
|
18
|
+
process.env.R2_ACCESS_KEY_ID &&
|
|
19
|
+
process.env.R2_SECRET_ACCESS_KEY);
|
|
20
|
+
}
|
|
21
|
+
function buildReportUrl(projectName, testRunId) {
|
|
22
|
+
return `https://reports.empirical.run/${projectName}/${testRunId}/index.html`;
|
|
23
|
+
}
|
|
24
|
+
function buildResult({ hasTestPassed, summaryJson, reportUrl, }) {
|
|
25
|
+
return `
|
|
26
|
+
Test run is complete. Result: ${hasTestPassed ? "Passed" : "Failed"}
|
|
27
|
+
|
|
28
|
+
${reportUrl ? `Report URL: ${reportUrl}` : ""}
|
|
29
|
+
|
|
30
|
+
# Raw result (in Playwright JSON format)
|
|
31
|
+
${JSON.stringify(summaryJson)}
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
20
34
|
exports.runTestTool = {
|
|
21
35
|
schema: {
|
|
22
36
|
name: "runTest",
|
|
@@ -24,7 +38,18 @@ exports.runTestTool = {
|
|
|
24
38
|
parameters: RunTestSchema,
|
|
25
39
|
},
|
|
26
40
|
execute: async (input) => {
|
|
27
|
-
|
|
41
|
+
let reportUrl = undefined;
|
|
42
|
+
let projectName = undefined;
|
|
43
|
+
let testRunId = undefined;
|
|
44
|
+
if (hasCloudflareCredentials()) {
|
|
45
|
+
projectName = "test-gen-chat-agent";
|
|
46
|
+
testRunId = Date.now().toString();
|
|
47
|
+
reportUrl = buildReportUrl(projectName, testRunId);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
console.warn("R2 credentials not found: report artifacts will not be uploaded");
|
|
51
|
+
}
|
|
52
|
+
const { testName, suites, fileName, project } = input;
|
|
28
53
|
try {
|
|
29
54
|
// {"project":"chromium","suites":[],"fileName":"tests/quizizz-for-work/group.spec.ts","testName":"Create a group"}
|
|
30
55
|
// This runs all tests - TODO: Debug this, should only run the testName
|
|
@@ -33,10 +58,20 @@ exports.runTestTool = {
|
|
|
33
58
|
suites,
|
|
34
59
|
fileName,
|
|
35
60
|
projects: [project],
|
|
36
|
-
|
|
61
|
+
// Adding these to enforce report artifacts are uploaded
|
|
62
|
+
envOverrides: projectName && testRunId
|
|
63
|
+
? {
|
|
64
|
+
PROJECT_NAME: projectName,
|
|
65
|
+
TEST_RUN_GITHUB_ACTION_ID: testRunId,
|
|
66
|
+
}
|
|
67
|
+
: undefined,
|
|
37
68
|
});
|
|
38
69
|
return {
|
|
39
|
-
result:
|
|
70
|
+
result: buildResult({
|
|
71
|
+
hasTestPassed: result.hasTestPassed,
|
|
72
|
+
summaryJson: result.summaryJson,
|
|
73
|
+
reportUrl: reportUrl,
|
|
74
|
+
}),
|
|
40
75
|
isError: false,
|
|
41
76
|
};
|
|
42
77
|
}
|
package/dist/utils/exec.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export declare class ProcessManager {
|
|
2
|
+
private childProcess;
|
|
3
|
+
execute(command: string[], options: {
|
|
4
|
+
env?: Record<string, string>;
|
|
5
|
+
}): Promise<number>;
|
|
6
|
+
terminate(): void;
|
|
7
|
+
isRunning(): boolean;
|
|
8
|
+
}
|
|
1
9
|
export declare function cmd(command: string[], options: {
|
|
2
10
|
env?: Record<string, string>;
|
|
3
11
|
}): Promise<number>;
|
package/dist/utils/exec.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAQA,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAA6B;IAE3C,OAAO,CACX,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GACxC,OAAO,CAAC,MAAM,CAAC;IAkDlB,SAAS,IAAI,IAAI;IASjB,SAAS,IAAI,OAAO;CAGrB;AAED,wBAAsB,GAAG,CACvB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACxC,OAAO,CAAC,MAAM,CAAC,CAGjB"}
|
package/dist/utils/exec.js
CHANGED
|
@@ -3,43 +3,73 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.cmd = void 0;
|
|
6
|
+
exports.cmd = exports.ProcessManager = void 0;
|
|
7
7
|
const child_process_1 = require("child_process");
|
|
8
8
|
const process_1 = __importDefault(require("process"));
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
const acceptableExitCodes = [
|
|
10
|
+
0, // Implies successful execution (no errors)
|
|
11
|
+
130, // Implies user interrupted the process (for SIGINT)
|
|
12
|
+
];
|
|
13
|
+
class ProcessManager {
|
|
14
|
+
childProcess = null;
|
|
15
|
+
async execute(command, options) {
|
|
16
|
+
if (this.childProcess) {
|
|
17
|
+
throw new Error("Process is already running");
|
|
15
18
|
}
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (log.includes("Error")) {
|
|
22
|
-
errorLogs.push(log);
|
|
23
|
-
}
|
|
24
|
-
process_1.default.stdout.write(log);
|
|
25
|
-
});
|
|
26
|
-
p.stderr.on("data", (x) => {
|
|
27
|
-
const log = x.toString();
|
|
28
|
-
process_1.default.stderr.write(log);
|
|
29
|
-
errorLogs.push(log);
|
|
30
|
-
});
|
|
31
|
-
p.on("error", async (err) => {
|
|
32
|
-
rejectFunc(err);
|
|
33
|
-
});
|
|
34
|
-
p.on("exit", async (code) => {
|
|
35
|
-
if (code !== 0) {
|
|
36
|
-
const errorMessage = errorLogs.slice(-3).join("\n");
|
|
37
|
-
rejectFunc(new Error(errorMessage));
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
resolveFunc(code ?? 1);
|
|
19
|
+
let errorLogs = [];
|
|
20
|
+
return new Promise((resolveFunc, rejectFunc) => {
|
|
21
|
+
if (!command[0]) {
|
|
22
|
+
rejectFunc(new Error("Command cannot be empty"));
|
|
23
|
+
return;
|
|
41
24
|
}
|
|
25
|
+
const p = (0, child_process_1.spawn)(command[0], command.slice(1), {
|
|
26
|
+
env: { ...process_1.default.env, ...options.env },
|
|
27
|
+
detached: true, // Create process group so we can terminate all child processes
|
|
28
|
+
});
|
|
29
|
+
this.childProcess = p;
|
|
30
|
+
p.stdout.on("data", (x) => {
|
|
31
|
+
const log = x.toString();
|
|
32
|
+
if (log.includes("Error")) {
|
|
33
|
+
errorLogs.push(log);
|
|
34
|
+
}
|
|
35
|
+
process_1.default.stdout.write(log);
|
|
36
|
+
});
|
|
37
|
+
p.stderr.on("data", (x) => {
|
|
38
|
+
const log = x.toString();
|
|
39
|
+
process_1.default.stderr.write(log);
|
|
40
|
+
errorLogs.push(log);
|
|
41
|
+
});
|
|
42
|
+
p.on("error", async (err) => {
|
|
43
|
+
this.childProcess = null;
|
|
44
|
+
rejectFunc(err);
|
|
45
|
+
});
|
|
46
|
+
p.on("exit", async (code) => {
|
|
47
|
+
this.childProcess = null;
|
|
48
|
+
if (!acceptableExitCodes.includes(code ?? 1)) {
|
|
49
|
+
const errorMessage = errorLogs.slice(-3).join("\n");
|
|
50
|
+
rejectFunc(new Error(errorMessage));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
resolveFunc(code ?? 1);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
42
56
|
});
|
|
43
|
-
}
|
|
57
|
+
}
|
|
58
|
+
terminate() {
|
|
59
|
+
if (!this.childProcess) {
|
|
60
|
+
throw new Error("No process is currently running");
|
|
61
|
+
}
|
|
62
|
+
if (this.childProcess.pid) {
|
|
63
|
+
process_1.default.kill(-this.childProcess.pid, "SIGINT");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
isRunning() {
|
|
67
|
+
return this.childProcess !== null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.ProcessManager = ProcessManager;
|
|
71
|
+
async function cmd(command, options) {
|
|
72
|
+
const manager = new ProcessManager();
|
|
73
|
+
return manager.execute(command, options);
|
|
44
74
|
}
|
|
45
75
|
exports.cmd = cmd;
|
package/dist/utils/pw-test.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pw-test.d.ts","sourceRoot":"","sources":["../../src/utils/pw-test.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,CAKd
|
|
1
|
+
{"version":3,"file":"pw-test.d.ts","sourceRoot":"","sources":["../../src/utils/pw-test.ts"],"names":[],"mappings":"AAEA,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,CAKd"}
|
package/dist/utils/pw-test.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.getTestFixtureModuleFromRepo = void 0;
|
|
7
7
|
const api_1 = __importDefault(require("tsx/cjs/api"));
|
|
8
8
|
async function getTestFixtureModuleFromRepo(repoDir) {
|
|
9
9
|
const [lastDir] = repoDir.split("/").reverse();
|
|
@@ -12,15 +12,3 @@ async function getTestFixtureModuleFromRepo(repoDir) {
|
|
|
12
12
|
return test;
|
|
13
13
|
}
|
|
14
14
|
exports.getTestFixtureModuleFromRepo = getTestFixtureModuleFromRepo;
|
|
15
|
-
async function skipTest() {
|
|
16
|
-
let test;
|
|
17
|
-
let repoDir = process.cwd();
|
|
18
|
-
try {
|
|
19
|
-
test = await getTestFixtureModuleFromRepo(repoDir);
|
|
20
|
-
}
|
|
21
|
-
catch (e) {
|
|
22
|
-
console.error("Error while importing fixture module to extract test:", e);
|
|
23
|
-
}
|
|
24
|
-
test.skip();
|
|
25
|
-
}
|
|
26
|
-
exports.skipTest = skipTest;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empiricalrun/test-gen",
|
|
3
|
-
"version": "0.53.
|
|
3
|
+
"version": "0.53.10",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org/",
|
|
6
6
|
"access": "public"
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
"tsx": "^4.16.2",
|
|
57
57
|
"typescript": "^5.3.3",
|
|
58
58
|
"zod": "^3.23.8",
|
|
59
|
+
"@empiricalrun/llm": "^0.14.5",
|
|
59
60
|
"@empiricalrun/r2-uploader": "^0.3.8",
|
|
60
|
-
"@empiricalrun/test-run": "^0.7.
|
|
61
|
-
"@empiricalrun/llm": "^0.14.5"
|
|
61
|
+
"@empiricalrun/test-run": "^0.7.7"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@playwright/test": "1.47.1",
|