-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create file tools/delete-file.ts * Refactor index.ts to remove unused imports and streamline code. * add delete tool and reorder * axe list repos * repos * add the thing * delete proerply maybe * fix that mayeb
- Loading branch information
1 parent
036ea7f
commit 54b6296
Showing
8 changed files
with
252 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,78 +1,128 @@ | ||
import { z } from "zod" | ||
|
||
async function githubApiRequest(url: string, token: string): Promise<any> { | ||
const response = await fetch(url, { | ||
headers: { | ||
Authorization: `token ${token}`, | ||
Accept: 'application/vnd.github.v3+json', | ||
}, | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error(`GitHub API request failed: ${response.statusText}`); | ||
} | ||
|
||
return response.json(); | ||
async function githubApiRequest(url: string, token: string, method: string = 'GET', body?: any): Promise<any> { | ||
const response = await fetch(url, { | ||
method, | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
Accept: 'application/vnd.github+json', | ||
'X-GitHub-Api-Version': '2022-11-28', | ||
'Content-Type': 'application/json', | ||
}, | ||
body: body ? JSON.stringify(body) : undefined, | ||
}); | ||
|
||
if (!response.ok) { | ||
const errorText = await response.text(); | ||
throw new Error(`GitHub API request failed: ${response.status} ${response.statusText}\n${errorText}`); | ||
} | ||
|
||
return response.json(); | ||
} | ||
|
||
const githubListUserReposArgsSchema = z.object({ | ||
token: z.string(), | ||
perPage: z.number().optional(), | ||
sort: z.enum(['created', 'updated', 'pushed', 'full_name']).optional(), | ||
direction: z.enum(['asc', 'desc']).optional(), | ||
token: z.string(), | ||
perPage: z.number().optional(), | ||
sort: z.enum(['created', 'updated', 'pushed', 'full_name']).optional(), | ||
direction: z.enum(['asc', 'desc']).optional(), | ||
}); | ||
|
||
export async function githubListUserRepos(args: z.infer<typeof githubListUserReposArgsSchema>): Promise<any[]> { | ||
const { token, perPage, sort, direction } = githubListUserReposArgsSchema.parse(args); | ||
const params = new URLSearchParams(); | ||
|
||
if (perPage !== undefined) params.append('per_page', perPage.toString()); | ||
if (sort !== undefined) params.append('sort', sort); | ||
if (direction !== undefined) params.append('direction', direction); | ||
|
||
const url = `https://api.github.com/user/repos?${params.toString()}`; | ||
|
||
const data = await githubApiRequest(url, token); | ||
|
||
if (!Array.isArray(data)) { | ||
throw new Error("Unexpected data format received from GitHub API"); | ||
} | ||
|
||
return data.map(repo => ({ | ||
name: repo.name, | ||
full_name: repo.full_name, | ||
description: repo.description, | ||
html_url: repo.html_url, | ||
private: repo.private, | ||
updated_at: repo.updated_at, | ||
pushed_at: repo.pushed_at, | ||
})); | ||
console.log("are we here") | ||
const { token, perPage, sort, direction } = githubListUserReposArgsSchema.parse(args); | ||
const params = new URLSearchParams(); | ||
|
||
if (perPage !== undefined) params.append('per_page', perPage.toString()); | ||
if (sort !== undefined) params.append('sort', sort); | ||
if (direction !== undefined) params.append('direction', direction); | ||
|
||
const url = `https://api.github.com/user/repos?${params.toString()}`; | ||
|
||
const data = await githubApiRequest(url, token); | ||
|
||
if (!Array.isArray(data)) { | ||
throw new Error("Unexpected data format received from GitHub API"); | ||
} | ||
|
||
return data.map(repo => ({ | ||
name: repo.name, | ||
full_name: repo.full_name, | ||
description: repo.description, | ||
html_url: repo.html_url, | ||
private: repo.private, | ||
updated_at: repo.updated_at, | ||
pushed_at: repo.pushed_at, | ||
})); | ||
} | ||
|
||
export async function githubReadFile(args: { path: string, token: string, repoOwner: string, repoName: string, branch?: string }): Promise<string> { | ||
const { path, token, repoOwner, repoName, branch } = args; | ||
const url = `https://api.github.com/repos/${repoOwner}/${repoName}/contents/${path}${branch ? `?ref=${branch}` : ''}`; | ||
const data = await githubApiRequest(url, token); | ||
if (data.type !== 'file') { | ||
throw new Error('The path does not point to a file'); | ||
} | ||
return Buffer.from(data.content, 'base64').toString('utf-8'); | ||
const { path, token, repoOwner, repoName, branch } = args; | ||
const url = `https://api.github.com/repos/${repoOwner}/${repoName}/contents/${path}${branch ? `?ref=${branch}` : ''}`; | ||
|
||
const data = await githubApiRequest(url, token); | ||
|
||
if (data.type !== 'file') { | ||
throw new Error('The path does not point to a file'); | ||
} | ||
|
||
return Buffer.from(data.content, 'base64').toString('utf-8'); | ||
} | ||
|
||
export async function githubListContents(args: { path: string, token: string, repoOwner: string, repoName: string, branch?: string }): Promise<string[]> { | ||
const { path, token, repoOwner, repoName, branch } = args; | ||
const url = `https://api.github.com/repos/${repoOwner}/${repoName}/contents/${path}${branch ? `?ref=${branch}` : ''}`; | ||
const data = await githubApiRequest(url, token); | ||
if (!Array.isArray(data)) { | ||
throw new Error('The path does not point to a directory'); | ||
} | ||
return data.map((item: any) => item.name); | ||
const { path, token, repoOwner, repoName, branch } = args; | ||
const url = `https://api.github.com/repos/${repoOwner}/${repoName}/contents/${path}${branch ? `?ref=${branch}` : ''}`; | ||
|
||
const data = await githubApiRequest(url, token); | ||
|
||
if (!Array.isArray(data)) { | ||
throw new Error('The path does not point to a directory'); | ||
} | ||
|
||
return data.map((item: any) => item.name); | ||
} | ||
|
||
// ... (rest of the file remains unchanged) | ||
export async function githubDeleteFile(args: { | ||
path: string, | ||
token: string, | ||
repoOwner: string, | ||
repoName: string, | ||
branch?: string, | ||
message?: string, | ||
committerName?: string, | ||
committerEmail?: string | ||
}): Promise<void> { | ||
const { | ||
path, | ||
token, | ||
repoOwner, | ||
repoName, | ||
branch = 'main', | ||
message, | ||
committerName = "GitHub API", | ||
committerEmail = "[email protected]" | ||
} = args; | ||
|
||
// Include the branch in the URL for both GET and DELETE requests | ||
const fileUrl = `https://api.github.com/repos/${repoOwner}/${repoName}/contents/${path}`; | ||
|
||
// First, get the current file to retrieve its SHA | ||
const fileData = await githubApiRequest(`${fileUrl}?ref=${branch}`, token); | ||
|
||
if (!fileData.sha) { | ||
throw new Error(`File not found: ${path} in branch ${branch}`); | ||
} | ||
|
||
// Prepare the request body | ||
const body = { | ||
message: message || `Delete ${path}`, | ||
committer: { | ||
name: committerName, | ||
email: committerEmail | ||
}, | ||
sha: fileData.sha, | ||
branch: branch, | ||
}; | ||
|
||
// Send DELETE request | ||
await githubApiRequest(fileUrl, token, 'DELETE', body); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { tool, CoreTool } from 'ai'; | ||
import { z } from 'zod'; | ||
import { githubDeleteFile } from '@/lib/githubUtils'; | ||
import { ToolContext } from '@/types'; | ||
|
||
const params = z.object({ | ||
path: z.string().describe("The path of the file to delete"), | ||
owner: z.string().optional().describe("The owner of the repository"), | ||
repo: z.string().optional().describe("The name of the repository"), | ||
branch: z.string().optional().describe("The branch to delete the file from"), | ||
}); | ||
|
||
type Params = z.infer<typeof params>; | ||
|
||
type Result = { | ||
success: boolean; | ||
error?: string; | ||
summary: string; | ||
details: string; | ||
}; | ||
|
||
export const deleteFileTool = (context: ToolContext): CoreTool<typeof params, Result> => tool({ | ||
description: "Delete file at path", | ||
parameters: params, | ||
execute: async ({ path, owner, repo, branch }: Params): Promise<Result> => { | ||
const repoOwner = owner || context.repo?.owner; | ||
const repoName = repo || context.repo?.name; | ||
const repoBranch = branch || context.repo?.branch || 'main'; | ||
|
||
if (!repoOwner || !repoName) { | ||
return { | ||
success: false, | ||
error: "Missing repository information", | ||
summary: "Failed to delete file due to missing repository information", | ||
details: "The repository owner or name is missing. Please provide both in the request or ensure they are set in the context." | ||
}; | ||
} | ||
|
||
if (!context.gitHubToken) { | ||
return { | ||
success: false, | ||
error: "Missing GitHub token", | ||
summary: "Failed to delete file due to missing GitHub token", | ||
details: "The GitHub token is missing. Please ensure it is provided in the context." | ||
}; | ||
} | ||
|
||
try { | ||
await githubDeleteFile({ | ||
path, | ||
token: context.gitHubToken, | ||
repoOwner, | ||
repoName, | ||
branch: repoBranch | ||
}); | ||
|
||
return { | ||
success: true, | ||
summary: `Deleted ${path} in ${repoOwner}/${repoName} on branch ${repoBranch}`, | ||
details: `File ${path} in ${repoOwner}/${repoName} on branch ${repoBranch} has been successfully deleted.` | ||
}; | ||
} catch (error: unknown) { | ||
const errorMessage = error instanceof Error ? error.message : String(error); | ||
console.error(errorMessage); | ||
return { | ||
success: false, | ||
error: errorMessage, | ||
summary: `Failed to delete ${path} in ${repoOwner}/${repoName} on branch ${repoBranch}`, | ||
details: `Failed to delete file at ${path} in ${repoOwner}/${repoName} on branch ${repoBranch}. Error: ${errorMessage}` | ||
}; | ||
} | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.