#!/usr/bin/env python3 """Generate the provider schema field coverage matrix. The input inventory is docs/api/provider-interface-definitions.md. Existing coverage rows are reused so audited status/notes survive regeneration. Newly introduced provider fields get conservative same-format/native and cross-format fail-closed defaults until a human audits whether they deserve an explicit mapping. """ from __future__ import annotations import argparse import dataclasses from collections import Counter, defaultdict from pathlib import Path from typing import Iterable ROOT = Path(__file__).resolve().parents[2] DEFAULT_DEFINITIONS = ROOT / "docs/api/provider-interface-definitions.md" DEFAULT_MATRIX = ROOT / "docs/api/format-field-coverage-matrix.md" @dataclasses.dataclass(frozen=True) class SourceField: provider: str schema: str field: str required: str field_type: str @dataclasses.dataclass(frozen=True) class CoverageStatus: surface: str same_format_runtime: str canonical_roundtrip: str cross_format: str notes: str OPENAI_CHAT_MAPPED = { "model", "messages", "max_tokens", "max_completion_tokens", "temperature", "top_p", "top_logprobs", "tools", "tool_choice", "parallel_tool_calls", "metadata", "response_format", "reasoning_effort", "verbosity", "store", "service_tier", "safety_identifier", "prompt_cache_key", "prompt_cache_retention", "stream", } OPENAI_CHAT_BLOCKED = { "n", "stop", "presence_penalty", "frequency_penalty", "seed", "logprobs", "stream_options", "user", "function_call", "functions", "logit_bias", "modalities", "prediction", "audio", "web_search_options", } OPENAI_RESPONSES_MAPPED = { "model", "input", "instructions", "max_output_tokens", "temperature", "top_p", "top_logprobs", "metadata", "parallel_tool_calls", "text", "tools", "tool_choice", "reasoning", "store", "service_tier", "safety_identifier", "prompt_cache_key", "prompt_cache_retention", } OPENAI_RESPONSES_BLOCKED = { "include", "previous_response_id", "truncation", "prompt", "conversation", "background", "max_tool_calls", "user", "context_management", "stream", "stream_options", } CLAUDE_MAPPED_FIELDS = { "id", "type", "role", "text", "content", "source", "name", "description", "input", "input_schema", "messages", "model", "max_tokens", "system", "temperature", "top_p", "top_k", "stop_sequences", "tool_choice", "tools", "metadata", "thinking", "output_config", "usage", "stop_reason", "stop_sequence", } CLAUDE_PROVIDER_ONLY_FIELDS = { "cache_control", "container", "inference_geo", "service_tier", "allowed_callers", "allowed_domains", "blocked_domains", "defer_loading", "max_uses", "strict", "user_location", "citations", "context", "title", "file_id", "document_index", "document_title", "cited_text", "caller", } def split_markdown_row(line: str) -> list[str]: cells: list[str] = [] current: list[str] = [] escaped = False for char in line: if char == "|" and not escaped: cells.append("".join(current).strip()) current.clear() else: current.append(char) escaped = char == "\\" and not escaped if escaped and char != "\\": escaped = False cells.append("".join(current).strip()) return cells def strip_markdown_code(value: str) -> str: value = value.strip() if value.startswith("`") and value.endswith("`"): value = value[1:-1] return value.replace("\\|", "|") def escape_markdown_cell(value: str) -> str: return value.replace("|", "\\|") def parse_schema_heading(line: str) -> str | None: if not line.startswith("### `"): return None rest = line[len("### `") :] schema, _, _ = rest.partition("`") return schema or None def parse_provider_definition_fields(definitions: str) -> list[SourceField]: provider: str | None = None schema: str | None = None fields: list[SourceField] = [] for line in definitions.splitlines(): if line.startswith("## "): if "OpenAI Schema" in line: provider = "OpenAI" elif "Claude / Anthropic TypeScript" in line: provider = "Claude" elif "Gemini Schema" in line: provider = "Gemini" else: provider = None schema = None continue if provider is None: continue if heading := parse_schema_heading(line): schema = heading continue if schema is None or not line.startswith("| `"): continue cells = split_markdown_row(line) if len(cells) < 4 or cells[2] not in {"是", "否"}: continue fields.append( SourceField( provider=provider, schema=schema, field=strip_markdown_code(cells[1]), required=cells[2], field_type=strip_markdown_code(cells[3]), ) ) return fields def parse_existing_coverage( matrix: str, ) -> tuple[dict[tuple[str, str, str], CoverageStatus], dict[tuple[str, str], list[CoverageStatus]]]: existing: dict[tuple[str, str, str], CoverageStatus] = {} profiles: dict[tuple[str, str], list[CoverageStatus]] = defaultdict(list) for line in matrix.splitlines(): if not line.startswith("| "): continue cells = split_markdown_row(line) if len(cells) < 11 or cells[1] not in {"OpenAI", "Claude", "Gemini"}: continue status = CoverageStatus( surface=cells[6], same_format_runtime=cells[7], canonical_roundtrip=cells[8], cross_format=cells[9], notes=cells[10], ) provider = cells[1] schema = strip_markdown_code(cells[2]) field = strip_markdown_code(cells[3]) existing[(provider, schema, field)] = status profiles[(provider, schema)].append(status) return existing, profiles def most_common(values: Iterable[str]) -> str | None: values = list(values) if not values: return None return Counter(values).most_common(1)[0][0] def openai_surface(schema: str) -> str: if "CreateChatCompletion" in schema or "ChatCompletion" in schema: return "openai:chat standard" if "CreateEmbedding" in schema or "Embedding" in schema: return "openai:embedding" if any(token in schema for token in ("CreateImage", "EditImage", "Image", "Images")): return "openai:image native-only" if any(token in schema for token in ("Compact", "Compaction")): return "openai:responses:compact native-only" if any( token in schema for token in ( "Response", "Input", "Output", "Tool", "Reasoning", "WebSearch", "FileSearch", "Computer", "MCP", "CodeInterpreter", "Function", "Custom", "EasyInput", "Prompt", "Conversation", "Annotation", "Citation", "LogProb", "TopLogProb", "Metadata", "ServiceTier", "Verbosity", "TextResponse", "ResponseFormat", "Include", "Modalities", "ParallelToolCalls", "StopConfiguration", ) ): return "openai:responses standard" return "openai auxiliary / not-in-conversion-surface" def openai_default_status(field: SourceField, profile: list[CoverageStatus]) -> CoverageStatus: surface = most_common(status.surface for status in profile) or openai_surface(field.schema) if "not-in-conversion-surface" in surface or "native-only" in surface: return CoverageStatus( surface=surface, same_format_runtime="native", canonical_roundtrip="not-in-conversion-surface", cross_format="not-in-conversion-surface", notes="not part of current canonical cross-format conversion; same-format runtime path remains provider-native when routed directly", ) if field.schema == "CreateChatCompletionRequest": if field.field in OPENAI_CHAT_MAPPED: return CoverageStatus( surface=surface, same_format_runtime="native", canonical_roundtrip="mapped", cross_format="mapped", notes="Chat request field maps provider-specifically; target-incompatible cases fail closed", ) if field.field in OPENAI_CHAT_BLOCKED: return CoverageStatus( surface=surface, same_format_runtime="native", canonical_roundtrip="extension-preserved", cross_format="lossy-blocked", notes="Chat-only or provider-specific field has no audited lossless target equivalent", ) if field.schema == "CreateResponse": if field.field in OPENAI_RESPONSES_MAPPED: return CoverageStatus( surface=surface, same_format_runtime="native", canonical_roundtrip="mapped", cross_format="mapped", notes="Responses request field maps provider-specifically; target-incompatible cases fail closed", ) if field.field in OPENAI_RESPONSES_BLOCKED: return CoverageStatus( surface=surface, same_format_runtime="native", canonical_roundtrip="extension-preserved", cross_format="lossy-blocked", notes="Responses-only field has no audited lossless Chat/Claude/Gemini target equivalent", ) if profile: cross_format = most_common(status.cross_format for status in profile) or "lossy-blocked" return CoverageStatus( surface=surface, same_format_runtime="native", canonical_roundtrip=most_common(status.canonical_roundtrip for status in profile) or "extension-preserved", cross_format=cross_format, notes=next( (status.notes for status in profile if status.cross_format == cross_format), "schema-level handling inherited from audited sibling fields", ), ) return CoverageStatus( surface=surface, same_format_runtime="native", canonical_roundtrip="extension-preserved", cross_format="lossy-blocked", notes="OpenAI documented field is preserved same-format; cross-format requires explicit target mapping or fails closed", ) def claude_default_status(field: SourceField) -> CoverageStatus: if "CountTokens" in field.schema: return CoverageStatus( surface="claude:messages/count_tokens native-only", same_format_runtime="native", canonical_roundtrip="not-in-conversion-surface", cross_format="not-in-conversion-surface", notes="count_tokens schemas are provider-native and outside canonical generation conversion", ) if field.field in CLAUDE_MAPPED_FIELDS: return CoverageStatus( surface="claude:messages standard", same_format_runtime="native", canonical_roundtrip="mapped", cross_format="mapped/lossy-blocked", notes="Claude field maps where canonical and target support an equivalent; otherwise conversion fails closed", ) if ( field.field in CLAUDE_PROVIDER_ONLY_FIELDS or field.field.endswith("_tokens_details") or "cache" in field.field ): return CoverageStatus( surface="claude:messages standard", same_format_runtime="native", canonical_roundtrip="extension-preserved", cross_format="lossy-blocked", notes="Claude provider-specific field is preserved same-format and blocked cross-format without an audited target equivalent", ) return CoverageStatus( surface="claude:messages standard", same_format_runtime="native", canonical_roundtrip="extension-preserved", cross_format="lossy-blocked", notes="Claude nested/provider-specific field is same-format preserved; cross-format requires explicit mapping or fails closed", ) def gemini_default_status(field: SourceField, profile: list[CoverageStatus]) -> CoverageStatus: if profile: cross_format = most_common(status.cross_format for status in profile) or "lossy-blocked" return CoverageStatus( surface=most_common(status.surface for status in profile) or "gemini:generate_content standard", same_format_runtime="native", canonical_roundtrip=most_common(status.canonical_roundtrip for status in profile) or "extension-preserved", cross_format=cross_format, notes=next( (status.notes for status in profile if status.cross_format == cross_format), "Gemini field follows schema-level handling", ), ) return CoverageStatus( surface="gemini:generate_content standard", same_format_runtime="native", canonical_roundtrip="extension-preserved", cross_format="lossy-blocked", notes="Gemini documented field is preserved same-format; cross-format requires explicit mapping or fails closed", ) def default_status(field: SourceField, profile: list[CoverageStatus]) -> CoverageStatus: if field.provider == "OpenAI": return openai_default_status(field, profile) if field.provider == "Claude": return claude_default_status(field) if field.provider == "Gemini": return gemini_default_status(field, profile) raise ValueError(f"unsupported provider: {field.provider}") def render_matrix( fields: list[SourceField], existing: dict[tuple[str, str, str], CoverageStatus], profiles: dict[tuple[str, str], list[CoverageStatus]], ) -> str: rows: list[str] = [ "# Format Field Coverage Matrix", "", "Last generated: 2026-06-03", "", "This file is generated from the schema inventory in `docs/api/provider-interface-definitions.md` and gives every documented schema field an explicit handling status. “处理到” here means the field is either mapped, preserved in same-format paths, rejected with a structured fail-closed error, or explicitly outside the current conversion surface. It does not mean every field can be cross-format converted.", "", "Provider schema updates do not require immediate conversion-code changes for runtime safety. Same-format runtime paths bypass canonical conversion, and same-format canonical roundtrip preserves provider extension fields. Cross-format conversion only enables fields with an audited semantic mapping; newly discovered or unknown provider fields default to structured fail-closed behavior until mapped.", "", "Regenerate with: `python3 docs/api/generate_format_field_coverage.py`.", "", "Statuses used in this matrix: `native`, `mapped`, `mapped/lossy-blocked`, `extension-preserved`, `unaudited`, `unsupported`, `invalid-enum`, `lossy-blocked`, `not-in-conversion-surface`.", "", "| Provider | Schema | Field | Required | Type | Surface | Same-Format Runtime | Canonical Roundtrip | Cross-Format | Notes |", "| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |", ] for field in fields: status = existing.get( (field.provider, field.schema, field.field), default_status(field, profiles[(field.provider, field.schema)]), ) rows.append( "| " + " | ".join( [ field.provider, f"`{escape_markdown_cell(field.schema)}`", f"`{escape_markdown_cell(field.field)}`", field.required, f"`{escape_markdown_cell(field.field_type)}`", escape_markdown_cell(status.surface), escape_markdown_cell(status.same_format_runtime), escape_markdown_cell(status.canonical_roundtrip), escape_markdown_cell(status.cross_format), escape_markdown_cell(status.notes), ] ) + " |" ) rows.extend(["", f"Total covered schema fields: {len(fields)}."]) return "\n".join(rows) + "\n" def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--definitions", type=Path, default=DEFAULT_DEFINITIONS) parser.add_argument("--matrix", type=Path, default=DEFAULT_MATRIX) parser.add_argument("--check", action="store_true") args = parser.parse_args() definitions = args.definitions.read_text() current_matrix = args.matrix.read_text() if args.matrix.exists() else "" fields = parse_provider_definition_fields(definitions) existing, profiles = parse_existing_coverage(current_matrix) next_matrix = render_matrix(fields, existing, profiles) if args.check: if current_matrix != next_matrix: print( f"{args.matrix} is not up to date; run " "`python3 docs/api/generate_format_field_coverage.py`", ) return 1 return 0 args.matrix.write_text(next_matrix) print(f"wrote {len(fields)} field coverage rows to {args.matrix}") return 0 if __name__ == "__main__": raise SystemExit(main())