mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-27 03:32:55 +00:00
Share Paseo Agent env reference helpers
This commit is contained in:
@@ -18,6 +18,7 @@ import {
|
||||
} from "./config.js";
|
||||
import { hasStoredOAuthCredential, storeCodexOAuthCredential } from "./oauth-store.js";
|
||||
import { isRefreshTokenExpressionConfigured } from "./oauth-credentials.js";
|
||||
import { findEnvReferences } from "./env-references.js";
|
||||
|
||||
interface PaseoAgentConfigServiceOptions {
|
||||
paseoHome: string;
|
||||
@@ -46,8 +47,6 @@ interface SetProviderInput {
|
||||
};
|
||||
}
|
||||
|
||||
const ENV_REFERENCE_PATTERN = /\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?/g;
|
||||
|
||||
function resolveEnv(paseoHome: string, env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
|
||||
return env ?? { ...process.env, PASEO_HOME: paseoHome };
|
||||
}
|
||||
@@ -71,7 +70,7 @@ function authStateForApiKey(
|
||||
if (value.startsWith("!")) {
|
||||
return { kind: "api_key", configured: true, source: "command" };
|
||||
}
|
||||
const referencedVars = Array.from(value.matchAll(ENV_REFERENCE_PATTERN), (match) => match[1]);
|
||||
const referencedVars = findEnvReferences(value);
|
||||
if (referencedVars.length > 0) {
|
||||
return {
|
||||
kind: "api_key",
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
resolveRefreshTokenExpression,
|
||||
} from "./oauth-credentials.js";
|
||||
import type { PaseoAgentInferenceProvider, PaseoAgentModelReference } from "./pi-services.js";
|
||||
import { findEnvReferences } from "./env-references.js";
|
||||
|
||||
export const PASEO_AGENT_PROVIDER = "paseo";
|
||||
|
||||
@@ -212,8 +213,6 @@ function resolveProviderSettings(
|
||||
};
|
||||
}
|
||||
|
||||
const ENV_REFERENCE_PATTERN = /\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?/g;
|
||||
|
||||
/**
|
||||
* Whether a resolved API-key value is actually configured. Mirrors Pi's config-value
|
||||
* semantics without importing Pi: literals and `!command` values count as present;
|
||||
@@ -226,7 +225,7 @@ function isAuthConfigured(value: string | undefined, env: NodeJS.ProcessEnv): bo
|
||||
if (value.startsWith("!")) {
|
||||
return true;
|
||||
}
|
||||
const referencedVars = Array.from(value.matchAll(ENV_REFERENCE_PATTERN), (match) => match[1]);
|
||||
const referencedVars = findEnvReferences(value);
|
||||
if (referencedVars.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
const ENV_REFERENCE_PATTERN = /\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?/g;
|
||||
const ENV_REFERENCE_DETECT = /\$\{?[A-Za-z_][A-Za-z0-9_]*\}?/;
|
||||
|
||||
export function findEnvReferences(value: string): string[] {
|
||||
return Array.from(value.matchAll(ENV_REFERENCE_PATTERN), (match) => match[1]);
|
||||
}
|
||||
|
||||
export function hasEnvReference(value: string): boolean {
|
||||
return ENV_REFERENCE_DETECT.test(value);
|
||||
}
|
||||
|
||||
export function substituteEnvReferences(value: string, env: NodeJS.ProcessEnv): string | undefined {
|
||||
let missing = false;
|
||||
const result = value.replace(ENV_REFERENCE_PATTERN, (_match, name: string) => {
|
||||
const resolved = env[name];
|
||||
if (resolved === undefined) {
|
||||
missing = true;
|
||||
return "";
|
||||
}
|
||||
return resolved;
|
||||
});
|
||||
return missing ? undefined : result;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { execSync } from "node:child_process";
|
||||
import { hasEnvReference, substituteEnvReferences } from "./env-references.js";
|
||||
|
||||
// Resolution of a *self-supplied* OAuth refresh token expression — a literal, an env
|
||||
// reference (`$VAR` / `${VAR}`), or a `!command` that prints the token. This is an
|
||||
@@ -9,23 +10,6 @@ import { execSync } from "node:child_process";
|
||||
// This module deliberately does NOT read any other tool's auth files (Codex CLI,
|
||||
// OpenCode, Pi, etc.) and imports no Pi runtime code. Token values are never logged.
|
||||
|
||||
const ENV_REFERENCE_PATTERN = /\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?/g;
|
||||
const ENV_REFERENCE_DETECT = /\$\{?[A-Za-z_][A-Za-z0-9_]*\}?/;
|
||||
|
||||
/** Substitute `$VAR` / `${VAR}` references. Returns undefined if any var is unset. */
|
||||
function substituteEnv(value: string, env: NodeJS.ProcessEnv): string | undefined {
|
||||
let missing = false;
|
||||
const result = value.replace(ENV_REFERENCE_PATTERN, (_match, name: string) => {
|
||||
const resolved = env[name];
|
||||
if (resolved === undefined) {
|
||||
missing = true;
|
||||
return "";
|
||||
}
|
||||
return resolved;
|
||||
});
|
||||
return missing ? undefined : result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a refresh-token expression to its literal value (may run a `!command`).
|
||||
* Returns undefined when it can't be resolved.
|
||||
@@ -46,8 +30,8 @@ export function resolveRefreshTokenExpression(
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
if (ENV_REFERENCE_DETECT.test(value)) {
|
||||
const substituted = substituteEnv(value, env);
|
||||
if (hasEnvReference(value)) {
|
||||
const substituted = substituteEnvReferences(value, env);
|
||||
return substituted && substituted.length > 0 ? substituted : undefined;
|
||||
}
|
||||
return value.length > 0 ? value : undefined;
|
||||
@@ -64,8 +48,8 @@ export function isRefreshTokenExpressionConfigured(
|
||||
if (value.startsWith("!")) {
|
||||
return true;
|
||||
}
|
||||
if (ENV_REFERENCE_DETECT.test(value)) {
|
||||
return substituteEnv(value, env) !== undefined;
|
||||
if (hasEnvReference(value)) {
|
||||
return substituteEnvReferences(value, env) !== undefined;
|
||||
}
|
||||
return value.length > 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user