Metadata-Version: 2.5
Name: sasi-sdk
Version: 1.7.2
Summary: Symbolic AI Safety Intelligence — deterministic pre-LLM and post-LLM safety middleware for AI applications
Project-URL: Homepage, https://www.saski.io
Project-URL: Documentation, https://docs.sasi.ai
Project-URL: Repository, https://github.com/SASKI-Institute-PBC/SASKI-SDK
Project-URL: Issues, https://github.com/SASKI-Institute-PBC/SASKI-SDK/issues
Author-email: SASKI Institute <info@saski.io>
License-Expression: MIT
License-File: LICENSE
Keywords: ai-safety,crisis-detection,healthcare-ai,mental-health,pii-redaction
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Healthcare Industry
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: cryptography
Requires-Dist: flashtext<3.0,>=2.7
Requires-Dist: numpy>=1.24.0
Requires-Dist: onnxruntime>=1.16.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rapidfuzz<4.0,>=3.9.0
Requires-Dist: regex>=2023.0.0
Requires-Dist: transformers>=4.36.0
Provides-Extra: agentic-slack
Requires-Dist: slack-sdk<4,>=3.27.0; extra == 'agentic-slack'
Provides-Extra: child
Provides-Extra: dev
Requires-Dist: black>=23.0; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Requires-Dist: sentence-transformers>=2.2.0; extra == 'dev'
Requires-Dist: tiktoken>=0.13.0; extra == 'dev'
Provides-Extra: fp16
Requires-Dist: onnx>=1.14.0; extra == 'fp16'
Requires-Dist: optimum[onnxruntime]>=1.14.0; extra == 'fp16'
Provides-Extra: gpu
Requires-Dist: onnxruntime-gpu>=1.16.0; extra == 'gpu'
Provides-Extra: hr
Provides-Extra: patient
Provides-Extra: sports
Provides-Extra: student
Description-Content-Type: text/markdown

# SASI SDK

**Symbolic AI Safety Intelligence** — deterministic pre-LLM and post-LLM safety middleware for AI applications.

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Overview

SASI is safety middleware that sits between your application and your LLM. It analyzes user messages for:

- **Crisis detection with graduated dispositions** — messages are routed to a range of responses, from ordinary continuation to supportive handling to a deterministic clarification step to immediate crisis referral, based on the signal detected.
- **PII redaction** (aligned to the HIPAA Safe Harbor identifier set; not a HIPAA certification)
- **Multi-dimension risk scoring** (6-dimension MDTSAS heuristic scores)
- **Mode-specific safety** (12 operational modes)

**SASI tells you WHAT to do. Partner decides HOW to do it.**

**CSAM / child-exploitation coverage (A2 — classifier-dependent):** SASKI does **not** natively detect CSAM content. Enforcement for `child_exploitation_content` and `csam_adjacent_content` is tag-gated: SASKI can block once those tags are present, but your upstream classifier must produce them. Deploying without an upstream CSAM classifier means this path will not trigger.

## Hosted API (Phase 0)

This repo also includes a **Phase 0 hosted API “walking skeleton”** (`sasi_server/`) deployed on Cloud Run with:
- **`POST /v1/process`** (signed evidence block, fail-closed behavior)
- **`POST /v1/demo`** (public demo proxy; no client API key; rate limited)
- **Tenant policy resolution** via Firestore (`tenants/{tenant_id}`)
- **Append-only decision ledger** (`tenants/{tenant_id}/decisions/{run_id}`) with hashes/metadata only (no raw text)
- **Jurisdiction input support** via request `metadata.userJurisdiction` (or `metadata.user_jurisdiction`)
- **Optional mode override** via request `mode` (validated + tenant-gated; evidence includes `mode_used`/`mode_source`)
- **Compliance matrix evidence**: `evidence.compliance_decisions` (jurisdiction block > mode redact) with stable `reason_code` values

Developer utilities:
- `deploy.sh`, `setup_firestore.py`, `test_deployment.sh`
- `DURABLE_DEMO_CODE.md` (copy/paste embed demo)

## Compliance-controls note (Firestore/GCP)

HIPAA compliance is primarily a matter of integrator controls and contracts, not a matter of switching clouds. This section describes controls SASKI provides to support integrator obligations; SASKI does not certify HIPAA compliance. The most important safeguards for regulated tiers are:
- **No raw text persistence** (hashes/metadata only across all storage boundaries)
- **Strict logging discipline** (no request bodies or redacted text in logs)
- **Least-privilege IAM** and environment separation
- **Audit trails** (enable Firestore Data Access audit logs for regulated tiers)
- **Key management + rotation** (Secret Manager/KMS) and documented incident/retention procedures

## Quick Start

```bash
pip install sasi-sdk
```

### ⚠️ Production Deployment

**Before deploying to production, read:**
- **[DEPLOYMENT_RULES.md](docs/DEPLOYMENT_RULES.md)** - Safety requirements, compliance, fail-closed behavior
- **[AUDIT_REPORTING_GUIDE.md](docs/archive/AUDIT_REPORTING_GUIDE.md)** - How to extract audit reports suitable for partner regulatory workflows

**Critical requirements:**
- Crisis detection cannot be disabled
- PII redaction cannot be disabled (mode-specific)
- Audit logging required for regulated modes (partner HIPAA/COPPA obligations)
- Fail-closed behavior (errors → crisis response)
- Audit records must be stored securely (partner responsibility)
- CSAM/child-exploitation enforcement requires your upstream classifier to emit the relevant intent tags (SASKI does not natively detect CSAM)

```python
from sasi_sdk import SasiSession

# Create session with model-specific tuning (CRITICAL for safety)
session = SasiSession(
    user_id="user_123", 
    config_path="config/sasi_sdk_config.yaml",  # Mode from config file
    llm_profile="anthropic"  # or "openai", "google", etc.
)

# Analyze message
result = session.analyze("I'm feeling really down today")

# Check result
if result.action == "immediate_988":
    show_crisis_resources()
else:
    # Candidate for LLM egress when action/flags allow (use message_for_llm)
    llm_response = my_llm_call(result.message_for_llm)
```

### ⚠️ Critical: Configuration Patterns

**1. Always Pass `llm_profile`**

Different LLMs need different crisis thresholds. Without `llm_profile`, you'll get inconsistent safety behavior:

```python
# ❌ BAD: Inconsistent crisis detection across models
session = SasiSession(user_id="user_123")

# ✅ GOOD: Per-LLM threshold tuning
session = SasiSession(user_id="user_123", llm_profile="openai")
```

**2. Use Config File for Mode (Recommended)**

```python
# ✅ RECOMMENDED: Let config file control mode
session = SasiSession(
    user_id="user_123",
    config_path="config/sasi.yaml",  # mode="mental_health_support" from here
    llm_profile="anthropic"
)

# ❌ NOT RECOMMENDED: Passing mode parameter overrides config
session = SasiSession(
    user_id="user_123",
    mode="default",  # This OVERRIDES config file!
    config_path="config/sasi.yaml"
)
```

**📖 See [Integration Patterns Guide](docs/INTEGRATION_PATTERNS.md) for detailed configuration patterns.**

See [Integration Guide](docs/INTEGRATION_GUIDE.md#llm-profile-tuning) for model mapping examples.

## 12 Operational Modes

| Mode | Marketing name | Target Market | Safety Level |
|------|----------------|---------------|--------------|
| `default` | — | General applications | Balanced |
| `child` | — | Roblox, Education games | Maximum |
| `student` | — | Duolingo, Khan Academy | Balanced |
| `patient` | health_platform_user | Health platforms | Maximum |
| `therapist` | professional_context | Professional / clinical documentation contexts | Maximum |
| `mental_health_support` | — | Mental-health chatbot platforms | Maximum |
| `wellness_coaching` | — | Headspace, Calm | Balanced |
| `career_coaching` | — | LinkedIn, Career platforms | Balanced |
| `sports_coaching` | — | Fitness apps | Turbo |
| `business` | — | Customer service | Turbo |
| `general_assistant` | — | Replika, Character.ai | Balanced |
| `hr_recruiting` | — | HireVue, Workday | Balanced + Bias Detection |

*Marketing names for `patient` and `therapist` reflect a renaming in flight; the code identifiers in the Mode column remain the strings the SDK accepts today.*

## Features

### Crisis Detection

Risk-classification levels (`RiskLevel` on the result — what the detector outputs, not a guarantee of a graduated response ladder):
- **SAFE**: No concerns
- **MODERATE**: Empathy recommended
- **ELEVATED**: Monitoring recommended
- **IMMINENT**: Immediate crisis-referral disposition indicated by detector

Partner-facing response is driven by `result.action` (and related flags), which can include continuation, supportive handling, clarification, monitoring, or immediate crisis referral — not a fixed four-step response sequence.

```python
result = session.analyze("I want to end it all tonight")
print(result.risk_level)  # RiskLevel.IMMINENT
print(result.action)       # Action.IMMEDIATE_988
print(result.show_hotline) # True
```

### PII Redaction

PII redaction covers the HIPAA Safe Harbor identifier set (18 identifiers); not a HIPAA certification:

```python
result = session.analyze("Call me at 555-123-4567, my SSN is 123-45-6789")
print(result.redacted_message)  # "Call me at [PHONE_1], my SSN is [SSN_1]"
print(result.pii_types)         # ["phone", "ssn"]

# Restore in LLM response
llm_response = "I'll call you at [PHONE_1]"
display_text = result.restore_placeholders(llm_response)
# "I'll call you at 555-123-4567"
```

### MDTSAS Scoring

6-dimension MDTSAS heuristic risk scores:
- **T**: Trauma
- **D**: Depression
- **C**: Crisis
- **A**: Anxiety
- **A2**: Alliance (positive)
- **S**: Suicidality

```python
print(result.mdtsas.to_dict())
# {"T": 0.1, "D": 0.4, "C": 0.2, "A": 0.3, "A2": 0.5, "S": 0.0}
print(result.mdtsas.total_score)  # 0.23
```

### Mode-Specific Flags

```python
# Child mode - parent alerts
session = SasiSession(user_id="child_123", mode="child")
result = session.analyze("I hate everything")
if result.parent_alert_flag:
    send_parent_notification()  # Partner's responsibility

# HR mode - bias detection
session = SasiSession(user_id="hr_123", mode="hr_recruiting")
result = session.analyze("We need a young, energetic candidate")
print(result.bias_flags)  # ["age_bias"]
print(result.explainability)  # "Potential age bias detected"
```

## Configuration

### YAML Config

```yaml
# config/sasi_config.yaml
mode: patient
safety_tier: maximum

crisis:
  threshold: 0.87
  monitoring_threshold: 0.55
  min_messages_for_escalation: 3

pii:
  level: hipaa
  detect_names: true
  detect_dates: true
```

### Environment Variables

```bash
export SASI_MODE=patient
export SASI_SAFETY_TIER=maximum
export SASI_PII_LEVEL=hipaa
```

## Safety Locks

These features **CANNOT be disabled**:
- Crisis detection
- PII redaction

```python
# This raises SafetyLockError:
session = SasiSession(crisis_detection=False)
```

## Fail-Closed Design

If SASI encounters any internal error, it defaults to crisis response:

```python
try:
    result = session.analyze(message)
except CrisisEscalationError:
    # MANDATORY: Show crisis resources on internal failure
    show_crisis_resources()
```

## Air-Gapped Deployments

For deployments without internet access:

```bash
# Pre-download model
python -c "import sasi_sdk; sasi_sdk.download_models()"

# Or set custom model path
export SASI_MODEL_PATH=/path/to/local/models
```

## Plugins

Extend SASI with custom detection:

```python
from sasi_sdk.plugins import PluginBase, HookType

class MyPlugin(PluginBase):
    name = "my_company.custom"
    hooks = [HookType.POST_ANALYSIS]
    
    def post_analysis(self, result, context):
        if "company secret" in context.message:
            return {"confidential_detected": True}
        return {}

session.register_plugin(MyPlugin())
```

## Compliance

- **HIPAA Safe Harbor identifier set**: redaction patterns for 18 identifier types (integrator remains responsible for HIPAA compliance)
- **Child-privacy controls**: `child` mode applies maximum PII redaction for child-facing deployments (integrator remains responsible for COPPA obligations)
- **Education-data controls**: `student` mode provides academic data protection patterns (integrator remains responsible for FERPA obligations)
- **EU AI Act support fields**: explainability and audit-logging fields intended to support integrator EU AI Act obligations (not a conformity assessment)

## Documentation

- [SDK API Specification](docs/api_roadmap/SDK_API_SPECIFICATION.md)
- [SASI API Roadmap](docs/api_roadmap/SASI_API_ROADMAP.md)
- **[NEW] [SASKI-MCP Consolidated Blueprint (v1.0)](docs/mcp/SASKI-MCP-CONSOLIDATED-BLUEPRINT-v1.0.md)** — Compulsory Execution Shell, trust models, and the Hazardous Triad for agentic AI governance; authoritative for MCP-based implementations alongside this SDK.
- [SASKI MCP (Dev stdio scaffold)](saski_mcp/README.md)
- [Agent Rules](AGENTS.md)

## License

MIT License - See [LICENSE](LICENSE) for details.

## Support

- Email: info@saski.io
- Documentation: https://docs.sasi.ai

---

**SASKI Institute** — safety middleware for AI applications.

