Durable, dependency-free Python SDK for capturing AI-agent runs and shipping them to Intencion.
Project description
intencion
Durable, dependency-free Python SDK for capturing AI-agent runs and shipping them to Intencion. Pure stdlib, Python 3.8+, non-blocking background transport.
Install
pip install intencion
Quickstart
import intencion
intencion.init(api_key="in_pk_...") # call once at startup
with intencion.run(intent="support", input=user_msg, user="u_123",
session="s_1", model="gpt-4o") as run:
run.step(name="lookup_order", tool="db", status="success", ms=42)
result = my_agent(user_msg) # your agent work
# outcome defaults to "success"; override with run.fail("...")/run.abandon()
# decorator form
@intencion.trace(intent="classify")
def classify(msg): ...
intencion.flush() # force send queued runs
If the wrapped code raises, the run is recorded as failure and the exception is re-raised unchanged.
Auto-instrumentation (zero per-call code)
Wrap your OpenAI or Anthropic client once and every model call is captured automatically — model, token usage, latency, and outcome — with no run.step(...) calls:
from openai import OpenAI
import intencion
intencion.init(api_key="in_pk_...")
client = intencion.instrument_openai(OpenAI()) # the whole integration
# Just use the client. A run shows up in Intencion for every call.
client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "where is my order?"}],
)
- Calls made inside an
intencion.run(...)block become steps on that run, and their model + token usage are folded into it. - Calls made outside a run emit a standalone one-call run. Its intent defaults to
"auto", which the server infers into a real label (e.g.order_status) from the input. - Sync, async (
AsyncOpenAI/AsyncAnthropic), and streaming calls are all supported; iteration is transparent.
client = intencion.instrument_anthropic(Anthropic())
# Pin a fixed intent, or skip prompt capture:
client = intencion.instrument_openai(OpenAI(), intent="support", capture_input=False)
Patching is at the class level, so it covers every client instance — including the ones agent frameworks (LangChain, the OpenAI Agents SDK, LlamaIndex, Instructor) build internally. You can pass a client, or call with no argument to patch the installed package directly:
intencion.instrument_openai() # patches the openai package (covers framework-built clients)
intencion.instrument_anthropic() # patches the anthropic package
It instruments create, parse (structured outputs), and the stream() helper, across sync/async. instrument_* is idempotent and never raises; enable debug=True logging to see which methods were patched (it warns loudly if it found nothing — so a miss isn't silent).
Not yet covered (roadmap): stacks that don't call the official SDK — the Vercel AI SDK, CrewAI/LiteLLM, raw boto3 Bedrock, and google-genai (Gemini/Vertex). And without an intencion.run(...) wrapper, a multi-call agent task is recorded as several runs rather than one trace.
Short-lived processes
The worker flushes on an interval, on atexit, and on SIGTERM/SIGINT. For a script, a serverless function, or any process that exits quickly, call flush() before the process ends to ensure queued runs are sent:
intencion.flush() # block until queued runs are sent (or timeout)
intencion.shutdown() # flush + stop the worker thread
Configuration
| Option | Default | Meaning |
|---|---|---|
api_key |
— (required) | Sent as Authorization: Bearer <api_key>. |
endpoint |
https://intencion.io/api/ingest |
Ingest URL. |
flush_interval |
5.0 |
Seconds between timed flushes. |
max_batch |
100 |
Max runs per request (hard-capped at 500). |
max_queue |
1000 |
Bounded queue size; drop-oldest when full. |
sample_rate |
1.0 |
Fraction of runs captured (0.0 to 1.0). |
disabled |
False |
Disable all capture. |
debug |
False |
Enable debug logging on the intencion logger. |
API
intencion.init(api_key, endpoint=None, flush_interval=5.0, max_batch=100,
max_queue=1000, sample_rate=1.0, disabled=False, debug=False)
intencion.run(intent, input=None, user=None, session=None, model=None)
# use as a context manager (with statement)
intencion.trace(intent, user=None, session=None, model=None, capture_input=False)
# use as a function decorator
intencion.flush(timeout=None)
intencion.shutdown(timeout=2.0)
# Auto-instrument a provider client — every call is captured automatically
intencion.instrument_openai(client, intent="auto", capture_input=True)
intencion.instrument_anthropic(client, intent="auto", capture_input=True)
intencion.current_run() # the run in scope inside a run() block, or None
A run object exposes: step(name, status="success", tool=None, ms=None, error=None), ok(), fail(reason=None), abandon(reason=None), set_tokens(tokens_in, tokens_out), set_model(model).
License
MIT. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file intencion-0.2.0.tar.gz.
File metadata
- Download URL: intencion-0.2.0.tar.gz
- Upload date:
- Size: 28.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
20201913a6dddff91718f4e3c1d39510a50841199c872b3afbf43824b09af65d
|
|
| MD5 |
dba0c3a2aaeadef83e6fb8d34de58155
|
|
| BLAKE2b-256 |
aa37190b8c7bc1dcaf74aff80202be0e6671809fba3f3f54e61f4ec710d8401a
|
File details
Details for the file intencion-0.2.0-py3-none-any.whl.
File metadata
- Download URL: intencion-0.2.0-py3-none-any.whl
- Upload date:
- Size: 24.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7e315c115115c97fb0f225e97eb214e8fa60cac7c2ae9274dc926966af56f35
|
|
| MD5 |
8474d95c5faa9775e5b9bfabd65ba23c
|
|
| BLAKE2b-256 |
dd785778cc90f722eedd093253c07814c80389492ee12f36708042370e07304b
|