Plugins: generate bundled auth env metadata

This commit is contained in:
Vincent Koc 2026-03-18 10:53:48 -07:00
parent 8d73bc77fa
commit 7d08070dd7
7 changed files with 269 additions and 343 deletions

View File

@ -94,6 +94,10 @@
"types": "./dist/plugin-sdk/reply-runtime.d.ts",
"default": "./dist/plugin-sdk/reply-runtime.js"
},
"./plugin-sdk/reply-payload": {
"types": "./dist/plugin-sdk/reply-payload.d.ts",
"default": "./dist/plugin-sdk/reply-payload.js"
},
"./plugin-sdk/channel-runtime": {
"types": "./dist/plugin-sdk/channel-runtime.d.ts",
"default": "./dist/plugin-sdk/channel-runtime.js"
@ -394,6 +398,10 @@
"types": "./dist/plugin-sdk/channel-policy.d.ts",
"default": "./dist/plugin-sdk/channel-policy.js"
},
"./plugin-sdk/channel-send-result": {
"types": "./dist/plugin-sdk/channel-send-result.d.ts",
"default": "./dist/plugin-sdk/channel-send-result.js"
},
"./plugin-sdk/group-access": {
"types": "./dist/plugin-sdk/group-access.d.ts",
"default": "./dist/plugin-sdk/group-access.js"
@ -519,7 +527,8 @@
"build:plugin-sdk:dts": "tsc -p tsconfig.plugin-sdk.dts.json",
"build:strict-smoke": "pnpm canvas:a2ui:bundle && node scripts/tsdown-build.mjs && node scripts/runtime-postbuild.mjs && pnpm build:plugin-sdk:dts",
"canvas:a2ui:bundle": "bash scripts/bundle-a2ui.sh",
"check": "pnpm check:host-env-policy:swift && pnpm format:check && pnpm tsgo && pnpm plugin-sdk:check-exports && pnpm lint && pnpm lint:tmp:no-random-messaging && pnpm lint:tmp:channel-agnostic-boundaries && pnpm lint:tmp:no-raw-channel-fetch && pnpm lint:agent:ingress-owner && pnpm lint:plugins:no-register-http-handler && pnpm lint:plugins:no-monolithic-plugin-sdk-entry-imports && pnpm lint:plugins:no-extension-src-imports && pnpm lint:plugins:no-extension-test-core-imports && pnpm lint:plugins:no-extension-imports && pnpm lint:extensions:no-src-outside-plugin-sdk && pnpm lint:extensions:no-plugin-sdk-internal && pnpm lint:web-search-provider-boundaries && pnpm lint:webhook:no-low-level-body-read && pnpm lint:auth:no-pairing-store-group && pnpm lint:auth:pairing-account-scope",
"check": "pnpm check:host-env-policy:swift && pnpm check:bundled-provider-auth-env-vars && pnpm format:check && pnpm tsgo && pnpm plugin-sdk:check-exports && pnpm lint && pnpm lint:tmp:no-random-messaging && pnpm lint:tmp:channel-agnostic-boundaries && pnpm lint:tmp:no-raw-channel-fetch && pnpm lint:agent:ingress-owner && pnpm lint:plugins:no-register-http-handler && pnpm lint:plugins:no-monolithic-plugin-sdk-entry-imports && pnpm lint:plugins:no-extension-src-imports && pnpm lint:plugins:no-extension-test-core-imports && pnpm lint:plugins:no-extension-imports && pnpm lint:extensions:no-src-outside-plugin-sdk && pnpm lint:extensions:no-plugin-sdk-internal && pnpm lint:web-search-provider-boundaries && pnpm lint:webhook:no-low-level-body-read && pnpm lint:auth:no-pairing-store-group && pnpm lint:auth:pairing-account-scope",
"check:bundled-provider-auth-env-vars": "node scripts/generate-bundled-provider-auth-env-vars.mjs --check",
"check:docs": "pnpm format:docs:check && pnpm lint:docs && pnpm docs:check-i18n-glossary && pnpm docs:check-links",
"check:host-env-policy:swift": "node scripts/generate-host-env-security-policy-swift.mjs --check",
"check:loc": "node --import tsx scripts/check-ts-max-loc.ts --max 500",

View File

@ -0,0 +1,17 @@
export function collectBundledProviderAuthEnvVars(params?: {
repoRoot?: string;
}): Record<string, readonly string[]>;
export function renderBundledProviderAuthEnvVarModule(
entries: Record<string, readonly string[]>,
): string;
export function writeBundledProviderAuthEnvVarModule(params?: {
repoRoot?: string;
outputPath?: string;
check?: boolean;
}): {
changed: boolean;
wrote: boolean;
outputPath: string;
};

View File

@ -0,0 +1,131 @@
import fs from "node:fs";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { writeTextFileIfChanged } from "./runtime-postbuild-shared.mjs";
const GENERATED_BY = "scripts/generate-bundled-provider-auth-env-vars.mjs";
const DEFAULT_OUTPUT_PATH = "src/plugins/bundled-provider-auth-env-vars.generated.ts";
function readIfExists(filePath) {
try {
return fs.readFileSync(filePath, "utf8");
} catch {
return null;
}
}
function normalizeProviderAuthEnvVars(providerAuthEnvVars) {
if (
!providerAuthEnvVars ||
typeof providerAuthEnvVars !== "object" ||
Array.isArray(providerAuthEnvVars)
) {
return [];
}
return Object.entries(providerAuthEnvVars)
.map(([providerId, envVars]) => {
const normalizedProviderId = providerId.trim();
const normalizedEnvVars = Array.isArray(envVars)
? envVars.map((value) => String(value).trim()).filter(Boolean)
: [];
if (!normalizedProviderId || normalizedEnvVars.length === 0) {
return null;
}
return [normalizedProviderId, normalizedEnvVars];
})
.filter(Boolean)
.toSorted(([left], [right]) => left.localeCompare(right));
}
export function collectBundledProviderAuthEnvVars(params = {}) {
const repoRoot = path.resolve(params.repoRoot ?? process.cwd());
const extensionsRoot = path.join(repoRoot, "extensions");
if (!fs.existsSync(extensionsRoot)) {
return {};
}
const entries = new Map();
for (const dirent of fs.readdirSync(extensionsRoot, { withFileTypes: true })) {
if (!dirent.isDirectory()) {
continue;
}
const manifestPath = path.join(extensionsRoot, dirent.name, "openclaw.plugin.json");
if (!fs.existsSync(manifestPath)) {
continue;
}
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
for (const [providerId, envVars] of normalizeProviderAuthEnvVars(
manifest.providerAuthEnvVars,
)) {
entries.set(providerId, envVars);
}
}
return Object.fromEntries(
[...entries.entries()].toSorted(([left], [right]) => left.localeCompare(right)),
);
}
export function renderBundledProviderAuthEnvVarModule(entries) {
const renderedEntries = Object.entries(entries)
.map(([providerId, envVars]) => {
const renderedKey = /^[$A-Z_a-z][\w$]*$/u.test(providerId)
? providerId
: JSON.stringify(providerId);
const renderedEnvVars = envVars.map((value) => JSON.stringify(value)).join(", ");
return ` ${renderedKey}: [${renderedEnvVars}],`;
})
.join("\n");
return `// Auto-generated by ${GENERATED_BY}. Do not edit directly.
export const BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES = {
${renderedEntries}
} as const satisfies Record<string, readonly string[]>;
`;
}
export function writeBundledProviderAuthEnvVarModule(params = {}) {
const repoRoot = path.resolve(params.repoRoot ?? process.cwd());
const outputPath = path.resolve(repoRoot, params.outputPath ?? DEFAULT_OUTPUT_PATH);
const next = renderBundledProviderAuthEnvVarModule(
collectBundledProviderAuthEnvVars({ repoRoot }),
);
const current = readIfExists(outputPath);
const changed = current !== next;
if (params.check) {
return {
changed,
wrote: false,
outputPath,
};
}
return {
changed,
wrote: writeTextFileIfChanged(outputPath, next),
outputPath,
};
}
if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
const result = writeBundledProviderAuthEnvVarModule({
check: process.argv.includes("--check"),
});
if (result.changed) {
if (process.argv.includes("--check")) {
console.error(
`[bundled-provider-auth-env-vars] stale generated output at ${path.relative(process.cwd(), result.outputPath)}`,
);
process.exitCode = 1;
} else {
console.log(
`[bundled-provider-auth-env-vars] wrote ${path.relative(process.cwd(), result.outputPath)}`,
);
}
}
}

View File

@ -0,0 +1,38 @@
// Auto-generated by scripts/generate-bundled-provider-auth-env-vars.mjs. Do not edit directly.
export const BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES = {
anthropic: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"],
byteplus: ["BYTEPLUS_API_KEY"],
chutes: ["CHUTES_API_KEY", "CHUTES_OAUTH_TOKEN"],
"cloudflare-ai-gateway": ["CLOUDFLARE_AI_GATEWAY_API_KEY"],
fal: ["FAL_KEY"],
"github-copilot": ["COPILOT_GITHUB_TOKEN", "GH_TOKEN", "GITHUB_TOKEN"],
google: ["GEMINI_API_KEY", "GOOGLE_API_KEY"],
huggingface: ["HUGGINGFACE_HUB_TOKEN", "HF_TOKEN"],
kilocode: ["KILOCODE_API_KEY"],
kimi: ["KIMI_API_KEY", "KIMICODE_API_KEY"],
"kimi-coding": ["KIMI_API_KEY", "KIMICODE_API_KEY"],
minimax: ["MINIMAX_API_KEY"],
"minimax-portal": ["MINIMAX_OAUTH_TOKEN", "MINIMAX_API_KEY"],
mistral: ["MISTRAL_API_KEY"],
modelstudio: ["MODELSTUDIO_API_KEY"],
moonshot: ["MOONSHOT_API_KEY"],
nvidia: ["NVIDIA_API_KEY"],
ollama: ["OLLAMA_API_KEY"],
openai: ["OPENAI_API_KEY"],
opencode: ["OPENCODE_API_KEY", "OPENCODE_ZEN_API_KEY"],
"opencode-go": ["OPENCODE_API_KEY", "OPENCODE_ZEN_API_KEY"],
openrouter: ["OPENROUTER_API_KEY"],
qianfan: ["QIANFAN_API_KEY"],
"qwen-portal": ["QWEN_OAUTH_TOKEN", "QWEN_PORTAL_API_KEY"],
sglang: ["SGLANG_API_KEY"],
synthetic: ["SYNTHETIC_API_KEY"],
together: ["TOGETHER_API_KEY"],
venice: ["VENICE_API_KEY"],
"vercel-ai-gateway": ["AI_GATEWAY_API_KEY"],
vllm: ["VLLM_API_KEY"],
volcengine: ["VOLCANO_ENGINE_API_KEY"],
xai: ["XAI_API_KEY"],
xiaomi: ["XIAOMI_API_KEY"],
zai: ["ZAI_API_KEY", "Z_AI_API_KEY"],
} as const satisfies Record<string, readonly string[]>;

View File

@ -1,7 +1,35 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
import { afterEach } from "vitest";
import {
collectBundledProviderAuthEnvVars,
writeBundledProviderAuthEnvVarModule,
} from "../../scripts/generate-bundled-provider-auth-env-vars.mjs";
import { BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES } from "./bundled-provider-auth-env-vars.js";
const repoRoot = path.resolve(import.meta.dirname, "../..");
const tempDirs: string[] = [];
function writeJson(filePath: string, value: unknown): void {
fs.mkdirSync(path.dirname(filePath), { recursive: true });
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
}
afterEach(() => {
for (const dir of tempDirs.splice(0, tempDirs.length)) {
fs.rmSync(dir, { recursive: true, force: true });
}
});
describe("bundled provider auth env vars", () => {
it("matches the generated manifest snapshot", () => {
expect(BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES).toEqual(
collectBundledProviderAuthEnvVars({ repoRoot }),
);
});
it("reads bundled provider auth env vars from plugin manifests", () => {
expect(BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES["github-copilot"]).toEqual([
"COPILOT_GITHUB_TOKEN",
@ -17,6 +45,47 @@ describe("bundled provider auth env vars", () => {
"MINIMAX_API_KEY",
]);
expect(BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES.openai).toEqual(["OPENAI_API_KEY"]);
expect(BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES["openai-codex"]).toBeUndefined();
expect(BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES.fal).toEqual(["FAL_KEY"]);
expect("openai-codex" in BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES).toBe(false);
});
it("supports check mode for stale generated artifacts", () => {
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-provider-auth-env-vars-"));
tempDirs.push(tempRoot);
writeJson(path.join(tempRoot, "extensions", "alpha", "openclaw.plugin.json"), {
id: "alpha",
providerAuthEnvVars: {
alpha: ["ALPHA_TOKEN"],
},
});
const initial = writeBundledProviderAuthEnvVarModule({
repoRoot: tempRoot,
outputPath: "src/plugins/bundled-provider-auth-env-vars.generated.ts",
});
expect(initial.wrote).toBe(true);
const current = writeBundledProviderAuthEnvVarModule({
repoRoot: tempRoot,
outputPath: "src/plugins/bundled-provider-auth-env-vars.generated.ts",
check: true,
});
expect(current.changed).toBe(false);
expect(current.wrote).toBe(false);
fs.writeFileSync(
path.join(tempRoot, "src/plugins/bundled-provider-auth-env-vars.generated.ts"),
"// stale\n",
"utf8",
);
const stale = writeBundledProviderAuthEnvVarModule({
repoRoot: tempRoot,
outputPath: "src/plugins/bundled-provider-auth-env-vars.generated.ts",
check: true,
});
expect(stale.changed).toBe(true);
expect(stale.wrote).toBe(false);
});
});

View File

@ -1,93 +1,3 @@
import ANTHROPIC_MANIFEST from "../../extensions/anthropic/openclaw.plugin.json" with { type: "json" };
import BYTEPLUS_MANIFEST from "../../extensions/byteplus/openclaw.plugin.json" with { type: "json" };
import CLOUDFLARE_AI_GATEWAY_MANIFEST from "../../extensions/cloudflare-ai-gateway/openclaw.plugin.json" with { type: "json" };
import COPILOT_PROXY_MANIFEST from "../../extensions/copilot-proxy/openclaw.plugin.json" with { type: "json" };
import GITHUB_COPILOT_MANIFEST from "../../extensions/github-copilot/openclaw.plugin.json" with { type: "json" };
import GOOGLE_MANIFEST from "../../extensions/google/openclaw.plugin.json" with { type: "json" };
import HUGGINGFACE_MANIFEST from "../../extensions/huggingface/openclaw.plugin.json" with { type: "json" };
import KILOCODE_MANIFEST from "../../extensions/kilocode/openclaw.plugin.json" with { type: "json" };
import KIMI_CODING_MANIFEST from "../../extensions/kimi-coding/openclaw.plugin.json" with { type: "json" };
import MINIMAX_MANIFEST from "../../extensions/minimax/openclaw.plugin.json" with { type: "json" };
import MISTRAL_MANIFEST from "../../extensions/mistral/openclaw.plugin.json" with { type: "json" };
import MODELSTUDIO_MANIFEST from "../../extensions/modelstudio/openclaw.plugin.json" with { type: "json" };
import MOONSHOT_MANIFEST from "../../extensions/moonshot/openclaw.plugin.json" with { type: "json" };
import NVIDIA_MANIFEST from "../../extensions/nvidia/openclaw.plugin.json" with { type: "json" };
import OLLAMA_MANIFEST from "../../extensions/ollama/openclaw.plugin.json" with { type: "json" };
import OPENAI_MANIFEST from "../../extensions/openai/openclaw.plugin.json" with { type: "json" };
import OPENCODE_GO_MANIFEST from "../../extensions/opencode-go/openclaw.plugin.json" with { type: "json" };
import OPENCODE_MANIFEST from "../../extensions/opencode/openclaw.plugin.json" with { type: "json" };
import OPENROUTER_MANIFEST from "../../extensions/openrouter/openclaw.plugin.json" with { type: "json" };
import QIANFAN_MANIFEST from "../../extensions/qianfan/openclaw.plugin.json" with { type: "json" };
import QWEN_PORTAL_AUTH_MANIFEST from "../../extensions/qwen-portal-auth/openclaw.plugin.json" with { type: "json" };
import SGLANG_MANIFEST from "../../extensions/sglang/openclaw.plugin.json" with { type: "json" };
import SYNTHETIC_MANIFEST from "../../extensions/synthetic/openclaw.plugin.json" with { type: "json" };
import TOGETHER_MANIFEST from "../../extensions/together/openclaw.plugin.json" with { type: "json" };
import VENICE_MANIFEST from "../../extensions/venice/openclaw.plugin.json" with { type: "json" };
import VERCEL_AI_GATEWAY_MANIFEST from "../../extensions/vercel-ai-gateway/openclaw.plugin.json" with { type: "json" };
import VLLM_MANIFEST from "../../extensions/vllm/openclaw.plugin.json" with { type: "json" };
import VOLCENGINE_MANIFEST from "../../extensions/volcengine/openclaw.plugin.json" with { type: "json" };
import XAI_MANIFEST from "../../extensions/xai/openclaw.plugin.json" with { type: "json" };
import XIAOMI_MANIFEST from "../../extensions/xiaomi/openclaw.plugin.json" with { type: "json" };
import ZAI_MANIFEST from "../../extensions/zai/openclaw.plugin.json" with { type: "json" };
type ProviderAuthEnvVarManifest = {
id?: string;
providerAuthEnvVars?: Record<string, string[]>;
};
function collectBundledProviderAuthEnvVars(
manifests: readonly ProviderAuthEnvVarManifest[],
): Record<string, readonly string[]> {
const entries: Record<string, readonly string[]> = {};
for (const manifest of manifests) {
const providerAuthEnvVars = manifest.providerAuthEnvVars;
if (!providerAuthEnvVars) {
continue;
}
for (const [providerId, envVars] of Object.entries(providerAuthEnvVars)) {
const normalizedProviderId = providerId.trim();
const normalizedEnvVars = envVars.map((value) => value.trim()).filter(Boolean);
if (!normalizedProviderId || normalizedEnvVars.length === 0) {
continue;
}
entries[normalizedProviderId] = normalizedEnvVars;
}
}
return entries;
}
// Read bundled provider auth env metadata from manifests so env-based auth
// lookup stays cheap and does not need to boot plugin runtime code.
export const BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES = collectBundledProviderAuthEnvVars([
ANTHROPIC_MANIFEST,
BYTEPLUS_MANIFEST,
CLOUDFLARE_AI_GATEWAY_MANIFEST,
COPILOT_PROXY_MANIFEST,
GITHUB_COPILOT_MANIFEST,
GOOGLE_MANIFEST,
HUGGINGFACE_MANIFEST,
KILOCODE_MANIFEST,
KIMI_CODING_MANIFEST,
MINIMAX_MANIFEST,
MISTRAL_MANIFEST,
MODELSTUDIO_MANIFEST,
MOONSHOT_MANIFEST,
NVIDIA_MANIFEST,
OLLAMA_MANIFEST,
OPENAI_MANIFEST,
OPENCODE_GO_MANIFEST,
OPENCODE_MANIFEST,
OPENROUTER_MANIFEST,
QIANFAN_MANIFEST,
QWEN_PORTAL_AUTH_MANIFEST,
SGLANG_MANIFEST,
SYNTHETIC_MANIFEST,
TOGETHER_MANIFEST,
VENICE_MANIFEST,
VERCEL_AI_GATEWAY_MANIFEST,
VLLM_MANIFEST,
VOLCENGINE_MANIFEST,
XAI_MANIFEST,
XIAOMI_MANIFEST,
ZAI_MANIFEST,
]);
// Generated from extension manifests so core secrets/auth code does not need
// static imports into extension source trees.
export { BUNDLED_PROVIDER_AUTH_ENV_VAR_CANDIDATES } from "./bundled-provider-auth-env-vars.generated.js";

View File

@ -1,252 +1,4 @@
[
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 1,
"kind": "import",
"specifier": "../../extensions/anthropic/openclaw.plugin.json",
"resolvedPath": "extensions/anthropic/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 2,
"kind": "import",
"specifier": "../../extensions/byteplus/openclaw.plugin.json",
"resolvedPath": "extensions/byteplus/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 3,
"kind": "import",
"specifier": "../../extensions/cloudflare-ai-gateway/openclaw.plugin.json",
"resolvedPath": "extensions/cloudflare-ai-gateway/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 4,
"kind": "import",
"specifier": "../../extensions/copilot-proxy/openclaw.plugin.json",
"resolvedPath": "extensions/copilot-proxy/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 5,
"kind": "import",
"specifier": "../../extensions/github-copilot/openclaw.plugin.json",
"resolvedPath": "extensions/github-copilot/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 6,
"kind": "import",
"specifier": "../../extensions/google/openclaw.plugin.json",
"resolvedPath": "extensions/google/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 7,
"kind": "import",
"specifier": "../../extensions/huggingface/openclaw.plugin.json",
"resolvedPath": "extensions/huggingface/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 8,
"kind": "import",
"specifier": "../../extensions/kilocode/openclaw.plugin.json",
"resolvedPath": "extensions/kilocode/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 9,
"kind": "import",
"specifier": "../../extensions/kimi-coding/openclaw.plugin.json",
"resolvedPath": "extensions/kimi-coding/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 10,
"kind": "import",
"specifier": "../../extensions/minimax/openclaw.plugin.json",
"resolvedPath": "extensions/minimax/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 11,
"kind": "import",
"specifier": "../../extensions/mistral/openclaw.plugin.json",
"resolvedPath": "extensions/mistral/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 12,
"kind": "import",
"specifier": "../../extensions/modelstudio/openclaw.plugin.json",
"resolvedPath": "extensions/modelstudio/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 13,
"kind": "import",
"specifier": "../../extensions/moonshot/openclaw.plugin.json",
"resolvedPath": "extensions/moonshot/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 14,
"kind": "import",
"specifier": "../../extensions/nvidia/openclaw.plugin.json",
"resolvedPath": "extensions/nvidia/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 15,
"kind": "import",
"specifier": "../../extensions/ollama/openclaw.plugin.json",
"resolvedPath": "extensions/ollama/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 16,
"kind": "import",
"specifier": "../../extensions/openai/openclaw.plugin.json",
"resolvedPath": "extensions/openai/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 17,
"kind": "import",
"specifier": "../../extensions/opencode-go/openclaw.plugin.json",
"resolvedPath": "extensions/opencode-go/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 18,
"kind": "import",
"specifier": "../../extensions/opencode/openclaw.plugin.json",
"resolvedPath": "extensions/opencode/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 19,
"kind": "import",
"specifier": "../../extensions/openrouter/openclaw.plugin.json",
"resolvedPath": "extensions/openrouter/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 20,
"kind": "import",
"specifier": "../../extensions/qianfan/openclaw.plugin.json",
"resolvedPath": "extensions/qianfan/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 21,
"kind": "import",
"specifier": "../../extensions/qwen-portal-auth/openclaw.plugin.json",
"resolvedPath": "extensions/qwen-portal-auth/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 22,
"kind": "import",
"specifier": "../../extensions/sglang/openclaw.plugin.json",
"resolvedPath": "extensions/sglang/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 23,
"kind": "import",
"specifier": "../../extensions/synthetic/openclaw.plugin.json",
"resolvedPath": "extensions/synthetic/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 24,
"kind": "import",
"specifier": "../../extensions/together/openclaw.plugin.json",
"resolvedPath": "extensions/together/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 25,
"kind": "import",
"specifier": "../../extensions/venice/openclaw.plugin.json",
"resolvedPath": "extensions/venice/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 26,
"kind": "import",
"specifier": "../../extensions/vercel-ai-gateway/openclaw.plugin.json",
"resolvedPath": "extensions/vercel-ai-gateway/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 27,
"kind": "import",
"specifier": "../../extensions/vllm/openclaw.plugin.json",
"resolvedPath": "extensions/vllm/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 28,
"kind": "import",
"specifier": "../../extensions/volcengine/openclaw.plugin.json",
"resolvedPath": "extensions/volcengine/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 29,
"kind": "import",
"specifier": "../../extensions/xai/openclaw.plugin.json",
"resolvedPath": "extensions/xai/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 30,
"kind": "import",
"specifier": "../../extensions/xiaomi/openclaw.plugin.json",
"resolvedPath": "extensions/xiaomi/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/bundled-provider-auth-env-vars.ts",
"line": 31,
"kind": "import",
"specifier": "../../extensions/zai/openclaw.plugin.json",
"resolvedPath": "extensions/zai/openclaw.plugin.json",
"reason": "imports extension-owned file from src/plugins"
},
{
"file": "src/plugins/provider-model-definitions.ts",
"line": 1,