mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 11:09:34 +00:00
97 lines
3.2 KiB
TypeScript
97 lines
3.2 KiB
TypeScript
import type { ApiKeyAuth, ApiKeyCredential, AuthContext } from "../auth/types.ts";
|
|
import type { ProviderEnv } from "../types.ts";
|
|
|
|
const CLOUDFLARE_API_KEY = "CLOUDFLARE_API_KEY";
|
|
const CLOUDFLARE_ACCOUNT_ID = "CLOUDFLARE_ACCOUNT_ID";
|
|
const CLOUDFLARE_GATEWAY_ID = "CLOUDFLARE_GATEWAY_ID";
|
|
|
|
type CloudflareAuthKind = "workers-ai" | "ai-gateway";
|
|
|
|
async function resolveValue(
|
|
name: string,
|
|
ctx: AuthContext,
|
|
credential: ApiKeyCredential | undefined,
|
|
): Promise<string | undefined> {
|
|
// Per-field merge: prefer the credential value, fall back to ambient env.
|
|
// A credential carrying only the API key must still pick up the account /
|
|
// gateway id from the environment.
|
|
const fromCredential = credential
|
|
? name === CLOUDFLARE_API_KEY
|
|
? credential.key
|
|
: credential.env?.[name]
|
|
: undefined;
|
|
return fromCredential ?? (await ctx.env(name));
|
|
}
|
|
|
|
async function resolveCloudflareEnv(
|
|
kind: CloudflareAuthKind,
|
|
ctx: AuthContext,
|
|
credential: ApiKeyCredential | undefined,
|
|
): Promise<{ apiKey: string; env: ProviderEnv; source: string } | undefined> {
|
|
const apiKey = await resolveValue(CLOUDFLARE_API_KEY, ctx, credential);
|
|
const accountId = await resolveValue(CLOUDFLARE_ACCOUNT_ID, ctx, credential);
|
|
const gatewayId = kind === "ai-gateway" ? await resolveValue(CLOUDFLARE_GATEWAY_ID, ctx, credential) : undefined;
|
|
|
|
if (!apiKey || !accountId || (kind === "ai-gateway" && !gatewayId)) return undefined;
|
|
|
|
return {
|
|
apiKey,
|
|
env: {
|
|
CLOUDFLARE_ACCOUNT_ID: accountId,
|
|
...(gatewayId ? { CLOUDFLARE_GATEWAY_ID: gatewayId } : {}),
|
|
},
|
|
source: credential ? "stored credential" : CLOUDFLARE_API_KEY,
|
|
};
|
|
}
|
|
|
|
export function cloudflareWorkersAIAuth(): ApiKeyAuth {
|
|
return {
|
|
name: "Cloudflare API key",
|
|
login: async (interaction) => {
|
|
const key = await interaction.prompt({ type: "secret", message: "Enter Cloudflare API key" });
|
|
const accountId = await interaction.prompt({ type: "text", message: "Enter Cloudflare account ID" });
|
|
return { type: "api_key", key, env: { CLOUDFLARE_ACCOUNT_ID: accountId } };
|
|
},
|
|
resolve: async ({ ctx, credential }) => {
|
|
const resolved = await resolveCloudflareEnv("workers-ai", ctx, credential);
|
|
if (!resolved) return undefined;
|
|
return {
|
|
auth: { apiKey: resolved.apiKey },
|
|
env: resolved.env,
|
|
source: resolved.source,
|
|
};
|
|
},
|
|
};
|
|
}
|
|
|
|
export function cloudflareAIGatewayAuth(): ApiKeyAuth {
|
|
return {
|
|
name: "Cloudflare API key",
|
|
login: async (interaction) => {
|
|
const key = await interaction.prompt({ type: "secret", message: "Enter Cloudflare API key" });
|
|
const accountId = await interaction.prompt({ type: "text", message: "Enter Cloudflare account ID" });
|
|
const gatewayId = await interaction.prompt({ type: "text", message: "Enter Cloudflare AI Gateway ID" });
|
|
return {
|
|
type: "api_key",
|
|
key,
|
|
env: { CLOUDFLARE_ACCOUNT_ID: accountId, CLOUDFLARE_GATEWAY_ID: gatewayId },
|
|
};
|
|
},
|
|
resolve: async ({ ctx, credential }) => {
|
|
const resolved = await resolveCloudflareEnv("ai-gateway", ctx, credential);
|
|
if (!resolved) return undefined;
|
|
return {
|
|
auth: {
|
|
headers: {
|
|
"cf-aig-authorization": `Bearer ${resolved.apiKey}`,
|
|
Authorization: null,
|
|
"x-api-key": null,
|
|
},
|
|
},
|
|
env: resolved.env,
|
|
source: resolved.source,
|
|
};
|
|
},
|
|
};
|
|
}
|