Metadata-Version: 2.5
Name: pinta-ai-sdk
Version: 0.3.0
Summary: Pinta AI runtime guard adaptor for Python agents (OpenTelemetry spans + tool-call guard)
Project-URL: Homepage, https://pinta.sh
Project-URL: Documentation, https://pypi.org/project/pinta-ai-sdk/
Author: Pinta AI
License-Expression: MIT
License-File: LICENSE
Keywords: ai-spm,guardrails,langchain,observability,opentelemetry,security
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: System :: Monitoring
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: httpx>=0.27
Requires-Dist: opentelemetry-api>=1.44
Requires-Dist: opentelemetry-sdk>=1.44
Provides-Extra: langchain
Requires-Dist: langchain-core>=1.0; extra == 'langchain'
Requires-Dist: langchain>=1.0; extra == 'langchain'
Provides-Extra: poc
Requires-Dist: langchain-core>=1.0; extra == 'poc'
Requires-Dist: langchain-mcp-adapters<0.3,>=0.2.2; extra == 'poc'
Requires-Dist: langchain>=1.0; extra == 'poc'
Requires-Dist: langsmith<1,>=0.12; extra == 'poc'
Requires-Dist: mcp<2,>=1.30; extra == 'poc'
Description-Content-Type: text/markdown

# Pinta AI SDK for Python agents

Pinta adds observability, telemetry masking and local tool-call policy evaluation
to Python agents. LangChain integration uses middleware; no sidecar is required.

**Requirements:** Python 3.12 or newer. LangChain integration requires
`langchain >= 1.0` with `create_agent`.

The distribution name is **`pinta-ai-sdk`**; the Python import remains **`pinta`**.
It is not the unrelated `pinta` distribution on PyPI. If you installed an earlier
private `pinta-ai` wheel, uninstall that distribution before installing this one:
both use the same Python namespace.

## Install

If your application already has a compatible LangChain installation:

```bash
python -m pip install pinta-ai-sdk
```

To install LangChain dependencies as well:

```bash
python -m pip install "pinta-ai-sdk[langchain]"
```

Check the installed version and run the bundled offline self-check:

```bash
python -c "import pinta; print(pinta.__version__)"
python -m pinta.selfcheck
```

The self-check requires LangChain. It uses a deterministic local model and
in-memory tools, does not contact a model provider or the Pinta backend, and does
not prove that your application's telemetry has reached the management console.

## Offline installation into an existing LangChain application

On an internet-connected computer using the same Python minor version as the
target server, download the SDK and its dependencies. Replace `VERSION` with
the selected release number:

```bash
python -m pip download "pinta-ai-sdk==VERSION" -d sdk --only-binary=:all: --platform any
```

Transfer the entire `sdk` directory through your approved file-transfer channel.
In the target application's Python environment:

```bash
python -m pip install --no-index --find-links=sdk "pinta-ai-sdk==VERSION"
python -m pinta.selfcheck
```

This path deliberately omits the `langchain` extra: the application already
provides LangChain. `--platform any` accepts platform-independent wheels only,
instead of accidentally downloading a workstation-specific native dependency.
Installing or upgrading LangChain itself requires a separate bundle compatible
with the server's Python version, operating system and architecture.

## Connect an application

Set `PINTA_BACKEND_URL` and `PINTA_API_KEY` in the application process using your
organization's approved endpoint and secret-management mechanism. Start with
`PINTA_GUARD_MODE=monitor`; switch to `enforce` only after reviewing policies and
normal application behavior.

At process startup, configure Pinta. Add middleware at the agent factory and
provide the authenticated application's user identity around each invocation:

```python
from langchain.agents import create_agent
from pinta import PintaSettings, configure, get_runtime, pinta_context
from pinta.langchain import PintaMiddleware

configure(PintaSettings.from_env())
agent = create_agent(model, tools=tools, middleware=[PintaMiddleware()])

async def answer(user, session_id, messages):
    async with pinta_context(
        user_id=user.id, user_email=user.email, session_id=session_id,
    ):
        return await agent.ainvoke({"messages": messages})

# In the application's async shutdown hook:
# await get_runtime().ashutdown()
```

Here `model`, `tools` and `user` are supplied by your application. Installation
alone does not instrument an agent or enable telemetry transmission. Outbound
HTTPS to the configured Pinta endpoint is required for export and policy refresh;
local evaluation and the self-check do not require that connection.

## Model attribution

Each model-call span retains `langchain.model.name`. A nonblank string from
`AIMessage.response_metadata` (`model_name`, `model`, then `model_id`) takes
precedence over the requested model. `langchain.model.source` records the exact
evidence field; `langchain.model.requested_name` and `.requested_source` retain
the request separately. Provider and requested-provider fields also carry sources;
providers are not inferred from model names or Python class names.

Invocation-scoped LangChain callbacks observe bound/configurable models and
dynamic middleware selections, including automatic instrumentation and deepagents.
Without response model metadata, the name is **requested**, not response-confirmed.
Names only have boundary whitespace trimmed; case, prefixes and internal whitespace
stay intact. Missing/non-string/blank values and `unknown` (case-insensitive) are
omitted, as are identifiers that masking or truncation would change. Objects and
arrays are never stringified; no SDK version or placeholder is substituted.
Strings beginning with `{` or `[` after trimming are also omitted, including
malformed or truncated JSON; rejection does not depend on successful JSON parsing.
Opaque or ambiguous multi-model wrappers can remain
unidentified; hidden retries do not create additional spans.

Model evidence belongs to that call's user and agent context, never a global
“current model” or unrelated tool call. Agent manifests describe configuration,
not observed usage. Response metadata is provider/integration-reported evidence,
not independent verification of the provider's internal routing.

## Scope and limitations

- Masking protects Pinta telemetry, not original business inputs, tool results
  or prompts sent to a model provider.
- `monitor` evaluates without blocking. `enforce` blocks `DENY` and `REVIEW`
  before the selected tool handler executes.
- Policy evaluation errors fail open with diagnostics; masking errors redact
  the affected telemetry value and are reported as failures.
- Detection depends on configured policies and supported input shapes.
  This SDK is not universally equivalent to every TypeScript runtime extractor
  and does not guarantee detection of every credential or unsafe action.
- Treat this alpha SDK as a version-pinned integration and validate your own
  normal and violation cases before enforcement.

MIT licensed. Learn more at [pinta.sh](https://pinta.sh).
