mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 17:10:49 +00:00
refactor: rename to openclaw
This commit is contained in:
@@ -4,11 +4,11 @@ import path from "node:path";
|
||||
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
|
||||
import { resolveMoltbotAgentDir } from "./agent-paths.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
|
||||
describe("resolveMoltbotAgentDir", () => {
|
||||
const previousStateDir = process.env.CLAWDBOT_STATE_DIR;
|
||||
const previousAgentDir = process.env.CLAWDBOT_AGENT_DIR;
|
||||
describe("resolveOpenClawAgentDir", () => {
|
||||
const previousStateDir = process.env.OPENCLAW_STATE_DIR;
|
||||
const previousAgentDir = process.env.OPENCLAW_AGENT_DIR;
|
||||
const previousPiAgentDir = process.env.PI_CODING_AGENT_DIR;
|
||||
let tempStateDir: string | null = null;
|
||||
|
||||
@@ -18,14 +18,14 @@ describe("resolveMoltbotAgentDir", () => {
|
||||
tempStateDir = null;
|
||||
}
|
||||
if (previousStateDir === undefined) {
|
||||
delete process.env.CLAWDBOT_STATE_DIR;
|
||||
delete process.env.OPENCLAW_STATE_DIR;
|
||||
} else {
|
||||
process.env.CLAWDBOT_STATE_DIR = previousStateDir;
|
||||
process.env.OPENCLAW_STATE_DIR = previousStateDir;
|
||||
}
|
||||
if (previousAgentDir === undefined) {
|
||||
delete process.env.CLAWDBOT_AGENT_DIR;
|
||||
delete process.env.OPENCLAW_AGENT_DIR;
|
||||
} else {
|
||||
process.env.CLAWDBOT_AGENT_DIR = previousAgentDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = previousAgentDir;
|
||||
}
|
||||
if (previousPiAgentDir === undefined) {
|
||||
delete process.env.PI_CODING_AGENT_DIR;
|
||||
@@ -35,23 +35,23 @@ describe("resolveMoltbotAgentDir", () => {
|
||||
});
|
||||
|
||||
it("defaults to the multi-agent path when no overrides are set", async () => {
|
||||
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
process.env.CLAWDBOT_STATE_DIR = tempStateDir;
|
||||
delete process.env.CLAWDBOT_AGENT_DIR;
|
||||
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
process.env.OPENCLAW_STATE_DIR = tempStateDir;
|
||||
delete process.env.OPENCLAW_AGENT_DIR;
|
||||
delete process.env.PI_CODING_AGENT_DIR;
|
||||
|
||||
const resolved = resolveMoltbotAgentDir();
|
||||
const resolved = resolveOpenClawAgentDir();
|
||||
|
||||
expect(resolved).toBe(path.join(tempStateDir, "agents", "main", "agent"));
|
||||
});
|
||||
|
||||
it("honors CLAWDBOT_AGENT_DIR overrides", async () => {
|
||||
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
it("honors OPENCLAW_AGENT_DIR overrides", async () => {
|
||||
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
const override = path.join(tempStateDir, "agent");
|
||||
process.env.CLAWDBOT_AGENT_DIR = override;
|
||||
process.env.OPENCLAW_AGENT_DIR = override;
|
||||
delete process.env.PI_CODING_AGENT_DIR;
|
||||
|
||||
const resolved = resolveMoltbotAgentDir();
|
||||
const resolved = resolveOpenClawAgentDir();
|
||||
|
||||
expect(resolved).toBe(path.resolve(override));
|
||||
});
|
||||
|
||||
@@ -4,17 +4,17 @@ import { resolveStateDir } from "../config/paths.js";
|
||||
import { DEFAULT_AGENT_ID } from "../routing/session-key.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
|
||||
export function resolveMoltbotAgentDir(): string {
|
||||
export function resolveOpenClawAgentDir(): string {
|
||||
const override =
|
||||
process.env.CLAWDBOT_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
|
||||
process.env.OPENCLAW_AGENT_DIR?.trim() || process.env.PI_CODING_AGENT_DIR?.trim();
|
||||
if (override) return resolveUserPath(override);
|
||||
const defaultAgentDir = path.join(resolveStateDir(), "agents", DEFAULT_AGENT_ID, "agent");
|
||||
return resolveUserPath(defaultAgentDir);
|
||||
}
|
||||
|
||||
export function ensureMoltbotAgentEnv(): string {
|
||||
const dir = resolveMoltbotAgentDir();
|
||||
if (!process.env.CLAWDBOT_AGENT_DIR) process.env.CLAWDBOT_AGENT_DIR = dir;
|
||||
export function ensureOpenClawAgentEnv(): string {
|
||||
const dir = resolveOpenClawAgentDir();
|
||||
if (!process.env.OPENCLAW_AGENT_DIR) process.env.OPENCLAW_AGENT_DIR = dir;
|
||||
if (!process.env.PI_CODING_AGENT_DIR) process.env.PI_CODING_AGENT_DIR = dir;
|
||||
return dir;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
resolveAgentConfig,
|
||||
resolveAgentModelFallbacksOverride,
|
||||
@@ -8,15 +8,15 @@ import {
|
||||
|
||||
describe("resolveAgentConfig", () => {
|
||||
it("should return undefined when no agents config exists", () => {
|
||||
const cfg: MoltbotConfig = {};
|
||||
const cfg: OpenClawConfig = {};
|
||||
const result = resolveAgentConfig(cfg, "main");
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should return undefined when agent id does not exist", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [{ id: "main", workspace: "~/clawd" }],
|
||||
list: [{ id: "main", workspace: "~/openclaw" }],
|
||||
},
|
||||
};
|
||||
const result = resolveAgentConfig(cfg, "nonexistent");
|
||||
@@ -24,14 +24,14 @@ describe("resolveAgentConfig", () => {
|
||||
});
|
||||
|
||||
it("should return basic agent config", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
id: "main",
|
||||
name: "Main Agent",
|
||||
workspace: "~/clawd",
|
||||
agentDir: "~/.clawdbot/agents/main",
|
||||
workspace: "~/openclaw",
|
||||
agentDir: "~/.openclaw/agents/main",
|
||||
model: "anthropic/claude-opus-4",
|
||||
},
|
||||
],
|
||||
@@ -40,8 +40,8 @@ describe("resolveAgentConfig", () => {
|
||||
const result = resolveAgentConfig(cfg, "main");
|
||||
expect(result).toEqual({
|
||||
name: "Main Agent",
|
||||
workspace: "~/clawd",
|
||||
agentDir: "~/.clawdbot/agents/main",
|
||||
workspace: "~/openclaw",
|
||||
agentDir: "~/.openclaw/agents/main",
|
||||
model: "anthropic/claude-opus-4",
|
||||
identity: undefined,
|
||||
groupChat: undefined,
|
||||
@@ -52,7 +52,7 @@ describe("resolveAgentConfig", () => {
|
||||
});
|
||||
|
||||
it("supports per-agent model primary+fallbacks", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
defaults: {
|
||||
model: {
|
||||
@@ -76,7 +76,7 @@ describe("resolveAgentConfig", () => {
|
||||
expect(resolveAgentModelFallbacksOverride(cfg, "linus")).toEqual(["openai/gpt-5.2"]);
|
||||
|
||||
// If fallbacks isn't present, we don't override the global fallbacks.
|
||||
const cfgNoOverride: MoltbotConfig = {
|
||||
const cfgNoOverride: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
@@ -91,7 +91,7 @@ describe("resolveAgentConfig", () => {
|
||||
expect(resolveAgentModelFallbacksOverride(cfgNoOverride, "linus")).toBe(undefined);
|
||||
|
||||
// Explicit empty list disables global fallbacks for that agent.
|
||||
const cfgDisable: MoltbotConfig = {
|
||||
const cfgDisable: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
@@ -108,12 +108,12 @@ describe("resolveAgentConfig", () => {
|
||||
});
|
||||
|
||||
it("should return agent-specific sandbox config", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
id: "work",
|
||||
workspace: "~/clawd-work",
|
||||
workspace: "~/openclaw-work",
|
||||
sandbox: {
|
||||
mode: "all",
|
||||
scope: "agent",
|
||||
@@ -136,12 +136,12 @@ describe("resolveAgentConfig", () => {
|
||||
});
|
||||
|
||||
it("should return agent-specific tools config", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
id: "restricted",
|
||||
workspace: "~/clawd-restricted",
|
||||
workspace: "~/openclaw-restricted",
|
||||
tools: {
|
||||
allow: ["read"],
|
||||
deny: ["exec", "write", "edit"],
|
||||
@@ -166,12 +166,12 @@ describe("resolveAgentConfig", () => {
|
||||
});
|
||||
|
||||
it("should return both sandbox and tools config", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
id: "family",
|
||||
workspace: "~/clawd-family",
|
||||
workspace: "~/openclaw-family",
|
||||
sandbox: {
|
||||
mode: "all",
|
||||
scope: "agent",
|
||||
@@ -190,14 +190,14 @@ describe("resolveAgentConfig", () => {
|
||||
});
|
||||
|
||||
it("should normalize agent id", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [{ id: "main", workspace: "~/clawd" }],
|
||||
list: [{ id: "main", workspace: "~/openclaw" }],
|
||||
},
|
||||
};
|
||||
// Should normalize to "main" (default)
|
||||
const result = resolveAgentConfig(cfg, "");
|
||||
expect(result).toBeDefined();
|
||||
expect(result?.workspace).toBe("~/clawd");
|
||||
expect(result?.workspace).toBe("~/openclaw");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveStateDir } from "../config/paths.js";
|
||||
import {
|
||||
DEFAULT_AGENT_ID,
|
||||
@@ -13,7 +13,7 @@ import { DEFAULT_AGENT_WORKSPACE_DIR } from "./workspace.js";
|
||||
|
||||
export { resolveAgentIdFromSessionKey } from "../routing/session-key.js";
|
||||
|
||||
type AgentEntry = NonNullable<NonNullable<MoltbotConfig["agents"]>["list"]>[number];
|
||||
type AgentEntry = NonNullable<NonNullable<OpenClawConfig["agents"]>["list"]>[number];
|
||||
|
||||
type ResolvedAgentConfig = {
|
||||
name?: string;
|
||||
@@ -32,13 +32,13 @@ type ResolvedAgentConfig = {
|
||||
|
||||
let defaultAgentWarned = false;
|
||||
|
||||
function listAgents(cfg: MoltbotConfig): AgentEntry[] {
|
||||
function listAgents(cfg: OpenClawConfig): AgentEntry[] {
|
||||
const list = cfg.agents?.list;
|
||||
if (!Array.isArray(list)) return [];
|
||||
return list.filter((entry): entry is AgentEntry => Boolean(entry && typeof entry === "object"));
|
||||
}
|
||||
|
||||
export function listAgentIds(cfg: MoltbotConfig): string[] {
|
||||
export function listAgentIds(cfg: OpenClawConfig): string[] {
|
||||
const agents = listAgents(cfg);
|
||||
if (agents.length === 0) return [DEFAULT_AGENT_ID];
|
||||
const seen = new Set<string>();
|
||||
@@ -52,7 +52,7 @@ export function listAgentIds(cfg: MoltbotConfig): string[] {
|
||||
return ids.length > 0 ? ids : [DEFAULT_AGENT_ID];
|
||||
}
|
||||
|
||||
export function resolveDefaultAgentId(cfg: MoltbotConfig): string {
|
||||
export function resolveDefaultAgentId(cfg: OpenClawConfig): string {
|
||||
const agents = listAgents(cfg);
|
||||
if (agents.length === 0) return DEFAULT_AGENT_ID;
|
||||
const defaults = agents.filter((agent) => agent?.default);
|
||||
@@ -64,7 +64,7 @@ export function resolveDefaultAgentId(cfg: MoltbotConfig): string {
|
||||
return normalizeAgentId(chosen || DEFAULT_AGENT_ID);
|
||||
}
|
||||
|
||||
export function resolveSessionAgentIds(params: { sessionKey?: string; config?: MoltbotConfig }): {
|
||||
export function resolveSessionAgentIds(params: { sessionKey?: string; config?: OpenClawConfig }): {
|
||||
defaultAgentId: string;
|
||||
sessionAgentId: string;
|
||||
} {
|
||||
@@ -78,18 +78,18 @@ export function resolveSessionAgentIds(params: { sessionKey?: string; config?: M
|
||||
|
||||
export function resolveSessionAgentId(params: {
|
||||
sessionKey?: string;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
}): string {
|
||||
return resolveSessionAgentIds(params).sessionAgentId;
|
||||
}
|
||||
|
||||
function resolveAgentEntry(cfg: MoltbotConfig, agentId: string): AgentEntry | undefined {
|
||||
function resolveAgentEntry(cfg: OpenClawConfig, agentId: string): AgentEntry | undefined {
|
||||
const id = normalizeAgentId(agentId);
|
||||
return listAgents(cfg).find((entry) => normalizeAgentId(entry.id) === id);
|
||||
}
|
||||
|
||||
export function resolveAgentConfig(
|
||||
cfg: MoltbotConfig,
|
||||
cfg: OpenClawConfig,
|
||||
agentId: string,
|
||||
): ResolvedAgentConfig | undefined {
|
||||
const id = normalizeAgentId(agentId);
|
||||
@@ -114,7 +114,7 @@ export function resolveAgentConfig(
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveAgentModelPrimary(cfg: MoltbotConfig, agentId: string): string | undefined {
|
||||
export function resolveAgentModelPrimary(cfg: OpenClawConfig, agentId: string): string | undefined {
|
||||
const raw = resolveAgentConfig(cfg, agentId)?.model;
|
||||
if (!raw) return undefined;
|
||||
if (typeof raw === "string") return raw.trim() || undefined;
|
||||
@@ -123,7 +123,7 @@ export function resolveAgentModelPrimary(cfg: MoltbotConfig, agentId: string): s
|
||||
}
|
||||
|
||||
export function resolveAgentModelFallbacksOverride(
|
||||
cfg: MoltbotConfig,
|
||||
cfg: OpenClawConfig,
|
||||
agentId: string,
|
||||
): string[] | undefined {
|
||||
const raw = resolveAgentConfig(cfg, agentId)?.model;
|
||||
@@ -133,7 +133,7 @@ export function resolveAgentModelFallbacksOverride(
|
||||
return Array.isArray(raw.fallbacks) ? raw.fallbacks : undefined;
|
||||
}
|
||||
|
||||
export function resolveAgentWorkspaceDir(cfg: MoltbotConfig, agentId: string) {
|
||||
export function resolveAgentWorkspaceDir(cfg: OpenClawConfig, agentId: string) {
|
||||
const id = normalizeAgentId(agentId);
|
||||
const configured = resolveAgentConfig(cfg, id)?.workspace?.trim();
|
||||
if (configured) return resolveUserPath(configured);
|
||||
@@ -143,10 +143,10 @@ export function resolveAgentWorkspaceDir(cfg: MoltbotConfig, agentId: string) {
|
||||
if (fallback) return resolveUserPath(fallback);
|
||||
return DEFAULT_AGENT_WORKSPACE_DIR;
|
||||
}
|
||||
return path.join(os.homedir(), `clawd-${id}`);
|
||||
return path.join(os.homedir(), ".openclaw", `workspace-${id}`);
|
||||
}
|
||||
|
||||
export function resolveAgentDir(cfg: MoltbotConfig, agentId: string) {
|
||||
export function resolveAgentDir(cfg: OpenClawConfig, agentId: string) {
|
||||
const id = normalizeAgentId(agentId);
|
||||
const configured = resolveAgentConfig(cfg, id)?.agentDir?.trim();
|
||||
if (configured) return resolveUserPath(configured);
|
||||
|
||||
@@ -42,8 +42,8 @@ const writers = new Map<string, PayloadLogWriter>();
|
||||
const log = createSubsystemLogger("agent/anthropic-payload");
|
||||
|
||||
function resolvePayloadLogConfig(env: NodeJS.ProcessEnv): PayloadLogConfig {
|
||||
const enabled = parseBooleanValue(env.CLAWDBOT_ANTHROPIC_PAYLOAD_LOG) ?? false;
|
||||
const fileOverride = env.CLAWDBOT_ANTHROPIC_PAYLOAD_LOG_FILE?.trim();
|
||||
const enabled = parseBooleanValue(env.OPENCLAW_ANTHROPIC_PAYLOAD_LOG) ?? false;
|
||||
const fileOverride = env.OPENCLAW_ANTHROPIC_PAYLOAD_LOG_FILE?.trim();
|
||||
const filePath = fileOverride
|
||||
? resolveUserPath(fileOverride)
|
||||
: path.join(resolveStateDir(env), "logs", "anthropic-payload.jsonl");
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
validateAnthropicSetupToken,
|
||||
} from "../commands/auth-token.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { resolveMoltbotAgentDir } from "./agent-paths.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import {
|
||||
type AuthProfileCredential,
|
||||
ensureAuthProfileStore,
|
||||
@@ -20,13 +20,13 @@ import {
|
||||
} from "./auth-profiles.js";
|
||||
import { getApiKeyForModel, requireApiKey } from "./model-auth.js";
|
||||
import { normalizeProviderId, parseModelRef } from "./model-selection.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
|
||||
const LIVE = isTruthyEnvValue(process.env.LIVE) || isTruthyEnvValue(process.env.CLAWDBOT_LIVE_TEST);
|
||||
const SETUP_TOKEN_RAW = process.env.CLAWDBOT_LIVE_SETUP_TOKEN?.trim() ?? "";
|
||||
const SETUP_TOKEN_VALUE = process.env.CLAWDBOT_LIVE_SETUP_TOKEN_VALUE?.trim() ?? "";
|
||||
const SETUP_TOKEN_PROFILE = process.env.CLAWDBOT_LIVE_SETUP_TOKEN_PROFILE?.trim() ?? "";
|
||||
const SETUP_TOKEN_MODEL = process.env.CLAWDBOT_LIVE_SETUP_TOKEN_MODEL?.trim() ?? "";
|
||||
const LIVE = isTruthyEnvValue(process.env.LIVE) || isTruthyEnvValue(process.env.OPENCLAW_LIVE_TEST);
|
||||
const SETUP_TOKEN_RAW = process.env.OPENCLAW_LIVE_SETUP_TOKEN?.trim() ?? "";
|
||||
const SETUP_TOKEN_VALUE = process.env.OPENCLAW_LIVE_SETUP_TOKEN_VALUE?.trim() ?? "";
|
||||
const SETUP_TOKEN_PROFILE = process.env.OPENCLAW_LIVE_SETUP_TOKEN_PROFILE?.trim() ?? "";
|
||||
const SETUP_TOKEN_MODEL = process.env.OPENCLAW_LIVE_SETUP_TOKEN_MODEL?.trim() ?? "";
|
||||
|
||||
const ENABLED = LIVE && Boolean(SETUP_TOKEN_RAW || SETUP_TOKEN_VALUE || SETUP_TOKEN_PROFILE);
|
||||
const describeLive = ENABLED ? describe : describe.skip;
|
||||
@@ -70,7 +70,7 @@ async function resolveTokenSource(): Promise<TokenSource> {
|
||||
if (error) {
|
||||
throw new Error(`Invalid setup-token: ${error}`);
|
||||
}
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-setup-token-"));
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-setup-token-"));
|
||||
const profileId = `anthropic:setup-token-live-${randomUUID()}`;
|
||||
const store = ensureAuthProfileStore(tempDir, {
|
||||
allowKeychainPrompt: false,
|
||||
@@ -90,7 +90,7 @@ async function resolveTokenSource(): Promise<TokenSource> {
|
||||
};
|
||||
}
|
||||
|
||||
const agentDir = resolveMoltbotAgentDir();
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const store = ensureAuthProfileStore(agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
@@ -108,13 +108,13 @@ async function resolveTokenSource(): Promise<TokenSource> {
|
||||
|
||||
if (SETUP_TOKEN_RAW && SETUP_TOKEN_RAW !== "1" && SETUP_TOKEN_RAW !== "auto") {
|
||||
throw new Error(
|
||||
"CLAWDBOT_LIVE_SETUP_TOKEN did not look like a setup-token. Use CLAWDBOT_LIVE_SETUP_TOKEN_VALUE for raw tokens.",
|
||||
"OPENCLAW_LIVE_SETUP_TOKEN did not look like a setup-token. Use OPENCLAW_LIVE_SETUP_TOKEN_VALUE for raw tokens.",
|
||||
);
|
||||
}
|
||||
|
||||
if (candidates.length === 0) {
|
||||
throw new Error(
|
||||
"No Anthropics setup-token profiles found. Set CLAWDBOT_LIVE_SETUP_TOKEN_VALUE or CLAWDBOT_LIVE_SETUP_TOKEN_PROFILE.",
|
||||
"No Anthropics setup-token profiles found. Set OPENCLAW_LIVE_SETUP_TOKEN_VALUE or OPENCLAW_LIVE_SETUP_TOKEN_PROFILE.",
|
||||
);
|
||||
}
|
||||
return { agentDir, profileId: pickSetupTokenProfile(candidates) };
|
||||
@@ -153,7 +153,7 @@ describeLive("live anthropic setup-token", () => {
|
||||
const tokenSource = await resolveTokenSource();
|
||||
try {
|
||||
const cfg = loadConfig();
|
||||
await ensureMoltbotModelsJson(cfg, tokenSource.agentDir);
|
||||
await ensureOpenClawModelsJson(cfg, tokenSource.agentDir);
|
||||
|
||||
const authStorage = discoverAuthStorage(tokenSource.agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, tokenSource.agentDir);
|
||||
|
||||
@@ -6,7 +6,7 @@ import { describe, expect, it } from "vitest";
|
||||
import { applyPatch } from "./apply-patch.js";
|
||||
|
||||
async function withTempDir<T>(fn: (dir: string) => Promise<T>) {
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-patch-"));
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-patch-"));
|
||||
try {
|
||||
return await fn(dir);
|
||||
} finally {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
type AuthProfileCredential,
|
||||
type AuthProfileStore,
|
||||
@@ -76,7 +76,7 @@ function buildProfileHealth(params: {
|
||||
profileId: string;
|
||||
credential: AuthProfileCredential;
|
||||
store: AuthProfileStore;
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
now: number;
|
||||
warnAfterMs: number;
|
||||
}): AuthProfileHealth {
|
||||
@@ -138,7 +138,7 @@ function buildProfileHealth(params: {
|
||||
|
||||
export function buildAuthHealthSummary(params: {
|
||||
store: AuthProfileStore;
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
warnAfterMs?: number;
|
||||
providers?: string[];
|
||||
}): AuthHealthSummary {
|
||||
|
||||
@@ -11,8 +11,8 @@ import {
|
||||
import { CHUTES_TOKEN_ENDPOINT, type ChutesStoredOAuth } from "./chutes-oauth.js";
|
||||
|
||||
describe("auth-profiles (chutes)", () => {
|
||||
const previousStateDir = process.env.CLAWDBOT_STATE_DIR;
|
||||
const previousAgentDir = process.env.CLAWDBOT_AGENT_DIR;
|
||||
const previousStateDir = process.env.OPENCLAW_STATE_DIR;
|
||||
const previousAgentDir = process.env.OPENCLAW_AGENT_DIR;
|
||||
const previousPiAgentDir = process.env.PI_CODING_AGENT_DIR;
|
||||
const previousChutesClientId = process.env.CHUTES_CLIENT_ID;
|
||||
let tempDir: string | null = null;
|
||||
@@ -23,10 +23,10 @@ describe("auth-profiles (chutes)", () => {
|
||||
await fs.rm(tempDir, { recursive: true, force: true });
|
||||
tempDir = null;
|
||||
}
|
||||
if (previousStateDir === undefined) delete process.env.CLAWDBOT_STATE_DIR;
|
||||
else process.env.CLAWDBOT_STATE_DIR = previousStateDir;
|
||||
if (previousAgentDir === undefined) delete process.env.CLAWDBOT_AGENT_DIR;
|
||||
else process.env.CLAWDBOT_AGENT_DIR = previousAgentDir;
|
||||
if (previousStateDir === undefined) delete process.env.OPENCLAW_STATE_DIR;
|
||||
else process.env.OPENCLAW_STATE_DIR = previousStateDir;
|
||||
if (previousAgentDir === undefined) delete process.env.OPENCLAW_AGENT_DIR;
|
||||
else process.env.OPENCLAW_AGENT_DIR = previousAgentDir;
|
||||
if (previousPiAgentDir === undefined) delete process.env.PI_CODING_AGENT_DIR;
|
||||
else process.env.PI_CODING_AGENT_DIR = previousPiAgentDir;
|
||||
if (previousChutesClientId === undefined) delete process.env.CHUTES_CLIENT_ID;
|
||||
@@ -34,10 +34,10 @@ describe("auth-profiles (chutes)", () => {
|
||||
});
|
||||
|
||||
it("refreshes expired Chutes OAuth credentials", async () => {
|
||||
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-chutes-"));
|
||||
process.env.CLAWDBOT_STATE_DIR = tempDir;
|
||||
process.env.CLAWDBOT_AGENT_DIR = path.join(tempDir, "agents", "main", "agent");
|
||||
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
|
||||
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-chutes-"));
|
||||
process.env.OPENCLAW_STATE_DIR = tempDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = path.join(tempDir, "agents", "main", "agent");
|
||||
process.env.PI_CODING_AGENT_DIR = process.env.OPENCLAW_AGENT_DIR;
|
||||
|
||||
const authProfilePath = path.join(tempDir, "agents", "main", "agent", "auth-profiles.json");
|
||||
await fs.mkdir(path.dirname(authProfilePath), { recursive: true });
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AUTH_STORE_VERSION } from "./auth-profiles/constants.js";
|
||||
|
||||
describe("ensureAuthProfileStore", () => {
|
||||
it("migrates legacy auth.json and deletes it (PR #368)", () => {
|
||||
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-auth-profiles-"));
|
||||
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-auth-profiles-"));
|
||||
try {
|
||||
const legacyPath = path.join(agentDir, "auth.json");
|
||||
fs.writeFileSync(
|
||||
@@ -48,8 +48,8 @@ describe("ensureAuthProfileStore", () => {
|
||||
});
|
||||
|
||||
it("merges main auth profiles into agent store and keeps agent overrides", () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-auth-merge-"));
|
||||
const previousAgentDir = process.env.CLAWDBOT_AGENT_DIR;
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-auth-merge-"));
|
||||
const previousAgentDir = process.env.OPENCLAW_AGENT_DIR;
|
||||
const previousPiAgentDir = process.env.PI_CODING_AGENT_DIR;
|
||||
try {
|
||||
const mainDir = path.join(root, "main-agent");
|
||||
@@ -57,7 +57,7 @@ describe("ensureAuthProfileStore", () => {
|
||||
fs.mkdirSync(mainDir, { recursive: true });
|
||||
fs.mkdirSync(agentDir, { recursive: true });
|
||||
|
||||
process.env.CLAWDBOT_AGENT_DIR = mainDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = mainDir;
|
||||
process.env.PI_CODING_AGENT_DIR = mainDir;
|
||||
|
||||
const mainStore = {
|
||||
@@ -110,9 +110,9 @@ describe("ensureAuthProfileStore", () => {
|
||||
});
|
||||
} finally {
|
||||
if (previousAgentDir === undefined) {
|
||||
delete process.env.CLAWDBOT_AGENT_DIR;
|
||||
delete process.env.OPENCLAW_AGENT_DIR;
|
||||
} else {
|
||||
process.env.CLAWDBOT_AGENT_DIR = previousAgentDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = previousAgentDir;
|
||||
}
|
||||
if (previousPiAgentDir === undefined) {
|
||||
delete process.env.PI_CODING_AGENT_DIR;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ensureAuthProfileStore, markAuthProfileFailure } from "./auth-profiles.
|
||||
|
||||
describe("markAuthProfileFailure", () => {
|
||||
it("disables billing failures for ~5 hours by default", async () => {
|
||||
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-auth-"));
|
||||
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-auth-"));
|
||||
try {
|
||||
const authPath = path.join(agentDir, "auth-profiles.json");
|
||||
fs.writeFileSync(
|
||||
@@ -42,7 +42,7 @@ describe("markAuthProfileFailure", () => {
|
||||
}
|
||||
});
|
||||
it("honors per-provider billing backoff overrides", async () => {
|
||||
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-auth-"));
|
||||
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-auth-"));
|
||||
try {
|
||||
const authPath = path.join(agentDir, "auth-profiles.json");
|
||||
fs.writeFileSync(
|
||||
@@ -86,7 +86,7 @@ describe("markAuthProfileFailure", () => {
|
||||
}
|
||||
});
|
||||
it("resets backoff counters outside the failure window", async () => {
|
||||
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-auth-"));
|
||||
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-auth-"));
|
||||
try {
|
||||
const authPath = path.join(agentDir, "auth-profiles.json");
|
||||
const now = Date.now();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { AuthProfileStore } from "./types.js";
|
||||
|
||||
export function resolveAuthProfileDisplayLabel(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
store: AuthProfileStore;
|
||||
profileId: string;
|
||||
}): string {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { formatCliCommand } from "../../cli/command-format.js";
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { normalizeProviderId } from "../model-selection.js";
|
||||
import { listProfilesForProvider } from "./profiles.js";
|
||||
import { suggestOAuthProfileIdForLegacyDefault } from "./repair.js";
|
||||
import type { AuthProfileStore } from "./types.js";
|
||||
|
||||
export function formatAuthDoctorHint(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
store: AuthProfileStore;
|
||||
provider: string;
|
||||
profileId?: string;
|
||||
@@ -38,6 +38,6 @@ export function formatAuthDoctorHint(params: {
|
||||
}`,
|
||||
`- auth store oauth profiles: ${storeOauthProfiles || "(none)"}`,
|
||||
`- suggested profile: ${suggested}`,
|
||||
`Fix: run "${formatCliCommand("moltbot doctor --yes")}"`,
|
||||
`Fix: run "${formatCliCommand("openclaw doctor --yes")}"`,
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import { ensureAuthProfileStore } from "./store.js";
|
||||
import type { AuthProfileStore } from "./types.js";
|
||||
|
||||
describe("resolveApiKeyForProfile fallback to main agent", () => {
|
||||
const previousStateDir = process.env.CLAWDBOT_STATE_DIR;
|
||||
const previousAgentDir = process.env.CLAWDBOT_AGENT_DIR;
|
||||
const previousStateDir = process.env.OPENCLAW_STATE_DIR;
|
||||
const previousAgentDir = process.env.OPENCLAW_AGENT_DIR;
|
||||
const previousPiAgentDir = process.env.PI_CODING_AGENT_DIR;
|
||||
let tmpDir: string;
|
||||
let mainAgentDir: string;
|
||||
@@ -21,9 +21,9 @@ describe("resolveApiKeyForProfile fallback to main agent", () => {
|
||||
await fs.mkdir(mainAgentDir, { recursive: true });
|
||||
await fs.mkdir(secondaryAgentDir, { recursive: true });
|
||||
|
||||
// Set environment variables so resolveMoltbotAgentDir() returns mainAgentDir
|
||||
process.env.CLAWDBOT_STATE_DIR = tmpDir;
|
||||
process.env.CLAWDBOT_AGENT_DIR = mainAgentDir;
|
||||
// Set environment variables so resolveOpenClawAgentDir() returns mainAgentDir
|
||||
process.env.OPENCLAW_STATE_DIR = tmpDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = mainAgentDir;
|
||||
process.env.PI_CODING_AGENT_DIR = mainAgentDir;
|
||||
});
|
||||
|
||||
@@ -31,10 +31,10 @@ describe("resolveApiKeyForProfile fallback to main agent", () => {
|
||||
vi.unstubAllGlobals();
|
||||
|
||||
// Restore original environment
|
||||
if (previousStateDir === undefined) delete process.env.CLAWDBOT_STATE_DIR;
|
||||
else process.env.CLAWDBOT_STATE_DIR = previousStateDir;
|
||||
if (previousAgentDir === undefined) delete process.env.CLAWDBOT_AGENT_DIR;
|
||||
else process.env.CLAWDBOT_AGENT_DIR = previousAgentDir;
|
||||
if (previousStateDir === undefined) delete process.env.OPENCLAW_STATE_DIR;
|
||||
else process.env.OPENCLAW_STATE_DIR = previousStateDir;
|
||||
if (previousAgentDir === undefined) delete process.env.OPENCLAW_AGENT_DIR;
|
||||
else process.env.OPENCLAW_AGENT_DIR = previousAgentDir;
|
||||
if (previousPiAgentDir === undefined) delete process.env.PI_CODING_AGENT_DIR;
|
||||
else process.env.PI_CODING_AGENT_DIR = previousPiAgentDir;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getOAuthApiKey, type OAuthCredentials, type OAuthProvider } from "@mariozechner/pi-ai";
|
||||
import lockfile from "proper-lockfile";
|
||||
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { refreshChutesTokens } from "../chutes-oauth.js";
|
||||
import { refreshQwenPortalCredentials } from "../../providers/qwen-portal-oauth.js";
|
||||
import { AUTH_STORE_LOCK_OPTIONS, log } from "./constants.js";
|
||||
@@ -84,7 +84,7 @@ async function refreshOAuthTokenWithLock(params: {
|
||||
}
|
||||
|
||||
async function tryResolveOAuthProfile(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
store: AuthProfileStore;
|
||||
profileId: string;
|
||||
agentDir?: string;
|
||||
@@ -117,7 +117,7 @@ async function tryResolveOAuthProfile(params: {
|
||||
}
|
||||
|
||||
export async function resolveApiKeyForProfile(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
store: AuthProfileStore;
|
||||
profileId: string;
|
||||
agentDir?: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { normalizeProviderId } from "../model-selection.js";
|
||||
import { listProfilesForProvider } from "./profiles.js";
|
||||
import type { AuthProfileStore } from "./types.js";
|
||||
@@ -16,7 +16,7 @@ function resolveProfileUnusableUntil(stats: {
|
||||
}
|
||||
|
||||
export function resolveAuthProfileOrder(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
store: AuthProfileStore;
|
||||
provider: string;
|
||||
preferredProfile?: string;
|
||||
|
||||
@@ -3,17 +3,17 @@ import path from "node:path";
|
||||
|
||||
import { saveJsonFile } from "../../infra/json-file.js";
|
||||
import { resolveUserPath } from "../../utils.js";
|
||||
import { resolveMoltbotAgentDir } from "../agent-paths.js";
|
||||
import { resolveOpenClawAgentDir } from "../agent-paths.js";
|
||||
import { AUTH_PROFILE_FILENAME, AUTH_STORE_VERSION, LEGACY_AUTH_FILENAME } from "./constants.js";
|
||||
import type { AuthProfileStore } from "./types.js";
|
||||
|
||||
export function resolveAuthStorePath(agentDir?: string): string {
|
||||
const resolved = resolveUserPath(agentDir ?? resolveMoltbotAgentDir());
|
||||
const resolved = resolveUserPath(agentDir ?? resolveOpenClawAgentDir());
|
||||
return path.join(resolved, AUTH_PROFILE_FILENAME);
|
||||
}
|
||||
|
||||
export function resolveLegacyAuthStorePath(agentDir?: string): string {
|
||||
const resolved = resolveUserPath(agentDir ?? resolveMoltbotAgentDir());
|
||||
const resolved = resolveUserPath(agentDir ?? resolveOpenClawAgentDir());
|
||||
return path.join(resolved, LEGACY_AUTH_FILENAME);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { AuthProfileConfig } from "../../config/types.js";
|
||||
import { normalizeProviderId } from "../model-selection.js";
|
||||
import { listProfilesForProvider } from "./profiles.js";
|
||||
@@ -17,7 +17,7 @@ function isEmailLike(value: string): boolean {
|
||||
}
|
||||
|
||||
export function suggestOAuthProfileIdForLegacyDefault(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
store: AuthProfileStore;
|
||||
provider: string;
|
||||
legacyProfileId: string;
|
||||
@@ -64,7 +64,7 @@ export function suggestOAuthProfileIdForLegacyDefault(params: {
|
||||
}
|
||||
|
||||
export function repairOAuthProfileIdMismatch(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
store: AuthProfileStore;
|
||||
provider: string;
|
||||
legacyProfileId?: string;
|
||||
@@ -123,7 +123,7 @@ export function repairOAuthProfileIdMismatch(params: {
|
||||
return { ...order, [resolvedKey]: deduped };
|
||||
})();
|
||||
|
||||
const nextCfg: MoltbotConfig = {
|
||||
const nextCfg: OpenClawConfig = {
|
||||
...params.cfg,
|
||||
auth: {
|
||||
...params.cfg.auth,
|
||||
|
||||
@@ -3,7 +3,7 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { SessionEntry } from "../../config/sessions.js";
|
||||
import { resolveSessionAuthProfileOverride } from "./session-override.js";
|
||||
|
||||
@@ -23,9 +23,9 @@ async function writeAuthStore(agentDir: string) {
|
||||
|
||||
describe("resolveSessionAuthProfileOverride", () => {
|
||||
it("keeps user override when provider alias differs", async () => {
|
||||
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
|
||||
const prevStateDir = process.env.CLAWDBOT_STATE_DIR;
|
||||
process.env.CLAWDBOT_STATE_DIR = tmpDir;
|
||||
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-auth-"));
|
||||
const prevStateDir = process.env.OPENCLAW_STATE_DIR;
|
||||
process.env.OPENCLAW_STATE_DIR = tmpDir;
|
||||
try {
|
||||
const agentDir = path.join(tmpDir, "agent");
|
||||
await fs.mkdir(agentDir, { recursive: true });
|
||||
@@ -40,7 +40,7 @@ describe("resolveSessionAuthProfileOverride", () => {
|
||||
const sessionStore = { "agent:main:main": sessionEntry };
|
||||
|
||||
const resolved = await resolveSessionAuthProfileOverride({
|
||||
cfg: {} as MoltbotConfig,
|
||||
cfg: {} as OpenClawConfig,
|
||||
provider: "z.ai",
|
||||
agentDir,
|
||||
sessionEntry,
|
||||
@@ -53,8 +53,8 @@ describe("resolveSessionAuthProfileOverride", () => {
|
||||
expect(resolved).toBe("zai:work");
|
||||
expect(sessionEntry.authProfileOverride).toBe("zai:work");
|
||||
} finally {
|
||||
if (prevStateDir === undefined) delete process.env.CLAWDBOT_STATE_DIR;
|
||||
else process.env.CLAWDBOT_STATE_DIR = prevStateDir;
|
||||
if (prevStateDir === undefined) delete process.env.OPENCLAW_STATE_DIR;
|
||||
else process.env.OPENCLAW_STATE_DIR = prevStateDir;
|
||||
await fs.rm(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { updateSessionStore, type SessionEntry } from "../../config/sessions.js";
|
||||
import { normalizeProviderId } from "../model-selection.js";
|
||||
import {
|
||||
@@ -37,7 +37,7 @@ export async function clearSessionAuthProfileOverride(params: {
|
||||
}
|
||||
|
||||
export async function resolveSessionAuthProfileOverride(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
provider: string;
|
||||
agentDir: string;
|
||||
sessionEntry?: SessionEntry;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { OAuthCredentials } from "@mariozechner/pi-ai";
|
||||
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
|
||||
export type ApiKeyCredential = {
|
||||
type: "api_key";
|
||||
@@ -12,7 +12,7 @@ export type ApiKeyCredential = {
|
||||
export type TokenCredential = {
|
||||
/**
|
||||
* Static bearer-style token (often OAuth access token / PAT).
|
||||
* Not refreshable by moltbot (unlike `type: "oauth"`).
|
||||
* Not refreshable by OpenClaw (unlike `type: "oauth"`).
|
||||
*/
|
||||
type: "token";
|
||||
provider: string;
|
||||
@@ -65,7 +65,7 @@ export type AuthProfileStore = {
|
||||
};
|
||||
|
||||
export type AuthProfileIdRepairResult = {
|
||||
config: MoltbotConfig;
|
||||
config: OpenClawConfig;
|
||||
changes: string[];
|
||||
migrated: boolean;
|
||||
fromProfileId?: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { normalizeProviderId } from "../model-selection.js";
|
||||
import { saveAuthProfileStore, updateAuthProfileStoreWithLock } from "./store.js";
|
||||
import type { AuthProfileFailureReason, AuthProfileStore, ProfileUsageStats } from "./types.js";
|
||||
@@ -82,7 +82,7 @@ type ResolvedAuthCooldownConfig = {
|
||||
};
|
||||
|
||||
function resolveAuthCooldownConfig(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
providerId: string;
|
||||
}): ResolvedAuthCooldownConfig {
|
||||
const defaults = {
|
||||
@@ -192,7 +192,7 @@ export async function markAuthProfileFailure(params: {
|
||||
store: AuthProfileStore;
|
||||
profileId: string;
|
||||
reason: AuthProfileFailureReason;
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
agentDir?: string;
|
||||
}): Promise<void> {
|
||||
const { store, profileId, reason, agentDir, cfg } = params;
|
||||
|
||||
@@ -21,7 +21,7 @@ describe("exec approvals", () => {
|
||||
beforeEach(async () => {
|
||||
previousHome = process.env.HOME;
|
||||
previousUserProfile = process.env.USERPROFILE;
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-test-"));
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-test-"));
|
||||
process.env.HOME = tempDir;
|
||||
// Windows uses USERPROFILE for os.homedir()
|
||||
process.env.USERPROFILE = tempDir;
|
||||
@@ -80,7 +80,7 @@ describe("exec approvals", () => {
|
||||
|
||||
it("skips approval when node allowlist is satisfied", async () => {
|
||||
const { callGatewayTool } = await import("./tools/gateway.js");
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-test-bin-"));
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-test-bin-"));
|
||||
const binDir = path.join(tempDir, "bin");
|
||||
await fs.mkdir(binDir, { recursive: true });
|
||||
const exeName = process.platform === "win32" ? "tool.cmd" : "tool";
|
||||
|
||||
@@ -64,7 +64,7 @@ const DEFAULT_MAX_OUTPUT = clampNumber(
|
||||
200_000,
|
||||
);
|
||||
const DEFAULT_PENDING_MAX_OUTPUT = clampNumber(
|
||||
readEnvInt("CLAWDBOT_BASH_PENDING_MAX_OUTPUT_CHARS"),
|
||||
readEnvInt("OPENCLAW_BASH_PENDING_MAX_OUTPUT_CHARS"),
|
||||
200_000,
|
||||
1_000,
|
||||
200_000,
|
||||
|
||||
@@ -63,14 +63,14 @@ export function buildDockerExecArgs(params: {
|
||||
const hasCustomPath = typeof params.env.PATH === "string" && params.env.PATH.length > 0;
|
||||
if (hasCustomPath) {
|
||||
// Avoid interpolating PATH into the shell command; pass it via env instead.
|
||||
args.push("-e", `CLAWDBOT_PREPEND_PATH=${params.env.PATH}`);
|
||||
args.push("-e", `OPENCLAW_PREPEND_PATH=${params.env.PATH}`);
|
||||
}
|
||||
// Login shell (-l) sources /etc/profile which resets PATH to a minimal set,
|
||||
// overriding both Docker ENV and -e PATH=... environment variables.
|
||||
// Prepend custom PATH after profile sourcing to ensure custom tools are accessible
|
||||
// while preserving system paths that /etc/profile may have added.
|
||||
const pathExport = hasCustomPath
|
||||
? 'export PATH="${CLAWDBOT_PREPEND_PATH}:$PATH"; unset CLAWDBOT_PREPEND_PATH; '
|
||||
? 'export PATH="${OPENCLAW_PREPEND_PATH}:$PATH"; unset OPENCLAW_PREPEND_PATH; '
|
||||
: "";
|
||||
args.push(params.containerName, "sh", "-lc", `${pathExport}${params.command}`);
|
||||
return args;
|
||||
|
||||
@@ -26,7 +26,7 @@ const resolveShellFromPath = (name: string) => {
|
||||
};
|
||||
const defaultShell = isWin
|
||||
? undefined
|
||||
: process.env.CLAWDBOT_TEST_SHELL || resolveShellFromPath("bash") || process.env.SHELL || "sh";
|
||||
: process.env.OPENCLAW_TEST_SHELL || resolveShellFromPath("bash") || process.env.SHELL || "sh";
|
||||
// PowerShell: Start-Sleep for delays, ; for command separation, $null for null device
|
||||
const shortDelayCmd = isWin ? "Start-Sleep -Milliseconds 50" : "sleep 0.05";
|
||||
const yieldDelayCmd = isWin ? "Start-Sleep -Milliseconds 200" : "sleep 0.2";
|
||||
@@ -337,16 +337,16 @@ describe("buildDockerExecArgs", () => {
|
||||
});
|
||||
|
||||
const commandArg = args[args.length - 1];
|
||||
expect(args).toContain("CLAWDBOT_PREPEND_PATH=/custom/bin:/usr/local/bin:/usr/bin");
|
||||
expect(commandArg).toContain('export PATH="${CLAWDBOT_PREPEND_PATH}:$PATH"');
|
||||
expect(args).toContain("OPENCLAW_PREPEND_PATH=/custom/bin:/usr/local/bin:/usr/bin");
|
||||
expect(commandArg).toContain('export PATH="${OPENCLAW_PREPEND_PATH}:$PATH"');
|
||||
expect(commandArg).toContain("echo hello");
|
||||
expect(commandArg).toBe(
|
||||
'export PATH="${CLAWDBOT_PREPEND_PATH}:$PATH"; unset CLAWDBOT_PREPEND_PATH; echo hello',
|
||||
'export PATH="${OPENCLAW_PREPEND_PATH}:$PATH"; unset OPENCLAW_PREPEND_PATH; echo hello',
|
||||
);
|
||||
});
|
||||
|
||||
it("does not interpolate PATH into the shell command", () => {
|
||||
const injectedPath = "$(touch /tmp/moltbot-path-injection)";
|
||||
const injectedPath = "$(touch /tmp/openclaw-path-injection)";
|
||||
const args = buildDockerExecArgs({
|
||||
containerName: "test-container",
|
||||
command: "echo hello",
|
||||
@@ -358,9 +358,9 @@ describe("buildDockerExecArgs", () => {
|
||||
});
|
||||
|
||||
const commandArg = args[args.length - 1];
|
||||
expect(args).toContain(`CLAWDBOT_PREPEND_PATH=${injectedPath}`);
|
||||
expect(args).toContain(`OPENCLAW_PREPEND_PATH=${injectedPath}`);
|
||||
expect(commandArg).not.toContain(injectedPath);
|
||||
expect(commandArg).toContain("CLAWDBOT_PREPEND_PATH");
|
||||
expect(commandArg).toContain("OPENCLAW_PREPEND_PATH");
|
||||
});
|
||||
|
||||
it("does not add PATH export when PATH is not in env", () => {
|
||||
|
||||
@@ -28,7 +28,7 @@ describe("resolveBootstrapFilesForRun", () => {
|
||||
];
|
||||
});
|
||||
|
||||
const workspaceDir = await makeTempWorkspace("moltbot-bootstrap-");
|
||||
const workspaceDir = await makeTempWorkspace("openclaw-bootstrap-");
|
||||
const files = await resolveBootstrapFilesForRun({ workspaceDir });
|
||||
|
||||
expect(files.some((file) => file.name === "EXTRA.md")).toBe(true);
|
||||
@@ -53,7 +53,7 @@ describe("resolveBootstrapContextForRun", () => {
|
||||
];
|
||||
});
|
||||
|
||||
const workspaceDir = await makeTempWorkspace("moltbot-bootstrap-");
|
||||
const workspaceDir = await makeTempWorkspace("openclaw-bootstrap-");
|
||||
const result = await resolveBootstrapContextForRun({ workspaceDir });
|
||||
const extra = result.contextFiles.find((file) => file.path === "EXTRA.md");
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { applyBootstrapHookOverrides } from "./bootstrap-hooks.js";
|
||||
import {
|
||||
filterBootstrapFilesForSession,
|
||||
@@ -18,7 +18,7 @@ export function makeBootstrapWarn(params: {
|
||||
|
||||
export async function resolveBootstrapFilesForRun(params: {
|
||||
workspaceDir: string;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
sessionKey?: string;
|
||||
sessionId?: string;
|
||||
agentId?: string;
|
||||
@@ -40,7 +40,7 @@ export async function resolveBootstrapFilesForRun(params: {
|
||||
|
||||
export async function resolveBootstrapContextForRun(params: {
|
||||
workspaceDir: string;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
sessionKey?: string;
|
||||
sessionId?: string;
|
||||
agentId?: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { createInternalHookEvent, triggerInternalHook } from "../hooks/internal-hooks.js";
|
||||
import type { AgentBootstrapHookContext } from "../hooks/internal-hooks.js";
|
||||
import { resolveAgentIdFromSessionKey } from "../routing/session-key.js";
|
||||
@@ -7,7 +7,7 @@ import type { WorkspaceBootstrapFile } from "./workspace.js";
|
||||
export async function applyBootstrapHookOverrides(params: {
|
||||
files: WorkspaceBootstrapFile[];
|
||||
workspaceDir: string;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
sessionKey?: string;
|
||||
sessionId?: string;
|
||||
agentId?: string;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
import { createCacheTrace } from "./cache-trace.js";
|
||||
|
||||
describe("createCacheTrace", () => {
|
||||
it("returns null when diagnostics cache tracing is disabled", () => {
|
||||
const trace = createCacheTrace({
|
||||
cfg: {} as MoltbotConfig,
|
||||
cfg: {} as OpenClawConfig,
|
||||
env: {},
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@ describe("createCacheTrace", () => {
|
||||
diagnostics: {
|
||||
cacheTrace: {
|
||||
enabled: true,
|
||||
filePath: "~/.clawdbot/logs/cache-trace.jsonl",
|
||||
filePath: "~/.openclaw/logs/cache-trace.jsonl",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -33,7 +33,7 @@ describe("createCacheTrace", () => {
|
||||
});
|
||||
|
||||
expect(trace).not.toBeNull();
|
||||
expect(trace?.filePath).toBe(resolveUserPath("~/.clawdbot/logs/cache-trace.jsonl"));
|
||||
expect(trace?.filePath).toBe(resolveUserPath("~/.openclaw/logs/cache-trace.jsonl"));
|
||||
|
||||
trace?.recordStage("session:loaded", {
|
||||
messages: [],
|
||||
@@ -80,7 +80,7 @@ describe("createCacheTrace", () => {
|
||||
},
|
||||
},
|
||||
env: {
|
||||
CLAWDBOT_CACHE_TRACE: "0",
|
||||
OPENCLAW_CACHE_TRACE: "0",
|
||||
},
|
||||
writer: {
|
||||
filePath: "memory",
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from "node:path";
|
||||
import type { AgentMessage, StreamFn } from "@mariozechner/pi-agent-core";
|
||||
import type { Api, Model } from "@mariozechner/pi-ai";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveStateDir } from "../config/paths.js";
|
||||
import { parseBooleanValue } from "../utils/boolean.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
@@ -52,7 +52,7 @@ export type CacheTrace = {
|
||||
};
|
||||
|
||||
type CacheTraceInit = {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
runId?: string;
|
||||
sessionId?: string;
|
||||
@@ -82,17 +82,17 @@ const writers = new Map<string, CacheTraceWriter>();
|
||||
function resolveCacheTraceConfig(params: CacheTraceInit): CacheTraceConfig {
|
||||
const env = params.env ?? process.env;
|
||||
const config = params.cfg?.diagnostics?.cacheTrace;
|
||||
const envEnabled = parseBooleanValue(env.CLAWDBOT_CACHE_TRACE);
|
||||
const envEnabled = parseBooleanValue(env.OPENCLAW_CACHE_TRACE);
|
||||
const enabled = envEnabled ?? config?.enabled ?? false;
|
||||
const fileOverride = config?.filePath?.trim() || env.CLAWDBOT_CACHE_TRACE_FILE?.trim();
|
||||
const fileOverride = config?.filePath?.trim() || env.OPENCLAW_CACHE_TRACE_FILE?.trim();
|
||||
const filePath = fileOverride
|
||||
? resolveUserPath(fileOverride)
|
||||
: path.join(resolveStateDir(env), "logs", "cache-trace.jsonl");
|
||||
|
||||
const includeMessages =
|
||||
parseBooleanValue(env.CLAWDBOT_CACHE_TRACE_MESSAGES) ?? config?.includeMessages;
|
||||
const includePrompt = parseBooleanValue(env.CLAWDBOT_CACHE_TRACE_PROMPT) ?? config?.includePrompt;
|
||||
const includeSystem = parseBooleanValue(env.CLAWDBOT_CACHE_TRACE_SYSTEM) ?? config?.includeSystem;
|
||||
parseBooleanValue(env.OPENCLAW_CACHE_TRACE_MESSAGES) ?? config?.includeMessages;
|
||||
const includePrompt = parseBooleanValue(env.OPENCLAW_CACHE_TRACE_PROMPT) ?? config?.includePrompt;
|
||||
const includeSystem = parseBooleanValue(env.OPENCLAW_CACHE_TRACE_SYSTEM) ?? config?.includeSystem;
|
||||
|
||||
return {
|
||||
enabled,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { ChannelPlugin } from "../channels/plugins/types.js";
|
||||
import { setActivePluginRegistry } from "../plugins/runtime.js";
|
||||
import { createTestRegistry } from "../test-utils/channel-plugins.js";
|
||||
@@ -43,7 +43,7 @@ describe("channel tools", () => {
|
||||
});
|
||||
|
||||
it("skips crashing plugins and logs once", () => {
|
||||
const cfg = {} as MoltbotConfig;
|
||||
const cfg = {} as OpenClawConfig;
|
||||
expect(listAllChannelSupportedActions({ cfg })).toEqual([]);
|
||||
expect(errorSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
ChannelMessageActionName,
|
||||
ChannelPlugin,
|
||||
} from "../channels/plugins/types.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
|
||||
/**
|
||||
@@ -14,13 +14,13 @@ import { defaultRuntime } from "../runtime.js";
|
||||
* Returns an empty array if channel is not found or has no actions configured.
|
||||
*/
|
||||
export function listChannelSupportedActions(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
channel?: string;
|
||||
}): ChannelMessageActionName[] {
|
||||
if (!params.channel) return [];
|
||||
const plugin = getChannelPlugin(params.channel as Parameters<typeof getChannelPlugin>[0]);
|
||||
if (!plugin?.actions?.listActions) return [];
|
||||
const cfg = params.cfg ?? ({} as MoltbotConfig);
|
||||
const cfg = params.cfg ?? ({} as OpenClawConfig);
|
||||
return runPluginListActions(plugin, cfg);
|
||||
}
|
||||
|
||||
@@ -28,12 +28,12 @@ export function listChannelSupportedActions(params: {
|
||||
* Get the list of all supported message actions across all configured channels.
|
||||
*/
|
||||
export function listAllChannelSupportedActions(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
}): ChannelMessageActionName[] {
|
||||
const actions = new Set<ChannelMessageActionName>();
|
||||
for (const plugin of listChannelPlugins()) {
|
||||
if (!plugin.actions?.listActions) continue;
|
||||
const cfg = params.cfg ?? ({} as MoltbotConfig);
|
||||
const cfg = params.cfg ?? ({} as OpenClawConfig);
|
||||
const channelActions = runPluginListActions(plugin, cfg);
|
||||
for (const action of channelActions) {
|
||||
actions.add(action);
|
||||
@@ -42,7 +42,7 @@ export function listAllChannelSupportedActions(params: {
|
||||
return Array.from(actions);
|
||||
}
|
||||
|
||||
export function listChannelAgentTools(params: { cfg?: MoltbotConfig }): ChannelAgentTool[] {
|
||||
export function listChannelAgentTools(params: { cfg?: OpenClawConfig }): ChannelAgentTool[] {
|
||||
// Channel docking: aggregate channel-owned tools (login, etc.).
|
||||
const tools: ChannelAgentTool[] = [];
|
||||
for (const plugin of listChannelPlugins()) {
|
||||
@@ -55,7 +55,7 @@ export function listChannelAgentTools(params: { cfg?: MoltbotConfig }): ChannelA
|
||||
}
|
||||
|
||||
export function resolveChannelMessageToolHints(params: {
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
channel?: string | null;
|
||||
accountId?: string | null;
|
||||
}): string[] {
|
||||
@@ -64,7 +64,7 @@ export function resolveChannelMessageToolHints(params: {
|
||||
const dock = getChannelDock(channelId);
|
||||
const resolve = dock?.agentPrompt?.messageToolHints;
|
||||
if (!resolve) return [];
|
||||
const cfg = params.cfg ?? ({} as MoltbotConfig);
|
||||
const cfg = params.cfg ?? ({} as OpenClawConfig);
|
||||
return (resolve({ cfg, accountId: params.accountId }) ?? [])
|
||||
.map((entry) => entry.trim())
|
||||
.filter(Boolean);
|
||||
@@ -74,7 +74,7 @@ const loggedListActionErrors = new Set<string>();
|
||||
|
||||
function runPluginListActions(
|
||||
plugin: ChannelPlugin,
|
||||
cfg: MoltbotConfig,
|
||||
cfg: OpenClawConfig,
|
||||
): ChannelMessageActionName[] {
|
||||
if (!plugin.actions?.listActions) return [];
|
||||
try {
|
||||
|
||||
@@ -45,7 +45,7 @@ describe("runClaudeCliAgent", () => {
|
||||
});
|
||||
|
||||
await runClaudeCliAgent({
|
||||
sessionId: "moltbot-session",
|
||||
sessionId: "openclaw-session",
|
||||
sessionFile: "/tmp/session.jsonl",
|
||||
workspaceDir: "/tmp",
|
||||
prompt: "hi",
|
||||
@@ -71,7 +71,7 @@ describe("runClaudeCliAgent", () => {
|
||||
});
|
||||
|
||||
await runClaudeCliAgent({
|
||||
sessionId: "moltbot-session",
|
||||
sessionId: "openclaw-session",
|
||||
sessionFile: "/tmp/session.jsonl",
|
||||
workspaceDir: "/tmp",
|
||||
prompt: "hi",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { CliBackendConfig } from "../config/types.js";
|
||||
import { normalizeProviderId } from "./model-selection.js";
|
||||
|
||||
@@ -103,7 +103,7 @@ function mergeBackendConfig(base: CliBackendConfig, override?: CliBackendConfig)
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveCliBackendIds(cfg?: MoltbotConfig): Set<string> {
|
||||
export function resolveCliBackendIds(cfg?: OpenClawConfig): Set<string> {
|
||||
const ids = new Set<string>([
|
||||
normalizeBackendKey("claude-cli"),
|
||||
normalizeBackendKey("codex-cli"),
|
||||
@@ -117,7 +117,7 @@ export function resolveCliBackendIds(cfg?: MoltbotConfig): Set<string> {
|
||||
|
||||
export function resolveCliBackendConfig(
|
||||
provider: string,
|
||||
cfg?: MoltbotConfig,
|
||||
cfg?: OpenClawConfig,
|
||||
): ResolvedCliBackend | null {
|
||||
const normalized = normalizeBackendKey(provider);
|
||||
const configured = cfg?.agents?.defaults?.cliBackends ?? {};
|
||||
|
||||
@@ -59,7 +59,7 @@ describe("cli credentials", () => {
|
||||
});
|
||||
|
||||
it("falls back to the file store when the keychain update fails", async () => {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-"));
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-"));
|
||||
const credPath = path.join(tempDir, ".claude", ".credentials.json");
|
||||
|
||||
fs.mkdirSync(path.dirname(credPath), { recursive: true, mode: 0o700 });
|
||||
@@ -182,7 +182,7 @@ describe("cli credentials", () => {
|
||||
});
|
||||
|
||||
it("reads Codex credentials from keychain when available", async () => {
|
||||
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-codex-"));
|
||||
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-codex-"));
|
||||
process.env.CODEX_HOME = tempHome;
|
||||
|
||||
const accountHash = "cli|";
|
||||
@@ -211,7 +211,7 @@ describe("cli credentials", () => {
|
||||
});
|
||||
|
||||
it("falls back to Codex auth.json when keychain is unavailable", async () => {
|
||||
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "moltbot-codex-"));
|
||||
const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-codex-"));
|
||||
process.env.CODEX_HOME = tempHome;
|
||||
execSyncMock.mockImplementation(() => {
|
||||
throw new Error("not found");
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { ImageContent } from "@mariozechner/pi-ai";
|
||||
import { resolveHeartbeatPrompt } from "../auto-reply/heartbeat.js";
|
||||
import type { ThinkLevel } from "../auto-reply/thinking.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import { shouldLogVerbose } from "../globals.js";
|
||||
import { createSubsystemLogger } from "../logging/subsystem.js";
|
||||
import { runCommandWithTimeout } from "../process/exec.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
import { resolveMoltbotDocsPath } from "./docs-path.js";
|
||||
import { resolveOpenClawDocsPath } from "./docs-path.js";
|
||||
import { resolveSessionAgentIds } from "./agent-scope.js";
|
||||
import { makeBootstrapWarn, resolveBootstrapContextForRun } from "./bootstrap-files.js";
|
||||
import { resolveCliBackendConfig } from "./cli-backends.js";
|
||||
@@ -37,7 +37,7 @@ export async function runCliAgent(params: {
|
||||
sessionKey?: string;
|
||||
sessionFile: string;
|
||||
workspaceDir: string;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
prompt: string;
|
||||
provider: string;
|
||||
model?: string;
|
||||
@@ -86,7 +86,7 @@ export async function runCliAgent(params: {
|
||||
sessionAgentId === defaultAgentId
|
||||
? resolveHeartbeatPrompt(params.config?.agents?.defaults?.heartbeat?.prompt)
|
||||
: undefined;
|
||||
const docsPath = await resolveMoltbotDocsPath({
|
||||
const docsPath = await resolveOpenClawDocsPath({
|
||||
workspaceDir,
|
||||
argv1: process.argv[1],
|
||||
cwd: process.cwd(),
|
||||
@@ -167,7 +167,7 @@ export async function runCliAgent(params: {
|
||||
log.info(
|
||||
`cli exec: provider=${params.provider} model=${normalizedModel} promptChars=${params.prompt.length}`,
|
||||
);
|
||||
const logOutputText = isTruthyEnvValue(process.env.CLAWDBOT_CLAUDE_CLI_LOG_OUTPUT);
|
||||
const logOutputText = isTruthyEnvValue(process.env.OPENCLAW_CLAUDE_CLI_LOG_OUTPUT);
|
||||
if (logOutputText) {
|
||||
const logArgs: string[] = [];
|
||||
for (let i = 0; i < args.length; i += 1) {
|
||||
@@ -303,7 +303,7 @@ export async function runClaudeCliAgent(params: {
|
||||
sessionKey?: string;
|
||||
sessionFile: string;
|
||||
workspaceDir: string;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
prompt: string;
|
||||
provider?: string;
|
||||
model?: string;
|
||||
|
||||
@@ -6,7 +6,7 @@ import path from "node:path";
|
||||
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
||||
import type { ImageContent } from "@mariozechner/pi-ai";
|
||||
import type { ThinkLevel } from "../../auto-reply/thinking.js";
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { CliBackendConfig } from "../../config/types.js";
|
||||
import { runExec } from "../../process/exec.js";
|
||||
import type { EmbeddedContextFile } from "../pi-embedded-helpers.js";
|
||||
@@ -86,7 +86,7 @@ function tokenToRegex(token: string): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup suspended Moltbot CLI processes that have accumulated.
|
||||
* Cleanup suspended OpenClaw CLI processes that have accumulated.
|
||||
* Only cleans up if there are more than the threshold (default: 10).
|
||||
*/
|
||||
export async function cleanupSuspendedCliProcesses(
|
||||
@@ -148,7 +148,7 @@ export type CliOutput = {
|
||||
usage?: CliUsage;
|
||||
};
|
||||
|
||||
function buildModelAliasLines(cfg?: MoltbotConfig) {
|
||||
function buildModelAliasLines(cfg?: OpenClawConfig) {
|
||||
const models = cfg?.agents?.defaults?.models ?? {};
|
||||
const entries: Array<{ alias: string; model: string }> = [];
|
||||
for (const [keyRaw, entryRaw] of Object.entries(models)) {
|
||||
@@ -165,7 +165,7 @@ function buildModelAliasLines(cfg?: MoltbotConfig) {
|
||||
|
||||
export function buildSystemPrompt(params: {
|
||||
workspaceDir: string;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
defaultThinkLevel?: ThinkLevel;
|
||||
extraSystemPrompt?: string;
|
||||
ownerNumbers?: string[];
|
||||
@@ -187,7 +187,7 @@ export function buildSystemPrompt(params: {
|
||||
workspaceDir: params.workspaceDir,
|
||||
cwd: process.cwd(),
|
||||
runtime: {
|
||||
host: "moltbot",
|
||||
host: "openclaw",
|
||||
os: `${os.type()} ${os.release()}`,
|
||||
arch: os.arch(),
|
||||
node: process.version,
|
||||
@@ -389,7 +389,7 @@ export function appendImagePathsToPrompt(prompt: string, paths: string[]): strin
|
||||
export async function writeCliImages(
|
||||
images: ImageContent[],
|
||||
): Promise<{ paths: string[]; cleanup: () => Promise<void> }> {
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-cli-images-"));
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-cli-images-"));
|
||||
const paths: string[] = [];
|
||||
for (let i = 0; i < images.length; i += 1) {
|
||||
const image = images[i];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
CONTEXT_WINDOW_HARD_MIN_TOKENS,
|
||||
CONTEXT_WINDOW_WARN_BELOW_TOKENS,
|
||||
@@ -72,7 +72,7 @@ describe("context-window-guard", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies MoltbotConfig;
|
||||
} satisfies OpenClawConfig;
|
||||
|
||||
const info = resolveContextWindowInfo({
|
||||
cfg,
|
||||
@@ -89,7 +89,7 @@ describe("context-window-guard", () => {
|
||||
it("falls back to agents.defaults.contextTokens", () => {
|
||||
const cfg = {
|
||||
agents: { defaults: { contextTokens: 20_000 } },
|
||||
} satisfies MoltbotConfig;
|
||||
} satisfies OpenClawConfig;
|
||||
const info = resolveContextWindowInfo({
|
||||
cfg,
|
||||
provider: "anthropic",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
export const CONTEXT_WINDOW_HARD_MIN_TOKENS = 16_000;
|
||||
export const CONTEXT_WINDOW_WARN_BELOW_TOKENS = 32_000;
|
||||
@@ -17,7 +17,7 @@ function normalizePositiveInt(value: unknown): number | null {
|
||||
}
|
||||
|
||||
export function resolveContextWindowInfo(params: {
|
||||
cfg: MoltbotConfig | undefined;
|
||||
cfg: OpenClawConfig | undefined;
|
||||
provider: string;
|
||||
modelId: string;
|
||||
modelContextWindow?: number;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// the agent reports a model id. This includes custom models.json entries.
|
||||
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { resolveMoltbotAgentDir } from "./agent-paths.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
|
||||
type ModelEntry = { id: string; contextWindow?: number };
|
||||
|
||||
@@ -12,8 +12,8 @@ const loadPromise = (async () => {
|
||||
try {
|
||||
const { discoverAuthStorage, discoverModels } = await import("@mariozechner/pi-coding-agent");
|
||||
const cfg = loadConfig();
|
||||
await ensureMoltbotModelsJson(cfg);
|
||||
const agentDir = resolveMoltbotAgentDir();
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, agentDir);
|
||||
const models = modelRegistry.getAll() as ModelEntry[];
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
import { resolveMoltbotPackageRoot } from "../infra/moltbot-root.js";
|
||||
import { resolveOpenClawPackageRoot } from "../infra/openclaw-root.js";
|
||||
|
||||
export async function resolveMoltbotDocsPath(params: {
|
||||
export async function resolveOpenClawDocsPath(params: {
|
||||
workspaceDir?: string;
|
||||
argv1?: string;
|
||||
cwd?: string;
|
||||
@@ -15,7 +15,7 @@ export async function resolveMoltbotDocsPath(params: {
|
||||
if (fs.existsSync(workspaceDocs)) return workspaceDocs;
|
||||
}
|
||||
|
||||
const packageRoot = await resolveMoltbotPackageRoot({
|
||||
const packageRoot = await resolveOpenClawPackageRoot({
|
||||
cwd: params.cwd,
|
||||
argv1: params.argv1,
|
||||
moduleUrl: params.moduleUrl,
|
||||
|
||||
@@ -4,7 +4,7 @@ import path from "node:path";
|
||||
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveAgentAvatar } from "./identity-avatar.js";
|
||||
|
||||
async function writeFile(filePath: string, contents = "avatar") {
|
||||
@@ -14,12 +14,12 @@ async function writeFile(filePath: string, contents = "avatar") {
|
||||
|
||||
describe("resolveAgentAvatar", () => {
|
||||
it("resolves local avatar from config when inside workspace", async () => {
|
||||
const root = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-avatar-"));
|
||||
const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-avatar-"));
|
||||
const workspace = path.join(root, "work");
|
||||
const avatarPath = path.join(workspace, "avatars", "main.png");
|
||||
await writeFile(avatarPath);
|
||||
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
@@ -41,13 +41,13 @@ describe("resolveAgentAvatar", () => {
|
||||
});
|
||||
|
||||
it("rejects avatars outside the workspace", async () => {
|
||||
const root = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-avatar-"));
|
||||
const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-avatar-"));
|
||||
const workspace = path.join(root, "work");
|
||||
await fs.mkdir(workspace, { recursive: true });
|
||||
const outsidePath = path.join(root, "outside.png");
|
||||
await writeFile(outsidePath);
|
||||
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [
|
||||
{
|
||||
@@ -67,7 +67,7 @@ describe("resolveAgentAvatar", () => {
|
||||
});
|
||||
|
||||
it("falls back to IDENTITY.md when config has no avatar", async () => {
|
||||
const root = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-avatar-"));
|
||||
const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-avatar-"));
|
||||
const workspace = path.join(root, "work");
|
||||
const avatarPath = path.join(workspace, "avatars", "fallback.png");
|
||||
await writeFile(avatarPath);
|
||||
@@ -78,7 +78,7 @@ describe("resolveAgentAvatar", () => {
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [{ id: "main", workspace }],
|
||||
},
|
||||
@@ -94,7 +94,7 @@ describe("resolveAgentAvatar", () => {
|
||||
});
|
||||
|
||||
it("accepts remote and data avatars", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
list: [
|
||||
{ id: "main", identity: { avatar: "https://example.com/avatar.png" } },
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveUserPath } from "../utils.js";
|
||||
import { resolveAgentWorkspaceDir } from "./agent-scope.js";
|
||||
import { loadAgentIdentityFromWorkspace } from "./identity-file.js";
|
||||
@@ -20,7 +20,7 @@ function normalizeAvatarValue(value: string | undefined | null): string | null {
|
||||
return trimmed ? trimmed : null;
|
||||
}
|
||||
|
||||
function resolveAvatarSource(cfg: MoltbotConfig, agentId: string): string | null {
|
||||
function resolveAvatarSource(cfg: OpenClawConfig, agentId: string): string | null {
|
||||
const fromConfig = normalizeAvatarValue(resolveAgentIdentity(cfg, agentId)?.avatar);
|
||||
if (fromConfig) return fromConfig;
|
||||
const workspace = resolveAgentWorkspaceDir(cfg, agentId);
|
||||
@@ -79,7 +79,7 @@ function resolveLocalAvatarPath(params: {
|
||||
return { ok: true, filePath: realPath };
|
||||
}
|
||||
|
||||
export function resolveAgentAvatar(cfg: MoltbotConfig, agentId: string): AgentAvatarResolution {
|
||||
export function resolveAgentAvatar(cfg: OpenClawConfig, agentId: string): AgentAvatarResolution {
|
||||
const source = resolveAvatarSource(cfg, agentId);
|
||||
if (!source) {
|
||||
return { kind: "none", reason: "missing" };
|
||||
|
||||
@@ -23,7 +23,7 @@ describe("parseIdentityMarkdown", () => {
|
||||
- **Creature:** Robot
|
||||
- **Vibe:** Warm
|
||||
- **Emoji:** :robot:
|
||||
- **Avatar:** avatars/clawd.png
|
||||
- **Avatar:** avatars/openclaw.png
|
||||
`;
|
||||
const parsed = parseIdentityMarkdown(content);
|
||||
expect(parsed).toEqual({
|
||||
@@ -31,7 +31,7 @@ describe("parseIdentityMarkdown", () => {
|
||||
creature: "Robot",
|
||||
vibe: "Warm",
|
||||
emoji: ":robot:",
|
||||
avatar: "avatars/clawd.png",
|
||||
avatar: "avatars/openclaw.png",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveHumanDelayConfig } from "./identity.js";
|
||||
|
||||
describe("resolveHumanDelayConfig", () => {
|
||||
it("returns undefined when no humanDelay config is set", () => {
|
||||
const cfg: MoltbotConfig = {};
|
||||
const cfg: OpenClawConfig = {};
|
||||
expect(resolveHumanDelayConfig(cfg, "main")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("merges defaults with per-agent overrides", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
defaults: {
|
||||
humanDelay: { mode: "natural", minMs: 800, maxMs: 1800 },
|
||||
|
||||
@@ -1,35 +1,38 @@
|
||||
import type { MoltbotConfig, HumanDelayConfig, IdentityConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig, HumanDelayConfig, IdentityConfig } from "../config/config.js";
|
||||
import { resolveAgentConfig } from "./agent-scope.js";
|
||||
|
||||
const DEFAULT_ACK_REACTION = "👀";
|
||||
|
||||
export function resolveAgentIdentity(
|
||||
cfg: MoltbotConfig,
|
||||
cfg: OpenClawConfig,
|
||||
agentId: string,
|
||||
): IdentityConfig | undefined {
|
||||
return resolveAgentConfig(cfg, agentId)?.identity;
|
||||
}
|
||||
|
||||
export function resolveAckReaction(cfg: MoltbotConfig, agentId: string): string {
|
||||
export function resolveAckReaction(cfg: OpenClawConfig, agentId: string): string {
|
||||
const configured = cfg.messages?.ackReaction;
|
||||
if (configured !== undefined) return configured.trim();
|
||||
const emoji = resolveAgentIdentity(cfg, agentId)?.emoji?.trim();
|
||||
return emoji || DEFAULT_ACK_REACTION;
|
||||
}
|
||||
|
||||
export function resolveIdentityNamePrefix(cfg: MoltbotConfig, agentId: string): string | undefined {
|
||||
export function resolveIdentityNamePrefix(
|
||||
cfg: OpenClawConfig,
|
||||
agentId: string,
|
||||
): string | undefined {
|
||||
const name = resolveAgentIdentity(cfg, agentId)?.name?.trim();
|
||||
if (!name) return undefined;
|
||||
return `[${name}]`;
|
||||
}
|
||||
|
||||
/** Returns just the identity name (without brackets) for template context. */
|
||||
export function resolveIdentityName(cfg: MoltbotConfig, agentId: string): string | undefined {
|
||||
export function resolveIdentityName(cfg: OpenClawConfig, agentId: string): string | undefined {
|
||||
return resolveAgentIdentity(cfg, agentId)?.name?.trim() || undefined;
|
||||
}
|
||||
|
||||
export function resolveMessagePrefix(
|
||||
cfg: MoltbotConfig,
|
||||
cfg: OpenClawConfig,
|
||||
agentId: string,
|
||||
opts?: { configured?: string; hasAllowFrom?: boolean; fallback?: string },
|
||||
): string {
|
||||
@@ -39,10 +42,10 @@ export function resolveMessagePrefix(
|
||||
const hasAllowFrom = opts?.hasAllowFrom === true;
|
||||
if (hasAllowFrom) return "";
|
||||
|
||||
return resolveIdentityNamePrefix(cfg, agentId) ?? opts?.fallback ?? "[moltbot]";
|
||||
return resolveIdentityNamePrefix(cfg, agentId) ?? opts?.fallback ?? "[openclaw]";
|
||||
}
|
||||
|
||||
export function resolveResponsePrefix(cfg: MoltbotConfig, agentId: string): string | undefined {
|
||||
export function resolveResponsePrefix(cfg: OpenClawConfig, agentId: string): string | undefined {
|
||||
const configured = cfg.messages?.responsePrefix;
|
||||
if (configured !== undefined) {
|
||||
if (configured === "auto") {
|
||||
@@ -54,7 +57,7 @@ export function resolveResponsePrefix(cfg: MoltbotConfig, agentId: string): stri
|
||||
}
|
||||
|
||||
export function resolveEffectiveMessagesConfig(
|
||||
cfg: MoltbotConfig,
|
||||
cfg: OpenClawConfig,
|
||||
agentId: string,
|
||||
opts?: { hasAllowFrom?: boolean; fallbackMessagePrefix?: string },
|
||||
): { messagePrefix: string; responsePrefix?: string } {
|
||||
@@ -68,7 +71,7 @@ export function resolveEffectiveMessagesConfig(
|
||||
}
|
||||
|
||||
export function resolveHumanDelayConfig(
|
||||
cfg: MoltbotConfig,
|
||||
cfg: OpenClawConfig,
|
||||
agentId: string,
|
||||
): HumanDelayConfig | undefined {
|
||||
const defaults = cfg.agents?.defaults?.humanDelay;
|
||||
|
||||
@@ -20,10 +20,10 @@ function collectEnvPrefixedKeys(prefix: string): string[] {
|
||||
}
|
||||
|
||||
export function collectAnthropicApiKeys(): string[] {
|
||||
const forcedSingle = process.env.CLAWDBOT_LIVE_ANTHROPIC_KEY?.trim();
|
||||
const forcedSingle = process.env.OPENCLAW_LIVE_ANTHROPIC_KEY?.trim();
|
||||
if (forcedSingle) return [forcedSingle];
|
||||
|
||||
const fromList = parseKeyList(process.env.CLAWDBOT_LIVE_ANTHROPIC_KEYS);
|
||||
const fromList = parseKeyList(process.env.OPENCLAW_LIVE_ANTHROPIC_KEYS);
|
||||
const fromEnv = collectEnvPrefixedKeys("ANTHROPIC_API_KEY");
|
||||
const primary = process.env.ANTHROPIC_API_KEY?.trim();
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
import type { MoltbotConfig, MemorySearchConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig, MemorySearchConfig } from "../config/config.js";
|
||||
import { resolveStateDir } from "../config/paths.js";
|
||||
import { clampInt, clampNumber, resolveUserPath } from "../utils.js";
|
||||
import { resolveAgentConfig } from "./agent-scope.js";
|
||||
@@ -280,7 +280,7 @@ function mergeConfig(
|
||||
}
|
||||
|
||||
export function resolveMemorySearchConfig(
|
||||
cfg: MoltbotConfig,
|
||||
cfg: OpenClawConfig,
|
||||
agentId: string,
|
||||
): ResolvedMemorySearchConfig | null {
|
||||
const defaults = cfg.agents?.defaults?.memorySearch;
|
||||
|
||||
@@ -65,7 +65,7 @@ export async function minimaxUnderstandImage(params: {
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey}`,
|
||||
"Content-Type": "application/json",
|
||||
"MM-API-Source": "Moltbot",
|
||||
"MM-API-Source": "OpenClaw",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
prompt,
|
||||
|
||||
@@ -13,15 +13,15 @@ const oauthFixture = {
|
||||
|
||||
describe("getApiKeyForModel", () => {
|
||||
it("migrates legacy oauth.json into auth-profiles.json", async () => {
|
||||
const previousStateDir = process.env.CLAWDBOT_STATE_DIR;
|
||||
const previousAgentDir = process.env.CLAWDBOT_AGENT_DIR;
|
||||
const previousStateDir = process.env.OPENCLAW_STATE_DIR;
|
||||
const previousAgentDir = process.env.OPENCLAW_AGENT_DIR;
|
||||
const previousPiAgentDir = process.env.PI_CODING_AGENT_DIR;
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-oauth-"));
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-oauth-"));
|
||||
|
||||
try {
|
||||
process.env.CLAWDBOT_STATE_DIR = tempDir;
|
||||
process.env.CLAWDBOT_AGENT_DIR = path.join(tempDir, "agent");
|
||||
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
|
||||
process.env.OPENCLAW_STATE_DIR = tempDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = path.join(tempDir, "agent");
|
||||
process.env.PI_CODING_AGENT_DIR = process.env.OPENCLAW_AGENT_DIR;
|
||||
|
||||
const oauthDir = path.join(tempDir, "credentials");
|
||||
await fs.mkdir(oauthDir, { recursive: true, mode: 0o700 });
|
||||
@@ -41,7 +41,7 @@ describe("getApiKeyForModel", () => {
|
||||
api: "openai-codex-responses",
|
||||
} as Model<Api>;
|
||||
|
||||
const store = ensureAuthProfileStore(process.env.CLAWDBOT_AGENT_DIR, {
|
||||
const store = ensureAuthProfileStore(process.env.OPENCLAW_AGENT_DIR, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
const apiKey = await getApiKeyForModel({
|
||||
@@ -57,7 +57,7 @@ describe("getApiKeyForModel", () => {
|
||||
},
|
||||
},
|
||||
store,
|
||||
agentDir: process.env.CLAWDBOT_AGENT_DIR,
|
||||
agentDir: process.env.OPENCLAW_AGENT_DIR,
|
||||
});
|
||||
expect(apiKey.apiKey).toBe(oauthFixture.access);
|
||||
|
||||
@@ -76,14 +76,14 @@ describe("getApiKeyForModel", () => {
|
||||
});
|
||||
} finally {
|
||||
if (previousStateDir === undefined) {
|
||||
delete process.env.CLAWDBOT_STATE_DIR;
|
||||
delete process.env.OPENCLAW_STATE_DIR;
|
||||
} else {
|
||||
process.env.CLAWDBOT_STATE_DIR = previousStateDir;
|
||||
process.env.OPENCLAW_STATE_DIR = previousStateDir;
|
||||
}
|
||||
if (previousAgentDir === undefined) {
|
||||
delete process.env.CLAWDBOT_AGENT_DIR;
|
||||
delete process.env.OPENCLAW_AGENT_DIR;
|
||||
} else {
|
||||
process.env.CLAWDBOT_AGENT_DIR = previousAgentDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = previousAgentDir;
|
||||
}
|
||||
if (previousPiAgentDir === undefined) {
|
||||
delete process.env.PI_CODING_AGENT_DIR;
|
||||
@@ -95,17 +95,17 @@ describe("getApiKeyForModel", () => {
|
||||
});
|
||||
|
||||
it("suggests openai-codex when only Codex OAuth is configured", async () => {
|
||||
const previousStateDir = process.env.CLAWDBOT_STATE_DIR;
|
||||
const previousAgentDir = process.env.CLAWDBOT_AGENT_DIR;
|
||||
const previousStateDir = process.env.OPENCLAW_STATE_DIR;
|
||||
const previousAgentDir = process.env.OPENCLAW_AGENT_DIR;
|
||||
const previousPiAgentDir = process.env.PI_CODING_AGENT_DIR;
|
||||
const previousOpenAiKey = process.env.OPENAI_API_KEY;
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-auth-"));
|
||||
|
||||
try {
|
||||
delete process.env.OPENAI_API_KEY;
|
||||
process.env.CLAWDBOT_STATE_DIR = tempDir;
|
||||
process.env.CLAWDBOT_AGENT_DIR = path.join(tempDir, "agent");
|
||||
process.env.PI_CODING_AGENT_DIR = process.env.CLAWDBOT_AGENT_DIR;
|
||||
process.env.OPENCLAW_STATE_DIR = tempDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = path.join(tempDir, "agent");
|
||||
process.env.PI_CODING_AGENT_DIR = process.env.OPENCLAW_AGENT_DIR;
|
||||
|
||||
const authProfilesPath = path.join(tempDir, "agent", "auth-profiles.json");
|
||||
await fs.mkdir(path.dirname(authProfilesPath), {
|
||||
@@ -148,14 +148,14 @@ describe("getApiKeyForModel", () => {
|
||||
process.env.OPENAI_API_KEY = previousOpenAiKey;
|
||||
}
|
||||
if (previousStateDir === undefined) {
|
||||
delete process.env.CLAWDBOT_STATE_DIR;
|
||||
delete process.env.OPENCLAW_STATE_DIR;
|
||||
} else {
|
||||
process.env.CLAWDBOT_STATE_DIR = previousStateDir;
|
||||
process.env.OPENCLAW_STATE_DIR = previousStateDir;
|
||||
}
|
||||
if (previousAgentDir === undefined) {
|
||||
delete process.env.CLAWDBOT_AGENT_DIR;
|
||||
delete process.env.OPENCLAW_AGENT_DIR;
|
||||
} else {
|
||||
process.env.CLAWDBOT_AGENT_DIR = previousAgentDir;
|
||||
process.env.OPENCLAW_AGENT_DIR = previousAgentDir;
|
||||
}
|
||||
if (previousPiAgentDir === undefined) {
|
||||
delete process.env.PI_CODING_AGENT_DIR;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from "node:path";
|
||||
|
||||
import { type Api, getEnvApiKey, type Model } from "@mariozechner/pi-ai";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { ModelProviderAuthMode, ModelProviderConfig } from "../config/types.js";
|
||||
import { getShellEnvAppliedKeys } from "../infra/shell-env.js";
|
||||
import { formatCliCommand } from "../cli/command-format.js";
|
||||
@@ -23,7 +23,7 @@ const AWS_SECRET_KEY_ENV = "AWS_SECRET_ACCESS_KEY";
|
||||
const AWS_PROFILE_ENV = "AWS_PROFILE";
|
||||
|
||||
function resolveProviderConfig(
|
||||
cfg: MoltbotConfig | undefined,
|
||||
cfg: OpenClawConfig | undefined,
|
||||
provider: string,
|
||||
): ModelProviderConfig | undefined {
|
||||
const providers = cfg?.models?.providers ?? {};
|
||||
@@ -45,7 +45,7 @@ function resolveProviderConfig(
|
||||
}
|
||||
|
||||
export function getCustomProviderApiKey(
|
||||
cfg: MoltbotConfig | undefined,
|
||||
cfg: OpenClawConfig | undefined,
|
||||
provider: string,
|
||||
): string | undefined {
|
||||
const entry = resolveProviderConfig(cfg, provider);
|
||||
@@ -54,7 +54,7 @@ export function getCustomProviderApiKey(
|
||||
}
|
||||
|
||||
function resolveProviderAuthOverride(
|
||||
cfg: MoltbotConfig | undefined,
|
||||
cfg: OpenClawConfig | undefined,
|
||||
provider: string,
|
||||
): ModelProviderAuthMode | undefined {
|
||||
const entry = resolveProviderConfig(cfg, provider);
|
||||
@@ -128,7 +128,7 @@ export type ResolvedProviderAuth = {
|
||||
|
||||
export async function resolveApiKeyForProvider(params: {
|
||||
provider: string;
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
profileId?: string;
|
||||
preferredProfile?: string;
|
||||
store?: AuthProfileStore;
|
||||
@@ -221,7 +221,7 @@ export async function resolveApiKeyForProvider(params: {
|
||||
[
|
||||
`No API key found for provider "${provider}".`,
|
||||
`Auth store: ${authStorePath} (agentDir: ${resolvedAgentDir}).`,
|
||||
`Configure auth for this agent (${formatCliCommand("moltbot agents add <id>")}) or copy auth-profiles.json from the main agentDir.`,
|
||||
`Configure auth for this agent (${formatCliCommand("openclaw agents add <id>")}) or copy auth-profiles.json from the main agentDir.`,
|
||||
].join(" "),
|
||||
);
|
||||
}
|
||||
@@ -294,7 +294,7 @@ export function resolveEnvApiKey(provider: string): EnvApiKeyResult | null {
|
||||
|
||||
export function resolveModelAuthMode(
|
||||
provider?: string,
|
||||
cfg?: MoltbotConfig,
|
||||
cfg?: OpenClawConfig,
|
||||
store?: AuthProfileStore,
|
||||
): ModelAuthMode | undefined {
|
||||
const resolved = provider?.trim();
|
||||
@@ -336,7 +336,7 @@ export function resolveModelAuthMode(
|
||||
|
||||
export async function getApiKeyForModel(params: {
|
||||
model: Model<Api>;
|
||||
cfg?: MoltbotConfig;
|
||||
cfg?: OpenClawConfig;
|
||||
profileId?: string;
|
||||
preferredProfile?: string;
|
||||
store?: AuthProfileStore;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
__setModelCatalogImportForTest,
|
||||
loadModelCatalog,
|
||||
@@ -10,11 +10,11 @@ import {
|
||||
type PiSdkModule = typeof import("@mariozechner/pi-coding-agent");
|
||||
|
||||
vi.mock("./models-config.js", () => ({
|
||||
ensureMoltbotModelsJson: vi.fn().mockResolvedValue({ agentDir: "/tmp", wrote: false }),
|
||||
ensureOpenClawModelsJson: vi.fn().mockResolvedValue({ agentDir: "/tmp", wrote: false }),
|
||||
}));
|
||||
|
||||
vi.mock("./agent-paths.js", () => ({
|
||||
resolveMoltbotAgentDir: () => "/tmp/moltbot",
|
||||
resolveOpenClawAgentDir: () => "/tmp/openclaw",
|
||||
}));
|
||||
|
||||
describe("loadModelCatalog", () => {
|
||||
@@ -43,7 +43,7 @@ describe("loadModelCatalog", () => {
|
||||
} as unknown as PiSdkModule;
|
||||
});
|
||||
|
||||
const cfg = {} as MoltbotConfig;
|
||||
const cfg = {} as OpenClawConfig;
|
||||
const first = await loadModelCatalog({ config: cfg });
|
||||
expect(first).toEqual([]);
|
||||
|
||||
@@ -75,7 +75,7 @@ describe("loadModelCatalog", () => {
|
||||
}) as unknown as PiSdkModule,
|
||||
);
|
||||
|
||||
const result = await loadModelCatalog({ config: {} as MoltbotConfig });
|
||||
const result = await loadModelCatalog({ config: {} as OpenClawConfig });
|
||||
expect(result).toEqual([{ id: "gpt-4.1", name: "GPT-4.1", provider: "openai" }]);
|
||||
expect(warnSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { type MoltbotConfig, loadConfig } from "../config/config.js";
|
||||
import { resolveMoltbotAgentDir } from "./agent-paths.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import { type OpenClawConfig, loadConfig } from "../config/config.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
|
||||
export type ModelCatalogEntry = {
|
||||
id: string;
|
||||
@@ -39,7 +39,7 @@ export function __setModelCatalogImportForTest(loader?: () => Promise<PiSdkModul
|
||||
}
|
||||
|
||||
export async function loadModelCatalog(params?: {
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
useCache?: boolean;
|
||||
}): Promise<ModelCatalogEntry[]> {
|
||||
if (params?.useCache === false) {
|
||||
@@ -57,13 +57,13 @@ export async function loadModelCatalog(params?: {
|
||||
});
|
||||
try {
|
||||
const cfg = params?.config ?? loadConfig();
|
||||
await ensureMoltbotModelsJson(cfg);
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
// IMPORTANT: keep the dynamic import *inside* the try/catch.
|
||||
// If this fails once (e.g. during a pnpm install that temporarily swaps node_modules),
|
||||
// we must not poison the cache with a rejected promise (otherwise all channel handlers
|
||||
// will keep failing until restart).
|
||||
const piSdk = await importPiSdk();
|
||||
const agentDir = resolveMoltbotAgentDir();
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const authStorage = piSdk.discoverAuthStorage(agentDir);
|
||||
const registry = piSdk.discoverModels(authStorage, agentDir) as
|
||||
| {
|
||||
|
||||
@@ -4,13 +4,13 @@ import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { AuthProfileStore } from "./auth-profiles.js";
|
||||
import { saveAuthProfileStore } from "./auth-profiles.js";
|
||||
import { AUTH_STORE_VERSION } from "./auth-profiles/constants.js";
|
||||
import { runWithModelFallback } from "./model-fallback.js";
|
||||
|
||||
function makeCfg(overrides: Partial<MoltbotConfig> = {}): MoltbotConfig {
|
||||
function makeCfg(overrides: Partial<OpenClawConfig> = {}): OpenClawConfig {
|
||||
return {
|
||||
agents: {
|
||||
defaults: {
|
||||
@@ -21,7 +21,7 @@ function makeCfg(overrides: Partial<MoltbotConfig> = {}): MoltbotConfig {
|
||||
},
|
||||
},
|
||||
...overrides,
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
describe("runWithModelFallback", () => {
|
||||
@@ -125,7 +125,7 @@ describe("runWithModelFallback", () => {
|
||||
});
|
||||
|
||||
it("skips providers when all profiles are in cooldown", async () => {
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-auth-"));
|
||||
const provider = `cooldown-test-${crypto.randomUUID()}`;
|
||||
const profileId = `${provider}:default`;
|
||||
|
||||
@@ -180,7 +180,7 @@ describe("runWithModelFallback", () => {
|
||||
});
|
||||
|
||||
it("does not skip when any profile is available", async () => {
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-auth-"));
|
||||
const provider = `cooldown-mixed-${crypto.randomUUID()}`;
|
||||
const profileA = `${provider}:a`;
|
||||
const profileB = `${provider}:b`;
|
||||
@@ -279,7 +279,7 @@ describe("runWithModelFallback", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
|
||||
const calls: Array<{ provider: string; model: string }> = [];
|
||||
|
||||
@@ -316,7 +316,7 @@ describe("runWithModelFallback", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
|
||||
const calls: Array<{ provider: string; model: string }> = [];
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "./defaults.js";
|
||||
import {
|
||||
coerceToFailoverError,
|
||||
@@ -48,7 +48,7 @@ function shouldRethrowAbort(err: unknown): boolean {
|
||||
}
|
||||
|
||||
function buildAllowedModelKeys(
|
||||
cfg: MoltbotConfig | undefined,
|
||||
cfg: OpenClawConfig | undefined,
|
||||
defaultProvider: string,
|
||||
): Set<string> | null {
|
||||
const rawAllowlist = (() => {
|
||||
@@ -66,7 +66,7 @@ function buildAllowedModelKeys(
|
||||
}
|
||||
|
||||
function resolveImageFallbackCandidates(params: {
|
||||
cfg: MoltbotConfig | undefined;
|
||||
cfg: OpenClawConfig | undefined;
|
||||
defaultProvider: string;
|
||||
modelOverride?: string;
|
||||
}): ModelCandidate[] {
|
||||
@@ -127,7 +127,7 @@ function resolveImageFallbackCandidates(params: {
|
||||
}
|
||||
|
||||
function resolveFallbackCandidates(params: {
|
||||
cfg: MoltbotConfig | undefined;
|
||||
cfg: OpenClawConfig | undefined;
|
||||
provider: string;
|
||||
model: string;
|
||||
/** Optional explicit fallbacks list; when provided (even empty), replaces agents.defaults.model.fallbacks. */
|
||||
@@ -191,7 +191,7 @@ function resolveFallbackCandidates(params: {
|
||||
}
|
||||
|
||||
export async function runWithModelFallback<T>(params: {
|
||||
cfg: MoltbotConfig | undefined;
|
||||
cfg: OpenClawConfig | undefined;
|
||||
provider: string;
|
||||
model: string;
|
||||
agentDir?: string;
|
||||
@@ -299,7 +299,7 @@ export async function runWithModelFallback<T>(params: {
|
||||
}
|
||||
|
||||
export async function runWithImageModelFallback<T>(params: {
|
||||
cfg: MoltbotConfig | undefined;
|
||||
cfg: OpenClawConfig | undefined;
|
||||
modelOverride?: string;
|
||||
run: (provider: string, model: string) => Promise<T>;
|
||||
onError?: (attempt: {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
normalizeProviderId,
|
||||
modelKey,
|
||||
} from "./model-selection.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
describe("model-selection", () => {
|
||||
describe("normalizeProviderId", () => {
|
||||
@@ -49,7 +49,7 @@ describe("model-selection", () => {
|
||||
|
||||
describe("buildModelAliasIndex", () => {
|
||||
it("should build alias index from config", () => {
|
||||
const cfg: Partial<MoltbotConfig> = {
|
||||
const cfg: Partial<OpenClawConfig> = {
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
@@ -61,7 +61,7 @@ describe("model-selection", () => {
|
||||
};
|
||||
|
||||
const index = buildModelAliasIndex({
|
||||
cfg: cfg as MoltbotConfig,
|
||||
cfg: cfg as OpenClawConfig,
|
||||
defaultProvider: "anthropic",
|
||||
});
|
||||
|
||||
@@ -105,7 +105,7 @@ describe("model-selection", () => {
|
||||
describe("resolveConfiguredModelRef", () => {
|
||||
it("should fall back to anthropic and warn if provider is missing for non-alias", () => {
|
||||
const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
const cfg: Partial<MoltbotConfig> = {
|
||||
const cfg: Partial<OpenClawConfig> = {
|
||||
agents: {
|
||||
defaults: {
|
||||
model: "claude-3-5-sonnet",
|
||||
@@ -114,7 +114,7 @@ describe("model-selection", () => {
|
||||
};
|
||||
|
||||
const result = resolveConfiguredModelRef({
|
||||
cfg: cfg as MoltbotConfig,
|
||||
cfg: cfg as OpenClawConfig,
|
||||
defaultProvider: "google",
|
||||
defaultModel: "gemini-pro",
|
||||
});
|
||||
@@ -127,9 +127,9 @@ describe("model-selection", () => {
|
||||
});
|
||||
|
||||
it("should use default provider/model if config is empty", () => {
|
||||
const cfg: Partial<MoltbotConfig> = {};
|
||||
const cfg: Partial<OpenClawConfig> = {};
|
||||
const result = resolveConfiguredModelRef({
|
||||
cfg: cfg as MoltbotConfig,
|
||||
cfg: cfg as OpenClawConfig,
|
||||
defaultProvider: "openai",
|
||||
defaultModel: "gpt-4",
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { ModelCatalogEntry } from "./model-catalog.js";
|
||||
import { normalizeGoogleModelId } from "./models-config.providers.js";
|
||||
import { resolveAgentModelPrimary } from "./agent-scope.js";
|
||||
@@ -32,7 +32,7 @@ export function normalizeProviderId(provider: string): string {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function isCliProvider(provider: string, cfg?: MoltbotConfig): boolean {
|
||||
export function isCliProvider(provider: string, cfg?: OpenClawConfig): boolean {
|
||||
const normalized = normalizeProviderId(provider);
|
||||
if (normalized === "claude-cli") return true;
|
||||
if (normalized === "codex-cli") return true;
|
||||
@@ -73,7 +73,7 @@ export function parseModelRef(raw: string, defaultProvider: string): ModelRef |
|
||||
}
|
||||
|
||||
export function buildModelAliasIndex(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
defaultProvider: string;
|
||||
}): ModelAliasIndex {
|
||||
const byAlias = new Map<string, { alias: string; ref: ModelRef }>();
|
||||
@@ -116,7 +116,7 @@ export function resolveModelRefFromString(params: {
|
||||
}
|
||||
|
||||
export function resolveConfiguredModelRef(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
defaultProvider: string;
|
||||
defaultModel: string;
|
||||
}): ModelRef {
|
||||
@@ -138,7 +138,7 @@ export function resolveConfiguredModelRef(params: {
|
||||
|
||||
// Default to anthropic if no provider is specified, but warn as this is deprecated.
|
||||
console.warn(
|
||||
`[moltbot] Model "${trimmed}" specified without provider. Falling back to "anthropic/${trimmed}". Please use "anthropic/${trimmed}" in your config.`,
|
||||
`[openclaw] Model "${trimmed}" specified without provider. Falling back to "anthropic/${trimmed}". Please use "anthropic/${trimmed}" in your config.`,
|
||||
);
|
||||
return { provider: "anthropic", model: trimmed };
|
||||
}
|
||||
@@ -154,7 +154,7 @@ export function resolveConfiguredModelRef(params: {
|
||||
}
|
||||
|
||||
export function resolveDefaultModelForAgent(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
agentId?: string;
|
||||
}): ModelRef {
|
||||
const agentModelOverride = params.agentId
|
||||
@@ -186,7 +186,7 @@ export function resolveDefaultModelForAgent(params: {
|
||||
}
|
||||
|
||||
export function buildAllowedModelSet(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
catalog: ModelCatalogEntry[];
|
||||
defaultProvider: string;
|
||||
defaultModel?: string;
|
||||
@@ -262,7 +262,7 @@ export type ModelRefStatus = {
|
||||
};
|
||||
|
||||
export function getModelRefStatus(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
catalog: ModelCatalogEntry[];
|
||||
ref: ModelRef;
|
||||
defaultProvider: string;
|
||||
@@ -284,7 +284,7 @@ export function getModelRefStatus(params: {
|
||||
}
|
||||
|
||||
export function resolveAllowedModelRef(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
catalog: ModelCatalogEntry[];
|
||||
raw: string;
|
||||
defaultProvider: string;
|
||||
@@ -323,7 +323,7 @@ export function resolveAllowedModelRef(params: {
|
||||
}
|
||||
|
||||
export function resolveThinkingDefault(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
provider: string;
|
||||
model: string;
|
||||
catalog?: ModelCatalogEntry[];
|
||||
@@ -342,7 +342,7 @@ export function resolveThinkingDefault(params: {
|
||||
* Returns null if hooks.gmail.model is not set.
|
||||
*/
|
||||
export function resolveHooksGmailModel(params: {
|
||||
cfg: MoltbotConfig;
|
||||
cfg: OpenClawConfig;
|
||||
defaultProvider: string;
|
||||
}): ModelRef | null {
|
||||
const hooksModel = params.cfg.hooks?.gmail?.model;
|
||||
|
||||
@@ -2,13 +2,13 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { withTempHome as withTempHomeBase } from "../../test/helpers/temp-home.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
async function withTempHome<T>(fn: (home: string) => Promise<T>): Promise<T> {
|
||||
return withTempHomeBase(fn, { prefix: "moltbot-models-" });
|
||||
return withTempHomeBase(fn, { prefix: "openclaw-models-" });
|
||||
}
|
||||
|
||||
const _MODELS_CONFIG: MoltbotConfig = {
|
||||
const _MODELS_CONFIG: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
"custom-proxy": {
|
||||
@@ -61,10 +61,10 @@ describe("models-config", () => {
|
||||
}),
|
||||
}));
|
||||
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
|
||||
const agentDir = path.join(home, "agent-default-base-url");
|
||||
await ensureMoltbotModelsJson({ models: { providers: {} } }, agentDir);
|
||||
await ensureOpenClawModelsJson({ models: { providers: {} } }, agentDir);
|
||||
|
||||
const raw = await fs.readFile(path.join(agentDir, "models.json"), "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
@@ -102,9 +102,9 @@ describe("models-config", () => {
|
||||
resolveCopilotApiToken,
|
||||
}));
|
||||
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
|
||||
await ensureMoltbotModelsJson({ models: { providers: {} } });
|
||||
await ensureOpenClawModelsJson({ models: { providers: {} } });
|
||||
|
||||
expect(resolveCopilotApiToken).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ githubToken: "copilot-token" }),
|
||||
|
||||
@@ -2,13 +2,13 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { withTempHome as withTempHomeBase } from "../../test/helpers/temp-home.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
async function withTempHome<T>(fn: (home: string) => Promise<T>): Promise<T> {
|
||||
return withTempHomeBase(fn, { prefix: "moltbot-models-" });
|
||||
return withTempHomeBase(fn, { prefix: "openclaw-models-" });
|
||||
}
|
||||
|
||||
const _MODELS_CONFIG: MoltbotConfig = {
|
||||
const _MODELS_CONFIG: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
"custom-proxy": {
|
||||
@@ -56,12 +56,12 @@ describe("models-config", () => {
|
||||
resolveCopilotApiToken: vi.fn().mockRejectedValue(new Error("boom")),
|
||||
}));
|
||||
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { resolveMoltbotAgentDir } = await import("./agent-paths.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
const { resolveOpenClawAgentDir } = await import("./agent-paths.js");
|
||||
|
||||
await ensureMoltbotModelsJson({ models: { providers: {} } });
|
||||
await ensureOpenClawModelsJson({ models: { providers: {} } });
|
||||
|
||||
const agentDir = resolveMoltbotAgentDir();
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const raw = await fs.readFile(path.join(agentDir, "models.json"), "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
providers: Record<string, { baseUrl?: string }>;
|
||||
@@ -115,9 +115,9 @@ describe("models-config", () => {
|
||||
}),
|
||||
}));
|
||||
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
|
||||
await ensureMoltbotModelsJson({ models: { providers: {} } }, agentDir);
|
||||
await ensureOpenClawModelsJson({ models: { providers: {} } }, agentDir);
|
||||
|
||||
const raw = await fs.readFile(path.join(agentDir, "models.json"), "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
|
||||
@@ -2,13 +2,13 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { withTempHome as withTempHomeBase } from "../../test/helpers/temp-home.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
async function withTempHome<T>(fn: (home: string) => Promise<T>): Promise<T> {
|
||||
return withTempHomeBase(fn, { prefix: "moltbot-models-" });
|
||||
return withTempHomeBase(fn, { prefix: "openclaw-models-" });
|
||||
}
|
||||
|
||||
const MODELS_CONFIG: MoltbotConfig = {
|
||||
const MODELS_CONFIG: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
"custom-proxy": {
|
||||
@@ -49,10 +49,10 @@ describe("models-config", () => {
|
||||
const prevKey = process.env.MINIMAX_API_KEY;
|
||||
process.env.MINIMAX_API_KEY = "sk-minimax-test";
|
||||
try {
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { resolveMoltbotAgentDir } = await import("./agent-paths.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
const { resolveOpenClawAgentDir } = await import("./agent-paths.js");
|
||||
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
minimax: {
|
||||
@@ -74,9 +74,9 @@ describe("models-config", () => {
|
||||
},
|
||||
};
|
||||
|
||||
await ensureMoltbotModelsJson(cfg);
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
|
||||
const modelPath = path.join(resolveMoltbotAgentDir(), "models.json");
|
||||
const modelPath = path.join(resolveOpenClawAgentDir(), "models.json");
|
||||
const raw = await fs.readFile(modelPath, "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
providers: Record<string, { apiKey?: string; models?: Array<{ id: string }> }>;
|
||||
@@ -93,10 +93,10 @@ describe("models-config", () => {
|
||||
it("merges providers by default", async () => {
|
||||
await withTempHome(async () => {
|
||||
vi.resetModules();
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { resolveMoltbotAgentDir } = await import("./agent-paths.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
const { resolveOpenClawAgentDir } = await import("./agent-paths.js");
|
||||
|
||||
const agentDir = resolveMoltbotAgentDir();
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
await fs.mkdir(agentDir, { recursive: true });
|
||||
await fs.writeFile(
|
||||
path.join(agentDir, "models.json"),
|
||||
@@ -128,7 +128,7 @@ describe("models-config", () => {
|
||||
"utf8",
|
||||
);
|
||||
|
||||
await ensureMoltbotModelsJson(MODELS_CONFIG);
|
||||
await ensureOpenClawModelsJson(MODELS_CONFIG);
|
||||
|
||||
const raw = await fs.readFile(path.join(agentDir, "models.json"), "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
|
||||
@@ -2,13 +2,13 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { withTempHome as withTempHomeBase } from "../../test/helpers/temp-home.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
async function withTempHome<T>(fn: (home: string) => Promise<T>): Promise<T> {
|
||||
return withTempHomeBase(fn, { prefix: "moltbot-models-" });
|
||||
return withTempHomeBase(fn, { prefix: "openclaw-models-" });
|
||||
}
|
||||
|
||||
const _MODELS_CONFIG: MoltbotConfig = {
|
||||
const _MODELS_CONFIG: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
"custom-proxy": {
|
||||
@@ -46,10 +46,10 @@ describe("models-config", () => {
|
||||
it("normalizes gemini 3 ids to preview for google providers", async () => {
|
||||
await withTempHome(async () => {
|
||||
vi.resetModules();
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { resolveMoltbotAgentDir } = await import("./agent-paths.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
const { resolveOpenClawAgentDir } = await import("./agent-paths.js");
|
||||
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
google: {
|
||||
@@ -83,9 +83,9 @@ describe("models-config", () => {
|
||||
},
|
||||
};
|
||||
|
||||
await ensureMoltbotModelsJson(cfg);
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
|
||||
const modelPath = path.join(resolveMoltbotAgentDir(), "models.json");
|
||||
const modelPath = path.join(resolveOpenClawAgentDir(), "models.json");
|
||||
const raw = await fs.readFile(modelPath, "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
providers: Record<string, { models: Array<{ id: string }> }>;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { tmpdir } from "node:os";
|
||||
|
||||
describe("Ollama provider", () => {
|
||||
it("should not include ollama when no API key is configured", async () => {
|
||||
const agentDir = mkdtempSync(join(tmpdir(), "clawd-test-"));
|
||||
const agentDir = mkdtempSync(join(tmpdir(), "openclaw-test-"));
|
||||
const providers = await resolveImplicitProviders({ agentDir });
|
||||
|
||||
// Ollama requires explicit configuration via OLLAMA_API_KEY env var or profile
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { ModelDefinitionConfig } from "../config/types.models.js";
|
||||
import {
|
||||
DEFAULT_COPILOT_API_BASE_URL,
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
} from "./synthetic-models.js";
|
||||
import { discoverVeniceModels, VENICE_BASE_URL } from "./venice-models.js";
|
||||
|
||||
type ModelsConfig = NonNullable<MoltbotConfig["models"]>;
|
||||
type ModelsConfig = NonNullable<OpenClawConfig["models"]>;
|
||||
export type ProviderConfig = NonNullable<ModelsConfig["providers"]>[string];
|
||||
|
||||
const MINIMAX_API_BASE_URL = "https://api.minimax.chat/v1";
|
||||
@@ -495,15 +495,15 @@ export async function resolveImplicitCopilotProvider(params: {
|
||||
|
||||
// pi-coding-agent's ModelRegistry marks a model "available" only if its
|
||||
// `AuthStorage` has auth configured for that provider (via auth.json/env/etc).
|
||||
// Our Copilot auth lives in Moltbot's auth-profiles store instead, so we also
|
||||
// Our Copilot auth lives in OpenClaw's auth-profiles store instead, so we also
|
||||
// write a runtime-only auth.json entry for pi-coding-agent to pick up.
|
||||
//
|
||||
// This is safe because it's (1) within Moltbot's agent dir, (2) contains the
|
||||
// This is safe because it's (1) within OpenClaw's agent dir, (2) contains the
|
||||
// GitHub token (not the exchanged Copilot token), and (3) matches existing
|
||||
// patterns for OAuth-like providers in pi-coding-agent.
|
||||
// Note: we deliberately do not write pi-coding-agent's `auth.json` here.
|
||||
// Moltbot uses its own auth store and exchanges tokens at runtime.
|
||||
// `models list` uses Moltbot's auth heuristics for availability.
|
||||
// OpenClaw uses its own auth store and exchanges tokens at runtime.
|
||||
// `models list` uses OpenClaw's auth heuristics for availability.
|
||||
|
||||
// We intentionally do NOT define custom models for Copilot in models.json.
|
||||
// pi-coding-agent treats providers with models as replacements requiring apiKey.
|
||||
@@ -516,7 +516,7 @@ export async function resolveImplicitCopilotProvider(params: {
|
||||
|
||||
export async function resolveImplicitBedrockProvider(params: {
|
||||
agentDir: string;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): Promise<ProviderConfig | null> {
|
||||
const env = params.env ?? process.env;
|
||||
|
||||
@@ -2,13 +2,13 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { withTempHome as withTempHomeBase } from "../../test/helpers/temp-home.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
async function withTempHome<T>(fn: (home: string) => Promise<T>): Promise<T> {
|
||||
return withTempHomeBase(fn, { prefix: "moltbot-models-" });
|
||||
return withTempHomeBase(fn, { prefix: "openclaw-models-" });
|
||||
}
|
||||
|
||||
const MODELS_CONFIG: MoltbotConfig = {
|
||||
const MODELS_CONFIG: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
"custom-proxy": {
|
||||
@@ -66,10 +66,10 @@ describe("models-config", () => {
|
||||
|
||||
try {
|
||||
vi.resetModules();
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
|
||||
const agentDir = path.join(home, "agent-empty");
|
||||
const result = await ensureMoltbotModelsJson(
|
||||
const result = await ensureOpenClawModelsJson(
|
||||
{
|
||||
models: { providers: {} },
|
||||
},
|
||||
@@ -103,12 +103,12 @@ describe("models-config", () => {
|
||||
it("writes models.json for configured providers", async () => {
|
||||
await withTempHome(async () => {
|
||||
vi.resetModules();
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { resolveMoltbotAgentDir } = await import("./agent-paths.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
const { resolveOpenClawAgentDir } = await import("./agent-paths.js");
|
||||
|
||||
await ensureMoltbotModelsJson(MODELS_CONFIG);
|
||||
await ensureOpenClawModelsJson(MODELS_CONFIG);
|
||||
|
||||
const modelPath = path.join(resolveMoltbotAgentDir(), "models.json");
|
||||
const modelPath = path.join(resolveOpenClawAgentDir(), "models.json");
|
||||
const raw = await fs.readFile(modelPath, "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
providers: Record<string, { baseUrl?: string }>;
|
||||
@@ -123,12 +123,12 @@ describe("models-config", () => {
|
||||
const prevKey = process.env.MINIMAX_API_KEY;
|
||||
process.env.MINIMAX_API_KEY = "sk-minimax-test";
|
||||
try {
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { resolveMoltbotAgentDir } = await import("./agent-paths.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
const { resolveOpenClawAgentDir } = await import("./agent-paths.js");
|
||||
|
||||
await ensureMoltbotModelsJson({});
|
||||
await ensureOpenClawModelsJson({});
|
||||
|
||||
const modelPath = path.join(resolveMoltbotAgentDir(), "models.json");
|
||||
const modelPath = path.join(resolveOpenClawAgentDir(), "models.json");
|
||||
const raw = await fs.readFile(modelPath, "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
providers: Record<
|
||||
@@ -157,12 +157,12 @@ describe("models-config", () => {
|
||||
const prevKey = process.env.SYNTHETIC_API_KEY;
|
||||
process.env.SYNTHETIC_API_KEY = "sk-synthetic-test";
|
||||
try {
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { resolveMoltbotAgentDir } = await import("./agent-paths.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
const { resolveOpenClawAgentDir } = await import("./agent-paths.js");
|
||||
|
||||
await ensureMoltbotModelsJson({});
|
||||
await ensureOpenClawModelsJson({});
|
||||
|
||||
const modelPath = path.join(resolveMoltbotAgentDir(), "models.json");
|
||||
const modelPath = path.join(resolveOpenClawAgentDir(), "models.json");
|
||||
const raw = await fs.readFile(modelPath, "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
providers: Record<
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
import { type MoltbotConfig, loadConfig } from "../config/config.js";
|
||||
import { resolveMoltbotAgentDir } from "./agent-paths.js";
|
||||
import { type OpenClawConfig, loadConfig } from "../config/config.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import {
|
||||
normalizeProviders,
|
||||
type ProviderConfig,
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
resolveImplicitProviders,
|
||||
} from "./models-config.providers.js";
|
||||
|
||||
type ModelsConfig = NonNullable<MoltbotConfig["models"]>;
|
||||
type ModelsConfig = NonNullable<OpenClawConfig["models"]>;
|
||||
|
||||
const DEFAULT_MODE: NonNullable<ModelsConfig["mode"]> = "merge";
|
||||
|
||||
@@ -72,12 +72,12 @@ async function readJson(pathname: string): Promise<unknown> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureMoltbotModelsJson(
|
||||
config?: MoltbotConfig,
|
||||
export async function ensureOpenClawModelsJson(
|
||||
config?: OpenClawConfig,
|
||||
agentDirOverride?: string,
|
||||
): Promise<{ agentDir: string; wrote: boolean }> {
|
||||
const cfg = config ?? loadConfig();
|
||||
const agentDir = agentDirOverride?.trim() ? agentDirOverride.trim() : resolveMoltbotAgentDir();
|
||||
const agentDir = agentDirOverride?.trim() ? agentDirOverride.trim() : resolveOpenClawAgentDir();
|
||||
|
||||
const explicitProviders = (cfg.models?.providers ?? {}) as Record<string, ProviderConfig>;
|
||||
const implicitProviders = await resolveImplicitProviders({ agentDir });
|
||||
|
||||
@@ -2,13 +2,13 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { withTempHome as withTempHomeBase } from "../../test/helpers/temp-home.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
|
||||
async function withTempHome<T>(fn: (home: string) => Promise<T>): Promise<T> {
|
||||
return withTempHomeBase(fn, { prefix: "moltbot-models-" });
|
||||
return withTempHomeBase(fn, { prefix: "openclaw-models-" });
|
||||
}
|
||||
|
||||
const _MODELS_CONFIG: MoltbotConfig = {
|
||||
const _MODELS_CONFIG: OpenClawConfig = {
|
||||
models: {
|
||||
providers: {
|
||||
"custom-proxy": {
|
||||
@@ -92,9 +92,9 @@ describe("models-config", () => {
|
||||
resolveCopilotApiToken,
|
||||
}));
|
||||
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
|
||||
await ensureMoltbotModelsJson({ models: { providers: {} } }, agentDir);
|
||||
await ensureOpenClawModelsJson({ models: { providers: {} } }, agentDir);
|
||||
|
||||
expect(resolveCopilotApiToken).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ githubToken: "alpha-token" }),
|
||||
@@ -127,10 +127,10 @@ describe("models-config", () => {
|
||||
}),
|
||||
}));
|
||||
|
||||
const { ensureMoltbotModelsJson } = await import("./models-config.js");
|
||||
const { resolveMoltbotAgentDir } = await import("./agent-paths.js");
|
||||
const { ensureOpenClawModelsJson } = await import("./models-config.js");
|
||||
const { resolveOpenClawAgentDir } = await import("./agent-paths.js");
|
||||
|
||||
await ensureMoltbotModelsJson({
|
||||
await ensureOpenClawModelsJson({
|
||||
models: {
|
||||
providers: {
|
||||
"github-copilot": {
|
||||
@@ -142,7 +142,7 @@ describe("models-config", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const agentDir = resolveMoltbotAgentDir();
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const raw = await fs.readFile(path.join(agentDir, "models.json"), "utf8");
|
||||
const parsed = JSON.parse(raw) as {
|
||||
providers: Record<string, { baseUrl?: string }>;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Type } from "@sinclair/typebox";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import { resolveMoltbotAgentDir } from "./agent-paths.js";
|
||||
import { resolveOpenClawAgentDir } from "./agent-paths.js";
|
||||
import {
|
||||
collectAnthropicApiKeys,
|
||||
isAnthropicBillingError,
|
||||
@@ -12,12 +12,12 @@ import {
|
||||
} from "./live-auth-keys.js";
|
||||
import { isModernModelRef } from "./live-model-filter.js";
|
||||
import { getApiKeyForModel, requireApiKey } from "./model-auth.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
import { isRateLimitErrorMessage } from "./pi-embedded-helpers/errors.js";
|
||||
|
||||
const LIVE = isTruthyEnvValue(process.env.LIVE) || isTruthyEnvValue(process.env.CLAWDBOT_LIVE_TEST);
|
||||
const DIRECT_ENABLED = Boolean(process.env.CLAWDBOT_LIVE_MODELS?.trim());
|
||||
const REQUIRE_PROFILE_KEYS = isTruthyEnvValue(process.env.CLAWDBOT_LIVE_REQUIRE_PROFILE_KEYS);
|
||||
const LIVE = isTruthyEnvValue(process.env.LIVE) || isTruthyEnvValue(process.env.OPENCLAW_LIVE_TEST);
|
||||
const DIRECT_ENABLED = Boolean(process.env.OPENCLAW_LIVE_MODELS?.trim());
|
||||
const REQUIRE_PROFILE_KEYS = isTruthyEnvValue(process.env.OPENCLAW_LIVE_REQUIRE_PROFILE_KEYS);
|
||||
|
||||
const describeLive = LIVE ? describe : describe.skip;
|
||||
|
||||
@@ -151,10 +151,10 @@ describeLive("live models (profile keys)", () => {
|
||||
"completes across selected models",
|
||||
async () => {
|
||||
const cfg = loadConfig();
|
||||
await ensureMoltbotModelsJson(cfg);
|
||||
await ensureOpenClawModelsJson(cfg);
|
||||
if (!DIRECT_ENABLED) {
|
||||
logProgress(
|
||||
"[live-models] skipping (set CLAWDBOT_LIVE_MODELS=modern|all|<list>; all=modern)",
|
||||
"[live-models] skipping (set OPENCLAW_LIVE_MODELS=modern|all|<list>; all=modern)",
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -164,18 +164,18 @@ describeLive("live models (profile keys)", () => {
|
||||
logProgress(`[live-models] anthropic keys loaded: ${anthropicKeys.length}`);
|
||||
}
|
||||
|
||||
const agentDir = resolveMoltbotAgentDir();
|
||||
const agentDir = resolveOpenClawAgentDir();
|
||||
const authStorage = discoverAuthStorage(agentDir);
|
||||
const modelRegistry = discoverModels(authStorage, agentDir);
|
||||
const models = modelRegistry.getAll() as Array<Model<Api>>;
|
||||
|
||||
const rawModels = process.env.CLAWDBOT_LIVE_MODELS?.trim();
|
||||
const rawModels = process.env.OPENCLAW_LIVE_MODELS?.trim();
|
||||
const useModern = rawModels === "modern" || rawModels === "all";
|
||||
const useExplicit = Boolean(rawModels) && !useModern;
|
||||
const filter = useExplicit ? parseModelFilter(rawModels) : null;
|
||||
const allowNotFoundSkip = useModern;
|
||||
const providers = parseProviderFilter(process.env.CLAWDBOT_LIVE_PROVIDERS);
|
||||
const perModelTimeoutMs = toInt(process.env.CLAWDBOT_LIVE_MODEL_TIMEOUT_MS, 30_000);
|
||||
const providers = parseProviderFilter(process.env.OPENCLAW_LIVE_PROVIDERS);
|
||||
const perModelTimeoutMs = toInt(process.env.OPENCLAW_LIVE_MODEL_TIMEOUT_MS, 30_000);
|
||||
|
||||
const failures: Array<{ model: string; error: string }> = [];
|
||||
const skipped: Array<{ model: string; reason: string }> = [];
|
||||
|
||||
@@ -4,7 +4,7 @@ import path from "node:path";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
|
||||
vi.mock("./tools/gateway.js", () => ({
|
||||
callGatewayTool: vi.fn(async (method: string) => {
|
||||
@@ -19,14 +19,14 @@ describe("gateway tool", () => {
|
||||
it("schedules SIGUSR1 restart", async () => {
|
||||
vi.useFakeTimers();
|
||||
const kill = vi.spyOn(process, "kill").mockImplementation(() => true);
|
||||
const previousStateDir = process.env.CLAWDBOT_STATE_DIR;
|
||||
const previousProfile = process.env.CLAWDBOT_PROFILE;
|
||||
const stateDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-test-"));
|
||||
process.env.CLAWDBOT_STATE_DIR = stateDir;
|
||||
process.env.CLAWDBOT_PROFILE = "isolated";
|
||||
const previousStateDir = process.env.OPENCLAW_STATE_DIR;
|
||||
const previousProfile = process.env.OPENCLAW_PROFILE;
|
||||
const stateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-test-"));
|
||||
process.env.OPENCLAW_STATE_DIR = stateDir;
|
||||
process.env.OPENCLAW_PROFILE = "isolated";
|
||||
|
||||
try {
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
config: { commands: { restart: true } },
|
||||
}).find((candidate) => candidate.name === "gateway");
|
||||
expect(tool).toBeDefined();
|
||||
@@ -50,7 +50,7 @@ describe("gateway tool", () => {
|
||||
};
|
||||
expect(parsed.payload?.kind).toBe("restart");
|
||||
expect(parsed.payload?.doctorHint).toBe(
|
||||
"Run: moltbot --profile isolated doctor --non-interactive",
|
||||
"Run: openclaw --profile isolated doctor --non-interactive",
|
||||
);
|
||||
|
||||
expect(kill).not.toHaveBeenCalled();
|
||||
@@ -60,27 +60,27 @@ describe("gateway tool", () => {
|
||||
kill.mockRestore();
|
||||
vi.useRealTimers();
|
||||
if (previousStateDir === undefined) {
|
||||
delete process.env.CLAWDBOT_STATE_DIR;
|
||||
delete process.env.OPENCLAW_STATE_DIR;
|
||||
} else {
|
||||
process.env.CLAWDBOT_STATE_DIR = previousStateDir;
|
||||
process.env.OPENCLAW_STATE_DIR = previousStateDir;
|
||||
}
|
||||
if (previousProfile === undefined) {
|
||||
delete process.env.CLAWDBOT_PROFILE;
|
||||
delete process.env.OPENCLAW_PROFILE;
|
||||
} else {
|
||||
process.env.CLAWDBOT_PROFILE = previousProfile;
|
||||
process.env.OPENCLAW_PROFILE = previousProfile;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("passes config.apply through gateway call", async () => {
|
||||
const { callGatewayTool } = await import("./tools/gateway.js");
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "agent:main:whatsapp:dm:+15555550123",
|
||||
}).find((candidate) => candidate.name === "gateway");
|
||||
expect(tool).toBeDefined();
|
||||
if (!tool) throw new Error("missing gateway tool");
|
||||
|
||||
const raw = '{\n agents: { defaults: { workspace: "~/clawd" } }\n}\n';
|
||||
const raw = '{\n agents: { defaults: { workspace: "~/openclaw" } }\n}\n';
|
||||
await tool.execute("call2", {
|
||||
action: "config.apply",
|
||||
raw,
|
||||
@@ -100,7 +100,7 @@ describe("gateway tool", () => {
|
||||
|
||||
it("passes config.patch through gateway call", async () => {
|
||||
const { callGatewayTool } = await import("./tools/gateway.js");
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "agent:main:whatsapp:dm:+15555550123",
|
||||
}).find((candidate) => candidate.name === "gateway");
|
||||
expect(tool).toBeDefined();
|
||||
@@ -126,7 +126,7 @@ describe("gateway tool", () => {
|
||||
|
||||
it("passes update.run through gateway call", async () => {
|
||||
const { callGatewayTool } = await import("./tools/gateway.js");
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "agent:main:whatsapp:dm:+15555550123",
|
||||
}).find((candidate) => candidate.name === "gateway");
|
||||
expect(tool).toBeDefined();
|
||||
@@ -17,7 +17,7 @@ vi.mock("../config/config.js", async (importOriginal) => {
|
||||
});
|
||||
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
|
||||
describe("agents_list", () => {
|
||||
beforeEach(() => {
|
||||
@@ -30,7 +30,7 @@ describe("agents_list", () => {
|
||||
});
|
||||
|
||||
it("defaults to the requester agent only", async () => {
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
}).find((candidate) => candidate.name === "agents_list");
|
||||
if (!tool) throw new Error("missing agents_list tool");
|
||||
@@ -67,7 +67,7 @@ describe("agents_list", () => {
|
||||
},
|
||||
};
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
}).find((candidate) => candidate.name === "agents_list");
|
||||
if (!tool) throw new Error("missing agents_list tool");
|
||||
@@ -107,7 +107,7 @@ describe("agents_list", () => {
|
||||
},
|
||||
};
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
}).find((candidate) => candidate.name === "agents_list");
|
||||
if (!tool) throw new Error("missing agents_list tool");
|
||||
@@ -142,7 +142,7 @@ describe("agents_list", () => {
|
||||
},
|
||||
};
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
}).find((candidate) => candidate.name === "agents_list");
|
||||
if (!tool) throw new Error("missing agents_list tool");
|
||||
@@ -11,7 +11,7 @@ vi.mock("../media/image-ops.js", () => ({
|
||||
}));
|
||||
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
|
||||
describe("nodes camera_snap", () => {
|
||||
beforeEach(() => {
|
||||
@@ -36,7 +36,7 @@ describe("nodes camera_snap", () => {
|
||||
throw new Error(`unexpected method: ${String(method)}`);
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools().find((candidate) => candidate.name === "nodes");
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "nodes");
|
||||
if (!tool) throw new Error("missing nodes tool");
|
||||
|
||||
const result = await tool.execute("call1", {
|
||||
@@ -72,7 +72,7 @@ describe("nodes camera_snap", () => {
|
||||
throw new Error(`unexpected method: ${String(method)}`);
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools().find((candidate) => candidate.name === "nodes");
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "nodes");
|
||||
if (!tool) throw new Error("missing nodes tool");
|
||||
|
||||
await tool.execute("call1", {
|
||||
@@ -113,7 +113,7 @@ describe("nodes run", () => {
|
||||
throw new Error(`unexpected method: ${String(method)}`);
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools().find((candidate) => candidate.name === "nodes");
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "nodes");
|
||||
if (!tool) throw new Error("missing nodes tool");
|
||||
|
||||
await tool.execute("call1", {
|
||||
@@ -77,7 +77,7 @@ vi.mock("../infra/provider-usage.js", () => ({
|
||||
}));
|
||||
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
|
||||
describe("session_status tool", () => {
|
||||
it("returns a status card for the current session", async () => {
|
||||
@@ -90,7 +90,7 @@ describe("session_status tool", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({ agentSessionKey: "main" }).find(
|
||||
const tool = createOpenClawTools({ agentSessionKey: "main" }).find(
|
||||
(candidate) => candidate.name === "session_status",
|
||||
);
|
||||
expect(tool).toBeDefined();
|
||||
@@ -99,7 +99,7 @@ describe("session_status tool", () => {
|
||||
const result = await tool.execute("call1", {});
|
||||
const details = result.details as { ok?: boolean; statusText?: string };
|
||||
expect(details.ok).toBe(true);
|
||||
expect(details.statusText).toContain("Moltbot");
|
||||
expect(details.statusText).toContain("OpenClaw");
|
||||
expect(details.statusText).toContain("🧠 Model:");
|
||||
expect(details.statusText).not.toContain("OAuth/token status");
|
||||
});
|
||||
@@ -111,7 +111,7 @@ describe("session_status tool", () => {
|
||||
main: { sessionId: "s1", updatedAt: 10 },
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({ agentSessionKey: "main" }).find(
|
||||
const tool = createOpenClawTools({ agentSessionKey: "main" }).find(
|
||||
(candidate) => candidate.name === "session_status",
|
||||
);
|
||||
expect(tool).toBeDefined();
|
||||
@@ -134,7 +134,7 @@ describe("session_status tool", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({ agentSessionKey: "main" }).find(
|
||||
const tool = createOpenClawTools({ agentSessionKey: "main" }).find(
|
||||
(candidate) => candidate.name === "session_status",
|
||||
);
|
||||
expect(tool).toBeDefined();
|
||||
@@ -156,7 +156,7 @@ describe("session_status tool", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({ agentSessionKey: "main" }).find(
|
||||
const tool = createOpenClawTools({ agentSessionKey: "main" }).find(
|
||||
(candidate) => candidate.name === "session_status",
|
||||
);
|
||||
expect(tool).toBeDefined();
|
||||
@@ -178,7 +178,7 @@ describe("session_status tool", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({ agentSessionKey: "agent:main:main" }).find(
|
||||
const tool = createOpenClawTools({ agentSessionKey: "agent:main:main" }).find(
|
||||
(candidate) => candidate.name === "session_status",
|
||||
);
|
||||
expect(tool).toBeDefined();
|
||||
@@ -218,7 +218,7 @@ describe("session_status tool", () => {
|
||||
},
|
||||
);
|
||||
|
||||
const tool = createMoltbotTools({ agentSessionKey: "agent:support:main" }).find(
|
||||
const tool = createOpenClawTools({ agentSessionKey: "agent:support:main" }).find(
|
||||
(candidate) => candidate.name === "session_status",
|
||||
);
|
||||
expect(tool).toBeDefined();
|
||||
@@ -243,7 +243,7 @@ describe("session_status tool", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({ agentSessionKey: "main" }).find(
|
||||
const tool = createOpenClawTools({ agentSessionKey: "main" }).find(
|
||||
(candidate) => candidate.name === "session_status",
|
||||
);
|
||||
expect(tool).toBeDefined();
|
||||
@@ -21,7 +21,7 @@ vi.mock("../config/config.js", async (importOriginal) => {
|
||||
});
|
||||
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
|
||||
const waitForCalls = async (getCount: () => number, count: number, timeoutMs = 2000) => {
|
||||
const start = Date.now();
|
||||
@@ -35,7 +35,7 @@ const waitForCalls = async (getCount: () => number, count: number, timeoutMs = 2
|
||||
|
||||
describe("sessions tools", () => {
|
||||
it("uses number (not integer) in tool schemas for Gemini compatibility", () => {
|
||||
const tools = createMoltbotTools();
|
||||
const tools = createOpenClawTools();
|
||||
const byName = (name: string) => {
|
||||
const tool = tools.find((candidate) => candidate.name === name);
|
||||
expect(tool).toBeDefined();
|
||||
@@ -118,7 +118,7 @@ describe("sessions tools", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools().find((candidate) => candidate.name === "sessions_list");
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "sessions_list");
|
||||
expect(tool).toBeDefined();
|
||||
if (!tool) throw new Error("missing sessions_list tool");
|
||||
|
||||
@@ -155,7 +155,7 @@ describe("sessions tools", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools().find((candidate) => candidate.name === "sessions_history");
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "sessions_history");
|
||||
expect(tool).toBeDefined();
|
||||
if (!tool) throw new Error("missing sessions_history tool");
|
||||
|
||||
@@ -191,7 +191,7 @@ describe("sessions tools", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools().find((candidate) => candidate.name === "sessions_history");
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "sessions_history");
|
||||
expect(tool).toBeDefined();
|
||||
if (!tool) throw new Error("missing sessions_history tool");
|
||||
|
||||
@@ -218,7 +218,7 @@ describe("sessions tools", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools().find((candidate) => candidate.name === "sessions_history");
|
||||
const tool = createOpenClawTools().find((candidate) => candidate.name === "sessions_history");
|
||||
expect(tool).toBeDefined();
|
||||
if (!tool) throw new Error("missing sessions_history tool");
|
||||
|
||||
@@ -290,7 +290,7 @@ describe("sessions tools", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: requesterKey,
|
||||
agentChannel: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_send");
|
||||
@@ -390,7 +390,7 @@ describe("sessions tools", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_send");
|
||||
@@ -480,7 +480,7 @@ describe("sessions tools", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: requesterKey,
|
||||
agentChannel: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_send");
|
||||
@@ -22,10 +22,10 @@ vi.mock("../config/config.js", async (importOriginal) => {
|
||||
});
|
||||
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
import { resetSubagentRegistryForTests } from "./subagent-registry.js";
|
||||
|
||||
describe("moltbot-tools: subagents", () => {
|
||||
describe("openclaw-tools: subagents", () => {
|
||||
beforeEach(() => {
|
||||
configOverride = {
|
||||
session: {
|
||||
@@ -69,7 +69,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "whatsapp",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -120,7 +120,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "whatsapp",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -22,10 +22,10 @@ vi.mock("../config/config.js", async (importOriginal) => {
|
||||
});
|
||||
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
import { resetSubagentRegistryForTests } from "./subagent-registry.js";
|
||||
|
||||
describe("moltbot-tools: subagents", () => {
|
||||
describe("openclaw-tools: subagents", () => {
|
||||
beforeEach(() => {
|
||||
configOverride = {
|
||||
session: {
|
||||
@@ -89,7 +89,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "discord:group:req",
|
||||
agentChannel: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -22,10 +22,10 @@ vi.mock("../config/config.js", async (importOriginal) => {
|
||||
});
|
||||
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
import { resetSubagentRegistryForTests } from "./subagent-registry.js";
|
||||
|
||||
describe("moltbot-tools: subagents", () => {
|
||||
describe("openclaw-tools: subagents", () => {
|
||||
beforeEach(() => {
|
||||
configOverride = {
|
||||
session: {
|
||||
@@ -65,7 +65,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "discord:group:req",
|
||||
agentSurface: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -108,7 +108,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "discord:group:req",
|
||||
agentChannel: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -139,7 +139,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "discord:group:req",
|
||||
agentChannel: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -176,7 +176,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "agent:main:main",
|
||||
agentChannel: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -23,10 +23,10 @@ vi.mock("../config/config.js", async (importOriginal) => {
|
||||
|
||||
import { emitAgentEvent } from "../infra/agent-events.js";
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
import { resetSubagentRegistryForTests } from "./subagent-registry.js";
|
||||
|
||||
describe("moltbot-tools: subagents", () => {
|
||||
describe("openclaw-tools: subagents", () => {
|
||||
beforeEach(() => {
|
||||
configOverride = {
|
||||
session: {
|
||||
@@ -70,7 +70,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "whatsapp",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -107,7 +107,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
},
|
||||
};
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "whatsapp",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -171,7 +171,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "discord:group:req",
|
||||
agentChannel: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -272,7 +272,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "whatsapp",
|
||||
agentAccountId: "kev",
|
||||
@@ -22,10 +22,10 @@ vi.mock("../config/config.js", async (importOriginal) => {
|
||||
});
|
||||
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
import { resetSubagentRegistryForTests } from "./subagent-registry.js";
|
||||
|
||||
describe("moltbot-tools: subagents", () => {
|
||||
describe("openclaw-tools: subagents", () => {
|
||||
beforeEach(() => {
|
||||
configOverride = {
|
||||
session: {
|
||||
@@ -59,7 +59,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "agent:research:main",
|
||||
agentChannel: "discord",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -108,7 +108,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "whatsapp",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -143,7 +143,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "whatsapp",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -23,10 +23,10 @@ vi.mock("../config/config.js", async (importOriginal) => {
|
||||
|
||||
import { emitAgentEvent } from "../infra/agent-events.js";
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import { createMoltbotTools } from "./moltbot-tools.js";
|
||||
import { createOpenClawTools } from "./openclaw-tools.js";
|
||||
import { resetSubagentRegistryForTests } from "./subagent-registry.js";
|
||||
|
||||
describe("moltbot-tools: subagents", () => {
|
||||
describe("openclaw-tools: subagents", () => {
|
||||
beforeEach(() => {
|
||||
configOverride = {
|
||||
session: {
|
||||
@@ -95,7 +95,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
return {};
|
||||
});
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "whatsapp",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -155,7 +155,7 @@ describe("moltbot-tools: subagents", () => {
|
||||
resetSubagentRegistryForTests();
|
||||
callGatewayMock.mockReset();
|
||||
|
||||
const tool = createMoltbotTools({
|
||||
const tool = createOpenClawTools({
|
||||
agentSessionKey: "main",
|
||||
agentChannel: "whatsapp",
|
||||
}).find((candidate) => candidate.name === "sessions_spawn");
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolvePluginTools } from "../plugins/tools.js";
|
||||
import type { GatewayMessageChannel } from "../utils/message-channel.js";
|
||||
import { resolveSessionAgentId } from "./agent-scope.js";
|
||||
@@ -19,7 +19,7 @@ import { createSessionsSpawnTool } from "./tools/sessions-spawn-tool.js";
|
||||
import { createWebFetchTool, createWebSearchTool } from "./tools/web-tools.js";
|
||||
import { createTtsTool } from "./tools/tts-tool.js";
|
||||
|
||||
export function createMoltbotTools(options?: {
|
||||
export function createOpenClawTools(options?: {
|
||||
sandboxBrowserBridgeUrl?: string;
|
||||
allowHostBrowserControl?: boolean;
|
||||
agentSessionKey?: string;
|
||||
@@ -39,7 +39,7 @@ export function createMoltbotTools(options?: {
|
||||
sandboxRoot?: string;
|
||||
workspaceDir?: string;
|
||||
sandboxed?: boolean;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
pluginToolAllowlist?: string[];
|
||||
/** Current channel ID for auto-threading (Slack). */
|
||||
currentChannelId?: string;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { DEFAULT_BOOTSTRAP_MAX_CHARS, resolveBootstrapMaxChars } from "./pi-embedded-helpers.js";
|
||||
import { DEFAULT_AGENTS_FILENAME } from "./workspace.js";
|
||||
|
||||
@@ -17,13 +17,13 @@ describe("resolveBootstrapMaxChars", () => {
|
||||
it("uses configured value when valid", () => {
|
||||
const cfg = {
|
||||
agents: { defaults: { bootstrapMaxChars: 12345 } },
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(resolveBootstrapMaxChars(cfg)).toBe(12345);
|
||||
});
|
||||
it("falls back when invalid", () => {
|
||||
const cfg = {
|
||||
agents: { defaults: { bootstrapMaxChars: -1 } },
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(resolveBootstrapMaxChars(cfg)).toBe(DEFAULT_BOOTSTRAP_MAX_CHARS);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from "node:path";
|
||||
|
||||
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
||||
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import type { WorkspaceBootstrapFile } from "../workspace.js";
|
||||
import type { EmbeddedContextFile } from "./types.js";
|
||||
|
||||
@@ -80,7 +80,7 @@ type TrimBootstrapResult = {
|
||||
originalLength: number;
|
||||
};
|
||||
|
||||
export function resolveBootstrapMaxChars(cfg?: MoltbotConfig): number {
|
||||
export function resolveBootstrapMaxChars(cfg?: OpenClawConfig): number {
|
||||
const raw = cfg?.agents?.defaults?.bootstrapMaxChars;
|
||||
if (typeof raw === "number" && Number.isFinite(raw) && raw > 0) {
|
||||
return Math.floor(raw);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AssistantMessage } from "@mariozechner/pi-ai";
|
||||
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { formatSandboxToolPolicyBlockedMessage } from "../sandbox.js";
|
||||
import type { FailoverReason } from "./types.js";
|
||||
|
||||
@@ -252,7 +252,7 @@ export function formatRawAssistantErrorForUi(raw?: string): string {
|
||||
|
||||
export function formatAssistantErrorText(
|
||||
msg: AssistantMessage,
|
||||
opts?: { cfg?: MoltbotConfig; sessionKey?: string },
|
||||
opts?: { cfg?: OpenClawConfig; sessionKey?: string },
|
||||
): string | undefined {
|
||||
// Also format errors if errorMessage is present, even if stopReason isn't "error"
|
||||
const raw = (msg.errorMessage ?? "").trim();
|
||||
|
||||
@@ -51,7 +51,7 @@ function hasFollowingNonThinkingBlock(
|
||||
* OpenAI Responses API can reject transcripts that contain a standalone `reasoning` item id
|
||||
* without the required following item.
|
||||
*
|
||||
* Moltbot persists provider-specific reasoning metadata in `thinkingSignature`; if that metadata
|
||||
* OpenClaw persists provider-specific reasoning metadata in `thinkingSignature`; if that metadata
|
||||
* is incomplete, drop the block to keep history usable.
|
||||
*/
|
||||
export function downgradeOpenAIReasoningBlocks(messages: AgentMessage[]): AgentMessage[] {
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { Model } from "@mariozechner/pi-ai";
|
||||
import { getModel, streamSimple } from "@mariozechner/pi-ai";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { applyExtraParamsToAgent } from "./pi-embedded-runner.js";
|
||||
|
||||
const OPENAI_KEY = process.env.OPENAI_API_KEY ?? "";
|
||||
@@ -14,7 +14,7 @@ describeLive("pi embedded extra params (live)", () => {
|
||||
it("applies config maxTokens to openai streamFn", async () => {
|
||||
const model = getModel("openai", "gpt-5.2") as Model<"openai-completions">;
|
||||
|
||||
const cfg: MoltbotConfig = {
|
||||
const cfg: OpenClawConfig = {
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
|
||||
@@ -2,8 +2,8 @@ import fs from "node:fs/promises";
|
||||
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
||||
import { SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
import { applyGoogleTurnOrderingFix } from "./pi-embedded-runner.js";
|
||||
|
||||
vi.mock("@mariozechner/pi-ai", async () => {
|
||||
@@ -69,10 +69,10 @@ const _makeOpenAiConfig = (modelIds: string[]) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const _ensureModels = (cfg: MoltbotConfig, agentDir: string) =>
|
||||
ensureMoltbotModelsJson(cfg, agentDir) as unknown;
|
||||
const _ensureModels = (cfg: OpenClawConfig, agentDir: string) =>
|
||||
ensureOpenClawModelsJson(cfg, agentDir) as unknown;
|
||||
|
||||
const _textFromContent = (content: unknown) => {
|
||||
if (typeof content === "string") return content;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
import { buildEmbeddedSandboxInfo } from "./pi-embedded-runner.js";
|
||||
import type { SandboxContext } from "./sandbox.js";
|
||||
|
||||
@@ -68,10 +68,10 @@ const _makeOpenAiConfig = (modelIds: string[]) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const _ensureModels = (cfg: MoltbotConfig, agentDir: string) =>
|
||||
ensureMoltbotModelsJson(cfg, agentDir) as unknown;
|
||||
const _ensureModels = (cfg: OpenClawConfig, agentDir: string) =>
|
||||
ensureOpenClawModelsJson(cfg, agentDir) as unknown;
|
||||
|
||||
const _textFromContent = (content: unknown) => {
|
||||
if (typeof content === "string") return content;
|
||||
@@ -105,14 +105,14 @@ describe("buildEmbeddedSandboxInfo", () => {
|
||||
const sandbox = {
|
||||
enabled: true,
|
||||
sessionKey: "session:test",
|
||||
workspaceDir: "/tmp/moltbot-sandbox",
|
||||
agentWorkspaceDir: "/tmp/moltbot-workspace",
|
||||
workspaceDir: "/tmp/openclaw-sandbox",
|
||||
agentWorkspaceDir: "/tmp/openclaw-workspace",
|
||||
workspaceAccess: "none",
|
||||
containerName: "moltbot-sbx-test",
|
||||
containerName: "openclaw-sbx-test",
|
||||
containerWorkdir: "/workspace",
|
||||
docker: {
|
||||
image: "moltbot-sandbox:bookworm-slim",
|
||||
containerPrefix: "moltbot-sbx-",
|
||||
image: "openclaw-sandbox:bookworm-slim",
|
||||
containerPrefix: "openclaw-sbx-",
|
||||
workdir: "/workspace",
|
||||
readOnlyRoot: true,
|
||||
tmpfs: ["/tmp"],
|
||||
@@ -129,13 +129,13 @@ describe("buildEmbeddedSandboxInfo", () => {
|
||||
browser: {
|
||||
bridgeUrl: "http://localhost:9222",
|
||||
noVncUrl: "http://localhost:6080",
|
||||
containerName: "moltbot-sbx-browser-test",
|
||||
containerName: "openclaw-sbx-browser-test",
|
||||
},
|
||||
} satisfies SandboxContext;
|
||||
|
||||
expect(buildEmbeddedSandboxInfo(sandbox)).toEqual({
|
||||
enabled: true,
|
||||
workspaceDir: "/tmp/moltbot-sandbox",
|
||||
workspaceDir: "/tmp/openclaw-sandbox",
|
||||
workspaceAccess: "none",
|
||||
agentWorkspaceMount: undefined,
|
||||
browserBridgeUrl: "http://localhost:9222",
|
||||
@@ -147,14 +147,14 @@ describe("buildEmbeddedSandboxInfo", () => {
|
||||
const sandbox = {
|
||||
enabled: true,
|
||||
sessionKey: "session:test",
|
||||
workspaceDir: "/tmp/moltbot-sandbox",
|
||||
agentWorkspaceDir: "/tmp/moltbot-workspace",
|
||||
workspaceDir: "/tmp/openclaw-sandbox",
|
||||
agentWorkspaceDir: "/tmp/openclaw-workspace",
|
||||
workspaceAccess: "none",
|
||||
containerName: "moltbot-sbx-test",
|
||||
containerName: "openclaw-sbx-test",
|
||||
containerWorkdir: "/workspace",
|
||||
docker: {
|
||||
image: "moltbot-sandbox:bookworm-slim",
|
||||
containerPrefix: "moltbot-sbx-",
|
||||
image: "openclaw-sandbox:bookworm-slim",
|
||||
containerPrefix: "openclaw-sbx-",
|
||||
workdir: "/workspace",
|
||||
readOnlyRoot: true,
|
||||
tmpfs: ["/tmp"],
|
||||
@@ -178,7 +178,7 @@ describe("buildEmbeddedSandboxInfo", () => {
|
||||
}),
|
||||
).toEqual({
|
||||
enabled: true,
|
||||
workspaceDir: "/tmp/moltbot-sandbox",
|
||||
workspaceDir: "/tmp/openclaw-sandbox",
|
||||
workspaceAccess: "none",
|
||||
agentWorkspaceMount: undefined,
|
||||
hostBrowserAllowed: false,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
import { createSystemPromptOverride } from "./pi-embedded-runner.js";
|
||||
|
||||
vi.mock("@mariozechner/pi-ai", async () => {
|
||||
@@ -67,10 +67,10 @@ const _makeOpenAiConfig = (modelIds: string[]) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const _ensureModels = (cfg: MoltbotConfig, agentDir: string) =>
|
||||
ensureMoltbotModelsJson(cfg, agentDir) as unknown;
|
||||
const _ensureModels = (cfg: OpenClawConfig, agentDir: string) =>
|
||||
ensureOpenClawModelsJson(cfg, agentDir) as unknown;
|
||||
|
||||
const _textFromContent = (content: unknown) => {
|
||||
if (typeof content === "string") return content;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
import { getDmHistoryLimitFromSessionKey } from "./pi-embedded-runner.js";
|
||||
|
||||
vi.mock("@mariozechner/pi-ai", async () => {
|
||||
@@ -67,10 +67,10 @@ const _makeOpenAiConfig = (modelIds: string[]) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const _ensureModels = (cfg: MoltbotConfig, agentDir: string) =>
|
||||
ensureMoltbotModelsJson(cfg, agentDir);
|
||||
const _ensureModels = (cfg: OpenClawConfig, agentDir: string) =>
|
||||
ensureOpenClawModelsJson(cfg, agentDir);
|
||||
|
||||
const _textFromContent = (content: unknown) => {
|
||||
if (typeof content === "string") return content;
|
||||
@@ -105,7 +105,7 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
dms: { "456": { historyLimit: 5 } },
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("telegram:dm:123", config)).toBe(15);
|
||||
});
|
||||
it("returns per-DM override for agent-prefixed keys", () => {
|
||||
@@ -116,7 +116,7 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
dms: { "789": { historyLimit: 3 } },
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("agent:main:telegram:dm:789", config)).toBe(3);
|
||||
});
|
||||
it("handles userId with colons (e.g., email)", () => {
|
||||
@@ -127,7 +127,7 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
dms: { "user@example.com": { historyLimit: 7 } },
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("msteams:dm:user@example.com", config)).toBe(7);
|
||||
});
|
||||
it("returns undefined when per-DM historyLimit is not set", () => {
|
||||
@@ -137,7 +137,7 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
dms: { "123": {} },
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("telegram:dm:123", config)).toBeUndefined();
|
||||
});
|
||||
it("returns 0 when per-DM historyLimit is explicitly 0 (unlimited)", () => {
|
||||
@@ -148,7 +148,7 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
dms: { "123": { historyLimit: 0 } },
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("telegram:dm:123", config)).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
import { getDmHistoryLimitFromSessionKey } from "./pi-embedded-runner.js";
|
||||
|
||||
vi.mock("@mariozechner/pi-ai", async () => {
|
||||
@@ -67,10 +67,10 @@ const _makeOpenAiConfig = (modelIds: string[]) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const _ensureModels = (cfg: MoltbotConfig, agentDir: string) =>
|
||||
ensureMoltbotModelsJson(cfg, agentDir) as unknown;
|
||||
const _ensureModels = (cfg: OpenClawConfig, agentDir: string) =>
|
||||
ensureOpenClawModelsJson(cfg, agentDir) as unknown;
|
||||
|
||||
const _textFromContent = (content: unknown) => {
|
||||
if (typeof content === "string") return content;
|
||||
@@ -106,25 +106,25 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
it("returns dmHistoryLimit for telegram provider", () => {
|
||||
const config = {
|
||||
channels: { telegram: { dmHistoryLimit: 15 } },
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("telegram:dm:123", config)).toBe(15);
|
||||
});
|
||||
it("returns dmHistoryLimit for whatsapp provider", () => {
|
||||
const config = {
|
||||
channels: { whatsapp: { dmHistoryLimit: 20 } },
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("whatsapp:dm:123", config)).toBe(20);
|
||||
});
|
||||
it("returns dmHistoryLimit for agent-prefixed session keys", () => {
|
||||
const config = {
|
||||
channels: { telegram: { dmHistoryLimit: 10 } },
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("agent:main:telegram:dm:123", config)).toBe(10);
|
||||
});
|
||||
it("strips thread suffix from dm session keys", () => {
|
||||
const config = {
|
||||
channels: { telegram: { dmHistoryLimit: 10, dms: { "123": { historyLimit: 7 } } } },
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("agent:main:telegram:dm:123:thread:999", config)).toBe(
|
||||
7,
|
||||
);
|
||||
@@ -136,7 +136,7 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
channels: {
|
||||
telegram: { dms: { "user:thread:abc": { historyLimit: 9 } } },
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("agent:main:telegram:dm:user:thread:abc", config)).toBe(
|
||||
9,
|
||||
);
|
||||
@@ -147,18 +147,18 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
telegram: { dmHistoryLimit: 15 },
|
||||
slack: { dmHistoryLimit: 10 },
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("agent:beta:slack:channel:c1", config)).toBeUndefined();
|
||||
expect(getDmHistoryLimitFromSessionKey("telegram:slash:123", config)).toBeUndefined();
|
||||
});
|
||||
it("returns undefined for unknown provider", () => {
|
||||
const config = {
|
||||
channels: { telegram: { dmHistoryLimit: 15 } },
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("unknown:dm:123", config)).toBeUndefined();
|
||||
});
|
||||
it("returns undefined when provider config has no dmHistoryLimit", () => {
|
||||
const config = { channels: { telegram: {} } } as MoltbotConfig;
|
||||
const config = { channels: { telegram: {} } } as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("telegram:dm:123", config)).toBeUndefined();
|
||||
});
|
||||
it("handles all supported providers", () => {
|
||||
@@ -176,7 +176,7 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
for (const provider of providers) {
|
||||
const config = {
|
||||
channels: { [provider]: { dmHistoryLimit: 5 } },
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey(`${provider}:dm:123`, config)).toBe(5);
|
||||
}
|
||||
});
|
||||
@@ -201,7 +201,7 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
dms: { user123: { historyLimit: 7 } },
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey(`${provider}:dm:user123`, configWithOverride)).toBe(7);
|
||||
|
||||
// Test fallback to provider default when user not in dms
|
||||
@@ -223,7 +223,7 @@ describe("getDmHistoryLimitFromSessionKey", () => {
|
||||
dms: { "123": { historyLimit: 5 } },
|
||||
},
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
expect(getDmHistoryLimitFromSessionKey("telegram:dm:123", config)).toBe(5);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import fs from "node:fs/promises";
|
||||
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
import { limitHistoryTurns } from "./pi-embedded-runner.js";
|
||||
|
||||
vi.mock("@mariozechner/pi-ai", async () => {
|
||||
@@ -68,10 +68,10 @@ const _makeOpenAiConfig = (modelIds: string[]) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const _ensureModels = (cfg: MoltbotConfig, agentDir: string) =>
|
||||
ensureMoltbotModelsJson(cfg, agentDir) as unknown;
|
||||
const _ensureModels = (cfg: OpenClawConfig, agentDir: string) =>
|
||||
ensureOpenClawModelsJson(cfg, agentDir) as unknown;
|
||||
|
||||
const _textFromContent = (content: unknown) => {
|
||||
if (typeof content === "string") return content;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import fs from "node:fs/promises";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveSessionAgentIds } from "./agent-scope.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
|
||||
vi.mock("@mariozechner/pi-ai", async () => {
|
||||
const actual = await vi.importActual<typeof import("@mariozechner/pi-ai")>("@mariozechner/pi-ai");
|
||||
@@ -67,10 +67,10 @@ const _makeOpenAiConfig = (modelIds: string[]) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const _ensureModels = (cfg: MoltbotConfig, agentDir: string) =>
|
||||
ensureMoltbotModelsJson(cfg, agentDir) as unknown;
|
||||
const _ensureModels = (cfg: OpenClawConfig, agentDir: string) =>
|
||||
ensureOpenClawModelsJson(cfg, agentDir) as unknown;
|
||||
|
||||
const _textFromContent = (content: unknown) => {
|
||||
if (typeof content === "string") return content;
|
||||
@@ -101,7 +101,7 @@ describe("resolveSessionAgentIds", () => {
|
||||
agents: {
|
||||
list: [{ id: "main" }, { id: "beta", default: true }],
|
||||
},
|
||||
} as MoltbotConfig;
|
||||
} as OpenClawConfig;
|
||||
|
||||
it("falls back to the configured default when sessionKey is missing", () => {
|
||||
const { defaultAgentId, sessionAgentId } = resolveSessionAgentIds({
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from "node:path";
|
||||
import type { AssistantMessage } from "@mariozechner/pi-ai";
|
||||
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { EmbeddedRunAttemptResult } from "./pi-embedded-runner/run/types.js";
|
||||
|
||||
const runEmbeddedAttemptMock = vi.fn<Promise<EmbeddedRunAttemptResult>, [unknown]>();
|
||||
@@ -63,7 +63,7 @@ const makeAttempt = (overrides: Partial<EmbeddedRunAttemptResult>): EmbeddedRunA
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const makeConfig = (opts?: { fallbacks?: string[]; apiKey?: string }): MoltbotConfig =>
|
||||
const makeConfig = (opts?: { fallbacks?: string[]; apiKey?: string }): OpenClawConfig =>
|
||||
({
|
||||
agents: {
|
||||
defaults: {
|
||||
@@ -92,7 +92,7 @@ const makeConfig = (opts?: { fallbacks?: string[]; apiKey?: string }): MoltbotCo
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const writeAuthStore = async (
|
||||
agentDir: string,
|
||||
@@ -123,8 +123,8 @@ const writeAuthStore = async (
|
||||
|
||||
describe("runEmbeddedPiAgent auth profile rotation", () => {
|
||||
it("rotates for auto-pinned profiles", async () => {
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-workspace-"));
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-workspace-"));
|
||||
try {
|
||||
await writeAuthStore(agentDir);
|
||||
|
||||
@@ -177,8 +177,8 @@ describe("runEmbeddedPiAgent auth profile rotation", () => {
|
||||
});
|
||||
|
||||
it("does not rotate for user-pinned profiles", async () => {
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-workspace-"));
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-workspace-"));
|
||||
try {
|
||||
await writeAuthStore(agentDir);
|
||||
|
||||
@@ -223,8 +223,8 @@ describe("runEmbeddedPiAgent auth profile rotation", () => {
|
||||
it("honors user-pinned profiles even when in cooldown", async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-workspace-"));
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-workspace-"));
|
||||
const now = Date.now();
|
||||
vi.setSystemTime(now);
|
||||
|
||||
@@ -289,8 +289,8 @@ describe("runEmbeddedPiAgent auth profile rotation", () => {
|
||||
});
|
||||
|
||||
it("ignores user-locked profile when provider mismatches", async () => {
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-workspace-"));
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-workspace-"));
|
||||
try {
|
||||
await writeAuthStore(agentDir, { includeAnthropic: true });
|
||||
|
||||
@@ -330,8 +330,8 @@ describe("runEmbeddedPiAgent auth profile rotation", () => {
|
||||
it("skips profiles in cooldown during initial selection", async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-workspace-"));
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-workspace-"));
|
||||
const now = Date.now();
|
||||
vi.setSystemTime(now);
|
||||
|
||||
@@ -395,8 +395,8 @@ describe("runEmbeddedPiAgent auth profile rotation", () => {
|
||||
it("fails over when all profiles are in cooldown and fallbacks are configured", async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-workspace-"));
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-workspace-"));
|
||||
const now = Date.now();
|
||||
vi.setSystemTime(now);
|
||||
|
||||
@@ -441,8 +441,8 @@ describe("runEmbeddedPiAgent auth profile rotation", () => {
|
||||
});
|
||||
|
||||
it("fails over when auth is unavailable and fallbacks are configured", async () => {
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-workspace-"));
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-workspace-"));
|
||||
const previousOpenAiKey = process.env.OPENAI_API_KEY;
|
||||
delete process.env.OPENAI_API_KEY;
|
||||
try {
|
||||
@@ -481,8 +481,8 @@ describe("runEmbeddedPiAgent auth profile rotation", () => {
|
||||
it("skips profiles in cooldown when rotating after failure", async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-workspace-"));
|
||||
const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-agent-"));
|
||||
const workspaceDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-workspace-"));
|
||||
const now = Date.now();
|
||||
vi.setSystemTime(now);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import fs from "node:fs/promises";
|
||||
import type { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
import { splitSdkTools } from "./pi-embedded-runner.js";
|
||||
|
||||
vi.mock("@mariozechner/pi-ai", async () => {
|
||||
@@ -68,10 +68,10 @@ const _makeOpenAiConfig = (modelIds: string[]) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const _ensureModels = (cfg: MoltbotConfig, agentDir: string) =>
|
||||
ensureMoltbotModelsJson(cfg, agentDir) as unknown;
|
||||
const _ensureModels = (cfg: OpenClawConfig, agentDir: string) =>
|
||||
ensureOpenClawModelsJson(cfg, agentDir) as unknown;
|
||||
|
||||
const _textFromContent = (content: unknown) => {
|
||||
if (typeof content === "string") return content;
|
||||
|
||||
@@ -4,8 +4,8 @@ import path from "node:path";
|
||||
|
||||
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import "./test-helpers/fast-coding-tools.js";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
import { ensureMoltbotModelsJson } from "./models-config.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { ensureOpenClawModelsJson } from "./models-config.js";
|
||||
|
||||
vi.mock("@mariozechner/pi-ai", async () => {
|
||||
const actual = await vi.importActual<typeof import("@mariozechner/pi-ai")>("@mariozechner/pi-ai");
|
||||
@@ -96,7 +96,7 @@ let sessionCounter = 0;
|
||||
beforeAll(async () => {
|
||||
vi.useRealTimers();
|
||||
({ runEmbeddedPiAgent } = await import("./pi-embedded-runner.js"));
|
||||
tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-embedded-agent-"));
|
||||
tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-embedded-agent-"));
|
||||
agentDir = path.join(tempRoot, "agent");
|
||||
workspaceDir = path.join(tempRoot, "workspace");
|
||||
await fs.mkdir(agentDir, { recursive: true });
|
||||
@@ -129,9 +129,9 @@ const makeOpenAiConfig = (modelIds: string[]) =>
|
||||
},
|
||||
},
|
||||
},
|
||||
}) satisfies MoltbotConfig;
|
||||
}) satisfies OpenClawConfig;
|
||||
|
||||
const ensureModels = (cfg: MoltbotConfig) => ensureMoltbotModelsJson(cfg, agentDir) as unknown;
|
||||
const ensureModels = (cfg: OpenClawConfig) => ensureOpenClawModelsJson(cfg, agentDir) as unknown;
|
||||
|
||||
const nextSessionFile = () => {
|
||||
sessionCounter += 1;
|
||||
@@ -191,7 +191,7 @@ describe("runEmbeddedPiAgent", () => {
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies MoltbotConfig;
|
||||
} satisfies OpenClawConfig;
|
||||
|
||||
await expect(
|
||||
runEmbeddedPiAgent({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
type CustomEntryLike = { type?: unknown; customType?: unknown; data?: unknown };
|
||||
|
||||
export const CACHE_TTL_CUSTOM_TYPE = "moltbot.cache-ttl";
|
||||
export const CACHE_TTL_CUSTOM_TYPE = "openclaw.cache-ttl";
|
||||
|
||||
export type CacheTtlEntryData = {
|
||||
timestamp: number;
|
||||
|
||||
@@ -12,7 +12,7 @@ import { resolveHeartbeatPrompt } from "../../auto-reply/heartbeat.js";
|
||||
import type { ReasoningLevel, ThinkLevel } from "../../auto-reply/thinking.js";
|
||||
import { listChannelSupportedActions, resolveChannelMessageToolHints } from "../channel-tools.js";
|
||||
import { resolveChannelCapabilities } from "../../config/channel-capabilities.js";
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { getMachineDisplayName } from "../../infra/machine-name.js";
|
||||
import { resolveTelegramInlineButtonsScope } from "../../telegram/inline-buttons.js";
|
||||
import { resolveTelegramReactionLevel } from "../../telegram/reaction-level.js";
|
||||
@@ -22,14 +22,14 @@ import { normalizeMessageChannel } from "../../utils/message-channel.js";
|
||||
import { isSubagentSessionKey } from "../../routing/session-key.js";
|
||||
import { isReasoningTagProvider } from "../../utils/provider-utils.js";
|
||||
import { resolveUserPath } from "../../utils.js";
|
||||
import { resolveMoltbotAgentDir } from "../agent-paths.js";
|
||||
import { resolveOpenClawAgentDir } from "../agent-paths.js";
|
||||
import { resolveSessionAgentIds } from "../agent-scope.js";
|
||||
import { makeBootstrapWarn, resolveBootstrapContextForRun } from "../bootstrap-files.js";
|
||||
import { resolveMoltbotDocsPath } from "../docs-path.js";
|
||||
import { resolveOpenClawDocsPath } from "../docs-path.js";
|
||||
import type { ExecElevatedDefaults } from "../bash-tools.js";
|
||||
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../defaults.js";
|
||||
import { getApiKeyForModel, resolveModelAuthMode } from "../model-auth.js";
|
||||
import { ensureMoltbotModelsJson } from "../models-config.js";
|
||||
import { ensureOpenClawModelsJson } from "../models-config.js";
|
||||
import {
|
||||
ensureSessionHeader,
|
||||
validateAnthropicTurns,
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
ensurePiCompactionReserveTokens,
|
||||
resolveCompactionReserveTokensFloor,
|
||||
} from "../pi-settings.js";
|
||||
import { createMoltbotCodingTools } from "../pi-tools.js";
|
||||
import { createOpenClawCodingTools } from "../pi-tools.js";
|
||||
import { resolveSandboxContext } from "../sandbox.js";
|
||||
import { guardSessionManager } from "../session-tool-result-guard-wrapper.js";
|
||||
import { resolveTranscriptPolicy } from "../transcript-policy.js";
|
||||
@@ -88,7 +88,7 @@ export type CompactEmbeddedPiSessionParams = {
|
||||
sessionFile: string;
|
||||
workspaceDir: string;
|
||||
agentDir?: string;
|
||||
config?: MoltbotConfig;
|
||||
config?: OpenClawConfig;
|
||||
skillsSnapshot?: SkillSnapshot;
|
||||
provider?: string;
|
||||
model?: string;
|
||||
@@ -114,8 +114,8 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
|
||||
const provider = (params.provider ?? DEFAULT_PROVIDER).trim() || DEFAULT_PROVIDER;
|
||||
const modelId = (params.model ?? DEFAULT_MODEL).trim() || DEFAULT_MODEL;
|
||||
const agentDir = params.agentDir ?? resolveMoltbotAgentDir();
|
||||
await ensureMoltbotModelsJson(params.config, agentDir);
|
||||
const agentDir = params.agentDir ?? resolveOpenClawAgentDir();
|
||||
await ensureOpenClawModelsJson(params.config, agentDir);
|
||||
const { model, error, authStorage, modelRegistry } = resolveModel(
|
||||
provider,
|
||||
modelId,
|
||||
@@ -211,7 +211,7 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
warn: makeBootstrapWarn({ sessionLabel, warn: (message) => log.warn(message) }),
|
||||
});
|
||||
const runAbortController = new AbortController();
|
||||
const toolsRaw = createMoltbotCodingTools({
|
||||
const toolsRaw = createOpenClawCodingTools({
|
||||
exec: {
|
||||
...resolveExecToolDefaults(params.config),
|
||||
elevated: params.bashElevated,
|
||||
@@ -315,7 +315,7 @@ export async function compactEmbeddedPiSessionDirect(
|
||||
});
|
||||
const isDefaultAgent = sessionAgentId === defaultAgentId;
|
||||
const promptMode = isSubagentSessionKey(params.sessionKey) ? "minimal" : "full";
|
||||
const docsPath = await resolveMoltbotDocsPath({
|
||||
const docsPath = await resolveOpenClawDocsPath({
|
||||
workspaceDir: effectiveWorkspace,
|
||||
argv1: process.argv[1],
|
||||
cwd: process.cwd(),
|
||||
|
||||
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
|
||||
import type { Api, Model } from "@mariozechner/pi-ai";
|
||||
import type { SessionManager } from "@mariozechner/pi-coding-agent";
|
||||
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { resolveContextWindowInfo } from "../context-window-guard.js";
|
||||
import { DEFAULT_CONTEXT_TOKENS } from "../defaults.js";
|
||||
import { setCompactionSafeguardRuntime } from "../pi-extensions/compaction-safeguard-runtime.js";
|
||||
@@ -23,7 +23,7 @@ function resolvePiExtensionPath(id: string): string {
|
||||
}
|
||||
|
||||
function resolveContextWindowTokens(params: {
|
||||
cfg: MoltbotConfig | undefined;
|
||||
cfg: OpenClawConfig | undefined;
|
||||
provider: string;
|
||||
modelId: string;
|
||||
model: Model<Api> | undefined;
|
||||
@@ -38,7 +38,7 @@ function resolveContextWindowTokens(params: {
|
||||
}
|
||||
|
||||
function buildContextPruningExtension(params: {
|
||||
cfg: MoltbotConfig | undefined;
|
||||
cfg: OpenClawConfig | undefined;
|
||||
sessionManager: SessionManager;
|
||||
provider: string;
|
||||
modelId: string;
|
||||
@@ -63,12 +63,12 @@ function buildContextPruningExtension(params: {
|
||||
};
|
||||
}
|
||||
|
||||
function resolveCompactionMode(cfg?: MoltbotConfig): "default" | "safeguard" {
|
||||
function resolveCompactionMode(cfg?: OpenClawConfig): "default" | "safeguard" {
|
||||
return cfg?.agents?.defaults?.compaction?.mode === "safeguard" ? "safeguard" : "default";
|
||||
}
|
||||
|
||||
export function buildEmbeddedExtensionPaths(params: {
|
||||
cfg: MoltbotConfig | undefined;
|
||||
cfg: OpenClawConfig | undefined;
|
||||
sessionManager: SessionManager;
|
||||
provider: string;
|
||||
modelId: string;
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { StreamFn } from "@mariozechner/pi-agent-core";
|
||||
import type { Api, Model, SimpleStreamOptions } from "@mariozechner/pi-ai";
|
||||
import { streamSimple } from "@mariozechner/pi-ai";
|
||||
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { log } from "./logger.js";
|
||||
|
||||
/**
|
||||
@@ -12,7 +12,7 @@ import { log } from "./logger.js";
|
||||
* @internal Exported for testing only
|
||||
*/
|
||||
export function resolveExtraParams(params: {
|
||||
cfg: MoltbotConfig | undefined;
|
||||
cfg: OpenClawConfig | undefined;
|
||||
provider: string;
|
||||
modelId: string;
|
||||
}): Record<string, unknown> | undefined {
|
||||
@@ -80,7 +80,7 @@ function createStreamFnWithExtraParams(
|
||||
*/
|
||||
export function applyExtraParamsToAgent(
|
||||
agent: { streamFn?: StreamFn },
|
||||
cfg: MoltbotConfig | undefined,
|
||||
cfg: OpenClawConfig | undefined,
|
||||
provider: string,
|
||||
modelId: string,
|
||||
extraParamsOverride?: Record<string, unknown>,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AgentMessage } from "@mariozechner/pi-agent-core";
|
||||
|
||||
import type { MoltbotConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
|
||||
const THREAD_SUFFIX_REGEX = /^(.*)(?::(?:thread|topic):\d+)$/i;
|
||||
|
||||
@@ -40,7 +40,7 @@ export function limitHistoryTurns(
|
||||
*/
|
||||
export function getDmHistoryLimitFromSessionKey(
|
||||
sessionKey: string | undefined,
|
||||
config: MoltbotConfig | undefined,
|
||||
config: OpenClawConfig | undefined,
|
||||
): number | undefined {
|
||||
if (!sessionKey || !config) return undefined;
|
||||
|
||||
@@ -71,7 +71,7 @@ export function getDmHistoryLimitFromSessionKey(
|
||||
};
|
||||
|
||||
const resolveProviderConfig = (
|
||||
cfg: MoltbotConfig | undefined,
|
||||
cfg: OpenClawConfig | undefined,
|
||||
providerId: string,
|
||||
): { dmHistoryLimit?: number; dms?: Record<string, { historyLimit?: number }> } | undefined => {
|
||||
const channels = cfg?.channels;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user