Metadata-Version: 2.3
Name: perceptic-workflow-sdk
Version: 0.50.97
Summary: Python SDK for Perceptic Workflow definitions - cross-language Temporal workflow types
Author: Perceptic Technologies Ltd.
License: Proprietary
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
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: Typing :: Typed
Requires-Dist: pydantic>=2.12.5
Requires-Dist: temporalio>=1.22.0
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# Perceptic Workflow SDK

Python SDK for Perceptic Workflow definitions. This package provides cross-language Temporal workflow types that are compatible with the Java workflow definitions in perceptic-core-client.

## Installation

```bash
uv add perceptic-workflow-sdk
```

## Usage

### Runtime Input Contract

Workflows started through Perceptic Core receive a typed envelope:

- `AgentInput[T]` where:
  - `run_rid` identifies the run
  - `user_id` identifies the authenticated caller
  - `payload` contains your workflow-specific input model `T`

On the wire, Perceptic Core sends camelCase (`runRid`, `userId`, `payload`). In Python, use snake_case (`run_rid`, `user_id`, `payload`) per PEP 8. The SDK handles alias mapping automatically.

### Workflow Events

```python
from perceptic_workflow import (
    WorkflowEvent,
    InfoEvent,
    CheckpointEvent,
    UserInputEvent,
    UserInputRequestEvent,
    WorkflowCheckpointStatus,
)

# Create events
info_event = InfoEvent(
    event_id=1,
    type="progress",
    payload={"step": "processing"},
    timestamp=datetime.now()
)
```

### Implementing Workflows

The SDK provides a mixin class for implementing Perceptic-compatible workflows:

```python
from pydantic import BaseModel
from temporalio import workflow
from perceptic_workflow import AgentInput, PercepticWorkflowMixin, WorkflowEvent


class ResearchInput(BaseModel):
    query: str
    context: str

@workflow.defn
class MyWorkflow(PercepticWorkflowMixin):
    def __init__(self):
        self._events: list[WorkflowEvent] = []
        self._paused = False

    @workflow.run
    async def run(self, input: AgentInput[ResearchInput]) -> dict:
        # Envelope fields use snake_case in Python.
        run_rid = input.run_rid
        user_id = input.user_id
        request = input.payload

        if request is None:
            raise ValueError("payload is required")

        return {
            "runRid": run_rid,
            "userId": user_id,
            "query": request.query,
            "context": request.context,
        }

    @workflow.update(name=PercepticWorkflowMixin.UPDATE_SUBMIT_USER_INPUT)
    async def submit_user_input(self, inputs: dict) -> None:
        self._paused = False
        # Handle user input

    @workflow.update(name=PercepticWorkflowMixin.UPDATE_INTERRUPT)
    async def interrupt(self, reason: str) -> None:
        # Handle interruption
        pass

    @workflow.query(name=PercepticWorkflowMixin.QUERY_IS_PAUSED)
    def is_paused(self) -> bool:
        return self._paused

    @workflow.query(name=PercepticWorkflowMixin.QUERY_GET_EVENTS)
    def get_events(self, after_event_id: int | None = None) -> list[WorkflowEvent]:
        if after_event_id is None:
            return self._events
        return [e for e in self._events if e.event_id > after_event_id]
```

### Decorator Validation

`PercepticWorkflowMixin` validates required Temporal handlers at class definition time.
If any required method is missing a decorator, uses the wrong decorator kind, or uses
the wrong reserved handler name, class creation raises `TypeError`.

Example error shape:

```text
TypeError: MyWorkflow must implement Perceptic workflow handlers with the required Temporal decorators:
- Method 'submit_user_input' is not decorated with a Temporal handler. Expected @workflow.update(name=MyWorkflow.UPDATE_SUBMIT_USER_INPUT)
```

For static feedback before runtime, run type checks and the mixin checker together:

```bash
uv run ty check
uv run workflow-typecheck
```

### Troubleshooting

- `ValidationError: Field required ... run_rid/user_id` during workflow activation usually means your `@workflow.run` signature expects the wrong shape.
- Use `AgentInput[YourPayloadModel]` for the first workflow argument, not a flattened domain model.
- For run-start requests, send `runRid` and `inputs`; `userId` is derived from auth context by Perceptic Core.

## Compatibility

This package is designed to be compatible with:

- perceptic-core-client (Java)
- perceptic-core-workflow-runtime (Java)

The workflow definitions and event types are generated from the same JSON Schema sources to ensure cross-language compatibility.
