Releases: acodercat/cave-agent
Agent Skills Support
What's New
CaveAgent implements the Agent Skills open standard—a portable format for packaging instructions that agents can discover and use. Originally developed by Anthropic and now supported across the AI ecosystem (Claude, Gemini CLI, Cursor, VS Code, and more), Skills enable agents to acquire domain expertise on-demand.
- SKILL.md: Define skills with YAML frontmatter (name, description, license, metadata)
- injection.py: Inject functions, variables, and types into runtime when skill is activated
- Progressive loading: Metadata at startup, instructions on-demand
- Discovery: Load skills from files or directories
Usage
from cave_agent import CaveAgent
agent = CaveAgent(model=model, skills_dir="./skills")
# Agent can call activate_skill("skill-name") to load instructionsDocumentation
Creating a Skill
A Skill is a directory containing a SKILL.md file with YAML frontmatter:
my-skill/
├── SKILL.md # Required: Skill definition and instructions
└── injection.py # Optional: Functions/variables/types to inject (CaveAgent extension)
SKILL.md structure:
---
name: data-processor
description: Process and analyze datasets with statistical methods. Use when working with data analysis tasks.
---
# Data Processing Instructions
## Quick Start
Use the injected functions to analyze datasets...
## Workflows
1. Activate the skill to load injected functions
2. Apply statistical analysis using the provided functions
3. Return structured resultsRequired fields: name (max 64 chars, lowercase with hyphens) and description (max 1024 chars)
Optional fields: license, compatibility, metadata
How Skills Load (Progressive Disclosure)
Skills use progressive disclosure to minimize context usage:
| Level | When Loaded | Content |
|---|---|---|
| Metadata | At startup | name and description from YAML frontmatter (~100 tokens) |
| Instructions | When activated | SKILL.md body with guidance (loaded on-demand) |
Using Skills
from cave_agent import CaveAgent
from cave_agent.skills import SkillDiscovery
# Load skills from directory
agent = CaveAgent(model=model, skills_dir="./skills")
# Or load specific skills
skill = SkillDiscovery.from_file("./my-skill/SKILL.md")
agent = CaveAgent(model=model, skills=[skill])When skills are loaded, the agent gains access to the activate_skill(skill_name) runtime function to activate a skill and load its instructions.
Injection Module (CaveAgent Extension)
CaveAgent extends the Agent Skills standard with injection.py—allowing skills to inject functions, variables, and types directly into the runtime when activated:
from cave_agent.runtime import Function, Variable, Type
from dataclasses import dataclass
def analyze_data(data: list) -> dict:
"""Analyze data and return statistics."""
return {"mean": sum(data) / len(data), "count": len(data)}
@dataclass
class AnalysisResult:
mean: float
count: int
status: str
CONFIG = {"threshold": 0.5, "max_items": 1000}
__exports__ = [
Function(analyze_data, description="Analyze data statistically"),
Variable("CONFIG", value=CONFIG, description="Analysis configuration"),
Type(AnalysisResult, description="Result structure"),
]When activate_skill() is called, these exports are automatically injected into the runtime namespace.
See examples/skill_data_processor.py for a complete example.
v0.6.2
Breaking Changes
- Import paths changed: Reorganized into domain subpackages
cave_agent.python_runtime→cave_agent.runtimecave_agent.security_checker→cave_agent.security
- API rename:
runtime.get_variable()→runtime.retrieve()
What's New
- Multi-Agent Coordination: Sub-agents can be injected as first-class objects into an orchestrator's runtime for programmatic control
- Domain subpackages: Cleaner organization with
models/,runtime/,security/,parsing/ - arXiv paper: Added citation for CaveAgent: Transforming LLMs into Stateful Runtime Operators
v0.6.1 - Token Usage Tracking
New Features
- Token Usage Tracking - Track prompt, completion, and total tokens across agent
execution viaAgentResponse.token_usage
Improvements
- Simplified security rules API (removed
nameparameter fromSecurityRule) RegexRulesignature changed toRegexRule(pattern, description)- Cleaner README formatting
v0.6.0
Breaking Changes
- get_variable_value() renamed to get_variable()
New Features
- Type Injection - New Type class for explicit type injection with include_schema and include_doc control
- TypeSchemaExtractor - Automatic schema extraction for Pydantic models, dataclasses, Enums, and classes
- Auto-inject types from function signatures and variable values
- New section in system prompt for LLM visibility
Improvements
- Added pydantic as core dependency
- Updated dependencies: ipython, litellm, openai, pytest
- Improved README with new examples and documentation
Release v0.5.0 - CaveAgent rebrand
refactor: rebrand PyCallingAgent to CaveAgent
- Rename package from py-calling-agent to cave-agent
- Rename module from py_calling_agent to cave_agent
- Rename main class PyCallingAgent to CaveAgent
- Update all imports across examples and tests
- Update documentation and repository URLs
- Bump version to 0.5.0
Release v0.4.4: Security Error Handling Fix
Bug Fix
- Fixed SecurityError.message attribute missing from SecurityError class causing AttributeError in agent error handling
- Improved security violation output by setting stdout to None instead of empty string for cleaner error responses
v0.4.3 - Fix Real-time Streaming
Bug Fixes
- Fixed critical streaming bug where backticks caused character loss and reordering in real-time text parsing
- Resolved execution prompt inconsistencies by renaming RESULT to OUTPUT for clearer error handling semantics
- Improved import structure with relative imports and removed duplicate SecurityError imports
v0.4.1 - Fix Real-time Streaming
Fixed streaming functionality to properly yield text character-by-character while detecting Python code blocks.
What's Fixed
- Text now streams immediately character-by-character instead of being buffered
- Python code blocks are correctly detected and buffered until complete
- Added flush() call to ensure all content is properly yielded at stream end
- Fixed state management and buffer handling for edge cases
v0.4.1: Simplified Rule-Based Security
✨ Simplified Rule-Based Security
What's Changed
- Refactored Security System: Replaced complex enum-based levels with flexible rule architecture
- New Security Rules:
ImportRule,FunctionRule,AttributeRule,RegexRule - Better Flexibility: Mix and match rules for custom security policies
- Cleaner Codebase: Reduced code by 422 lines
Release v0.4.0
🛡️ Security System Added
✨ What's New
- Security Checker: AST-based validation prevents dangerous code execution
- Security Levels: STRICT/STANDARD/RELAXED configurations
- Custom Rules: Define app-specific restrictions with regex patterns
- Simplified Error Handling: Removed
detailed_error_feedbackparameter
🔒 Security Protection
Automatically blocks: eval(), exec(), unsafe imports, file operations
📖 Usage
runtime = PythonRuntime(
enable_security=True,
security_level=SecurityLevel.STANDARD
)