switch to start_dependency_installation and await_dependency_installation, fix action play.ts repo

This commit is contained in:
David Blass
2025-12-19 16:29:46 -05:00
parent bd8fc8abdf
commit 5034ff8285
15 changed files with 8183 additions and 8858 deletions
+2 -2
View File
@@ -14,11 +14,11 @@ export const claude = agent({
executablePath: "cli.js",
});
},
run: async ({ payload, mcpServers, apiKey, cliPath, prepResults, repo }) => {
run: async ({ payload, mcpServers, apiKey, cliPath, repo }) => {
// Ensure API key is NOT in process.env - only pass via SDK's env option
delete process.env.ANTHROPIC_API_KEY;
const prompt = addInstructions({ payload, prepResults, repo });
const prompt = addInstructions({ payload, repo });
log.group("» Full prompt", () => log.info(prompt));
// configure sandbox mode if enabled
+2 -2
View File
@@ -20,7 +20,7 @@ export const codex = agent({
executablePath: "bin/codex.js",
});
},
run: async ({ payload, mcpServers, apiKey, cliPath, prepResults, repo }) => {
run: async ({ payload, mcpServers, apiKey, cliPath, repo }) => {
// create config directory for codex before setting HOME
const tempHome = process.env.PULLFROG_TEMP_DIR!;
const configDir = join(tempHome, ".config", "codex");
@@ -61,7 +61,7 @@ export const codex = agent({
);
try {
const streamedTurn = await thread.runStreamed(addInstructions({ payload, prepResults, repo }));
const streamedTurn = await thread.runStreamed(addInstructions({ payload, repo }));
let finalOutput = "";
for await (const event of streamedTurn.events) {
+2 -2
View File
@@ -91,7 +91,7 @@ export const cursor = agent({
executableName: "cursor-agent",
});
},
run: async ({ payload, apiKey, cliPath, mcpServers, prepResults, repo }) => {
run: async ({ payload, apiKey, cliPath, mcpServers, repo }) => {
configureCursorMcpServers({ mcpServers, cliPath });
configureCursorSandbox({ sandbox: payload.sandbox ?? false });
@@ -166,7 +166,7 @@ export const cursor = agent({
};
try {
const fullPrompt = addInstructions({ payload, prepResults, repo });
const fullPrompt = addInstructions({ payload, repo });
log.group("» Full prompt", () => log.info(fullPrompt));
// configure sandbox mode if enabled
+2 -2
View File
@@ -154,14 +154,14 @@ export const gemini = agent({
...(githubInstallationToken && { githubInstallationToken }),
});
},
run: async ({ payload, apiKey, mcpServers, cliPath, prepResults, repo }) => {
run: async ({ payload, apiKey, mcpServers, cliPath, repo }) => {
configureGeminiMcpServers({ mcpServers, cliPath });
if (!apiKey) {
throw new Error("google_api_key or gemini_api_key is required for gemini agent");
}
const sessionPrompt = addInstructions({ payload, prepResults, repo });
const sessionPrompt = addInstructions({ payload, repo });
log.group("» Full prompt", () => log.info(sessionPrompt));
// configure sandbox mode if enabled
+4 -81
View File
@@ -3,68 +3,6 @@ import { encode as toonEncode } from "@toon-format/toon";
import type { Payload } from "../external.ts";
import { ghPullfrogMcpName } from "../external.ts";
import { getModes } from "../modes.ts";
import type { PrepResult } from "../prep/index.ts";
/**
* Format prep results into a human-readable string for the agent prompt
*/
function formatPrepResults(results: PrepResult[]): string {
if (results.length === 0) {
return "";
}
const lines: string[] = [];
for (const result of results) {
if (result.language === "unknown") {
continue;
}
const langDisplay = result.language === "node" ? "Node.js" : "Python";
if (result.language === "node") {
if (result.dependenciesInstalled) {
lines.push(
`${langDisplay} dependencies installed successfully via \`${result.packageManager}\`.`
);
} else {
lines.push(
`⚠️ ${langDisplay} dependency installation FAILED (using \`${result.packageManager}\`).`
);
for (const issue of result.issues) {
lines.push(` - ${issue}`);
}
lines.push(
` You may need to run \`${result.packageManager} install\` or address this issue before proceeding.`
);
}
}
if (result.language === "python") {
if (result.dependenciesInstalled) {
lines.push(
`${langDisplay} dependencies installed successfully via \`${result.packageManager}\` (from ${result.configFile}).`
);
} else {
lines.push(
`⚠️ ${langDisplay} dependency installation FAILED (using \`${result.packageManager}\` from ${result.configFile}).`
);
for (const issue of result.issues) {
lines.push(` - ${issue}`);
}
lines.push(
` You may need to run the appropriate install command or address this issue before proceeding.`
);
}
}
}
if (lines.length === 0) {
return "";
}
return lines.join("\n");
}
interface RepoInfo {
owner: string;
@@ -72,15 +10,10 @@ interface RepoInfo {
defaultBranch: string;
}
interface BuildRuntimeContextParams {
repo: RepoInfo;
prepResults: PrepResult[];
}
/**
* Build runtime context string with git status, repo data, and GitHub Actions variables
*/
function buildRuntimeContext({ repo, prepResults }: BuildRuntimeContextParams): string {
function buildRuntimeContext(repo: RepoInfo): string {
const lines: string[] = [];
// working directory
@@ -114,24 +47,15 @@ function buildRuntimeContext({ repo, prepResults }: BuildRuntimeContextParams):
}
}
// environment setup (dependency installation results)
const envSetup = formatPrepResults(prepResults);
if (envSetup) {
lines.push("");
lines.push("environment_setup:");
lines.push(envSetup);
}
return lines.join("\n");
}
interface AddInstructionsParams {
payload: Payload;
prepResults: PrepResult[];
repo: RepoInfo;
}
export const addInstructions = ({ payload, prepResults, repo }: AddInstructionsParams) => {
export const addInstructions = ({ payload, repo }: AddInstructionsParams) => {
let encodedEvent = "";
const eventKeys = Object.keys(payload.event);
@@ -143,8 +67,7 @@ export const addInstructions = ({ payload, prepResults, repo }: AddInstructionsP
encodedEvent = toonEncode(payload.event);
}
const runtimeContext = buildRuntimeContext({ repo, prepResults });
const dependenciesPreinstalled = prepResults.every((r) => r.dependenciesInstalled) || undefined;
const runtimeContext = buildRuntimeContext(repo);
return (
`
@@ -264,7 +187,7 @@ Tool names may be formatted as \`(server name)/(tool name)\`, for example: \`${g
### Available modes
${[...getModes({ disableProgressComment: payload.disableProgressComment, dependenciesPreinstalled }), ...payload.modes].map((w) => ` - "${w.name}": ${w.description}`).join("\n")}
${[...getModes({ disableProgressComment: payload.disableProgressComment }), ...payload.modes].map((w) => ` - "${w.name}": ${w.description}`).join("\n")}
### Following the mode instructions
+2 -2
View File
@@ -21,7 +21,7 @@ export const opencode = agent({
installDependencies: true,
});
},
run: async ({ payload, apiKey: _apiKey, apiKeys, mcpServers, cliPath, prepResults, repo }) => {
run: async ({ payload, apiKey: _apiKey, apiKeys, mcpServers, cliPath, repo }) => {
// 1. configure home/config directory
const tempHome = process.env.PULLFROG_TEMP_DIR!;
const configDir = join(tempHome, ".config", "opencode");
@@ -29,7 +29,7 @@ export const opencode = agent({
configureOpenCode({ mcpServers, sandbox: payload.sandbox ?? false });
const prompt = addInstructions({ payload, prepResults, repo });
const prompt = addInstructions({ payload, repo });
log.group("» Full prompt", () => log.info(prompt));
// message positional must come right after "run", before flags
-2
View File
@@ -7,7 +7,6 @@ import { pipeline } from "node:stream/promises";
import type { McpHttpServerConfig } from "@anthropic-ai/claude-agent-sdk";
import type { show } from "@ark/util";
import { type AgentManifest, type AgentName, agentsManifest, type Payload } from "../external.ts";
import type { PrepResult } from "../prep/index.ts";
import { log } from "../utils/cli.ts";
import { getGitHubInstallationToken } from "../utils/github.ts";
@@ -39,7 +38,6 @@ export interface AgentConfig {
payload: Payload;
mcpServers: Record<string, McpHttpServerConfig>;
cliPath: string;
prepResults: PrepResult[];
repo: RepoInfo;
}