Core detection, scoring, and healing engine for Pisama agent forensics
Project description
pisama-core
Detection, scoring, and healing engine for AI agent systems. Detect failure modes like infinite loops, hallucinations, cost overruns, and coordination breakdowns in your LLM agents -- entirely offline, no API keys required.
Part of the Pisama platform for multi-agent failure detection.
Install
pip install pisama-core
Quick Start
import asyncio
from pisama_core import Trace, SpanKind, DetectionOrchestrator
# Build a trace from your agent's execution
trace = Trace()
for i in range(8):
trace.create_span(name="Read", kind=SpanKind.TOOL)
# Run all built-in detectors
orchestrator = DetectionOrchestrator()
result = asyncio.run(orchestrator.analyze(trace))
for detection in result.detections:
print(f"[{detection.detector_name}] {detection.summary}")
print(f" Severity: {detection.severity}/100")
print(f" Fix: {detection.fix_recommendation.instruction}")
Output:
[loop] Tool 'Read' repeated 8x consecutively
Severity: 45/100
Fix: Stop the current loop. Try a different approach or ask the user for guidance.
No API key. No network calls. Runs completely locally. The optional telemetry is opt-in and disabled by default.
Built-in Detectors
| Detector | What it catches |
|---|---|
| Loop | Consecutive repetitions, cyclic patterns (A->B->A->B), low tool diversity |
| Repetition | Similar actions with slight variations, tool dominance |
| Cost | Token budget overruns, excessive LLM/tool calls |
| Hallucination | Failed file operations, error rate spikes |
| Coordination | Message storms, agent imbalance, handoff loops |
All detectors support both batch analysis (full trace) and real-time hooks (per-span).
Use Individual Detectors
import asyncio
from pisama_core import Trace, SpanKind
from pisama_core.detection.detectors.loop import LoopDetector
from pisama_core.detection.detectors.cost import CostDetector
trace = Trace()
# ... add spans representing your agent's execution
loop = LoopDetector()
cost = CostDetector()
loop_result = asyncio.run(loop.detect(trace))
cost_result = asyncio.run(cost.detect(trace))
if loop_result.detected:
print(f"Loop detected: {loop_result.summary}")
Write Your Own Detector
from pisama_core import BaseDetector, DetectionResult, Trace
from pisama_core.detection.result import FixType
class MyDetector(BaseDetector):
name = "my_detector"
description = "Detects my custom failure pattern"
version = "0.1.0"
async def detect(self, trace: Trace) -> DetectionResult:
# Your detection logic here
tool_names = trace.get_tool_sequence()
if len(set(tool_names)) == 1 and len(tool_names) > 5:
return DetectionResult.issue_found(
detector_name=self.name,
severity=50,
summary="Agent is stuck using a single tool",
fix_type=FixType.SWITCH_STRATEGY,
fix_instruction="Try a different approach",
)
return DetectionResult.no_issue(self.name)
Register it so the orchestrator picks it up:
from pisama_core import registry
registry.register(MyDetector())
Core Concepts
- Trace -- A complete agent execution session containing multiple spans
- Span -- A single unit of work (tool call, LLM inference, agent turn) with
kind, timing, and optional I/O data - DetectionResult -- Detector output: issue found (yes/no), severity (0-100), evidence, fix recommendation
- DetectorRegistry -- Plugin system for registering detectors (built-ins auto-register on import)
- DetectionOrchestrator -- Runs all registered detectors and aggregates results
Platform Support
Traces are framework-agnostic. Set platform for platform-aware threshold tuning:
from pisama_core import Trace, TraceMetadata, Platform
trace = Trace(metadata=TraceMetadata(platform=Platform.LANGGRAPH))
Works with Claude Agent SDK, LangGraph, AutoGen, CrewAI, n8n, Dify, and custom agents.
Pisama Platform
For production monitoring with 25+ calibrated detectors, ML-based detection, LLM-as-judge verification, and a dashboard, see pisama.ai.
Telemetry
pisama-core does not send any telemetry by default. Nothing leaves your
process unless you explicitly opt in.
If you'd like to help us understand which Python versions, operating systems, and runtime environments to prioritize, you can opt in with one of:
export PISAMA_TELEMETRY=1
Or programmatically:
import pisama_core
pisama_core.enable_telemetry()
When opted in, one HTTP POST is sent to https://api.pisama.ai/api/v1/telemetry/install:
| Field | Example |
|---|---|
install_id |
locally-generated UUID4, persisted at ~/.pisama/install_id |
sdk_version |
1.7.1 |
python |
3.12.3 |
os |
Darwin, Linux, Windows |
os_release |
25.2.0 (truncated to 64 chars) |
runtime_env |
github_actions, aws_lambda, vercel, fly, modal, kubernetes, docker, local, etc. |
event |
first_run once, session thereafter |
What is never sent: trace contents, detector outputs, file paths, environment variables, hostnames, IPs (the server discards them on receipt), API keys, or user identifiers.
To opt back out (overrides any opt-in):
export DO_NOT_TRACK=1
touch ~/.pisama/telemetry_disabled
Or: pisama_core.disable_telemetry().
The implementation is a single file:
src/pisama_core/utils/_telemetry.py —
stdlib-only, daemon-thread send, 2-second timeout, swallows all exceptions.
Telemetry can never block, slow down, or crash your process.
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 pisama_core-1.7.1.tar.gz.
File metadata
- Download URL: pisama_core-1.7.1.tar.gz
- Upload date:
- Size: 253.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d72f11fca1a1d3aec1298fb705cf7c0b4bb2f112a30721486f803b1aa8fed4a
|
|
| MD5 |
ae07f7ffe11fd524637ddaf61e454149
|
|
| BLAKE2b-256 |
5e6f8b48adae019fb02f077e4b9670b50ad22965b2a144cc3dc8b117196adf2c
|
Provenance
The following attestation bundles were made for pisama_core-1.7.1.tar.gz:
Publisher:
publish.yml on tn-pisama/pisama
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pisama_core-1.7.1.tar.gz -
Subject digest:
1d72f11fca1a1d3aec1298fb705cf7c0b4bb2f112a30721486f803b1aa8fed4a - Sigstore transparency entry: 1405626286
- Sigstore integration time:
-
Permalink:
tn-pisama/pisama@e41cbf6267782e247d5f7b6c19fb9387b33d26ee -
Branch / Tag:
refs/tags/pisama-core-v1.7.1 - Owner: https://github.com/tn-pisama
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e41cbf6267782e247d5f7b6c19fb9387b33d26ee -
Trigger Event:
push
-
Statement type:
File details
Details for the file pisama_core-1.7.1-py3-none-any.whl.
File metadata
- Download URL: pisama_core-1.7.1-py3-none-any.whl
- Upload date:
- Size: 257.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18657a7a92fd4764c4f148f45cc9ccbb82bdd2df8eb6fe6c9173775a9c8eb249
|
|
| MD5 |
9a44d8812f55ff82006ab85dc93a61ce
|
|
| BLAKE2b-256 |
3c165043104f4091de130cb7e9ab0a6bb192f5958c15e6f54fceb9be467264bd
|
Provenance
The following attestation bundles were made for pisama_core-1.7.1-py3-none-any.whl:
Publisher:
publish.yml on tn-pisama/pisama
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pisama_core-1.7.1-py3-none-any.whl -
Subject digest:
18657a7a92fd4764c4f148f45cc9ccbb82bdd2df8eb6fe6c9173775a9c8eb249 - Sigstore transparency entry: 1405626375
- Sigstore integration time:
-
Permalink:
tn-pisama/pisama@e41cbf6267782e247d5f7b6c19fb9387b33d26ee -
Branch / Tag:
refs/tags/pisama-core-v1.7.1 - Owner: https://github.com/tn-pisama
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e41cbf6267782e247d5f7b6c19fb9387b33d26ee -
Trigger Event:
push
-
Statement type: