Spaces:
Running
Running
Download _utils/_document_generation.py from scikit-plots/ai: direct link, hf CLI and curl.
- Browser
- Download file 7 kB
-
https://huggingface.co/spaces/scikit-plots/ai/resolve/main/_utils/_document_generation.py
- Command line
-
hf download hf://spaces/scikit-plots/ai/_utils/_document_generation.py
-
curl -L -o _document_generation.py https://huggingface.co/spaces/scikit-plots/ai/resolve/main/_utils/_document_generation.py
7 kB
| # scikitplot/_externals/_sphinx_ext/_sphinx_ai_assistant/_hf_spaces_proxy/_utils/_document_generation.py | |
| # | |
| # flake8: noqa: D213 | |
| # | |
| # Authors: The scikit-plots developers | |
| # SPDX-License-Identifier: BSD-3-Clause | |
| """Bounded provider-neutral contract for one-shot AI Learn document generation.""" | |
| from __future__ import annotations | |
| import hashlib | |
| import json | |
| import re | |
| import uuid | |
| from dataclasses import dataclass | |
| from datetime import datetime, timezone | |
| from typing import Any | |
| DOCUMENT_GENERATION_REQUEST_CONTRACT = "assistant.document-generation-request.v1" | |
| DOCUMENT_GENERATION_RESPONSE_CONTRACT = "assistant.document-generation-response.v1" | |
| DOCUMENT_GENERATION_CAPABILITY_VERSION = 1 | |
| MAX_DOCUMENT_GENERATION_REQUEST_BYTES = 128 * 1024 | |
| MAX_DOCUMENT_PROMPT_CHARS = 48_000 | |
| MAX_DOCUMENT_TITLE_CHARS = 200 | |
| MAX_DOCUMENT_OUTPUT_CHARS = 1_000_000 | |
| FORMATS = { | |
| "markdown": ("md", "text/markdown"), | |
| "rst": ("rst", "text/x-rst"), | |
| "text": ("txt", "text/plain"), | |
| } | |
| class DocumentGenerationError(ValueError): | |
| """Stable public request/response validation error.""" | |
| def __init__(self, code: str, message: str = "") -> None: | |
| super().__init__(message or code) | |
| self.code = code | |
| class DocumentGenerationRequest: | |
| prompt: str | |
| selected_model: str | |
| format: str | |
| title: str | |
| def _text(value: Any, *, field: str, maximum: int, required: bool = False) -> str: | |
| if value is None: | |
| value = "" | |
| if not isinstance(value, str) or len(value) > maximum: | |
| raise DocumentGenerationError("REQUEST_INVALID", f"{field} is invalid") | |
| if ( | |
| any( # lint | |
| ( | |
| ord(ch) < 32 # ruff: ignore[magic-value-comparison] | |
| and ch not in "\n\r\t" | |
| ) | |
| for ch in value | |
| ) | |
| or "\x7f" in value | |
| ): | |
| raise DocumentGenerationError( | |
| "REQUEST_INVALID", f"{field} contains control characters" | |
| ) | |
| value = value.strip() | |
| if required and not value: | |
| raise DocumentGenerationError("REQUEST_INVALID", f"{field} is required") | |
| return value | |
| def parse_document_generation_request(raw: bytes) -> DocumentGenerationRequest: | |
| if len(raw) > MAX_DOCUMENT_GENERATION_REQUEST_BYTES: | |
| raise DocumentGenerationError("REQUEST_TOO_LARGE") | |
| try: | |
| value = json.loads(raw) | |
| except (UnicodeDecodeError, json.JSONDecodeError, TypeError, ValueError) as exc: | |
| raise DocumentGenerationError( | |
| "REQUEST_INVALID", | |
| "request must be valid JSON", | |
| ) from exc | |
| if not isinstance(value, dict): | |
| raise DocumentGenerationError("REQUEST_INVALID", "request must be an object") | |
| allowed = {"contract", "prompt", "selected_model", "format", "title"} | |
| if set(value) - allowed: | |
| raise DocumentGenerationError( | |
| "REQUEST_INVALID", | |
| "request contains unsupported fields", | |
| ) | |
| if value.get("contract") != DOCUMENT_GENERATION_REQUEST_CONTRACT: | |
| raise DocumentGenerationError( | |
| "REQUEST_INVALID", "unsupported document generation contract" | |
| ) | |
| fmt = _text( | |
| value.get("format", "markdown"), | |
| field="format", | |
| maximum=32, | |
| required=True, | |
| ).lower() | |
| if fmt not in FORMATS: | |
| raise DocumentGenerationError("REQUEST_INVALID", "unsupported document format") | |
| return DocumentGenerationRequest( | |
| prompt=_text( | |
| value.get("prompt"), | |
| field="prompt", | |
| maximum=MAX_DOCUMENT_PROMPT_CHARS, | |
| required=True, | |
| ), | |
| selected_model=_text( | |
| value.get("selected_model"), | |
| field="selected_model", | |
| maximum=256, | |
| ), | |
| format=fmt, | |
| title=_text( | |
| value.get("title", "AI Learn document"), | |
| field="title", | |
| maximum=MAX_DOCUMENT_TITLE_CHARS, | |
| ) | |
| or "AI Learn document", | |
| ) | |
| def build_document_prompt( | |
| request: DocumentGenerationRequest, | |
| ) -> str: | |
| syntax = { | |
| "markdown": "GitHub-flavored Markdown", | |
| "rst": "reStructuredText", | |
| "text": "plain text", | |
| }[request.format] | |
| return ( | |
| "Create one self-contained learning document from the request below.\n" | |
| f"Output format: {syntax}.\n" | |
| "Return only the document body: no surrounding code fence, no preamble about the task, " | |
| "and no claim that the document was saved or published. Preserve uncertainty, distinguish " | |
| "source-grounded facts from synthesis, and do not invent citations.\n\n" | |
| "Untrusted document request:\n" + request.prompt | |
| ) | |
| def extract_text_completion( | |
| payload: Any, | |
| ) -> str: | |
| """Extract bounded text from common OpenAI-compatible non-stream responses.""" | |
| text = "" | |
| if isinstance(payload, dict): | |
| choices = payload.get("choices") | |
| if isinstance(choices, list) and choices and isinstance(choices[0], dict): | |
| message = choices[0].get("message") | |
| if isinstance(message, dict): | |
| content = message.get("content") | |
| if isinstance(content, str): | |
| text = content | |
| elif isinstance(content, list): | |
| parts = [ | |
| part["text"] | |
| for part in content | |
| if isinstance(part, dict) and isinstance(part.get("text"), str) | |
| ] | |
| text = "".join(parts) | |
| if not text and isinstance(payload.get("output_text"), str): | |
| text = payload["output_text"] | |
| text = text.strip() | |
| if not text: | |
| raise DocumentGenerationError( | |
| "UPSTREAM_RESPONSE_INVALID", | |
| "model returned no document text", | |
| ) | |
| if len(text) > MAX_DOCUMENT_OUTPUT_CHARS: | |
| raise DocumentGenerationError( | |
| "UPSTREAM_RESPONSE_TOO_LARGE", | |
| ) | |
| return text | |
| def _filename(title: str, fmt: str) -> str: | |
| stem = ( | |
| re.sub(r"[^a-z0-9]+", "-", title.casefold()).strip("-")[:80] | |
| or "ai-learn-document" | |
| ) | |
| return f"{stem}.{FORMATS[fmt][0]}" | |
| def build_document_response( | |
| request: DocumentGenerationRequest, | |
| content: str, | |
| *, | |
| selected_model: str, | |
| ) -> dict[str, Any]: | |
| if len(content) > MAX_DOCUMENT_OUTPUT_CHARS: | |
| raise DocumentGenerationError("UPSTREAM_RESPONSE_TOO_LARGE") | |
| raw = content.encode("utf-8") | |
| return { | |
| "contract": DOCUMENT_GENERATION_RESPONSE_CONTRACT, | |
| "document_id": "doc_" + uuid.uuid4().hex, | |
| "title": request.title, | |
| "format": request.format, | |
| "filename": _filename(request.title, request.format), | |
| "mime_type": FORMATS[request.format][1], | |
| "content": content, | |
| "sha256": hashlib.sha256(raw).hexdigest(), | |
| "size": len(raw), | |
| "selected_model": selected_model, | |
| "created_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), | |
| "publication": "separate-reviewed-step", | |
| } | |