mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 04:50:44 +00:00
refactor: remove legacy agent dir resolver
This commit is contained in:
@@ -80,6 +80,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Providers/Fireworks: expose Kimi models as thinking-off-only and keep K2.5/K2.6 requests on `thinking: disabled`, so manual model switches do not send Fireworks-rejected `reasoning*` parameters. Refs #74289. Thanks @frankekn.
|
||||
- WhatsApp responsiveness: stop only verified stale local TUI clients when they degrade the Gateway event loop and delay replies. Thanks @vincentkoc.
|
||||
- Hooks/session-memory: add collision suffixes to fallback memory filenames so repeated `/new` or `/reset` captures in the same minute do not overwrite the earlier session archive. Thanks @vincentkoc.
|
||||
- Agents/config: remove the ambiguous legacy `main` agent dir helper from runtime paths; model, auth, gateway, bundled plugin, and test helpers now resolve default/session agent dirs through `agents.list`/agent-scope helpers while plugin SDK keeps a deprecated compatibility export.
|
||||
- Video generation: wait up to 20 minutes for slow fal/MiniMax queue-backed jobs, stop forwarding unsupported Google Veo generated-audio options, and normalize MiniMax `720P` requests to its supported `768P` resolution with the usual override warning/details instead of failing fallback.
|
||||
- Video generation: accept provider-specific aspect-ratio and resolution hints at the tool boundary, normalize `720P` to MiniMax's supported `768P`, and stop sending Google `generateAudio` on Gemini video requests so provider fallback can recover from model-specific parameter differences. Thanks @vincentkoc.
|
||||
- OpenAI/Google Meet: fail realtime voice connection attempts when the socket closes before `session.updated`, avoiding stuck Meet joins waiting on a bridge that never became ready. Thanks @vincentkoc.
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
43c6f668cd8301f485c64e6a663dc1b19d38c146ce2572943e2dc961973e0c6f plugin-sdk-api-baseline.json
|
||||
1d877d94bebb634d90d929fe0581ba4bccf4d12d8342d179ae9bf1053e68c013 plugin-sdk-api-baseline.jsonl
|
||||
2164ea491c61e643f0a9c68f7b9bd2e41ab338eb93bbdf301da2fae548722581 plugin-sdk-api-baseline.json
|
||||
c07c3719218a12482e2a76e6b9654da2ddddf75d8d70145cdaef3da2b2eaccef plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -117,7 +117,7 @@ For the plugin authoring guide, see [Plugin SDK overview](/plugins/sdk-overview)
|
||||
| `plugin-sdk/provider-auth-result` | Standard OAuth auth-result builder |
|
||||
| `plugin-sdk/provider-auth-login` | Shared interactive login helpers for provider plugins |
|
||||
| `plugin-sdk/provider-env-vars` | Provider auth env-var lookup helpers |
|
||||
| `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials` |
|
||||
| `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials`, deprecated `resolveOpenClawAgentDir` compatibility export |
|
||||
| `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`, shared replay-policy builders, provider-endpoint helpers, and model-id normalization helpers such as `normalizeNativeXaiModelId` |
|
||||
| `plugin-sdk/provider-catalog-runtime` | Provider catalog augmentation runtime hook and plugin-provider registry seams for contract tests |
|
||||
| `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `buildManifestModelProviderConfig`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` |
|
||||
@@ -253,7 +253,7 @@ For the plugin authoring guide, see [Plugin SDK overview](/plugins/sdk-overview)
|
||||
| `plugin-sdk/string-coerce-runtime` | Narrow primitive record/string coercion and normalization helpers without markdown/logging imports |
|
||||
| `plugin-sdk/host-runtime` | Hostname and SCP host normalization helpers |
|
||||
| `plugin-sdk/retry-runtime` | Retry config and retry runner helpers |
|
||||
| `plugin-sdk/agent-runtime` | Agent dir/identity/workspace helpers |
|
||||
| `plugin-sdk/agent-runtime` | Agent dir/identity/workspace helpers, including `resolveAgentDir`, `resolveDefaultAgentDir`, and deprecated `resolveOpenClawAgentDir` compatibility export |
|
||||
| `plugin-sdk/directory-runtime` | Config-backed directory query/dedup |
|
||||
| `plugin-sdk/keyed-async-queue` | `KeyedAsyncQueue` |
|
||||
</Accordion>
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
resolveAuthProfileOrder,
|
||||
resolveProviderIdForAuth,
|
||||
resolveApiKeyForProfile,
|
||||
resolveOpenClawAgentDir,
|
||||
resolveDefaultAgentDir,
|
||||
resolvePersistedAuthProfileOwnerAgentDir,
|
||||
saveAuthProfileStore,
|
||||
type AuthProfileCredential,
|
||||
@@ -82,7 +82,7 @@ export function resolveCodexAppServerAuthProfileIdForAgent(params: {
|
||||
agentDir?: string;
|
||||
config?: AuthProfileOrderConfig;
|
||||
}): string | undefined {
|
||||
const agentDir = params.agentDir?.trim() || resolveOpenClawAgentDir();
|
||||
const agentDir = params.agentDir?.trim() || resolveDefaultAgentDir(params.config ?? {});
|
||||
const store = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false });
|
||||
return resolveCodexAppServerAuthProfileId({
|
||||
authProfileId: params.authProfileId,
|
||||
|
||||
@@ -27,8 +27,8 @@ vi.mock("./managed-binary.js", () => ({
|
||||
resolveManagedCodexAppServerStartOptions: mocks.managedBinary.startOptions,
|
||||
}));
|
||||
|
||||
vi.mock("openclaw/plugin-sdk/provider-auth", () => ({
|
||||
resolveOpenClawAgentDir: mocks.providerAuth.agentDir,
|
||||
vi.mock("openclaw/plugin-sdk/agent-runtime", () => ({
|
||||
resolveDefaultAgentDir: mocks.providerAuth.agentDir,
|
||||
}));
|
||||
|
||||
let listCodexAppServerModels: typeof import("./models.js").listCodexAppServerModels;
|
||||
|
||||
@@ -16,9 +16,9 @@ import {
|
||||
isSubagentSessionKey,
|
||||
normalizeAgentRuntimeTools,
|
||||
resolveAttemptSpawnWorkspaceDir,
|
||||
resolveAgentDir,
|
||||
resolveAgentHarnessBeforePromptBuildResult,
|
||||
resolveModelAuthMode,
|
||||
resolveOpenClawAgentDir,
|
||||
resolveSandboxContext,
|
||||
resolveSessionAgentIds,
|
||||
resolveUserPath,
|
||||
@@ -385,7 +385,7 @@ export async function runCodexAppServerAttempt(
|
||||
config: params.config,
|
||||
agentId: params.agentId,
|
||||
});
|
||||
const agentDir = params.agentDir ?? resolveOpenClawAgentDir();
|
||||
const agentDir = params.agentDir ?? resolveAgentDir(params.config ?? {}, sessionAgentId);
|
||||
const startupBinding = await readCodexAppServerBinding(params.sessionFile);
|
||||
const startupAuthProfileCandidate =
|
||||
params.runtimePlan?.auth.forwardedAuthProfileId ??
|
||||
@@ -1477,7 +1477,7 @@ async function buildDynamicTools(input: DynamicToolBuildParams) {
|
||||
return [];
|
||||
}
|
||||
const modelHasVision = params.model.input?.includes("image") ?? false;
|
||||
const agentDir = params.agentDir ?? resolveOpenClawAgentDir();
|
||||
const agentDir = params.agentDir ?? resolveAgentDir(params.config ?? {}, input.sessionAgentId);
|
||||
const { createOpenClawCodingTools } = await import("openclaw/plugin-sdk/agent-harness");
|
||||
const allTools = createOpenClawCodingTools({
|
||||
agentId: input.sessionAgentId,
|
||||
|
||||
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
|
||||
import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import {
|
||||
ensureAuthProfileStore,
|
||||
resolveOpenClawAgentDir,
|
||||
resolveDefaultAgentDir,
|
||||
resolveProviderIdForAuth,
|
||||
type AuthProfileStore,
|
||||
} from "openclaw/plugin-sdk/agent-runtime";
|
||||
@@ -194,12 +194,16 @@ function resolveCodexAppServerAuthProfileCredential(
|
||||
if (!authProfileId) {
|
||||
return undefined;
|
||||
}
|
||||
const store = lookup.authProfileStore ?? loadCodexAppServerAuthProfileStore(lookup.agentDir);
|
||||
const store =
|
||||
lookup.authProfileStore ?? loadCodexAppServerAuthProfileStore(lookup.agentDir, lookup.config);
|
||||
return store.profiles[authProfileId];
|
||||
}
|
||||
|
||||
function loadCodexAppServerAuthProfileStore(agentDir: string | undefined): AuthProfileStore {
|
||||
return ensureAuthProfileStore(agentDir?.trim() || resolveOpenClawAgentDir(), {
|
||||
function loadCodexAppServerAuthProfileStore(
|
||||
agentDir: string | undefined,
|
||||
config?: ProviderAuthAliasConfig,
|
||||
): AuthProfileStore {
|
||||
return ensureAuthProfileStore(agentDir?.trim() || resolveDefaultAgentDir(config ?? {}), {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ const mocks = vi.hoisted(() => ({
|
||||
),
|
||||
resolveManagedCodexAppServerStartOptions: vi.fn(async (startOptions) => startOptions),
|
||||
embeddedAgentLog: { debug: vi.fn(), warn: vi.fn() },
|
||||
resolveOpenClawAgentDir: vi.fn(() => "/tmp/openclaw-agent"),
|
||||
resolveDefaultAgentDir: vi.fn(() => "/tmp/openclaw-agent"),
|
||||
}));
|
||||
|
||||
vi.mock("./auth-bridge.js", () => ({
|
||||
@@ -29,8 +29,8 @@ vi.mock("openclaw/plugin-sdk/agent-harness-runtime", () => ({
|
||||
OPENCLAW_VERSION: "test",
|
||||
}));
|
||||
|
||||
vi.mock("openclaw/plugin-sdk/provider-auth", () => ({
|
||||
resolveOpenClawAgentDir: mocks.resolveOpenClawAgentDir,
|
||||
vi.mock("openclaw/plugin-sdk/agent-runtime", () => ({
|
||||
resolveDefaultAgentDir: mocks.resolveDefaultAgentDir,
|
||||
}));
|
||||
|
||||
let listCodexAppServerModels: typeof import("./models.js").listCodexAppServerModels;
|
||||
@@ -81,7 +81,7 @@ describe("shared Codex app-server client", () => {
|
||||
);
|
||||
mocks.embeddedAgentLog.debug.mockClear();
|
||||
mocks.embeddedAgentLog.warn.mockClear();
|
||||
mocks.resolveOpenClawAgentDir.mockClear();
|
||||
mocks.resolveDefaultAgentDir.mockClear();
|
||||
});
|
||||
|
||||
it("closes the shared app-server when the version gate fails", async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { resolveOpenClawAgentDir } from "openclaw/plugin-sdk/provider-auth";
|
||||
import { resolveDefaultAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import {
|
||||
applyCodexAppServerAuthProfile,
|
||||
bridgeCodexAppServerStartOptions,
|
||||
@@ -37,7 +37,7 @@ export async function getSharedCodexAppServerClient(options?: {
|
||||
config?: Parameters<typeof resolveCodexAppServerAuthProfileIdForAgent>[0]["config"];
|
||||
}): Promise<CodexAppServerClient> {
|
||||
const state = getSharedCodexAppServerClientState();
|
||||
const agentDir = options?.agentDir ?? resolveOpenClawAgentDir();
|
||||
const agentDir = options?.agentDir ?? resolveDefaultAgentDir(options?.config ?? {});
|
||||
const authProfileId = resolveCodexAppServerAuthProfileIdForAgent({
|
||||
authProfileId: options?.authProfileId,
|
||||
agentDir,
|
||||
@@ -104,7 +104,7 @@ export async function createIsolatedCodexAppServerClient(options?: {
|
||||
agentDir?: string;
|
||||
config?: Parameters<typeof resolveCodexAppServerAuthProfileIdForAgent>[0]["config"];
|
||||
}): Promise<CodexAppServerClient> {
|
||||
const agentDir = options?.agentDir ?? resolveOpenClawAgentDir();
|
||||
const agentDir = options?.agentDir ?? resolveDefaultAgentDir(options?.config ?? {});
|
||||
const authProfileId = resolveCodexAppServerAuthProfileIdForAgent({
|
||||
authProfileId: options?.authProfileId,
|
||||
agentDir,
|
||||
|
||||
@@ -12,7 +12,7 @@ const agentRuntimeMocks = vi.hoisted(() => ({
|
||||
loadAuthProfileStoreForSecretsRuntime: vi.fn(),
|
||||
resolveApiKeyForProfile: vi.fn(),
|
||||
resolveAuthProfileOrder: vi.fn(),
|
||||
resolveOpenClawAgentDir: vi.fn(() => "/agent"),
|
||||
resolveDefaultAgentDir: vi.fn(() => "/agent"),
|
||||
resolvePersistedAuthProfileOwnerAgentDir: vi.fn(),
|
||||
resolveProviderIdForAuth: vi.fn((provider: string) => provider),
|
||||
saveAuthProfileStore: vi.fn(),
|
||||
@@ -40,7 +40,7 @@ describe("codex conversation binding", () => {
|
||||
agentRuntimeMocks.loadAuthProfileStoreForSecretsRuntime.mockReset();
|
||||
agentRuntimeMocks.resolveApiKeyForProfile.mockReset();
|
||||
agentRuntimeMocks.resolveAuthProfileOrder.mockReset();
|
||||
agentRuntimeMocks.resolveOpenClawAgentDir.mockClear();
|
||||
agentRuntimeMocks.resolveDefaultAgentDir.mockClear();
|
||||
agentRuntimeMocks.resolvePersistedAuthProfileOwnerAgentDir.mockReset();
|
||||
agentRuntimeMocks.resolveProviderIdForAuth.mockClear();
|
||||
agentRuntimeMocks.saveAuthProfileStore.mockReset();
|
||||
@@ -53,7 +53,7 @@ describe("codex conversation binding", () => {
|
||||
profiles: {},
|
||||
});
|
||||
agentRuntimeMocks.resolveAuthProfileOrder.mockReturnValue([]);
|
||||
agentRuntimeMocks.resolveOpenClawAgentDir.mockReturnValue("/agent");
|
||||
agentRuntimeMocks.resolveDefaultAgentDir.mockReturnValue("/agent");
|
||||
agentRuntimeMocks.resolveProviderIdForAuth.mockImplementation((provider: string) => provider);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { resolveOpenClawAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import { resolveDefaultAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";
|
||||
import { createTestPluginApi } from "openclaw/plugin-sdk/plugin-test-api";
|
||||
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
||||
@@ -42,7 +42,7 @@ describeLive("comfy live", () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
cfg = withPluginsEnabled(getRuntimeConfig());
|
||||
agentDir = resolveOpenClawAgentDir();
|
||||
agentDir = resolveDefaultAgentDir(cfg as never);
|
||||
plugin.register(
|
||||
createTestPluginApi({
|
||||
config: cfg as never,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
resolveApiKeyForProvider,
|
||||
resolveOpenClawAgentDir,
|
||||
resolveDefaultAgentDir,
|
||||
} from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";
|
||||
import {
|
||||
@@ -159,7 +159,7 @@ describeLive("music generation provider live", () => {
|
||||
async () => {
|
||||
const cfg = withPluginsEnabled(getRuntimeConfig());
|
||||
const configuredModels = resolveConfiguredLiveMusicModels(cfg);
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg as never);
|
||||
const attempted: string[] = [];
|
||||
const skipped: string[] = [];
|
||||
const failures: string[] = [];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
resolveApiKeyForProvider,
|
||||
resolveOpenClawAgentDir,
|
||||
resolveDefaultAgentDir,
|
||||
} from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";
|
||||
import {
|
||||
@@ -361,7 +361,7 @@ function resolveLiveSmokeDurationSeconds(params: {
|
||||
async function runLiveVideoProviderCase(testCase: LiveProviderCase): Promise<void> {
|
||||
const cfg = withPluginsEnabled(getRuntimeConfig());
|
||||
const configuredModels = resolveConfiguredLiveVideoModels(cfg);
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg as never);
|
||||
const attempted: string[] = [];
|
||||
const skipped: string[] = [];
|
||||
const failures: string[] = [];
|
||||
|
||||
@@ -12,7 +12,7 @@ import http from "node:http";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import process from "node:process";
|
||||
import { resolveOpenClawAgentDir } from "../src/agents/agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../src/agents/agent-scope.js";
|
||||
import { ensureAuthProfileStore, type AuthProfileCredential } from "../src/agents/auth-profiles.js";
|
||||
import { normalizeProviderId } from "../src/agents/model-selection.js";
|
||||
import { validateAnthropicSetupToken } from "../src/commands/auth-token.js";
|
||||
@@ -185,7 +185,7 @@ function resolveSetupTokenSource(): TokenSource {
|
||||
};
|
||||
}
|
||||
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir({});
|
||||
const store = ensureAuthProfileStore(agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
|
||||
@@ -189,3 +189,10 @@ export function resolveAgentDir(
|
||||
const root = resolveStateDir(env);
|
||||
return path.join(root, "agents", id, "agent");
|
||||
}
|
||||
|
||||
export function resolveDefaultAgentDir(
|
||||
cfg: OpenClawConfig,
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
): string {
|
||||
return resolveAgentDir(cfg, resolveDefaultAgentId(cfg), env);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
hasConfiguredModelFallbacks,
|
||||
resolveAgentConfig,
|
||||
resolveDefaultAgentDir,
|
||||
resolveAgentDir,
|
||||
resolveAgentEffectiveModelPrimary,
|
||||
resolveAgentExplicitModelPrimary,
|
||||
@@ -595,6 +596,20 @@ describe("resolveAgentConfig", () => {
|
||||
expect(agentDir).toBe(path.join(path.resolve(home), ".openclaw", "agents", "main", "agent"));
|
||||
});
|
||||
|
||||
it("resolves default agentDir from the configured default agent", () => {
|
||||
const stateDir = path.join(path.sep, "tmp", "test-state");
|
||||
vi.stubEnv("OPENCLAW_STATE_DIR", stateDir);
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [{ id: "main" }, { id: "ops", default: true }],
|
||||
},
|
||||
};
|
||||
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
|
||||
expect(agentDir).toBe(path.join(stateDir, "agents", "ops", "agent"));
|
||||
});
|
||||
|
||||
it("non-default agent uses agents.defaults.workspace as base (#59789)", () => {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
resolveAgentConfig,
|
||||
resolveAgentContextLimits,
|
||||
resolveAgentDir,
|
||||
resolveDefaultAgentDir,
|
||||
resolveAgentWorkspaceDir,
|
||||
resolveDefaultAgentId,
|
||||
type ResolvedAgentConfig,
|
||||
@@ -34,6 +35,7 @@ export {
|
||||
resolveAgentConfig,
|
||||
resolveAgentContextLimits,
|
||||
resolveAgentDir,
|
||||
resolveDefaultAgentDir,
|
||||
resolveAgentWorkspaceDir,
|
||||
resolveDefaultAgentId,
|
||||
type ResolvedAgentConfig,
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
validateAnthropicSetupToken,
|
||||
} from "../commands/auth-token.js";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import {
|
||||
type AuthProfileCredential,
|
||||
ensureAuthProfileStore,
|
||||
@@ -95,7 +95,7 @@ async function resolveTokenSource(): Promise<TokenSource> {
|
||||
};
|
||||
}
|
||||
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(getRuntimeConfig());
|
||||
const store = ensureAuthProfileStore(agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@ describe("resolveApiKeyForProfile fallback to main agent", () => {
|
||||
await fs.mkdir(mainAgentDir, { recursive: true });
|
||||
await fs.mkdir(secondaryAgentDir, { recursive: true });
|
||||
|
||||
// Set environment variables so resolveOpenClawAgentDir() returns mainAgentDir
|
||||
// Set environment variables so the default agent dir resolves under tmpDir.
|
||||
process.env.OPENCLAW_STATE_DIR = tmpDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = mainAgentDir;
|
||||
process.env.PI_CODING_AGENT_DIR = mainAgentDir;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createHash } from "node:crypto";
|
||||
import path from "node:path";
|
||||
import { resolveStateDir } from "../../config/paths.js";
|
||||
import { resolveUserPath } from "../../utils.js";
|
||||
import { resolveOpenClawAgentDir } from "../agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../agent-scope-config.js";
|
||||
import {
|
||||
AUTH_PROFILE_FILENAME,
|
||||
AUTH_STATE_FILENAME,
|
||||
@@ -10,17 +10,17 @@ import {
|
||||
} from "./path-constants.js";
|
||||
|
||||
export function resolveAuthStorePath(agentDir?: string): string {
|
||||
const resolved = resolveUserPath(agentDir ?? resolveOpenClawAgentDir());
|
||||
const resolved = resolveUserPath(agentDir ?? resolveDefaultAgentDir({}));
|
||||
return path.join(resolved, AUTH_PROFILE_FILENAME);
|
||||
}
|
||||
|
||||
export function resolveLegacyAuthStorePath(agentDir?: string): string {
|
||||
const resolved = resolveUserPath(agentDir ?? resolveOpenClawAgentDir());
|
||||
const resolved = resolveUserPath(agentDir ?? resolveDefaultAgentDir({}));
|
||||
return path.join(resolved, LEGACY_AUTH_FILENAME);
|
||||
}
|
||||
|
||||
export function resolveAuthStatePath(agentDir?: string): string {
|
||||
const resolved = resolveUserPath(agentDir ?? resolveOpenClawAgentDir());
|
||||
const resolved = resolveUserPath(agentDir ?? resolveDefaultAgentDir({}));
|
||||
return path.join(resolved, AUTH_STATE_FILENAME);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,10 +41,9 @@ describe("path-resolve helpers (direct-import coverage attribution)", () => {
|
||||
expect(path.basename(resolved)).toMatch(/auth-profiles/);
|
||||
});
|
||||
|
||||
it("resolveAuthStorePath falls back to resolveOpenClawAgentDir when agentDir is omitted", () => {
|
||||
// Omitting agentDir exercises the `agentDir ?? resolveOpenClawAgentDir()`
|
||||
// nullish branch. With OPENCLAW_STATE_DIR set to our tempdir, the
|
||||
// resolved path must live under it.
|
||||
it("resolveAuthStorePath falls back to the default agent dir when agentDir is omitted", () => {
|
||||
// Omitting agentDir exercises the default agent-dir branch. With
|
||||
// OPENCLAW_STATE_DIR set to our tempdir, the resolved path must live under it.
|
||||
const resolved = resolveAuthStorePath();
|
||||
expect(resolved.startsWith(stateDir)).toBe(true);
|
||||
expect(path.basename(resolved)).toMatch(/auth-profiles/);
|
||||
|
||||
@@ -12,8 +12,7 @@ import type {
|
||||
import { buildAgentHookContextChannelFields } from "../../plugins/hook-agent-context.js";
|
||||
import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js";
|
||||
import { annotateInterSessionPromptText } from "../../sessions/input-provenance.js";
|
||||
import { resolveOpenClawAgentDir } from "../agent-paths.js";
|
||||
import { resolveSessionAgentIds } from "../agent-scope.js";
|
||||
import { resolveAgentDir, resolveSessionAgentIds } from "../agent-scope.js";
|
||||
import { externalCliDiscoveryForProviderAuth } from "../auth-profiles/external-cli-discovery.js";
|
||||
import { loadAuthProfileStoreForRuntime } from "../auth-profiles/store.js";
|
||||
import type { AuthProfileCredential } from "../auth-profiles/types.js";
|
||||
@@ -119,7 +118,12 @@ export async function prepareCliRunContext(
|
||||
`CLI backend ${backendResolved.id} cannot run with tools disabled because it exposes native tools`,
|
||||
);
|
||||
}
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const { defaultAgentId, sessionAgentId } = resolveSessionAgentIds({
|
||||
sessionKey: params.sessionKey,
|
||||
config: params.config,
|
||||
agentId: params.agentId,
|
||||
});
|
||||
const agentDir = resolveAgentDir(params.config ?? {}, sessionAgentId);
|
||||
const requestedAuthProfileId = params.authProfileId?.trim() || undefined;
|
||||
const effectiveAuthProfileId =
|
||||
requestedAuthProfileId ?? backendResolved.defaultAuthProfileId?.trim() ?? undefined;
|
||||
@@ -175,11 +179,6 @@ export async function prepareCliRunContext(
|
||||
seenSignatures: params.bootstrapPromptWarningSignaturesSeen,
|
||||
previousSignature: params.bootstrapPromptWarningSignature,
|
||||
});
|
||||
const { defaultAgentId, sessionAgentId } = resolveSessionAgentIds({
|
||||
sessionKey: params.sessionKey,
|
||||
config: params.config,
|
||||
agentId: params.agentId,
|
||||
});
|
||||
const bundleMcpEnabled = backendResolved.bundleMcp && params.disableTools !== true;
|
||||
let mcpLoopbackRuntime = bundleMcpEnabled ? prepareDeps.getActiveMcpLoopbackRuntime() : undefined;
|
||||
if (bundleMcpEnabled && !mcpLoopbackRuntime) {
|
||||
|
||||
@@ -29,10 +29,6 @@ vi.mock("./models-config.runtime.js", () => ({
|
||||
ensureOpenClawModelsJson: contextTestState.ensureOpenClawModelsJson,
|
||||
}));
|
||||
|
||||
vi.mock("./agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: () => "/tmp/openclaw-agent",
|
||||
}));
|
||||
|
||||
vi.mock("./pi-model-discovery-runtime.js", () => ({
|
||||
discoverAuthStorage: contextTestState.discoverAuthStorage,
|
||||
discoverModels: contextTestState.discoverModels,
|
||||
@@ -301,7 +297,7 @@ describe("lookupContextTokens", () => {
|
||||
|
||||
expect(contextTestState.discoverModels).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
"/tmp/openclaw-agent",
|
||||
expect.stringMatching(/\/\.openclaw\/agents\/main\/agent$/),
|
||||
{ normalizeModels: false },
|
||||
);
|
||||
expect(lookupContextTokens("anthropic/claude-opus-4.7-20260219")).toBe(1_048_576);
|
||||
|
||||
@@ -8,7 +8,7 @@ import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { computeBackoff, type BackoffPolicy } from "../infra/backoff.js";
|
||||
import { consumeRootOptionToken, FLAG_TERMINATOR } from "../infra/cli-root-options.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import { lookupCachedContextTokens, MODEL_CONTEXT_TOKEN_CACHE } from "./context-cache.js";
|
||||
import { CONTEXT_WINDOW_RUNTIME_STATE } from "./context-runtime-state.js";
|
||||
import { normalizeProviderId } from "./model-selection.js";
|
||||
@@ -240,7 +240,7 @@ function ensureContextWindowCacheLoaded(): Promise<void> {
|
||||
try {
|
||||
const { discoverAuthStorage, discoverModels } =
|
||||
await import("./pi-model-discovery-runtime.js");
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, agentDir, {
|
||||
normalizeModels: false,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { completeSimple, type Api, type AssistantMessage, type Model } from "@mariozechner/pi-ai";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import { collectProviderApiKeys } from "./live-auth-keys.js";
|
||||
import { isLiveTestEnabled } from "./live-test-helpers.js";
|
||||
import { getApiKeyForModel, requireApiKey } from "./model-auth.js";
|
||||
@@ -163,7 +163,7 @@ export async function resolveLiveDirectModel(params: {
|
||||
}): Promise<LiveResolvedModel> {
|
||||
const cfg = getRuntimeConfig();
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const models = discoverModels(authStorage, agentDir).getAll();
|
||||
|
||||
|
||||
@@ -92,8 +92,8 @@ describe("loadModelCatalog", () => {
|
||||
vi.doMock("./models-config.js", () => ({
|
||||
ensureOpenClawModelsJson: ensureOpenClawModelsJsonMock,
|
||||
}));
|
||||
vi.doMock("./agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: () => "/tmp/openclaw",
|
||||
vi.doMock("./agent-scope.js", () => ({
|
||||
resolveDefaultAgentDir: () => "/tmp/openclaw",
|
||||
}));
|
||||
vi.doMock("../plugins/provider-runtime.runtime.js", () => ({
|
||||
augmentModelCatalogWithProviderPlugins: vi.fn().mockResolvedValue([]),
|
||||
@@ -143,7 +143,7 @@ describe("loadModelCatalog", () => {
|
||||
afterAll(() => {
|
||||
vi.doUnmock("node:fs/promises");
|
||||
vi.doUnmock("./models-config.js");
|
||||
vi.doUnmock("./agent-paths.js");
|
||||
vi.doUnmock("./agent-scope.js");
|
||||
vi.doUnmock("../plugins/provider-runtime.runtime.js");
|
||||
vi.doUnmock("../plugins/current-plugin-metadata-snapshot.js");
|
||||
vi.doUnmock("../plugins/plugin-metadata-snapshot.js");
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
normalizeOptionalString,
|
||||
} from "../shared/string-coerce.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import { modelSupportsInput as modelCatalogEntrySupportsInput } from "./model-catalog-lookup.js";
|
||||
import type { ModelCatalogEntry, ModelInputType } from "./model-catalog.types.js";
|
||||
import { buildConfiguredModelCatalog } from "./model-selection-shared.js";
|
||||
@@ -224,7 +224,7 @@ async function loadReadOnlyPersistedModelCatalog(params?: {
|
||||
config?: OpenClawConfig;
|
||||
}): Promise<ModelCatalogEntry[]> {
|
||||
const cfg = params?.config ?? getRuntimeConfig();
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const raw = await readFile(join(agentDir, "models.json"), "utf8");
|
||||
const parsed = JSON.parse(raw) as Record<string, unknown>;
|
||||
const models: ModelCatalogEntry[] = [];
|
||||
@@ -333,7 +333,7 @@ export async function loadModelCatalog(params?: {
|
||||
// will keep failing until restart).
|
||||
const piSdk = await importPiSdk();
|
||||
logStage("pi-sdk-imported");
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const { buildShouldSuppressBuiltInModel } = await loadModelSuppression();
|
||||
logStage("catalog-deps-ready");
|
||||
const authStorage = piSdk.discoverAuthStorage(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import {
|
||||
CUSTOM_PROXY_MODELS_CONFIG,
|
||||
installModelsConfigTestHooks,
|
||||
@@ -107,7 +107,7 @@ async function runEnvProviderCase(params: {
|
||||
try {
|
||||
await ensureOpenClawModelsJson({});
|
||||
|
||||
const modelPath = path.join(resolveOpenClawAgentDir(), "models.json");
|
||||
const modelPath = path.join(resolveDefaultAgentDir({}), "models.json");
|
||||
const raw = await fs.readFile(modelPath, "utf8");
|
||||
const parsed = JSON.parse(raw) as { providers: Record<string, ParsedProviderConfig> };
|
||||
const provider = parsed.providers[params.providerKey];
|
||||
@@ -177,7 +177,7 @@ describe("models-config", () => {
|
||||
await withTempHome(async () => {
|
||||
await ensureOpenClawModelsJson(CUSTOM_PROXY_MODELS_CONFIG);
|
||||
|
||||
const modelPath = path.join(resolveOpenClawAgentDir(), "models.json");
|
||||
const modelPath = path.join(resolveDefaultAgentDir({}), "models.json");
|
||||
const raw = await fs.readFile(modelPath, "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
providers: Record<
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
|
||||
export async function readGeneratedModelsJson<T>(agentDir = resolveOpenClawAgentDir()): Promise<T> {
|
||||
export async function readGeneratedModelsJson<T>(
|
||||
agentDir = resolveDefaultAgentDir({}),
|
||||
): Promise<T> {
|
||||
const modelPath = path.join(agentDir, "models.json");
|
||||
const raw = await fs.readFile(modelPath, "utf8");
|
||||
return JSON.parse(raw) as T;
|
||||
|
||||
@@ -10,8 +10,11 @@ import { createConfigRuntimeEnv } from "../config/env-vars.js";
|
||||
import { getCurrentPluginMetadataSnapshot } from "../plugins/current-plugin-metadata-snapshot.js";
|
||||
import { resolveInstalledManifestRegistryIndexFingerprint } from "../plugins/manifest-registry-installed.js";
|
||||
import type { PluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "./agent-scope.js";
|
||||
import {
|
||||
resolveAgentWorkspaceDir,
|
||||
resolveDefaultAgentDir,
|
||||
resolveDefaultAgentId,
|
||||
} from "./agent-scope.js";
|
||||
import { MODELS_JSON_STATE } from "./models-config-state.js";
|
||||
import { planOpenClawModelsJson } from "./models-config.plan.js";
|
||||
|
||||
@@ -180,7 +183,7 @@ export async function ensureOpenClawModelsJson(
|
||||
config: cfg,
|
||||
...(workspaceDir ? { workspaceDir } : {}),
|
||||
});
|
||||
const agentDir = agentDirOverride?.trim() ? agentDirOverride.trim() : resolveOpenClawAgentDir();
|
||||
const agentDir = agentDirOverride?.trim() ? agentDirOverride.trim() : resolveDefaultAgentDir(cfg);
|
||||
const targetPath = path.join(agentDir, "models.json");
|
||||
const fingerprint = await buildModelsJsonFingerprint({
|
||||
config: cfg,
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from "node:path";
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { resolveInstalledPluginIndexPolicyHash } from "../plugins/installed-plugin-index-policy.js";
|
||||
import type { PluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import {
|
||||
CUSTOM_PROXY_MODELS_CONFIG,
|
||||
installModelsConfigTestHooks,
|
||||
@@ -114,6 +114,24 @@ describe("models-config write serialization", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("writes implicit models.json into the configured default agent dir", async () => {
|
||||
await withModelsTempHome(async (home) => {
|
||||
const cfg = {
|
||||
agents: {
|
||||
list: [{ id: "main" }, { id: "ops", default: true }],
|
||||
},
|
||||
};
|
||||
|
||||
const result = await ensureOpenClawModelsJson(cfg);
|
||||
|
||||
expect(result.agentDir).toBe(path.join(home, ".openclaw", "agents", "ops", "agent"));
|
||||
await expect(fs.access(path.join(result.agentDir, "models.json"))).resolves.toBeUndefined();
|
||||
await expect(
|
||||
fs.access(path.join(home, ".openclaw", "agents", "main", "agent", "models.json")),
|
||||
).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
it("does not reuse scoped startup discovery cache for a different provider scope", async () => {
|
||||
await withModelsTempHome(async (home) => {
|
||||
planOpenClawModelsJsonMock.mockImplementation(async () => ({ action: "skip" }));
|
||||
@@ -151,7 +169,7 @@ describe("models-config write serialization", () => {
|
||||
await ensureOpenClawModelsJson(CUSTOM_PROXY_MODELS_CONFIG);
|
||||
await ensureOpenClawModelsJson(CUSTOM_PROXY_MODELS_CONFIG);
|
||||
|
||||
const modelPath = path.join(resolveOpenClawAgentDir(), "models.json");
|
||||
const modelPath = path.join(resolveDefaultAgentDir({}), "models.json");
|
||||
await fs.writeFile(modelPath, `${JSON.stringify({ external: true })}\n`, "utf8");
|
||||
const externalMtime = new Date(Date.now() + 2000);
|
||||
await fs.utimes(modelPath, externalMtime, externalMtime);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { describe, expect, it } from "vitest";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { parseLiveCsvFilter } from "../media-generation/live-test-helpers.js";
|
||||
import { runTasksWithConcurrency } from "../utils/run-with-concurrency.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import { externalCliDiscoveryForProviders } from "./auth-profiles/external-cli-discovery.js";
|
||||
import {
|
||||
collectAnthropicApiKeys,
|
||||
@@ -733,7 +733,7 @@ describeLive("live models (profile keys)", () => {
|
||||
|
||||
const providers = parseProviderFilter(process.env.OPENCLAW_LIVE_PROVIDERS);
|
||||
const providerList = providers ? [...providers] : null;
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir, {
|
||||
config: cfg,
|
||||
env: process.env,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { Type } from "typebox";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import { isLiveProfileKeyModeEnabled, isLiveTestEnabled } from "./live-test-helpers.js";
|
||||
import { getApiKeyForModel, requireApiKey } from "./model-auth.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
@@ -127,7 +127,7 @@ describeLive("openai reasoning compat live", () => {
|
||||
const cfg = getRuntimeConfig();
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, agentDir);
|
||||
const model = modelRegistry.find(provider, modelId) as Model<Api> | null;
|
||||
@@ -181,7 +181,7 @@ describeLive("openai reasoning compat live", () => {
|
||||
const cfg = getRuntimeConfig();
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, agentDir);
|
||||
const model = modelRegistry.find(provider, modelId) as Model<Api> | null;
|
||||
|
||||
@@ -499,13 +499,11 @@ export async function loadCompactHooksHarness(): Promise<{
|
||||
resolveSkillsPromptForRun: vi.fn(() => undefined),
|
||||
}));
|
||||
|
||||
vi.doMock("../agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: vi.fn(() => "/tmp"),
|
||||
}));
|
||||
|
||||
vi.doMock("../agent-scope.js", () => ({
|
||||
listAgentEntries: vi.fn(() => []),
|
||||
resolveAgentConfig: vi.fn(() => undefined),
|
||||
resolveAgentDir: vi.fn((_cfg: unknown, agentId: string) => `/tmp/agents/${agentId}/agent`),
|
||||
resolveDefaultAgentDir: vi.fn(() => "/tmp/agents/main/agent"),
|
||||
resolveDefaultAgentId: vi.fn(() => "main"),
|
||||
resolveRunModelFallbacksOverride: vi.fn(() => undefined),
|
||||
resolveSessionAgentId: resolveSessionAgentIdMock,
|
||||
|
||||
@@ -14,8 +14,7 @@ import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js";
|
||||
import type { ProviderRuntimeModel } from "../../plugins/provider-runtime-model.types.js";
|
||||
import { enqueueCommandInLane } from "../../process/command-queue.js";
|
||||
import { resolveUserPath } from "../../utils.js";
|
||||
import { resolveOpenClawAgentDir } from "../agent-paths.js";
|
||||
import { resolveSessionAgentIds } from "../agent-scope.js";
|
||||
import { resolveAgentDir, resolveSessionAgentIds } from "../agent-scope.js";
|
||||
import { resolveContextWindowInfo } from "../context-window-guard.js";
|
||||
import { DEFAULT_CONTEXT_TOKENS, DEFAULT_MODEL, DEFAULT_PROVIDER } from "../defaults.js";
|
||||
import { maybeCompactAgentHarnessSession } from "../harness/selection.js";
|
||||
@@ -51,7 +50,11 @@ export async function compactEmbeddedPiSession(
|
||||
allowGatewaySubagentBinding: params.allowGatewaySubagentBinding,
|
||||
});
|
||||
ensureContextEnginesInitialized();
|
||||
const agentDir = params.agentDir ?? resolveOpenClawAgentDir();
|
||||
const agentIds = resolveSessionAgentIds({
|
||||
sessionKey: params.sessionKey,
|
||||
config: params.config,
|
||||
});
|
||||
const agentDir = params.agentDir ?? resolveAgentDir(params.config ?? {}, agentIds.sessionAgentId);
|
||||
const resolvedWorkspaceDir = resolveUserPath(params.workspaceDir);
|
||||
const contextEngine = await resolveContextEngine(params.config, {
|
||||
agentDir,
|
||||
|
||||
@@ -34,8 +34,11 @@ import { buildTtsSystemPromptHint } from "../../tts/tts.js";
|
||||
import { resolveUserPath } from "../../utils.js";
|
||||
import { normalizeMessageChannel } from "../../utils/message-channel.js";
|
||||
import { isReasoningTagProvider } from "../../utils/provider-utils.js";
|
||||
import { resolveOpenClawAgentDir } from "../agent-paths.js";
|
||||
import { resolveRunModelFallbacksOverride, resolveSessionAgentIds } from "../agent-scope.js";
|
||||
import {
|
||||
resolveAgentDir,
|
||||
resolveRunModelFallbacksOverride,
|
||||
resolveSessionAgentIds,
|
||||
} from "../agent-scope.js";
|
||||
import {
|
||||
makeBootstrapWarn,
|
||||
resolveBootstrapContextForRun,
|
||||
@@ -481,7 +484,12 @@ async function compactEmbeddedPiSessionDirectOnce(
|
||||
: undefined,
|
||||
};
|
||||
};
|
||||
const agentDir = params.agentDir ?? resolveOpenClawAgentDir();
|
||||
const earlyAgentIds = resolveSessionAgentIds({
|
||||
sessionKey: params.sessionKey,
|
||||
config: params.config,
|
||||
});
|
||||
const agentDir =
|
||||
params.agentDir ?? resolveAgentDir(params.config ?? {}, earlyAgentIds.sessionAgentId);
|
||||
await ensureOpenClawModelsJson(params.config, agentDir, {
|
||||
workspaceDir: resolvedWorkspace,
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
normalizeProviderResolvedModelWithPlugin,
|
||||
shouldPreferProviderRuntimeResolvedModel,
|
||||
} from "../../plugins/provider-runtime.js";
|
||||
import { resolveOpenClawAgentDir } from "../agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../agent-scope.js";
|
||||
import { DEFAULT_CONTEXT_TOKENS } from "../defaults.js";
|
||||
import { buildModelAliasLines } from "../model-alias-lines.js";
|
||||
import { modelKey, normalizeStaticProviderModelId } from "../model-ref-shared.js";
|
||||
@@ -989,7 +989,7 @@ export function resolveModel(
|
||||
provider,
|
||||
model: normalizeStaticProviderModelId(normalizeProviderId(provider), modelId),
|
||||
};
|
||||
const resolvedAgentDir = agentDir ?? resolveOpenClawAgentDir();
|
||||
const resolvedAgentDir = agentDir ?? resolveDefaultAgentDir(cfg ?? {});
|
||||
const authStorage = options?.authStorage ?? discoverAuthStorage(resolvedAgentDir);
|
||||
const modelRegistry = options?.modelRegistry ?? discoverModels(authStorage, resolvedAgentDir);
|
||||
const runtimeHooks = resolveRuntimeHooks(options);
|
||||
@@ -1041,7 +1041,7 @@ export async function resolveModelAsync(
|
||||
provider,
|
||||
model: normalizeStaticProviderModelId(normalizeProviderId(provider), modelId),
|
||||
};
|
||||
const resolvedAgentDir = agentDir ?? resolveOpenClawAgentDir();
|
||||
const resolvedAgentDir = agentDir ?? resolveDefaultAgentDir(cfg ?? {});
|
||||
const emptyDiscoveryStores =
|
||||
options?.skipPiDiscovery && (!options.authStorage || !options.modelRegistry)
|
||||
? createEmptyPiDiscoveryStores()
|
||||
|
||||
@@ -535,10 +535,6 @@ export async function loadRunOverflowCompactionHarness(): Promise<{
|
||||
isMarkdownCapableMessageChannel: vi.fn(() => true),
|
||||
}));
|
||||
|
||||
vi.doMock("../agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: vi.fn(() => "/tmp/agent-dir"),
|
||||
}));
|
||||
|
||||
vi.doMock("../defaults.js", () => ({
|
||||
DEFAULT_CONTEXT_TOKENS: 200000,
|
||||
DEFAULT_MODEL: "test-model",
|
||||
|
||||
@@ -205,7 +205,7 @@ describe("runEmbeddedPiAgent overflow compaction trigger routing", () => {
|
||||
|
||||
expect(mockedEnsureAuthProfileStore).not.toHaveBeenCalled();
|
||||
expect(mockedEnsureAuthProfileStoreWithoutExternalProfiles).toHaveBeenCalledWith(
|
||||
"/tmp/agent-dir",
|
||||
expect.stringMatching(/[/\\]\.openclaw[/\\]agents[/\\]main[/\\]agent$/),
|
||||
{ allowKeychainPrompt: false },
|
||||
);
|
||||
});
|
||||
|
||||
@@ -18,10 +18,10 @@ import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import { sanitizeForLog } from "../../terminal/ansi.js";
|
||||
import { resolveUserPath } from "../../utils.js";
|
||||
import { isMarkdownCapableMessageChannel } from "../../utils/message-channel.js";
|
||||
import { resolveOpenClawAgentDir } from "../agent-paths.js";
|
||||
import {
|
||||
hasConfiguredModelFallbacks,
|
||||
resolveAgentExecutionContract,
|
||||
resolveAgentDir,
|
||||
resolveSessionAgentIds,
|
||||
resolveAgentWorkspaceDir,
|
||||
} from "../agent-scope.js";
|
||||
@@ -429,7 +429,8 @@ export async function runEmbeddedPiAgent(
|
||||
|
||||
let provider = (params.provider ?? DEFAULT_PROVIDER).trim() || DEFAULT_PROVIDER;
|
||||
let modelId = (params.model ?? DEFAULT_MODEL).trim() || DEFAULT_MODEL;
|
||||
const agentDir = params.agentDir ?? resolveOpenClawAgentDir();
|
||||
const agentDir =
|
||||
params.agentDir ?? resolveAgentDir(params.config ?? {}, workspaceResolution.agentId);
|
||||
const normalizedSessionKey = params.sessionKey?.trim();
|
||||
const fallbackConfigured = hasConfiguredModelFallbacks({
|
||||
cfg: params.config,
|
||||
|
||||
@@ -50,8 +50,7 @@ import { buildTtsSystemPromptHint } from "../../../tts/tts.js";
|
||||
import { resolveUserPath } from "../../../utils.js";
|
||||
import { normalizeMessageChannel } from "../../../utils/message-channel.js";
|
||||
import { isReasoningTagProvider } from "../../../utils/provider-utils.js";
|
||||
import { resolveOpenClawAgentDir } from "../../agent-paths.js";
|
||||
import { resolveSessionAgentIds } from "../../agent-scope.js";
|
||||
import { resolveAgentDir, resolveSessionAgentIds } from "../../agent-scope.js";
|
||||
import { createAnthropicPayloadLogger } from "../../anthropic-payload-log.js";
|
||||
import {
|
||||
analyzeBootstrapBudget,
|
||||
@@ -749,7 +748,7 @@ export async function runEmbeddedAttempt(
|
||||
);
|
||||
}
|
||||
const activeContextEngine = isRawModelRun ? undefined : params.contextEngine;
|
||||
const agentDir = params.agentDir ?? resolveOpenClawAgentDir();
|
||||
const agentDir = params.agentDir ?? resolveAgentDir(params.config ?? {}, sessionAgentId);
|
||||
const diagnosticTrace = freezeDiagnosticTraceContext(
|
||||
createDiagnosticTraceContextFromActiveScope(),
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { Type } from "typebox";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getRuntimeConfig } from "../config/config.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "./agent-scope.js";
|
||||
import { isLiveProfileKeyModeEnabled, isLiveTestEnabled } from "./live-test-helpers.js";
|
||||
import { getApiKeyForModel, requireApiKey } from "./model-auth.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
@@ -189,7 +189,7 @@ describeLive("tool replay repair live", () => {
|
||||
const cfg = getRuntimeConfig();
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, agentDir);
|
||||
const model = modelRegistry.find(target.provider, target.modelId) as Model<Api> | null;
|
||||
@@ -304,7 +304,7 @@ describeLive("tool replay repair live", () => {
|
||||
const cfg = getRuntimeConfig();
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, agentDir);
|
||||
const model = modelRegistry.find(target.provider, target.modelId) as Model<Api> | null;
|
||||
|
||||
@@ -58,11 +58,6 @@ vi.mock("../agents/workspace.js", () => ({
|
||||
resolveDefaultAgentWorkspaceDir,
|
||||
}));
|
||||
|
||||
const resolveOpenClawAgentDir = vi.hoisted(() => vi.fn(() => "/tmp/agent"));
|
||||
vi.mock("../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir,
|
||||
}));
|
||||
|
||||
const applyAuthProfileConfig = vi.hoisted(() => vi.fn((config) => config));
|
||||
vi.mock("../plugins/provider-auth-helpers.js", () => ({
|
||||
applyAuthProfileConfig,
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
createAuthTestLifecycle,
|
||||
createExitThrowingRuntime,
|
||||
createWizardPrompter,
|
||||
requireOpenClawAgentDir,
|
||||
setupAuthTestEnv,
|
||||
} from "./test-wizard-helpers.js";
|
||||
|
||||
@@ -72,13 +71,10 @@ vi.mock("../plugins/provider-zai-endpoint.js", () => ({
|
||||
detectZaiEndpoint,
|
||||
}));
|
||||
|
||||
vi.mock("../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: () => process.env.OPENCLAW_AGENT_DIR ?? "/tmp/openclaw-agent",
|
||||
}));
|
||||
|
||||
vi.mock("../agents/agent-scope.js", () => ({
|
||||
resolveDefaultAgentId: () => "main",
|
||||
resolveAgentDir: (_config: unknown, agentId: string) => `/tmp/openclaw-agents/${agentId}`,
|
||||
resolveAgentDir: (_config: unknown, agentId: string) =>
|
||||
`${process.env.OPENCLAW_STATE_DIR ?? "/tmp/openclaw-state"}/agents/${agentId}/agent`,
|
||||
resolveAgentWorkspaceDir: (_config: unknown, agentId: string) =>
|
||||
`/tmp/openclaw-workspaces/${agentId}`,
|
||||
}));
|
||||
@@ -606,7 +602,7 @@ describe("applyAuthChoice", () => {
|
||||
};
|
||||
}
|
||||
async function readAuthProfiles() {
|
||||
return readTestAuthProfileStore(requireOpenClawAgentDir());
|
||||
return readTestAuthProfileStore(resolveAgentDir({} as OpenClawConfig, "main"));
|
||||
}
|
||||
async function readAuthProfilesForAgentDir(agentDir: string) {
|
||||
return readTestAuthProfileStore(agentDir);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
import { resolveAgentDir, listAgentIds } from "../agents/agent-scope.js";
|
||||
import { resolveAgentDir, resolveDefaultAgentDir, listAgentIds } from "../agents/agent-scope.js";
|
||||
import { AUTH_STORE_VERSION } from "../agents/auth-profiles/constants.js";
|
||||
import { resolveAuthStorePath } from "../agents/auth-profiles/paths.js";
|
||||
import {
|
||||
@@ -176,7 +175,7 @@ function listExistingAgentDirsFromState(): string[] {
|
||||
|
||||
function listAuthProfileRepairCandidates(cfg: OpenClawConfig): AuthProfileRepairCandidate[] {
|
||||
const candidates = new Map<string, AuthProfileRepairCandidate>();
|
||||
addCandidate(candidates, resolveOpenClawAgentDir());
|
||||
addCandidate(candidates, resolveDefaultAgentDir(cfg));
|
||||
for (const agentId of listAgentIds(cfg)) {
|
||||
addCandidate(candidates, resolveAgentDir(cfg, agentId));
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ const readConfigFileSnapshotForWrite = vi.fn().mockResolvedValue({
|
||||
writeOptions: {},
|
||||
});
|
||||
const setRuntimeConfigSnapshot = vi.fn();
|
||||
const resolveOpenClawAgentDir = vi.fn().mockReturnValue("/tmp/openclaw-agent");
|
||||
const ensureAuthProfileStore = vi.fn().mockReturnValue({ version: 1, profiles: {} });
|
||||
const listProfilesForProvider = vi.fn().mockReturnValue([]);
|
||||
const resolveEnvApiKey = vi.fn().mockReturnValue(undefined);
|
||||
@@ -55,10 +54,6 @@ vi.mock("./models/load-config.js", () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock("../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir,
|
||||
}));
|
||||
|
||||
vi.mock("../agents/auth-profiles/profile-list.js", () => ({
|
||||
listProfilesForProvider,
|
||||
}));
|
||||
@@ -512,8 +507,9 @@ describe("models list/status", () => {
|
||||
loadProviderCatalogModelsForList.mockResolvedValueOnce([MOONSHOT_MODEL]);
|
||||
const runtime = makeRuntime();
|
||||
|
||||
await withEnvAsync({ KIMI_API_KEY: undefined, MOONSHOT_API_KEY: undefined }, () =>
|
||||
modelsListCommand({ all: true, provider: "moonshot", json: true }, runtime),
|
||||
await withEnvAsync(
|
||||
{ KIMI_API_KEY: undefined, KIMICODE_API_KEY: undefined, MOONSHOT_API_KEY: undefined },
|
||||
() => modelsListCommand({ all: true, provider: "moonshot", json: true }, runtime),
|
||||
);
|
||||
|
||||
const payload = parseJsonLog(runtime);
|
||||
|
||||
@@ -45,7 +45,7 @@ const mocks = vi.hoisted(() => {
|
||||
loadModelsConfigWithSource: vi.fn(),
|
||||
ensureOpenClawModelsJson: vi.fn(),
|
||||
ensureAuthProfileStore: vi.fn(),
|
||||
resolveOpenClawAgentDir: vi.fn(),
|
||||
resolveDefaultAgentDir: vi.fn(),
|
||||
loadModelRegistry: vi.fn(),
|
||||
loadModelCatalog: vi.fn(),
|
||||
loadProviderCatalogModelsForList: vi.fn(),
|
||||
@@ -69,7 +69,7 @@ function resetMocks() {
|
||||
});
|
||||
mocks.ensureOpenClawModelsJson.mockResolvedValue({ wrote: false });
|
||||
mocks.ensureAuthProfileStore.mockReturnValue({ version: 1, profiles: {}, order: {} });
|
||||
mocks.resolveOpenClawAgentDir.mockReturnValue("/tmp/openclaw-agent");
|
||||
mocks.resolveDefaultAgentDir.mockReturnValue("/tmp/openclaw-agent");
|
||||
mocks.loadModelRegistry.mockResolvedValue({
|
||||
models: [],
|
||||
availableKeys: new Set(),
|
||||
@@ -201,8 +201,10 @@ function installModelsListCommandForwardCompatMocks() {
|
||||
loadAuthProfileStoreWithoutExternalProfiles: mocks.ensureAuthProfileStore,
|
||||
}));
|
||||
|
||||
vi.doMock("../../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: mocks.resolveOpenClawAgentDir,
|
||||
vi.doMock("../../agents/agent-scope.js", () => ({
|
||||
resolveAgentWorkspaceDir: vi.fn(() => "/tmp/openclaw-workspace"),
|
||||
resolveDefaultAgentDir: mocks.resolveDefaultAgentDir,
|
||||
resolveDefaultAgentId: vi.fn(() => "main"),
|
||||
}));
|
||||
|
||||
vi.doMock("../../agents/model-catalog.js", () => ({
|
||||
|
||||
@@ -71,12 +71,10 @@ export async function modelsListCommand(
|
||||
}
|
||||
const [
|
||||
{ loadAuthProfileStoreWithoutExternalProfiles },
|
||||
{ resolveOpenClawAgentDir },
|
||||
{ resolveAgentWorkspaceDir, resolveDefaultAgentId },
|
||||
{ resolveAgentWorkspaceDir, resolveDefaultAgentDir, resolveDefaultAgentId },
|
||||
{ resolveDefaultAgentWorkspaceDir },
|
||||
] = await Promise.all([
|
||||
import("../../agents/auth-profiles/store.js"),
|
||||
import("../../agents/agent-paths.js"),
|
||||
import("../../agents/agent-scope.js"),
|
||||
import("../../agents/workspace.js"),
|
||||
]);
|
||||
@@ -84,8 +82,8 @@ export async function modelsListCommand(
|
||||
commandName: "models list",
|
||||
runtime,
|
||||
});
|
||||
const authStore = loadAuthProfileStoreWithoutExternalProfiles();
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStore = loadAuthProfileStoreWithoutExternalProfiles(agentDir);
|
||||
const workspaceDir =
|
||||
resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg)) ?? resolveDefaultAgentWorkspaceDir();
|
||||
const authIndex = createModelListAuthIndex({ cfg, authStore, workspaceDir });
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import crypto from "node:crypto";
|
||||
import fs from "node:fs/promises";
|
||||
import { resolveOpenClawAgentDir } from "../../agents/agent-paths.js";
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
|
||||
import {
|
||||
resolveAgentDir,
|
||||
resolveAgentWorkspaceDir,
|
||||
resolveDefaultAgentId,
|
||||
} from "../../agents/agent-scope.js";
|
||||
import {
|
||||
type AuthProfileCredential,
|
||||
type AuthProfileEligibilityReasonCode,
|
||||
@@ -522,7 +525,7 @@ async function runTargetsWithConcurrency(params: {
|
||||
const concurrency = Math.max(1, Math.min(targets.length || 1, params.concurrency));
|
||||
|
||||
const agentId = params.agentId ?? resolveDefaultAgentId(cfg);
|
||||
const agentDir = params.agentDir ?? resolveOpenClawAgentDir();
|
||||
const agentDir = params.agentDir ?? resolveAgentDir(cfg, agentId);
|
||||
const workspaceDir =
|
||||
params.workspaceDir ??
|
||||
resolveAgentWorkspaceDir(cfg, agentId) ??
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Api, Model } from "@mariozechner/pi-ai";
|
||||
import type { ModelRegistry } from "@mariozechner/pi-coding-agent";
|
||||
import { resolveOpenClawAgentDir } from "../../agents/agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../../agents/agent-scope.js";
|
||||
import { shouldSuppressBuiltInModel } from "../../agents/model-suppression.js";
|
||||
import { discoverAuthStorage, discoverModels } from "../../agents/pi-model-discovery.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
@@ -51,7 +51,7 @@ export function loadConfiguredListModelRegistry(
|
||||
entries: ConfiguredEntry[],
|
||||
opts?: { providerFilter?: string; workspaceDir?: string },
|
||||
) {
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir, {
|
||||
readOnly: true,
|
||||
config: cfg,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Api, Model } from "@mariozechner/pi-ai";
|
||||
import type { ModelRegistry } from "@mariozechner/pi-coding-agent";
|
||||
import { resolveOpenClawAgentDir } from "../../agents/agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../../agents/agent-scope.js";
|
||||
import {
|
||||
shouldSuppressBuiltInModel,
|
||||
shouldSuppressBuiltInModelFromManifest,
|
||||
@@ -95,7 +95,7 @@ export async function loadModelRegistry(
|
||||
},
|
||||
) {
|
||||
const runtimeSuppression = opts?.normalizeModels !== false;
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir, {
|
||||
readOnly: true,
|
||||
skipCredentials: opts?.loadAvailability === false,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import path from "node:path";
|
||||
import { resolveOpenClawAgentDir } from "../../agents/agent-paths.js";
|
||||
import {
|
||||
resolveAgentDir,
|
||||
resolveAgentExplicitModelPrimary,
|
||||
@@ -45,7 +44,7 @@ import { type RuntimeEnv, writeRuntimeJson } from "../../runtime.js";
|
||||
import { createLazyImportLoader } from "../../shared/lazy-promise.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import { colorize, theme } from "../../terminal/theme.js";
|
||||
import { shortenHomePath } from "../../utils.js";
|
||||
import { resolveUserPath, shortenHomePath } from "../../utils.js";
|
||||
import { resolveProviderAuthOverview } from "./list.auth-overview.js";
|
||||
import { isRich } from "./list.format.js";
|
||||
import { type AuthProbeSummary } from "./list.probe.js";
|
||||
@@ -59,6 +58,11 @@ import {
|
||||
|
||||
type ProviderUsageRuntime = typeof import("../../infra/provider-usage.js");
|
||||
type ProgressRuntime = typeof import("../../cli/progress.js");
|
||||
|
||||
function resolveEnvAgentDirOverride(env: NodeJS.ProcessEnv = process.env): string | undefined {
|
||||
const override = env.OPENCLAW_AGENT_DIR?.trim() || env.PI_CODING_AGENT_DIR?.trim();
|
||||
return override ? resolveUserPath(override, env) : undefined;
|
||||
}
|
||||
type TerminalTableRuntime = typeof import("../../terminal/table.js");
|
||||
type ListProbeRuntime = typeof import("./list.probe.js");
|
||||
|
||||
@@ -173,8 +177,10 @@ export async function modelsStatusCommand(
|
||||
const configPath = createConfigIO().configPath;
|
||||
const cfg = await loadModelsConfig({ commandName: "models status", runtime });
|
||||
const agentId = resolveKnownAgentId({ cfg, rawAgentId: opts.agent });
|
||||
const agentDir = agentId ? resolveAgentDir(cfg, agentId) : resolveOpenClawAgentDir();
|
||||
const workspaceAgentId = agentId ?? resolveDefaultAgentId(cfg);
|
||||
const agentDir = agentId
|
||||
? resolveAgentDir(cfg, agentId)
|
||||
: (resolveEnvAgentDirOverride() ?? resolveAgentDir(cfg, workspaceAgentId));
|
||||
const workspaceDir =
|
||||
resolveAgentWorkspaceDir(cfg, workspaceAgentId) ?? resolveDefaultAgentWorkspaceDir();
|
||||
const agentModelPrimary = agentId ? resolveAgentExplicitModelPrimary(cfg, agentId) : undefined;
|
||||
|
||||
@@ -35,7 +35,6 @@ const mocks = vi.hoisted(() => {
|
||||
|
||||
return {
|
||||
store,
|
||||
resolveOpenClawAgentDir: vi.fn().mockReturnValue("/tmp/openclaw-agent"),
|
||||
resolveAgentDir: vi.fn().mockReturnValue("/tmp/openclaw-agent"),
|
||||
resolveAgentWorkspaceDir: vi.fn().mockReturnValue("/tmp/openclaw-agent/workspace"),
|
||||
resolveDefaultAgentId: vi.fn().mockReturnValue("main"),
|
||||
@@ -139,9 +138,6 @@ const mocks = vi.hoisted(() => {
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: mocks.resolveOpenClawAgentDir,
|
||||
}));
|
||||
vi.mock("../../agents/agent-scope.js", () => ({
|
||||
resolveAgentDir: mocks.resolveAgentDir,
|
||||
resolveAgentWorkspaceDir: mocks.resolveAgentWorkspaceDir,
|
||||
@@ -310,7 +306,7 @@ describe("modelsStatusCommand auth overview", () => {
|
||||
await modelsStatusCommand({ json: true }, runtime as never);
|
||||
const payload = JSON.parse(String((runtime.log as Mock).mock.calls[0]?.[0]));
|
||||
|
||||
expect(mocks.resolveOpenClawAgentDir).toHaveBeenCalled();
|
||||
expect(mocks.resolveAgentDir).toHaveBeenCalledWith(expect.anything(), "main");
|
||||
expect(mocks.ensureAuthProfileStore).toHaveBeenCalled();
|
||||
expect(payload.defaultModel).toBe("anthropic/claude-opus-4-6");
|
||||
expect(payload.configPath).toBe("/tmp/openclaw-dev/openclaw.json");
|
||||
@@ -362,6 +358,28 @@ describe("modelsStatusCommand auth overview", () => {
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("honors OPENCLAW_AGENT_DIR when no --agent override is provided", async () => {
|
||||
const localRuntime = createRuntime();
|
||||
const previous = process.env.OPENCLAW_AGENT_DIR;
|
||||
process.env.OPENCLAW_AGENT_DIR = "/tmp/openclaw-isolated-agent";
|
||||
mocks.resolveAgentDir.mockClear();
|
||||
try {
|
||||
await modelsStatusCommand({ json: true }, localRuntime as never);
|
||||
} finally {
|
||||
if (previous === undefined) {
|
||||
delete process.env.OPENCLAW_AGENT_DIR;
|
||||
} else {
|
||||
process.env.OPENCLAW_AGENT_DIR = previous;
|
||||
}
|
||||
}
|
||||
|
||||
expect(mocks.resolveAgentDir).not.toHaveBeenCalled();
|
||||
expect(mocks.ensureAuthProfileStore).toHaveBeenCalledWith("/tmp/openclaw-isolated-agent");
|
||||
const payload = JSON.parse(String((localRuntime.log as Mock).mock.calls[0]?.[0]));
|
||||
expect(payload.agentDir).toBe("/tmp/openclaw-isolated-agent");
|
||||
expect(payload.auth.storePath).toBe("/tmp/openclaw-isolated-agent/auth-profiles.json");
|
||||
});
|
||||
|
||||
it("uses agent overrides and reports sources", async () => {
|
||||
const localRuntime = createRuntime();
|
||||
await withAgentScopeOverrides(
|
||||
|
||||
@@ -26,10 +26,6 @@ const providerEnvVarsById = vi.hoisted(
|
||||
}),
|
||||
);
|
||||
|
||||
vi.mock("../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: () => process.env.OPENCLAW_AGENT_DIR ?? "/tmp/openclaw-agent",
|
||||
}));
|
||||
|
||||
vi.mock("../config/paths.js", () => ({
|
||||
resolveStateDir: () => process.env.OPENCLAW_STATE_DIR ?? "/tmp/openclaw-state",
|
||||
}));
|
||||
@@ -39,7 +35,8 @@ vi.mock("../agents/auth-profiles/profiles.js", async () => {
|
||||
const path = await import("node:path");
|
||||
return {
|
||||
upsertAuthProfile: (params: { profileId: string; credential: unknown; agentDir?: string }) => {
|
||||
const agentDir = params.agentDir ?? process.env.OPENCLAW_AGENT_DIR ?? "/tmp/openclaw-agent";
|
||||
const stateDir = process.env.OPENCLAW_STATE_DIR ?? "/tmp/openclaw-state";
|
||||
const agentDir = params.agentDir ?? path.join(stateDir, "agents", "main", "agent");
|
||||
const file = path.join(agentDir, "auth-profiles.json");
|
||||
fs.mkdirSync(agentDir, { recursive: true });
|
||||
const existing = (() => {
|
||||
@@ -99,9 +96,10 @@ describe("writeOAuthCredentials", () => {
|
||||
await lifecycle.cleanup();
|
||||
});
|
||||
|
||||
it("writes auth-profiles.json under OPENCLAW_AGENT_DIR when set", async () => {
|
||||
it("writes auth-profiles.json under the default agent dir", async () => {
|
||||
const env = await setupAuthTestEnv("openclaw-oauth-");
|
||||
lifecycle.setStateDir(env.stateDir);
|
||||
const defaultAgentDir = path.join(env.stateDir, "agents", "main", "agent");
|
||||
|
||||
const creds = {
|
||||
refresh: "refresh-token",
|
||||
@@ -113,7 +111,7 @@ describe("writeOAuthCredentials", () => {
|
||||
|
||||
const parsed = await readAuthProfilesForAgent<{
|
||||
profiles?: Record<string, OAuthCredentials & { type?: string }>;
|
||||
}>(env.agentDir);
|
||||
}>(defaultAgentDir);
|
||||
expect(parsed.profiles?.["openai-codex:default"]).toMatchObject({
|
||||
refresh: "refresh-token",
|
||||
access: "access-token",
|
||||
@@ -121,7 +119,7 @@ describe("writeOAuthCredentials", () => {
|
||||
});
|
||||
|
||||
await expect(
|
||||
fs.readFile(path.join(env.stateDir, "agents", "main", "agent", "auth-profiles.json"), "utf8"),
|
||||
fs.readFile(path.join(env.agentDir, "auth-profiles.json"), "utf8"),
|
||||
).rejects.toThrow();
|
||||
});
|
||||
|
||||
@@ -393,15 +391,16 @@ describe("upsertApiKeyProfile", () => {
|
||||
await lifecycle.cleanup();
|
||||
});
|
||||
|
||||
it("writes to OPENCLAW_AGENT_DIR when set", async () => {
|
||||
it("writes to the default agent dir", async () => {
|
||||
const env = await setupAuthTestEnv("openclaw-minimax-", { agentSubdir: "custom-agent" });
|
||||
lifecycle.setStateDir(env.stateDir);
|
||||
const defaultAgentDir = path.join(env.stateDir, "agents", "main", "agent");
|
||||
|
||||
upsertApiKeyProfile({ provider: "minimax", input: "sk-minimax-test" });
|
||||
|
||||
const parsed = await readAuthProfilesForAgent<{
|
||||
profiles?: Record<string, { type?: string; provider?: string; key?: string }>;
|
||||
}>(env.agentDir);
|
||||
}>(defaultAgentDir);
|
||||
expect(parsed.profiles?.["minimax:default"]).toMatchObject({
|
||||
type: "api_key",
|
||||
provider: "minimax",
|
||||
@@ -409,7 +408,7 @@ describe("upsertApiKeyProfile", () => {
|
||||
});
|
||||
|
||||
await expect(
|
||||
fs.readFile(path.join(env.stateDir, "agents", "main", "agent", "auth-profiles.json"), "utf8"),
|
||||
fs.readFile(path.join(env.agentDir, "auth-profiles.json"), "utf8"),
|
||||
).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,8 +5,7 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import type { Api, Model } from "@mariozechner/pi-ai";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
import { resolveAgentWorkspaceDir } from "../agents/agent-scope.js";
|
||||
import { resolveAgentWorkspaceDir, resolveDefaultAgentDir } from "../agents/agent-scope.js";
|
||||
import { ensureAuthProfileStore, saveAuthProfileStore } from "../agents/auth-profiles/store.js";
|
||||
import type { AuthProfileStore } from "../agents/auth-profiles/types.js";
|
||||
import {
|
||||
@@ -1425,7 +1424,7 @@ async function runGatewayModelSuite(params: GatewayModelSuiteParams) {
|
||||
process.env.OPENCLAW_GATEWAY_TOKEN = token;
|
||||
const agentId = "dev";
|
||||
|
||||
const hostAgentDir = resolveOpenClawAgentDir();
|
||||
const hostAgentDir = resolveDefaultAgentDir(getRuntimeConfig());
|
||||
const hostStore = ensureAuthProfileStore(hostAgentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
@@ -1469,7 +1468,7 @@ async function runGatewayModelSuite(params: GatewayModelSuiteParams) {
|
||||
const toolProbePath = path.join(workspaceDir, `.openclaw-live-tool-probe.${nonceA}.txt`);
|
||||
await fs.writeFile(toolProbePath, `nonceA=${nonceA}\nnonceB=${nonceB}\n`);
|
||||
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(params.cfg);
|
||||
const sanitizedCfg: OpenClawConfig = {
|
||||
...params.cfg,
|
||||
auth: await sanitizeAuthConfig({ cfg: params.cfg, agentDir }),
|
||||
@@ -2169,7 +2168,7 @@ describeLive("gateway live (dev agent, profile keys)", () => {
|
||||
const cfg = getRuntimeConfig();
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, agentDir);
|
||||
const all = modelRegistry.getAll();
|
||||
@@ -2319,7 +2318,7 @@ describeLive("gateway live (dev agent, profile keys)", () => {
|
||||
const cfg = getRuntimeConfig();
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, agentDir);
|
||||
const anthropic = modelRegistry.find("anthropic", "claude-opus-4-6") as Model<Api> | null;
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { GatewayRequestHandlerOptions } from "./types.js";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
getRuntimeConfig: vi.fn(() => ({})),
|
||||
resolveOpenClawAgentDir: vi.fn(() => "/tmp/agent"),
|
||||
resolveDefaultAgentDir: vi.fn(() => "/tmp/agent"),
|
||||
ensureAuthProfileStore: vi.fn((agentDir?: string, options?: unknown) => {
|
||||
void agentDir;
|
||||
void options;
|
||||
@@ -20,8 +20,8 @@ vi.mock("../../config/config.js", () => ({
|
||||
getRuntimeConfig: mocks.getRuntimeConfig,
|
||||
}));
|
||||
|
||||
vi.mock("../../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: mocks.resolveOpenClawAgentDir,
|
||||
vi.mock("../../agents/agent-scope.js", () => ({
|
||||
resolveDefaultAgentDir: mocks.resolveDefaultAgentDir,
|
||||
}));
|
||||
|
||||
vi.mock("../../agents/auth-profiles.js", async () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { resolveOpenClawAgentDir } from "../../agents/agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../../agents/agent-scope.js";
|
||||
import {
|
||||
type AuthHealthSummary,
|
||||
type AuthProfileHealthStatus,
|
||||
@@ -291,7 +291,7 @@ export const modelsAuthStatusHandlers: GatewayRequestHandlers = {
|
||||
}
|
||||
try {
|
||||
const cfg = context.getRuntimeConfig();
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const store = ensureAuthProfileStore(agentDir, {
|
||||
externalCli: externalCliDiscoveryForConfigStatus({ cfg }),
|
||||
});
|
||||
|
||||
@@ -35,7 +35,7 @@ const hoisted = vi.hoisted(() => {
|
||||
}));
|
||||
const resolveAgentModelPrimaryValue = vi.fn(() => "");
|
||||
const normalizeProviderId = vi.fn((provider: string) => provider.toLowerCase());
|
||||
const resolveOpenClawAgentDir = vi.fn(() => "/tmp/openclaw-state/agents/default/agent");
|
||||
const resolveDefaultAgentDir = vi.fn(() => "/tmp/openclaw-state/agents/default/agent");
|
||||
const isCliProvider = vi.fn(() => false);
|
||||
const resolveConfiguredModelRef = vi.fn(() => ({
|
||||
provider: "openai",
|
||||
@@ -64,7 +64,7 @@ const hoisted = vi.hoisted(() => {
|
||||
reconcilePendingSessionIdentities,
|
||||
resolveAgentModelPrimaryValue,
|
||||
normalizeProviderId,
|
||||
resolveOpenClawAgentDir,
|
||||
resolveDefaultAgentDir,
|
||||
isCliProvider,
|
||||
resolveConfiguredModelRef,
|
||||
resolveEmbeddedAgentRuntime,
|
||||
@@ -154,11 +154,8 @@ vi.mock("../agents/provider-id.js", () => ({
|
||||
normalizeProviderId: hoisted.normalizeProviderId,
|
||||
}));
|
||||
|
||||
vi.mock("../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: hoisted.resolveOpenClawAgentDir,
|
||||
}));
|
||||
|
||||
vi.mock("../agents/agent-scope.js", () => ({
|
||||
resolveDefaultAgentDir: hoisted.resolveDefaultAgentDir,
|
||||
resolveAgentWorkspaceDir: vi.fn(() => "/tmp/openclaw-workspace"),
|
||||
resolveDefaultAgentId: vi.fn(() => "default"),
|
||||
}));
|
||||
@@ -218,7 +215,7 @@ describe("startGatewayPostAttachRuntime", () => {
|
||||
hoisted.resolveAgentModelPrimaryValue.mockReset();
|
||||
hoisted.resolveAgentModelPrimaryValue.mockReturnValue("");
|
||||
hoisted.normalizeProviderId.mockClear();
|
||||
hoisted.resolveOpenClawAgentDir.mockClear();
|
||||
hoisted.resolveDefaultAgentDir.mockClear();
|
||||
hoisted.isCliProvider.mockReset();
|
||||
hoisted.isCliProvider.mockReturnValue(false);
|
||||
hoisted.resolveConfiguredModelRef.mockClear();
|
||||
@@ -576,6 +573,33 @@ describe("startGatewayPostAttachRuntime", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("prewarms models.json in the configured default agent dir", async () => {
|
||||
const cfg = {
|
||||
agents: {
|
||||
defaults: { model: "openai/gpt-5.4" },
|
||||
list: [{ id: "main" }, { id: "ops", default: true }],
|
||||
},
|
||||
} as never;
|
||||
hoisted.resolveAgentModelPrimaryValue.mockReturnValue("openai/gpt-5.4");
|
||||
hoisted.resolveDefaultAgentDir.mockReturnValue("/tmp/openclaw-state/agents/ops/agent");
|
||||
|
||||
await __testing.prewarmConfiguredPrimaryModel({
|
||||
cfg,
|
||||
workspaceDir: "/tmp/openclaw-workspace",
|
||||
log: { warn: vi.fn() },
|
||||
});
|
||||
|
||||
expect(hoisted.resolveDefaultAgentDir).toHaveBeenCalledWith(cfg);
|
||||
expect(hoisted.ensureOpenClawModelsJson).toHaveBeenCalledWith(
|
||||
cfg,
|
||||
"/tmp/openclaw-state/agents/ops/agent",
|
||||
expect.objectContaining({
|
||||
workspaceDir: "/tmp/openclaw-workspace",
|
||||
providerDiscoveryProviderIds: ["openai"],
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("starts channels without waiting for primary model prewarm completion", async () => {
|
||||
await withEnvAsync(
|
||||
{ OPENCLAW_SKIP_CHANNELS: undefined, OPENCLAW_SKIP_PROVIDERS: undefined },
|
||||
|
||||
@@ -271,13 +271,11 @@ async function prewarmConfiguredPrimaryModel(params: {
|
||||
return;
|
||||
}
|
||||
const [
|
||||
{ resolveOpenClawAgentDir },
|
||||
{ resolveAgentWorkspaceDir, resolveDefaultAgentId },
|
||||
{ resolveAgentWorkspaceDir, resolveDefaultAgentDir, resolveDefaultAgentId },
|
||||
{ DEFAULT_MODEL, DEFAULT_PROVIDER },
|
||||
{ isCliProvider, resolveConfiguredModelRef },
|
||||
{ resolveEmbeddedAgentRuntime },
|
||||
] = await Promise.all([
|
||||
import("../agents/agent-paths.js"),
|
||||
import("../agents/agent-scope.js"),
|
||||
import("../agents/defaults.js"),
|
||||
import("../agents/model-selection.js"),
|
||||
@@ -297,7 +295,7 @@ async function prewarmConfiguredPrimaryModel(params: {
|
||||
}
|
||||
// Keep startup prewarm metadata-only; resolving models can import provider runtimes and block readiness.
|
||||
const { ensureOpenClawModelsJson } = await import("../agents/models-config.js");
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(params.cfg);
|
||||
const workspaceDir =
|
||||
params.workspaceDir ?? resolveAgentWorkspaceDir(params.cfg, resolveDefaultAgentId(params.cfg));
|
||||
try {
|
||||
|
||||
@@ -11,11 +11,8 @@ const ensureOpenClawModelsJsonMock = vi.fn<
|
||||
const piModelModuleLoadedMock = vi.fn();
|
||||
const resolveEmbeddedAgentRuntimeMock = vi.fn(() => "auto");
|
||||
|
||||
vi.mock("../agents/agent-paths.js", () => ({
|
||||
resolveOpenClawAgentDir: () => "/tmp/agent",
|
||||
}));
|
||||
|
||||
vi.mock("../agents/agent-scope.js", () => ({
|
||||
resolveDefaultAgentDir: () => "/tmp/agent",
|
||||
resolveAgentWorkspaceDir: () => "/tmp/workspace",
|
||||
resolveDefaultAgentId: () => "default",
|
||||
}));
|
||||
|
||||
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterAll, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
||||
import { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../agents/agent-scope.js";
|
||||
import { AUTH_PROFILE_FILENAME } from "../agents/auth-profiles/constants.js";
|
||||
import { __testing as controlPlaneRateLimitTesting } from "./control-plane-rate-limit.js";
|
||||
import {
|
||||
@@ -72,7 +72,7 @@ async function expectSchemaLookupInvalid(path: unknown) {
|
||||
|
||||
async function writeUnresolvedAuthProfileTokenRef(missingEnvVar: string) {
|
||||
delete process.env[missingEnvVar];
|
||||
const authStorePath = path.join(resolveOpenClawAgentDir(), AUTH_PROFILE_FILENAME);
|
||||
const authStorePath = path.join(resolveDefaultAgentDir({}), AUTH_PROFILE_FILENAME);
|
||||
await fs.mkdir(path.dirname(authStorePath), { recursive: true });
|
||||
await fs.writeFile(
|
||||
authStorePath,
|
||||
|
||||
11
src/plugin-sdk/agent-dir-compat.ts
Normal file
11
src/plugin-sdk/agent-dir-compat.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
|
||||
/**
|
||||
* @deprecated Prefer resolveAgentDir(cfg, agentId) or resolveDefaultAgentDir(cfg).
|
||||
* Kept for third-party plugin SDK compatibility.
|
||||
*/
|
||||
export function resolveOpenClawAgentDir(env: NodeJS.ProcessEnv = process.env): string {
|
||||
const override = env.OPENCLAW_AGENT_DIR?.trim() || env.PI_CODING_AGENT_DIR?.trim();
|
||||
return override ? resolveUserPath(override, env) : resolveDefaultAgentDir({}, env);
|
||||
}
|
||||
@@ -86,7 +86,7 @@ export {
|
||||
filterToolResultMediaUrls,
|
||||
} from "../agents/pi-embedded-subscribe.tools.js";
|
||||
export { normalizeUsage } from "../agents/usage.js";
|
||||
export { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
export { resolveOpenClawAgentDir } from "./agent-dir-compat.js";
|
||||
export { resolveSessionAgentIds } from "../agents/agent-scope.js";
|
||||
export { resolveModelAuthMode } from "../agents/model-auth.js";
|
||||
export { supportsModelTools } from "../agents/model-tool-support.js";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Public agent/model/runtime helpers for plugins that integrate with core agent flows.
|
||||
|
||||
export * from "../agents/agent-scope.js";
|
||||
export { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
export { resolveOpenClawAgentDir } from "./agent-dir-compat.js";
|
||||
export * from "../agents/current-time.js";
|
||||
export * from "../agents/date-time.js";
|
||||
export * from "../agents/defaults.js";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Public auth/onboarding helpers for provider plugins.
|
||||
|
||||
import path from "node:path";
|
||||
import { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js";
|
||||
import { resolveApiKeyForProfile } from "../agents/auth-profiles/oauth.js";
|
||||
import { resolveAuthProfileOrder } from "../agents/auth-profiles/order.js";
|
||||
import { listProfilesForProvider } from "../agents/auth-profiles/profiles.js";
|
||||
@@ -72,7 +72,7 @@ export { createProviderApiKeyAuthMethod } from "../plugins/provider-api-key-auth
|
||||
export { coerceSecretRef, hasConfiguredSecretInput } from "../config/types.secrets.js";
|
||||
export { resolveDefaultSecretProviderAlias } from "../secrets/ref-contract.js";
|
||||
export { resolveRequiredHomeDir } from "../infra/home-dir.js";
|
||||
export { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
export { resolveOpenClawAgentDir } from "./agent-dir-compat.js";
|
||||
export {
|
||||
normalizeOptionalSecretInput,
|
||||
normalizeSecretInput,
|
||||
@@ -279,7 +279,7 @@ export function listUsableProviderAuthProfileIds(params: {
|
||||
agentDir?: string;
|
||||
}): { agentDir: string; profileIds: string[] } {
|
||||
try {
|
||||
const agentDir = params.agentDir?.trim() || resolveOpenClawAgentDir();
|
||||
const agentDir = params.agentDir?.trim() || resolveDefaultAgentDir(params.cfg ?? {});
|
||||
const store = ensureAuthProfileStore(agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
import {
|
||||
resolveDefaultAgentId,
|
||||
resolveAgentDir,
|
||||
@@ -221,12 +220,7 @@ export async function runProviderPluginAuthMethod(params: {
|
||||
opts?: Partial<ProviderAuthOptionBag>;
|
||||
}): Promise<{ config: OpenClawConfig; defaultModel?: string }> {
|
||||
const agentId = params.agentId ?? resolveDefaultAgentId(params.config);
|
||||
const defaultAgentId = resolveDefaultAgentId(params.config);
|
||||
const agentDir =
|
||||
params.agentDir ??
|
||||
(agentId === defaultAgentId
|
||||
? resolveOpenClawAgentDir()
|
||||
: resolveAgentDir(params.config, agentId));
|
||||
const agentDir = params.agentDir ?? resolveAgentDir(params.config, agentId);
|
||||
const workspaceDir =
|
||||
params.workspaceDir ??
|
||||
resolveAgentWorkspaceDir(params.config, agentId) ??
|
||||
@@ -469,10 +463,7 @@ export async function applyAuthChoicePluginProvider(
|
||||
}
|
||||
|
||||
const agentId = params.agentId ?? resolveDefaultAgentId(nextConfig);
|
||||
const defaultAgentId = resolveDefaultAgentId(nextConfig);
|
||||
const agentDir =
|
||||
params.agentDir ??
|
||||
(agentId === defaultAgentId ? resolveOpenClawAgentDir() : resolveAgentDir(nextConfig, agentId));
|
||||
const agentDir = params.agentDir ?? resolveAgentDir(nextConfig, agentId);
|
||||
const workspaceDir =
|
||||
resolveAgentWorkspaceDir(nextConfig, agentId) ?? resolveDefaultAgentWorkspaceDir();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { OAuthCredentials } from "@mariozechner/pi-ai";
|
||||
import { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js";
|
||||
import { buildAuthProfileId } from "../agents/auth-profiles/identity.js";
|
||||
import { upsertAuthProfile } from "../agents/auth-profiles/profiles.js";
|
||||
import { resolveProviderIdForAuth } from "../agents/provider-auth-aliases.js";
|
||||
@@ -19,7 +19,8 @@ import type { SecretInputMode } from "./provider-auth-types.js";
|
||||
|
||||
const ENV_REF_PATTERN = /^\$\{([A-Z][A-Z0-9_]*)\}$/;
|
||||
|
||||
const resolveAuthAgentDir = (agentDir?: string) => agentDir ?? resolveOpenClawAgentDir();
|
||||
const resolveAuthAgentDir = (agentDir?: string, config?: OpenClawConfig) =>
|
||||
agentDir ?? resolveDefaultAgentDir(config ?? {});
|
||||
|
||||
export type ApiKeyStorageOptions = {
|
||||
secretInputMode?: SecretInputMode;
|
||||
@@ -127,7 +128,7 @@ export function upsertApiKeyProfile(params: {
|
||||
params.metadata,
|
||||
params.options,
|
||||
),
|
||||
agentDir: resolveAuthAgentDir(params.agentDir),
|
||||
agentDir: resolveAuthAgentDir(params.agentDir, params.options?.config),
|
||||
});
|
||||
return profileId;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
import {
|
||||
listAgentIds,
|
||||
resolveAgentDir,
|
||||
resolveAgentWorkspaceDir,
|
||||
resolveDefaultAgentDir,
|
||||
resolveDefaultAgentId,
|
||||
} from "../agents/agent-scope.js";
|
||||
import {
|
||||
@@ -114,7 +114,7 @@ function collectCandidateAgentDirs(
|
||||
env: NodeJS.ProcessEnv = process.env,
|
||||
): string[] {
|
||||
const dirs = new Set<string>();
|
||||
dirs.add(resolveUserPath(resolveOpenClawAgentDir(env), env));
|
||||
dirs.add(resolveUserPath(resolveDefaultAgentDir(config, env), env));
|
||||
for (const agentId of listAgentIds(config)) {
|
||||
dirs.add(resolveUserPath(resolveAgentDir(config, agentId, env), env));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { resolveOpenClawAgentDir } from "../agents/agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../agents/agent-scope-config.js";
|
||||
import { modelKey, normalizeModelRef, normalizeProviderId } from "../agents/model-selection.js";
|
||||
import type { NormalizedUsage } from "../agents/usage.js";
|
||||
import type { ModelProviderConfig } from "../config/types.models.js";
|
||||
@@ -204,7 +204,7 @@ function loadModelsJsonCostIndex(options?: {
|
||||
allowPluginNormalization?: boolean;
|
||||
}): Map<string, ModelCostConfig> {
|
||||
const useRawEntries = options?.allowPluginNormalization === false;
|
||||
const modelsPath = path.join(resolveOpenClawAgentDir(), "models.json");
|
||||
const modelsPath = path.join(resolveDefaultAgentDir({}), "models.json");
|
||||
try {
|
||||
const stat = fs.statSync(modelsPath);
|
||||
if (
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
requireRegisteredProvider,
|
||||
} from "openclaw/plugin-sdk/plugin-test-runtime";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveOpenClawAgentDir } from "../src/agents/agent-paths.js";
|
||||
import { resolveDefaultAgentDir } from "../src/agents/agent-scope.js";
|
||||
import { collectProviderApiKeys } from "../src/agents/live-auth-keys.js";
|
||||
import { isLiveProfileKeyModeEnabled, isLiveTestEnabled } from "../src/agents/live-test-helpers.js";
|
||||
import { resolveApiKeyForProvider } from "../src/agents/model-auth.js";
|
||||
@@ -199,7 +199,7 @@ describeLive("image generation live (provider sweep)", () => {
|
||||
async () => {
|
||||
const cfg = withPluginsEnabled(loadConfig());
|
||||
const configuredModels = resolveConfiguredLiveImageModels(cfg);
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const agentDir = resolveDefaultAgentDir(cfg);
|
||||
const attempted: string[] = [];
|
||||
const skipped: string[] = [];
|
||||
const failures: string[] = [];
|
||||
|
||||
Reference in New Issue
Block a user