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
2 changes: 1 addition & 1 deletion .licenserc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ header:
- 'docs/**/*'
- 'LICENSE'

comment: on-failure
comment: on-failure
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
"packageManager": "ms-python.python:conda"
}
]
}
}
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
74 changes: 40 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
Agent Codemode generates **programmatic tools** from two sources:

1. **MCP Servers** - Connect to any MCP server and generate typed Python bindings for its tools
2. **Skills** - Reusable code patterns that compose multiple tools into higher-level operations
1. **Skills** - Reusable code patterns that compose multiple tools into higher-level operations

These programmatic tools can be:

Expand Down Expand Up @@ -59,14 +59,21 @@ Same task, same MCP server — Code Mode uses significantly fewer tokens by comp

## Configuration Highlights

| Option | Description |
|--------|-------------|
| `allow_direct_tool_calls` | When `False` (default), `call_tool` is hidden; all execution flows through `execute_code` |
| `max_tool_calls` | Safety cap limiting tool invocations per `execute_code` run |
| `sandbox_variant` | Sandbox type for code execution (default: `"eval"`) |
| `workspace_path` | Working directory for sandbox execution |
| `generated_path` | Path where tool bindings are generated |
| `skills_path` | Path for saved skills |
| Option | Description |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `allow_direct_tool_calls` | When `False` (default), `call_tool` is hidden; all execution flows through `execute_code` |
| `max_tool_calls` | Safety cap limiting tool invocations per `execute_code` run |
| `sandbox_variant` | Sandbox type for code execution (default: `"eval"`). One of `eval`, `monty`, `docker`, `jupyter`, `colab`, `kaggle`, `modal`, `datalayer` |
| `sandbox_gpu` | Optional GPU flavor / accelerator for supported variants (Modal/Datalayer examples: `T4`, `A10G`, `A100`, `H100`; Kaggle batch examples: `NvidiaTeslaT4`, `NvidiaTeslaP100`, `T4`, `P100`) |
| `workspace_path` | Working directory for sandbox execution |
| `generated_path` | Path where tool bindings are generated |
| `skills_path` | Path for saved skills |

When using cloud notebook variants via code-sandboxes:

- `colab` reuses an already-running Colab kernel (from explicit runtime values or a channels URL).
- `kaggle` defaults to batch execution via Kaggle's API when no runtime URL/channels are provided; it can also create/attach interactive kernels when runtime values are provided.
- `kaggle` accelerator selection is available in batch mode via `gpu` / `accelerator` (for example `T4`, `P100`, `NvidiaTeslaT4`).

### Tool Discovery Options

Expand Down Expand Up @@ -108,14 +115,14 @@ await registry.discover_all()
async with CodeModeExecutor(registry) as executor:
result = await executor.execute("""
from generated.mcp.filesystem import read_file, write_file

# Read multiple files
content1 = await read_file({"path": "/tmp/file1.txt"})
content2 = await read_file({"path": "/tmp/file2.txt"})

# Process and combine
combined = content1 + "\\n---\\n" + content2

# Write result
await write_file({"path": "/tmp/combined.txt", "content": combined})
""")
Expand Down Expand Up @@ -150,10 +157,10 @@ async with CodeModeExecutor(registry) as executor:
execution = await executor.execute("""
import asyncio
from generated.mcp.filesystem import ls, read_file

# List all files
files = await ls({"path": "/data"})

# Read all files in parallel
contents = await asyncio.gather(*[
read_file({"path": f}) for f in files
Expand Down Expand Up @@ -186,25 +193,25 @@ The primary pattern is skills as Python files in a `skills/` directory:

async def batch_process(input_dir: str, output_dir: str) -> dict:
"""Process all files in a directory.

Args:
input_dir: Input directory path.
output_dir: Output directory path.

Returns:
Processing statistics.
"""
from generated.mcp.filesystem import list_directory, read_file, write_file

entries = await list_directory({"path": input_dir})
processed = 0

for entry in entries.get("entries", []):
content = await read_file({"path": f"{input_dir}/{entry}"})
# Process content...
await write_file({"path": f"{output_dir}/{entry}", "content": content.upper()})
processed += 1

return {"processed": processed}
```

Expand Down Expand Up @@ -368,17 +375,17 @@ Then configure your MCP client to run the launcher script.

**Tools exposed by the MCP server:**

| Tool | Description |
|------|-------------|
| `search_tools` | Progressive tool discovery |
| `list_servers` | List connected MCP servers |
| `list_tool_names` | Fast listing of tool names |
| `get_tool_details` | Get full tool schema |
| `execute_code` | Run code that composes tools |
| `call_tool` | Direct tool invocation |
| `save_skill` / `run_skill` | Skill management |
| `list_skills` / `delete_skill` | Skill management |
| `add_mcp_server` | Dynamically add servers |
| Tool | Description |
| ------------------------------ | ---------------------------- |
| `search_tools` | Progressive tool discovery |
| `list_servers` | List connected MCP servers |
| `list_tool_names` | Fast listing of tool names |
| `get_tool_details` | Get full tool schema |
| `execute_code` | Run code that composes tools |
| `call_tool` | Direct tool invocation |
| `save_skill` / `run_skill` | Skill management |
| `list_skills` / `delete_skill` | Skill management |
| `add_mcp_server` | Dynamically add servers |

## Recommended System Prompt

Expand All @@ -394,7 +401,7 @@ You are an AI assistant with access to MCP tools via Code Mode.
- **execute_code** - Execute Python code in a sandboxed environment

## Execution Model
ALL tool execution must go through execute_code. Write Python code that imports
ALL tool execution must go through execute_code. Write Python code that imports
and uses the generated tool bindings:

from generated.mcp.filesystem import read_file
Expand All @@ -405,9 +412,8 @@ print(content)
## Workflow

1. Discover tools using search_tools or list_tool_names
2. Write Python code that imports tools from generated.mcp.<name>
3. Execute using execute_code

1. Write Python code that imports tools from generated.mcp.<name>
1. Execute using execute_code

See the [Getting Started guide](https://agent-codemode.datalayer.tech/getting-started) for a complete system prompt example.

Expand Down
82 changes: 41 additions & 41 deletions agent_codemode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,28 @@
''')
"""

# Import skills functionality from agent_skills
from agent_skills import ( # type: ignore[import-untyped]
RateLimiter,
Skill,
SkillDirectory,
SkillFile,
SkillsManager,
parallel,
retry,
run_with_timeout,
setup_skills_directory,
wait_for,
)

from .composition.executor import CodeModeExecutor
from .discovery.codegen import PythonCodeGenerator
from .discovery.registry import ToolRegistry
from .proxy.mcp_client import MCPClient
from .proxy.meta_tools import MetaToolProvider
from .server import configure as configure_server
from .server import mcp as codemode_server
from .toolset import PYDANTIC_AI_AVAILABLE, CodemodeToolset
from .types import (
CodeModeConfig,
MCPServerConfig,
Expand All @@ -40,58 +59,39 @@
ToolDefinition,
ToolParameter,
)
from .proxy.mcp_client import MCPClient
from .proxy.meta_tools import MetaToolProvider

# Import skills functionality from agent_skills
from agent_skills import (
Skill,
SkillDirectory,
SkillFile,
SkillsManager,
setup_skills_directory,
wait_for,
retry,
run_with_timeout,
parallel,
RateLimiter,
)

from .server import mcp as codemode_server, configure as configure_server
from .toolset import CodemodeToolset, PYDANTIC_AI_AVAILABLE

__all__ = [
# Core components
"ToolRegistry",
"PYDANTIC_AI_AVAILABLE",
"CodeModeConfig",
"CodeModeExecutor",
"PythonCodeGenerator",
# Pydantic AI Toolset
"CodemodeToolset",
# Proxy
"MCPClient",
"MCPServerConfig",
"MetaToolProvider",
"PythonCodeGenerator",
"RateLimiter",
"SearchResult",
"ServerInfo",
# Skills (from agent_skills)
"Skill",
"SkillsManager",
"SkillDirectory",
"SkillFile",
"setup_skills_directory",
# Helpers (from agent_skills)
"wait_for",
"retry",
"run_with_timeout",
"parallel",
"RateLimiter",
# MCP Server
"codemode_server",
"configure_server",
# Pydantic AI Toolset
"CodemodeToolset",
"PYDANTIC_AI_AVAILABLE",
"SkillsManager",
"ToolCallResult",
# Models
"ToolDefinition",
"ToolParameter",
"ToolCallResult",
"MCPServerConfig",
"CodeModeConfig",
"SearchResult",
"ServerInfo",
# Core components
"ToolRegistry",
# MCP Server
"codemode_server",
"configure_server",
"parallel",
"retry",
"run_with_timeout",
"setup_skills_directory",
# Helpers (from agent_skills)
"wait_for",
]
2 changes: 1 addition & 1 deletion agent_codemode/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

"""Agent Codemode."""

__version__ = "0.1.3"
__version__ = "0.1.5"
Loading