feat: add sandbox, agent_configs, and routing config schemas
This commit is contained in:
+1
-1
@@ -1,2 +1,2 @@
|
||||
export { loadConfig } from './loader.js';
|
||||
export { configSchema, type Config, type TelegramConfig, type ModelConfig, type CronJobConfig, type AgentsConfig, type CompactionConfig, type ToolProfile, type ToolOverrideConfig, type ToolsConfig } from './schema.js';
|
||||
export { configSchema, type Config, type TelegramConfig, type ModelConfig, type CronJobConfig, type AgentsConfig, type CompactionConfig, type ToolProfile, type ToolOverrideConfig, type ToolsConfig, type SandboxConfig, type AgentConfigEntry, type RoutingConfig } from './schema.js';
|
||||
|
||||
@@ -1,6 +1,94 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { configSchema } from './schema.js';
|
||||
|
||||
describe('configSchema — sandbox', () => {
|
||||
const minimalConfig = {
|
||||
telegram: { bot_token: 'test', allowed_chat_ids: [1] },
|
||||
models: { default: { provider: 'anthropic', model: 'claude-3' } },
|
||||
};
|
||||
|
||||
it('defaults sandbox to disabled', () => {
|
||||
const result = configSchema.parse(minimalConfig);
|
||||
expect(result.sandbox.enabled).toBe(false);
|
||||
expect(result.sandbox.image).toBe('node:22-slim');
|
||||
expect(result.sandbox.network).toBe('none');
|
||||
expect(result.sandbox.memory_limit).toBe('512m');
|
||||
expect(result.sandbox.cpu_limit).toBe('1.0');
|
||||
expect(result.sandbox.timeout_seconds).toBe(300);
|
||||
});
|
||||
|
||||
it('accepts sandbox config', () => {
|
||||
const result = configSchema.parse({
|
||||
...minimalConfig,
|
||||
sandbox: { enabled: true, image: 'ubuntu:24.04', network: 'bridge' },
|
||||
});
|
||||
expect(result.sandbox.enabled).toBe(true);
|
||||
expect(result.sandbox.image).toBe('ubuntu:24.04');
|
||||
expect(result.sandbox.network).toBe('bridge');
|
||||
});
|
||||
});
|
||||
|
||||
describe('configSchema — agent_configs', () => {
|
||||
const minimalConfig = {
|
||||
telegram: { bot_token: 'test', allowed_chat_ids: [1] },
|
||||
models: { default: { provider: 'anthropic', model: 'claude-3' } },
|
||||
};
|
||||
|
||||
it('defaults agent_configs to empty', () => {
|
||||
const result = configSchema.parse(minimalConfig);
|
||||
expect(result.agent_configs).toEqual({});
|
||||
});
|
||||
|
||||
it('accepts named agent configs', () => {
|
||||
const result = configSchema.parse({
|
||||
...minimalConfig,
|
||||
agent_configs: {
|
||||
assistant: {
|
||||
system_prompt: 'You are helpful.',
|
||||
model_tier: 'default',
|
||||
tool_profile: 'messaging',
|
||||
},
|
||||
coder: {
|
||||
model_tier: 'complex',
|
||||
tool_profile: 'coding',
|
||||
sandbox: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(result.agent_configs.assistant.system_prompt).toBe('You are helpful.');
|
||||
expect(result.agent_configs.assistant.tool_profile).toBe('messaging');
|
||||
expect(result.agent_configs.coder.sandbox).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('configSchema — routing', () => {
|
||||
const minimalConfig = {
|
||||
telegram: { bot_token: 'test', allowed_chat_ids: [1] },
|
||||
models: { default: { provider: 'anthropic', model: 'claude-3' } },
|
||||
};
|
||||
|
||||
it('defaults routing to empty', () => {
|
||||
const result = configSchema.parse(minimalConfig);
|
||||
expect(result.routing.default_agent).toBeUndefined();
|
||||
expect(result.routing.channels).toEqual({});
|
||||
expect(result.routing.senders).toEqual({});
|
||||
});
|
||||
|
||||
it('accepts routing config', () => {
|
||||
const result = configSchema.parse({
|
||||
...minimalConfig,
|
||||
routing: {
|
||||
default_agent: 'assistant',
|
||||
channels: { discord: 'coder' },
|
||||
senders: { 'telegram:12345': 'coder' },
|
||||
},
|
||||
});
|
||||
expect(result.routing.default_agent).toBe('assistant');
|
||||
expect(result.routing.channels.discord).toBe('coder');
|
||||
expect(result.routing.senders['telegram:12345']).toBe('coder');
|
||||
});
|
||||
});
|
||||
|
||||
describe('configSchema automation', () => {
|
||||
const baseConfig = {
|
||||
telegram: { bot_token: 'test-token', allowed_chat_ids: [123] },
|
||||
|
||||
@@ -179,6 +179,38 @@ const toolsSchema = z.object({
|
||||
providers: z.record(z.string(), toolOverrideSchema).default({}),
|
||||
}).default({});
|
||||
|
||||
// ── Sandbox schemas ───────────────────────────────────────────────────
|
||||
|
||||
const sandboxSchema = z.object({
|
||||
enabled: z.boolean().default(false),
|
||||
image: z.string().default('node:22-slim'),
|
||||
workspace_dir: z.string().default('/workspace'),
|
||||
network: z.enum(['none', 'bridge', 'host']).default('none'),
|
||||
memory_limit: z.string().default('512m'),
|
||||
cpu_limit: z.string().default('1.0'),
|
||||
timeout_seconds: z.number().min(10).max(3600).default(300),
|
||||
}).default({});
|
||||
|
||||
// ── Agent config + routing schemas ────────────────────────────────────
|
||||
|
||||
const modelTierEnum = z.enum(['fast', 'default', 'complex', 'local']);
|
||||
|
||||
const agentConfigEntrySchema = z.object({
|
||||
system_prompt: z.string().optional(),
|
||||
model_tier: modelTierEnum.optional(),
|
||||
tool_profile: toolProfileEnum.optional(),
|
||||
tool_overrides: toolOverrideSchema.optional(),
|
||||
sandbox: z.boolean().default(false),
|
||||
});
|
||||
|
||||
const agentConfigsSchema = z.record(z.string(), agentConfigEntrySchema).default({});
|
||||
|
||||
const routingSchema = z.object({
|
||||
default_agent: z.string().optional(),
|
||||
channels: z.record(z.string(), z.string()).default({}),
|
||||
senders: z.record(z.string(), z.string()).default({}),
|
||||
}).default({});
|
||||
|
||||
const promptSchema = z.object({
|
||||
/** Additional directories to search for prompt template files. */
|
||||
search_dirs: z.array(z.string()).default([]),
|
||||
@@ -209,6 +241,9 @@ export const configSchema = z.object({
|
||||
web_search: webSearchSchema,
|
||||
prompt: promptSchema,
|
||||
tools: toolsSchema,
|
||||
sandbox: sandboxSchema,
|
||||
agent_configs: agentConfigsSchema,
|
||||
routing: routingSchema,
|
||||
});
|
||||
|
||||
export type Config = z.infer<typeof configSchema>;
|
||||
@@ -228,3 +263,6 @@ export type PromptConfig = z.infer<typeof promptSchema>;
|
||||
export type ToolProfile = z.infer<typeof toolProfileEnum>;
|
||||
export type ToolOverrideConfig = z.infer<typeof toolOverrideSchema>;
|
||||
export type ToolsConfig = z.infer<typeof toolsSchema>;
|
||||
export type SandboxConfig = z.infer<typeof sandboxSchema>;
|
||||
export type AgentConfigEntry = z.infer<typeof agentConfigEntrySchema>;
|
||||
export type RoutingConfig = z.infer<typeof routingSchema>;
|
||||
|
||||
Reference in New Issue
Block a user