feat: assemble resource prompts and skills

This commit is contained in:
Codex
2026-06-02 20:40:14 +08:00
parent a53f5b8a0d
commit 3018b8a937
11 changed files with 394 additions and 15 deletions
+32 -2
View File
@@ -4,7 +4,7 @@ import { accessSync, constants as fsConstants } from "node:fs";
import { chmod, copyFile, mkdir } from "node:fs/promises";
import path from "node:path";
import * as readline from "node:readline";
import type { BackendEvent, BackendProfile, BackendTurnResult, FailureKind, JsonRecord, JsonValue, TerminalStatus } from "../common/types.js";
import type { BackendEvent, BackendProfile, BackendTurnResult, FailureKind, InitialPromptAssembly, JsonRecord, JsonValue, TerminalStatus } from "../common/types.js";
import { redactJson, redactText } from "../common/redaction.js";
import { backendProfileSpec } from "../common/backend-profiles.js";
import { boundedTextSummary, commandOutputPayload } from "../common/output.js";
@@ -31,6 +31,8 @@ const childEnvSummaryKeys = [
"CODEX_API_KEY",
"GITHUB_TOKEN",
"GH_TOKEN",
"AGENTRUN_SKILLS_DIRS",
"HWLAB_CODE_AGENT_SKILLS_DIRS",
];
export interface CodexStdioTurnOptions {
@@ -46,6 +48,7 @@ export interface CodexStdioTurnOptions {
args?: string[];
env?: NodeJS.ProcessEnv;
codexHome?: string;
initialPrompt?: InitialPromptAssembly;
abortSignal?: AbortSignal;
onEvent?: (event: BackendEvent) => void | Promise<void>;
onActiveTurn?: (control: CodexActiveTurnControl) => void | (() => void);
@@ -445,6 +448,7 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
return nextThreadId;
};
const willResumeThread = Boolean(options.threadId);
if (options.threadId) {
try {
const threadResponse = requireResponseRecord(await client.request("thread/resume", withOptionalModel({ threadId: options.threadId, cwd: options.cwd, approvalPolicy: options.approvalPolicy, sandbox: options.sandbox }, options.model), requestTimeoutMs), "thread/resume");
@@ -458,7 +462,9 @@ async function runCodexStdioTurnWithSession(options: CodexStdioTurnOptions, sess
threadId = await startThread();
}
const turnResponse = requireResponseRecord(await client.request("turn/start", withOptionalModel({ threadId, input: textInput(options.prompt), cwd: options.cwd, approvalPolicy: options.approvalPolicy }, options.model), requestTimeoutMs), "turn/start");
const promptInjection = initialPromptInjection(options.initialPrompt, willResumeThread);
emitEvent({ type: "backend_status", payload: { phase: "initial-prompt-assembly", initialPromptInjected: promptInjection.injected, reason: promptInjection.reason, initialPrompt: options.initialPrompt?.summary ?? { available: false, valuesPrinted: false }, valuesPrinted: false } });
const turnResponse = requireResponseRecord(await client.request("turn/start", withOptionalModel({ threadId, input: textInputForUserMessage(options.prompt, promptInjection), cwd: options.cwd, approvalPolicy: options.approvalPolicy }, options.model), requestTimeoutMs), "turn/start");
turnId = requireNestedId(turnResponse, "turn/start", "turn");
emitEvent({ type: "backend_status", payload: { phase: "turn/start:completed", turnId } });
if (threadId && turnId && options.onActiveTurn) {
@@ -794,6 +800,30 @@ function textInput(text: string): JsonValue[] {
return [{ type: "text", text, text_elements: [] }];
}
function initialPromptInjection(initialPrompt: InitialPromptAssembly | undefined, resume: boolean): { text: string; injected: boolean; reason: string } {
if (!initialPrompt) return { text: "", injected: false, reason: "no-initial-prompt" };
if (resume) return { text: "", injected: false, reason: "thread-resume" };
return {
text: [
"<agentrun-initial-prompt>",
initialPrompt.text,
"</agentrun-initial-prompt>",
].join("\n"),
injected: true,
reason: "thread-start",
};
}
function textInputForUserMessage(prompt: string, initial: ReturnType<typeof initialPromptInjection>): JsonValue[] {
if (!initial.injected) return textInput(prompt);
return textInput([
initial.text,
"<agentrun-user-message>",
prompt,
"</agentrun-user-message>",
].join("\n"));
}
function agentMessageText(item: JsonRecord): string {
for (const key of ["text", "content", "message"]) {
const value = item[key];