mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-13 08:23:18 +08:00
重构主控编排与运行时预热链路,统一工作区提示词/专家调度协议并补齐 wiki 记忆注入与写回闭环。
同时收敛启动与运维脚本默认行为(含 wiki worker)、更新 Admin 可观测性与相关测试,降低首轮时延并提高运行稳定性。 Made-with: Cursor
This commit is contained in:
parent
4a23b715a2
commit
dbbe3add6a
14438 changed files with 2693620 additions and 2546 deletions
92
openclaw/extensions/google/oauth.ts
Normal file
92
openclaw/extensions/google/oauth.ts
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import { clearCredentialsCache, extractGeminiCliCredentials } from "./oauth.credentials.js";
|
||||
import {
|
||||
buildAuthUrl,
|
||||
generateOAuthState,
|
||||
generatePkce,
|
||||
parseCallbackInput,
|
||||
shouldUseManualOAuthFlow,
|
||||
waitForLocalCallback,
|
||||
} from "./oauth.flow.js";
|
||||
import type { GeminiCliOAuthContext, GeminiCliOAuthCredentials } from "./oauth.shared.js";
|
||||
import { exchangeCodeForTokens } from "./oauth.token.js";
|
||||
|
||||
export { clearCredentialsCache, extractGeminiCliCredentials };
|
||||
export type { GeminiCliOAuthContext, GeminiCliOAuthCredentials };
|
||||
|
||||
export async function loginGeminiCliOAuth(
|
||||
ctx: GeminiCliOAuthContext,
|
||||
): Promise<GeminiCliOAuthCredentials> {
|
||||
const needsManual = shouldUseManualOAuthFlow(ctx.isRemote);
|
||||
await ctx.note(
|
||||
needsManual
|
||||
? [
|
||||
"You are running in a remote/VPS environment.",
|
||||
"A URL will be shown for you to open in your LOCAL browser.",
|
||||
"After signing in, copy the redirect URL and paste it back here.",
|
||||
].join("\n")
|
||||
: [
|
||||
"Browser will open for Google authentication.",
|
||||
"Sign in with your Google account for Gemini CLI access.",
|
||||
"The callback will be captured automatically on localhost:8085.",
|
||||
].join("\n"),
|
||||
"Gemini CLI OAuth",
|
||||
);
|
||||
|
||||
const { verifier, challenge } = generatePkce();
|
||||
const state = generateOAuthState();
|
||||
const authUrl = buildAuthUrl(challenge, state);
|
||||
|
||||
if (needsManual) {
|
||||
ctx.progress.update("OAuth URL ready");
|
||||
ctx.log(`\nOpen this URL in your LOCAL browser:\n\n${authUrl}\n`);
|
||||
ctx.progress.update("Waiting for you to paste the callback URL...");
|
||||
const callbackInput = await ctx.prompt("Paste the redirect URL here: ");
|
||||
const parsed = parseCallbackInput(callbackInput);
|
||||
if ("error" in parsed) {
|
||||
throw new Error(parsed.error);
|
||||
}
|
||||
if (parsed.state !== state) {
|
||||
throw new Error("OAuth state mismatch - please try again");
|
||||
}
|
||||
ctx.progress.update("Exchanging authorization code for tokens...");
|
||||
return exchangeCodeForTokens(parsed.code, verifier);
|
||||
}
|
||||
|
||||
ctx.progress.update("Complete sign-in in browser...");
|
||||
try {
|
||||
await ctx.openUrl(authUrl);
|
||||
} catch {
|
||||
ctx.log(`\nOpen this URL in your browser:\n\n${authUrl}\n`);
|
||||
}
|
||||
|
||||
try {
|
||||
const { code } = await waitForLocalCallback({
|
||||
expectedState: state,
|
||||
timeoutMs: 5 * 60 * 1000,
|
||||
onProgress: (msg) => ctx.progress.update(msg),
|
||||
});
|
||||
ctx.progress.update("Exchanging authorization code for tokens...");
|
||||
return await exchangeCodeForTokens(code, verifier);
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof Error &&
|
||||
(err.message.includes("EADDRINUSE") ||
|
||||
err.message.includes("port") ||
|
||||
err.message.includes("listen"))
|
||||
) {
|
||||
ctx.progress.update("Local callback server failed. Switching to manual mode...");
|
||||
ctx.log(`\nOpen this URL in your LOCAL browser:\n\n${authUrl}\n`);
|
||||
const callbackInput = await ctx.prompt("Paste the redirect URL here: ");
|
||||
const parsed = parseCallbackInput(callbackInput);
|
||||
if ("error" in parsed) {
|
||||
throw new Error(parsed.error, { cause: err });
|
||||
}
|
||||
if (parsed.state !== state) {
|
||||
throw new Error("OAuth state mismatch - please try again", { cause: err });
|
||||
}
|
||||
ctx.progress.update("Exchanging authorization code for tokens...");
|
||||
return exchangeCodeForTokens(parsed.code, verifier);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue