204 lines
5.2 KiB
TypeScript
204 lines
5.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { ClawdbotConfig } from "../config/config.js";
|
|
import {
|
|
resolveAgentConfig,
|
|
resolveAgentModelFallbacksOverride,
|
|
resolveAgentModelPrimary,
|
|
} from "./agent-scope.js";
|
|
|
|
describe("resolveAgentConfig", () => {
|
|
it("should return undefined when no agents config exists", () => {
|
|
const cfg: ClawdbotConfig = {};
|
|
const result = resolveAgentConfig(cfg, "main");
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
it("should return undefined when agent id does not exist", () => {
|
|
const cfg: ClawdbotConfig = {
|
|
agents: {
|
|
list: [{ id: "main", workspace: "~/clawd" }],
|
|
},
|
|
};
|
|
const result = resolveAgentConfig(cfg, "nonexistent");
|
|
expect(result).toBeUndefined();
|
|
});
|
|
|
|
it("should return basic agent config", () => {
|
|
const cfg: ClawdbotConfig = {
|
|
agents: {
|
|
list: [
|
|
{
|
|
id: "main",
|
|
name: "Main Agent",
|
|
workspace: "~/clawd",
|
|
agentDir: "~/.clawdbot/agents/main",
|
|
model: "anthropic/claude-opus-4",
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const result = resolveAgentConfig(cfg, "main");
|
|
expect(result).toEqual({
|
|
name: "Main Agent",
|
|
workspace: "~/clawd",
|
|
agentDir: "~/.clawdbot/agents/main",
|
|
model: "anthropic/claude-opus-4",
|
|
identity: undefined,
|
|
groupChat: undefined,
|
|
subagents: undefined,
|
|
sandbox: undefined,
|
|
tools: undefined,
|
|
});
|
|
});
|
|
|
|
it("supports per-agent model primary+fallbacks", () => {
|
|
const cfg: ClawdbotConfig = {
|
|
agents: {
|
|
defaults: {
|
|
model: {
|
|
primary: "anthropic/claude-sonnet-4",
|
|
fallbacks: ["openai/gpt-4.1"],
|
|
},
|
|
},
|
|
list: [
|
|
{
|
|
id: "linus",
|
|
model: {
|
|
primary: "anthropic/claude-opus-4",
|
|
fallbacks: ["openai/gpt-5.2"],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
|
|
expect(resolveAgentModelPrimary(cfg, "linus")).toBe("anthropic/claude-opus-4");
|
|
expect(resolveAgentModelFallbacksOverride(cfg, "linus")).toEqual(["openai/gpt-5.2"]);
|
|
|
|
// If fallbacks isn't present, we don't override the global fallbacks.
|
|
const cfgNoOverride: ClawdbotConfig = {
|
|
agents: {
|
|
list: [
|
|
{
|
|
id: "linus",
|
|
model: {
|
|
primary: "anthropic/claude-opus-4",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
expect(resolveAgentModelFallbacksOverride(cfgNoOverride, "linus")).toBe(undefined);
|
|
|
|
// Explicit empty list disables global fallbacks for that agent.
|
|
const cfgDisable: ClawdbotConfig = {
|
|
agents: {
|
|
list: [
|
|
{
|
|
id: "linus",
|
|
model: {
|
|
primary: "anthropic/claude-opus-4",
|
|
fallbacks: [],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
expect(resolveAgentModelFallbacksOverride(cfgDisable, "linus")).toEqual([]);
|
|
});
|
|
|
|
it("should return agent-specific sandbox config", () => {
|
|
const cfg: ClawdbotConfig = {
|
|
agents: {
|
|
list: [
|
|
{
|
|
id: "work",
|
|
workspace: "~/clawd-work",
|
|
sandbox: {
|
|
mode: "all",
|
|
scope: "agent",
|
|
perSession: false,
|
|
workspaceAccess: "ro",
|
|
workspaceRoot: "~/sandboxes",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const result = resolveAgentConfig(cfg, "work");
|
|
expect(result?.sandbox).toEqual({
|
|
mode: "all",
|
|
scope: "agent",
|
|
perSession: false,
|
|
workspaceAccess: "ro",
|
|
workspaceRoot: "~/sandboxes",
|
|
});
|
|
});
|
|
|
|
it("should return agent-specific tools config", () => {
|
|
const cfg: ClawdbotConfig = {
|
|
agents: {
|
|
list: [
|
|
{
|
|
id: "restricted",
|
|
workspace: "~/clawd-restricted",
|
|
tools: {
|
|
allow: ["read"],
|
|
deny: ["exec", "write", "edit"],
|
|
elevated: {
|
|
enabled: false,
|
|
allowFrom: { whatsapp: ["+15555550123"] },
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const result = resolveAgentConfig(cfg, "restricted");
|
|
expect(result?.tools).toEqual({
|
|
allow: ["read"],
|
|
deny: ["exec", "write", "edit"],
|
|
elevated: {
|
|
enabled: false,
|
|
allowFrom: { whatsapp: ["+15555550123"] },
|
|
},
|
|
});
|
|
});
|
|
|
|
it("should return both sandbox and tools config", () => {
|
|
const cfg: ClawdbotConfig = {
|
|
agents: {
|
|
list: [
|
|
{
|
|
id: "family",
|
|
workspace: "~/clawd-family",
|
|
sandbox: {
|
|
mode: "all",
|
|
scope: "agent",
|
|
},
|
|
tools: {
|
|
allow: ["read"],
|
|
deny: ["exec"],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
};
|
|
const result = resolveAgentConfig(cfg, "family");
|
|
expect(result?.sandbox?.mode).toBe("all");
|
|
expect(result?.tools?.allow).toEqual(["read"]);
|
|
});
|
|
|
|
it("should normalize agent id", () => {
|
|
const cfg: ClawdbotConfig = {
|
|
agents: {
|
|
list: [{ id: "main", workspace: "~/clawd" }],
|
|
},
|
|
};
|
|
// Should normalize to "main" (default)
|
|
const result = resolveAgentConfig(cfg, "");
|
|
expect(result).toBeDefined();
|
|
expect(result?.workspace).toBe("~/clawd");
|
|
});
|
|
});
|