UNPKG

@gguf/claw

Version:

Multi-channel AI gateway with extensible messaging integrations

120 lines (118 loc) 3.91 kB
import "./paths-CyR9Pa1R.js"; import "./registry-BmY4gNy6.js"; import "./agent-scope-BLYwrEEA.js"; import "./subsystem-B5g771Td.js"; import "./workspace-D9IzNnST.js"; import "./boolean-B8-BqKGQ.js"; import "./command-format-Ck2WauwF.js"; import { A as normalizeProviderId, _ as ensureAuthProfileStore } from "./model-auth-BPNt9bHS.js"; import "./github-copilot-token-BQ98eazZ.js"; import fs from "node:fs/promises"; import path from "node:path"; //#region src/agents/pi-auth-json.ts async function readAuthJson(filePath) { try { const raw = await fs.readFile(filePath, "utf8"); const parsed = JSON.parse(raw); if (!parsed || typeof parsed !== "object") return {}; return parsed; } catch { return {}; } } /** * Convert an OpenClaw auth-profiles credential to pi-coding-agent auth.json format. * Returns null if the credential cannot be converted. */ function convertCredential(cred) { if (cred.type === "api_key") { const key = typeof cred.key === "string" ? cred.key.trim() : ""; if (!key) return null; return { type: "api_key", key }; } if (cred.type === "token") { const token = typeof cred.token === "string" ? cred.token.trim() : ""; if (!token) return null; const expires = typeof cred.expires === "number" ? cred.expires : NaN; if (Number.isFinite(expires) && expires > 0 && Date.now() >= expires) return null; return { type: "api_key", key: token }; } if (cred.type === "oauth") { const accessRaw = cred.access; const refreshRaw = cred.refresh; const expiresRaw = cred.expires; const access = typeof accessRaw === "string" ? accessRaw.trim() : ""; const refresh = typeof refreshRaw === "string" ? refreshRaw.trim() : ""; const expires = typeof expiresRaw === "number" ? expiresRaw : NaN; if (!access || !refresh || !Number.isFinite(expires) || expires <= 0) return null; return { type: "oauth", access, refresh, expires }; } return null; } /** * Check if two auth.json credentials are equivalent. */ function credentialsEqual(a, b) { if (!a || typeof a !== "object") return false; if (a.type !== b.type) return false; if (a.type === "api_key" && b.type === "api_key") return a.key === b.key; if (a.type === "oauth" && b.type === "oauth") return a.access === b.access && a.refresh === b.refresh && a.expires === b.expires; return false; } /** * pi-coding-agent's ModelRegistry/AuthStorage expects credentials in auth.json. * * OpenClaw stores credentials in auth-profiles.json instead. This helper * bridges all credentials into agentDir/auth.json so pi-coding-agent can * (a) consider providers authenticated and (b) include built-in models in its * registry/catalog output. * * Syncs all credential types: api_key, token (as api_key), and oauth. */ async function ensurePiAuthJsonFromAuthProfiles(agentDir) { const store = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false }); const authPath = path.join(agentDir, "auth.json"); const providerCredentials = /* @__PURE__ */ new Map(); for (const [, cred] of Object.entries(store.profiles)) { const provider = normalizeProviderId(String(cred.provider ?? "")).trim(); if (!provider || providerCredentials.has(provider)) continue; const converted = convertCredential(cred); if (converted) providerCredentials.set(provider, converted); } if (providerCredentials.size === 0) return { wrote: false, authPath }; const existing = await readAuthJson(authPath); let changed = false; for (const [provider, cred] of providerCredentials) if (!credentialsEqual(existing[provider], cred)) { existing[provider] = cred; changed = true; } if (!changed) return { wrote: false, authPath }; await fs.mkdir(agentDir, { recursive: true, mode: 448 }); await fs.writeFile(authPath, `${JSON.stringify(existing, null, 2)}\n`, { mode: 384 }); return { wrote: true, authPath }; } //#endregion export { ensurePiAuthJsonFromAuthProfiles };