mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-23 00:53:38 +02:00
fix: preserve native Codex sign-in and settle retry fixture
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
ad5d8826ad
commit
f6a15200c2
7 files changed
+124
-24
No files matched your search
@@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { mkdir, mkdtemp, readFile, realpath, rm, stat, symlink, writeFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join, posix } from "node:path";
|
||||
import { ADAPTER_AUTH_MISSING_CHECK_CODE } from "@paperclipai/shared";
|
||||
const { execute, nativeProbe, selectedRunner, sshExecute, sshRunner, nativeArtifacts, remoteLauncher, registerPrp, ingressConnect } = vi.hoisted(() => ({ execute: vi.fn(), nativeProbe: vi.fn(), selectedRunner: vi.fn(), sshExecute: vi.fn(), sshRunner: vi.fn(), nativeArtifacts: vi.fn(), remoteLauncher: vi.fn(), registerPrp: vi.fn(), ingressConnect: vi.fn() }));
|
||||
vi.mock("@paperclipai/adapter-utils/execution-target", () => ({ runAdapterExecutionTargetShellCommand: execute }));
|
||||
vi.mock("./native-ssh-command-runner.js", () => ({ createNativeSshCommandRunner: sshRunner }));
|
||||
@@ -179,11 +180,27 @@ describe("Codex selected native account verification", () => {
|
||||
])("fails closed and redacts native failures (%s)", async (message, code) => {
|
||||
nativeProbe.mockRejectedValue(new Error(message));
|
||||
const result = await testNativeRunnerAuthentication({ companyId: "company", adapterType: "paperclip_runner", config: { env: { OPENAI_API_KEY: "bound-account" } } }, "codex", "gpt-6.1-sol");
|
||||
expect(result).toMatchObject({ status: "fail", checks: [{ code: `codex_hello_probe_${code}`, level: "error" }] });
|
||||
expect(result.status).toBe("fail");
|
||||
expect(result.checks[0]).toMatchObject({ code: `codex_hello_probe_${code}`, level: "error" });
|
||||
expect(result.checks.some(check => check.code === ADAPTER_AUTH_MISSING_CHECK_CODE)).toBe(code === "auth_required");
|
||||
expect(JSON.stringify(result)).not.toContain("bound-account");
|
||||
expect(nativeProbe).toHaveBeenCalledOnce();
|
||||
expect(execute).not.toHaveBeenCalled();
|
||||
});
|
||||
it.each([
|
||||
["authentication required: selected-account", true],
|
||||
["Model is unavailable", false],
|
||||
["native executable is missing", false],
|
||||
])("projects the canonical sandbox login check only for authentication failures (%s)", async (message, authentication) => {
|
||||
nativeProbe.mockRejectedValue(new Error(message));
|
||||
const result = await testNativeRunnerAuthentication(context, "codex", "gpt-6.1-sol");
|
||||
expect(result.status).toBe("fail");
|
||||
expect(result.checks[0].code).toBe(`codex_hello_probe_${authentication ? "auth_required" : "failed"}`);
|
||||
expect(result.checks.some(check => check.code === ADAPTER_AUTH_MISSING_CHECK_CODE)).toBe(authentication);
|
||||
if (authentication) expect(result.checks).toContainEqual(expect.objectContaining({ code: ADAPTER_AUTH_MISSING_CHECK_CODE, level: "error" }));
|
||||
expect(nativeProbe).toHaveBeenCalledOnce();
|
||||
expect(execute).not.toHaveBeenCalled();
|
||||
});
|
||||
it.each([
|
||||
{ helloProbePassed: undefined }, { effectiveModel: "another-model" }, { effectiveModel: null }, { effectiveModel: "" }, { provider: "opencode" }, { providerDriver: "codex_cli" },
|
||||
])("rejects installation-only, legacy, or mismatched receipts", async override => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import { tmpdir } from "node:os";
|
||||
import { join, posix } from "node:path";
|
||||
import { copyBackCodexAuth } from "@paperclipai/adapter-codex-local/server";
|
||||
import type { AdapterEnvironmentTestContext, AdapterEnvironmentTestResult } from "@paperclipai/adapter-utils";
|
||||
import { ADAPTER_AUTH_MISSING_CHECK_CODE } from "@paperclipai/shared";
|
||||
import { probeNativeRunnerEnvironment, resolveSourceCodexHome } from "../../vendor/paperclip-runner/index.js";
|
||||
import { resolvePaperclipRunnerBinary } from "./native-codex-runner.js";
|
||||
import { readLocalAiCredentialFile } from "../local-ai-credential-file.js";
|
||||
@@ -207,6 +208,9 @@ export async function testNativeRunnerAuthentication(context: AdapterEnvironment
|
||||
const message = redactNativeProbeMessage(error instanceof Error ? error.message : "The selected native runtime could not verify this account.", environment);
|
||||
const authentication = /(?:invalid (?:api[- ]?key|auth(?:entication)? token)|authentication (?:failed|required)|unauthenticated|unauthorized|not authenticated|please (?:log|sign) in|not logged in|\b(?:401|403)\b)/i.test(message);
|
||||
return { adapterType: "paperclip_runner", status: "fail", testedAt: new Date().toISOString(), checks: [{ code: `${provider}_hello_probe_${authentication ? "auth_required" : /timed out/i.test(message) ? "timeout" : "failed"}`, level: "error", message,
|
||||
hint: "Check the selected account, model access, and native runtime prerequisites, then retry. Legacy runner is available explicitly in Advanced." }] };
|
||||
hint: "Check the selected account, model access, and native runtime prerequisites, then retry. Legacy runner is available explicitly in Advanced." },
|
||||
...(authentication && provider === "codex" ? [{ code: ADAPTER_AUTH_MISSING_CHECK_CODE, level: "error" as const,
|
||||
message: "The selected Codex account needs authentication.",
|
||||
hint: "Sign in to Codex or choose an authenticated account, then test again." }] : [])] };
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user