even more cleanup, the deltas should be much smaller now

This commit is contained in:
Ashwin Bharambe 2025-11-14 14:18:15 -08:00
parent 5293b4e5e9
commit 9deb0beb86
14 changed files with 5038 additions and 17435 deletions

View file

@ -12,462 +12,492 @@ These lists help the new generator match the previous ordering so that diffs
remain readable while we debug schema content regressions. Remove once stable.
"""
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_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_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_RESPONSE_ORDER = ["BadRequest400", "TooManyRequests429", "InternalServerError500", "DefaultError"]
LEGACY_TAGS = [{'description': 'APIs for creating and interacting with agentic systems.',
'name': 'Agents',
'x-displayName': 'Agents'},
{'description': 'The API is designed to allow use of openai client libraries for seamless integration.\n'
'\n'
'This API provides the following extensions:\n'
' - idempotent batch creation\n'
'\n'
'Note: This API is currently under active development and may undergo changes.',
'name': 'Batches',
'x-displayName': 'The Batches API enables efficient processing of multiple requests in a single operation, '
'particularly useful for processing large datasets, batch evaluation workflows, and cost-effective '
'inference at scale.'},
{'description': '', 'name': 'Benchmarks'},
{'description': 'Protocol for conversation management operations.',
'name': 'Conversations',
'x-displayName': 'Conversations'},
{'description': '', 'name': 'DatasetIO'},
{'description': '', 'name': 'Datasets'},
{'description': 'Llama Stack Evaluation API for running evaluations on model and agent candidates.',
'name': 'Eval',
'x-displayName': 'Evaluations'},
{'description': 'This API is used to upload documents that can be used with other Llama Stack APIs.',
'name': 'Files',
'x-displayName': 'Files'},
{'description': 'Llama Stack Inference API for generating completions, chat completions, and embeddings.\n'
'\n'
'This API provides the raw interface to the underlying models. Three kinds of models are supported:\n'
'- LLM models: these models generate "raw" and "chat" (conversational) completions.\n'
'- Embedding models: these models generate embeddings to be used for semantic search.\n'
'- Rerank models: these models reorder the documents based on their relevance to a query.',
'name': 'Inference',
'x-displayName': 'Inference'},
{'description': 'APIs for inspecting the Llama Stack service, including health status, available API routes with '
'methods and implementing providers.',
'name': 'Inspect',
'x-displayName': 'Inspect'},
{'description': '', 'name': 'Models'},
{'description': '', 'name': 'PostTraining (Coming Soon)'},
{'description': 'Protocol for prompt management operations.', 'name': 'Prompts', 'x-displayName': 'Prompts'},
{'description': 'Providers API for inspecting, listing, and modifying providers and their configurations.',
'name': 'Providers',
'x-displayName': 'Providers'},
{'description': 'OpenAI-compatible Moderations API.', 'name': 'Safety', 'x-displayName': 'Safety'},
{'description': '', 'name': 'Scoring'},
{'description': '', 'name': 'ScoringFunctions'},
{'description': '', 'name': 'Shields'},
{'description': '', 'name': 'ToolGroups'},
{'description': '', 'name': 'ToolRuntime'},
{'description': '', 'name': 'VectorIO'}]
LEGACY_TAGS = [
{
"description": "APIs for creating and interacting with agentic systems.",
"name": "Agents",
"x-displayName": "Agents",
},
{
"description": "The API is designed to allow use of openai client libraries for seamless integration.\n"
"\n"
"This API provides the following extensions:\n"
" - idempotent batch creation\n"
"\n"
"Note: This API is currently under active development and may undergo changes.",
"name": "Batches",
"x-displayName": "The Batches API enables efficient processing of multiple requests in a single operation, "
"particularly useful for processing large datasets, batch evaluation workflows, and cost-effective "
"inference at scale.",
},
{"description": "", "name": "Benchmarks"},
{
"description": "Protocol for conversation management operations.",
"name": "Conversations",
"x-displayName": "Conversations",
},
{"description": "", "name": "DatasetIO"},
{"description": "", "name": "Datasets"},
{
"description": "Llama Stack Evaluation API for running evaluations on model and agent candidates.",
"name": "Eval",
"x-displayName": "Evaluations",
},
{
"description": "This API is used to upload documents that can be used with other Llama Stack APIs.",
"name": "Files",
"x-displayName": "Files",
},
{
"description": "Llama Stack Inference API for generating completions, chat completions, and embeddings.\n"
"\n"
"This API provides the raw interface to the underlying models. Three kinds of models are supported:\n"
'- LLM models: these models generate "raw" and "chat" (conversational) completions.\n'
"- Embedding models: these models generate embeddings to be used for semantic search.\n"
"- Rerank models: these models reorder the documents based on their relevance to a query.",
"name": "Inference",
"x-displayName": "Inference",
},
{
"description": "APIs for inspecting the Llama Stack service, including health status, available API routes with "
"methods and implementing providers.",
"name": "Inspect",
"x-displayName": "Inspect",
},
{"description": "", "name": "Models"},
{"description": "", "name": "PostTraining (Coming Soon)"},
{"description": "Protocol for prompt management operations.", "name": "Prompts", "x-displayName": "Prompts"},
{
"description": "Providers API for inspecting, listing, and modifying providers and their configurations.",
"name": "Providers",
"x-displayName": "Providers",
},
{"description": "OpenAI-compatible Moderations API.", "name": "Safety", "x-displayName": "Safety"},
{"description": "", "name": "Scoring"},
{"description": "", "name": "ScoringFunctions"},
{"description": "", "name": "Shields"},
{"description": "", "name": "ToolGroups"},
{"description": "", "name": "ToolRuntime"},
{"description": "", "name": "VectorIO"},
]
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_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']}]
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",
],
}
]
LEGACY_SECURITY = [{'Default': []}]
LEGACY_SECURITY = [{"Default": []}]
LEGACY_OPERATION_KEYS = [
'responses',
'tags',
'summary',
'description',
'operationId',
'parameters',
'requestBody',
'deprecated',
"responses",
"tags",
"summary",
"description",
"operationId",
"parameters",
"requestBody",
"deprecated",
]

View file

@ -19,6 +19,7 @@ from pydantic import Field, create_model
from llama_stack.log import get_logger
from llama_stack_api import Api
from llama_stack_api.schema_utils import get_registered_schema_info
from . import app as app_module
from .state import _extra_body_fields, register_dynamic_model
@ -31,23 +32,16 @@ def _to_pascal_case(segment: str) -> str:
return "".join(token.capitalize() for token in tokens if token)
def _compose_request_model_name(webmethod, http_method: str, variant: str | None = None) -> str:
segments = []
level = (webmethod.level or "").lower()
if level and level != "v1":
segments.append(_to_pascal_case(str(webmethod.level)))
for part in filter(None, webmethod.route.split("/")):
lower_part = part.lower()
if lower_part in {"v1", "v1alpha", "v1beta"}:
continue
if part.startswith("{"):
param = part[1:].split(":", 1)[0]
segments.append(f"By{_to_pascal_case(param)}")
else:
segments.append(_to_pascal_case(part))
if not segments:
segments.append("Root")
base_name = "".join(segments) + http_method.title() + "Request"
def _compose_request_model_name(api: Api, method_name: str, variant: str | None = None) -> str:
"""Generate a deterministic model name from the protocol method."""
def _to_pascal_from_snake(value: str) -> str:
return "".join(segment.capitalize() for segment in value.split("_") if segment)
base_name = _to_pascal_from_snake(method_name)
if not base_name:
base_name = _to_pascal_case(api.value)
base_name = f"{base_name}Request"
if variant:
base_name = f"{base_name}{variant}"
return base_name
@ -130,6 +124,7 @@ def _build_field_definitions(query_parameters: list[tuple[str, type, Any]], use_
def _create_dynamic_request_model(
api: Api,
webmethod,
method_name: str,
http_method: str,
query_parameters: list[tuple[str, type, Any]],
use_any: bool = False,
@ -140,7 +135,7 @@ def _create_dynamic_request_model(
field_definitions = _build_field_definitions(query_parameters, use_any)
if not field_definitions:
return None
model_name = _compose_request_model_name(webmethod, http_method, variant_suffix)
model_name = _compose_request_model_name(api, method_name, variant_suffix or None)
request_model = create_model(model_name, **field_definitions)
return register_dynamic_model(model_name, request_model)
except Exception:
@ -261,9 +256,7 @@ def _extract_response_models_from_union(union_type: Any) -> tuple[type | None, t
streaming_model = inner_type
else:
# Might be a registered schema - check if it's registered
from llama_stack_api.schema_utils import _registered_schemas
if inner_type in _registered_schemas:
if get_registered_schema_info(inner_type):
# We'll need to look this up later, but for now store the type
streaming_model = inner_type
elif hasattr(arg, "model_json_schema"):
@ -427,17 +420,28 @@ def _find_models_for_endpoint(
try:
from fastapi import Response as FastAPIResponse
except ImportError:
FastAPIResponse = None
fastapi_response_cls = None
else:
fastapi_response_cls = FastAPIResponse
try:
from starlette.responses import Response as StarletteResponse
except ImportError:
StarletteResponse = None
starlette_response_cls = None
else:
starlette_response_cls = StarletteResponse
response_types = tuple(t for t in (FastAPIResponse, StarletteResponse) if t is not None)
response_types = tuple(t for t in (fastapi_response_cls, starlette_response_cls) if t is not None)
if response_types and any(return_annotation is t for t in response_types):
response_schema_name = "Response"
return request_model, response_model, query_parameters, file_form_params, streaming_response_model, response_schema_name
return (
request_model,
response_model,
query_parameters,
file_form_params,
streaming_response_model,
response_schema_name,
)
except Exception as exc:
logger.warning(
@ -465,9 +469,7 @@ def _create_fastapi_endpoint(app: FastAPI, route, webmethod, api: Api):
file_form_params,
streaming_response_model,
response_schema_name,
) = (
_find_models_for_endpoint(webmethod, api, name, is_post_put)
)
) = _find_models_for_endpoint(webmethod, api, name, is_post_put)
operation_description = _extract_operation_description_from_docstring(api, name)
response_description = _extract_response_description_from_docstring(webmethod, response_model, api, name)
@ -479,6 +481,17 @@ def _create_fastapi_endpoint(app: FastAPI, route, webmethod, api: Api):
key = (fastapi_path, method.upper())
_extra_body_fields[key] = extra_body_params
if is_post_put and not request_model and not file_form_params and query_parameters:
request_model = _create_dynamic_request_model(
api, webmethod, name, primary_method, query_parameters, use_any=False
)
if not request_model:
request_model = _create_dynamic_request_model(
api, webmethod, name, primary_method, query_parameters, use_any=True, variant_suffix="Loose"
)
if request_model:
query_parameters = []
if file_form_params and is_post_put:
signature_params = list(file_form_params)
param_annotations = {param.name: param.annotation for param in file_form_params}
@ -503,12 +516,16 @@ def _create_fastapi_endpoint(app: FastAPI, route, webmethod, api: Api):
endpoint_func = file_form_endpoint
elif request_model and response_model:
endpoint_func = _create_endpoint_with_request_model(request_model, response_model, operation_description)
elif request_model:
endpoint_func = _create_endpoint_with_request_model(request_model, None, operation_description)
elif response_model and query_parameters:
if is_post_put:
request_model = _create_dynamic_request_model(api, webmethod, primary_method, query_parameters, use_any=False)
request_model = _create_dynamic_request_model(
api, webmethod, name, primary_method, query_parameters, use_any=False
)
if not request_model:
request_model = _create_dynamic_request_model(
api, webmethod, primary_method, query_parameters, use_any=True, variant_suffix="Loose"
api, webmethod, name, primary_method, query_parameters, use_any=True, variant_suffix="Loose"
)
if request_model:
@ -600,10 +617,8 @@ def _create_fastapi_endpoint(app: FastAPI, route, webmethod, api: Api):
streaming_schema_name = None
# Check if it's a registered schema first (before checking __name__)
# because registered schemas might be Annotated types
from llama_stack_api.schema_utils import _registered_schemas
if streaming_response_model in _registered_schemas:
streaming_schema_name = _registered_schemas[streaming_response_model]["name"]
if schema_info := get_registered_schema_info(streaming_response_model):
streaming_schema_name = schema_info.name
elif hasattr(streaming_response_model, "__name__"):
streaming_schema_name = streaming_response_model.__name__

View file

@ -9,11 +9,8 @@ Schema discovery and collection for OpenAPI generation.
"""
import importlib
import pkgutil
from typing import Any
from .state import _dynamic_models
def _ensure_components_schemas(openapi_schema: dict[str, Any]) -> None:
"""Ensure components.schemas exists in the schema."""
@ -23,54 +20,21 @@ def _ensure_components_schemas(openapi_schema: dict[str, Any]) -> None:
openapi_schema["components"]["schemas"] = {}
def _import_all_modules_in_package(package_name: str) -> list[Any]:
def _load_extra_schema_modules() -> None:
"""
Dynamically import all modules in a package to trigger register_schema calls.
Import modules outside llama_stack_api that use schema_utils to register schemas.
This walks through all modules in the package and imports them, ensuring
that any register_schema() calls at module level are executed.
Args:
package_name: The fully qualified package name (e.g., 'llama_stack_api')
Returns:
List of imported module objects
The API package already imports its submodules via __init__, but server-side modules
like telemetry need to be imported explicitly so their decorator side effects run.
"""
modules = []
try:
package = importlib.import_module(package_name)
except ImportError:
return modules
package_path = getattr(package, "__path__", None)
if not package_path:
return modules
# Walk packages and modules recursively
for _, modname, ispkg in pkgutil.walk_packages(package_path, prefix=f"{package_name}."):
if not modname.startswith("_"):
try:
module = importlib.import_module(modname)
modules.append(module)
# If this is a package, also try to import any .py files directly
# (e.g., llama_stack_api.scoring_functions.scoring_functions)
if ispkg:
try:
# Try importing the module file with the same name as the package
# This handles cases like scoring_functions/scoring_functions.py
module_file_name = f"{modname}.{modname.split('.')[-1]}"
module_file = importlib.import_module(module_file_name)
if module_file not in modules:
modules.append(module_file)
except (ImportError, AttributeError, TypeError):
# It's okay if this fails - not all packages have a module file with the same name
pass
except (ImportError, AttributeError, TypeError):
# Skip modules that can't be imported (e.g., missing dependencies)
continue
return modules
extra_modules = [
"llama_stack.core.telemetry.telemetry",
]
for module_name in extra_modules:
try:
importlib.import_module(module_name)
except ImportError:
continue
def _extract_and_fix_defs(schema: dict[str, Any], openapi_schema: dict[str, Any]) -> None:
@ -102,82 +66,66 @@ def _extract_and_fix_defs(schema: dict[str, Any], openapi_schema: dict[str, Any]
def _ensure_json_schema_types_included(openapi_schema: dict[str, Any]) -> dict[str, Any]:
"""
Ensure all @json_schema_type decorated models and registered schemas are included in the OpenAPI schema.
This finds all models with the _llama_stack_schema_type attribute and schemas registered via register_schema.
Ensure all registered schemas (decorated, explicit, and dynamic) are included in the OpenAPI schema.
Relies on llama_stack_api's registry instead of recursively importing every module.
"""
_ensure_components_schemas(openapi_schema)
# Import TypeAdapter for handling union types and other non-model types
from pydantic import TypeAdapter
# Dynamically import all modules in packages that might register schemas
# This ensures register_schema() calls execute and populate _registered_schemas
# Also collect the modules for later scanning of @json_schema_type decorated classes
apis_modules = _import_all_modules_in_package("llama_stack_api")
_import_all_modules_in_package("llama_stack.core.telemetry")
from llama_stack_api.schema_utils import (
iter_dynamic_schema_types,
iter_json_schema_types,
iter_registered_schema_types,
)
# First, handle registered schemas (union types, etc.)
from llama_stack_api.schema_utils import _registered_schemas
# Import extra modules (e.g., telemetry) whose schema registrations live outside llama_stack_api
_load_extra_schema_modules()
for schema_type, registration_info in _registered_schemas.items():
schema_name = registration_info["name"]
# Handle explicitly registered schemas first (union types, Annotated structs, etc.)
for registration_info in iter_registered_schema_types():
schema_type = registration_info.type
schema_name = registration_info.name
if schema_name not in openapi_schema["components"]["schemas"]:
try:
# Use TypeAdapter for union types and other non-model types
# Use ref_template to generate references in the format we need
adapter = TypeAdapter(schema_type)
schema = adapter.json_schema(ref_template="#/components/schemas/{model}")
# Extract and fix $defs if present
_extract_and_fix_defs(schema, openapi_schema)
openapi_schema["components"]["schemas"][schema_name] = schema
except Exception as e:
# Skip if we can't generate the schema
print(f"Warning: Failed to generate schema for registered type {schema_name}: {e}")
import traceback
traceback.print_exc()
continue
# Find all classes with the _llama_stack_schema_type attribute
# Use the modules we already imported above
for module in apis_modules:
for attr_name in dir(module):
# Add @json_schema_type decorated models
for model in iter_json_schema_types():
schema_name = getattr(model, "_llama_stack_schema_name", None) or getattr(model, "__name__", None)
if not schema_name:
continue
if schema_name not in openapi_schema["components"]["schemas"]:
try:
attr = getattr(module, attr_name)
if (
hasattr(attr, "_llama_stack_schema_type")
and hasattr(attr, "model_json_schema")
and hasattr(attr, "__name__")
):
schema_name = attr.__name__
if schema_name not in openapi_schema["components"]["schemas"]:
try:
# Use ref_template to ensure consistent reference format and $defs handling
schema = attr.model_json_schema(ref_template="#/components/schemas/{model}")
# Extract and fix $defs if present (model_json_schema can also generate $defs)
_extract_and_fix_defs(schema, openapi_schema)
openapi_schema["components"]["schemas"][schema_name] = schema
except Exception as e:
# Skip if we can't generate the schema
print(f"Warning: Failed to generate schema for {schema_name}: {e}")
continue
except (AttributeError, TypeError):
if hasattr(model, "model_json_schema"):
schema = model.model_json_schema(ref_template="#/components/schemas/{model}")
else:
adapter = TypeAdapter(model)
schema = adapter.json_schema(ref_template="#/components/schemas/{model}")
_extract_and_fix_defs(schema, openapi_schema)
openapi_schema["components"]["schemas"][schema_name] = schema
except Exception as e:
print(f"Warning: Failed to generate schema for {schema_name}: {e}")
continue
# Also include any dynamic models that were created during endpoint generation
# This is a workaround to ensure dynamic models appear in the schema
for model in _dynamic_models:
# Include any dynamic models generated while building endpoints
for model in iter_dynamic_schema_types():
try:
schema_name = model.__name__
if schema_name not in openapi_schema["components"]["schemas"]:
schema = model.model_json_schema(ref_template="#/components/schemas/{model}")
# Extract and fix $defs if present
_extract_and_fix_defs(schema, openapi_schema)
openapi_schema["components"]["schemas"][schema_name] = schema
except Exception:
# Skip if we can't generate the schema
continue
return openapi_schema

View file

@ -16,39 +16,6 @@ from llama_stack_api.version import (
LLAMA_STACK_API_V1BETA,
)
from . import schema_collection
def _get_all_json_schema_type_names() -> set[str]:
"""
Get all schema names from @json_schema_type decorated models.
This ensures they are included in filtered schemas even if not directly referenced by paths.
"""
schema_names = set()
apis_modules = schema_collection._import_all_modules_in_package("llama_stack_api")
for module in apis_modules:
for attr_name in dir(module):
try:
attr = getattr(module, attr_name)
if (
hasattr(attr, "_llama_stack_schema_type")
and hasattr(attr, "model_json_schema")
and hasattr(attr, "__name__")
):
schema_names.add(attr.__name__)
except (AttributeError, TypeError):
continue
return schema_names
def _get_explicit_schema_names(openapi_schema: dict[str, Any]) -> set[str]:
"""Get all registered schema names and @json_schema_type decorated model names."""
from llama_stack_api.schema_utils import _registered_schemas
registered_schema_names = {info["name"] for info in _registered_schemas.values()}
json_schema_type_names = _get_all_json_schema_type_names()
return registered_schema_names | json_schema_type_names
def _find_schema_refs_in_object(obj: Any) -> set[str]:
"""
@ -70,21 +37,12 @@ def _find_schema_refs_in_object(obj: Any) -> set[str]:
return refs
def _add_transitive_references(
referenced_schemas: set[str], all_schemas: dict[str, Any], initial_schemas: set[str] | None = None
) -> set[str]:
def _add_transitive_references(referenced_schemas: set[str], all_schemas: dict[str, Any]) -> set[str]:
"""Add transitive references for given schemas."""
if initial_schemas:
referenced_schemas.update(initial_schemas)
additional_schemas = set()
for schema_name in initial_schemas:
if schema_name in all_schemas:
additional_schemas.update(_find_schema_refs_in_object(all_schemas[schema_name]))
else:
additional_schemas = set()
for schema_name in referenced_schemas:
if schema_name in all_schemas:
additional_schemas.update(_find_schema_refs_in_object(all_schemas[schema_name]))
additional_schemas = set()
for schema_name in referenced_schemas:
if schema_name in all_schemas:
additional_schemas.update(_find_schema_refs_in_object(all_schemas[schema_name]))
while additional_schemas:
new_schemas = additional_schemas - referenced_schemas
@ -155,8 +113,7 @@ def _filter_schemas_by_references(
referenced_schemas = _find_schemas_referenced_by_paths(filtered_paths, openapi_schema)
all_schemas = openapi_schema.get("components", {}).get("schemas", {})
explicit_schema_names = _get_explicit_schema_names(openapi_schema)
referenced_schemas = _add_transitive_references(referenced_schemas, all_schemas, explicit_schema_names)
referenced_schemas = _add_transitive_references(referenced_schemas, all_schemas)
filtered_schemas = {
name: schema for name, schema in filtered_schema["components"]["schemas"].items() if name in referenced_schemas

View file

@ -19,14 +19,13 @@ from openapi_spec_validator.exceptions import OpenAPISpecValidatorError
from . import endpoints, schema_collection
from ._legacy_order import (
LEGACY_OPERATION_KEYS,
LEGACY_PATH_ORDER,
LEGACY_RESPONSE_ORDER,
LEGACY_SCHEMA_ORDER,
LEGACY_OPERATION_KEYS,
LEGACY_SECURITY,
LEGACY_TAGS,
LEGACY_TAG_GROUPS,
LEGACY_TAG_ORDER,
LEGACY_TAGS,
)
from .state import _extra_body_fields
@ -864,7 +863,15 @@ def _apply_legacy_sorting(openapi_schema: dict[str, Any]) -> dict[str, Any]:
ordered_path_item[method] = order_mapping(path_item[method], LEGACY_OPERATION_KEYS)
for key, value in path_item.items():
if key not in ordered_path_item:
if isinstance(value, dict) and key.lower() in {"get", "post", "put", "delete", "patch", "head", "options"}:
if isinstance(value, dict) and key.lower() in {
"get",
"post",
"put",
"delete",
"patch",
"head",
"options",
}:
ordered_path_item[key] = order_mapping(value, LEGACY_OPERATION_KEYS)
else:
ordered_path_item[key] = value

View file

@ -11,9 +11,8 @@ Shared state for the OpenAPI generator module.
from typing import Any
from llama_stack_api import Api
from llama_stack_api.schema_utils import clear_dynamic_schema_types, register_dynamic_schema_type
# Global list to store dynamic models created during endpoint generation
_dynamic_models: list[Any] = []
_dynamic_model_registry: dict[str, type] = {}
# Cache for protocol methods to avoid repeated lookups
@ -28,14 +27,15 @@ def register_dynamic_model(name: str, model: type) -> type:
"""Register and deduplicate dynamically generated request models."""
existing = _dynamic_model_registry.get(name)
if existing is not None:
register_dynamic_schema_type(existing)
return existing
_dynamic_model_registry[name] = model
_dynamic_models.append(model)
register_dynamic_schema_type(model)
return model
def reset_generator_state() -> None:
"""Clear per-run caches so repeated generations stay deterministic."""
_dynamic_models.clear()
_dynamic_model_registry.clear()
_extra_body_fields.clear()
clear_dynamic_schema_types()