cleanup mcp server too
This commit is contained in:
@@ -126416,7 +126416,7 @@ async function startMcpHttpServer(ctx) {
|
|||||||
const url2 = `http://${host}:${port}${endpoint2}`;
|
const url2 = `http://${host}:${port}${endpoint2}`;
|
||||||
return {
|
return {
|
||||||
url: url2,
|
url: url2,
|
||||||
close: async () => {
|
[Symbol.asyncDispose]: async () => {
|
||||||
await server.stop();
|
await server.stop();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -126556,120 +126556,125 @@ var Inputs = type({
|
|||||||
...keyInputDefs
|
...keyInputDefs
|
||||||
});
|
});
|
||||||
async function main(inputs) {
|
async function main(inputs) {
|
||||||
var _stack = [];
|
var _stack2 = [];
|
||||||
try {
|
try {
|
||||||
const timer = new Timer();
|
const timer = new Timer();
|
||||||
const installationToken = __using(_stack, await setupGitHubInstallationToken(), true);
|
const tokenRef = __using(_stack2, await setupGitHubInstallationToken(), true);
|
||||||
let mcpServerClose;
|
|
||||||
let payload;
|
let payload;
|
||||||
try {
|
try {
|
||||||
payload = parsePayload(inputs);
|
var _stack = [];
|
||||||
Inputs.assert(inputs);
|
try {
|
||||||
setupGitConfig();
|
payload = parsePayload(inputs);
|
||||||
const [githubSetup, sharedTempDir] = await Promise.all([
|
Inputs.assert(inputs);
|
||||||
initializeGitHub(installationToken.token),
|
setupGitConfig();
|
||||||
createTempDirectory()
|
const [githubSetup, sharedTempDir] = await Promise.all([
|
||||||
]);
|
initializeGitHub(tokenRef.token),
|
||||||
timer.checkpoint("githubSetup");
|
createTempDirectory()
|
||||||
const agent2 = resolveAgent({
|
]);
|
||||||
inputs,
|
timer.checkpoint("githubSetup");
|
||||||
payload,
|
const agent2 = resolveAgent({
|
||||||
repoSettings: githubSetup.repoSettings
|
inputs,
|
||||||
});
|
payload,
|
||||||
const resolvedPayload = { ...payload, agent: agent2.name };
|
repoSettings: githubSetup.repoSettings
|
||||||
const apiKeySetup = validateApiKey({
|
});
|
||||||
agent: agent2,
|
const resolvedPayload = { ...payload, agent: agent2.name };
|
||||||
inputs,
|
const apiKeySetup = validateApiKey({
|
||||||
owner: githubSetup.owner,
|
agent: agent2,
|
||||||
name: githubSetup.name
|
inputs,
|
||||||
});
|
owner: githubSetup.owner,
|
||||||
if (!apiKeySetup.success) {
|
name: githubSetup.name
|
||||||
await reportErrorToComment({ error: apiKeySetup.error });
|
});
|
||||||
return { success: false, error: apiKeySetup.error };
|
if (!apiKeySetup.success) {
|
||||||
}
|
await reportErrorToComment({ error: apiKeySetup.error });
|
||||||
const toolState = {};
|
return { success: false, error: apiKeySetup.error };
|
||||||
const [cliPath] = await Promise.all([
|
}
|
||||||
installAgentCli({ agent: agent2, token: installationToken.token }),
|
const toolState = {};
|
||||||
setupGitAuth({
|
const [cliPath] = await Promise.all([
|
||||||
token: installationToken.token,
|
installAgentCli({ agent: agent2, token: tokenRef.token }),
|
||||||
|
setupGitAuth({
|
||||||
|
token: tokenRef.token,
|
||||||
|
owner: githubSetup.owner,
|
||||||
|
name: githubSetup.name,
|
||||||
|
payload: resolvedPayload,
|
||||||
|
octokit: githubSetup.octokit,
|
||||||
|
toolState
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
timer.checkpoint("agentSetup+gitAuth");
|
||||||
|
const computedModes = [
|
||||||
|
...getModes({
|
||||||
|
disableProgressComment: resolvedPayload.disableProgressComment
|
||||||
|
}),
|
||||||
|
...resolvedPayload.modes || []
|
||||||
|
];
|
||||||
|
const runId = process.env.GITHUB_RUN_ID || "";
|
||||||
|
if (runId) {
|
||||||
|
const workflowRunInfo = await fetchWorkflowRunInfo(runId);
|
||||||
|
if (workflowRunInfo.progressCommentId) {
|
||||||
|
process.env.PULLFROG_PROGRESS_COMMENT_ID = workflowRunInfo.progressCommentId;
|
||||||
|
log.info(`\u{1F4DD} Using pre-created progress comment: ${workflowRunInfo.progressCommentId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let jobId;
|
||||||
|
const jobName = process.env.GITHUB_JOB;
|
||||||
|
if (jobName && runId) {
|
||||||
|
const jobs = await githubSetup.octokit.rest.actions.listJobsForWorkflowRun({
|
||||||
|
owner: githubSetup.owner,
|
||||||
|
repo: githubSetup.name,
|
||||||
|
run_id: parseInt(runId, 10)
|
||||||
|
});
|
||||||
|
const matchingJob = jobs.data.jobs.find((job) => job.name === jobName);
|
||||||
|
if (matchingJob) {
|
||||||
|
jobId = String(matchingJob.id);
|
||||||
|
log.info(`\u{1F4CB} Found job ID: ${jobId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const toolContext = {
|
||||||
owner: githubSetup.owner,
|
owner: githubSetup.owner,
|
||||||
name: githubSetup.name,
|
name: githubSetup.name,
|
||||||
payload: resolvedPayload,
|
githubInstallationToken: tokenRef.token,
|
||||||
octokit: githubSetup.octokit,
|
octokit: githubSetup.octokit,
|
||||||
toolState
|
payload: resolvedPayload,
|
||||||
})
|
repo: githubSetup.repo,
|
||||||
]);
|
repoSettings: githubSetup.repoSettings,
|
||||||
timer.checkpoint("agentSetup+gitAuth");
|
modes: computedModes,
|
||||||
const computedModes = [
|
toolState,
|
||||||
...getModes({
|
agent: agent2,
|
||||||
disableProgressComment: resolvedPayload.disableProgressComment
|
sharedTempDir,
|
||||||
}),
|
runId,
|
||||||
...resolvedPayload.modes || []
|
jobId
|
||||||
];
|
};
|
||||||
const runId = process.env.GITHUB_RUN_ID || "";
|
const mcpHttpServer = __using(_stack, await startMcpHttpServer(toolContext), true);
|
||||||
if (runId) {
|
log.info(`\u{1F680} MCP server started at ${mcpHttpServer.url}`);
|
||||||
const workflowRunInfo = await fetchWorkflowRunInfo(runId);
|
const mcpServers = createMcpConfigs(mcpHttpServer.url);
|
||||||
if (workflowRunInfo.progressCommentId) {
|
log.debug(`\u{1F4CB} MCP Config: ${JSON.stringify(mcpServers, null, 2)}`);
|
||||||
process.env.PULLFROG_PROGRESS_COMMENT_ID = workflowRunInfo.progressCommentId;
|
timer.checkpoint("mcpServer");
|
||||||
log.info(`\u{1F4DD} Using pre-created progress comment: ${workflowRunInfo.progressCommentId}`);
|
const ctx = {
|
||||||
}
|
...toolContext,
|
||||||
}
|
inputs,
|
||||||
let jobId;
|
mcpServerUrl: mcpHttpServer.url,
|
||||||
const jobName = process.env.GITHUB_JOB;
|
mcpServers,
|
||||||
if (jobName && runId) {
|
cliPath,
|
||||||
const jobs = await githubSetup.octokit.rest.actions.listJobsForWorkflowRun({
|
apiKey: apiKeySetup.apiKey,
|
||||||
owner: githubSetup.owner,
|
apiKeys: apiKeySetup.apiKeys
|
||||||
repo: githubSetup.name,
|
};
|
||||||
run_id: parseInt(runId, 10)
|
if (ctx.payload.event.trigger === "fix_review" && Array.isArray(ctx.payload.event.comment_ids) && ctx.payload.event.comment_ids.length === 0) {
|
||||||
});
|
const noThumbsMessage = `\u{1F44D} **No approved comments found**
|
||||||
const matchingJob = jobs.data.jobs.find((job) => job.name === jobName);
|
|
||||||
if (matchingJob) {
|
|
||||||
jobId = String(matchingJob.id);
|
|
||||||
log.info(`\u{1F4CB} Found job ID: ${jobId}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const toolContext = {
|
|
||||||
owner: githubSetup.owner,
|
|
||||||
name: githubSetup.name,
|
|
||||||
githubInstallationToken: installationToken.token,
|
|
||||||
octokit: githubSetup.octokit,
|
|
||||||
payload: resolvedPayload,
|
|
||||||
repo: githubSetup.repo,
|
|
||||||
repoSettings: githubSetup.repoSettings,
|
|
||||||
modes: computedModes,
|
|
||||||
toolState,
|
|
||||||
agent: agent2,
|
|
||||||
sharedTempDir,
|
|
||||||
runId,
|
|
||||||
jobId
|
|
||||||
};
|
|
||||||
const { url: mcpServerUrl, close: mcpServerCloseFunc } = await startMcpHttpServer(toolContext);
|
|
||||||
mcpServerClose = mcpServerCloseFunc;
|
|
||||||
log.info(`\u{1F680} MCP server started at ${mcpServerUrl}`);
|
|
||||||
const mcpServers = createMcpConfigs(mcpServerUrl);
|
|
||||||
log.debug(`\u{1F4CB} MCP Config: ${JSON.stringify(mcpServers, null, 2)}`);
|
|
||||||
timer.checkpoint("mcpServer");
|
|
||||||
const ctx = {
|
|
||||||
...toolContext,
|
|
||||||
inputs,
|
|
||||||
mcpServerUrl,
|
|
||||||
mcpServerClose: mcpServerCloseFunc,
|
|
||||||
mcpServers,
|
|
||||||
cliPath,
|
|
||||||
apiKey: apiKeySetup.apiKey,
|
|
||||||
apiKeys: apiKeySetup.apiKeys
|
|
||||||
};
|
|
||||||
if (ctx.payload.event.trigger === "fix_review" && Array.isArray(ctx.payload.event.comment_ids) && ctx.payload.event.comment_ids.length === 0) {
|
|
||||||
const noThumbsMessage = `\u{1F44D} **No approved comments found**
|
|
||||||
|
|
||||||
To use "Fix \u{1F44D}s", add a \u{1F44D} reaction to one or more inline review comments you want fixed.`;
|
To use "Fix \u{1F44D}s", add a \u{1F44D} reaction to one or more inline review comments you want fixed.`;
|
||||||
log.error(noThumbsMessage);
|
log.error(noThumbsMessage);
|
||||||
await reportProgress(ctx, { body: noThumbsMessage });
|
await reportProgress(ctx, { body: noThumbsMessage });
|
||||||
return { success: true };
|
return { success: true };
|
||||||
|
}
|
||||||
|
const result = await runAgent(ctx);
|
||||||
|
const mainResult = await handleAgentResult(result);
|
||||||
|
return mainResult;
|
||||||
|
} catch (_) {
|
||||||
|
var _error = _, _hasError = true;
|
||||||
|
} finally {
|
||||||
|
var _promise2 = __callDispose(_stack, _error, _hasError);
|
||||||
|
_promise2 && await _promise2;
|
||||||
}
|
}
|
||||||
const result = await runAgent(ctx);
|
|
||||||
const mainResult = await handleAgentResult(result);
|
|
||||||
return mainResult;
|
|
||||||
} catch (error41) {
|
} catch (error41) {
|
||||||
const errorMessage = error41 instanceof Error ? error41.message : "Unknown error occurred";
|
const errorMessage = error41 instanceof Error ? error41.message : "Unknown error occurred";
|
||||||
log.error(errorMessage);
|
log.error(errorMessage);
|
||||||
@@ -126687,15 +126692,12 @@ To use "Fix \u{1F44D}s", add a \u{1F44D} reaction to one or more inline review c
|
|||||||
await ensureProgressCommentUpdated(payload);
|
await ensureProgressCommentUpdated(payload);
|
||||||
} catch {
|
} catch {
|
||||||
}
|
}
|
||||||
if (mcpServerClose) {
|
|
||||||
await mcpServerClose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_2) {
|
||||||
var _error = _, _hasError = true;
|
var _error2 = _2, _hasError2 = true;
|
||||||
} finally {
|
} finally {
|
||||||
var _promise2 = __callDispose(_stack, _error, _hasError);
|
var _promise3 = __callDispose(_stack2, _error2, _hasError2);
|
||||||
_promise2 && await _promise2;
|
_promise3 && await _promise3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function agentHasApiKeys(agent2, inputs) {
|
function agentHasApiKeys(agent2, inputs) {
|
||||||
|
|||||||
@@ -66,8 +66,7 @@ type ApiKeySetup =
|
|||||||
|
|
||||||
export async function main(inputs: Inputs): Promise<MainResult> {
|
export async function main(inputs: Inputs): Promise<MainResult> {
|
||||||
const timer = new Timer();
|
const timer = new Timer();
|
||||||
await using installationToken = await setupGitHubInstallationToken();
|
await using tokenRef = await setupGitHubInstallationToken();
|
||||||
let mcpServerClose: (() => Promise<void>) | undefined;
|
|
||||||
let payload: Payload | undefined;
|
let payload: Payload | undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -78,7 +77,7 @@ export async function main(inputs: Inputs): Promise<MainResult> {
|
|||||||
|
|
||||||
// phase 2: fast setup (github + temp dir)
|
// phase 2: fast setup (github + temp dir)
|
||||||
const [githubSetup, sharedTempDir] = await Promise.all([
|
const [githubSetup, sharedTempDir] = await Promise.all([
|
||||||
initializeGitHub(installationToken.token),
|
initializeGitHub(tokenRef.token),
|
||||||
createTempDirectory(),
|
createTempDirectory(),
|
||||||
]);
|
]);
|
||||||
timer.checkpoint("githubSetup");
|
timer.checkpoint("githubSetup");
|
||||||
@@ -106,9 +105,9 @@ export async function main(inputs: Inputs): Promise<MainResult> {
|
|||||||
// phase 5: parallel long-running operations (agent install + git auth)
|
// phase 5: parallel long-running operations (agent install + git auth)
|
||||||
const toolState: ToolState = {};
|
const toolState: ToolState = {};
|
||||||
const [cliPath] = await Promise.all([
|
const [cliPath] = await Promise.all([
|
||||||
installAgentCli({ agent, token: installationToken.token }),
|
installAgentCli({ agent, token: tokenRef.token }),
|
||||||
setupGitAuth({
|
setupGitAuth({
|
||||||
token: installationToken.token,
|
token: tokenRef.token,
|
||||||
owner: githubSetup.owner,
|
owner: githubSetup.owner,
|
||||||
name: githubSetup.name,
|
name: githubSetup.name,
|
||||||
payload: resolvedPayload,
|
payload: resolvedPayload,
|
||||||
@@ -155,7 +154,7 @@ export async function main(inputs: Inputs): Promise<MainResult> {
|
|||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
owner: githubSetup.owner,
|
owner: githubSetup.owner,
|
||||||
name: githubSetup.name,
|
name: githubSetup.name,
|
||||||
githubInstallationToken: installationToken.token,
|
githubInstallationToken: tokenRef.token,
|
||||||
octokit: githubSetup.octokit,
|
octokit: githubSetup.octokit,
|
||||||
payload: resolvedPayload,
|
payload: resolvedPayload,
|
||||||
repo: githubSetup.repo,
|
repo: githubSetup.repo,
|
||||||
@@ -168,11 +167,10 @@ export async function main(inputs: Inputs): Promise<MainResult> {
|
|||||||
jobId,
|
jobId,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { url: mcpServerUrl, close: mcpServerCloseFunc } = await startMcpHttpServer(toolContext);
|
await using mcpHttpServer = await startMcpHttpServer(toolContext);
|
||||||
mcpServerClose = mcpServerCloseFunc;
|
log.info(`🚀 MCP server started at ${mcpHttpServer.url}`);
|
||||||
log.info(`🚀 MCP server started at ${mcpServerUrl}`);
|
|
||||||
|
|
||||||
const mcpServers = createMcpConfigs(mcpServerUrl);
|
const mcpServers = createMcpConfigs(mcpHttpServer.url);
|
||||||
log.debug(`📋 MCP Config: ${JSON.stringify(mcpServers, null, 2)}`);
|
log.debug(`📋 MCP Config: ${JSON.stringify(mcpServers, null, 2)}`);
|
||||||
timer.checkpoint("mcpServer");
|
timer.checkpoint("mcpServer");
|
||||||
|
|
||||||
@@ -180,8 +178,7 @@ export async function main(inputs: Inputs): Promise<MainResult> {
|
|||||||
const ctx: AgentContext = {
|
const ctx: AgentContext = {
|
||||||
...toolContext,
|
...toolContext,
|
||||||
inputs,
|
inputs,
|
||||||
mcpServerUrl,
|
mcpServerUrl: mcpHttpServer.url,
|
||||||
mcpServerClose: mcpServerCloseFunc,
|
|
||||||
mcpServers,
|
mcpServers,
|
||||||
cliPath,
|
cliPath,
|
||||||
apiKey: apiKeySetup.apiKey,
|
apiKey: apiKeySetup.apiKey,
|
||||||
@@ -224,10 +221,6 @@ export async function main(inputs: Inputs): Promise<MainResult> {
|
|||||||
} catch {
|
} catch {
|
||||||
// error updating comment, but don't let it mask the original error
|
// error updating comment, but don't let it mask the original error
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mcpServerClose) {
|
|
||||||
await mcpServerClose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +312,6 @@ export interface ToolContext {
|
|||||||
export interface AgentContext extends Readonly<ToolContext> {
|
export interface AgentContext extends Readonly<ToolContext> {
|
||||||
readonly inputs: Inputs;
|
readonly inputs: Inputs;
|
||||||
readonly mcpServerUrl: string;
|
readonly mcpServerUrl: string;
|
||||||
readonly mcpServerClose: () => Promise<void>;
|
|
||||||
readonly mcpServers: ReturnType<typeof createMcpConfigs>;
|
readonly mcpServers: ReturnType<typeof createMcpConfigs>;
|
||||||
readonly cliPath: string;
|
readonly cliPath: string;
|
||||||
readonly apiKey: string;
|
readonly apiKey: string;
|
||||||
|
|||||||
+2
-2
@@ -64,7 +64,7 @@ async function findAvailablePort(startPort: number): Promise<number> {
|
|||||||
*/
|
*/
|
||||||
export async function startMcpHttpServer(
|
export async function startMcpHttpServer(
|
||||||
ctx: ToolContext
|
ctx: ToolContext
|
||||||
): Promise<{ url: string; close: () => Promise<void> }> {
|
): Promise<{ url: string; [Symbol.asyncDispose]: () => Promise<void> }> {
|
||||||
const server = new FastMCP({
|
const server = new FastMCP({
|
||||||
name: ghPullfrogMcpName,
|
name: ghPullfrogMcpName,
|
||||||
version: "0.0.1",
|
version: "0.0.1",
|
||||||
@@ -119,7 +119,7 @@ export async function startMcpHttpServer(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
url,
|
url,
|
||||||
close: async () => {
|
[Symbol.asyncDispose]: async () => {
|
||||||
await server.stop();
|
await server.stop();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user