Skip to content

Repository files navigation

🧠 llm-safecall (Python)

Secure, fail-safe, and observable LLM calls for Python.

llm-safecall is a framework-agnostic, enterprise-grade safety and observability layer for interacting with large language models (LLMs).
It enforces policy guardrails, validates structured outputs, scans for secrets, applies circuit breakers and retries, and guarantees fail-safe operation.

Fail-safe by default. Secure by design. Enterprise ready.


πŸš€ Why use llm-safecall

Problem Solution
Prompt injection or data exfiltration Policy engine with prompt heuristics, secret scanning, and sanitization
Invalid or unstructured outputs Schema-based validation (Pydantic v2) with auto-repair and JSON-only enforcement
Hallucinated shell commands or URLs Output sanitization + URL allowlists
Sensitive data exposure Automatic redaction and structured logs
Network instability Retries with jitter + circuit breaker
High latency or cost Local caching + budget & rate limiting
App-breaking exceptions Fail-safe mode ensures graceful recovery

Predictable. Auditable. Secure.


βš™οΈ Installation

pip install llm-safecall
# or for development / optional providers:
pip install -e ".[dev]"
pip install ".[openai]" ".[anthropic]"

Requires Python β‰₯3.10.


✨ Quickstart

from pydantic import BaseModel
from llm_safecall import SafeCall, OpenAIProvider, PolicyEngine, PolicyConfig

class Output(BaseModel):
    title: str
    summary: str

policy = PolicyEngine(PolicyConfig(
    outbound_url_allowlist=["https://docs.company.com/"],
    allow_shell_output=False,
))

safe = SafeCall(
    llm=OpenAIProvider(model="gpt-4o-mini"),
    output=Output,
    policy=policy,
    timeout_s=15,
    retries=2,
    redact=["email", "phone"],
)

result = safe.generate("Return a JSON with keys title and summary.")
print(result.model_dump())         # validated Output
print(result._report.model_dump()) # observability info

πŸ”’ Fail-Safe Guarantee

llm-safecall never breaks your code.

Scenario Result
Validation fails Returns {} or fallback value
Provider error Returns safe fallback
Policy violation Returns sanitized fallback
Redaction triggered Sensitive data removed
All fails Returns quietly, logs structured event

Worst case: nothing happens.
Best case: you get a secure, validated, policy-compliant result.


🧱 Policy Engine

Policies can be defined in YAML or Python β€” enforcing safety both before and after LLM calls.

Example YAML

allowed_urls:
  - "https://docs.mycompany.com"
disallowed_patterns:
  - "os.system"
  - "subprocess"
  - "open('"

Example Python config

from llm_safecall import PolicyEngine, PolicyConfig

policy = PolicyEngine(PolicyConfig(
    outbound_url_allowlist=[
        "https://intranet.company.com/",
        "https://docs.company.com/",
    ],
    allow_shell_output=False,
    max_input_chars=20000,
    max_output_chars=10000,
))

Load from file:

from llm_safecall import load_policy
policy = load_policy("policy.yml")

🧩 Key Features

βœ… Safety & Policy

  • Prompt-injection detection (reveal system prompt, ignore instructions, etc.)
  • Secret scanning (AWS/GCP keys, Slack tokens, GitHub PATs)
  • Output sanitization (blocks shell commands, restricts URLs)
  • Redaction for sensitive fields (e.g. phone numbers, emails)
  • JSON-only enforcement when schema is defined

βš™οΈ Reliability

  • Retries with exponential jitter
  • Circuit breaker with cooldown
  • Timeout control
  • Local caching for consistent results

πŸ“Š Observability

  • Structured JSON logs (event=llm_call_start|end|error|cache_hit)
  • Unique call_id per call
  • Attached CallReport (latency, tokens, model)
  • SIEM/ELK-friendly log output

πŸ’° Governance

  • Optional daily budget caps
  • Token bucket rate limiter
  • Redaction + logging control for compliance

🌊 Streaming (guarded)

for chunk in safe.stream_generate("Explain quantum encryption."):
    print(chunk, end="", flush=True)

If any error or policy violation occurs, it yields a fallback token and ends gracefully β€” no crash, no broken coroutine.


πŸ€– For Agents & Copilots

⚠️ Mandatory wrapper for copilots and orchestrators

All AI agents and code copilots must route LLM calls through SafeCall.
This enforces policy compliance, prevents unsafe tool calls, blocks secret leakage, and guarantees JSON correctness.

safe = SafeCall(OpenAIProvider(model="gpt-4o-mini"), fail_safe=True)
res = safe.generate("Suggest a shell command to deploy my app.")
print(res.value)

If the response violates your org policy or produces disallowed content, you get a safe fallback β€” your copilot continues running safely.


🧰 Provider Adapters

Provider Model Package Status
OpenAI gpt-4o-mini openai βœ…
Anthropic claude-3-5-sonnet-20240620 anthropic βœ…
Mock local dev / CI built-in βœ…

Pass API keys via environment variables (OPENAI_API_KEY, ANTHROPIC_API_KEY)
or directly in constructor.


⚑ Environment-based Setup

from llm_safecall import from_env
# env: LLM_PROVIDER=openai|anthropic|mock, LLM_MODEL=..., OPENAI_API_KEY=..., etc.
safe = from_env(output=None)

πŸ§ͺ Tool Sandbox Example

from pydantic import BaseModel
from llm_safecall import ToolRunner, PolicyEngine, PolicyConfig

class Args(BaseModel):
    url: str

def fetch(url: str) -> str:
    return f"Fetched {url}"

tr = ToolRunner(PolicyEngine(PolicyConfig(outbound_url_allowlist=['https://example.com/'])))
tr.register("fetch", fetch, Args, None)
print(tr.call("fetch", url="https://example.com/ok"))

🧩 Development & Contribution

Run tests

pytest -v

Build & publish

python -m build
twine upload dist/*

Contribute

Pull requests are welcome β€” new providers, richer policies, and better telemetry are encouraged.


πŸ“¦ Repository & Metadata

PyPI version GitHub stars License: MIT


🧩 Summary

llm-safecall is a drop-in safety, observability, and compliance layer for LLM applications.

Fail-safe by default.
Secure by design.
Observable and auditable.
Enterprise ready.

About

A lightweight wrapper that makes LLM calls boring and safe

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages