Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.orcbot.buzzchat.site/llms.txt

Use this file to discover all available pages before exploring further.

OrcBot’s skills system is the interface between the LLM’s reasoning and the outside world. Skills are executable functions that the agent can call to perform actions: search the web, send messages, run commands, manipulate files, and more.

Architecture

Skill Types

1. Core Skills

Purpose: Built-in tools registered at agent startup. Implementation: Agent.ts (lines 908-2500+) — registerInternalSkills() Registration:
this.skills.registerSkill({
  name: 'web_search',
  description: 'Search the web for information. Use this for current events, facts, or research.',
  usage: 'web_search(query)',
  handler: async (args) => {
    const query = args.query;
    const results = await this.browser.search(query);
    return JSON.stringify(results, null, 2);
  },
  isResearch: true,  // Higher repetition budget
  isDeep: true       // Counts as substantive progress
});
Categories:
CategorySkillsDescription
Researchweb_search, browser_navigate, http_fetch, extract_article, download_fileWeb browsing and data retrieval
Communicationsend_telegram, send_whatsapp, send_discord, send_slack, send_emailMulti-channel messaging
Telegram Rich UItelegram_send_buttons, telegram_send_poll, telegram_react, telegram_edit_message, telegram_pin_messageInteractive Telegram features
File Operationsread_file, write_file, send_file, send_voice_noteFile I/O and delivery
Systemrun_command, get_system_info, system_checkShell execution and diagnostics
Memoryrecall_memory, update_user_profile, update_learning, update_journalLong-term storage
RAGrag_ingest, rag_search, rag_ingest_url, rag_list, rag_deleteKnowledge store operations
Orchestrationschedule_task, heartbeat_schedule, spawn_agent, delegate_taskTask scheduling and multi-agent
Configurationmanage_configRuntime config modification
Reasoningdeep_reason, request_supporting_dataExtended reasoning and clarification
Skills Metamanage_skills, create_custom_skill, self_repair_skillSkill lifecycle
Full list: See SKILLS.md

2. Dynamic Plugins

Purpose: Hot-reloadable TypeScript/JavaScript files for custom skills. Location: ~/.orcbot/plugins/*.ts or ./plugins/*.ts Format:
// ~/.orcbot/plugins/weather-api.ts
export default {
  name: 'weather_api',
  description: 'Get weather from OpenWeatherMap API. Use for weather queries.',
  usage: 'weather_api(city)',
  handler: async (args: any, context: any) => {
    const apiKey = context.config.get('openWeatherApiKey');
    const city = args.city;
    const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}`;
    
    const response = await fetch(url);
    const data = await response.json();
    
    return `Weather in ${city}: ${data.main.temp}°C, ${data.weather[0].description}`;
  },
  isDeep: true,  // Resets communication cooldown
  isParallelSafe: false  // Can't run in parallel with other tools
};
Loading:
// Automatic at startup
skillsManager.loadPlugins();

// Manual hot reload
skillsManager.loadPlugins();
logger.info('Plugins reloaded');
Hot Reload: OrcBot clears the require cache before each load, so you can edit plugins without restarting:
# 1. Edit plugin
vim ~/.orcbot/plugins/weather-api.ts

# 2. Trigger reload (automatic on file change, or manual via TUI)
orcbot ui Skills Reload Plugins
Safety:
# orcbot.config.yaml
pluginAllowList: [weather_api, custom_tool]  # Only these plugins load
pluginDenyList: [dangerous_plugin]            # Block these plugins
safeMode: true                                # Disable all plugins

3. Agent Skills (SKILL.md)

Purpose: Declarative skill packages following the agentskills.io spec. Location: ~/.orcbot/plugins/skills/*/SKILL.md Format:
---
name: web-scraper
description: Advanced web scraping with Cheerio and Puppeteer. Use for extracting structured data from complex websites.
license: MIT
compatibility: orcbot >= 2.0
allowedTools:
  - browser_navigate
  - http_fetch
  - run_command
orcbot:
  autoActivate: false
  requiredPackages:
    - cheerio
    - puppeteer
  permissions:
    - network
    - browser
  triggerPatterns:
    - scrape.*website
    - extract.*data.*from
---

# Web Scraper Skill

## When to Use

Use this skill when the user asks to:
- Extract structured data from a website (tables, lists, prices)
- Scrape multiple pages following pagination
- Parse complex HTML structures beyond simple article extraction

## Approach

1. First, use `browser_navigate` to inspect the page structure
2. If the page requires JavaScript, use the browser. Otherwise, use `http_fetch` + Cheerio for speed.
3. Identify CSS selectors for the target data
4. Extract and structure the data as JSON
5. Handle pagination by following "next" links

## Example Selectors

```javascript
// Extract product prices
const prices = $('span.price').map((i, el) => $(el).text()).get();

// Extract table rows
const rows = $('table tr').map((i, el) => {
  return $(el).find('td').map((j, cell) => $(cell).text()).get();
}).get();

Error Handling

  • If the page is protected by CAPTCHA, inform the user
  • If selectors fail, try alternative patterns (XPath, data attributes)
  • If rate-limited, suggest adding delays between requests

**Progressive Disclosure:**

Agent skills use a 2-level disclosure system:

**Level 1: Metadata only (always in prompt)**

```xml
<available_skills>
  <skill>
    <name>web-scraper</name>
    <description>Advanced web scraping with Cheerio and Puppeteer...</description>
    <scripts>scrape.ts, pagination.ts</scripts>
    <references>cheerio-guide.md, puppeteer-tips.md</references>
  </skill>
</available_skills>
Level 2: Full instructions (activated on-demand)
// Agent calls activate_skill("web-scraper")
const skill = skillsManager.activateAgentSkill('web-scraper');

// Now the full SKILL.md body is injected into the prompt
Installation:
# From npm package (follows agentskills.io spec)
orcbot skill install firecrawl/cli
# → Resolves to @firecrawl/cli or firecrawl-cli
# → Downloads via npm pack
# → Extracts and discovers SKILL.md files
# → Installs to ~/.orcbot/plugins/skills/

# From GitHub repo
orcbot skill install https://github.com/user/repo

# From local directory
orcbot skill install ./my-skill/

# From .skill (zip) file
orcbot skill install ./my-skill.skill
Skill matching (auto-activation):
// On action start, SkillsManager scans task description
const matched = await skills.classifySkillsWithLLM(taskDescription, llm);
// → Activates matched skills automatically

// Fallback to regex if LLM unavailable
const matched = skills.matchSkillsForTask(taskDescription);

Skill Interface

interface Skill {
  name: string;           // Unique identifier (lowercase, no spaces)
  description: string;    // What it does + when to use it
  usage: string;          // Example call: "web_search(query)"
  handler: (args: any, context?: AgentContext) => Promise<any>;
  
  // Optional metadata flags
  pluginPath?: string;    // Source file (for uninstallation)
  sourceUrl?: string;     // Original URL (if generated)
  isResearch?: boolean;   // Higher repetition budget
  isSideEffect?: boolean; // Subject to deduplication
  isDeep?: boolean;       // Resets communication cooldown
  isDangerous?: boolean;  // Requires confirmation in autonomy
  isElevated?: boolean;   // Requires admin privileges
  isParallelSafe?: boolean; // Can run in parallel
}

Metadata Flags

isResearch:
  • Higher tool repetition budget (10 vs. 5)
  • Used for: web_search, browser_navigate, http_fetch
  • Prevents premature loop detection during research
isSideEffect:
  • Subject to strict deduplication
  • Used for: send_telegram, send_whatsapp, write_file
  • Prevents duplicate messages/writes
isDeep:
  • Resets transparency nudge timer
  • Counts as “substantive progress”
  • Used for: web_search, browser_navigate, run_command, deep_reason
  • Tells termination review: “real work was done”
isDangerous:
  • Requires explicit confirmation in autonomy mode
  • Used for: run_command, delete_file, install_npm_dependency
  • Blocks execution if user approval not granted
isElevated:
  • Requires admin privileges
  • Filtered out for non-admin tasks
  • Used for: run_command, write_file, manage_config, browser_navigate
isParallelSafe:
  • Can be executed in parallel with other parallel-safe tools
  • Used for: read_file, http_fetch (read-only operations)
  • Enables concurrent execution in multi-agent scenarios

Skill Execution Flow

// 1. LLM decides to call a tool
const decision = {
  tools: [
    { name: 'web_search', metadata: { query: 'Paris weather' } }
  ]
};

// 2. Agent looks up skill
const skill = skills.getSkill('web_search');
if (!skill) {
  throw new Error('Skill not found: web_search');
}

// 3. Validate arguments (basic checks)
if (!decision.tools[0].metadata.query) {
  throw new Error('Missing required argument: query');
}

// 4. Execute handler
try {
  const result = await skill.handler(
    decision.tools[0].metadata,
    { browser, config, agent, logger }
  );
  
  // 5. Save observation to memory
  memory.saveMemory({
    id: `${actionId}-step-${step}`,
    type: 'short',
    content: `Observation: Tool ${skill.name} returned ${result}`,
    metadata: { actionId, step, skill: skill.name }
  });
} catch (error) {
  // 6. Save error to memory
  memory.saveMemory({
    id: `${actionId}-step-${step}-error`,
    type: 'short',
    content: `Observation: Tool ${skill.name} FAILED: ${error.message}`,
    metadata: { actionId, step, skill: skill.name, error: true }
  });
}

Tool Definitions (Native Tool Calling)

For LLMs that support native function calling (OpenAI, Google), SkillsManager generates JSON schemas:
interface LLMToolDefinition {
  type: 'function';
  function: {
    name: string;
    description: string;
    parameters: {
      type: 'object';
      properties: Record<string, any>;
      required: string[];
    };
  };
}

// Generated from skill metadata
const toolDefs = skills.getToolDefinitions();
// [
//   {
//     type: 'function',
//     function: {
//       name: 'web_search',
//       description: 'Search the web for information...',
//       parameters: {
//         type: 'object',
//         properties: {
//           query: { type: 'string', description: 'Search query' }
//         },
//         required: ['query']
//       }
//     }
//   },
//   ...
// ]
Passed to LLM:
const response = await llm.callWithTools(prompt, systemPrompt, toolDefs);
// Native response:
// {
//   content: "I'll search for Paris weather.",
//   toolCalls: [
//     { name: 'web_search', arguments: { query: 'Paris weather' } }
//   ]
// }

Skill Context (AgentContext)

All skill handlers receive a context object:
interface AgentContext {
  browser: WebBrowser;       // Playwright browser instance
  config: ConfigManager;     // Runtime configuration
  agent: Agent;              // Full agent instance
  logger: Logger;            // Winston logger
  workerProfile?: WorkerProfileManager; // Multi-agent metadata
  orchestrator?: AgentOrchestrator;     // Worker spawn/coordination
  [key: string]: any;        // Custom extensions
}

// Usage in skill handler:
handler: async (args, context) => {
  const apiKey = context.config.get('myApiKey');
  const userAgent = await context.browser.getUserAgent();
  context.logger.info('Executing custom skill');
  
  // Access agent methods
  await context.agent.pushTask('Follow-up task', 5);
  
  return 'Result';
}

Prompt Injection

Compact mode (after step 1):
AVAILABLE SKILLS:
- web_search(query) — Search the web
- browser_navigate(url) — Visit a URL
- send_telegram(chatId, message) — Send Telegram message
[... 40+ more skills, name + usage only]

AGENT SKILLS:
- web-scraper — Advanced web scraping (use activate_skill to load)
- pdf-extractor — Extract text from PDFs (use activate_skill to load)
Activated skills (after activate_skill called):
AVAILABLE SKILLS:
[... same as above]

ACTIVATED SKILL INSTRUCTIONS:
<skill name="web-scraper">
# Web Scraper Skill

## When to Use
Use this skill when the user asks to:
- Extract structured data from a website
...
</skill>

Skill Discovery

List all skills:
orcbot skill list
# Core Skills (45):
# - web_search: Search the web for information
# - browser_navigate: Visit a URL and extract content
# ...
# 
# Dynamic Plugins (2):
# - weather_api: Get weather from OpenWeatherMap
# - custom_tool: My custom tool
# 
# Agent Skills (3):
# - web-scraper: Advanced web scraping [INACTIVE]
# - pdf-extractor: Extract text from PDFs [ACTIVE]
# - news-finder: Find latest news [INACTIVE]
Inspect skill:
orcbot skill info web-scraper
# Name: web-scraper
# Description: Advanced web scraping with Cheerio and Puppeteer...
# License: MIT
# Required packages: cheerio, puppeteer
# Permissions: network, browser
# Trigger patterns: scrape.*website, extract.*data.*from
# 
# Bundled resources:
# - scripts/scrape.ts
# - scripts/pagination.ts
# - references/cheerio-guide.md
# - references/puppeteer-tips.md

Creating Skills

Option 1: Core Skill (Hardcoded)

Edit Agent.ts and register:
this.skills.registerSkill({
  name: 'my_skill',
  description: 'What it does and when to use it',
  usage: 'my_skill(arg1, arg2)',
  handler: async (args, context) => {
    // Implementation
    return 'Result';
  },
  isDeep: true
});

Option 2: Dynamic Plugin

Create ~/.orcbot/plugins/my-skill.ts:
export default {
  name: 'my_skill',
  description: 'What it does and when to use it',
  usage: 'my_skill(arg1, arg2)',
  handler: async (args: any, context: any) => {
    // Implementation
    return 'Result';
  }
};
Reload plugins via TUI or restart agent.

Option 3: Agent Skill (SKILL.md)

Create directory structure:
~/.orcbot/plugins/skills/my-skill/
├── SKILL.md              # Frontmatter + instructions
├── scripts/
│   └── helper.ts         # Executable scripts
├── references/
│   └── guide.md          # Documentation
└── assets/
    └── example.png       # Images/files
Write SKILL.md:
---
name: my-skill
description: Brief description of what this skill does and when to use it
license: MIT
allowedTools:
  - browser_navigate
  - http_fetch
orcbot:
  autoActivate: false
  triggerPatterns:
    - my.*skill.*pattern
---

# My Skill

## When to Use
...

## Approach
...
Restart agent or use:
orcbot skill discover

Option 4: Self-Generated Plugin (create_custom_skill)

Ask the agent:
User: Create a skill that fetches crypto prices from CoinGecko
Agent: [Uses create_custom_skill to generate ~/.orcbot/plugins/crypto-price.ts]
Agent: Skill created and loaded. You can now use crypto_price(symbol).

Self-Repair

When a plugin fails to load (syntax error, missing dependency), OrcBot auto-triggers repair:
// SkillsManager.ts:296-315
try {
  const plugin = require(pluginPath);
  this.registerSkill(plugin);
} catch (error) {
  logger.error(`Failed to load plugin ${file}: ${error.message}`);
  
  // Push repair task
  agent.pushTask(
    `System Alert: Plugin '${skillName}' failed to compile. Error: ${error.message}. Use self_repair_skill to fix it.`,
    10,  // High priority
    { source: 'system', error: error.message, skillName }
  );
}
The self_repair_skill handler:
  1. Reads the broken plugin file
  2. Analyzes the error (syntax, type, import)
  3. Calls LLM to generate a fix
  4. Writes corrected code
  5. Reloads plugins
  6. Validates the fix

Skill Validation

For Agent Skills (SKILL.md), OrcBot validates against the spec:
orcbot skill validate ~/.orcbot/plugins/skills/my-skill
# ✓ SKILL.md found
# ✓ Name matches directory (my-skill)
# ✓ Description is descriptive (120 chars)
# ✗ ERROR: name contains uppercase letters (must be lowercase)
# ✗ ERROR: description exceeds 1024 chars
Validation rules:
  • Name: lowercase, alphanumeric + hyphens, no consecutive hyphens, 1-64 chars
  • Description: 10-1024 chars
  • Compatibility: 500 chars max
  • Body: < 500 lines (warning only, large skills are valid)

Parallel Execution

Skills marked isParallelSafe: true can run concurrently:
const tools = [
  { name: 'read_file', metadata: { path: 'file1.txt' } },
  { name: 'read_file', metadata: { path: 'file2.txt' } },
  { name: 'http_fetch', metadata: { url: 'https://api.example.com' } }
];

// All are parallel-safe → execute concurrently
const results = await Promise.all(
  tools.map(t => skills.execute(t.name, t.metadata, context))
);
Unsafe for parallel execution:
  • write_file (race conditions)
  • send_telegram (message ordering)
  • run_command (shared stdout)

Configuration

# Skills behavior
safeMode: false                   # Disable dangerous skills
pluginAllowList: []               # Empty = all plugins allowed
pluginDenyList: []                # Block specific plugins by name
compactSkillsPrompt: false        # Use compact format (names only)
skipSimulationForSimpleTasks: true # Skip pre-task simulation

# Skill routing
skillRoutingRules:
  - intent: search
    preferSkills: [web_search, browser_navigate]
  - intent: code
    preferSkills: [run_command, read_file, write_file]

# Plugin paths
pluginsPath: ~/.orcbot/plugins
skillsPath: ./SKILLS.md

# Agent skill auto-activation
agentSkillAutoActivatePatterns:
  - web-scraper: "scrape.*website"
  - pdf-extractor: "extract.*pdf"

Further Reading