ignore v1 in JSON schema codegen (#12408)

## Why

The generated unnamespaced JSON envelope schemas (`ClientRequest` and
`ServerNotification`) still contained both v1 and v2 variants, which
pulled legacy v1/core types and v2 types into the same `definitions`
graph. That caused `schemars` to produce numeric suffix names (for
example `AskForApproval2`, `ByteRange2`, `MessagePhase2`).

This PR moves JSON codegen toward v2-only output while preserving the
unnamespaced envelope artifacts, and avoids reintroducing numeric-suffix
tolerance by removing the v1/internal-only variants that caused the
collisions in those envelope schemas.

## What Changed

- In `codex-rs/app-server-protocol/src/export.rs`, JSON generation now
excludes v1 schema artifacts (`v1/*`) while continuing to emit
unnamespaced/root JSON schemas and the JSON bundle.
- Added a narrow JSON v1 allowlist (`JSON_V1_ALLOWLIST`) so
`InitializeParams` and `InitializeResponse` are still emitted.
- Added JSON-only post-processing for the mixed envelope schemas before
collision checks run:
- `ClientRequest`: strips v1 request variants from the generated `oneOf`
using the temporary `V1_CLIENT_REQUEST_METHODS` list
- `ServerNotification`: strips v1 notifications plus the internal-only
`rawResponseItem/completed` notification using the temporary
`EXCLUDED_SERVER_NOTIFICATION_METHODS_FOR_JSON` list
- Added a temporary local-definition pruning pass for those envelope
schemas so now-unreferenced v1/core definitions are removed from
`definitions` after method filtering.
- Updated the variant-title naming heuristic for single-property literal
object variants to use the literal value (when available), avoiding
collisions like multiple `state`-only variants all deriving the same
title.
- Collision handling remains fail-fast (no numeric suffix fallback map
in this PR path).

## Verification

- `just write-app-server-schema`

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/12408).
* __->__ #12408
* #12406
This commit is contained in:
Michael Bolin
2026-02-20 21:36:12 -08:00
committed by GitHub
Unverified
parent dca9c40dd5
commit 1779feb6a7
47 changed files with 204 additions and 32323 deletions
File diff suppressed because it is too large Load Diff
@@ -3519,7 +3519,7 @@
"required": [
"state"
],
"title": "StateMcpStartupStatus",
"title": "StartingMcpStartupStatus",
"type": "object"
},
{
@@ -3534,7 +3534,7 @@
"required": [
"state"
],
"title": "StateMcpStartupStatus2",
"title": "ReadyMcpStartupStatus",
"type": "object"
},
{
@@ -3567,7 +3567,7 @@
"required": [
"state"
],
"title": "StateMcpStartupStatus3",
"title": "CancelledMcpStartupStatus",
"type": "object"
}
]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,22 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ThreadId": {
"type": "string"
}
},
"properties": {
"conversationId": {
"$ref": "#/definitions/ThreadId"
},
"experimentalRawEvents": {
"default": false,
"type": "boolean"
}
},
"required": [
"conversationId"
],
"title": "AddConversationListenerParams",
"type": "object"
}
@@ -1,13 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"subscriptionId": {
"type": "string"
}
},
"required": [
"subscriptionId"
],
"title": "AddConversationSubscriptionResponse",
"type": "object"
}
@@ -1,22 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ThreadId": {
"type": "string"
}
},
"properties": {
"conversationId": {
"$ref": "#/definitions/ThreadId"
},
"rolloutPath": {
"type": "string"
}
},
"required": [
"conversationId",
"rolloutPath"
],
"title": "ArchiveConversationParams",
"type": "object"
}
@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ArchiveConversationResponse",
"type": "object"
}
@@ -1,46 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AuthMode": {
"description": "Authentication mode for OpenAI-backed providers.",
"oneOf": [
{
"description": "OpenAI API key provided by the caller and stored by Codex.",
"enum": [
"apikey"
],
"type": "string"
},
{
"description": "ChatGPT OAuth managed by Codex (tokens persisted and refreshed by Codex).",
"enum": [
"chatgpt"
],
"type": "string"
},
{
"description": "[UNSTABLE] FOR OPENAI INTERNAL USE ONLY - DO NOT USE.\n\nChatGPT auth tokens are supplied by an external host app and are only stored in memory. Token refresh must be handled by the external host app.",
"enum": [
"chatgptAuthTokens"
],
"type": "string"
}
]
}
},
"description": "Deprecated notification. Use AccountUpdatedNotification instead.",
"properties": {
"authMethod": {
"anyOf": [
{
"$ref": "#/definitions/AuthMode"
},
{
"type": "null"
}
]
}
},
"title": "AuthStatusChangeNotification",
"type": "object"
}
@@ -1,13 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"loginId": {
"type": "string"
}
},
"required": [
"loginId"
],
"title": "CancelLoginChatGptParams",
"type": "object"
}
@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "CancelLoginChatGptResponse",
"type": "object"
}
@@ -1,225 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AbsolutePathBuf": {
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
"type": "string"
},
"NetworkAccess": {
"description": "Represents whether outbound network access is available to the agent.",
"enum": [
"restricted",
"enabled"
],
"type": "string"
},
"ReadOnlyAccess": {
"description": "Determines how read-only file access is granted inside a restricted sandbox.",
"oneOf": [
{
"description": "Restrict reads to an explicit set of roots.\n\nWhen `include_platform_defaults` is `true`, platform defaults required for basic execution are included in addition to `readable_roots`.",
"properties": {
"include_platform_defaults": {
"default": true,
"description": "Include built-in platform read roots required for basic process execution.",
"type": "boolean"
},
"readable_roots": {
"description": "Additional absolute roots that should be readable.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": "array"
},
"type": {
"enum": [
"restricted"
],
"title": "RestrictedReadOnlyAccessType",
"type": "string"
}
},
"required": [
"type"
],
"title": "RestrictedReadOnlyAccess",
"type": "object"
},
{
"description": "Allow unrestricted file reads.",
"properties": {
"type": {
"enum": [
"full-access"
],
"title": "FullAccessReadOnlyAccessType",
"type": "string"
}
},
"required": [
"type"
],
"title": "FullAccessReadOnlyAccess",
"type": "object"
}
]
},
"SandboxPolicy": {
"description": "Determines execution restrictions for model shell commands.",
"oneOf": [
{
"description": "No restrictions whatsoever. Use with caution.",
"properties": {
"type": {
"enum": [
"danger-full-access"
],
"title": "DangerFullAccessSandboxPolicyType",
"type": "string"
}
},
"required": [
"type"
],
"title": "DangerFullAccessSandboxPolicy",
"type": "object"
},
{
"description": "Read-only access configuration.",
"properties": {
"access": {
"allOf": [
{
"$ref": "#/definitions/ReadOnlyAccess"
}
],
"description": "Read access granted while running under this policy."
},
"type": {
"enum": [
"read-only"
],
"title": "ReadOnlySandboxPolicyType",
"type": "string"
}
},
"required": [
"type"
],
"title": "ReadOnlySandboxPolicy",
"type": "object"
},
{
"description": "Indicates the process is already in an external sandbox. Allows full disk access while honoring the provided network setting.",
"properties": {
"network_access": {
"allOf": [
{
"$ref": "#/definitions/NetworkAccess"
}
],
"default": "restricted",
"description": "Whether the external sandbox permits outbound network traffic."
},
"type": {
"enum": [
"external-sandbox"
],
"title": "ExternalSandboxSandboxPolicyType",
"type": "string"
}
},
"required": [
"type"
],
"title": "ExternalSandboxSandboxPolicy",
"type": "object"
},
{
"description": "Same as `ReadOnly` but additionally grants write access to the current working directory (\"workspace\").",
"properties": {
"exclude_slash_tmp": {
"default": false,
"description": "When set to `true`, will NOT include the `/tmp` among the default writable roots on UNIX. Defaults to `false`.",
"type": "boolean"
},
"exclude_tmpdir_env_var": {
"default": false,
"description": "When set to `true`, will NOT include the per-user `TMPDIR` environment variable among the default writable roots. Defaults to `false`.",
"type": "boolean"
},
"network_access": {
"default": false,
"description": "When set to `true`, outbound network access is allowed. `false` by default.",
"type": "boolean"
},
"read_only_access": {
"allOf": [
{
"$ref": "#/definitions/ReadOnlyAccess"
}
],
"description": "Read access granted while running under this policy."
},
"type": {
"enum": [
"workspace-write"
],
"title": "WorkspaceWriteSandboxPolicyType",
"type": "string"
},
"writable_roots": {
"description": "Additional folders (beyond cwd and possibly TMPDIR) that should be writable from within the sandbox.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": "array"
}
},
"required": [
"type"
],
"title": "WorkspaceWriteSandboxPolicy",
"type": "object"
}
]
}
},
"properties": {
"command": {
"items": {
"type": "string"
},
"type": "array"
},
"cwd": {
"type": [
"string",
"null"
]
},
"sandboxPolicy": {
"anyOf": [
{
"$ref": "#/definitions/SandboxPolicy"
},
{
"type": "null"
}
]
},
"timeoutMs": {
"format": "uint64",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"required": [
"command"
],
"title": "ExecOneOffCommandParams",
"type": "object"
}
@@ -1,22 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"exitCode": {
"format": "int32",
"type": "integer"
},
"stderr": {
"type": "string"
},
"stdout": {
"type": "string"
}
},
"required": [
"exitCode",
"stderr",
"stdout"
],
"title": "ExecOneOffCommandResponse",
"type": "object"
}
@@ -1,195 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AskForApproval": {
"description": "Determines the conditions under which the user is consulted to approve running the command proposed by Codex.",
"oneOf": [
{
"description": "Under this policy, only \"known safe\" commands—as determined by `is_safe_command()`—that **only read files** are autoapproved. Everything else will ask the user to approve.",
"enum": [
"untrusted"
],
"type": "string"
},
{
"description": "DEPRECATED: *All* commands are autoapproved, but they are expected to run inside a sandbox where network access is disabled and writes are confined to a specific set of paths. If the command fails, it will be escalated to the user to approve execution without a sandbox. Prefer `OnRequest` for interactive runs or `Never` for non-interactive runs.",
"enum": [
"on-failure"
],
"type": "string"
},
{
"description": "The model decides when to ask the user for approval.",
"enum": [
"on-request"
],
"type": "string"
},
{
"additionalProperties": false,
"description": "Fine-grained rejection controls for approval prompts.\n\nWhen a field is `true`, prompts of that category are automatically rejected instead of shown to the user.",
"properties": {
"reject": {
"$ref": "#/definitions/RejectConfig"
}
},
"required": [
"reject"
],
"title": "RejectAskForApproval",
"type": "object"
},
{
"description": "Never ask the user to approve commands. Failures are immediately returned to the model, and never escalated to the user for approval.",
"enum": [
"never"
],
"type": "string"
}
]
},
"NewConversationParams": {
"properties": {
"approvalPolicy": {
"anyOf": [
{
"$ref": "#/definitions/AskForApproval"
},
{
"type": "null"
}
]
},
"baseInstructions": {
"type": [
"string",
"null"
]
},
"compactPrompt": {
"type": [
"string",
"null"
]
},
"config": {
"additionalProperties": true,
"type": [
"object",
"null"
]
},
"cwd": {
"type": [
"string",
"null"
]
},
"developerInstructions": {
"type": [
"string",
"null"
]
},
"includeApplyPatchTool": {
"type": [
"boolean",
"null"
]
},
"model": {
"type": [
"string",
"null"
]
},
"modelProvider": {
"type": [
"string",
"null"
]
},
"profile": {
"type": [
"string",
"null"
]
},
"sandbox": {
"anyOf": [
{
"$ref": "#/definitions/SandboxMode"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"RejectConfig": {
"properties": {
"mcp_elicitations": {
"description": "Reject MCP elicitation prompts.",
"type": "boolean"
},
"rules": {
"description": "Reject prompts triggered by execpolicy `prompt` rules.",
"type": "boolean"
},
"sandbox_approval": {
"description": "Reject approval prompts related to sandbox escalation.",
"type": "boolean"
}
},
"required": [
"mcp_elicitations",
"rules",
"sandbox_approval"
],
"type": "object"
},
"SandboxMode": {
"enum": [
"read-only",
"workspace-write",
"danger-full-access"
],
"type": "string"
},
"ThreadId": {
"type": "string"
}
},
"properties": {
"conversationId": {
"anyOf": [
{
"$ref": "#/definitions/ThreadId"
},
{
"type": "null"
}
]
},
"overrides": {
"anyOf": [
{
"$ref": "#/definitions/NewConversationParams"
},
{
"type": "null"
}
]
},
"path": {
"type": [
"string",
"null"
]
}
},
"title": "ForkConversationParams",
"type": "object"
}
File diff suppressed because it is too large Load Diff
@@ -1,19 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"includeToken": {
"type": [
"boolean",
"null"
]
},
"refreshToken": {
"type": [
"boolean",
"null"
]
}
},
"title": "GetAuthStatusParams",
"type": "object"
}
@@ -1,57 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AuthMode": {
"description": "Authentication mode for OpenAI-backed providers.",
"oneOf": [
{
"description": "OpenAI API key provided by the caller and stored by Codex.",
"enum": [
"apikey"
],
"type": "string"
},
{
"description": "ChatGPT OAuth managed by Codex (tokens persisted and refreshed by Codex).",
"enum": [
"chatgpt"
],
"type": "string"
},
{
"description": "[UNSTABLE] FOR OPENAI INTERNAL USE ONLY - DO NOT USE.\n\nChatGPT auth tokens are supplied by an external host app and are only stored in memory. Token refresh must be handled by the external host app.",
"enum": [
"chatgptAuthTokens"
],
"type": "string"
}
]
}
},
"properties": {
"authMethod": {
"anyOf": [
{
"$ref": "#/definitions/AuthMode"
},
{
"type": "null"
}
]
},
"authToken": {
"type": [
"string",
"null"
]
},
"requiresOpenaiAuth": {
"type": [
"boolean",
"null"
]
}
},
"title": "GetAuthStatusResponse",
"type": "object"
}
@@ -1,35 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"anyOf": [
{
"properties": {
"rolloutPath": {
"type": "string"
}
},
"required": [
"rolloutPath"
],
"title": "RolloutPathv1::GetConversationSummaryParams",
"type": "object"
},
{
"properties": {
"conversationId": {
"$ref": "#/definitions/ThreadId"
}
},
"required": [
"conversationId"
],
"title": "ConversationIdv1::GetConversationSummaryParams",
"type": "object"
}
],
"definitions": {
"ThreadId": {
"type": "string"
}
},
"title": "GetConversationSummaryParams"
}
@@ -1,190 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ConversationGitInfo": {
"properties": {
"branch": {
"type": [
"string",
"null"
]
},
"origin_url": {
"type": [
"string",
"null"
]
},
"sha": {
"type": [
"string",
"null"
]
}
},
"type": "object"
},
"ConversationSummary": {
"properties": {
"cliVersion": {
"type": "string"
},
"conversationId": {
"$ref": "#/definitions/ThreadId"
},
"cwd": {
"type": "string"
},
"gitInfo": {
"anyOf": [
{
"$ref": "#/definitions/ConversationGitInfo"
},
{
"type": "null"
}
]
},
"modelProvider": {
"type": "string"
},
"path": {
"type": "string"
},
"preview": {
"type": "string"
},
"source": {
"$ref": "#/definitions/SessionSource"
},
"timestamp": {
"type": [
"string",
"null"
]
},
"updatedAt": {
"type": [
"string",
"null"
]
}
},
"required": [
"cliVersion",
"conversationId",
"cwd",
"modelProvider",
"path",
"preview",
"source"
],
"type": "object"
},
"SessionSource": {
"oneOf": [
{
"enum": [
"cli",
"vscode",
"exec",
"mcp",
"unknown"
],
"type": "string"
},
{
"additionalProperties": false,
"properties": {
"subagent": {
"$ref": "#/definitions/SubAgentSource"
}
},
"required": [
"subagent"
],
"title": "SubagentSessionSource",
"type": "object"
}
]
},
"SubAgentSource": {
"oneOf": [
{
"enum": [
"review",
"compact",
"memory_consolidation"
],
"type": "string"
},
{
"additionalProperties": false,
"properties": {
"thread_spawn": {
"properties": {
"agent_nickname": {
"default": null,
"type": [
"string",
"null"
]
},
"agent_role": {
"default": null,
"type": [
"string",
"null"
]
},
"depth": {
"format": "int32",
"type": "integer"
},
"parent_thread_id": {
"$ref": "#/definitions/ThreadId"
}
},
"required": [
"depth",
"parent_thread_id"
],
"type": "object"
}
},
"required": [
"thread_spawn"
],
"title": "ThreadSpawnSubAgentSource",
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"other": {
"type": "string"
}
},
"required": [
"other"
],
"title": "OtherSubAgentSource",
"type": "object"
}
]
},
"ThreadId": {
"type": "string"
}
},
"properties": {
"summary": {
"$ref": "#/definitions/ConversationSummary"
}
},
"required": [
"summary"
],
"title": "GetConversationSummaryResponse",
"type": "object"
}
@@ -1,13 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"userAgent": {
"type": "string"
}
},
"required": [
"userAgent"
],
"title": "GetUserAgentResponse",
"type": "object"
}
@@ -1,366 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AbsolutePathBuf": {
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
"type": "string"
},
"AskForApproval": {
"description": "Determines the conditions under which the user is consulted to approve running the command proposed by Codex.",
"oneOf": [
{
"description": "Under this policy, only \"known safe\" commands—as determined by `is_safe_command()`—that **only read files** are autoapproved. Everything else will ask the user to approve.",
"enum": [
"untrusted"
],
"type": "string"
},
{
"description": "DEPRECATED: *All* commands are autoapproved, but they are expected to run inside a sandbox where network access is disabled and writes are confined to a specific set of paths. If the command fails, it will be escalated to the user to approve execution without a sandbox. Prefer `OnRequest` for interactive runs or `Never` for non-interactive runs.",
"enum": [
"on-failure"
],
"type": "string"
},
{
"description": "The model decides when to ask the user for approval.",
"enum": [
"on-request"
],
"type": "string"
},
{
"additionalProperties": false,
"description": "Fine-grained rejection controls for approval prompts.\n\nWhen a field is `true`, prompts of that category are automatically rejected instead of shown to the user.",
"properties": {
"reject": {
"$ref": "#/definitions/RejectConfig"
}
},
"required": [
"reject"
],
"title": "RejectAskForApproval",
"type": "object"
},
{
"description": "Never ask the user to approve commands. Failures are immediately returned to the model, and never escalated to the user for approval.",
"enum": [
"never"
],
"type": "string"
}
]
},
"ForcedLoginMethod": {
"enum": [
"chatgpt",
"api"
],
"type": "string"
},
"Profile": {
"properties": {
"approvalPolicy": {
"anyOf": [
{
"$ref": "#/definitions/AskForApproval"
},
{
"type": "null"
}
]
},
"chatgptBaseUrl": {
"type": [
"string",
"null"
]
},
"model": {
"type": [
"string",
"null"
]
},
"modelProvider": {
"type": [
"string",
"null"
]
},
"modelReasoningEffort": {
"anyOf": [
{
"$ref": "#/definitions/ReasoningEffort"
},
{
"type": "null"
}
]
},
"modelReasoningSummary": {
"anyOf": [
{
"$ref": "#/definitions/ReasoningSummary"
},
{
"type": "null"
}
]
},
"modelVerbosity": {
"anyOf": [
{
"$ref": "#/definitions/Verbosity"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"ReasoningEffort": {
"description": "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning",
"enum": [
"none",
"minimal",
"low",
"medium",
"high",
"xhigh"
],
"type": "string"
},
"ReasoningSummary": {
"description": "A summary of the reasoning performed by the model. This can be useful for debugging and understanding the model's reasoning process. See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#reasoning-summaries",
"oneOf": [
{
"enum": [
"auto",
"concise",
"detailed"
],
"type": "string"
},
{
"description": "Option to disable reasoning summaries.",
"enum": [
"none"
],
"type": "string"
}
]
},
"RejectConfig": {
"properties": {
"mcp_elicitations": {
"description": "Reject MCP elicitation prompts.",
"type": "boolean"
},
"rules": {
"description": "Reject prompts triggered by execpolicy `prompt` rules.",
"type": "boolean"
},
"sandbox_approval": {
"description": "Reject approval prompts related to sandbox escalation.",
"type": "boolean"
}
},
"required": [
"mcp_elicitations",
"rules",
"sandbox_approval"
],
"type": "object"
},
"SandboxMode": {
"enum": [
"read-only",
"workspace-write",
"danger-full-access"
],
"type": "string"
},
"SandboxSettings": {
"properties": {
"excludeSlashTmp": {
"type": [
"boolean",
"null"
]
},
"excludeTmpdirEnvVar": {
"type": [
"boolean",
"null"
]
},
"networkAccess": {
"type": [
"boolean",
"null"
]
},
"writableRoots": {
"default": [],
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": "array"
}
},
"type": "object"
},
"Tools": {
"properties": {
"viewImage": {
"type": [
"boolean",
"null"
]
},
"webSearch": {
"type": [
"boolean",
"null"
]
}
},
"type": "object"
},
"UserSavedConfig": {
"properties": {
"approvalPolicy": {
"anyOf": [
{
"$ref": "#/definitions/AskForApproval"
},
{
"type": "null"
}
]
},
"forcedChatgptWorkspaceId": {
"type": [
"string",
"null"
]
},
"forcedLoginMethod": {
"anyOf": [
{
"$ref": "#/definitions/ForcedLoginMethod"
},
{
"type": "null"
}
]
},
"model": {
"type": [
"string",
"null"
]
},
"modelReasoningEffort": {
"anyOf": [
{
"$ref": "#/definitions/ReasoningEffort"
},
{
"type": "null"
}
]
},
"modelReasoningSummary": {
"anyOf": [
{
"$ref": "#/definitions/ReasoningSummary"
},
{
"type": "null"
}
]
},
"modelVerbosity": {
"anyOf": [
{
"$ref": "#/definitions/Verbosity"
},
{
"type": "null"
}
]
},
"profile": {
"type": [
"string",
"null"
]
},
"profiles": {
"additionalProperties": {
"$ref": "#/definitions/Profile"
},
"type": "object"
},
"sandboxMode": {
"anyOf": [
{
"$ref": "#/definitions/SandboxMode"
},
{
"type": "null"
}
]
},
"sandboxSettings": {
"anyOf": [
{
"$ref": "#/definitions/SandboxSettings"
},
{
"type": "null"
}
]
},
"tools": {
"anyOf": [
{
"$ref": "#/definitions/Tools"
},
{
"type": "null"
}
]
}
},
"required": [
"profiles"
],
"type": "object"
},
"Verbosity": {
"description": "Controls output length/detail on GPT-5 models via the Responses API. Serialized with lowercase values to match the OpenAI API.",
"enum": [
"low",
"medium",
"high"
],
"type": "string"
}
},
"properties": {
"config": {
"$ref": "#/definitions/UserSavedConfig"
}
},
"required": [
"config"
],
"title": "GetUserSavedConfigResponse",
"type": "object"
}
@@ -1,13 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"cwd": {
"type": "string"
}
},
"required": [
"cwd"
],
"title": "GitDiffToRemoteParams",
"type": "object"
}
@@ -1,22 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"GitSha": {
"type": "string"
}
},
"properties": {
"diff": {
"type": "string"
},
"sha": {
"$ref": "#/definitions/GitSha"
}
},
"required": [
"diff",
"sha"
],
"title": "GitDiffToRemoteResponse",
"type": "object"
}
@@ -1,18 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ThreadId": {
"type": "string"
}
},
"properties": {
"conversationId": {
"$ref": "#/definitions/ThreadId"
}
},
"required": [
"conversationId"
],
"title": "InterruptConversationParams",
"type": "object"
}
@@ -1,23 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"TurnAbortReason": {
"enum": [
"interrupted",
"replaced",
"review_ended"
],
"type": "string"
}
},
"properties": {
"abortReason": {
"$ref": "#/definitions/TurnAbortReason"
}
},
"required": [
"abortReason"
],
"title": "InterruptConversationResponse",
"type": "object"
}
@@ -1,30 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"cursor": {
"type": [
"string",
"null"
]
},
"modelProviders": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"pageSize": {
"format": "uint",
"minimum": 0.0,
"type": [
"integer",
"null"
]
}
},
"title": "ListConversationsParams",
"type": "object"
}
@@ -1,199 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ConversationGitInfo": {
"properties": {
"branch": {
"type": [
"string",
"null"
]
},
"origin_url": {
"type": [
"string",
"null"
]
},
"sha": {
"type": [
"string",
"null"
]
}
},
"type": "object"
},
"ConversationSummary": {
"properties": {
"cliVersion": {
"type": "string"
},
"conversationId": {
"$ref": "#/definitions/ThreadId"
},
"cwd": {
"type": "string"
},
"gitInfo": {
"anyOf": [
{
"$ref": "#/definitions/ConversationGitInfo"
},
{
"type": "null"
}
]
},
"modelProvider": {
"type": "string"
},
"path": {
"type": "string"
},
"preview": {
"type": "string"
},
"source": {
"$ref": "#/definitions/SessionSource"
},
"timestamp": {
"type": [
"string",
"null"
]
},
"updatedAt": {
"type": [
"string",
"null"
]
}
},
"required": [
"cliVersion",
"conversationId",
"cwd",
"modelProvider",
"path",
"preview",
"source"
],
"type": "object"
},
"SessionSource": {
"oneOf": [
{
"enum": [
"cli",
"vscode",
"exec",
"mcp",
"unknown"
],
"type": "string"
},
{
"additionalProperties": false,
"properties": {
"subagent": {
"$ref": "#/definitions/SubAgentSource"
}
},
"required": [
"subagent"
],
"title": "SubagentSessionSource",
"type": "object"
}
]
},
"SubAgentSource": {
"oneOf": [
{
"enum": [
"review",
"compact",
"memory_consolidation"
],
"type": "string"
},
{
"additionalProperties": false,
"properties": {
"thread_spawn": {
"properties": {
"agent_nickname": {
"default": null,
"type": [
"string",
"null"
]
},
"agent_role": {
"default": null,
"type": [
"string",
"null"
]
},
"depth": {
"format": "int32",
"type": "integer"
},
"parent_thread_id": {
"$ref": "#/definitions/ThreadId"
}
},
"required": [
"depth",
"parent_thread_id"
],
"type": "object"
}
},
"required": [
"thread_spawn"
],
"title": "ThreadSpawnSubAgentSource",
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"other": {
"type": "string"
}
},
"required": [
"other"
],
"title": "OtherSubAgentSource",
"type": "object"
}
]
},
"ThreadId": {
"type": "string"
}
},
"properties": {
"items": {
"items": {
"$ref": "#/definitions/ConversationSummary"
},
"type": "array"
},
"nextCursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"items"
],
"title": "ListConversationsResponse",
"type": "object"
}
@@ -1,13 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"apiKey": {
"type": "string"
}
},
"required": [
"apiKey"
],
"title": "LoginApiKeyParams",
"type": "object"
}
@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "LoginApiKeyResponse",
"type": "object"
}
@@ -1,24 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Deprecated in favor of AccountLoginCompletedNotification.",
"properties": {
"error": {
"type": [
"string",
"null"
]
},
"loginId": {
"type": "string"
},
"success": {
"type": "boolean"
}
},
"required": [
"loginId",
"success"
],
"title": "LoginChatGptCompleteNotification",
"type": "object"
}
@@ -1,17 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"authUrl": {
"type": "string"
},
"loginId": {
"type": "string"
}
},
"required": [
"authUrl",
"loginId"
],
"title": "LoginChatGptResponse",
"type": "object"
}
@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "LogoutChatGptResponse",
"type": "object"
}
@@ -1,161 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AskForApproval": {
"description": "Determines the conditions under which the user is consulted to approve running the command proposed by Codex.",
"oneOf": [
{
"description": "Under this policy, only \"known safe\" commands—as determined by `is_safe_command()`—that **only read files** are autoapproved. Everything else will ask the user to approve.",
"enum": [
"untrusted"
],
"type": "string"
},
{
"description": "DEPRECATED: *All* commands are autoapproved, but they are expected to run inside a sandbox where network access is disabled and writes are confined to a specific set of paths. If the command fails, it will be escalated to the user to approve execution without a sandbox. Prefer `OnRequest` for interactive runs or `Never` for non-interactive runs.",
"enum": [
"on-failure"
],
"type": "string"
},
{
"description": "The model decides when to ask the user for approval.",
"enum": [
"on-request"
],
"type": "string"
},
{
"additionalProperties": false,
"description": "Fine-grained rejection controls for approval prompts.\n\nWhen a field is `true`, prompts of that category are automatically rejected instead of shown to the user.",
"properties": {
"reject": {
"$ref": "#/definitions/RejectConfig"
}
},
"required": [
"reject"
],
"title": "RejectAskForApproval",
"type": "object"
},
{
"description": "Never ask the user to approve commands. Failures are immediately returned to the model, and never escalated to the user for approval.",
"enum": [
"never"
],
"type": "string"
}
]
},
"RejectConfig": {
"properties": {
"mcp_elicitations": {
"description": "Reject MCP elicitation prompts.",
"type": "boolean"
},
"rules": {
"description": "Reject prompts triggered by execpolicy `prompt` rules.",
"type": "boolean"
},
"sandbox_approval": {
"description": "Reject approval prompts related to sandbox escalation.",
"type": "boolean"
}
},
"required": [
"mcp_elicitations",
"rules",
"sandbox_approval"
],
"type": "object"
},
"SandboxMode": {
"enum": [
"read-only",
"workspace-write",
"danger-full-access"
],
"type": "string"
}
},
"properties": {
"approvalPolicy": {
"anyOf": [
{
"$ref": "#/definitions/AskForApproval"
},
{
"type": "null"
}
]
},
"baseInstructions": {
"type": [
"string",
"null"
]
},
"compactPrompt": {
"type": [
"string",
"null"
]
},
"config": {
"additionalProperties": true,
"type": [
"object",
"null"
]
},
"cwd": {
"type": [
"string",
"null"
]
},
"developerInstructions": {
"type": [
"string",
"null"
]
},
"includeApplyPatchTool": {
"type": [
"boolean",
"null"
]
},
"model": {
"type": [
"string",
"null"
]
},
"modelProvider": {
"type": [
"string",
"null"
]
},
"profile": {
"type": [
"string",
"null"
]
},
"sandbox": {
"anyOf": [
{
"$ref": "#/definitions/SandboxMode"
},
{
"type": "null"
}
]
}
},
"title": "NewConversationParams",
"type": "object"
}
@@ -1,48 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ReasoningEffort": {
"description": "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning",
"enum": [
"none",
"minimal",
"low",
"medium",
"high",
"xhigh"
],
"type": "string"
},
"ThreadId": {
"type": "string"
}
},
"properties": {
"conversationId": {
"$ref": "#/definitions/ThreadId"
},
"model": {
"type": "string"
},
"reasoningEffort": {
"anyOf": [
{
"$ref": "#/definitions/ReasoningEffort"
},
{
"type": "null"
}
]
},
"rolloutPath": {
"type": "string"
}
},
"required": [
"conversationId",
"model",
"rolloutPath"
],
"title": "NewConversationResponse",
"type": "object"
}
@@ -1,13 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"subscriptionId": {
"type": "string"
}
},
"required": [
"subscriptionId"
],
"title": "RemoveConversationListenerParams",
"type": "object"
}
@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "RemoveConversationSubscriptionResponse",
"type": "object"
}
@@ -1,984 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AskForApproval": {
"description": "Determines the conditions under which the user is consulted to approve running the command proposed by Codex.",
"oneOf": [
{
"description": "Under this policy, only \"known safe\" commands—as determined by `is_safe_command()`—that **only read files** are autoapproved. Everything else will ask the user to approve.",
"enum": [
"untrusted"
],
"type": "string"
},
{
"description": "DEPRECATED: *All* commands are autoapproved, but they are expected to run inside a sandbox where network access is disabled and writes are confined to a specific set of paths. If the command fails, it will be escalated to the user to approve execution without a sandbox. Prefer `OnRequest` for interactive runs or `Never` for non-interactive runs.",
"enum": [
"on-failure"
],
"type": "string"
},
{
"description": "The model decides when to ask the user for approval.",
"enum": [
"on-request"
],
"type": "string"
},
{
"additionalProperties": false,
"description": "Fine-grained rejection controls for approval prompts.\n\nWhen a field is `true`, prompts of that category are automatically rejected instead of shown to the user.",
"properties": {
"reject": {
"$ref": "#/definitions/RejectConfig"
}
},
"required": [
"reject"
],
"title": "RejectAskForApproval",
"type": "object"
},
{
"description": "Never ask the user to approve commands. Failures are immediately returned to the model, and never escalated to the user for approval.",
"enum": [
"never"
],
"type": "string"
}
]
},
"ContentItem": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"input_text"
],
"title": "InputTextContentItemType",
"type": "string"
}
},
"required": [
"text",
"type"
],
"title": "InputTextContentItem",
"type": "object"
},
{
"properties": {
"image_url": {
"type": "string"
},
"type": {
"enum": [
"input_image"
],
"title": "InputImageContentItemType",
"type": "string"
}
},
"required": [
"image_url",
"type"
],
"title": "InputImageContentItem",
"type": "object"
},
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"output_text"
],
"title": "OutputTextContentItemType",
"type": "string"
}
},
"required": [
"text",
"type"
],
"title": "OutputTextContentItem",
"type": "object"
}
]
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"FunctionCallOutputContentItem": {
"description": "Responses API compatible content items that can be returned by a tool call. This is a subset of ContentItem with the types we support as function call outputs.",
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"input_text"
],
"title": "InputTextFunctionCallOutputContentItemType",
"type": "string"
}
},
"required": [
"text",
"type"
],
"title": "InputTextFunctionCallOutputContentItem",
"type": "object"
},
{
"properties": {
"image_url": {
"type": "string"
},
"type": {
"enum": [
"input_image"
],
"title": "InputImageFunctionCallOutputContentItemType",
"type": "string"
}
},
"required": [
"image_url",
"type"
],
"title": "InputImageFunctionCallOutputContentItem",
"type": "object"
}
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
},
"success": {
"type": [
"boolean",
"null"
]
}
},
"required": [
"body"
],
"type": "object"
},
"GhostCommit": {
"description": "Details of a ghost commit created from a repository state.",
"properties": {
"id": {
"type": "string"
},
"parent": {
"type": [
"string",
"null"
]
},
"preexisting_untracked_dirs": {
"items": {
"type": "string"
},
"type": "array"
},
"preexisting_untracked_files": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"id",
"preexisting_untracked_dirs",
"preexisting_untracked_files"
],
"type": "object"
},
"LocalShellAction": {
"oneOf": [
{
"properties": {
"command": {
"items": {
"type": "string"
},
"type": "array"
},
"env": {
"additionalProperties": {
"type": "string"
},
"type": [
"object",
"null"
]
},
"timeout_ms": {
"format": "uint64",
"minimum": 0.0,
"type": [
"integer",
"null"
]
},
"type": {
"enum": [
"exec"
],
"title": "ExecLocalShellActionType",
"type": "string"
},
"user": {
"type": [
"string",
"null"
]
},
"working_directory": {
"type": [
"string",
"null"
]
}
},
"required": [
"command",
"type"
],
"title": "ExecLocalShellAction",
"type": "object"
}
]
},
"LocalShellStatus": {
"enum": [
"completed",
"in_progress",
"incomplete"
],
"type": "string"
},
"MessagePhase": {
"description": "Classifies an assistant message as interim commentary or final answer text.\n\nProviders do not emit this consistently, so callers must treat `None` as \"phase unknown\" and keep compatibility behavior for legacy models.",
"oneOf": [
{
"description": "Mid-turn assistant text (for example preamble/progress narration).\n\nAdditional tool calls or assistant output may follow before turn completion.",
"enum": [
"commentary"
],
"type": "string"
},
{
"description": "The assistant's terminal answer text for the current turn.",
"enum": [
"final_answer"
],
"type": "string"
}
]
},
"NewConversationParams": {
"properties": {
"approvalPolicy": {
"anyOf": [
{
"$ref": "#/definitions/AskForApproval"
},
{
"type": "null"
}
]
},
"baseInstructions": {
"type": [
"string",
"null"
]
},
"compactPrompt": {
"type": [
"string",
"null"
]
},
"config": {
"additionalProperties": true,
"type": [
"object",
"null"
]
},
"cwd": {
"type": [
"string",
"null"
]
},
"developerInstructions": {
"type": [
"string",
"null"
]
},
"includeApplyPatchTool": {
"type": [
"boolean",
"null"
]
},
"model": {
"type": [
"string",
"null"
]
},
"modelProvider": {
"type": [
"string",
"null"
]
},
"profile": {
"type": [
"string",
"null"
]
},
"sandbox": {
"anyOf": [
{
"$ref": "#/definitions/SandboxMode"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"ReasoningItemContent": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"reasoning_text"
],
"title": "ReasoningTextReasoningItemContentType",
"type": "string"
}
},
"required": [
"text",
"type"
],
"title": "ReasoningTextReasoningItemContent",
"type": "object"
},
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"text"
],
"title": "TextReasoningItemContentType",
"type": "string"
}
},
"required": [
"text",
"type"
],
"title": "TextReasoningItemContent",
"type": "object"
}
]
},
"ReasoningItemReasoningSummary": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"summary_text"
],
"title": "SummaryTextReasoningItemReasoningSummaryType",
"type": "string"
}
},
"required": [
"text",
"type"
],
"title": "SummaryTextReasoningItemReasoningSummary",
"type": "object"
}
]
},
"RejectConfig": {
"properties": {
"mcp_elicitations": {
"description": "Reject MCP elicitation prompts.",
"type": "boolean"
},
"rules": {
"description": "Reject prompts triggered by execpolicy `prompt` rules.",
"type": "boolean"
},
"sandbox_approval": {
"description": "Reject approval prompts related to sandbox escalation.",
"type": "boolean"
}
},
"required": [
"mcp_elicitations",
"rules",
"sandbox_approval"
],
"type": "object"
},
"ResponseItem": {
"oneOf": [
{
"properties": {
"content": {
"items": {
"$ref": "#/definitions/ContentItem"
},
"type": "array"
},
"end_turn": {
"type": [
"boolean",
"null"
]
},
"id": {
"type": [
"string",
"null"
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
"type": {
"enum": [
"message"
],
"title": "MessageResponseItemType",
"type": "string"
}
},
"required": [
"content",
"role",
"type"
],
"title": "MessageResponseItem",
"type": "object"
},
{
"properties": {
"content": {
"default": null,
"items": {
"$ref": "#/definitions/ReasoningItemContent"
},
"type": [
"array",
"null"
]
},
"encrypted_content": {
"type": [
"string",
"null"
]
},
"id": {
"type": "string",
"writeOnly": true
},
"summary": {
"items": {
"$ref": "#/definitions/ReasoningItemReasoningSummary"
},
"type": "array"
},
"type": {
"enum": [
"reasoning"
],
"title": "ReasoningResponseItemType",
"type": "string"
}
},
"required": [
"id",
"summary",
"type"
],
"title": "ReasoningResponseItem",
"type": "object"
},
{
"properties": {
"action": {
"$ref": "#/definitions/LocalShellAction"
},
"call_id": {
"description": "Set when using the Responses API.",
"type": [
"string",
"null"
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"type": [
"string",
"null"
],
"writeOnly": true
},
"status": {
"$ref": "#/definitions/LocalShellStatus"
},
"type": {
"enum": [
"local_shell_call"
],
"title": "LocalShellCallResponseItemType",
"type": "string"
}
},
"required": [
"action",
"status",
"type"
],
"title": "LocalShellCallResponseItem",
"type": "object"
},
{
"properties": {
"arguments": {
"type": "string"
},
"call_id": {
"type": "string"
},
"id": {
"type": [
"string",
"null"
],
"writeOnly": true
},
"name": {
"type": "string"
},
"type": {
"enum": [
"function_call"
],
"title": "FunctionCallResponseItemType",
"type": "string"
}
},
"required": [
"arguments",
"call_id",
"name",
"type"
],
"title": "FunctionCallResponseItem",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"output": {
"$ref": "#/definitions/FunctionCallOutputPayload"
},
"type": {
"enum": [
"function_call_output"
],
"title": "FunctionCallOutputResponseItemType",
"type": "string"
}
},
"required": [
"call_id",
"output",
"type"
],
"title": "FunctionCallOutputResponseItem",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"id": {
"type": [
"string",
"null"
],
"writeOnly": true
},
"input": {
"type": "string"
},
"name": {
"type": "string"
},
"status": {
"type": [
"string",
"null"
]
},
"type": {
"enum": [
"custom_tool_call"
],
"title": "CustomToolCallResponseItemType",
"type": "string"
}
},
"required": [
"call_id",
"input",
"name",
"type"
],
"title": "CustomToolCallResponseItem",
"type": "object"
},
{
"properties": {
"call_id": {
"type": "string"
},
"output": {
"type": "string"
},
"type": {
"enum": [
"custom_tool_call_output"
],
"title": "CustomToolCallOutputResponseItemType",
"type": "string"
}
},
"required": [
"call_id",
"output",
"type"
],
"title": "CustomToolCallOutputResponseItem",
"type": "object"
},
{
"properties": {
"action": {
"anyOf": [
{
"$ref": "#/definitions/WebSearchAction"
},
{
"type": "null"
}
]
},
"id": {
"type": [
"string",
"null"
],
"writeOnly": true
},
"status": {
"type": [
"string",
"null"
]
},
"type": {
"enum": [
"web_search_call"
],
"title": "WebSearchCallResponseItemType",
"type": "string"
}
},
"required": [
"type"
],
"title": "WebSearchCallResponseItem",
"type": "object"
},
{
"properties": {
"ghost_commit": {
"$ref": "#/definitions/GhostCommit"
},
"type": {
"enum": [
"ghost_snapshot"
],
"title": "GhostSnapshotResponseItemType",
"type": "string"
}
},
"required": [
"ghost_commit",
"type"
],
"title": "GhostSnapshotResponseItem",
"type": "object"
},
{
"properties": {
"encrypted_content": {
"type": "string"
},
"type": {
"enum": [
"compaction"
],
"title": "CompactionResponseItemType",
"type": "string"
}
},
"required": [
"encrypted_content",
"type"
],
"title": "CompactionResponseItem",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"other"
],
"title": "OtherResponseItemType",
"type": "string"
}
},
"required": [
"type"
],
"title": "OtherResponseItem",
"type": "object"
}
]
},
"SandboxMode": {
"enum": [
"read-only",
"workspace-write",
"danger-full-access"
],
"type": "string"
},
"ThreadId": {
"type": "string"
},
"WebSearchAction": {
"oneOf": [
{
"properties": {
"queries": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
},
"query": {
"type": [
"string",
"null"
]
},
"type": {
"enum": [
"search"
],
"title": "SearchWebSearchActionType",
"type": "string"
}
},
"required": [
"type"
],
"title": "SearchWebSearchAction",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"open_page"
],
"title": "OpenPageWebSearchActionType",
"type": "string"
},
"url": {
"type": [
"string",
"null"
]
}
},
"required": [
"type"
],
"title": "OpenPageWebSearchAction",
"type": "object"
},
{
"properties": {
"pattern": {
"type": [
"string",
"null"
]
},
"type": {
"enum": [
"find_in_page"
],
"title": "FindInPageWebSearchActionType",
"type": "string"
},
"url": {
"type": [
"string",
"null"
]
}
},
"required": [
"type"
],
"title": "FindInPageWebSearchAction",
"type": "object"
},
{
"properties": {
"type": {
"enum": [
"other"
],
"title": "OtherWebSearchActionType",
"type": "string"
}
},
"required": [
"type"
],
"title": "OtherWebSearchAction",
"type": "object"
}
]
}
},
"properties": {
"conversationId": {
"anyOf": [
{
"$ref": "#/definitions/ThreadId"
},
{
"type": "null"
}
]
},
"history": {
"items": {
"$ref": "#/definitions/ResponseItem"
},
"type": [
"array",
"null"
]
},
"overrides": {
"anyOf": [
{
"$ref": "#/definitions/NewConversationParams"
},
{
"type": "null"
}
]
},
"path": {
"type": [
"string",
"null"
]
}
},
"title": "ResumeConversationParams",
"type": "object"
}
File diff suppressed because it is too large Load Diff
@@ -1,165 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"InputItem": {
"oneOf": [
{
"properties": {
"data": {
"properties": {
"text": {
"type": "string"
},
"text_elements": {
"default": [],
"description": "UI-defined spans within `text` used to render or persist special elements.",
"items": {
"$ref": "#/definitions/V1TextElement"
},
"type": "array"
}
},
"required": [
"text"
],
"type": "object"
},
"type": {
"enum": [
"text"
],
"title": "TextInputItemType",
"type": "string"
}
},
"required": [
"data",
"type"
],
"title": "TextInputItem",
"type": "object"
},
{
"properties": {
"data": {
"properties": {
"image_url": {
"type": "string"
}
},
"required": [
"image_url"
],
"type": "object"
},
"type": {
"enum": [
"image"
],
"title": "ImageInputItemType",
"type": "string"
}
},
"required": [
"data",
"type"
],
"title": "ImageInputItem",
"type": "object"
},
{
"properties": {
"data": {
"properties": {
"path": {
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
},
"type": {
"enum": [
"localImage"
],
"title": "LocalImageInputItemType",
"type": "string"
}
},
"required": [
"data",
"type"
],
"title": "LocalImageInputItem",
"type": "object"
}
]
},
"ThreadId": {
"type": "string"
},
"V1ByteRange": {
"properties": {
"end": {
"description": "End byte offset (exclusive) within the UTF-8 text buffer.",
"format": "uint",
"minimum": 0.0,
"type": "integer"
},
"start": {
"description": "Start byte offset (inclusive) within the UTF-8 text buffer.",
"format": "uint",
"minimum": 0.0,
"type": "integer"
}
},
"required": [
"end",
"start"
],
"type": "object"
},
"V1TextElement": {
"properties": {
"byteRange": {
"allOf": [
{
"$ref": "#/definitions/V1ByteRange"
}
],
"description": "Byte range in the parent `text` buffer that this element occupies."
},
"placeholder": {
"description": "Optional human-readable placeholder for the element, displayed in the UI.",
"type": [
"string",
"null"
]
}
},
"required": [
"byteRange"
],
"type": "object"
}
},
"properties": {
"conversationId": {
"$ref": "#/definitions/ThreadId"
},
"items": {
"items": {
"$ref": "#/definitions/InputItem"
},
"type": "array"
}
},
"required": [
"conversationId",
"items"
],
"title": "SendUserMessageParams",
"type": "object"
}
@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "SendUserMessageResponse",
"type": "object"
}
@@ -1,482 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AbsolutePathBuf": {
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
"type": "string"
},
"AskForApproval": {
"description": "Determines the conditions under which the user is consulted to approve running the command proposed by Codex.",
"oneOf": [
{
"description": "Under this policy, only \"known safe\" commands—as determined by `is_safe_command()`—that **only read files** are autoapproved. Everything else will ask the user to approve.",
"enum": [
"untrusted"
],
"type": "string"
},
{
"description": "DEPRECATED: *All* commands are autoapproved, but they are expected to run inside a sandbox where network access is disabled and writes are confined to a specific set of paths. If the command fails, it will be escalated to the user to approve execution without a sandbox. Prefer `OnRequest` for interactive runs or `Never` for non-interactive runs.",
"enum": [
"on-failure"
],
"type": "string"
},
{
"description": "The model decides when to ask the user for approval.",
"enum": [
"on-request"
],
"type": "string"
},
{
"additionalProperties": false,
"description": "Fine-grained rejection controls for approval prompts.\n\nWhen a field is `true`, prompts of that category are automatically rejected instead of shown to the user.",
"properties": {
"reject": {
"$ref": "#/definitions/RejectConfig"
}
},
"required": [
"reject"
],
"title": "RejectAskForApproval",
"type": "object"
},
{
"description": "Never ask the user to approve commands. Failures are immediately returned to the model, and never escalated to the user for approval.",
"enum": [
"never"
],
"type": "string"
}
]
},
"InputItem": {
"oneOf": [
{
"properties": {
"data": {
"properties": {
"text": {
"type": "string"
},
"text_elements": {
"default": [],
"description": "UI-defined spans within `text` used to render or persist special elements.",
"items": {
"$ref": "#/definitions/V1TextElement"
},
"type": "array"
}
},
"required": [
"text"
],
"type": "object"
},
"type": {
"enum": [
"text"
],
"title": "TextInputItemType",
"type": "string"
}
},
"required": [
"data",
"type"
],
"title": "TextInputItem",
"type": "object"
},
{
"properties": {
"data": {
"properties": {
"image_url": {
"type": "string"
}
},
"required": [
"image_url"
],
"type": "object"
},
"type": {
"enum": [
"image"
],
"title": "ImageInputItemType",
"type": "string"
}
},
"required": [
"data",
"type"
],
"title": "ImageInputItem",
"type": "object"
},
{
"properties": {
"data": {
"properties": {
"path": {
"type": "string"
}
},
"required": [
"path"
],
"type": "object"
},
"type": {
"enum": [
"localImage"
],
"title": "LocalImageInputItemType",
"type": "string"
}
},
"required": [
"data",
"type"
],
"title": "LocalImageInputItem",
"type": "object"
}
]
},
"NetworkAccess": {
"description": "Represents whether outbound network access is available to the agent.",
"enum": [
"restricted",
"enabled"
],
"type": "string"
},
"ReadOnlyAccess": {
"description": "Determines how read-only file access is granted inside a restricted sandbox.",
"oneOf": [
{
"description": "Restrict reads to an explicit set of roots.\n\nWhen `include_platform_defaults` is `true`, platform defaults required for basic execution are included in addition to `readable_roots`.",
"properties": {
"include_platform_defaults": {
"default": true,
"description": "Include built-in platform read roots required for basic process execution.",
"type": "boolean"
},
"readable_roots": {
"description": "Additional absolute roots that should be readable.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": "array"
},
"type": {
"enum": [
"restricted"
],
"title": "RestrictedReadOnlyAccessType",
"type": "string"
}
},
"required": [
"type"
],
"title": "RestrictedReadOnlyAccess",
"type": "object"
},
{
"description": "Allow unrestricted file reads.",
"properties": {
"type": {
"enum": [
"full-access"
],
"title": "FullAccessReadOnlyAccessType",
"type": "string"
}
},
"required": [
"type"
],
"title": "FullAccessReadOnlyAccess",
"type": "object"
}
]
},
"ReasoningEffort": {
"description": "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning",
"enum": [
"none",
"minimal",
"low",
"medium",
"high",
"xhigh"
],
"type": "string"
},
"ReasoningSummary": {
"description": "A summary of the reasoning performed by the model. This can be useful for debugging and understanding the model's reasoning process. See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#reasoning-summaries",
"oneOf": [
{
"enum": [
"auto",
"concise",
"detailed"
],
"type": "string"
},
{
"description": "Option to disable reasoning summaries.",
"enum": [
"none"
],
"type": "string"
}
]
},
"RejectConfig": {
"properties": {
"mcp_elicitations": {
"description": "Reject MCP elicitation prompts.",
"type": "boolean"
},
"rules": {
"description": "Reject prompts triggered by execpolicy `prompt` rules.",
"type": "boolean"
},
"sandbox_approval": {
"description": "Reject approval prompts related to sandbox escalation.",
"type": "boolean"
}
},
"required": [
"mcp_elicitations",
"rules",
"sandbox_approval"
],
"type": "object"
},
"SandboxPolicy": {
"description": "Determines execution restrictions for model shell commands.",
"oneOf": [
{
"description": "No restrictions whatsoever. Use with caution.",
"properties": {
"type": {
"enum": [
"danger-full-access"
],
"title": "DangerFullAccessSandboxPolicyType",
"type": "string"
}
},
"required": [
"type"
],
"title": "DangerFullAccessSandboxPolicy",
"type": "object"
},
{
"description": "Read-only access configuration.",
"properties": {
"access": {
"allOf": [
{
"$ref": "#/definitions/ReadOnlyAccess"
}
],
"description": "Read access granted while running under this policy."
},
"type": {
"enum": [
"read-only"
],
"title": "ReadOnlySandboxPolicyType",
"type": "string"
}
},
"required": [
"type"
],
"title": "ReadOnlySandboxPolicy",
"type": "object"
},
{
"description": "Indicates the process is already in an external sandbox. Allows full disk access while honoring the provided network setting.",
"properties": {
"network_access": {
"allOf": [
{
"$ref": "#/definitions/NetworkAccess"
}
],
"default": "restricted",
"description": "Whether the external sandbox permits outbound network traffic."
},
"type": {
"enum": [
"external-sandbox"
],
"title": "ExternalSandboxSandboxPolicyType",
"type": "string"
}
},
"required": [
"type"
],
"title": "ExternalSandboxSandboxPolicy",
"type": "object"
},
{
"description": "Same as `ReadOnly` but additionally grants write access to the current working directory (\"workspace\").",
"properties": {
"exclude_slash_tmp": {
"default": false,
"description": "When set to `true`, will NOT include the `/tmp` among the default writable roots on UNIX. Defaults to `false`.",
"type": "boolean"
},
"exclude_tmpdir_env_var": {
"default": false,
"description": "When set to `true`, will NOT include the per-user `TMPDIR` environment variable among the default writable roots. Defaults to `false`.",
"type": "boolean"
},
"network_access": {
"default": false,
"description": "When set to `true`, outbound network access is allowed. `false` by default.",
"type": "boolean"
},
"read_only_access": {
"allOf": [
{
"$ref": "#/definitions/ReadOnlyAccess"
}
],
"description": "Read access granted while running under this policy."
},
"type": {
"enum": [
"workspace-write"
],
"title": "WorkspaceWriteSandboxPolicyType",
"type": "string"
},
"writable_roots": {
"description": "Additional folders (beyond cwd and possibly TMPDIR) that should be writable from within the sandbox.",
"items": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"type": "array"
}
},
"required": [
"type"
],
"title": "WorkspaceWriteSandboxPolicy",
"type": "object"
}
]
},
"ThreadId": {
"type": "string"
},
"V1ByteRange": {
"properties": {
"end": {
"description": "End byte offset (exclusive) within the UTF-8 text buffer.",
"format": "uint",
"minimum": 0.0,
"type": "integer"
},
"start": {
"description": "Start byte offset (inclusive) within the UTF-8 text buffer.",
"format": "uint",
"minimum": 0.0,
"type": "integer"
}
},
"required": [
"end",
"start"
],
"type": "object"
},
"V1TextElement": {
"properties": {
"byteRange": {
"allOf": [
{
"$ref": "#/definitions/V1ByteRange"
}
],
"description": "Byte range in the parent `text` buffer that this element occupies."
},
"placeholder": {
"description": "Optional human-readable placeholder for the element, displayed in the UI.",
"type": [
"string",
"null"
]
}
},
"required": [
"byteRange"
],
"type": "object"
}
},
"properties": {
"approvalPolicy": {
"$ref": "#/definitions/AskForApproval"
},
"conversationId": {
"$ref": "#/definitions/ThreadId"
},
"cwd": {
"type": "string"
},
"effort": {
"anyOf": [
{
"$ref": "#/definitions/ReasoningEffort"
},
{
"type": "null"
}
]
},
"items": {
"items": {
"$ref": "#/definitions/InputItem"
},
"type": "array"
},
"model": {
"type": "string"
},
"outputSchema": {
"description": "Optional JSON Schema used to constrain the final assistant message for this turn."
},
"sandboxPolicy": {
"$ref": "#/definitions/SandboxPolicy"
},
"summary": {
"$ref": "#/definitions/ReasoningSummary"
}
},
"required": [
"approvalPolicy",
"conversationId",
"cwd",
"items",
"model",
"sandboxPolicy",
"summary"
],
"title": "SendUserTurnParams",
"type": "object"
}
@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "SendUserTurnResponse",
"type": "object"
}
File diff suppressed because it is too large Load Diff
@@ -1,37 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"ReasoningEffort": {
"description": "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning",
"enum": [
"none",
"minimal",
"low",
"medium",
"high",
"xhigh"
],
"type": "string"
}
},
"properties": {
"model": {
"type": [
"string",
"null"
]
},
"reasoningEffort": {
"anyOf": [
{
"$ref": "#/definitions/ReasoningEffort"
},
{
"type": "null"
}
]
}
},
"title": "SetDefaultModelParams",
"type": "object"
}
@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "SetDefaultModelResponse",
"type": "object"
}
@@ -1,13 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"allegedUserEmail": {
"type": [
"string",
"null"
]
}
},
"title": "UserInfoResponse",
"type": "object"
}
+196 -176
View File
@@ -32,93 +32,41 @@ use std::io::Write;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use std::sync::LazyLock;
use ts_rs::TS;
const HEADER: &str = "// GENERATED CODE! DO NOT MODIFY BY HAND!\n\n";
const IGNORED_DEFINITIONS: &[&str] = &["Option<()>"];
static VARIANT_TITLE_COLLISION_OVERRIDES: LazyLock<HashMap<&'static str, &'static str>> =
LazyLock::new(|| {
HashMap::from([
(
"base=McpStartupStatus|generated=StateMcpStartupStatus|literal:state=ready|only_property=state|required_only=state",
"StateMcpStartupStatus2",
),
(
"base=McpStartupStatus|generated=StateMcpStartupStatus|literal:state=cancelled|only_property=state|required_only=state",
"StateMcpStartupStatus3",
),
])
});
static NUMBERED_DEFINITION_COLLISION_OVERRIDES: LazyLock<HashMap<&'static str, &'static str>> =
LazyLock::new(|| {
HashMap::from([
(
"schema=ClientRequest|container=definitions|generated=AskForApproval2|base=AskForApproval",
"AskForApproval2",
),
(
"schema=ClientRequest|container=definitions|generated=NetworkAccess2|base=NetworkAccess",
"NetworkAccess2",
),
(
"schema=ClientRequest|container=definitions|generated=ReadOnlyAccess2|base=ReadOnlyAccess",
"ReadOnlyAccess2",
),
(
"schema=ClientRequest|container=definitions|generated=SandboxMode2|base=SandboxMode",
"SandboxMode2",
),
(
"schema=ClientRequest|container=definitions|generated=SandboxPolicy2|base=SandboxPolicy",
"SandboxPolicy2",
),
(
"schema=ServerNotification|container=definitions|generated=ByteRange2|base=ByteRange",
"ByteRange2",
),
(
"schema=ServerNotification|container=definitions|generated=CodexErrorInfo2|base=CodexErrorInfo",
"CodexErrorInfo2",
),
(
"schema=ServerNotification|container=definitions|generated=CreditsSnapshot2|base=CreditsSnapshot",
"CreditsSnapshot2",
),
(
"schema=ServerNotification|container=definitions|generated=MessagePhase2|base=MessagePhase",
"MessagePhase2",
),
(
"schema=ServerNotification|container=definitions|generated=ModelRerouteReason2|base=ModelRerouteReason",
"ModelRerouteReason2",
),
(
"schema=ServerNotification|container=definitions|generated=PatchApplyStatus2|base=PatchApplyStatus",
"PatchApplyStatus2",
),
(
"schema=ServerNotification|container=definitions|generated=RateLimitSnapshot2|base=RateLimitSnapshot",
"RateLimitSnapshot2",
),
(
"schema=ServerNotification|container=definitions|generated=RateLimitWindow2|base=RateLimitWindow",
"RateLimitWindow2",
),
(
"schema=ServerNotification|container=definitions|generated=TextElement2|base=TextElement",
"TextElement2",
),
(
"schema=ServerNotification|container=definitions|generated=UserInput2|base=UserInput",
"UserInput2",
),
(
"schema=ServerNotification|container=definitions|generated=WebSearchAction2|base=WebSearchAction",
"WebSearchAction2",
),
])
});
const JSON_V1_ALLOWLIST: &[&str] = &["InitializeParams", "InitializeResponse"];
const V1_CLIENT_REQUEST_METHODS: &[&str] = &[
"newConversation",
"getConversationSummary",
"listConversations",
"resumeConversation",
"forkConversation",
"archiveConversation",
"sendUserMessage",
"sendUserTurn",
"interruptConversation",
"addConversationListener",
"removeConversationListener",
"gitDiffToRemote",
"loginApiKey",
"loginChatGpt",
"cancelLoginChatGpt",
"logoutChatGpt",
"getAuthStatus",
"getUserSavedConfig",
"setDefaultModel",
"getUserAgent",
"userInfo",
"execOneOffCommand",
];
const EXCLUDED_SERVER_NOTIFICATION_METHODS_FOR_JSON: &[&str] = &[
"authStatusChange",
"loginChatGptComplete",
"sessionConfigured",
"rawResponseItem/completed",
];
#[derive(Clone)]
pub struct GeneratedSchema {
@@ -264,6 +212,8 @@ pub fn generate_json_with_experimental(out_dir: &Path, experimental_api: bool) -
schemas.extend(export_server_response_schemas(out_dir)?);
schemas.extend(export_client_notification_schemas(out_dir)?);
schemas.extend(export_server_notification_schemas(out_dir)?);
schemas
.retain(|schema| !schema.in_v1_dir || JSON_V1_ALLOWLIST.contains(&schema.logical_name()));
let mut bundle = build_schema_bundle(schemas)?;
if !experimental_api {
@@ -1031,14 +981,23 @@ where
T: JsonSchema,
{
let file_stem = name.trim();
let (raw_namespace, logical_name) = split_namespace(file_stem);
let include_in_json_codegen =
raw_namespace != Some("v1") || JSON_V1_ALLOWLIST.contains(&logical_name);
let schema = schema_for!(T);
let mut schema_value = serde_json::to_value(schema)?;
enforce_numbered_definition_collision_overrides(file_stem, &mut schema_value);
annotate_schema(&mut schema_value, Some(file_stem));
if include_in_json_codegen {
if file_stem == "ClientRequest" {
strip_v1_client_request_variants_from_json_schema(&mut schema_value);
} else if file_stem == "ServerNotification" {
strip_v1_server_notification_variants_from_json_schema(&mut schema_value);
}
enforce_numbered_definition_collision_overrides(file_stem, &mut schema_value);
annotate_schema(&mut schema_value, Some(file_stem));
}
// If the name looks like a namespaced path (e.g., "v2::Type"), mirror
// the TypeScript layout and write to out_dir/v2/Type.json. Otherwise
// write alongside the legacy files.
let (raw_namespace, logical_name) = split_namespace(file_stem);
let out_path = if let Some(ns) = raw_namespace {
let dir = out_dir.join(ns);
ensure_dir(&dir)?;
@@ -1047,7 +1006,7 @@ where
out_dir.join(format!("{file_stem}.json"))
};
if !IGNORED_DEFINITIONS.contains(&logical_name) {
if include_in_json_codegen && !IGNORED_DEFINITIONS.contains(&logical_name) {
write_pretty_json(out_path, &schema_value)
.with_context(|| format!("Failed to write JSON schema for {file_stem}"))?;
}
@@ -1066,96 +1025,162 @@ where
fn enforce_numbered_definition_collision_overrides(schema_name: &str, schema: &mut Value) {
for defs_key in ["definitions", "$defs"] {
let renames = {
let Some(defs) = schema.get(defs_key).and_then(Value::as_object) else {
continue;
};
collect_numbered_definition_collision_renames(schema_name, defs_key, defs)
};
if renames.is_empty() {
let Some(defs) = schema.get(defs_key).and_then(Value::as_object) else {
continue;
}
#[expect(clippy::expect_used)]
let defs = schema
.get_mut(defs_key)
.and_then(Value::as_object_mut)
.expect("definition map should still be present");
for (old_name, new_name, collision_key) in &renames {
if old_name == new_name {
continue;
}
assert!(
!defs.contains_key(new_name),
"Numbered definition collision override produced duplicate definition {new_name} for {collision_key}",
);
let schema_value = defs.remove(old_name).unwrap_or_else(|| {
panic!("Missing generated numbered definition {old_name} for {collision_key}")
});
defs.insert(new_name.clone(), schema_value);
}
for (old_name, new_name, _) in renames {
if old_name != new_name {
rewrite_named_local_ref(schema, defs_key, &old_name, &new_name);
}
}
};
detect_numbered_definition_collisions(schema_name, defs_key, defs);
}
}
fn collect_numbered_definition_collision_renames(
fn strip_v1_client_request_variants_from_json_schema(schema: &mut Value) {
let v1_methods: HashSet<&str> = V1_CLIENT_REQUEST_METHODS.iter().copied().collect();
strip_method_variants_from_json_schema(schema, &v1_methods);
}
fn strip_v1_server_notification_variants_from_json_schema(schema: &mut Value) {
let methods: HashSet<&str> = EXCLUDED_SERVER_NOTIFICATION_METHODS_FOR_JSON
.iter()
.copied()
.collect();
strip_method_variants_from_json_schema(schema, &methods);
}
fn strip_method_variants_from_json_schema(schema: &mut Value, methods_to_remove: &HashSet<&str>) {
{
let Some(root) = schema.as_object_mut() else {
return;
};
let Some(Value::Array(variants)) = root.get_mut("oneOf") else {
return;
};
variants.retain(|variant| !is_method_variant_in_set(variant, methods_to_remove));
}
let reachable = reachable_local_definitions(schema, "definitions");
let Some(root) = schema.as_object_mut() else {
return;
};
if let Some(definitions) = root.get_mut("definitions").and_then(Value::as_object_mut) {
definitions.retain(|name, _| reachable.contains(name));
}
}
fn is_method_variant_in_set(value: &Value, methods: &HashSet<&str>) -> bool {
let Value::Object(map) = value else {
return false;
};
let Some(properties) = map.get("properties").and_then(Value::as_object) else {
return false;
};
let Some(method_schema) = properties.get("method") else {
return false;
};
let Some(method) = string_literal(method_schema) else {
return false;
};
methods.contains(method)
}
fn reachable_local_definitions(schema: &Value, defs_key: &str) -> HashSet<String> {
let Some(definitions) = schema.get(defs_key).and_then(Value::as_object) else {
return HashSet::new();
};
let mut queue: Vec<String> = Vec::new();
let mut reachable: HashSet<String> = HashSet::new();
collect_local_definition_refs_excluding_maps(schema, defs_key, &mut queue, &mut reachable);
while let Some(name) = queue.pop() {
if let Some(def_schema) = definitions.get(&name) {
collect_local_definition_refs(def_schema, defs_key, &mut queue, &mut reachable);
}
}
reachable
}
fn collect_local_definition_refs_excluding_maps(
value: &Value,
defs_key: &str,
queue: &mut Vec<String>,
reachable: &mut HashSet<String>,
) {
match value {
Value::Object(map) => {
for (key, child) in map {
if key == defs_key || key == "$defs" || key == "definitions" {
continue;
}
collect_local_definition_refs_excluding_maps(child, defs_key, queue, reachable);
}
}
Value::Array(items) => {
for child in items {
collect_local_definition_refs_excluding_maps(child, defs_key, queue, reachable);
}
}
_ => {}
}
collect_local_definition_ref_here(value, defs_key, queue, reachable);
}
fn collect_local_definition_refs(
value: &Value,
defs_key: &str,
queue: &mut Vec<String>,
reachable: &mut HashSet<String>,
) {
collect_local_definition_ref_here(value, defs_key, queue, reachable);
match value {
Value::Object(map) => {
for child in map.values() {
collect_local_definition_refs(child, defs_key, queue, reachable);
}
}
Value::Array(items) => {
for child in items {
collect_local_definition_refs(child, defs_key, queue, reachable);
}
}
_ => {}
}
}
fn collect_local_definition_ref_here(
value: &Value,
defs_key: &str,
queue: &mut Vec<String>,
reachable: &mut HashSet<String>,
) {
let Some(reference) = value
.as_object()
.and_then(|obj| obj.get("$ref"))
.and_then(Value::as_str)
else {
return;
};
let Some(name) = reference.strip_prefix(&format!("#/{defs_key}/")) else {
return;
};
let name = name.split('/').next().unwrap_or(name);
if reachable.insert(name.to_string()) {
queue.push(name.to_string());
}
}
fn detect_numbered_definition_collisions(
schema_name: &str,
defs_key: &str,
defs: &Map<String, Value>,
) -> Vec<(String, String, String)> {
let mut renames = Vec::new();
) {
for generated_name in defs.keys() {
let base_name = generated_name.trim_end_matches(|c: char| c.is_ascii_digit());
if base_name == generated_name || !defs.contains_key(base_name) {
continue;
}
let collision_key = format!(
"schema={schema_name}|container={defs_key}|generated={generated_name}|base={base_name}"
panic!(
"Numbered definition naming collision detected: schema={schema_name}|container={defs_key}|generated={generated_name}|base={base_name}"
);
let replacement = NUMBERED_DEFINITION_COLLISION_OVERRIDES
.get(collision_key.as_str())
.map(|value| (*value).to_string())
.unwrap_or_else(|| {
panic!("Missing numbered definition collision override for {collision_key}")
});
renames.push((generated_name.clone(), replacement, collision_key));
}
renames
}
fn rewrite_named_local_ref(value: &mut Value, defs_key: &str, old_name: &str, new_name: &str) {
let direct = format!("#/{defs_key}/{old_name}");
let prefixed = format!("{direct}/");
let replacement = format!("#/{defs_key}/{new_name}");
let replacement_prefixed = format!("{replacement}/");
match value {
Value::Object(obj) => {
if let Some(Value::String(reference)) = obj.get_mut("$ref") {
if reference == &direct {
*reference = replacement;
} else if let Some(rest) = reference.strip_prefix(&prefixed) {
*reference = format!("{replacement_prefixed}{rest}");
}
}
for child in obj.values_mut() {
rewrite_named_local_ref(child, defs_key, old_name, new_name);
}
}
Value::Array(items) => {
for child in items {
rewrite_named_local_ref(child, defs_key, old_name, new_name);
}
}
_ => {}
}
}
@@ -1263,7 +1288,11 @@ fn variant_definition_name(base: &str, variant: &Value) -> Option<String> {
if props.len() == 1
&& let Some(key) = props.keys().next()
{
let pascal = to_pascal_case(key);
let pascal = props
.get(key)
.and_then(string_literal)
.map(to_pascal_case)
.unwrap_or_else(|| to_pascal_case(key));
return Some(format!("{pascal}{base}"));
}
}
@@ -1376,20 +1405,11 @@ fn annotate_variant_list(variants: &mut [Value], base: Option<&str>) {
&& let Some(base_name) = base
&& let Some(name) = variant_definition_name(base_name, variant)
{
let mut candidate = name.clone();
let candidate = name.clone();
if seen.contains(&candidate) {
let collision_key = variant_title_collision_key(base_name, &name, variant);
candidate = VARIANT_TITLE_COLLISION_OVERRIDES
.get(collision_key.as_str())
.map(|value| (*value).to_string())
.unwrap_or_else(|| {
panic!(
"Missing variant title collision override for {collision_key} (generated name: {name})"
)
});
assert!(
!seen.contains(&candidate),
"Variant title collision override produced duplicate title {candidate} for {collision_key}",
panic!(
"Variant title naming collision detected: {collision_key} (generated name: {name})"
);
}
if let Some(obj) = variant.as_object_mut() {