mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 02:26:12 +02:00
feat(codex): add GPT-6 Sol support
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
a10702a878
commit
240e5759c3
7 files changed
+29
-24
No files matched your search
@@ -14,21 +14,23 @@ describe("codex local adapter metadata", () => {
|
||||
// Default to the concrete gpt-5.6-sol slug — Codex ships no metadata for the bare gpt-5.6
|
||||
// alias, so it must not be advertised or used as the default (it triggers a fallback warning).
|
||||
expect(DEFAULT_CODEX_LOCAL_MODEL).toBe("gpt-5.6-sol");
|
||||
expect(modelIds.slice(0, 4)).toEqual([
|
||||
expect(modelIds.slice(0, 5)).toEqual([
|
||||
"gpt-5.6-sol",
|
||||
"gpt-6-astra",
|
||||
"gpt-6-sol",
|
||||
"gpt-5.6-terra",
|
||||
"gpt-5.6-luna",
|
||||
]);
|
||||
expect(modelIds).not.toContain("gpt-5.6");
|
||||
expect(isCodexLocalFastModeSupported(DEFAULT_CODEX_LOCAL_MODEL)).toBe(true);
|
||||
expect(isCodexLocalFastModeSupported("gpt-6-astra")).toBe(true);
|
||||
expect(isCodexLocalFastModeSupported("gpt-6-sol")).toBe(true);
|
||||
expect(modelIds).not.toContain("gpt-5.3-codex");
|
||||
expect(modelIds).not.toContain("gpt-5.3-codex-spark");
|
||||
});
|
||||
|
||||
it("uses the reasoning efforts advertised for GPT-6 Astra", () => {
|
||||
expect(codexLocalReasoningEffortsForModel("gpt-6-astra")).toEqual([
|
||||
it.each(["gpt-6-astra", "gpt-6-sol", " gpt-6-sol "])("uses the reasoning efforts advertised for %s", (model) => {
|
||||
expect(codexLocalReasoningEffortsForModel(model)).toEqual([
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
|
||||
@@ -14,6 +14,7 @@ export const DEFAULT_CODEX_LOCAL_MODEL = PAPERCLIP_RUNNER_DEFAULT_MODELS.codex;
|
||||
export const DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX = true;
|
||||
export const CODEX_LOCAL_FAST_MODE_SUPPORTED_MODELS = [
|
||||
"gpt-6-astra",
|
||||
"gpt-6-sol",
|
||||
"gpt-5.6-sol",
|
||||
"gpt-5.6-terra",
|
||||
"gpt-5.6-luna",
|
||||
@@ -41,7 +42,7 @@ const CODEX_LOCAL_DEFAULT_REASONING_EFFORTS = [
|
||||
"xhigh",
|
||||
] as const;
|
||||
|
||||
const CODEX_LOCAL_ASTRA_REASONING_EFFORTS = [
|
||||
const CODEX_LOCAL_GPT_6_REASONING_EFFORTS = [
|
||||
"low",
|
||||
"medium",
|
||||
"high",
|
||||
@@ -52,7 +53,7 @@ const CODEX_LOCAL_ASTRA_REASONING_EFFORTS = [
|
||||
|
||||
export type CodexLocalReasoningEffort =
|
||||
| (typeof CODEX_LOCAL_DEFAULT_REASONING_EFFORTS)[number]
|
||||
| (typeof CODEX_LOCAL_ASTRA_REASONING_EFFORTS)[number];
|
||||
| (typeof CODEX_LOCAL_GPT_6_REASONING_EFFORTS)[number];
|
||||
|
||||
export function normalizeCodexModel(model: string | null | undefined): string {
|
||||
const normalizedModel = normalizeModelId(model);
|
||||
@@ -62,8 +63,9 @@ export function normalizeCodexModel(model: string | null | undefined): string {
|
||||
export function codexLocalReasoningEffortsForModel(
|
||||
model: string | null | undefined,
|
||||
): readonly CodexLocalReasoningEffort[] {
|
||||
return normalizeCodexModel(model) === "gpt-6-astra"
|
||||
? CODEX_LOCAL_ASTRA_REASONING_EFFORTS
|
||||
const normalizedModel = normalizeCodexModel(model);
|
||||
return normalizedModel === "gpt-6-astra" || normalizedModel === "gpt-6-sol"
|
||||
? CODEX_LOCAL_GPT_6_REASONING_EFFORTS
|
||||
: CODEX_LOCAL_DEFAULT_REASONING_EFFORTS;
|
||||
}
|
||||
|
||||
@@ -94,6 +96,7 @@ export const models = [
|
||||
// DEFAULT_CODEX_LOCAL_MODEL is gpt-5.6-sol, so it doubles as the first (default) 5.6 entry.
|
||||
{ id: DEFAULT_CODEX_LOCAL_MODEL, label: DEFAULT_CODEX_LOCAL_MODEL },
|
||||
{ id: "gpt-6-astra", label: "gpt-6-astra" },
|
||||
{ id: "gpt-6-sol", label: "gpt-6-sol" },
|
||||
{ id: "gpt-5.6-terra", label: "gpt-5.6-terra" },
|
||||
{ id: "gpt-5.6-luna", label: "gpt-5.6-luna" },
|
||||
{ id: "gpt-5.4", label: "gpt-5.4" },
|
||||
@@ -116,10 +119,10 @@ Core fields:
|
||||
- cwd (string, optional): default absolute working directory fallback for the agent process (created if missing when possible)
|
||||
- instructionsFilePath (string, optional): absolute path to a markdown instructions file prepended to stdin prompt at runtime
|
||||
- model (string, optional): Codex model id
|
||||
- modelReasoningEffort (string, optional): reasoning effort override passed via -c model_reasoning_effort=...; GPT-6 Astra supports low|medium|high|xhigh|max|ultra
|
||||
- modelReasoningEffort (string, optional): reasoning effort override passed via -c model_reasoning_effort=...; GPT-6 Astra and Sol support low|medium|high|xhigh|max|ultra
|
||||
- promptTemplate (string, optional): run prompt template
|
||||
- search (boolean, optional): run codex with --search
|
||||
- fastMode (boolean, optional): enable Codex Fast mode; supported on GPT-6 Astra, GPT-5.6 (sol/terra/luna), GPT-5.5, GPT-5.4 and passed through for manual model IDs
|
||||
- fastMode (boolean, optional): enable Codex Fast mode; supported on GPT-6 Astra and Sol, GPT-5.6 (sol/terra/luna), GPT-5.5, GPT-5.4 and passed through for manual model IDs
|
||||
- dangerouslyBypassApprovalsAndSandbox (boolean, optional): run with bypass flag
|
||||
- command (string, optional): defaults to "codex"
|
||||
- extraArgs (string[], optional): additional CLI args
|
||||
@@ -150,7 +153,7 @@ Notes:
|
||||
- Paperclip injects desired local skills into the effective CODEX_HOME/skills/ directory at execution time so Codex can discover "$paperclip" and related skills without polluting the project working directory. For new and updated agents, Paperclip assigns an isolated managed home at ~/.paperclip/instances/<id>/companies/<companyId>/agents/<agentId>/codex-home/skills/; when CODEX_HOME is explicitly overridden in adapter config, that override is used instead.
|
||||
- New and updated codex_local agents persist an empty OPENAI_API_KEY override by default so a host-level OPENAI_API_KEY cannot leak into Codex runs through process inheritance. Explicit CODEX_HOME overrides must not point at the shared company codex-home, $CODEX_HOME, or ~/.codex.
|
||||
- Some model/tool combinations reject certain effort levels (for example minimal with web search enabled).
|
||||
- Fast mode is supported on GPT-6 Astra, GPT-5.6 (sol/terra/luna), GPT-5.5, GPT-5.4 and manual model IDs. When enabled for those models, Paperclip applies \`service_tier="fast"\` and \`features.fast_mode=true\`.
|
||||
- Fast mode is supported on GPT-6 Astra and Sol, GPT-5.6 (sol/terra/luna), GPT-5.5, GPT-5.4 and manual model IDs. When enabled for those models, Paperclip applies \`service_tier="fast"\` and \`features.fast_mode=true\`.
|
||||
- When Paperclip realizes a workspace/runtime for a run, it injects PAPERCLIP_WORKSPACE_* and PAPERCLIP_RUNTIME_* env vars for agent-side tooling.
|
||||
- The ACP engine keeps its workspace sandbox and enables network access on each turn. Explicit sandbox_workspace_write.network_access overrides in extraArgs (or env.PAPERCLIP_CODEX_ACP_NETWORK_ACCESS="false") disable it; execution-target network denial wins. The bundled ACP patch is needed because upstream mode presets override Codex config.toml on every turn.
|
||||
- The CLI engine defaults to a writable workspace sandbox with network access for unattended work and Paperclip API calls. It does not enable the dangerous bypass flag. Explicit sandbox modes/profiles and network overrides in extraArgs retain their meaning. An execution-target network denial remains enforced.
|
||||
|
||||
@@ -508,14 +508,14 @@ describe("codex_local ACP lane", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("forwards GPT-6 Astra controls to the ACPX Codex target", () => {
|
||||
it.each(["gpt-6-astra", "gpt-6-sol"])("forwards %s controls to the ACPX Codex target", (model) => {
|
||||
expect(buildCodexAcpConfig({
|
||||
engine: "acp",
|
||||
model: "gpt-6-astra",
|
||||
model,
|
||||
modelReasoningEffort: "ultra",
|
||||
fastMode: true,
|
||||
})).toMatchObject({
|
||||
model: "gpt-6-astra",
|
||||
model,
|
||||
modelReasoningEffort: "ultra",
|
||||
fastMode: true,
|
||||
});
|
||||
|
||||
@@ -9,14 +9,14 @@ describe("buildCodexExecArgs", () => {
|
||||
if (resumeSessionId) expect(args.slice(-3)).toEqual(["resume", resumeSessionId, "-"]);
|
||||
});
|
||||
|
||||
it("forwards GPT-6 Astra, its ultra reasoning effort, and fast mode", () => {
|
||||
it.each(["gpt-6-astra", "gpt-6-sol"])("forwards %s, its ultra reasoning effort, and fast mode", (model) => {
|
||||
const result = buildCodexExecArgs({
|
||||
model: "gpt-6-astra",
|
||||
model,
|
||||
modelReasoningEffort: "ultra",
|
||||
fastMode: true,
|
||||
});
|
||||
|
||||
expect(result.model).toBe("gpt-6-astra");
|
||||
expect(result.model).toBe(model);
|
||||
expect(result.fastModeApplied).toBe(true);
|
||||
expect(result.fastModeIgnoredReason).toBeNull();
|
||||
expect(result.args).toEqual([
|
||||
@@ -24,7 +24,7 @@ describe("buildCodexExecArgs", () => {
|
||||
"--json",
|
||||
"--dangerously-bypass-approvals-and-sandbox",
|
||||
"--model",
|
||||
"gpt-6-astra",
|
||||
model,
|
||||
"-c",
|
||||
'model_reasoning_effort="ultra"',
|
||||
"-c",
|
||||
@@ -148,7 +148,7 @@ describe("buildCodexExecArgs", () => {
|
||||
expect(result.fastModeRequested).toBe(true);
|
||||
expect(result.fastModeApplied).toBe(false);
|
||||
expect(result.fastModeIgnoredReason).toContain(
|
||||
"currently only supported on gpt-6-astra, gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, gpt-5.5, gpt-5.4 or manually configured model IDs",
|
||||
"currently only supported on gpt-6-astra, gpt-6-sol, gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, gpt-5.5, gpt-5.4 or manually configured model IDs",
|
||||
);
|
||||
expect(result.args).toEqual([
|
||||
"exec",
|
||||
|
||||
@@ -63,17 +63,17 @@ describe("buildCodexLocalConfig", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("persists the exact GPT-6 Astra model and supported controls", () => {
|
||||
it.each(["gpt-6-astra", "gpt-6-sol"])("persists the exact %s model and supported controls", (model) => {
|
||||
const config = buildCodexLocalConfig(
|
||||
makeValues({
|
||||
model: "gpt-6-astra",
|
||||
model,
|
||||
thinkingEffort: "ultra",
|
||||
fastMode: true,
|
||||
}),
|
||||
);
|
||||
|
||||
expect(config).toMatchObject({
|
||||
model: "gpt-6-astra",
|
||||
model,
|
||||
modelReasoningEffort: "ultra",
|
||||
fastMode: true,
|
||||
});
|
||||
|
||||
@@ -34,7 +34,7 @@ export const help: Record<string, string> = {
|
||||
dangerouslySkipPermissions: "Run unattended by auto-approving adapter permission prompts when supported.",
|
||||
dangerouslyBypassSandbox: "Run Codex without sandbox restrictions. Required for filesystem/network access.",
|
||||
search: "Enable Codex web search capability during runs.",
|
||||
fastMode: "Enable Codex Fast mode. This burns credits/tokens much faster and is supported on GPT-6 Astra, GPT-5.6, GPT-5.5, GPT-5.4, and manual Codex model IDs.",
|
||||
fastMode: "Enable Codex Fast mode. This burns credits/tokens much faster and is supported on GPT-6 Astra and Sol, GPT-5.6, GPT-5.5, GPT-5.4, and manual Codex model IDs.",
|
||||
workspaceStrategy: "How Paperclip should realize an execution workspace for this agent. Keep project_primary for normal cwd execution, or use git_worktree for issue-scoped isolated checkouts.",
|
||||
workspaceBaseRef: "Base git ref used when creating a worktree branch. Leave blank to use the resolved workspace ref or HEAD.",
|
||||
workspaceBranchTemplate: "Template for naming derived branches. Supports {{issue.identifier}}, {{issue.title}}, {{agent.name}}, {{project.id}}, {{workspace.repoRef}}, and {{slug}}.",
|
||||
|
||||
@@ -4,8 +4,8 @@ import { describe, expect, it } from "vitest";
|
||||
import { codexReasoningEffortOptions } from "./codex-reasoning-effort";
|
||||
|
||||
describe("codexReasoningEffortOptions", () => {
|
||||
it("exposes only the supported GPT-6 Astra reasoning efforts", () => {
|
||||
expect(codexReasoningEffortOptions("gpt-6-astra")).toEqual([
|
||||
it.each(["gpt-6-astra", "gpt-6-sol"])("exposes only the supported %s reasoning efforts", (model) => {
|
||||
expect(codexReasoningEffortOptions(model)).toEqual([
|
||||
{ value: "", label: "Default" },
|
||||
{ value: "low", label: "Low" },
|
||||
{ value: "medium", label: "Medium" },
|
||||
|
||||
Reference in new issue
Block a user