Metadata-Version: 2.4
Name: wippa-project-manager
Version: 0.1.0
Summary: Client SDK for wippa-project-manager: agents as first-class assignees, and 'done' as a signed run report
Author: wippa-studios
License: MIT
Project-URL: Homepage, https://github.com/wippa-studios/wippa-project-manager
Project-URL: Source, https://github.com/wippa-studios/wippa-project-manager
Project-URL: Issues, https://github.com/wippa-studios/wippa-project-manager/issues
Project-URL: AI Policy, https://github.com/wippa-studios/wippa-project-manager/blob/main/AI_POLICY.md
Keywords: agents,ai,agent-framework,multi-agent,project-management,task-management,uacp,agent-protocol,provenance,audit-log
Classifier: Development Status :: 3 - Alpha
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 :: Software Development :: Libraries
Classifier: Topic :: Office/Business :: Scheduling
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"

# wippa-project-manager (Python client)

Project management where an agent can be the assignee, and a task is only
**done** when a run report proves it.

This is the **client SDK**, not a Python port of the server. The server is
Node; porting it would mean two implementations of the completion gate, and the
gate is the entire product. This package sends, reports, and decides nothing.

## Install

```bash
pip install wippa-project-manager
```

Zero runtime dependencies. Deliberate: this client runs inside agents executing
untrusted work, where every dependency is another package somebody has to trust,
pin and audit in their own sandbox.

## Use

```python
from wippa_project_manager import AgentDescriptor, Capability, Client, obj_schema

client = Client()                       # http://127.0.0.1:8790

client.register_agent(AgentDescriptor(
    id="agent.reviewer",
    name="Reviewer",
    version="1.0.0",
    description="Reviews a diff",
    capabilities=(Capability(
        name="code.review",
        description="Review a diff and return findings",
        input_schema=obj_schema(diff=str, repo=str),
        output_schema=obj_schema(findings=list, verdict=str),
        tags=("review",),
    ),),
    transports=({"kind": "http"},),
))

task = client.create_task(
    "Review the auth diff",
    requirements=[{
        "name": "code.review",
        "inputSchema": obj_schema(diff=str, repo=str),
        "outputSchema": obj_schema(findings=list, verdict=str),
    }],
)

client.claim_task(task["id"], "agent.reviewer")
result = client.run(task["id"])
print(result["task"]["status"], result["report"]["outputHash"])
```

## A claim can be refused, and it says why

```python
from wippa_project_manager import ClaimRefused

try:
    client.claim_task(task["id"], "agent.partial")
except ClaimRefused as exc:
    print(exc.reason)
    # "code.review: output: output is missing 1 field(s): findings"
```

That is more useful than a boolean: it tells you which shape to change. Refusals
are recorded server-side, so they are the log of which task descriptions are
unmeetable.

## Status codes are not flattened

| Code | Meaning | Exception |
|---|---|---|
| `202` | claim accepted, nothing run yet | — |
| `409` | claim refused | `ClaimRefused` |
| `422` | a run happened, its report failed the gate | `ReportRejected` |

Collapsing these into "request failed" would hide the two outcomes worth noticing.

## The wire format

`AgentDescriptor`, `Capability` and `Envelope` mirror the published
`wippa-uacp` JSON Schemas, so a Python agent and a TypeScript agent speak the
same shape. No uacp source is copied.

## Server

[wippa-studios/wippa-project-manager](https://github.com/wippa-studios/wippa-project-manager)

```bash
npm run demo     # the vertical slice, in memory
npm start        # API + dashboard on 127.0.0.1:8790
```

## License

MIT
