Metadata-Version: 2.4
Name: engini
Version: 0.5.1
Summary: Engini SDK — agent-first ergonomic layer over the Engini Public API
Project-URL: Homepage, https://github.com/engini/engini-sdk
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.9
Requires-Dist: engini-client<0.5.0,>=0.4.0
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.6
Provides-Extra: all
Requires-Dist: tomli-w>=1.0; extra == 'all'
Requires-Dist: tomli>=2.0; (python_version < '3.11') and extra == 'all'
Requires-Dist: typer<1.0,>=0.12; extra == 'all'
Provides-Extra: cli
Requires-Dist: tomli-w>=1.0; extra == 'cli'
Requires-Dist: tomli>=2.0; (python_version < '3.11') and extra == 'cli'
Requires-Dist: typer<1.0,>=0.12; extra == 'cli'
Description-Content-Type: text/markdown

# engini

Agent-first Python SDK for the [Engini](https://engini.io) Public API — discover tools,
execute them against your connected apps, and wrap them as LLM tool definitions.

```bash
pip install engini            # SDK
pip install 'engini[cli]'     # SDK + the `engini` CLI
```

## Quickstart

```python
from engini import Engini

client = Engini(api_key="eng_…")          # or set ENGINI_API_KEY

# Discover canonical tool schemas
tools = client.tools.get(applications=["salesforce"], search="accounts", limit=5)

# Execute a tool against a connection
conn_id = next(c.connection_id for c in client.connections.list(application="salesforce"))
result = client.tools.execute(
    "salesforce_getrecords", {"sobject": "Account"}, connection_id=conn_id
)
print(result.output)
```

JWT auth is the fallback: `Engini(token="<jwt>", company_token="<id>")`, or set
`ENGINI_API_TOKEN` / `ENGINI_COMPANY_TOKEN`. With an API key the company is bound to the key,
so no company token is needed. Point at another host with `Engini(..., base_url=…)`.

## Use with an LLM

`Provider` adapters wrap canonical schemas into vendor tool definitions **client-side, with no
vendor SDK dependency**. OpenAI is the default; Anthropic is also available.

```python
# Bind applications → connections once, then drive a tool-calling loop
toolset = client.toolset(tools=["salesforce_getrecords"], connections={"salesforce": "Prod"})

openai_tools = client.provider.wrap_tools(toolset.tools())   # plain OpenAI tool-JSON dicts
# … send openai_tools to the model, get a response …
results = toolset.handle_tool_calls(llm_response)            # runs the calls, returns results
```

`client.toolset(...)` builds a local toolset (no I/O until used) or loads a server one via
`toolset_id=…`.

## What this adds over the raw REST client

Built on the autogenerated [`engini-client`](https://pypi.org/project/engini-client/), the SDK
adds what the generated client deliberately lacks: typed errors (the `EnginiError` family),
retry/backoff, auto-pagination, pluggable auth (`ApiKeyAuth` / `BearerAuth`), `Provider`
adapters for OpenAI/Anthropic, and the ergonomic `Toolset` object.

## Command-line interface

The `engini[cli]` extra ships an `engini` command — a machine-first CLI over the same surface.

```bash
engini --help     # login · logout · whoami · tools · applications · connections · connect
```

```bash
engini login --api-key eng_…                 # or run interactively on a TTY
engini whoami                                 # who am I / which company
engini applications list --available          # discover connector apps
engini tools list --application salesforce    # discover tools
engini tools call salesforce_getrecords --args '{"sobject":"Account"}' --connection <id>
engini connect                                # open the connections page in your browser
```

Output is machine-first: human-readable on a TTY, **compact JSON when piped**, pretty JSON with
`--json`. Every command also accepts `--quiet` and `--schema` (a machine-readable arg schema),
and mutating commands accept `--dry-run`. Exit codes are a stable contract
(`0` ok · `2` usage · `3` auth · `4` not found · `5` validation · `124` timeout).

Credentials and host config live in `$XDG_CONFIG_HOME/engini/config.toml`
(`%APPDATA%\engini\config.toml` on Windows), written `0600`. Resolution order is
**flags > environment > config**; the env vars are `ENGINI_API_KEY` (preferred) or
`ENGINI_API_TOKEN`, plus `ENGINI_COMPANY_TOKEN`.

Source & docs: <https://github.com/engini/engini-sdk>
