Clarify Codex instruction sources
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
c0c1fd17cb
commit
19154d0fec
6 changed files with 76 additions and 6 deletions
|
|
@ -40,6 +40,12 @@ pnpm paperclipai agent local-cli codexcoder --company-id <company-id>
|
||||||
|
|
||||||
This installs any missing skills, creates an agent API key, and prints shell exports to run as that agent.
|
This installs any missing skills, creates an agent API key, and prints shell exports to run as that agent.
|
||||||
|
|
||||||
|
## Instructions Resolution
|
||||||
|
|
||||||
|
If `instructionsFilePath` is configured, Paperclip reads that file and prepends it to the stdin prompt sent to `codex exec` on every run.
|
||||||
|
|
||||||
|
This is separate from any workspace-level instruction discovery that Codex itself performs in the run `cwd`. Paperclip does not disable Codex-native repo instruction files, so a repo-local `AGENTS.md` may still be loaded by Codex in addition to the Paperclip-managed agent instructions.
|
||||||
|
|
||||||
## Environment Test
|
## Environment Test
|
||||||
|
|
||||||
The environment test checks:
|
The environment test checks:
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@ Operational fields:
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- Prompts are piped via stdin (Codex receives "-" prompt argument).
|
- Prompts are piped via stdin (Codex receives "-" prompt argument).
|
||||||
|
- If instructionsFilePath is configured, Paperclip prepends that file's contents to the stdin prompt on every run.
|
||||||
|
- Codex exec automatically applies repo-scoped AGENTS.md instructions from the active workspace. Paperclip cannot suppress that discovery in exec mode, so repo AGENTS.md files may still apply even when you only configured an explicit instructionsFilePath.
|
||||||
- Paperclip injects desired local skills into the active workspace's ".agents/skills" directory at execution time so Codex can discover "$paperclip" and related skills without coupling them to the user's login home.
|
- Paperclip injects desired local skills into the active workspace's ".agents/skills" directory at execution time so Codex can discover "$paperclip" and related skills without coupling them to the user's login home.
|
||||||
- Unless explicitly overridden in adapter config, Paperclip runs Codex with a per-company managed CODEX_HOME under the active Paperclip instance and seeds auth/config from the shared Codex home (the CODEX_HOME env var, when set, or ~/.codex).
|
- Unless explicitly overridden in adapter config, Paperclip runs Codex with a per-company managed CODEX_HOME under the active Paperclip instance and seeds auth/config from the shared Codex home (the CODEX_HOME env var, when set, or ~/.codex).
|
||||||
- Some model/tool combinations reject certain effort levels (for example minimal with web search enabled).
|
- Some model/tool combinations reject certain effort levels (for example minimal with web search enabled).
|
||||||
|
|
|
||||||
|
|
@ -427,16 +427,22 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const repoAgentsNote =
|
||||||
|
"Codex exec automatically applies repo-scoped AGENTS.md instructions from the current workspace; Paperclip does not currently suppress that discovery.";
|
||||||
const commandNotes = (() => {
|
const commandNotes = (() => {
|
||||||
if (!instructionsFilePath) return [] as string[];
|
if (!instructionsFilePath) {
|
||||||
|
return [repoAgentsNote];
|
||||||
|
}
|
||||||
if (instructionsPrefix.length > 0) {
|
if (instructionsPrefix.length > 0) {
|
||||||
return [
|
return [
|
||||||
`Loaded agent instructions from ${instructionsFilePath}`,
|
`Loaded agent instructions from ${instructionsFilePath}`,
|
||||||
`Prepended instructions + path directive to stdin prompt (relative references from ${instructionsDir}).`,
|
`Prepended instructions + path directive to stdin prompt (relative references from ${instructionsDir}).`,
|
||||||
|
repoAgentsNote,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
`Configured instructionsFilePath ${instructionsFilePath}, but file could not be read; continuing without injected instructions.`,
|
`Configured instructionsFilePath ${instructionsFilePath}, but file could not be read; continuing without injected instructions.`,
|
||||||
|
repoAgentsNote,
|
||||||
];
|
];
|
||||||
})();
|
})();
|
||||||
const bootstrapPromptTemplate = asString(config.bootstrapPromptTemplate, "");
|
const bootstrapPromptTemplate = asString(config.bootstrapPromptTemplate, "");
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,62 @@ describe("codex execute", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("emits a command note that Codex auto-applies repo-scoped AGENTS.md files", async () => {
|
||||||
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-codex-execute-notes-"));
|
||||||
|
const workspace = path.join(root, "workspace");
|
||||||
|
const commandPath = path.join(root, "codex");
|
||||||
|
const capturePath = path.join(root, "capture.json");
|
||||||
|
await fs.mkdir(workspace, { recursive: true });
|
||||||
|
await writeFakeCodexCommand(commandPath);
|
||||||
|
|
||||||
|
const previousHome = process.env.HOME;
|
||||||
|
process.env.HOME = root;
|
||||||
|
|
||||||
|
let commandNotes: string[] = [];
|
||||||
|
try {
|
||||||
|
const result = await execute({
|
||||||
|
runId: "run-notes",
|
||||||
|
agent: {
|
||||||
|
id: "agent-1",
|
||||||
|
companyId: "company-1",
|
||||||
|
name: "Codex Coder",
|
||||||
|
adapterType: "codex_local",
|
||||||
|
adapterConfig: {},
|
||||||
|
},
|
||||||
|
runtime: {
|
||||||
|
sessionId: null,
|
||||||
|
sessionParams: null,
|
||||||
|
sessionDisplayId: null,
|
||||||
|
taskKey: null,
|
||||||
|
},
|
||||||
|
config: {
|
||||||
|
command: commandPath,
|
||||||
|
cwd: workspace,
|
||||||
|
env: {
|
||||||
|
PAPERCLIP_TEST_CAPTURE_PATH: capturePath,
|
||||||
|
},
|
||||||
|
promptTemplate: "Follow the paperclip heartbeat.",
|
||||||
|
},
|
||||||
|
context: {},
|
||||||
|
authToken: "run-jwt-token",
|
||||||
|
onLog: async () => {},
|
||||||
|
onMeta: async (meta) => {
|
||||||
|
commandNotes = Array.isArray(meta.commandNotes) ? meta.commandNotes : [];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.exitCode).toBe(0);
|
||||||
|
expect(result.errorMessage).toBeNull();
|
||||||
|
expect(commandNotes).toContain(
|
||||||
|
"Codex exec automatically applies repo-scoped AGENTS.md instructions from the current workspace; Paperclip does not currently suppress that discovery.",
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
if (previousHome === undefined) delete process.env.HOME;
|
||||||
|
else process.env.HOME = previousHome;
|
||||||
|
await fs.rm(root, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it("uses a worktree-isolated CODEX_HOME while preserving shared auth and config", async () => {
|
it("uses a worktree-isolated CODEX_HOME while preserving shared auth and config", async () => {
|
||||||
const root = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-codex-execute-"));
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-codex-execute-"));
|
||||||
const workspace = path.join(root, "workspace");
|
const workspace = path.join(root, "workspace");
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,7 @@ Use this when validating Paperclip itself (assignment flow, checkouts, run visib
|
||||||
1. Create a throwaway issue assigned to a known local agent (`claudecoder` or `codexcoder`):
|
1. Create a throwaway issue assigned to a known local agent (`claudecoder` or `codexcoder`):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm paperclipai issue create \
|
npx paperclipai issue create \
|
||||||
--company-id "$PAPERCLIP_COMPANY_ID" \
|
--company-id "$PAPERCLIP_COMPANY_ID" \
|
||||||
--title "Self-test: assignment/watch flow" \
|
--title "Self-test: assignment/watch flow" \
|
||||||
--description "Temporary validation issue" \
|
--description "Temporary validation issue" \
|
||||||
|
|
@ -341,19 +341,19 @@ pnpm paperclipai issue create \
|
||||||
2. Trigger and watch a heartbeat for that assignee:
|
2. Trigger and watch a heartbeat for that assignee:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm paperclipai heartbeat run --agent-id "$PAPERCLIP_AGENT_ID"
|
npx paperclipai heartbeat run --agent-id "$PAPERCLIP_AGENT_ID"
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Verify the issue transitions (`todo -> in_progress -> done` or `blocked`) and that comments are posted:
|
3. Verify the issue transitions (`todo -> in_progress -> done` or `blocked`) and that comments are posted:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm paperclipai issue get <issue-id-or-identifier>
|
npx paperclipai issue get <issue-id-or-identifier>
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Reassignment test (optional): move the same issue between `claudecoder` and `codexcoder` and confirm wake/run behavior:
|
4. Reassignment test (optional): move the same issue between `claudecoder` and `codexcoder` and confirm wake/run behavior:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm paperclipai issue update <issue-id> --assignee-agent-id <other-agent-id> --status todo
|
npx paperclipai issue update <issue-id> --assignee-agent-id <other-agent-id> --status todo
|
||||||
```
|
```
|
||||||
|
|
||||||
5. Cleanup: mark temporary issues done/cancelled with a clear note.
|
5. Cleanup: mark temporary issues done/cancelled with a clear note.
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import { LocalWorkspaceRuntimeFields } from "../local-workspace-runtime-fields";
|
||||||
const inputClass =
|
const inputClass =
|
||||||
"w-full rounded-md border border-border px-2.5 py-1.5 bg-transparent outline-none text-sm font-mono placeholder:text-muted-foreground/40";
|
"w-full rounded-md border border-border px-2.5 py-1.5 bg-transparent outline-none text-sm font-mono placeholder:text-muted-foreground/40";
|
||||||
const instructionsFileHint =
|
const instructionsFileHint =
|
||||||
"Absolute path to a markdown file (e.g. AGENTS.md) that defines this agent's behavior. Injected into the system prompt at runtime.";
|
"Absolute path to a markdown file (e.g. AGENTS.md) that defines this agent's behavior. Injected into the system prompt at runtime. Note: Codex may still auto-apply repo-scoped AGENTS.md files from the workspace.";
|
||||||
|
|
||||||
export function CodexLocalConfigFields({
|
export function CodexLocalConfigFields({
|
||||||
mode,
|
mode,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue