mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-12-03 01:48:05 +00:00
Apply a legacy order so we can easily see diff against what was generated
This commit is contained in:
parent
9381673405
commit
69e1176ff8
8 changed files with 29509 additions and 29034 deletions
File diff suppressed because it is too large
Load diff
10062
docs/static/deprecated-llama-stack-spec.yaml
vendored
10062
docs/static/deprecated-llama-stack-spec.yaml
vendored
File diff suppressed because it is too large
Load diff
9780
docs/static/experimental-llama-stack-spec.yaml
vendored
9780
docs/static/experimental-llama-stack-spec.yaml
vendored
File diff suppressed because it is too large
Load diff
12282
docs/static/llama-stack-spec.yaml
vendored
12282
docs/static/llama-stack-spec.yaml
vendored
File diff suppressed because it is too large
Load diff
12972
docs/static/stainless-llama-stack-spec.yaml
vendored
12972
docs/static/stainless-llama-stack-spec.yaml
vendored
File diff suppressed because it is too large
Load diff
410
scripts/openapi_generator/_legacy_order.py
Normal file
410
scripts/openapi_generator/_legacy_order.py
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This source code is licensed under the terms described in the LICENSE file in
|
||||
# the root directory of this source tree.
|
||||
|
||||
"""
|
||||
Temporary ordering helpers extracted from origin/main client-sdks/stainless/openapi.yml.
|
||||
|
||||
These lists help the new generator match the previous ordering so that diffs
|
||||
remain readable while we debug schema content regressions. Remove once stable.
|
||||
"""
|
||||
|
||||
# TODO: remove once generator output stabilizes
|
||||
LEGACY_PATH_ORDER = ['/v1/batches',
|
||||
'/v1/batches/{batch_id}',
|
||||
'/v1/batches/{batch_id}/cancel',
|
||||
'/v1/chat/completions',
|
||||
'/v1/chat/completions/{completion_id}',
|
||||
'/v1/completions',
|
||||
'/v1/conversations',
|
||||
'/v1/conversations/{conversation_id}',
|
||||
'/v1/conversations/{conversation_id}/items',
|
||||
'/v1/conversations/{conversation_id}/items/{item_id}',
|
||||
'/v1/embeddings',
|
||||
'/v1/files',
|
||||
'/v1/files/{file_id}',
|
||||
'/v1/files/{file_id}/content',
|
||||
'/v1/health',
|
||||
'/v1/inspect/routes',
|
||||
'/v1/models',
|
||||
'/v1/models/{model_id}',
|
||||
'/v1/moderations',
|
||||
'/v1/prompts',
|
||||
'/v1/prompts/{prompt_id}',
|
||||
'/v1/prompts/{prompt_id}/set-default-version',
|
||||
'/v1/prompts/{prompt_id}/versions',
|
||||
'/v1/providers',
|
||||
'/v1/providers/{provider_id}',
|
||||
'/v1/responses',
|
||||
'/v1/responses/{response_id}',
|
||||
'/v1/responses/{response_id}/input_items',
|
||||
'/v1/safety/run-shield',
|
||||
'/v1/scoring-functions',
|
||||
'/v1/scoring-functions/{scoring_fn_id}',
|
||||
'/v1/scoring/score',
|
||||
'/v1/scoring/score-batch',
|
||||
'/v1/shields',
|
||||
'/v1/shields/{identifier}',
|
||||
'/v1/tool-runtime/invoke',
|
||||
'/v1/tool-runtime/list-tools',
|
||||
'/v1/toolgroups',
|
||||
'/v1/toolgroups/{toolgroup_id}',
|
||||
'/v1/tools',
|
||||
'/v1/tools/{tool_name}',
|
||||
'/v1/vector-io/insert',
|
||||
'/v1/vector-io/query',
|
||||
'/v1/vector_stores',
|
||||
'/v1/vector_stores/{vector_store_id}',
|
||||
'/v1/vector_stores/{vector_store_id}/file_batches',
|
||||
'/v1/vector_stores/{vector_store_id}/file_batches/{batch_id}',
|
||||
'/v1/vector_stores/{vector_store_id}/file_batches/{batch_id}/cancel',
|
||||
'/v1/vector_stores/{vector_store_id}/file_batches/{batch_id}/files',
|
||||
'/v1/vector_stores/{vector_store_id}/files',
|
||||
'/v1/vector_stores/{vector_store_id}/files/{file_id}',
|
||||
'/v1/vector_stores/{vector_store_id}/files/{file_id}/content',
|
||||
'/v1/vector_stores/{vector_store_id}/search',
|
||||
'/v1/version',
|
||||
'/v1beta/datasetio/append-rows/{dataset_id}',
|
||||
'/v1beta/datasetio/iterrows/{dataset_id}',
|
||||
'/v1beta/datasets',
|
||||
'/v1beta/datasets/{dataset_id}',
|
||||
'/v1alpha/eval/benchmarks',
|
||||
'/v1alpha/eval/benchmarks/{benchmark_id}',
|
||||
'/v1alpha/eval/benchmarks/{benchmark_id}/evaluations',
|
||||
'/v1alpha/eval/benchmarks/{benchmark_id}/jobs',
|
||||
'/v1alpha/eval/benchmarks/{benchmark_id}/jobs/{job_id}',
|
||||
'/v1alpha/eval/benchmarks/{benchmark_id}/jobs/{job_id}/result',
|
||||
'/v1alpha/inference/rerank',
|
||||
'/v1alpha/post-training/job/artifacts',
|
||||
'/v1alpha/post-training/job/cancel',
|
||||
'/v1alpha/post-training/job/status',
|
||||
'/v1alpha/post-training/jobs',
|
||||
'/v1alpha/post-training/preference-optimize',
|
||||
'/v1alpha/post-training/supervised-fine-tune']
|
||||
|
||||
LEGACY_SCHEMA_ORDER = ['Error',
|
||||
'ListBatchesResponse',
|
||||
'CreateBatchRequest',
|
||||
'Batch',
|
||||
'Order',
|
||||
'ListOpenAIChatCompletionResponse',
|
||||
'OpenAIAssistantMessageParam',
|
||||
'OpenAIChatCompletionContentPartImageParam',
|
||||
'OpenAIChatCompletionContentPartParam',
|
||||
'OpenAIChatCompletionContentPartTextParam',
|
||||
'OpenAIChatCompletionToolCall',
|
||||
'OpenAIChatCompletionToolCallFunction',
|
||||
'OpenAIChatCompletionUsage',
|
||||
'OpenAIChoice',
|
||||
'OpenAIChoiceLogprobs',
|
||||
'OpenAIDeveloperMessageParam',
|
||||
'OpenAIFile',
|
||||
'OpenAIFileFile',
|
||||
'OpenAIImageURL',
|
||||
'OpenAIMessageParam',
|
||||
'OpenAISystemMessageParam',
|
||||
'OpenAITokenLogProb',
|
||||
'OpenAIToolMessageParam',
|
||||
'OpenAITopLogProb',
|
||||
'OpenAIUserMessageParam',
|
||||
'OpenAIJSONSchema',
|
||||
'OpenAIResponseFormatJSONObject',
|
||||
'OpenAIResponseFormatJSONSchema',
|
||||
'OpenAIResponseFormatParam',
|
||||
'OpenAIResponseFormatText',
|
||||
'OpenAIChatCompletionRequestWithExtraBody',
|
||||
'OpenAIChatCompletion',
|
||||
'OpenAIChatCompletionChunk',
|
||||
'OpenAIChoiceDelta',
|
||||
'OpenAIChunkChoice',
|
||||
'OpenAICompletionWithInputMessages',
|
||||
'OpenAICompletionRequestWithExtraBody',
|
||||
'OpenAICompletion',
|
||||
'OpenAICompletionChoice',
|
||||
'ConversationItem',
|
||||
'OpenAIResponseAnnotationCitation',
|
||||
'OpenAIResponseAnnotationContainerFileCitation',
|
||||
'OpenAIResponseAnnotationFileCitation',
|
||||
'OpenAIResponseAnnotationFilePath',
|
||||
'OpenAIResponseAnnotations',
|
||||
'OpenAIResponseContentPartRefusal',
|
||||
'OpenAIResponseInputFunctionToolCallOutput',
|
||||
'OpenAIResponseInputMessageContent',
|
||||
'OpenAIResponseInputMessageContentFile',
|
||||
'OpenAIResponseInputMessageContentImage',
|
||||
'OpenAIResponseInputMessageContentText',
|
||||
'OpenAIResponseMCPApprovalRequest',
|
||||
'OpenAIResponseMCPApprovalResponse',
|
||||
'OpenAIResponseMessage',
|
||||
'OpenAIResponseOutputMessageContent',
|
||||
'OpenAIResponseOutputMessageContentOutputText',
|
||||
'OpenAIResponseOutputMessageFileSearchToolCall',
|
||||
'OpenAIResponseOutputMessageFunctionToolCall',
|
||||
'OpenAIResponseOutputMessageMCPCall',
|
||||
'OpenAIResponseOutputMessageMCPListTools',
|
||||
'OpenAIResponseOutputMessageWebSearchToolCall',
|
||||
'CreateConversationRequest',
|
||||
'Conversation',
|
||||
'UpdateConversationRequest',
|
||||
'ConversationDeletedResource',
|
||||
'ConversationItemList',
|
||||
'AddItemsRequest',
|
||||
'ConversationItemDeletedResource',
|
||||
'OpenAIEmbeddingsRequestWithExtraBody',
|
||||
'OpenAIEmbeddingData',
|
||||
'OpenAIEmbeddingUsage',
|
||||
'OpenAIEmbeddingsResponse',
|
||||
'OpenAIFilePurpose',
|
||||
'ListOpenAIFileResponse',
|
||||
'OpenAIFileObject',
|
||||
'ExpiresAfter',
|
||||
'OpenAIFileDeleteResponse',
|
||||
'Response',
|
||||
'HealthInfo',
|
||||
'RouteInfo',
|
||||
'ListRoutesResponse',
|
||||
'OpenAIModel',
|
||||
'OpenAIListModelsResponse',
|
||||
'Model',
|
||||
'ModelType',
|
||||
'RunModerationRequest',
|
||||
'ModerationObject',
|
||||
'ModerationObjectResults',
|
||||
'Prompt',
|
||||
'ListPromptsResponse',
|
||||
'CreatePromptRequest',
|
||||
'UpdatePromptRequest',
|
||||
'SetDefaultVersionRequest',
|
||||
'ProviderInfo',
|
||||
'ListProvidersResponse',
|
||||
'ListOpenAIResponseObject',
|
||||
'OpenAIResponseError',
|
||||
'OpenAIResponseInput',
|
||||
'OpenAIResponseInputToolFileSearch',
|
||||
'OpenAIResponseInputToolFunction',
|
||||
'OpenAIResponseInputToolWebSearch',
|
||||
'OpenAIResponseObjectWithInput',
|
||||
'OpenAIResponseOutput',
|
||||
'OpenAIResponsePrompt',
|
||||
'OpenAIResponseText',
|
||||
'OpenAIResponseTool',
|
||||
'OpenAIResponseToolMCP',
|
||||
'OpenAIResponseUsage',
|
||||
'ResponseGuardrailSpec',
|
||||
'OpenAIResponseInputTool',
|
||||
'OpenAIResponseInputToolMCP',
|
||||
'CreateOpenaiResponseRequest',
|
||||
'OpenAIResponseObject',
|
||||
'OpenAIResponseContentPartOutputText',
|
||||
'OpenAIResponseContentPartReasoningSummary',
|
||||
'OpenAIResponseContentPartReasoningText',
|
||||
'OpenAIResponseObjectStream',
|
||||
'OpenAIResponseObjectStreamResponseCompleted',
|
||||
'OpenAIResponseObjectStreamResponseContentPartAdded',
|
||||
'OpenAIResponseObjectStreamResponseContentPartDone',
|
||||
'OpenAIResponseObjectStreamResponseCreated',
|
||||
'OpenAIResponseObjectStreamResponseFailed',
|
||||
'OpenAIResponseObjectStreamResponseFileSearchCallCompleted',
|
||||
'OpenAIResponseObjectStreamResponseFileSearchCallInProgress',
|
||||
'OpenAIResponseObjectStreamResponseFileSearchCallSearching',
|
||||
'OpenAIResponseObjectStreamResponseFunctionCallArgumentsDelta',
|
||||
'OpenAIResponseObjectStreamResponseFunctionCallArgumentsDone',
|
||||
'OpenAIResponseObjectStreamResponseInProgress',
|
||||
'OpenAIResponseObjectStreamResponseIncomplete',
|
||||
'OpenAIResponseObjectStreamResponseMcpCallArgumentsDelta',
|
||||
'OpenAIResponseObjectStreamResponseMcpCallArgumentsDone',
|
||||
'OpenAIResponseObjectStreamResponseMcpCallCompleted',
|
||||
'OpenAIResponseObjectStreamResponseMcpCallFailed',
|
||||
'OpenAIResponseObjectStreamResponseMcpCallInProgress',
|
||||
'OpenAIResponseObjectStreamResponseMcpListToolsCompleted',
|
||||
'OpenAIResponseObjectStreamResponseMcpListToolsFailed',
|
||||
'OpenAIResponseObjectStreamResponseMcpListToolsInProgress',
|
||||
'OpenAIResponseObjectStreamResponseOutputItemAdded',
|
||||
'OpenAIResponseObjectStreamResponseOutputItemDone',
|
||||
'OpenAIResponseObjectStreamResponseOutputTextAnnotationAdded',
|
||||
'OpenAIResponseObjectStreamResponseOutputTextDelta',
|
||||
'OpenAIResponseObjectStreamResponseOutputTextDone',
|
||||
'OpenAIResponseObjectStreamResponseReasoningSummaryPartAdded',
|
||||
'OpenAIResponseObjectStreamResponseReasoningSummaryPartDone',
|
||||
'OpenAIResponseObjectStreamResponseReasoningSummaryTextDelta',
|
||||
'OpenAIResponseObjectStreamResponseReasoningSummaryTextDone',
|
||||
'OpenAIResponseObjectStreamResponseReasoningTextDelta',
|
||||
'OpenAIResponseObjectStreamResponseReasoningTextDone',
|
||||
'OpenAIResponseObjectStreamResponseRefusalDelta',
|
||||
'OpenAIResponseObjectStreamResponseRefusalDone',
|
||||
'OpenAIResponseObjectStreamResponseWebSearchCallCompleted',
|
||||
'OpenAIResponseObjectStreamResponseWebSearchCallInProgress',
|
||||
'OpenAIResponseObjectStreamResponseWebSearchCallSearching',
|
||||
'OpenAIDeleteResponseObject',
|
||||
'ListOpenAIResponseInputItem',
|
||||
'RunShieldRequest',
|
||||
'RunShieldResponse',
|
||||
'SafetyViolation',
|
||||
'ViolationLevel',
|
||||
'AggregationFunctionType',
|
||||
'ArrayType',
|
||||
'BasicScoringFnParams',
|
||||
'BooleanType',
|
||||
'ChatCompletionInputType',
|
||||
'CompletionInputType',
|
||||
'JsonType',
|
||||
'LLMAsJudgeScoringFnParams',
|
||||
'NumberType',
|
||||
'ObjectType',
|
||||
'RegexParserScoringFnParams',
|
||||
'ScoringFn',
|
||||
'ScoringFnParams',
|
||||
'ScoringFnParamsType',
|
||||
'StringType',
|
||||
'UnionType',
|
||||
'ListScoringFunctionsResponse',
|
||||
'ScoreRequest',
|
||||
'ScoreResponse',
|
||||
'ScoringResult',
|
||||
'ScoreBatchRequest',
|
||||
'ScoreBatchResponse',
|
||||
'Shield',
|
||||
'ListShieldsResponse',
|
||||
'InvokeToolRequest',
|
||||
'ImageContentItem',
|
||||
'InterleavedContent',
|
||||
'InterleavedContentItem',
|
||||
'TextContentItem',
|
||||
'ToolInvocationResult',
|
||||
'URL',
|
||||
'ToolDef',
|
||||
'ListToolDefsResponse',
|
||||
'ToolGroup',
|
||||
'ListToolGroupsResponse',
|
||||
'Chunk',
|
||||
'ChunkMetadata',
|
||||
'InsertChunksRequest',
|
||||
'QueryChunksRequest',
|
||||
'QueryChunksResponse',
|
||||
'VectorStoreFileCounts',
|
||||
'VectorStoreListResponse',
|
||||
'VectorStoreObject',
|
||||
'VectorStoreChunkingStrategy',
|
||||
'VectorStoreChunkingStrategyAuto',
|
||||
'VectorStoreChunkingStrategyStatic',
|
||||
'VectorStoreChunkingStrategyStaticConfig',
|
||||
'OpenAICreateVectorStoreRequestWithExtraBody',
|
||||
'OpenaiUpdateVectorStoreRequest',
|
||||
'VectorStoreDeleteResponse',
|
||||
'OpenAICreateVectorStoreFileBatchRequestWithExtraBody',
|
||||
'VectorStoreFileBatchObject',
|
||||
'VectorStoreFileStatus',
|
||||
'VectorStoreFileLastError',
|
||||
'VectorStoreFileObject',
|
||||
'VectorStoreFilesListInBatchResponse',
|
||||
'VectorStoreListFilesResponse',
|
||||
'OpenaiAttachFileToVectorStoreRequest',
|
||||
'OpenaiUpdateVectorStoreFileRequest',
|
||||
'VectorStoreFileDeleteResponse',
|
||||
'bool',
|
||||
'VectorStoreContent',
|
||||
'VectorStoreFileContentResponse',
|
||||
'OpenaiSearchVectorStoreRequest',
|
||||
'VectorStoreSearchResponse',
|
||||
'VectorStoreSearchResponsePage',
|
||||
'VersionInfo',
|
||||
'AppendRowsRequest',
|
||||
'PaginatedResponse',
|
||||
'Dataset',
|
||||
'RowsDataSource',
|
||||
'URIDataSource',
|
||||
'ListDatasetsResponse',
|
||||
'Benchmark',
|
||||
'ListBenchmarksResponse',
|
||||
'BenchmarkConfig',
|
||||
'GreedySamplingStrategy',
|
||||
'ModelCandidate',
|
||||
'SamplingParams',
|
||||
'SystemMessage',
|
||||
'TopKSamplingStrategy',
|
||||
'TopPSamplingStrategy',
|
||||
'EvaluateRowsRequest',
|
||||
'EvaluateResponse',
|
||||
'RunEvalRequest',
|
||||
'Job',
|
||||
'RerankRequest',
|
||||
'RerankData',
|
||||
'RerankResponse',
|
||||
'Checkpoint',
|
||||
'PostTrainingJobArtifactsResponse',
|
||||
'PostTrainingMetric',
|
||||
'CancelTrainingJobRequest',
|
||||
'PostTrainingJobStatusResponse',
|
||||
'ListPostTrainingJobsResponse',
|
||||
'DPOAlignmentConfig',
|
||||
'DPOLossType',
|
||||
'DataConfig',
|
||||
'DatasetFormat',
|
||||
'EfficiencyConfig',
|
||||
'OptimizerConfig',
|
||||
'OptimizerType',
|
||||
'TrainingConfig',
|
||||
'PreferenceOptimizeRequest',
|
||||
'PostTrainingJob',
|
||||
'AlgorithmConfig',
|
||||
'LoraFinetuningConfig',
|
||||
'QATFinetuningConfig',
|
||||
'SupervisedFineTuneRequest',
|
||||
'RegisterModelRequest',
|
||||
'ParamType',
|
||||
'RegisterScoringFunctionRequest',
|
||||
'RegisterShieldRequest',
|
||||
'RegisterToolGroupRequest',
|
||||
'DataSource',
|
||||
'RegisterDatasetRequest',
|
||||
'RegisterBenchmarkRequest']
|
||||
|
||||
LEGACY_RESPONSE_ORDER = ['BadRequest400', 'TooManyRequests429', 'InternalServerError500', 'DefaultError']
|
||||
|
||||
LEGACY_TAG_ORDER = ['Agents',
|
||||
'Batches',
|
||||
'Benchmarks',
|
||||
'Conversations',
|
||||
'DatasetIO',
|
||||
'Datasets',
|
||||
'Eval',
|
||||
'Files',
|
||||
'Inference',
|
||||
'Inspect',
|
||||
'Models',
|
||||
'PostTraining (Coming Soon)',
|
||||
'Prompts',
|
||||
'Providers',
|
||||
'Safety',
|
||||
'Scoring',
|
||||
'ScoringFunctions',
|
||||
'Shields',
|
||||
'ToolGroups',
|
||||
'ToolRuntime',
|
||||
'VectorIO']
|
||||
|
||||
LEGACY_TAG_GROUPS = [{'name': 'Operations',
|
||||
'tags': ['Agents',
|
||||
'Batches',
|
||||
'Benchmarks',
|
||||
'Conversations',
|
||||
'DatasetIO',
|
||||
'Datasets',
|
||||
'Eval',
|
||||
'Files',
|
||||
'Inference',
|
||||
'Inspect',
|
||||
'Models',
|
||||
'PostTraining (Coming Soon)',
|
||||
'Prompts',
|
||||
'Providers',
|
||||
'Safety',
|
||||
'Scoring',
|
||||
'ScoringFunctions',
|
||||
'Shields',
|
||||
'ToolGroups',
|
||||
'ToolRuntime',
|
||||
'VectorIO']}]
|
||||
|
|
@ -141,6 +141,7 @@ def generate_openapi_spec(output_dir: str) -> dict[str, Any]:
|
|||
|
||||
for schema, _ in schemas_to_validate:
|
||||
schema_transforms._fix_schema_issues(schema)
|
||||
schema_transforms._apply_legacy_sorting(schema)
|
||||
|
||||
print("\n🔍 Validating generated schemas...")
|
||||
failed_schemas = [
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ Schema transformations and fixes for OpenAPI generation.
|
|||
"""
|
||||
|
||||
import copy
|
||||
from collections import OrderedDict
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
|
@ -17,6 +18,13 @@ from openapi_spec_validator import validate_spec
|
|||
from openapi_spec_validator.exceptions import OpenAPISpecValidatorError
|
||||
|
||||
from . import endpoints, schema_collection
|
||||
from ._legacy_order import (
|
||||
LEGACY_PATH_ORDER,
|
||||
LEGACY_RESPONSE_ORDER,
|
||||
LEGACY_SCHEMA_ORDER,
|
||||
LEGACY_TAG_GROUPS,
|
||||
LEGACY_TAG_ORDER,
|
||||
)
|
||||
from .state import _extra_body_fields
|
||||
|
||||
|
||||
|
|
@ -821,6 +829,62 @@ def _write_yaml_file(file_path: Path, schema: dict[str, Any]) -> None:
|
|||
f.writelines(cleaned_lines)
|
||||
|
||||
|
||||
def _apply_legacy_sorting(openapi_schema: dict[str, Any]) -> dict[str, Any]:
|
||||
"""
|
||||
Temporarily match the legacy ordering from origin/main so diffs are easier to read.
|
||||
Remove this once the generator output stabilizes and we no longer need legacy diffs.
|
||||
"""
|
||||
|
||||
def order_mapping(data: dict[str, Any], priority: list[str]) -> OrderedDict[str, Any]:
|
||||
ordered: OrderedDict[str, Any] = OrderedDict()
|
||||
for key in priority:
|
||||
if key in data:
|
||||
ordered[key] = data[key]
|
||||
for key, value in data.items():
|
||||
if key not in ordered:
|
||||
ordered[key] = value
|
||||
return ordered
|
||||
|
||||
paths = openapi_schema.get("paths")
|
||||
if isinstance(paths, dict):
|
||||
openapi_schema["paths"] = order_mapping(paths, LEGACY_PATH_ORDER)
|
||||
|
||||
components = openapi_schema.setdefault("components", {})
|
||||
schemas = components.get("schemas")
|
||||
if isinstance(schemas, dict):
|
||||
components["schemas"] = order_mapping(schemas, LEGACY_SCHEMA_ORDER)
|
||||
responses = components.get("responses")
|
||||
if isinstance(responses, dict):
|
||||
components["responses"] = order_mapping(responses, LEGACY_RESPONSE_ORDER)
|
||||
|
||||
tags = openapi_schema.get("tags")
|
||||
if isinstance(tags, list):
|
||||
tag_priority = {name: idx for idx, name in enumerate(LEGACY_TAG_ORDER)}
|
||||
|
||||
def tag_sort(tag_obj: dict[str, Any]) -> tuple[int, int | str]:
|
||||
name = tag_obj.get("name", "")
|
||||
if name in tag_priority:
|
||||
return (0, tag_priority[name])
|
||||
return (1, name)
|
||||
|
||||
openapi_schema["tags"] = sorted(tags, key=tag_sort)
|
||||
|
||||
tag_groups = openapi_schema.get("x-tagGroups")
|
||||
if isinstance(tag_groups, list) and LEGACY_TAG_GROUPS:
|
||||
legacy_tags = LEGACY_TAG_GROUPS[0].get("tags", [])
|
||||
tag_priority = {name: idx for idx, name in enumerate(legacy_tags)}
|
||||
for group in tag_groups:
|
||||
group_tags = group.get("tags")
|
||||
if isinstance(group_tags, list):
|
||||
group["tags"] = sorted(
|
||||
group_tags,
|
||||
key=lambda name: (0, tag_priority[name]) if name in tag_priority else (1, name),
|
||||
)
|
||||
openapi_schema["x-tagGroups"] = tag_groups
|
||||
|
||||
return openapi_schema
|
||||
|
||||
|
||||
def _fix_schema_issues(openapi_schema: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Fix common schema issues: exclusiveMinimum, null defaults, and add titles to unions."""
|
||||
# Convert anyOf with const values to enums across the entire schema
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue