refactor(protocol,cli,agent): replace apiKeyEnv with apiKey (#528)
Breaking change: Store API keys directly in config.yaml instead of environment variable names. ## Changes ### @uncaged/workflow-protocol - Change ProviderConfig.apiKeyEnv: string → apiKey: string - Update README to reflect new type ### @uncaged/workflow-util-agent - extract.ts: Remove dotenv loading, use providerEntry.apiKey directly - storage.ts: Update normalizeProviders to validate apiKey field - Update error messages to reference apiKey instead of apiKeyEnv ### @uncaged/cli-workflow - setup.ts: Write actual API key to config.yaml, not .env - Remove apiKeyEnvName(), loadEnvFile(), saveEnvFile() functions - Remove getEnvPath() function - Update cmdSetup to not return envPath in result - Update README to reflect config.yaml stores API keys - Fix setup-validate.test.ts to not expect envPath in result ## Verification - ✅ bun run build passes - ✅ All tests pass (260/260 in cli-workflow, 55/55 in util-agent) - ✅ bun run check passes (only pre-existing warnings) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { getSchema, validate } from "@uncaged/json-cas";
|
||||
|
||||
import type { CasRef, ModelAlias, WorkflowConfig } from "@uncaged/workflow-protocol";
|
||||
import { config as loadDotenv } from "dotenv";
|
||||
import { createAgentStore, getEnvPath, resolveStorageRoot } from "./storage.js";
|
||||
import { createAgentStore, resolveStorageRoot } from "./storage.js";
|
||||
|
||||
export type ResolvedLlmProvider = {
|
||||
baseUrl: string;
|
||||
@@ -38,9 +37,9 @@ export function resolveModel(config: WorkflowConfig, alias: ModelAlias): Resolve
|
||||
if (providerEntry === undefined) {
|
||||
throw new Error(`unknown provider "${modelEntry.provider}" for model "${alias}"`);
|
||||
}
|
||||
const apiKey = process.env[providerEntry.apiKeyEnv];
|
||||
const apiKey = providerEntry.apiKey;
|
||||
if (apiKey === undefined || apiKey === "") {
|
||||
throw new Error(`missing API key env var: ${providerEntry.apiKeyEnv}`);
|
||||
throw new Error(`missing API key for provider: ${modelEntry.provider}`);
|
||||
}
|
||||
return {
|
||||
baseUrl: providerEntry.baseUrl,
|
||||
@@ -130,7 +129,7 @@ export type ExtractResult = {
|
||||
|
||||
/**
|
||||
* Call an OpenAI-compatible LLM to extract structured output matching outputSchema.
|
||||
* Loads config.yaml and .env from the workflow storage root.
|
||||
* Loads config.yaml from the workflow storage root.
|
||||
*/
|
||||
export async function extract(
|
||||
rawOutput: string,
|
||||
@@ -138,7 +137,6 @@ export async function extract(
|
||||
config: WorkflowConfig,
|
||||
): Promise<ExtractResult> {
|
||||
const storageRoot = resolveStorageRoot();
|
||||
loadDotenv({ path: getEnvPath(storageRoot) });
|
||||
|
||||
const { store } = await createAgentStore(storageRoot);
|
||||
const schema = getSchema(store, outputSchema);
|
||||
|
||||
@@ -84,11 +84,11 @@ function normalizeProviders(raw: unknown): Record<ProviderAlias, ProviderConfig>
|
||||
throw new Error(`config.providers.${name} must be a mapping`);
|
||||
}
|
||||
const baseUrl = entry.baseUrl;
|
||||
const apiKeyEnv = entry.apiKeyEnv;
|
||||
if (typeof baseUrl !== "string" || typeof apiKeyEnv !== "string") {
|
||||
throw new Error(`config.providers.${name} requires baseUrl and apiKeyEnv`);
|
||||
const apiKey = entry.apiKey;
|
||||
if (typeof baseUrl !== "string" || typeof apiKey !== "string") {
|
||||
throw new Error(`config.providers.${name} requires baseUrl and apiKey`);
|
||||
}
|
||||
providers[name] = { baseUrl, apiKeyEnv };
|
||||
providers[name] = { baseUrl, apiKey };
|
||||
}
|
||||
return providers;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user