AI Cost Intelligence SDK — track, attribute, and reduce AI inference costs
Project description
runesignal Python SDK
Track, attribute, and reduce AI inference costs — per customer, per feature, per endpoint.
Install
pip install runesignal
Quick start
import runesignal
# Call once at startup
runesignal.configure(api_key="rs_live_YOUR_KEY")
# Decorate any async function that calls an LLM
@runesignal.track(customer_id=user.id, feature_tag="summarize", endpoint_id="POST /summarize")
async def summarize(text: str) -> str:
response = await openai_client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": text}],
)
return response.choices[0].message.content
That's it. RuneSignal captures model, token counts, cost, and latency — then ships the log in the background without blocking your code.
What gets captured
| Field | Source |
|---|---|
model |
response.model |
input_tokens |
response.usage.prompt_tokens |
output_tokens |
response.usage.completion_tokens |
cached_tokens |
response.usage.prompt_tokens_details.cached_tokens |
cost_usd |
Calculated from current pricing table |
latency_ms |
Wall-clock time around your function |
customer_id |
Your parameter |
feature_tag |
Your parameter |
endpoint_id |
Your parameter (defaults to function name) |
Supported providers
Works with any provider that returns an OpenAI-compatible response object (.usage.prompt_tokens, .usage.completion_tokens). Explicitly tested with:
- OpenAI (
openai≥ 1.0) - Anthropic (
anthropic≥ 0.25, returns.usage.input_tokens/.usage.output_tokens) - Google Gemini (via
google-generativeaiwith OpenAI-compat adapter)
Proxy mode (no decorator needed)
Instead of decorating individual functions, you can route all OpenAI calls through the RuneSignal proxy. The proxy forwards requests unchanged and logs in the background:
import openai
import runesignal
runesignal.configure(api_key="rs_live_YOUR_KEY")
client = openai.AsyncOpenAI(
base_url=runesignal.proxy_url(), # https://api.runesignal.com/proxy/openai/v1
api_key="your-openai-key", # still required by the OpenAI SDK
default_headers={"X-Customer-Id": user.id},
)
Safety guarantees
- Never raises — all exceptions inside the SDK are swallowed. Your code path is never affected.
- Never blocks — logs are shipped with
asyncio.create_task(fire-and-forget). - Never stores prompts or completions — only token counts and metadata.
Environment variables
| Variable | Description |
|---|---|
RUNESIGNAL_API_KEY |
Your RuneSignal API key (alternative to configure(api_key=...)) |
RUNESIGNAL_BASE_URL |
Override the ingest endpoint (useful for self-hosted or local dev) |
Pricing table
The SDK ships with a built-in pricing table (runesignal._cost_table.PRICING). It covers all major OpenAI, Anthropic, and Gemini models. Update it by bumping the SDK version or overriding PRICING directly.
License
MIT
Project details
Release history Release notifications | RSS feed
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 runesignal-0.2.0.tar.gz.
File metadata
- Download URL: runesignal-0.2.0.tar.gz
- Upload date:
- Size: 8.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63765487907386b77947dac902fdf21893bf29812b02a7b6b9abf76aac5ed4f6
|
|
| MD5 |
3ff8f046cc9f914574277b0967c1d3f5
|
|
| BLAKE2b-256 |
cae59e8ba3fb144a618f0adb6df26bf9fde7c8a284b245b279d205088ec81417
|
Provenance
The following attestation bundles were made for runesignal-0.2.0.tar.gz:
Publisher:
publish-sdk.yml on richardsplit/RuneSignal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
runesignal-0.2.0.tar.gz -
Subject digest:
63765487907386b77947dac902fdf21893bf29812b02a7b6b9abf76aac5ed4f6 - Sigstore transparency entry: 1462206879
- Sigstore integration time:
-
Permalink:
richardsplit/RuneSignal@3e00cf0105c739c610c3a3fa6ab3ce840a538696 -
Branch / Tag:
refs/tags/sdk-v0.2.0 - Owner: https://github.com/richardsplit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-sdk.yml@3e00cf0105c739c610c3a3fa6ab3ce840a538696 -
Trigger Event:
push
-
Statement type:
File details
Details for the file runesignal-0.2.0-py3-none-any.whl.
File metadata
- Download URL: runesignal-0.2.0-py3-none-any.whl
- Upload date:
- Size: 8.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45affced2378287735e53f56656ac49dc3bb326a8ceccf6e4569a2c55fba0424
|
|
| MD5 |
05d4ca449d17380455f1402cf5ff596f
|
|
| BLAKE2b-256 |
49014f47a89285ea179ee1a1c7a3e973caf04b1637a587c09c850a5e25282a7c
|
Provenance
The following attestation bundles were made for runesignal-0.2.0-py3-none-any.whl:
Publisher:
publish-sdk.yml on richardsplit/RuneSignal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
runesignal-0.2.0-py3-none-any.whl -
Subject digest:
45affced2378287735e53f56656ac49dc3bb326a8ceccf6e4569a2c55fba0424 - Sigstore transparency entry: 1462206904
- Sigstore integration time:
-
Permalink:
richardsplit/RuneSignal@3e00cf0105c739c610c3a3fa6ab3ce840a538696 -
Branch / Tag:
refs/tags/sdk-v0.2.0 - Owner: https://github.com/richardsplit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-sdk.yml@3e00cf0105c739c610c3a3fa6ab3ce840a538696 -
Trigger Event:
push
-
Statement type: