Metadata-Version: 2.5
Name: midge-security
Version: 0.2.0
Summary: Midge — fine-tuned model decisions and guards for prompts and agent actions.
Author-email: Ayush Kumar <ayushkumar23092@gmail.com>
License: MIT
Keywords: agent,ai-safety,guardrails,llm,prompt-injection,sdk,security
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: python-dotenv>=1.0
Requires-Dist: typer>=0.9
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Provides-Extra: local
Requires-Dist: laya==0.4.8; extra == 'local'
Requires-Dist: transformers==5.16.1; extra == 'local'
Provides-Extra: space
Requires-Dist: gradio-client==2.5.0; extra == 'space'
Description-Content-Type: text/markdown

# midge-security 0.2.0

The Midge customer SDK. Prompts are authorized by Midge's fine-tuned Laya checkpoint; guards stop blocked code before execution.

```python
from midge import Midge

# MIDGE_API_KEY is configured on your application server.
midge = Midge(base_url="http://127.0.0.1:8000")
verdict = midge.check("What is the capital of France?")
print(verdict.action, verdict.probabilities)

@midge.guard()
def tool(prompt: str):
    return your_tool(prompt)
```

Keep API keys server-side. `check`, `acheck`, `check_context`, `acheck_context`, `guard`, and `protect` remain supported. Checks return a truthy ALLOW verdict or a falsy BLOCK verdict. Guards raise `MidgeBlockedError` on BLOCK; `on_block` can return a fallback without executing the protected function.

For this unpublished source version, install with `pip install ./midge/midge-agent` from the repository root. `[local]` installs the Laya runtime for `Midge(offline=True)`; configure `MIDGE_MODEL_PATH` to the full fine-tuned checkpoint directory. `[space]` installs Gradio transport for `Midge(space_id="OWNER/SPACE")`; `hf_token=` is separate optional authentication for a private Space.

An explicit `base_url=` selects REST even when `MIDGE_SPACE_ID` is inherited from the environment. An explicit `space_id=` selects Space transport; supplying both arguments is a configuration error. Without either argument, `MIDGE_SPACE_ID` selects a Space, otherwise `MIDGE_BASE_URL` (or the legacy default) selects REST. Changing environment variables after importing the SDK does not update its import-time defaults: use explicit arguments or start a fresh process. `offline=True` explicitly selects local inference and is independent of backend availability. Remote clients never fall back to local inference.

To verify an outage, use the intended installed SDK, print `midge.__file__` and `midge.__version__`, confirm `client.offline is False`, `client.space_id is None`, and an explicit local `client.base_url`. Stopping a local server says nothing about availability if the client actually targets a Space, another port, or the hosted default. Connection failures, timeouts, HTTP errors and invalid verdicts refuse guarded execution; `raise_on_engine_error=True` raises a connection exception instead. An `on_block` fallback can return normally without executing the protected body, so test a body execution counter rather than only checking whether a call returned.

The real-model regression script `python scripts/smoke_guard_outage.py` (from the repository root, in an environment with local model and backend dependencies) starts its own temporary localhost backend, verifies sync/async ALLOW and BLOCK plus authentication failure, stops that backend, confirms the exact port refuses connections, and verifies both guarded bodies stay unexecuted. It records SDK location, mode, endpoint and real verdicts in `verification/guard_outage_smoke.json`. It uses synthetic credentials, forbids external connections and never stops an independently running service.

**0.2 compatibility changes:** intent, risk level and threat score are `None`; the model does not produce them. Inspect `label`, `probabilities`, optional model-returned `confidence`/`answer_confidence`, `usage`, and `error`. The reason is a status string, not an inferred explanation. `classification` and legacy `decision` are unavailable. Legacy policy names are tags with the same model behavior; custom scoring policies are rejected. Alternate model overrides are rejected. `OPENAI_API_KEY` is no longer accepted as a customer key. Upgrade SDK and backend together: missing model output is refused, even if an older service says ALLOW.

Structured context preserves all item content, order, duplicates, kind, source and parent provenance as canonical JSON. Single-prompt source/provenance metadata, and session/correlation identifiers, are not shown to the model. Over-window inputs BLOCK; no context reduction occurs.

The CLI uses the same endpoint via `Midge.check`; its optional agent provider runs only after ALLOW. Legacy classifier, detector, context and provenance utilities remain importable for existing utility callers but are never consulted by SDK checks. Their historical tests do not establish model accuracy.

See the repository's `docs/LAYA_MIGRATION.md` for the response contract, exact context serialization, verification, local setup and manual HF demo deployment. This version has not been published to PyPI.
