Spaces:
Sleeping
Sleeping
| /** | |
| * Agent Templates Library | |
| * | |
| * Defines agent archetypes that can be used as starting points for new deployments. | |
| * Each template provides a full OpenClaw agent config structure that | |
| * can be customized before creating an agent. | |
| */ | |
| export interface AgentToolsConfig { | |
| allow: string[] | |
| deny: string[] | |
| } | |
| export interface AgentSandboxConfig { | |
| mode: 'all' | 'non-main' | |
| workspaceAccess: 'rw' | 'ro' | 'none' | |
| scope: 'agent' | |
| docker?: { | |
| network: 'none' | 'bridge' | |
| } | |
| } | |
| export interface AgentModelConfig { | |
| primary: string | |
| fallbacks: string[] | |
| } | |
| export interface AgentIdentityConfig { | |
| name: string | |
| theme: string | |
| emoji: string | |
| } | |
| export interface AgentSubagentsConfig { | |
| allowAgents?: string[] | |
| model?: string | |
| } | |
| export interface AgentMemorySearchConfig { | |
| sources: string[] | |
| experimental?: { | |
| sessionMemory?: boolean | |
| } | |
| } | |
| export interface OpenClawAgentConfig { | |
| id: string | |
| name?: string | |
| workspace?: string | |
| agentDir?: string | |
| model: AgentModelConfig | |
| identity: AgentIdentityConfig | |
| subagents?: AgentSubagentsConfig | |
| sandbox: AgentSandboxConfig | |
| tools: AgentToolsConfig | |
| memorySearch?: AgentMemorySearchConfig | |
| } | |
| export interface AgentTemplate { | |
| type: string | |
| label: string | |
| description: string | |
| emoji: string | |
| modelTier: 'opus' | 'sonnet' | 'haiku' | |
| toolCount: number | |
| config: Omit<OpenClawAgentConfig, 'id' | 'workspace' | 'agentDir'> | |
| } | |
| import { getPluginToolProviders } from '@/lib/plugins' | |
| // Tool groups for template composition | |
| const TOOL_GROUPS: Record<string, readonly string[]> = { | |
| coding: ['read', 'write', 'edit', 'apply_patch', 'exec', 'bash', 'process'], | |
| browser: ['browser', 'web'], | |
| memory: ['memory_search', 'memory_get'], | |
| session: ['agents_list', 'sessions_list', 'sessions_history', 'sessions_send', 'sessions_spawn', 'session_status'], | |
| subagent: ['subagents', 'lobster', 'llm-task'], | |
| thinking: ['thinking', 'reactions', 'skills'], | |
| readonly: ['read', 'memory_search', 'memory_get', 'agents_list'], | |
| } | |
| /** Merge base TOOL_GROUPS with tools from plugin tool providers */ | |
| export function getEffectiveToolGroups(): Record<string, readonly string[]> { | |
| const merged: Record<string, string[]> = {} | |
| for (const [key, tools] of Object.entries(TOOL_GROUPS)) { | |
| merged[key] = [...tools] | |
| } | |
| for (const provider of getPluginToolProviders()) { | |
| const groupId = provider.id | |
| if (merged[groupId]) { | |
| // Append new tools that aren't already in the group | |
| const existing = new Set(merged[groupId]) | |
| for (const tool of provider.tools) { | |
| if (!existing.has(tool)) merged[groupId].push(tool) | |
| } | |
| } else { | |
| merged[groupId] = [...provider.tools] | |
| } | |
| } | |
| return merged | |
| } | |
| const COMMON_DENY = ['clawhub', 'cron', 'gateway', 'nodes'] | |
| const SONNET_FALLBACKS = [ | |
| 'openrouter/anthropic/claude-sonnet-4', | |
| 'moonshot/kimi-k2-thinking', | |
| 'openrouter/moonshotai/kimi-k2.5', | |
| 'nvidia/moonshotai/kimi-k2-instruct', | |
| 'openai/codex-mini-latest', | |
| 'ollama/qwen2.5-coder:14b', | |
| ] | |
| const OPUS_FALLBACKS = [ | |
| 'anthropic/claude-sonnet-4-20250514', | |
| 'moonshot/kimi-k2-thinking', | |
| 'nvidia/moonshotai/kimi-k2-instruct', | |
| 'openrouter/moonshotai/kimi-k2.5', | |
| 'openai/codex-mini-latest', | |
| ] | |
| const HAIKU_FALLBACKS = [ | |
| 'anthropic/claude-sonnet-4-20250514', | |
| 'ollama/qwen2.5-coder:14b', | |
| 'openai/codex-mini-latest', | |
| ] | |
| export const AGENT_TEMPLATES: AgentTemplate[] = [ | |
| { | |
| type: 'orchestrator', | |
| label: 'Orchestrator', | |
| description: 'Primary coordinator with full tool access. Routes tasks to specialist agents and manages workflows.', | |
| emoji: '\ud83e\udded', | |
| modelTier: 'opus', | |
| toolCount: 23, | |
| config: { | |
| model: { | |
| primary: 'anthropic/claude-opus-4-5', | |
| fallbacks: OPUS_FALLBACKS, | |
| }, | |
| identity: { | |
| name: '', | |
| theme: 'operator strategist', | |
| emoji: '\ud83e\udded', | |
| }, | |
| subagents: { | |
| allowAgents: [], | |
| }, | |
| sandbox: { | |
| mode: 'non-main', | |
| workspaceAccess: 'rw', | |
| scope: 'agent', | |
| }, | |
| tools: { | |
| allow: [ | |
| ...TOOL_GROUPS.coding, | |
| ...TOOL_GROUPS.browser, | |
| ...TOOL_GROUPS.memory, | |
| ...TOOL_GROUPS.session, | |
| ...TOOL_GROUPS.subagent, | |
| ...TOOL_GROUPS.thinking, | |
| ], | |
| deny: COMMON_DENY, | |
| }, | |
| memorySearch: { | |
| sources: ['memory', 'sessions'], | |
| experimental: { sessionMemory: true }, | |
| }, | |
| }, | |
| }, | |
| { | |
| type: 'developer', | |
| label: 'Developer', | |
| description: 'Full-stack builder with Docker bridge networking, exec/write access, and subagent spawning.', | |
| emoji: '\ud83d\udee0\ufe0f', | |
| modelTier: 'sonnet', | |
| toolCount: 21, | |
| config: { | |
| model: { | |
| primary: 'anthropic/claude-sonnet-4-20250514', | |
| fallbacks: SONNET_FALLBACKS, | |
| }, | |
| identity: { | |
| name: '', | |
| theme: 'builder engineer', | |
| emoji: '\ud83d\udee0\ufe0f', | |
| }, | |
| subagents: { | |
| allowAgents: [], | |
| model: 'openai/codex-mini-latest', | |
| }, | |
| sandbox: { | |
| mode: 'all', | |
| workspaceAccess: 'rw', | |
| scope: 'agent', | |
| docker: { network: 'bridge' }, | |
| }, | |
| tools: { | |
| allow: [ | |
| ...TOOL_GROUPS.coding, | |
| ...TOOL_GROUPS.browser, | |
| ...TOOL_GROUPS.memory, | |
| 'agents_list', 'sessions_spawn', 'sessions_history', 'session_status', | |
| ...TOOL_GROUPS.subagent, | |
| ...TOOL_GROUPS.thinking, | |
| ], | |
| deny: [...COMMON_DENY, 'sessions_send'], | |
| }, | |
| memorySearch: { | |
| sources: ['memory', 'sessions'], | |
| experimental: { sessionMemory: true }, | |
| }, | |
| }, | |
| }, | |
| { | |
| type: 'specialist-dev', | |
| label: 'Specialist Dev', | |
| description: 'Focused developer for specific domains (frontend, backend, blockchain). Docker bridge + write access.', | |
| emoji: '\u2699\ufe0f', | |
| modelTier: 'sonnet', | |
| toolCount: 15, | |
| config: { | |
| model: { | |
| primary: 'anthropic/claude-sonnet-4-20250514', | |
| fallbacks: SONNET_FALLBACKS, | |
| }, | |
| identity: { | |
| name: '', | |
| theme: 'specialist developer', | |
| emoji: '\u2699\ufe0f', | |
| }, | |
| subagents: { | |
| model: 'openai/codex-mini-latest', | |
| }, | |
| sandbox: { | |
| mode: 'all', | |
| workspaceAccess: 'rw', | |
| scope: 'agent', | |
| docker: { network: 'bridge' }, | |
| }, | |
| tools: { | |
| allow: [ | |
| ...TOOL_GROUPS.coding, | |
| ...TOOL_GROUPS.memory, | |
| 'agents_list', 'sessions_spawn', 'session_status', | |
| 'subagents', 'llm-task', | |
| 'thinking', 'reactions', 'skills', | |
| ], | |
| deny: [...COMMON_DENY, 'sessions_send', 'browser', 'web', 'lobster'], | |
| }, | |
| memorySearch: { | |
| sources: ['memory', 'sessions'], | |
| experimental: { sessionMemory: true }, | |
| }, | |
| }, | |
| }, | |
| { | |
| type: 'reviewer', | |
| label: 'Reviewer / QA', | |
| description: 'Read-only access for code review, quality gates, and auditing. Lightweight Haiku model.', | |
| emoji: '\ud83d\udd2c', | |
| modelTier: 'haiku', | |
| toolCount: 7, | |
| config: { | |
| model: { | |
| primary: 'anthropic/claude-haiku-4-5', | |
| fallbacks: HAIKU_FALLBACKS, | |
| }, | |
| identity: { | |
| name: '', | |
| theme: 'quality reviewer', | |
| emoji: '\ud83d\udd2c', | |
| }, | |
| sandbox: { | |
| mode: 'all', | |
| workspaceAccess: 'ro', | |
| scope: 'agent', | |
| }, | |
| tools: { | |
| allow: [ | |
| 'read', 'memory_search', 'memory_get', | |
| 'agents_list', 'thinking', 'reactions', 'skills', | |
| ], | |
| deny: [ | |
| ...COMMON_DENY, | |
| 'write', 'edit', 'apply_patch', 'exec', 'bash', 'process', | |
| 'browser', 'web', 'sessions_send', 'sessions_spawn', 'lobster', | |
| ], | |
| }, | |
| memorySearch: { | |
| sources: ['memory'], | |
| }, | |
| }, | |
| }, | |
| { | |
| type: 'researcher', | |
| label: 'Researcher', | |
| description: 'Browser and web access for research tasks. No workspace or code execution.', | |
| emoji: '\ud83d\udd0d', | |
| modelTier: 'sonnet', | |
| toolCount: 8, | |
| config: { | |
| model: { | |
| primary: 'anthropic/claude-sonnet-4-20250514', | |
| fallbacks: SONNET_FALLBACKS, | |
| }, | |
| identity: { | |
| name: '', | |
| theme: 'research analyst', | |
| emoji: '\ud83d\udd0d', | |
| }, | |
| sandbox: { | |
| mode: 'all', | |
| workspaceAccess: 'none', | |
| scope: 'agent', | |
| }, | |
| tools: { | |
| allow: [ | |
| 'browser', 'web', | |
| 'memory_search', 'memory_get', | |
| 'agents_list', 'thinking', 'reactions', 'skills', | |
| ], | |
| deny: [ | |
| ...COMMON_DENY, | |
| 'read', 'write', 'edit', 'apply_patch', 'exec', 'bash', 'process', | |
| 'sessions_send', 'sessions_spawn', 'lobster', | |
| ], | |
| }, | |
| memorySearch: { | |
| sources: ['memory', 'sessions'], | |
| }, | |
| }, | |
| }, | |
| { | |
| type: 'content-creator', | |
| label: 'Content Creator', | |
| description: 'Write and edit access for content generation. No code execution or browser.', | |
| emoji: '\u270f\ufe0f', | |
| modelTier: 'haiku', | |
| toolCount: 9, | |
| config: { | |
| model: { | |
| primary: 'anthropic/claude-haiku-4-5', | |
| fallbacks: HAIKU_FALLBACKS, | |
| }, | |
| identity: { | |
| name: '', | |
| theme: 'content creator', | |
| emoji: '\u270f\ufe0f', | |
| }, | |
| sandbox: { | |
| mode: 'all', | |
| workspaceAccess: 'none', | |
| scope: 'agent', | |
| }, | |
| tools: { | |
| allow: [ | |
| 'write', 'edit', | |
| 'memory_search', 'memory_get', | |
| 'agents_list', | |
| 'thinking', 'reactions', 'skills', | |
| 'web', | |
| ], | |
| deny: [ | |
| ...COMMON_DENY, | |
| 'read', 'apply_patch', 'exec', 'bash', 'process', | |
| 'browser', 'sessions_send', 'sessions_spawn', 'lobster', | |
| 'subagents', 'llm-task', | |
| ], | |
| }, | |
| memorySearch: { | |
| sources: ['memory'], | |
| }, | |
| }, | |
| }, | |
| { | |
| type: 'security-auditor', | |
| label: 'Security Auditor', | |
| description: 'Read-only workspace with bash for security scanning. No write access to prevent tampering.', | |
| emoji: '\ud83d\udee1\ufe0f', | |
| modelTier: 'sonnet', | |
| toolCount: 10, | |
| config: { | |
| model: { | |
| primary: 'anthropic/claude-sonnet-4-20250514', | |
| fallbacks: SONNET_FALLBACKS, | |
| }, | |
| identity: { | |
| name: '', | |
| theme: 'security auditor', | |
| emoji: '\ud83d\udee1\ufe0f', | |
| }, | |
| sandbox: { | |
| mode: 'all', | |
| workspaceAccess: 'ro', | |
| scope: 'agent', | |
| }, | |
| tools: { | |
| allow: [ | |
| 'read', 'exec', 'bash', | |
| 'memory_search', 'memory_get', | |
| 'agents_list', | |
| 'thinking', 'reactions', 'skills', | |
| 'web', | |
| ], | |
| deny: [ | |
| ...COMMON_DENY, | |
| 'write', 'edit', 'apply_patch', 'process', | |
| 'browser', 'sessions_send', 'sessions_spawn', 'lobster', | |
| 'subagents', 'llm-task', | |
| ], | |
| }, | |
| memorySearch: { | |
| sources: ['memory'], | |
| }, | |
| }, | |
| }, | |
| ] | |
| /** Get a template by type name */ | |
| export function getTemplate(type: string): AgentTemplate | undefined { | |
| return AGENT_TEMPLATES.find(t => t.type === type) | |
| } | |
| /** Build a full OpenClaw agent config from a template + overrides */ | |
| export function buildAgentConfig( | |
| template: AgentTemplate, | |
| overrides: { | |
| id: string | |
| name: string | |
| workspace?: string | |
| agentDir?: string | |
| emoji?: string | |
| theme?: string | |
| model?: string | |
| workspaceAccess?: 'rw' | 'ro' | 'none' | |
| sandboxMode?: 'all' | 'non-main' | |
| dockerNetwork?: 'none' | 'bridge' | |
| subagentAllowAgents?: string[] | |
| } | |
| ): OpenClawAgentConfig { | |
| const config = structuredClone(template.config) | |
| config.identity.name = overrides.name | |
| if (overrides.emoji) config.identity.emoji = overrides.emoji | |
| if (overrides.theme) config.identity.theme = overrides.theme | |
| if (overrides.model) config.model.primary = overrides.model | |
| if (overrides.workspaceAccess) config.sandbox.workspaceAccess = overrides.workspaceAccess | |
| if (overrides.sandboxMode) config.sandbox.mode = overrides.sandboxMode | |
| if (overrides.dockerNetwork) { | |
| config.sandbox.docker = { network: overrides.dockerNetwork } | |
| } | |
| if (overrides.subagentAllowAgents && config.subagents) { | |
| config.subagents.allowAgents = overrides.subagentAllowAgents | |
| } | |
| return { | |
| id: overrides.id, | |
| name: overrides.name, | |
| workspace: overrides.workspace, | |
| agentDir: overrides.agentDir, | |
| ...config, | |
| } | |
| } | |
| /** Model tier display info for UI */ | |
| export const MODEL_TIERS = { | |
| opus: { label: 'Opus', color: 'purple', costIndicator: '$$$' }, | |
| sonnet: { label: 'Sonnet', color: 'blue', costIndicator: '$$' }, | |
| haiku: { label: 'Haiku', color: 'green', costIndicator: '$' }, | |
| } as const | |
| /** Tool group labels for UI checkboxes */ | |
| export const TOOL_GROUP_LABELS = { | |
| coding: 'Coding (read/write/exec)', | |
| browser: 'Browser & Web', | |
| memory: 'Memory Search', | |
| session: 'Session Management', | |
| subagent: 'Subagents & LLM Tasks', | |
| thinking: 'Thinking & Skills', | |
| readonly: 'Read-only', | |
| } as const | |