Metadata-Version: 2.4
Name: hoshii-cdk
Version: 1.0.9
Summary: A framework for building Hoshii-compliant code components
Project-URL: Homepage, https://github.com/hoshii-ai/hoshii-cdk-python
Project-URL: Documentation, https://github.com/hoshii-ai/hoshii-cdk-python#readme
Project-URL: Repository, https://github.com/hoshii-ai/hoshii-cdk-python
Project-URL: Bug Tracker, https://github.com/hoshii-ai/hoshii-cdk-python/issues
Author-email: Hoshii AG <support@hoshii.ai>
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: protobuf>=4.0.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# hoshii-cdk

A Python framework for building Hoshii-compliant code components with declarative action definitions.

## Installation

```bash
pip install hoshii-cdk
```

## Quick Start

Define a component with typed actions:

```python
from hoshii_cdk import Component, action
from your_proto_package import ListItemsRequest, ListItemsResponse

class ItemsComponent(Component):
    name = "Items"
    description = "Item/product operations"
    
    @action(
        name="List Items",
        description="List items with optional filtering and pagination",
        request_schema=ListItemsRequest,
        response_schema=ListItemsResponse,
    )
    def list_items(self, request: dict) -> dict:
        # Your implementation here
        ...
```

Register and use the component:

```python
from hoshii_cdk import Registry
from your_components import ItemsComponent

registry = Registry()
registry.register(ItemsComponent)

# Get manifest for workflow platform introspection
manifest = registry.get_manifest()

# Invoke an action
result = registry.invoke("Items", "list_items", {"active_only": True})
```

## Features

- **Declarative Actions**: Define actions with `@action` decorator including name, description, and schemas
- **Protobuf Schema Support**: Automatically converts protobuf message types to JSON Schema
- **Registry System**: Discover, register, and invoke component actions
- **Workflow Platform Integration**: Get action manifests with full schema information for UI generation
- **Manifest Generation**: Export component metadata to JSON files for build-time discovery
- **Runtime Execution**: Load manifests and execute actions in sandboxed environments (e.g., e2b)
- **CLI Tools**: Command-line utilities for generating and validating manifests

## API Reference

### `Component`

Base class for defining components:

```python
class MyComponent(Component):
    name = "My Component"
    description = "Description of what this component does"
```

### `@action`

Decorator for defining actions:

```python
@action(
    name="Action Name",
    description="What this action does",
    request_schema=RequestProtoMessage,
    response_schema=ResponseProtoMessage,
    tags=["optional", "tags"],
)
def my_action(self, request: dict) -> dict:
    ...
```

### `Registry`

Central registry for managing components:

```python
registry = Registry()

# Register a component
registry.register(MyComponent)

# Auto-discover components in a module
registry.discover("my_package.components")

# Get manifest with all actions and schemas
manifest = registry.get_manifest()

# Invoke an action
result = registry.invoke("ComponentName", "action_name", request_dict)
```

## Manifest Workflow

The CDK supports a two-phase workflow for integration with workflow platforms:

### Build-Time: Generate Manifest

Generate a JSON manifest containing all component and action metadata:

```python
from hoshii_cdk import Registry, generate_manifest

# Discover and register components
registry = Registry()
registry.discover("my_component.components")

# Generate manifest.json
generate_manifest(registry, "manifest.json")
```

Or use the CLI:

```bash
python -m hoshii_cdk.cli generate \
  --module my_component.components \
  --output manifest.json
```

The generated manifest contains:
- Component names and descriptions
- Action names, descriptions, and tags
- Full JSON Schema for request/response types
- All metadata needed for UI generation

### Runtime: Execute from Manifest

In a sandboxed environment (e.g., e2b), load the manifest and execute actions:

```python
from hoshii_cdk import ComponentRunner

# Initialize runner with manifest and component module
runner = ComponentRunner("manifest.json", "my_component.components")

# Import components
runner.import_components()

# List available components and actions
components = runner.list_components()  # ["Items", "BusinessPartners"]
actions = runner.list_actions("Items")  # ["list_items", "get_item"]

# Get schema for an action
schema = runner.get_action_schema("Items", "list_items")
# Returns: {"request_schema": {...}, "response_schema": {...}}

# Invoke an action
result = runner.invoke("Items", "list_items", {"active_only": True})
```

### CLI Tools

Validate a manifest:

```bash
python -m hoshii_cdk.cli validate manifest.json -vv
```

## Development

### Setup

1. Clone the repository:
```bash
git clone https://github.com/hoshii-ai/hoshii-cdk-python
cd hoshii-cdk-python
```

2. Create and activate a virtual environment:
```bash
python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
```

3. Install the package in development mode with dev dependencies:
```bash
pip install -e ".[dev]"
```

### Running Tests

Run all tests:
```bash
pytest
```

Run with coverage:
```bash
pytest --cov=hoshii_cdk --cov-report=html
```

Run specific test file:
```bash
pytest tests/test_component.py -v
```

### Building the Package

1. Install build tools:
```bash
pip install build twine
```

2. Build the package:
```bash
python -m build
```

This creates distribution files in the `dist/` directory:
- `hoshii_cdk-1.0.0-py3-none-any.whl` (wheel)
- `hoshii-cdk-1.0.0.tar.gz` (source distribution)

### Publishing to PyPI

The package includes a publish script for easy deployment:

#### Quick Publish

```bash
# Publish to PyPI
./scripts/publish.sh

# Publish to TestPyPI (recommended first)
./scripts/publish.sh --test

# Build only (no upload)
./scripts/publish.sh --dry-run
```

#### Manual Publishing

If you prefer to publish manually:

##### Test PyPI (Recommended First)

1. Create an account on [Test PyPI](https://test.pypi.org/account/register/)

2. Upload to Test PyPI:
```bash
python -m build
python -m twine upload --repository testpypi dist/*
```

3. Test installation from Test PyPI:
```bash
pip install --index-url https://test.pypi.org/simple/ hoshii-cdk
```

##### Production PyPI

1. Create an account on [PyPI](https://pypi.org/account/register/)

2. Create an API token:
   - Go to Account Settings → API tokens
   - Create a token for the project or account

3. Configure credentials (optional):
```bash
# Create ~/.pypirc
cat > ~/.pypirc << EOF
[pypi]
username = __token__
password = pypi-YOUR-API-TOKEN
EOF
chmod 600 ~/.pypirc
```

4. Upload to PyPI:
```bash
python -m build
python -m twine upload dist/*
```

Or with token directly:
```bash
python -m twine upload -u __token__ -p pypi-YOUR-API-TOKEN dist/*
```

5. Verify installation:
```bash
pip install hoshii-cdk
```

### Version Bumping

Update the version in `pyproject.toml` and `src/hoshii_cdk/__init__.py` before publishing:

```toml
# pyproject.toml
[project]
version = "1.0.1"
```

```python
# src/hoshii_cdk/__init__.py
__version__ = "1.0.1"
```

## License

MIT
