Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Agent Instructions

## Branch Policy

**The `main` branch is protected.** You cannot push directly to main.

**ALWAYS create a feature branch before making changes:**
```bash
git checkout -b feature/description-of-work
# ... make changes ...
git push -u origin feature/description-of-work
# Then create a PR
```

---

This project uses **bd** (beads) for issue tracking. Run `bd onboard` to get started.

## Quick Reference
Expand Down
39 changes: 34 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ Over time, agents build a library of reliable capabilities. Simple skills become
```python
from pathlib import Path
from py_code_mode import Session, FileStorage
from py_code_mode.execution import SubprocessExecutor, SubprocessConfig

storage = FileStorage(base_path=Path("./data"))

async with Session(storage=storage) as session:
# SubprocessExecutor provides process isolation (recommended)
config = SubprocessConfig(tools_path=Path("./tools"))
executor = SubprocessExecutor(config=config)

async with Session(storage=storage, executor=executor) as session:
# Agent writes code with tools, skills, and artifacts available
result = await session.run('''
# Search for existing skills
Expand Down Expand Up @@ -61,13 +66,23 @@ skills.create(
claude mcp add py-code-mode -- uvx --from git+https://github.com/xpcmdshell/py-code-mode.git@v0.9.0 py-code-mode-mcp
```

## Three Namespaces
## Features

- **Skill persistence** - Save working code as reusable skills, invoke later without re-planning
- **Semantic search** - Find relevant skills and tools by natural language description
- **Tool integration** - Wrap CLI commands, MCP servers, and HTTP APIs as callable functions
- **Process isolation** - SubprocessExecutor runs code in a separate process with clean venv
- **Multiple storage backends** - FileStorage for local dev, RedisStorage for distributed deployments
- **Runtime dependency management** - Install packages on-demand or pre-configure for lockdown

When agents write code, three namespaces are available:
## Four Namespaces

When agents write code, four namespaces are available:

**tools**: CLI commands, MCP servers, and REST APIs wrapped as callable functions
**skills**: Reusable Python workflows with semantic search
**artifacts**: Persistent data storage across sessions
**deps**: Runtime Python package management

```python
# Tools: external capabilities
Expand All @@ -85,6 +100,10 @@ def run(repos: list) -> dict:
# Artifacts: persistent storage
artifacts.save("results", data)
cached = artifacts.load("results")

# Deps: runtime package management
deps.add("pandas>=2.0")
deps.list()
```

For programmatic access without code strings, Session also provides facade methods:
Expand All @@ -106,21 +125,31 @@ For MCP server installation, see [Getting Started](./docs/getting-started.md).

## Documentation

**Getting Started:**
- **[Getting Started](./docs/getting-started.md)** - Installation, first session, basic usage
- **[Session API](./docs/session-api.md)** - Complete Session method reference
- **[CLI Reference](./docs/cli-reference.md)** - MCP server and store CLI commands

**Core Concepts:**
- **[Tools](./docs/tools.md)** - CLI, MCP, and REST API adapters
- **[Skills](./docs/skills.md)** - Creating, composing, and managing workflows
- **[Artifacts](./docs/artifacts.md)** - Persistent data storage patterns
- **[Dependencies](./docs/dependencies.md)** - Managing Python packages
- **[Executors](./docs/executors.md)** - InProcess, Subprocess, Container execution

**Deployment:**
- **[Executors](./docs/executors.md)** - Subprocess, Container, InProcess execution
- **[Storage](./docs/storage.md)** - File vs Redis storage backends
- **[Integrations](./docs/integrations.md)** - Framework integration patterns
- **[Production](./docs/production.md)** - Deployment and scaling patterns

**Reference:**
- **[Architecture](./docs/ARCHITECTURE.md)** - System design and separation of concerns

## Examples

- **[minimal/](./examples/minimal/)** - Simple agent implementation (~100 lines)
- **[subprocess/](./examples/subprocess/)** - Process isolation without Docker
- **[autogen-direct/](./examples/autogen-direct/)** - AutoGen framework integration
- **[deps/](./examples/deps/)** - Dependency management patterns
- **[azure-container-apps/](./examples/azure-container-apps/)** - Production deployment

## License
Expand Down
31 changes: 24 additions & 7 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

This document explains how tools, skills, and artifacts interact across different deployment scenarios.

## Quick Reference

**Recommended executor for most users:** SubprocessExecutor
- Process isolation, crash recovery, no Docker required
- Used by the MCP server

**Storage decision:**
- Local development: FileStorage
- Distributed/production: RedisStorage

**Executor decision:**
- Default/Development: SubprocessExecutor (recommended)
- Untrusted code/Production: ContainerExecutor
- Trusted code + max speed: InProcessExecutor

---

## Core Concepts

| Component | Purpose | Format |
Expand Down Expand Up @@ -669,9 +686,9 @@ Choose storage backend (for skills and artifacts):

Choose executor (with tools_path):
|
+-- Same-process execution? -> InProcessExecutor(config=InProcessConfig(tools_path=...))
+-- Default (recommended) -> SubprocessExecutor(config=SubprocessConfig(tools_path=...))
+-- Docker isolation? -> ContainerExecutor(config=ContainerConfig(tools_path=...))
+-- Subprocess isolation? -> SubprocessExecutor(config=SubprocessConfig(tools_path=...))
+-- Trusted code + max speed? -> InProcessExecutor(config=InProcessConfig(tools_path=...))

Combine:
Session(storage=storage, executor=executor)
Expand Down Expand Up @@ -1036,12 +1053,12 @@ recipes: # Named presets

## Deployment Checklist

### Local Development (Session + FileStorage + InProcessExecutor)
### Local Development (Session + FileStorage + SubprocessExecutor)
- [ ] Create base storage directory for skills and artifacts
- [ ] Add YAML tool definitions to separate tools directory
- [ ] Add Python skill files to `<base_path>/skills/`
- [ ] Configure executor: `InProcessConfig(tools_path=Path("./tools"))`
- [ ] Use `Session(storage=FileStorage(base_path=...), executor=InProcessExecutor(config))`
- [ ] Configure executor: `SubprocessConfig(tools_path=Path("./tools"))`
- [ ] Use `Session(storage=FileStorage(base_path=...), executor=SubprocessExecutor(config))`

### Local with Container Isolation (Container + File)
- [ ] Build Docker image with py-code-mode installed
Expand All @@ -1050,12 +1067,12 @@ recipes: # Named presets
- [ ] Set `auth_disabled=True` for local development
- [ ] Use `Session(storage=FileStorage(...), executor=ContainerExecutor(config))`

### Production (Session + RedisStorage)
### Production (Session + RedisStorage + SubprocessExecutor)
- [ ] Provision Redis instance
- [ ] Bootstrap skills: `python -m py_code_mode.store bootstrap --target redis://... --prefix myapp:skills`
- [ ] Tools stay on filesystem (via executor config)
- [ ] Create storage: `RedisStorage(url="redis://...", prefix="myapp")`
- [ ] Configure executor: `InProcessConfig(tools_path=Path("./tools"))`
- [ ] Configure executor: `SubprocessConfig(tools_path=Path("./tools"))`
- [ ] Use `Session(storage=storage, executor=executor)`

### Production with Container Isolation
Expand Down
Loading
Loading