Metadata-Version: 2.5
Name: monkeyscode
Version: 1.0.0
Summary: MonkeysCode SDK — programmatic agent control for Python
Project-URL: Homepage, https://monkeyscode.com
Project-URL: Documentation, https://monkeyscode.com/docs/sdk/python
Project-URL: Repository, https://github.com/MonkeysCloud/monkeyscode
Project-URL: Issues, https://github.com/MonkeysCloud/monkeyscode/issues
License: MIT
License-File: LICENSE
Keywords: ai,automation,coding-agent,monkeyscode,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# MonkeysCode Python SDK

Programmatic agent control for Python. Run coding agents, stream events, define custom tools, and integrate with CI/CD pipelines.

## Installation

```bash
pip install monkeyscode
```

## Quick Start

```python
from monkeyscode import MonkeysCode
import asyncio

async def main():
    agent = MonkeysCode(api_key="mc_...")
    result = await agent.run("Fix all Python type errors")
    print(f"✓ {result.summary}")
    print(f"  Files: {len(result.files_changed)}, Cost: ${result.cost:.4f}")

asyncio.run(main())
```

## Streaming

```python
async for event in agent.stream("Refactor auth module"):
    if event.type == "text":
        print(event.content, end="", flush=True)
    elif event.type == "tool_call":
        print(f"  🔧 {event.tool}")
```

## Custom Tools

```python
from monkeyscode import define_tool

@define_tool(
    name="deploy",
    description="Deploy the application",
    parameters={"env": {"type": "string", "enum": ["staging", "prod"]}},
)
async def deploy(env: str) -> dict:
    return {"deployed": True, "url": f"https://{env}.example.com"}

agent.add_tool(deploy)
```

## Goal Mode

```python
result = await agent.goal(
    "All tests pass",
    verify_command="pytest",
    max_iterations=5,
)
print(f"Goal met: {result.goal_met} in {result.iterations} iterations")
```

## Sessions

```python
from monkeyscode import Session

session = await Session.create(agent, workspace="/my/project")
await session.run("Add auth module")
await session.run("Now add tests for it")  # Carries context
session.close()
```

## Local agent (`mc` subprocess)

The client above calls the hosted API. To run the agent **on this machine**
with your settings, permission rules, hooks and MCP servers, drive an
installed `mc` (standard library only):

```python
from monkeyscode.cli_process import (
    CliOptions, MonkeysCodeClient, PermissionAllow, PermissionDeny, ResultMessage, query,
)

async for event in query("explain src/main.ts"):
    if isinstance(event, ResultMessage):
        print(event.result, event.cost_usd)

async def can_use_tool(tool, tool_input, ctx):
    if str(tool_input.get("path", "")).startswith("docs/"):
        return PermissionAllow()
    return PermissionDeny(message="only docs/ may be written")

async with MonkeysCodeClient(CliOptions(can_use_tool=can_use_tool, max_cost_usd=1)) as client:
    await client.send("write docs/intro.md")
    result = await client.receive_result()
```

`query_cli` and `MonkeysCodeClient` are also exported from `monkeyscode`.
Guide: [docs/cli/sdk.md](../../docs/cli/sdk.md); a runnable three-turn
example: [`examples/three_turn_approval.py`](examples/three_turn_approval.py).

## CI/CD

```python
from monkeyscode.ci import ci_run, to_sarif
import json

result = await ci_run(
    prompt="Review this PR for security issues",
    diff=open("pr.diff").read(),
)

sarif = to_sarif(result)
with open("results.sarif", "w") as f:
    json.dump(sarif, f, indent=2)
```

## License

MIT
