Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ For fetching and including the latest failed CI build logs, use the `--fix-build
/codex --fix-build Please suggest changes to fix the build errors.
```

For fetching and including contents from URLs referenced in the prompt, use the `--fetch` flag:

```
/codex --fetch Please review the API docs at https://example.com/docs/api
```

Codex will analyze the request and create a new Pull Request with the code changes. The AI will also post a comment with the generated code.

### Example Usage in PRs
Expand Down Expand Up @@ -136,6 +142,12 @@ For fetching and including the latest failed CI build logs, use the `--fix-build
/codex --fix-build Please suggest changes to fix the build errors.
```

For fetching and including contents from URLs referenced in the prompt, use the `--fetch` flag:

```
/codex --fetch Please review the API docs at https://example.com/docs/api
```

Codex will analyze the request and create a new Pull Request with the code changes. The AI will also post a comment with the generated code.

### Example Usage: Creating Issues
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ inputs:
Each image can be referenced in the prompt by `<image_0>`, `<image_1>`, etc.
required: false
default: ''
fetch:
description: 'Fetch known URLs referenced in the prompt and include their contents in the prompt'
required: false
default: 'false'

runs:
using: 'docker'
Expand Down
6 changes: 6 additions & 0 deletions src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export interface ActionConfig {
* Optional list of local image file paths to include in the Codex CLI invocation.
*/
images: string[];
/**
* Whether to fetch known URLs referenced in the prompt and include their contents.
*/
fetch: boolean;
}

/**
Expand Down Expand Up @@ -150,6 +154,7 @@ export function getConfig(): ActionConfig {
const codexEnv = parseEnvInput(codexEnvInput);
const imagesInput = core.getInput('images') || '';
const images = parseListInput(imagesInput);
const fetch = core.getBooleanInput('fetch');

if (!openaiApiKey) {
throw new Error('OpenAI API key is required.');
Expand Down Expand Up @@ -181,5 +186,6 @@ export function getConfig(): ActionConfig {
assigneeTrigger,
codexEnv,
images,
fetch,
};
}
35 changes: 34 additions & 1 deletion src/github/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { runCodex } from '../client/codex.js';
import type { Octokit } from 'octokit';
import type { GitHubEvent } from './github.js';
import AdmZip from 'adm-zip';
import axios from 'axios';

/**
* Fetches the latest failed workflow run logs for the repository and returns their content.
Expand Down Expand Up @@ -375,6 +376,7 @@ export async function runAction(
includeFullHistory,
createIssues,
includeFixBuild,
includeFetch,
} = processedEvent;

// Add eyes reaction (instrumented)
Expand Down Expand Up @@ -455,8 +457,39 @@ export async function runAction(
const originalFileState = await captureFileState(workspace);
core.info(`[perf] captureFileState end - ${Date.now() - _t_captureState}ms`);

// generate Prompt (with special handling for --fix-build or create issues)
// generate Prompt (with special handling for --fetch, --fix-build, or create issues)
let effectiveUserPrompt = userPrompt;
if (includeFetch) {
core.info('Fetching contents of URLs for --fetch flag');
const urlRegex = /(https?:\/\/[^\s)]+)/g;
const urls = userPrompt.match(urlRegex) || [];
if (urls.length > 0) {
const fetchedParts: string[] = [];
for (const url of urls) {
try {
const response = await axios.get<string>(url, {
responseType: 'text',
timeout: 10000,
});
let data = typeof response.data === 'string'
? response.data
: JSON.stringify(response.data);
if (data.length > 2000) {
data = data.slice(0, 2000) + '\n...[truncated]';
}
fetchedParts.push(`=== ${url} ===\n${data}`);
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
fetchedParts.push(`Failed to fetch ${url}: ${msg}`);
}
}
effectiveUserPrompt = `Contents from URLs:\n\n${fetchedParts.join(
'\n\n',
)}\n\n${effectiveUserPrompt}`;
} else {
core.info('No URLs found to fetch for --fetch flag');
}
}
if (includeFixBuild) {
core.info('Fetching latest failed CI build logs for --fix-build flag');
let logs: string;
Expand Down
13 changes: 13 additions & 0 deletions src/github/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ export interface ProcessedEvent {
* Whether to fetch and include the latest failed CI build logs as context.
*/
includeFixBuild: boolean;
/**
* Whether to fetch known URLs referenced in the prompt and include their contents.
*/
includeFetch: boolean;
}

/**
Expand Down Expand Up @@ -61,10 +65,15 @@ export async function processEvent(
if (config.directPrompt) {
let prompt = config.directPrompt;
let includeFixBuild = false;
let includeFetch = false;
if (prompt.split(/\s+/).includes('--fix-build')) {
includeFixBuild = true;
prompt = prompt.replace(/--fix-build\b/, '').trim();
}
if (prompt.split(/\s+/).includes('--fetch')) {
includeFetch = true;
prompt = prompt.replace(/--fetch\b/, '').trim();
}
core.info('Direct prompt provided. Bypassing GitHub event trigger.');
return {
type: 'codex',
Expand All @@ -80,6 +89,7 @@ export async function processEvent(
createIssues: false,
noPr: false,
includeFixBuild,
includeFetch,
};
}
const eventPayload = await loadEventPayload(config.eventPath);
Expand Down Expand Up @@ -131,6 +141,8 @@ export async function processEvent(
// --fix-build: fetch latest failed CI build logs and include as context
const includeFixBuild = args.split(/\s+/).includes('--fix-build');
args = args.replace(/--fix-build\b/, '').trim();
const includeFetch = args.split(/\s+/).includes('--fetch');
args = args.replace(/--fetch\b/, '').trim();
let userPrompt = args;

let title: string | undefined;
Expand All @@ -157,5 +169,6 @@ export async function processEvent(
createIssues,
noPr,
includeFixBuild,
includeFetch,
};
}