mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-07 07:55:47 +01:00
feat: default Claude to the native runner on Apple Silicon
Carry Claude effort through versioned native admission and recovery. Preserve existing connections and saved runner choices, and price Opus 5.5 API receipts. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
058af8f1b6
commit
6fd56c445d
77 files changed
+909
-296
No files matched your search
@@ -575,13 +575,14 @@ function importAdapterValues(
|
||||
sourceAdapterType?: string,
|
||||
runner?: AgentRunnerChoice,
|
||||
): CreateConfigValues {
|
||||
const nativeCodex = sourceAdapterType === "paperclip_runner" && choice === "codex_local";
|
||||
const nativeHarness = sourceAdapterType === "paperclip_runner" && ["codex_local", "claude_local"].includes(choice);
|
||||
const nativeCodex = nativeHarness && choice === "codex_local";
|
||||
const savedBypass = sourceConfig?.dangerouslyBypassApprovalsAndSandbox
|
||||
?? (nativeCodex ? undefined : sourceConfig?.dangerouslyBypassSandbox);
|
||||
return {
|
||||
...defaultCreateValues,
|
||||
adapterType: choice === "openai_dot" ? "paperclip_runner" : choice,
|
||||
...(runner !== undefined ? { runner } : nativeCodex ? { runner: agentRunner("paperclip_runner") } : {}),
|
||||
...(runner !== undefined ? { runner } : nativeHarness ? { runner: agentRunner("paperclip_runner") } : {}),
|
||||
...(sourceConfig && choice === "codex_local" ? {
|
||||
model: typeof sourceConfig.model === "string" ? sourceConfig.model : "",
|
||||
thinkingEffort: String(sourceConfig.reasoningEffort ?? sourceConfig.modelReasoningEffort ?? ""),
|
||||
@@ -591,6 +592,7 @@ function importAdapterValues(
|
||||
? (sourceConfig.codexPermissionMode ?? PAPERCLIP_RUNNER_PERMISSION_CAPABILITIES.codex.defaultMode) === "never"
|
||||
: DEFAULT_CODEX_LOCAL_BYPASS_APPROVALS_AND_SANDBOX,
|
||||
} : {}),
|
||||
...(sourceConfig && choice === "claude_local" ? { model: typeof sourceConfig.model === "string" ? sourceConfig.model : "", thinkingEffort: String(sourceConfig.modelReasoningEffort ?? sourceConfig.reasoningEffort ?? sourceConfig.effort ?? "") } : {}),
|
||||
...(sourceAdapterType === "paperclip_runner" && choice !== "openai_dot"
|
||||
? { adapterSchemaValues: { ...sourceConfig } } : {}),
|
||||
...(choice === "openai_dot" ? {
|
||||
@@ -1670,14 +1672,15 @@ export function CompanyImport() {
|
||||
return importPreview.manifest.agents.map((a) => {
|
||||
const nativeCodex = a.adapterType === "paperclip_runner"
|
||||
&& (a.adapterConfig?.provider === "codex" || a.adapterConfig?.provider === undefined);
|
||||
const nativeHarness = nativeCodex || (a.adapterType === "paperclip_runner" && agentHarnessType(a.adapterType, a.adapterConfig) === "claude_local");
|
||||
const adapterChoice = a.adapterType === "paperclip_runner" && a.adapterConfig?.provider === "openai_dot"
|
||||
? "openai_dot" : nativeCodex ? agentHarnessType(a.adapterType, a.adapterConfig) : a.adapterType;
|
||||
? "openai_dot" : nativeHarness ? agentHarnessType(a.adapterType, a.adapterConfig) : a.adapterType;
|
||||
let fallbackAdapterType: string | null = null;
|
||||
let availabilityWarning: string | undefined;
|
||||
if (a.adapterType === "paperclip_runner") {
|
||||
const available = nativeCodex ? runnerInstalled : adapterChoice === "openai_dot" ? dotAvailable : nativeRunnerAvailable;
|
||||
if (!available && (availableAdapterTypes || !nativeCodex)) {
|
||||
availabilityWarning = nativeCodex
|
||||
const available = nativeHarness ? runnerInstalled : adapterChoice === "openai_dot" ? dotAvailable : nativeRunnerAvailable;
|
||||
if (!available && (availableAdapterTypes || !nativeHarness)) {
|
||||
availabilityWarning = nativeHarness
|
||||
? "Paperclip Runner is unavailable here. Choose a runner or another harness explicitly."
|
||||
: `Paperclip Runner provider ${String(a.adapterConfig?.provider)} requires its experimental feature to be enabled. This import keeps its saved harness until you choose another one.`;
|
||||
}
|
||||
|
||||
@@ -412,11 +412,21 @@ describe("New agent setup", () => {
|
||||
await click("Finish setup");
|
||||
expect(api.hire.mock.calls[0][1].defaultEnvironmentId).toBe("grok-sandbox");
|
||||
});
|
||||
it.each([false, true])("keeps non-Codex runner setup links gated when the experiment is disabled (cloud=%s)", async (cloud) => {
|
||||
it.each([false, true])("keeps other native setup links gated when the experiment is disabled (cloud=%s)", async (cloud) => {
|
||||
cache.setQueryData(queryKeys.health, { status: "ok", cloud: { managed: cloud } });
|
||||
settings.getExperimental.mockResolvedValue({ enableNativeRunner: false });
|
||||
await render("paperclip_runner", "grok");
|
||||
expect(container.textContent).toContain("This adapter is unavailable");
|
||||
expect(api.hire).not.toHaveBeenCalled();
|
||||
});
|
||||
it.each([false, true])("restores native Claude setup intent and its connection flow with experiment=false (cloud=%s)", async cloud => {
|
||||
cache.setQueryData(queryKeys.health, { status: "ok", cloud: { managed: cloud } });
|
||||
settings.getExperimental.mockResolvedValue({ enableNativeRunner: false });
|
||||
await render("paperclip_runner", "claude");
|
||||
expect(container.textContent).toContain("This adapter is unavailable");
|
||||
expect(container.textContent).not.toContain("This adapter is unavailable");
|
||||
expect(container.textContent).toContain("Claude Code");
|
||||
expect(container.textContent).toContain("Paperclip Runner");
|
||||
expect(container.textContent).toContain("Connect a model");
|
||||
expect(api.hire).not.toHaveBeenCalled();
|
||||
});
|
||||
it("blocks direct setup links for unsupported Cloud adapters", async () => {
|
||||
|
||||
Reference in new issue
Block a user