Metadata-Version: 2.4
Name: ocyan.plugin.openai
Version: 0.2.0rc1
Summary: MandelBlog OpenAI provider integration
Author: MandelBlog
License-Expression: LicenseRef-Proprietary
Classifier: Framework :: Django
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: <3.14,>=3.12
Description-Content-Type: text/markdown
Requires-Dist: Django<5.3,>=5.2
Requires-Dist: jsonschema<5,>=4.23
Requires-Dist: ocyan.core<2,>=1.2.14
Requires-Dist: openai<4,>=2

# MandelBlog OpenAI provider integration

`ocyan.plugin.openai` is the reusable, server-side OpenAI provider layer for
MandelBlogStack.  It centralizes provider configuration, capability gates,
timeouts, retries, response normalization, structured-output validation, usage
metadata, redacted telemetry and deterministic test seams.

It uses the current OpenAI **Responses API** through the official Python SDK.
The provider never enables itself by default and sends `store=False` on every
request.

## What it owns

- Server-side OpenAI client construction and environment-backed credentials.
- Bounded request execution: capability allowlist, output-token ceiling,
  timeout, retry/backoff for timeout/429/5xx failures and local concurrency cap.
- Plain-text generation and JSON-schema structured responses.
- Safe provider result metadata: model, response/request IDs, usage and a
  one-way input fingerprint.  Prompts, API keys and raw provider failures are
  never logged by this package.
- A consumer redaction hook for data minimization before a request leaves the
  application boundary.

## What it does not own

It does not own prompts, chat personalities, UI, Wagtail panels, product
operations, translation policies, publishing, CRM actions, task scheduling or
customer data classification.  Consumers retain those responsibilities and must
establish their own human-review or explicitly approved automation contract.

## Configuration

Use the established deployment secret/configuration mechanism; never place an
API key in source, fixtures, settings committed to Git or a Wagtail/site field.

```python
OPENAI_ENABLED = True                 # default: False
OPENAI_API_KEY = env("OPENAI_API_KEY")
OPENAI_MODEL = "gpt-5-mini"
OPENAI_ALLOWED_CAPABILITIES = ("draft", "summarize", "extract")
OPENAI_TIMEOUT_SECONDS = 20
OPENAI_MAX_RETRIES = 2
OPENAI_MAX_OUTPUT_TOKENS = 1200
OPENAI_MAX_CONCURRENCY = 4
```

`OPENAI_ENABLED=False`, a missing key, or an unapproved capability fail closed.
There is no production credential in this repository and package certification
does not make a live API call.

## Consumer example

```python
from ocyan.plugin.openai.provider import OpenAiProvider

result = OpenAiProvider().structured(
    capability="extract",
    input_text=reviewable_text,
    schema_name="ticket_classification",
    schema={
        "type": "object",
        "properties": {"category": {"type": "string"}},
        "required": ["category"],
        "additionalProperties": False,
    },
)
# result.data is schema-validated.  The consumer decides whether and how a
# human reviews it; this provider never publishes or performs business actions.
```

## Privacy, security and operations

- Restrict `OPENAI_ALLOWED_CAPABILITIES` per deployment; use a dedicated
  provider project/key with least privilege and rotate it through the normal
  secret-management process.
- Minimize input and use `redactor=` when a consumer can remove unnecessary
  personal or customer data.  Review OpenAI project data-control settings before
  approving production customer-data use.
- Monitor `response_id`, `request_id`, usage and input fingerprint; do not add
  prompt bodies or secrets to logs.
- Output-token ceilings and concurrency limits are the portable provider-level
  cost/abuse controls.  Monetary budgets remain deployment/account controls,
  since model pricing is provider-managed and changes over time.

## Existing consumers and migration

`ocyan.plugin.ai_auto_translate` and `ocyan.plugin.ai_assistant` currently
carry legacy direct OpenAI client/key/model logic.  This package is compatible
with a future controlled migration, but does not alter their translation
workflow or customer chat/UI contract in this release.  Migrations must be
versioned and tested in each consumer, retaining their own prompts, review
policy and public/admin boundaries.

## Testing

The deterministic suite uses fake clients only and covers disabled/missing
configuration, client construction, request construction, output limits,
structured-schema validation, retryable and non-retryable errors, redaction,
usage metadata and Django entrypoint defaults.  A live smoke test is intentionally
absent: it must be separately enabled with an approved non-production project
key and non-customer synthetic input.
