fix: show model auth in status
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
- Docs: clarify auth storage, migration, and OpenAI Codex OAuth onboarding.
|
- Docs: clarify auth storage, migration, and OpenAI Codex OAuth onboarding.
|
||||||
- Sandbox: copy inbound media into sandbox workspaces so agent tools can read attachments.
|
- Sandbox: copy inbound media into sandbox workspaces so agent tools can read attachments.
|
||||||
- Status: show runtime (docker/direct) and move shortcuts to `/help`.
|
- Status: show runtime (docker/direct) and move shortcuts to `/help`.
|
||||||
|
- Status: show model auth source (api-key/oauth).
|
||||||
|
|
||||||
### Maintenance
|
### Maintenance
|
||||||
- Deps: bump pi-* stack, Slack SDK, discord-api-types, file-type, zod, and Biome.
|
- Deps: bump pi-* stack, Slack SDK, discord-api-types, file-type, zod, and Biome.
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import fs from "node:fs";
|
||||||
|
|
||||||
import type { ClawdbotConfig } from "../../config/config.js";
|
import type { ClawdbotConfig } from "../../config/config.js";
|
||||||
import {
|
import {
|
||||||
type SessionEntry,
|
type SessionEntry,
|
||||||
@@ -10,6 +12,10 @@ import { resolveSendPolicy } from "../../sessions/send-policy.js";
|
|||||||
import { normalizeE164 } from "../../utils.js";
|
import { normalizeE164 } from "../../utils.js";
|
||||||
import { resolveHeartbeatSeconds } from "../../web/reconnect.js";
|
import { resolveHeartbeatSeconds } from "../../web/reconnect.js";
|
||||||
import { getWebAuthAgeMs, webAuthExists } from "../../web/session.js";
|
import { getWebAuthAgeMs, webAuthExists } from "../../web/session.js";
|
||||||
|
import { resolveClawdbotAgentDir } from "../../agents/agent-paths.js";
|
||||||
|
import { resolveOAuthPath } from "../../config/paths.js";
|
||||||
|
import { getEnvApiKey } from "@mariozechner/pi-ai";
|
||||||
|
import { discoverAuthStorage } from "@mariozechner/pi-coding-agent";
|
||||||
import {
|
import {
|
||||||
normalizeGroupActivation,
|
normalizeGroupActivation,
|
||||||
parseActivationCommand,
|
parseActivationCommand,
|
||||||
@@ -36,6 +42,58 @@ export type CommandContext = {
|
|||||||
to?: string;
|
to?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function hasOAuthCredentials(provider: string): boolean {
|
||||||
|
try {
|
||||||
|
const oauthPath = resolveOAuthPath();
|
||||||
|
if (!fs.existsSync(oauthPath)) return false;
|
||||||
|
const raw = fs.readFileSync(oauthPath, "utf8");
|
||||||
|
const parsed = JSON.parse(raw) as Record<string, unknown>;
|
||||||
|
const entry = parsed?.[provider] as
|
||||||
|
| {
|
||||||
|
refresh?: string;
|
||||||
|
refresh_token?: string;
|
||||||
|
refreshToken?: string;
|
||||||
|
access?: string;
|
||||||
|
access_token?: string;
|
||||||
|
accessToken?: string;
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
|
if (!entry) return false;
|
||||||
|
const refresh =
|
||||||
|
entry.refresh ?? entry.refresh_token ?? entry.refreshToken ?? "";
|
||||||
|
const access = entry.access ?? entry.access_token ?? entry.accessToken ?? "";
|
||||||
|
return Boolean(refresh.trim() && access.trim());
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveModelAuthLabel(provider?: string): string | undefined {
|
||||||
|
const resolved = provider?.trim();
|
||||||
|
if (!resolved) return undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const authStorage = discoverAuthStorage(resolveClawdbotAgentDir());
|
||||||
|
const stored = authStorage.get(resolved);
|
||||||
|
if (stored?.type === "oauth") return "oauth";
|
||||||
|
if (stored?.type === "api_key") return "api-key";
|
||||||
|
} catch {
|
||||||
|
// ignore auth storage errors
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolved === "anthropic") {
|
||||||
|
const oauthEnv = process.env.ANTHROPIC_OAUTH_TOKEN;
|
||||||
|
if (oauthEnv?.trim()) return "oauth";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasOAuthCredentials(resolved)) return "oauth";
|
||||||
|
|
||||||
|
const envKey = getEnvApiKey(resolved);
|
||||||
|
if (envKey?.trim()) return "api-key";
|
||||||
|
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
export function buildCommandContext(params: {
|
export function buildCommandContext(params: {
|
||||||
ctx: MsgContext;
|
ctx: MsgContext;
|
||||||
cfg: ClawdbotConfig;
|
cfg: ClawdbotConfig;
|
||||||
@@ -314,6 +372,7 @@ export async function handleCommands(params: {
|
|||||||
resolvedThinkLevel ?? (await resolveDefaultThinkingLevel()),
|
resolvedThinkLevel ?? (await resolveDefaultThinkingLevel()),
|
||||||
resolvedVerbose: resolvedVerboseLevel,
|
resolvedVerbose: resolvedVerboseLevel,
|
||||||
resolvedElevated: resolvedElevatedLevel,
|
resolvedElevated: resolvedElevatedLevel,
|
||||||
|
modelAuth: resolveModelAuthLabel(provider),
|
||||||
webLinked,
|
webLinked,
|
||||||
webAuthAgeMs,
|
webAuthAgeMs,
|
||||||
heartbeatSeconds,
|
heartbeatSeconds,
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ type StatusArgs = {
|
|||||||
resolvedThink?: ThinkLevel;
|
resolvedThink?: ThinkLevel;
|
||||||
resolvedVerbose?: VerboseLevel;
|
resolvedVerbose?: VerboseLevel;
|
||||||
resolvedElevated?: ElevatedLevel;
|
resolvedElevated?: ElevatedLevel;
|
||||||
|
modelAuth?: string;
|
||||||
now?: number;
|
now?: number;
|
||||||
webLinked?: boolean;
|
webLinked?: boolean;
|
||||||
webAuthAgeMs?: number | null;
|
webAuthAgeMs?: number | null;
|
||||||
@@ -236,6 +237,7 @@ export function buildStatusMessage(args: StatusArgs): string {
|
|||||||
const modelLabel = model ? `${provider}/${model}` : "unknown";
|
const modelLabel = model ? `${provider}/${model}` : "unknown";
|
||||||
|
|
||||||
const agentLine = `Agent: embedded pi • ${modelLabel}`;
|
const agentLine = `Agent: embedded pi • ${modelLabel}`;
|
||||||
|
const authLine = args.modelAuth ? `Model auth: ${args.modelAuth}` : undefined;
|
||||||
|
|
||||||
const workspaceLine = args.workspaceDir
|
const workspaceLine = args.workspaceDir
|
||||||
? `Workspace: ${shortenHomePath(args.workspaceDir)}`
|
? `Workspace: ${shortenHomePath(args.workspaceDir)}`
|
||||||
@@ -245,6 +247,7 @@ export function buildStatusMessage(args: StatusArgs): string {
|
|||||||
"⚙️ Status",
|
"⚙️ Status",
|
||||||
webLine,
|
webLine,
|
||||||
agentLine,
|
agentLine,
|
||||||
|
authLine,
|
||||||
runtime.line,
|
runtime.line,
|
||||||
workspaceLine,
|
workspaceLine,
|
||||||
contextLine,
|
contextLine,
|
||||||
|
|||||||
Reference in New Issue
Block a user