Something went wrong. Try again.
fork of prime agent with changes i want but are not upstreamable probqbly (and some fixes)
Something went wrong. Try again.
4.5 kB · 142 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143/** * Resolve configuration values that may be shell commands, environment variables, or literals. * Used by auth-storage.ts and model-registry.ts. */
import { execSyncHidden, spawnSyncHidden } from "../utils/child-process.js";import { getShellConfig } from "../utils/shell.js";
const commandResultCache = new Map<string, string | undefined>();
/** * Resolve a config value (API key, header value, etc.) to an actual value. * - If starts with "!", executes the rest as a shell command and uses stdout (cached) * - Otherwise checks environment variable first, then treats as literal (not cached) */export function resolveConfigValue(config: string): string | undefined { if (config.startsWith("!")) { return executeCommand(config); } return resolveEnvOrLiteral(config);}
/** Unset env var: fall back to the literal string. Set-but-empty: missing credential, never the var name. */function resolveEnvOrLiteral(config: string): string | undefined { const envValue = process.env[config]; if (envValue !== undefined) { return envValue || undefined; } return config;}
function executeWithConfiguredShell(command: string): { executed: boolean; value: string | undefined } { try { const { shell, args } = getShellConfig(); const result = spawnSyncHidden(shell, [...args, command], { encoding: "utf-8", timeout: 10000, stdio: ["ignore", "pipe", "ignore"], shell: false, });
if (result.error) { const error = result.error as NodeJS.ErrnoException; if (error.code === "ENOENT") { return { executed: false, value: undefined }; } return { executed: true, value: undefined }; }
if (result.status !== 0) { return { executed: true, value: undefined }; }
const value = (result.stdout ?? "").trim(); return { executed: true, value: value || undefined }; } catch { return { executed: false, value: undefined }; }}
function executeWithDefaultShell(command: string): string | undefined { try { const output = execSyncHidden(command, { encoding: "utf-8", timeout: 10000, stdio: ["ignore", "pipe", "ignore"], }); return output.trim() || undefined; } catch { return undefined; }}
function executeCommandUncached(commandConfig: string): string | undefined { const command = commandConfig.slice(1); return process.platform === "win32" ? (() => { const configuredResult = executeWithConfiguredShell(command); return configuredResult.executed ? configuredResult.value : executeWithDefaultShell(command); })() : executeWithDefaultShell(command);}
function executeCommand(commandConfig: string): string | undefined { if (commandResultCache.has(commandConfig)) { return commandResultCache.get(commandConfig); }
const result = executeCommandUncached(commandConfig); commandResultCache.set(commandConfig, result); return result;}
/** * Resolve all header values using the same resolution logic as API keys. */export function resolveConfigValueUncached(config: string): string | undefined { if (config.startsWith("!")) { return executeCommandUncached(config); } return resolveEnvOrLiteral(config);}
export function resolveConfigValueOrThrow(config: string, description: string): string { const resolvedValue = resolveConfigValueUncached(config); if (resolvedValue !== undefined) { return resolvedValue; }
if (config.startsWith("!")) { throw new Error(`Failed to resolve ${description} from shell command: ${config.slice(1)}`); }
throw new Error(`Failed to resolve ${description}`);}
/** * Resolve all header values using the same resolution logic as API keys. */export function resolveHeaders(headers: Record<string, string> | undefined): Record<string, string> | undefined { if (!headers) return undefined; const resolved: Record<string, string> = {}; for (const [key, value] of Object.entries(headers)) { const resolvedValue = resolveConfigValue(value); if (resolvedValue) { resolved[key] = resolvedValue; } } return Object.keys(resolved).length > 0 ? resolved : undefined;}
export function resolveHeadersOrThrow( headers: Record<string, string> | undefined, description: string,): Record<string, string> | undefined { if (!headers) return undefined; const resolved: Record<string, string> = {}; for (const [key, value] of Object.entries(headers)) { resolved[key] = resolveConfigValueOrThrow(value, `${description} header "${key}"`); } return Object.keys(resolved).length > 0 ? resolved : undefined;}