Metadata-Version: 2.5
Name: agenticorg
Version: 0.4.0
Summary: Python SDK for AgenticOrg agents, knowledge/OCR, voice, RPA, bridges, and commerce runtime
Author-email: Sanjeev Kumar <sanjeev@orchestrum.in>
Maintainer-email: Orchestrum Technologies LLP <sanjeev@orchestrum.in>
License-Expression: Apache-2.0
Keywords: agents,ai,enterprise,grantex,langraph
Classifier: Development Status :: 4 - Beta
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: grantex>=0.2.5
Requires-Dist: httpx>=0.28.0
Description-Content-Type: text/markdown

# AgenticOrg Python SDK

> AgenticOrg is owned by **Orchestrum Technologies LLP**. Inventor / Owner:
> **Sanjeev Kumar**. Contact [sanjeev@orchestrum.in](mailto:sanjeev@orchestrum.in)
> or [mishra.sanjeev@gmail.com](mailto:mishra.sanjeev@gmail.com). See
> [Ownership and contact](../docs/OWNERSHIP.md).

Repository client for selected AgenticOrg HTTP APIs. Method availability and
response shape depend on the installed SDK version, configured endpoint,
authentication, tenant/company access, grants, and backend deployment. Examples
below are integration candidates, not evidence of production availability or a
successful provider action.

Version `0.4.0` adds runtime resources, A2A v1 seller access and `client.cases`.
These methods are not available in `0.3.0`. Confirm that the reviewed release
exists in your package registry before installing it; publication is separate
from a repository merge. Matching backend routes, migrations and authorization
are still required.

## Install

When the package is available from the configured Python package registry:

```bash
pip install agenticorg==0.4.0
```

Pin and review the package version used by your application.

## Authentication

Create a client with an API key or delegated grant accepted by the configured
endpoint:

```python
from agenticorg import AgenticOrg

client = AgenticOrg(
    api_key="your-key",
    base_url="https://your-reviewed-endpoint.example",
)
```

Credentials identify a caller; they do not replace tenant/company authorization
or tool grants. Keep secrets outside source control.

A delegated grant (`grantex_token=`) is checked against each route's scope
exactly as an API key is: the grant must carry, for example, `agents:read` to
list agents or `agents:write` (or its alias `agents:run`) to start a run by
agent id. A grant with only tool scopes is refused with `403`.

A2A and MCP calls are scope-checked only when the deployment sets
`AGENTICORG_ROUTE_SCOPE_A2A_MCP=true` for the legacy routes. The new A2A v1
`send_message` route always requires `a2a:write` (or admin) for generic agent
runs. A merchant-issued buyer token is limited to non-binding seller questions
and does not grant generic agent execution. Then an API key or grant needs:

| Call | Route | Scope (or `agenticorg:admin`) |
|---|---|---|
| `client.agents.run(agent_type, company_id=...)` | `POST /api/v1/a2a/tasks` | `a2a:write` |
| `client.mcp.call(tool_name, arguments)` | `POST /api/v1/mcp/call` | `mcp:write`; `mcp:call` is accepted as its alias |

API keys created with the default scopes carry `mcp:call`, so `client.mcp.call`
keeps working, but not `a2a:write`, so a run by agent type gets `403` until the
key is replaced. `client.a2a` and `client.mcp.tools` read public discovery
routes and need no scope. The new `extended_agent_card` is private.

### A2A v1 seller access (0.4.0)

The tenant admin issues a one-time buyer credential, then hands it to the
approved buyer agent using a protected channel. An external agent can run on
any platform that sends A2A v1 HTTP+JSON; vendor-specific client enrollment
is separate. These SDK methods require the matching server migration and
ingress release; they are not included in the `0.3.0` wheel.

```python
from agenticorg import AgenticOrg

admin = AgenticOrg(api_key="tenant-admin-key", base_url="https://your-reviewed-endpoint.example")
approval = admin.a2a.create_buyer_access(
    merchant_id="merchant-123", seller_agent_id="seller-123",
    buyer_agent_id="external-buyer-123", expires_days=7,
)
# Deliver approval["token"] securely. It is returned only once.
buyer = AgenticOrg(api_key=approval["token"], base_url="https://your-reviewed-endpoint.example")
card = buyer.a2a.extended_agent_card()
reply = buyer.a2a.send_message("Is the canvas tote available?")
admin.a2a.revoke_buyer_access(approval["id"])
```

`standard_agent_card()` is public; `send_message(text, agent_type=...,
company_id=...)` runs a non-commerce agent only with a tenant credential and
explicit `a2a:write`. See the [A2A guide](../docs/a2a-interoperability.md).

## Company-scoped shadow candidate

Use an explicit company identifier when creating or generating a candidate.
Keep the initial state in shadow until separately reviewed and promoted:

```python
company_id = "00000000-0000-0000-0000-000000000001"

candidate = client.agents.create(
    company_id=company_id,
    name="Invoice review candidate",
    agent_type="invoice_review_candidate",
    domain="finance",
    authorized_tools=[],
    initial_status="shadow",
)

result = client.agents.run(
    candidate["agent_id"],
    action="review_draft",
    inputs={"document_ref": "sample-document"},
    company_id=company_id,  # required when running by agent type
)

print(result.status)
print(result.output)
```

The direct run uses the stored agent record; the backend must still verify its
tenant and company ownership. Do not use a company identifier supplied by
untrusted content without an authorized mapping.

## SOP draft workflow

SOP parsing produces a draft, not an approved or launchable agent:

```python
draft = client.sop.parse_text(
    "Receive a document, validate required fields, and route exceptions for review.",
    domain_hint="finance",
)

reviewed_config = dict(draft["config"])
reviewed_config["company_id"] = company_id
reviewed_config["initial_status"] = "shadow"

candidate = client.sop.deploy(reviewed_config)
print(candidate["initial_status"])
```

Before submission, review instructions, data sources, tools, grants, evidence,
approval rules, and the target company. Submission does not authorize promotion
or external actions.

## Discovery resources

| Resource | Selected methods | Boundary |
|---|---|---|
| `client.agents` | `list`, `get`, `run`, `create`, `generate` | Returned records and actions are endpoint-specific. |
| `client.connectors` | `list`, `get` | Discovery does not prove provider configuration. |
| `client.sop` | `parse_text`, `upload`, `deploy` | Parsed output requires review; deploy creates a candidate per backend policy. |
| `client.a2a` | `agent_card`, `agents` | Public discovery data can differ from authenticated runtime access. |
| `client.mcp` | `tools`, `call` | Tool records do not create execution authority. |
| `client.cases` | `submit`, `list`, `get`, `investigate` | Source-only machine-safe governed-case calls; requires tenant enablement and server-side grants. |
| `client.workflows` | generation, CRUD, run methods | Availability depends on the configured backend. |
| `client.knowledge` | search, supported types, upload, documents, delete, health, stats | Uploads can invoke OCR and indexing; inspect returned status. |
| `client.voice` | status, config, provider test, runtime health, calls, outbound call | Outbound calls are explicit and can incur provider charges. |
| `client.rpa` | scripts, history, run | A selected script can perform external browser actions. |
| `client.bridges` | register, list, status, route, deregister | Routes only to an authorized registered local bridge. |
| `client.commerce` | seller onboarding, Shopify sync, artifact/cache, buyer ask, adapters, mandate evidence, purchase/POS preparation | Purchase and POS helpers prepare handoffs; provider/POS systems remain transaction authorities. |

## Runtime examples

```python
types = client.knowledge.supported_types()
document = client.knowledge.upload("scanned-invoice.pdf")

products = client.commerce.products(merchant_id="merchant-123")
answer = client.commerce.ask({
    "merchant_id": "merchant-123",
    "question": "Which variants are fresh and in stock?",
})

voice = client.voice.status()
# Runtime health and call history are agent-scoped.
runtime = client.voice.runtime_health("00000000-0000-0000-0000-000000000001")
rpa_catalog = client.rpa.scripts()
```

`place_outbound_call`, `rpa.run`, `bridges.route`, Shopify sync, and provider
verification are intentionally explicit methods. Call them only with reviewed
tenant authorization and real external-action intent.

Inspect actual responses and errors instead of relying on illustrative output.
Authorization denials should remain denials; do not automatically broaden
credentials, scopes, or company context.

## Governed cases

Source clients can submit an application for review and start a read-only
investigation. Supply the purpose explicitly rather than relying on the API
default:

```python
case = client.cases.submit(
    {"legal_name": "Example Ltd", "jurisdiction": "GB"},
    purpose="aml.cdd.onboarding",
)
scheduled = client.cases.investigate(case["case_ref"])
record = client.cases.get(case["case_ref"])
```

The backend validates the tenant flag, actor, role registration, local purpose
allowlist, and delegated tool grant. A `202` response means investigation was
scheduled, not that it succeeded; inspect the later case state and failure
reason. This SDK intentionally has no decision, withdrawal, screening-review,
or information-request approval helper: those actions require a signed-in
human, which an API key or agent token does not represent. MCP discovery does
not expose the governed-case roles as agent tools. The legacy
`grantex==0.5.1` does not enforce purpose in the token or per-case caps. See
[case lifecycle](../docs/governance/case-lifecycle.md) and the
[tested client contract](../tests/regression/test_sdk_governed_cases.py).

## CLI

If the installed distribution provides the CLI, inspect commands with:

```bash
agenticorg --help
```

CLI behavior follows the same endpoint, evidence, authentication, and company
boundaries as the Python client.

## License

Apache-2.0
