mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-23 17:33:51 +02:00
Verify native Pi OpenRouter accounts without the Legacy CLI
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
8104d32a06
commit
7d5fd0f139
2 files changed
+25
-1
No files matched your search
@@ -100,6 +100,27 @@ describe("managed AI connections", () => {
|
||||
await expect(prepareManagedAiRuntime(db, { ...piInput, config: { ...piInput.config, env: { PAPERCLIP_PI_PROVIDERS: "{}" } } })).rejects.toThrow("routing is incompatible");
|
||||
});
|
||||
|
||||
it.each([200, 401])("reverifies native Pi OpenRouter keys without requiring the Legacy Pi CLI (HTTP %s)", async status => {
|
||||
const owner = `pi-adoption-${status}`;
|
||||
await db.insert(companyMemberships).values({ companyId, principalId: owner, principalType: "user", status: "active", membershipRole: "member" });
|
||||
const token = `fixture-pi-adoption-${status}`;
|
||||
const account = await service.save(companyId, owner, { provider: "openrouter", method: "api_key", ownership: "personal", name: owner, apiKey: token, allAgents: true, agentIds: [], routing: { kind: "openrouter", protocol: "chat", auth: "bearer", models: [] } }, token);
|
||||
const selected = { provider: "openrouter", method: "api_key", mode: "delegated", ...account } as const;
|
||||
const runtime = await prepareManagedAiRuntime(db, { companyId, agentId, responsibleUserId: owner, adapterType: "paperclip_runner", binding: selected, config: { provider: "acpx", acpxAgent: "pi", model: "openrouter/anthropic/claude-sonnet-4.5" } });
|
||||
const { requireServerAdapter } = await import("../adapters/index.js");
|
||||
const { agentEnvironmentTestService } = await import("../services/agent-environment-test.js");
|
||||
const native = vi.spyOn(requireServerAdapter("paperclip_runner"), "testEnvironment").mockResolvedValue({ adapterType: "paperclip_runner", status: "pass", testedAt: new Date().toISOString(), checks: [{ code: "acpx_runtime_ready", level: "info", message: "Pinned Pi runtime verified" }] });
|
||||
const legacy = vi.spyOn(requireServerAdapter("pi_local"), "testEnvironment").mockRejectedValue(new Error("Legacy Pi CLI must not be required"));
|
||||
const request = vi.spyOn(globalThis, "fetch").mockResolvedValue(new Response(JSON.stringify({ data: {} }), { status }));
|
||||
try {
|
||||
const result = await agentEnvironmentTestService(db).testManagedEnvironment("paperclip_runner", { companyId, adapterType: "paperclip_runner", config: runtime.config }, selected, runtime, agentId);
|
||||
expect(result.status).toBe(status === 200 ? "pass" : "fail");
|
||||
expect(result.checks).toContainEqual(expect.objectContaining({ code: status === 200 ? "ai_connection_api_key_reverified" : "ai_connection_api_key_rejected" }));
|
||||
expect(legacy).not.toHaveBeenCalled();
|
||||
expect(request).toHaveBeenCalled();
|
||||
} finally { native.mockRestore(); legacy.mockRestore(); request.mockRestore(); await runtime.cleanup(); }
|
||||
});
|
||||
|
||||
it("defers a new plugin agent's Copilot check until its saved-agent lifecycle can acquire the computer", async () => {
|
||||
const { errorHandler } = await import("../middleware/index.js");
|
||||
const owner = "copilot-plugin-bootstrap", pluginId = randomUUID();
|
||||
|
||||
@@ -548,7 +548,10 @@ export function agentEnvironmentTestService(db: Db, pluginWorkerManager?: Plugin
|
||||
// requirement stays for subscriptions: a stored login is a file layout
|
||||
// only a provider CLI reads, so proving the runtime lane can consume it
|
||||
// takes a real hello turn.
|
||||
if (resolvedMethod === "api_key" && !context.config.managedAiRouting) {
|
||||
const nativePiOpenRouter = adapterType === "paperclip_runner" && context.config.provider === "acpx"
|
||||
&& context.config.acpxAgent === "pi" && binding.provider === "openrouter"
|
||||
&& asRecord(context.config.managedAiRouting)?.kind === "openrouter";
|
||||
if (resolvedMethod === "api_key" && (!context.config.managedAiRouting || nativePiOpenRouter)) {
|
||||
const envKey = AI_CONNECTION_CAPABILITIES[binding.provider].methods.api_key?.envKey;
|
||||
const key = envKey ? parseObject(context.config.env)[envKey] : undefined;
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user