Skip to main content

pysaif

A local-first library that handles AI provider logistics — API calls, config, memory, quota — so you don't have to think about them every time.

from pysaif import AI

ai = AI()
response = ai.send("Hello!")
print(response)

Install

pip install pysaif

Setup

On first run, pysaif creates a Config/ folder next to your project with config.toml (API keys, model, personality — the stuff you'll actually touch) and advanced_config.toml (timeouts, retries, per-model metadata — the stuff most people never open). Drop your API key into config.toml and you're done.

Each project gets its own config and its own key — pysaif never shares keys or settings across projects, and never reads them from your environment implicitly.

What's implemented right now

  • Config: self-healing setup, two-file split, schema versioning and migration hook
  • Providers: Google Gemini, OpenAI, Anthropic Claude, OpenRouter (sync and async)
  • Provider selection: manual, cheapest, fastest, and smart strategies
  • Quota-aware daily token limits and automatic provider failover with retries
  • Local memory under Memory/ (rolling window, important, interests) with inject/store toggles
  • Usage tracking under Usage/ (state + optional JSONL logs; message content off by default)
  • In-memory response cache (opt-in via cache.enabled)
  • Prompt assembly from optional context, background, personality, and instructions

Configuration

pysaif splits config into two files so you only have to look at one of them.

Config/config.toml — everything you're likely to actually change:

[provider]
active = "gemini"                              # used when strategy = "manual"
strategy = "manual"                             # manual | cheapest | fastest | smart
fallback_order = ["gemini", "openai", "claude", "openrouter"]

[providers.gemini]
api_key = ""
model = "gemini-2.0-flash"

[providers.openai]
api_key = ""
model = "gpt-4o-mini"

[personality]
traits = ""                                     # see "Personality" below

[prompt]
include_context = false
include_background = false
include_personality = true

[memory]
store = true
inject = true
rolling_window_size = 40
context_window_size = 12
max_important_messages = 50
max_interest_entries = 50

[quota]
enabled = true
daily_token_limit = 0                           # 0 = unlimited

[cache]
enabled = false
max_entries = 128
  • provider.strategymanual uses provider.active directly; cheapest / fastest / smart pick a provider automatically each call (see pysaif/strategy/)
  • provider.fallback_order — if the selected provider errors out or is rate-limited, pysaif retries down this list
  • memory.store — persist each exchange to local memory; memory.inject — feed relevant memory back in as context on future calls (these are independent — you can store without injecting, or vice versa)
  • quota.daily_token_limit0 means unlimited; sits on top of whatever the provider's own API limits are

Config/advanced_config.toml — timeouts, retry/backoff, per-model cost and capability metadata, and logging settings (whether usage logs include the actual message text). Most people never need to open this one.

Personality

personality.traits in config.toml is a single free-text field — not a set of named profiles. Whatever you put there gets passed straight into the prompt as-is:

[personality]
traits = "Blunt, dry humor, no filler, gets to the point."

If prompt.include_personality is true (the default) and traits isn't empty, every call sends the provider a line like:

Respond with this personality: Blunt, dry humor, no filler, gets to the point.

You can override this per call without touching the config file:

response = ai.send("Hello!", personality="Overly formal, addresses you as 'sir'")

A per-call personality argument always wins over config.toml's traits — it's a one-time substitution, not a merge. Pass nothing and it falls back to traits; if traits is also empty, no personality line gets added to the prompt at all, and include_personality has nothing to include.

There's no personality file, no "active profile" concept, and no preset library — it's intentionally just a string you write. If you want several distinct personas, keep the different strings somewhere in your own project and pass whichever one you want as personality= on each call.

What's designed but not built yet

Interactive setup wizard, richer capability tools (search/look/make), and automated config migrations beyond schema backfill — see the module skeleton under pysaif/capabilities/ for planned expansion points.

License

See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pysaif-0.1.1.tar.gz (25.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pysaif-0.1.1-py3-none-any.whl (35.1 kB view details)

Uploaded Python 3

File details

Details for the file pysaif-0.1.1.tar.gz.

File metadata

  • Download URL: pysaif-0.1.1.tar.gz
  • Upload date:
  • Size: 25.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pysaif-0.1.1.tar.gz
Algorithm Hash digest
SHA256 31bf0e26fcc4b9ae5df8191168bac8a15dd644cf1c6f5ecf788344c49a43838f
MD5 59ade94013a4964908a814b241d5d40d
BLAKE2b-256 8efe24b0cc64ffe9d3dd3c34b76e8a390906967641391b14b3c5cf778eabc344

See more details on using hashes here.

File details

Details for the file pysaif-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: pysaif-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 35.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pysaif-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1f3dfdf7d6b7c1e9cdf0bd9ab21d36473de83c710337b22c0ecfde8ed772fd82
MD5 8b22f2a995fc146ce9b567c52876356a
BLAKE2b-256 f79e0c59c75369d1adbe87ff057a9e94e1a1955cf7c27ca2366462d1e71ab18b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page