@empiricalrun/test-gen 0.75.0 → 0.76.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/agent/base/index.d.ts +26 -19
- package/dist/agent/base/index.d.ts.map +1 -1
- package/dist/agent/base/index.js +88 -56
- package/dist/agent/chat/agent-loop.d.ts +4 -3
- package/dist/agent/chat/agent-loop.d.ts.map +1 -1
- package/dist/agent/chat/agent-loop.js +4 -10
- package/dist/agent/chat/exports.d.ts +4 -2
- package/dist/agent/chat/exports.d.ts.map +1 -1
- package/dist/agent/chat/exports.js +8 -7
- package/dist/agent/chat/index.d.ts +6 -10
- package/dist/agent/chat/index.d.ts.map +1 -1
- package/dist/agent/chat/index.js +129 -196
- package/dist/agent/chat/prompt/index.d.ts +5 -4
- package/dist/agent/chat/prompt/index.d.ts.map +1 -1
- package/dist/agent/chat/prompt/index.js +79 -68
- package/dist/agent/chat/state.d.ts +1 -2
- package/dist/agent/chat/state.d.ts.map +1 -1
- package/dist/agent/chat/state.js +2 -2
- package/dist/agent/chat/utils.d.ts +2 -3
- package/dist/agent/chat/utils.d.ts.map +1 -1
- package/dist/agent/chat/utils.js +1 -2
- package/dist/agent/cli.d.ts +11 -0
- package/dist/agent/cli.d.ts.map +1 -0
- package/dist/agent/cli.js +209 -0
- package/dist/agent/code-review/index.d.ts +7 -0
- package/dist/agent/code-review/index.d.ts.map +1 -0
- package/dist/agent/code-review/index.js +65 -0
- package/dist/agent/code-review/prompt.d.ts +1 -1
- package/dist/agent/code-review/prompt.d.ts.map +1 -1
- package/dist/agent/code-review/prompt.js +52 -16
- package/dist/agent/index.d.ts +10 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +19 -0
- package/dist/agent/triage/index.d.ts +7 -0
- package/dist/agent/triage/index.d.ts.map +1 -0
- package/dist/agent/triage/index.js +102 -0
- package/dist/agent/video-analysis/index.d.ts +7 -0
- package/dist/agent/video-analysis/index.d.ts.map +1 -0
- package/dist/agent/video-analysis/index.js +35 -0
- package/dist/bin/index.js +6 -6
- package/dist/file-info/adapters/github/index.d.ts.map +1 -1
- package/dist/file-info/adapters/github/index.js +1 -2
- package/dist/file-info/adapters/github/reader.d.ts +4 -9
- package/dist/file-info/adapters/github/reader.d.ts.map +1 -1
- package/dist/file-info/adapters/github/reader.js +163 -134
- package/dist/tools/create-pull-request/index.d.ts.map +1 -0
- package/dist/tools/{definitions/commit-and-create-pr.js → create-pull-request/index.js} +30 -1
- package/dist/tools/create-pull-request/utils.d.ts +21 -0
- package/dist/tools/create-pull-request/utils.d.ts.map +1 -0
- package/dist/tools/create-pull-request/utils.js +83 -0
- package/dist/tools/definitions/extract-frames-from-video.d.ts +39 -0
- package/dist/tools/definitions/extract-frames-from-video.d.ts.map +1 -0
- package/dist/tools/definitions/extract-frames-from-video.js +60 -0
- package/dist/tools/definitions/fetch-video-analysis.d.ts +4 -4
- package/dist/tools/executor/index.d.ts +1 -1
- package/dist/tools/executor/index.d.ts.map +1 -1
- package/dist/tools/executor/index.js +18 -4
- package/dist/tools/extract-frames-from-video/index.d.ts +7 -0
- package/dist/tools/extract-frames-from-video/index.d.ts.map +1 -0
- package/dist/tools/extract-frames-from-video/index.js +145 -0
- package/dist/tools/fetch-session-diff/index.d.ts +3 -0
- package/dist/tools/fetch-session-diff/index.d.ts.map +1 -0
- package/dist/tools/fetch-session-diff/index.js +46 -0
- package/dist/tools/fetch-video-analysis/index.d.ts.map +1 -1
- package/dist/tools/fetch-video-analysis/index.js +18 -7
- package/dist/tools/fetch-video-analysis/utils.d.ts +5 -2
- package/dist/tools/fetch-video-analysis/utils.d.ts.map +1 -1
- package/dist/tools/fetch-video-analysis/utils.js +34 -11
- package/dist/tools/fetch-video-analysis/video-analysis.d.ts +2 -2
- package/dist/tools/fetch-video-analysis/video-analysis.d.ts.map +1 -1
- package/dist/tools/fetch-video-analysis/video-analysis.js +24 -8
- package/dist/tools/index.d.ts +28 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +46 -28
- package/dist/tools/review-pull-request/index.d.ts +3 -0
- package/dist/tools/review-pull-request/index.d.ts.map +1 -0
- package/dist/tools/review-pull-request/index.js +103 -0
- package/dist/tools/test-run-fetcher/index.d.ts.map +1 -1
- package/dist/tools/test-run-fetcher/index.js +4 -14
- package/dist/tools/utils/urls.d.ts +5 -0
- package/dist/tools/utils/urls.d.ts.map +1 -0
- package/dist/tools/utils/urls.js +19 -0
- package/dist/tools/view-failed-test-run-report/index.d.ts.map +1 -1
- package/dist/tools/view-failed-test-run-report/index.js +3 -15
- package/dist/utils/file.d.ts +1 -0
- package/dist/utils/file.d.ts.map +1 -1
- package/dist/utils/file.js +45 -1
- package/dist/{tools/fetch-video-analysis → utils}/local-ffmpeg-client.d.ts +4 -0
- package/dist/utils/local-ffmpeg-client.d.ts.map +1 -0
- package/dist/{tools/fetch-video-analysis → utils}/local-ffmpeg-client.js +63 -11
- package/package.json +2 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/agent/chat/utils/tool-calls.d.ts +0 -21
- package/dist/agent/chat/utils/tool-calls.d.ts.map +0 -1
- package/dist/agent/chat/utils/tool-calls.js +0 -64
- package/dist/tools/commit-and-create-pr/index.d.ts.map +0 -1
- package/dist/tools/commit-and-create-pr/index.js +0 -83
- package/dist/tools/definitions/commit-and-create-pr.d.ts +0 -3
- package/dist/tools/definitions/commit-and-create-pr.d.ts.map +0 -1
- package/dist/tools/fetch-video-analysis/local-ffmpeg-client.d.ts.map +0 -1
- /package/dist/tools/{commit-and-create-pr → create-pull-request}/index.d.ts +0 -0
|
@@ -2,15 +2,10 @@ import { FileInfo, FileReadResult, IDashboardAPIClient } from "@empiricalrun/sha
|
|
|
2
2
|
export declare class GitHubFileReader {
|
|
3
3
|
private repoName;
|
|
4
4
|
private apiClient;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
private fetchFileFromGitHub;
|
|
8
|
-
private fetchTreeFromGitHub;
|
|
9
|
-
private resolveBranchName;
|
|
5
|
+
constructor(repoName: string, apiClient: IDashboardAPIClient);
|
|
6
|
+
resolveBranchName(branchName: string | undefined, baseBranch?: string): Promise<string>;
|
|
10
7
|
readFile(filePath: string, branchName: string, baseBranch: string): Promise<FileReadResult | null>;
|
|
11
|
-
private
|
|
12
|
-
private getContentsForDirectory;
|
|
13
|
-
getFileInfo(branchName: string, baseBranch: string): Promise<FileInfo>;
|
|
8
|
+
private readDirectory;
|
|
14
9
|
}
|
|
15
|
-
export declare function getFileInfoFromGitHub(repoName: string, apiClient: IDashboardAPIClient, branchName: string,
|
|
10
|
+
export declare function getFileInfoFromGitHub(repoName: string, apiClient: IDashboardAPIClient, branchName: string, baseBranchName: string): Promise<FileInfo>;
|
|
16
11
|
//# sourceMappingURL=reader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../../../src/file-info/adapters/github/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,cAAc,EACd,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../../../src/file-info/adapters/github/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,cAAc,EACd,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAcpC,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,SAAS;gBADT,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,mBAAmB;IAGlC,iBAAiB,CACrB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,UAAU,GAAE,MAAe,GAC1B,OAAO,CAAC,MAAM,CAAC;IAsBZ,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;YA4CnB,aAAa;CA8C5B;AAyED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,QAAQ,CAAC,CAyFnB"}
|
|
@@ -6,181 +6,210 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.GitHubFileReader = void 0;
|
|
7
7
|
exports.getFileInfoFromGitHub = getFileInfoFromGitHub;
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const dashboard_1 = require("../../../dashboard");
|
|
10
|
-
const REPO_OWNER = "empirical-run";
|
|
11
9
|
class GitHubFileReader {
|
|
12
10
|
repoName;
|
|
13
11
|
apiClient;
|
|
14
|
-
|
|
15
|
-
constructor(repoName, apiClient, repoOwner) {
|
|
12
|
+
constructor(repoName, apiClient) {
|
|
16
13
|
this.repoName = repoName;
|
|
17
14
|
this.apiClient = apiClient;
|
|
18
|
-
this.repoOwner = repoOwner;
|
|
19
15
|
}
|
|
20
|
-
async
|
|
21
|
-
return (await this.apiClient.callGitHubProxy({
|
|
22
|
-
method: "GET",
|
|
23
|
-
url: `/repos/${this.repoOwner}/${this.repoName}/contents/${filePath}?ref=${branch}`,
|
|
24
|
-
}));
|
|
25
|
-
}
|
|
26
|
-
async fetchTreeFromGitHub(branch) {
|
|
27
|
-
return (await this.apiClient.callGitHubProxy({
|
|
28
|
-
method: "GET",
|
|
29
|
-
url: `/repos/${this.repoOwner}/${this.repoName}/git/trees/${branch}?recursive=1`,
|
|
30
|
-
}));
|
|
31
|
-
}
|
|
32
|
-
async resolveBranchName(branchName, baseBranch) {
|
|
16
|
+
async resolveBranchName(branchName, baseBranch = "main") {
|
|
33
17
|
if (!branchName || branchName === baseBranch) {
|
|
34
18
|
return baseBranch;
|
|
35
19
|
}
|
|
36
20
|
try {
|
|
37
|
-
// Try to fetch the branch to see if it exists
|
|
21
|
+
// Try to fetch the branch to see if it exists via GitHub proxy
|
|
38
22
|
await this.apiClient.callGitHubProxy({
|
|
39
23
|
method: "GET",
|
|
40
|
-
url: `/repos/${this.
|
|
24
|
+
url: `/repos/empirical-run/${this.repoName}/branches/${branchName}`,
|
|
41
25
|
});
|
|
26
|
+
console.log(`[GitHubFileReader] Branch ${branchName} exists`);
|
|
42
27
|
return branchName;
|
|
43
28
|
}
|
|
44
29
|
catch {
|
|
45
30
|
// Branch doesn't exist, fallback to base branch
|
|
31
|
+
console.log(`[GitHubFileReader] Branch ${branchName} not found, falling back to ${baseBranch}`);
|
|
46
32
|
return baseBranch;
|
|
47
33
|
}
|
|
48
34
|
}
|
|
49
35
|
async readFile(filePath, branchName, baseBranch) {
|
|
50
|
-
const
|
|
51
|
-
|
|
36
|
+
const resolvedBranch = await this.resolveBranchName(branchName, baseBranch);
|
|
37
|
+
// Check if path has file extension - if not, treat as directory
|
|
38
|
+
const hasFileExtension = path_1.default.extname(filePath) !== "";
|
|
39
|
+
if (!hasFileExtension) {
|
|
40
|
+
console.log(`[GitHubFileReader] Reading as directory: ${filePath}`);
|
|
41
|
+
return this.readDirectory(filePath, resolvedBranch);
|
|
42
|
+
}
|
|
52
43
|
try {
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
else {
|
|
44
|
+
console.log(`[GitHubFileReader] Reading as file: ${filePath}, resolved branch: ${resolvedBranch}`);
|
|
45
|
+
const params = {
|
|
46
|
+
repo: this.repoName,
|
|
47
|
+
path: filePath,
|
|
48
|
+
ref: resolvedBranch,
|
|
49
|
+
};
|
|
50
|
+
const response = await this.apiClient.request(`/api/github/files`, {
|
|
51
|
+
method: "GET",
|
|
52
|
+
params,
|
|
53
|
+
});
|
|
54
|
+
if (response.data?.fileContents.available) {
|
|
65
55
|
return {
|
|
66
|
-
content: response.
|
|
67
|
-
isDirectory:
|
|
56
|
+
content: response.data.fileContents.content,
|
|
57
|
+
isDirectory: false,
|
|
68
58
|
};
|
|
69
59
|
}
|
|
60
|
+
console.log(`[GitHubFileReader] File not available: ${filePath}`);
|
|
61
|
+
// For file paths (with extensions), don't fall back to directory reading
|
|
62
|
+
return null;
|
|
70
63
|
}
|
|
71
64
|
catch (error) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
throw error; // Re-throw other errors
|
|
65
|
+
console.log(`[GitHubFileReader] Error reading file ${filePath}:`, error);
|
|
66
|
+
// For file paths, return null (file not found)
|
|
67
|
+
return null;
|
|
76
68
|
}
|
|
77
|
-
return null;
|
|
78
69
|
}
|
|
79
|
-
async
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
70
|
+
async readDirectory(filePath, resolvedBranch) {
|
|
71
|
+
try {
|
|
72
|
+
console.log(`[GitHubFileReader] Reading directory: ${filePath}, resolved branch: ${resolvedBranch}`);
|
|
73
|
+
const params = {
|
|
74
|
+
repo: this.repoName,
|
|
75
|
+
path: filePath || ".", // Handle empty path
|
|
76
|
+
ref: resolvedBranch,
|
|
77
|
+
};
|
|
78
|
+
const treeResponse = await this.apiClient.request(`/api/github/tree`, {
|
|
79
|
+
method: "GET",
|
|
80
|
+
params,
|
|
81
|
+
});
|
|
82
|
+
if (treeResponse.data?.tree) {
|
|
83
|
+
const targetPath = filePath === "." || filePath === "" ? "" : filePath;
|
|
84
|
+
const files = treeResponse.data.tree.tree
|
|
85
|
+
.map((item) => item.path)
|
|
86
|
+
.filter((itemPath) => {
|
|
87
|
+
if (!itemPath)
|
|
88
|
+
return false;
|
|
89
|
+
// Check if item is a direct child of the target directory
|
|
90
|
+
const itemDir = path_1.default.dirname(itemPath);
|
|
91
|
+
// Normalize "." to "" for root directory comparison
|
|
92
|
+
const normalizedItemDir = itemDir === "." ? "" : itemDir;
|
|
93
|
+
return normalizedItemDir === targetPath;
|
|
94
|
+
})
|
|
95
|
+
.map((itemPath) => path_1.default.basename(itemPath))
|
|
96
|
+
.sort()
|
|
97
|
+
.join("\n");
|
|
98
|
+
return { content: files, isDirectory: true };
|
|
99
|
+
}
|
|
85
100
|
}
|
|
86
|
-
|
|
87
|
-
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.log(`[GitHubFileReader] Error reading directory ${filePath}:`, error);
|
|
88
103
|
}
|
|
89
|
-
|
|
104
|
+
return null;
|
|
90
105
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
}
|
|
107
|
+
exports.GitHubFileReader = GitHubFileReader;
|
|
108
|
+
async function getFileContent(repoName, path, apiClient, branchName) {
|
|
109
|
+
const params = {
|
|
110
|
+
repo: repoName,
|
|
111
|
+
path: path,
|
|
112
|
+
};
|
|
113
|
+
if (branchName) {
|
|
114
|
+
params.ref = branchName;
|
|
115
|
+
}
|
|
116
|
+
const response = await apiClient.request(`/api/github/files`, {
|
|
117
|
+
method: "GET",
|
|
118
|
+
params,
|
|
119
|
+
});
|
|
120
|
+
if (!response.data) {
|
|
121
|
+
throw new Error(`Unable to fetch file for FileInfo`);
|
|
122
|
+
}
|
|
123
|
+
return response.data.fileContents.content;
|
|
124
|
+
}
|
|
125
|
+
async function getContentsForDirectory({ repo, path, }, apiClient, branchName) {
|
|
126
|
+
const params = {
|
|
127
|
+
repo: repo,
|
|
128
|
+
path: path,
|
|
129
|
+
};
|
|
130
|
+
if (branchName) {
|
|
131
|
+
params.ref = branchName;
|
|
132
|
+
}
|
|
133
|
+
const response = await apiClient.request(`/api/github/tree`, {
|
|
134
|
+
method: "GET",
|
|
135
|
+
params,
|
|
136
|
+
});
|
|
137
|
+
if (!response.data) {
|
|
138
|
+
throw new Error(`Unable to fetch file for FileInfo`);
|
|
139
|
+
}
|
|
140
|
+
return response.data.tree;
|
|
141
|
+
}
|
|
142
|
+
async function getFileInfoFromGitHub(repoName, apiClient, branchName, baseBranchName) {
|
|
143
|
+
// Use GitHubFileReader to resolve the branch
|
|
144
|
+
const fileReader = new GitHubFileReader(repoName, apiClient);
|
|
145
|
+
const resolvedBranch = await fileReader.resolveBranchName(branchName, baseBranchName);
|
|
146
|
+
const files = await getContentsForDirectory({ repo: repoName, path: "" }, apiClient, resolvedBranch);
|
|
147
|
+
const root = [];
|
|
148
|
+
const nodeMap = {};
|
|
149
|
+
if (!files) {
|
|
150
|
+
return {
|
|
151
|
+
type: "directory",
|
|
152
|
+
path: repoName,
|
|
153
|
+
name: repoName,
|
|
154
|
+
children: [],
|
|
155
|
+
};
|
|
108
156
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
157
|
+
files.tree.forEach((file) => {
|
|
158
|
+
if (!file.path) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const pathParts = file.path.split("/");
|
|
162
|
+
const fileName = path_1.default.basename(file.path);
|
|
163
|
+
const isFile = file.type === "blob";
|
|
164
|
+
const currentPath = file.path;
|
|
165
|
+
const currentNode = isFile
|
|
166
|
+
? {
|
|
167
|
+
type: "file",
|
|
168
|
+
path: currentPath,
|
|
169
|
+
name: fileName,
|
|
170
|
+
getContent: async () => getFileContent(repoName, currentPath, apiClient, resolvedBranch),
|
|
171
|
+
}
|
|
172
|
+
: {
|
|
116
173
|
type: "directory",
|
|
117
|
-
path:
|
|
118
|
-
name:
|
|
174
|
+
path: currentPath,
|
|
175
|
+
name: fileName,
|
|
119
176
|
children: [],
|
|
120
177
|
};
|
|
178
|
+
nodeMap[currentPath] = currentNode;
|
|
179
|
+
if (pathParts.length === 1) {
|
|
180
|
+
root.push(currentNode);
|
|
121
181
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const pathParts = file.path.split("/");
|
|
127
|
-
const fileName = path_1.default.basename(file.path);
|
|
128
|
-
const isFile = file.type === "blob";
|
|
129
|
-
const currentPath = file.path;
|
|
130
|
-
const currentNode = isFile
|
|
131
|
-
? {
|
|
132
|
-
type: "file",
|
|
133
|
-
path: currentPath,
|
|
134
|
-
name: fileName,
|
|
135
|
-
getContent: async () => this.getFileContent(currentPath, branchName, baseBranch),
|
|
136
|
-
}
|
|
137
|
-
: {
|
|
182
|
+
else {
|
|
183
|
+
const parentPath = path_1.default.dirname(currentPath);
|
|
184
|
+
if (!nodeMap[parentPath]) {
|
|
185
|
+
const parentNode = {
|
|
138
186
|
type: "directory",
|
|
139
|
-
path:
|
|
140
|
-
name:
|
|
187
|
+
path: parentPath,
|
|
188
|
+
name: parentPath.split("/").pop() || "",
|
|
141
189
|
children: [],
|
|
142
190
|
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
else {
|
|
148
|
-
const parentPath = path_1.default.dirname(currentPath);
|
|
149
|
-
if (!nodeMap[parentPath]) {
|
|
150
|
-
const parentNode = {
|
|
151
|
-
type: "directory",
|
|
152
|
-
path: parentPath,
|
|
153
|
-
name: parentPath.split("/").pop() || "",
|
|
154
|
-
children: [],
|
|
155
|
-
};
|
|
156
|
-
nodeMap[parentPath] = parentNode;
|
|
157
|
-
const parentPathParts = parentPath.split("/");
|
|
158
|
-
if (parentPathParts.length === 1) {
|
|
159
|
-
root.push(parentNode);
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
const grandparentPath = path_1.default.dirname(parentPath);
|
|
163
|
-
if (nodeMap[grandparentPath] &&
|
|
164
|
-
nodeMap[grandparentPath].type === "directory") {
|
|
165
|
-
nodeMap[grandparentPath].children.push(parentNode);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
191
|
+
nodeMap[parentPath] = parentNode;
|
|
192
|
+
const parentPathParts = parentPath.split("/");
|
|
193
|
+
if (parentPathParts.length === 1) {
|
|
194
|
+
root.push(parentNode);
|
|
168
195
|
}
|
|
169
|
-
|
|
170
|
-
|
|
196
|
+
else {
|
|
197
|
+
const grandparentPath = path_1.default.dirname(parentPath);
|
|
198
|
+
if (nodeMap[grandparentPath] &&
|
|
199
|
+
nodeMap[grandparentPath].type === "directory") {
|
|
200
|
+
nodeMap[grandparentPath].children.push(parentNode);
|
|
201
|
+
}
|
|
171
202
|
}
|
|
172
203
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const fileReader = new GitHubFileReader(repoName, apiClient, REPO_OWNER);
|
|
185
|
-
return fileReader.getFileInfo(branchName, baseBranch);
|
|
204
|
+
if (nodeMap[parentPath].type === "directory") {
|
|
205
|
+
nodeMap[parentPath].children.push(currentNode);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
return {
|
|
210
|
+
type: "directory",
|
|
211
|
+
path: repoName,
|
|
212
|
+
name: repoName,
|
|
213
|
+
children: root,
|
|
214
|
+
};
|
|
186
215
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/create-pull-request/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AA6BvD,eAAO,MAAM,qBAAqB,EAAE,IAwDnC,CAAC"}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createPullRequestTool = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
+
const utils_1 = require("../executor/utils");
|
|
6
|
+
const utils_2 = require("./utils");
|
|
7
|
+
const REPO_OWNER = "empirical-run";
|
|
5
8
|
const createPullRequestSchema = zod_1.z.object({
|
|
6
9
|
pullRequestTitle: zod_1.z
|
|
7
10
|
.string()
|
|
@@ -27,5 +30,31 @@ Don't ask the user for this information, just come up with it yourself.
|
|
|
27
30
|
parameters: createPullRequestSchema,
|
|
28
31
|
},
|
|
29
32
|
needsBrowser: false,
|
|
30
|
-
isInlineTool:
|
|
33
|
+
isInlineTool: true,
|
|
34
|
+
execute: async ({ input, apiClient, chatSession }) => {
|
|
35
|
+
const owner = REPO_OWNER;
|
|
36
|
+
try {
|
|
37
|
+
const valids = await (0, utils_2.validateInputs)({ input, apiClient, chatSession });
|
|
38
|
+
const { pullRequestTitle, pullRequestDescription, branchName } = valids;
|
|
39
|
+
const repo = await (0, utils_2.getRepoName)(chatSession, apiClient);
|
|
40
|
+
const existingPR = await (0, utils_1.getExistingPR)({
|
|
41
|
+
owner,
|
|
42
|
+
repo,
|
|
43
|
+
branchName,
|
|
44
|
+
apiClient: apiClient,
|
|
45
|
+
});
|
|
46
|
+
if (existingPR) {
|
|
47
|
+
return await (0, utils_2.handleExistingPullRequest)(existingPR, owner, repo, pullRequestDescription, chatSession, apiClient);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
return await (0, utils_2.handleNewPullRequest)(owner, repo, pullRequestTitle, branchName, chatSession, pullRequestDescription, apiClient);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
return {
|
|
55
|
+
isError: true,
|
|
56
|
+
result: `Failed to commit and push changes: ${error instanceof Error ? error.message : String(error)}`,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
},
|
|
31
60
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ChatSessionInfo, IDashboardAPIClient } from "@empiricalrun/shared-types";
|
|
2
|
+
export interface ValidatedInputs {
|
|
3
|
+
pullRequestTitle: string;
|
|
4
|
+
pullRequestDescription: string;
|
|
5
|
+
branchName: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function validateInputs({ input, apiClient, chatSession, }: any): Promise<ValidatedInputs>;
|
|
8
|
+
export declare function getRepoName(chatSession: ChatSessionInfo | null | undefined, apiClient: IDashboardAPIClient): Promise<string>;
|
|
9
|
+
export declare function getMergeableStateInfo(owner: string, repo: string, pullRequest: any, apiClient: any): Promise<{
|
|
10
|
+
mergeableState: "unknown" | "clean" | "dirty" | "unstable";
|
|
11
|
+
stateDescription: string;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function handleExistingPullRequest(pullRequest: any, owner: string, repo: string, pullRequestDescription: string, chatSession: any, apiClient: any): Promise<{
|
|
14
|
+
isError: boolean;
|
|
15
|
+
result: string;
|
|
16
|
+
}>;
|
|
17
|
+
export declare function handleNewPullRequest(owner: string, repo: string, pullRequestTitle: string, branchName: string, chatSession: any, pullRequestDescription: string, apiClient: any): Promise<{
|
|
18
|
+
isError: boolean;
|
|
19
|
+
result: string;
|
|
20
|
+
}>;
|
|
21
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tools/create-pull-request/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,mBAAmB,EAEpB,MAAM,4BAA4B,CAAC;AAUpC,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,cAAc,CAAC,EACnC,KAAK,EACL,SAAS,EACT,WAAW,GACZ,EAAE,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,CAehC;AAED,wBAAsB,WAAW,CAC/B,WAAW,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAC/C,SAAS,EAAE,mBAAmB,GAC7B,OAAO,CAAC,MAAM,CAAC,CA2BjB;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,GAAG,EAChB,SAAS,EAAE,GAAG;;;GAUf;AAED,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,GAAG,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,sBAAsB,EAAE,MAAM,EAC9B,WAAW,EAAE,GAAG,EAChB,SAAS,EAAE,GAAG;;;GAqBf;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EACxB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,GAAG,EAChB,sBAAsB,EAAE,MAAM,EAC9B,SAAS,EAAE,GAAG;;;GAuBf"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateInputs = validateInputs;
|
|
4
|
+
exports.getRepoName = getRepoName;
|
|
5
|
+
exports.getMergeableStateInfo = getMergeableStateInfo;
|
|
6
|
+
exports.handleExistingPullRequest = handleExistingPullRequest;
|
|
7
|
+
exports.handleNewPullRequest = handleNewPullRequest;
|
|
8
|
+
const utils_1 = require("../executor/utils");
|
|
9
|
+
const pr_description_1 = require("../executor/utils/pr-description");
|
|
10
|
+
async function validateInputs({ input, apiClient, chatSession, }) {
|
|
11
|
+
const { pullRequestTitle, pullRequestDescription } = input;
|
|
12
|
+
const branchName = chatSession?.branchName;
|
|
13
|
+
if (!apiClient) {
|
|
14
|
+
throw new Error("Dashboard API client is not available.");
|
|
15
|
+
}
|
|
16
|
+
if (!branchName) {
|
|
17
|
+
throw new Error("Branch name is not available in the chat session.");
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
pullRequestTitle,
|
|
21
|
+
pullRequestDescription,
|
|
22
|
+
branchName,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
async function getRepoName(chatSession, apiClient) {
|
|
26
|
+
if (!chatSession?.id) {
|
|
27
|
+
throw new Error("Cannot create pull request without repo name or chat session ID.");
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const url = `/api/chat-sessions/${chatSession.id}/details`;
|
|
31
|
+
const sessionDetails = await apiClient.request(url, { method: "GET" });
|
|
32
|
+
if ("error" in sessionDetails) {
|
|
33
|
+
throw new Error(`Failed to fetch session details: ${sessionDetails.error}`);
|
|
34
|
+
}
|
|
35
|
+
if (!sessionDetails.gitPayload?.repoName) {
|
|
36
|
+
throw new Error("Repository name not found in session details.");
|
|
37
|
+
}
|
|
38
|
+
return sessionDetails.gitPayload.repoName;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw new Error(`Failed to fetch repository name: ${error instanceof Error ? error.message : String(error)}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function getMergeableStateInfo(owner, repo, pullRequest, apiClient) {
|
|
45
|
+
const mergeableState = await (0, utils_1.getMergeableState)({
|
|
46
|
+
owner,
|
|
47
|
+
repo,
|
|
48
|
+
pullRequest,
|
|
49
|
+
apiClient,
|
|
50
|
+
});
|
|
51
|
+
const stateDescription = (0, utils_1.getMergeableStateDescription)(mergeableState);
|
|
52
|
+
return { mergeableState, stateDescription };
|
|
53
|
+
}
|
|
54
|
+
async function handleExistingPullRequest(pullRequest, owner, repo, pullRequestDescription, chatSession, apiClient) {
|
|
55
|
+
const updatedPR = await (0, utils_1.updatePullRequest)({
|
|
56
|
+
owner,
|
|
57
|
+
repo,
|
|
58
|
+
prNumber: pullRequest.number,
|
|
59
|
+
body: (0, pr_description_1.addMetadataToPRDescription)(pullRequestDescription, chatSession),
|
|
60
|
+
apiClient,
|
|
61
|
+
});
|
|
62
|
+
const { mergeableState, stateDescription } = await getMergeableStateInfo(owner, repo, updatedPR, apiClient);
|
|
63
|
+
return {
|
|
64
|
+
isError: false,
|
|
65
|
+
result: `Updated existing PR: ${updatedPR.html_url}\n\nMergeable state: ${mergeableState} - ${stateDescription}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async function handleNewPullRequest(owner, repo, pullRequestTitle, branchName, chatSession, pullRequestDescription, apiClient) {
|
|
69
|
+
const newPR = await (0, utils_1.createPullRequest)({
|
|
70
|
+
owner,
|
|
71
|
+
repo,
|
|
72
|
+
title: pullRequestTitle,
|
|
73
|
+
head: branchName,
|
|
74
|
+
base: chatSession?.baseBranchName || "main",
|
|
75
|
+
body: (0, pr_description_1.addMetadataToPRDescription)(pullRequestDescription, chatSession),
|
|
76
|
+
apiClient,
|
|
77
|
+
});
|
|
78
|
+
const { mergeableState, stateDescription } = await getMergeableStateInfo(owner, repo, newPR, apiClient);
|
|
79
|
+
return {
|
|
80
|
+
isError: false,
|
|
81
|
+
result: `Created a new PR: ${newPR.html_url}\n\nMergeable state: ${mergeableState} - ${stateDescription}`,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ToolDefinition } from "@empiricalrun/shared-types";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
export declare const extractFramesFromVideoSchema: z.ZodObject<{
|
|
4
|
+
videoUrl: z.ZodString;
|
|
5
|
+
params: z.ZodOptional<z.ZodObject<{
|
|
6
|
+
fps: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
7
|
+
threshold: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
|
|
8
|
+
startTime: z.ZodOptional<z.ZodString>;
|
|
9
|
+
duration: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
startTime?: string | undefined;
|
|
12
|
+
threshold?: number | undefined;
|
|
13
|
+
fps?: number | undefined;
|
|
14
|
+
duration?: string | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
startTime?: string | undefined;
|
|
17
|
+
threshold?: number | undefined;
|
|
18
|
+
fps?: number | undefined;
|
|
19
|
+
duration?: string | undefined;
|
|
20
|
+
}>>;
|
|
21
|
+
}, "strip", z.ZodTypeAny, {
|
|
22
|
+
videoUrl: string;
|
|
23
|
+
params?: {
|
|
24
|
+
startTime?: string | undefined;
|
|
25
|
+
threshold?: number | undefined;
|
|
26
|
+
fps?: number | undefined;
|
|
27
|
+
duration?: string | undefined;
|
|
28
|
+
} | undefined;
|
|
29
|
+
}, {
|
|
30
|
+
videoUrl: string;
|
|
31
|
+
params?: {
|
|
32
|
+
startTime?: string | undefined;
|
|
33
|
+
threshold?: number | undefined;
|
|
34
|
+
fps?: number | undefined;
|
|
35
|
+
duration?: string | undefined;
|
|
36
|
+
} | undefined;
|
|
37
|
+
}>;
|
|
38
|
+
export declare const extractFramesFromVideo: ToolDefinition<z.infer<typeof extractFramesFromVideoSchema>>;
|
|
39
|
+
//# sourceMappingURL=extract-frames-from-video.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-frames-from-video.d.ts","sourceRoot":"","sources":["../../../src/tools/definitions/extract-frames-from-video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCvC,CAAC;AAEH,eAAO,MAAM,sBAAsB,EAAE,cAAc,CACjD,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAoB7C,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
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.extractFramesFromVideo = exports.extractFramesFromVideoSchema = void 0;
|
|
7
|
+
const zod_1 = __importDefault(require("zod"));
|
|
8
|
+
exports.extractFramesFromVideoSchema = zod_1.default.object({
|
|
9
|
+
videoUrl: zod_1.default
|
|
10
|
+
.string()
|
|
11
|
+
.url("Must be a valid URL")
|
|
12
|
+
.describe("The URL of the video to extract frames from."),
|
|
13
|
+
params: zod_1.default
|
|
14
|
+
.object({
|
|
15
|
+
fps: zod_1.default
|
|
16
|
+
.number()
|
|
17
|
+
.int()
|
|
18
|
+
.min(1)
|
|
19
|
+
.max(120)
|
|
20
|
+
.default(30)
|
|
21
|
+
.optional()
|
|
22
|
+
.describe("Frames per second to extract from the video (default: 30)"),
|
|
23
|
+
threshold: zod_1.default
|
|
24
|
+
.number()
|
|
25
|
+
.min(0)
|
|
26
|
+
.max(0.5)
|
|
27
|
+
.default(0.001)
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Deduplication threshold (fraction of pixels that may differ to consider frames identical). Lower = stricter. Default: 0.001"),
|
|
30
|
+
startTime: zod_1.default
|
|
31
|
+
.string()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Start time in format MM:SS, example 1 min 32 sec -> 01:32"),
|
|
34
|
+
duration: zod_1.default
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("Duration time in format MM:SS, example 1 min 32 sec -> 01:32"),
|
|
38
|
+
})
|
|
39
|
+
.optional(),
|
|
40
|
+
});
|
|
41
|
+
exports.extractFramesFromVideo = {
|
|
42
|
+
schema: {
|
|
43
|
+
name: "extractFramesFromVideo",
|
|
44
|
+
description: `
|
|
45
|
+
Extracts frames from a video with precise timing control.
|
|
46
|
+
|
|
47
|
+
**Input:** Video URL (required), optional parameters for timing, frame rate, and output format
|
|
48
|
+
**Output:** PNG formate Frame URLs with metadata.
|
|
49
|
+
**Use when:** You need specific frames from a video segment, want to analyze particular time ranges, or need distinct frames fromthe video, or just need all frames from the video for further processing
|
|
50
|
+
|
|
51
|
+
**Key Features:**
|
|
52
|
+
- Time-based frame extraction (start time + duration)
|
|
53
|
+
- Configurable frame rate and deduplication threshold
|
|
54
|
+
- Frame metadata including timestamps and indices
|
|
55
|
+
- Memory-efficient processing for large videos`,
|
|
56
|
+
parameters: exports.extractFramesFromVideoSchema,
|
|
57
|
+
},
|
|
58
|
+
needsBrowser: false,
|
|
59
|
+
isInlineTool: false,
|
|
60
|
+
};
|