openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
875 lines (874 loc) • 28.8 kB
JavaScript
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { normalizeOpenAIServiceTier, supportsOpenAIResponsesFastMode } from "openclaw/plugin-sdk/provider-model-metadata";
//#region extensions/openai/base-url.ts
const OPENAI_CODEX_RESPONSES_BASE_URL = "https://chatgpt.com/backend-api/codex";
const OPENAI_CODEX_MODELS_ENDPOINT = `${OPENAI_CODEX_RESPONSES_BASE_URL}/models?client_version=0.160.0`;
const OPENAI_PLATFORM_PATHS = /* @__PURE__ */ new Set([
"/",
"/v1",
"/v1/"
]);
const OPENAI_CHATGPT_PATHS = /* @__PURE__ */ new Set([
"/backend-api",
"/backend-api/",
"/backend-api/v1",
"/backend-api/v1/",
"/backend-api/codex",
"/backend-api/codex/",
"/backend-api/codex/v1",
"/backend-api/codex/v1/",
"/backend-api/codex/responses",
"/backend-api/codex/responses/"
]);
/** Classifies exact native endpoints, valid custom URLs, and unsafe/invalid input. */
function classifyOpenAIBaseUrl(baseUrl) {
if (baseUrl === void 0 || baseUrl === null || baseUrl === "") return "unresolved";
if (typeof baseUrl !== "string") return "invalid";
const trimmed = baseUrl.trim();
if (!trimmed) return "unresolved";
try {
const url = new URL(trimmed);
if (url.protocol !== "http:" && url.protocol !== "https:" || !url.hostname || url.username || url.password) return "invalid";
const rawHost = url.hostname.toLowerCase();
const host = rawHost.endsWith(".") ? rawHost.slice(0, -1) : rawHost;
if (host === "api.openai.com" || host === "chatgpt.com") {
if (url.protocol !== "https:" || url.port || url.search || url.hash) return "invalid";
if (host === "api.openai.com" && OPENAI_PLATFORM_PATHS.has(url.pathname)) return "platform";
if (host === "chatgpt.com" && OPENAI_CHATGPT_PATHS.has(url.pathname)) return "chatgpt";
return "invalid";
}
return "custom";
} catch {
return "invalid";
}
}
function resolveOpenAIDefaultBaseUrl(env = process.env) {
return normalizeOptionalString(env.OPENAI_BASE_URL) ?? "https://api.openai.com/v1";
}
function isOpenAIApiBaseUrl(baseUrl) {
return classifyOpenAIBaseUrl(baseUrl) === "platform";
}
function isOpenAICodexBaseUrl(baseUrl) {
return classifyOpenAIBaseUrl(baseUrl) === "chatgpt";
}
//#endregion
//#region extensions/openai/model-route-contract.ts
const OPENAI_CHAT_LATEST_MODEL_ID = "chat-latest";
const OPENAI_DAYBREAK_MODEL_IDS = ["gpt-daybreak-blue-latest", "gpt-daybreak-red-latest"];
const OPENAI_GPT_6_MODEL_IDS = [
"gpt-6-astra",
"gpt-6-sol",
"gpt-6-luna",
"gpt-6.1-sol"
];
const OPENAI_GPT_56_MODEL_ID = "gpt-5.6";
const OPENAI_GPT_56_SOL_MODEL_ID = "gpt-5.6-sol";
const OPENAI_GPT_56_TERRA_MODEL_ID = "gpt-5.6-terra";
const OPENAI_GPT_56_LUNA_MODEL_ID = "gpt-5.6-luna";
const OPENAI_GPT_55_MODEL_ID = "gpt-5.5";
const OPENAI_GPT_55_PRO_MODEL_ID = "gpt-5.5-pro";
const OPENAI_GPT_54_MODEL_ID = "gpt-5.4";
const OPENAI_GPT_54_LEGACY_MODEL_ID = "gpt-5.4-codex";
const OPENAI_GPT_54_PRO_MODEL_ID = "gpt-5.4-pro";
const OPENAI_GPT_54_MINI_MODEL_ID = "gpt-5.4-mini";
const OPENAI_GPT_54_NANO_MODEL_ID = "gpt-5.4-nano";
const OPENAI_GPT_53_CODEX_SPARK_MODEL_ID = "gpt-5.3-codex-spark";
const OPENAI_GPT_56_VARIANT_MODEL_IDS = [
OPENAI_GPT_56_SOL_MODEL_ID,
OPENAI_GPT_56_TERRA_MODEL_ID,
OPENAI_GPT_56_LUNA_MODEL_ID
];
const OPENAI_CODEX_REASONING_EFFORT_ORDER = [
"low",
"medium",
"high",
"xhigh",
"max",
"ultra"
];
const OPENAI_CODEX_REASONING_EFFORTS_BY_MODEL = /* @__PURE__ */ new Map([
[OPENAI_GPT_56_SOL_MODEL_ID, OPENAI_CODEX_REASONING_EFFORT_ORDER],
[OPENAI_GPT_56_TERRA_MODEL_ID, OPENAI_CODEX_REASONING_EFFORT_ORDER],
[OPENAI_GPT_56_LUNA_MODEL_ID, OPENAI_CODEX_REASONING_EFFORT_ORDER.slice(0, -1)]
]);
/** Models with known first-party Platform and ChatGPT transports. */
const OPENAI_DUAL_ROUTE_MODEL_IDS = [
...OPENAI_GPT_6_MODEL_IDS,
...OPENAI_GPT_56_VARIANT_MODEL_IDS,
OPENAI_GPT_55_MODEL_ID,
OPENAI_GPT_55_PRO_MODEL_ID,
OPENAI_GPT_54_MODEL_ID,
OPENAI_GPT_54_PRO_MODEL_ID,
OPENAI_GPT_54_MINI_MODEL_ID
];
/** Direct aliases excluded from the ChatGPT catalog. */
const OPENAI_PLATFORM_ONLY_ROUTE_MODEL_IDS = [OPENAI_CHAT_LATEST_MODEL_ID, OPENAI_GPT_56_MODEL_ID];
const OPENAI_SUBSCRIPTION_ONLY_ROUTE_MODEL_IDS = [OPENAI_GPT_53_CODEX_SPARK_MODEL_ID];
/** Modern model refs recognized by the unified OpenAI provider surface. */
const OPENAI_PROVIDER_MODERN_MODEL_IDS = [
...OPENAI_PLATFORM_ONLY_ROUTE_MODEL_IDS,
...OPENAI_DUAL_ROUTE_MODEL_IDS,
OPENAI_GPT_54_NANO_MODEL_ID,
...OPENAI_SUBSCRIPTION_ONLY_ROUTE_MODEL_IDS
];
const OPENAI_CHATGPT_MODERN_MODEL_IDS = [...OPENAI_DUAL_ROUTE_MODEL_IDS, ...OPENAI_SUBSCRIPTION_ONLY_ROUTE_MODEL_IDS];
new Set(OPENAI_DUAL_ROUTE_MODEL_IDS);
const openAIPlatformOnlyRouteModelIds = new Set(OPENAI_PLATFORM_ONLY_ROUTE_MODEL_IDS);
const openAISubscriptionOnlyRouteModelIds = new Set(OPENAI_SUBSCRIPTION_ONLY_ROUTE_MODEL_IDS);
function normalizeOpenAIModelRouteId(value) {
const modelId = value?.trim() ?? "";
const normalized = modelId.toLowerCase();
return normalized === "gpt-5.4-codex" || normalized === `openai/gpt-5.4-codex` ? OPENAI_GPT_54_MODEL_ID : modelId;
}
function normalizeOpenAIRouteMembershipId(value) {
return normalizeOpenAIModelRouteId(value).toLowerCase();
}
/**
* Merge live Codex observations with first-party model capabilities.
* An explicit empty list remains authoritative; partial non-empty observations
* cannot erase capabilities known by every other OpenAI model surface.
*/
function resolveOpenAICodexReasoningEfforts(modelId, observed) {
const known = OPENAI_CODEX_REASONING_EFFORTS_BY_MODEL.get(normalizeOpenAIRouteMembershipId(modelId));
if (!known) return observed ? [...observed] : void 0;
if (observed === void 0 || observed.length === 0) return observed ? [] : [...known];
const extraEfforts = observed.map((effort) => effort.trim().toLowerCase()).filter((effort) => effort && !OPENAI_CODEX_REASONING_EFFORT_ORDER.some((level) => level === effort));
return [...known, ...new Set(extraEfforts)];
}
function isOpenAIPlatformOnlyRouteModelId(value) {
return openAIPlatformOnlyRouteModelIds.has(normalizeOpenAIRouteMembershipId(value));
}
function isOpenAISubscriptionOnlyRouteModelId(value) {
return openAISubscriptionOnlyRouteModelIds.has(normalizeOpenAIRouteMembershipId(value));
}
function buildOpenAIUnknownModelHint(modelId) {
if (modelId.trim().toLowerCase() !== "gpt-5.3-codex-spark") return;
return "gpt-5.3-codex-spark is available only through ChatGPT/Codex OAuth. Run `openclaw models auth login --provider openai` and use openai/gpt-5.3-codex-spark with that OAuth profile; OpenAI API-key auth cannot use this model.";
}
//#endregion
//#region extensions/openai/realtime-quicksilver.ts
const OPENAI_GPT_LIVE_MODEL_PREFIX = "gpt-live";
const OPENAI_GPT_LIVE_MODELS = ["gpt-live-1", "gpt-live-1-codex"];
const OPENAI_GPT_LIVE_API_VOICES = [
"alloy",
"ash",
"ballad",
"beacon",
"bossa",
"cedar",
"cinder",
"coral",
"delta",
"echo",
"gleam",
"marin",
"meridian",
"quartz",
"ripple",
"sage",
"shimmer",
"stone",
"tempo",
"verse",
"vesper",
"willow"
];
const OPENAI_GPT_LIVE_VOICES = [
"arbor",
"breeze",
"cove",
"ember",
"juniper",
"maple",
"sol",
"spruce",
"vale"
];
const OPENAI_GPT_LIVE_UNLISTED_VOICES = ["marin", "cedar"];
function isOpenAIGptLiveApiModel(model) {
return model?.trim().toLowerCase() === "gpt-live-1";
}
function isOpenAIGptLiveSubscriptionModel(model) {
return model?.trim().toLowerCase() === "gpt-live-1-codex";
}
function isSupportedOpenAIGptLiveModel(model) {
return isOpenAIGptLiveApiModel(model) || isOpenAIGptLiveSubscriptionModel(model);
}
function resolveOpenAIQuicksilverVoice(model, value) {
const voices = resolveOpenAIQuicksilverVoices(model);
const defaultVoice = isOpenAIGptLiveSubscriptionModel(model) ? "cove" : "marin";
const normalized = normalizeOptionalLowercaseString(value);
return voices.find((voice) => voice === normalized) ?? defaultVoice;
}
function resolveOpenAIQuicksilverVoices(model) {
if (isOpenAIGptLiveApiModel(model)) return OPENAI_GPT_LIVE_API_VOICES;
return isOpenAIGptLiveSubscriptionModel(model) ? OPENAI_GPT_LIVE_VOICES : OPENAI_GPT_LIVE_UNLISTED_VOICES;
}
function isOpenAIGptLiveModel(model) {
if (!model) return false;
const normalized = model.trim().toLowerCase();
return normalized === OPENAI_GPT_LIVE_MODEL_PREFIX || normalized.startsWith(`${OPENAI_GPT_LIVE_MODEL_PREFIX}-`);
}
const OPENAI_QUICKSILVER_CAPABILITIES = {
transports: ["webrtc", "gateway-relay"],
handlesAgentConsult: true,
supportsBargeIn: false,
handlesInputAudioBargeIn: true,
supportsActivationNameGating: false,
supportsToolCalls: false,
supportsVideoFrames: false
};
function resolveOpenAIQuicksilverVoiceCapabilities(model) {
return {
voices: resolveOpenAIQuicksilverVoices(model),
voiceSelectionPolicy: "allowlist-default"
};
}
//#endregion
//#region extensions/openai/service-tier-policy.ts
/** Alias capabilities are independent of the snapshot behind each Daybreak name. */
function resolveOpenAIModelServiceTiers(params) {
if (params.api !== "openai-responses" || classifyOpenAIBaseUrl(params.baseUrl) !== "platform") return;
const [blue, red] = OPENAI_DAYBREAK_MODEL_IDS;
return params.modelId === blue ? ["default", "priority"] : params.modelId === red ? ["default"] : void 0;
}
//#endregion
//#region extensions/openai/openclaw.plugin.json
var modelCatalog = {
"modelsDev": { "openai": "openai" },
"providers": { "openai": {
"baseUrl": "https://api.openai.com/v1",
"api": "openai-responses",
"defaultUtilityModel": "gpt-5.6-luna",
"models": [
{
"id": "gpt-daybreak-blue-latest",
"name": "Daybreak Blue",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"thinkingLevelMap": {
"off": null,
"minimal": "low",
"xhigh": "xhigh",
"max": "max"
},
"compat": {
"supportsReasoningEffort": true,
"supportedReasoningEfforts": [
"low",
"medium",
"high",
"xhigh",
"max"
],
"supportsTemperature": false
}
},
{
"id": "gpt-daybreak-red-latest",
"name": "Daybreak Red",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 4e5,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 0,
"output": 0,
"cacheRead": 0,
"cacheWrite": 0
},
"thinkingLevelMap": {
"off": "none",
"minimal": "low",
"xhigh": "xhigh",
"max": "max"
},
"compat": {
"supportsReasoningEffort": true,
"supportedReasoningEfforts": [
"none",
"low",
"medium",
"high",
"xhigh",
"max"
],
"supportsTemperature": false
}
},
{
"id": "gpt-6-astra",
"name": "GPT-6 Astra",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 10,
"output": 50,
"cacheRead": 1,
"cacheWrite": 12.5,
"tieredPricing": [{
"range": [0, 272001],
"input": 10,
"output": 50,
"cacheRead": 1,
"cacheWrite": 12.5
}, {
"range": [272001],
"input": 20,
"output": 75,
"cacheRead": 2,
"cacheWrite": 25
}]
},
"thinkingLevelMap": {
"off": null,
"minimal": "low",
"xhigh": "xhigh",
"max": "max"
},
"compat": {
"supportsReasoningEffort": true,
"supportedReasoningEfforts": [
"low",
"medium",
"high",
"xhigh",
"max"
],
"supportsTemperature": false,
"codeMode": "preferred"
}
},
{
"id": "gpt-6.1-sol",
"name": "GPT-6.1 Sol",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 2,
"output": 10,
"cacheRead": .1,
"cacheWrite": 2.5,
"tieredPricing": [{
"range": [0, 272001],
"input": 2,
"output": 10,
"cacheRead": .1,
"cacheWrite": 2.5
}, {
"range": [272001],
"input": 4,
"output": 15,
"cacheRead": .2,
"cacheWrite": 5
}]
},
"thinkingLevelMap": {
"off": null,
"minimal": "low",
"xhigh": "xhigh",
"max": "max"
},
"compat": {
"supportsReasoningEffort": true,
"supportedReasoningEfforts": [
"low",
"medium",
"high",
"xhigh",
"max"
],
"supportsTemperature": false,
"codeMode": "preferred"
}
},
{
"id": "gpt-6-sol",
"name": "GPT-6 Sol",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 2,
"output": 10,
"cacheRead": .2,
"cacheWrite": 2.5,
"tieredPricing": [{
"range": [0, 272001],
"input": 2,
"output": 10,
"cacheRead": .2,
"cacheWrite": 2.5
}, {
"range": [272001],
"input": 4,
"output": 15,
"cacheRead": .4,
"cacheWrite": 5
}]
},
"thinkingLevelMap": {
"off": "none",
"minimal": "low",
"xhigh": "xhigh",
"max": "max"
},
"compat": {
"supportsReasoningEffort": true,
"supportedReasoningEfforts": [
"none",
"low",
"medium",
"high",
"xhigh",
"max"
],
"supportsTemperature": false,
"codeMode": "preferred"
}
},
{
"id": "gpt-6-luna",
"name": "GPT-6 Luna",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": .1,
"output": .5,
"cacheRead": .01,
"cacheWrite": .125,
"tieredPricing": [{
"range": [0, 272001],
"input": .1,
"output": .5,
"cacheRead": .01,
"cacheWrite": .125
}, {
"range": [272001],
"input": .2,
"output": .75,
"cacheRead": .02,
"cacheWrite": .25
}]
},
"thinkingLevelMap": {
"off": "none",
"minimal": "low",
"xhigh": "xhigh",
"max": "max"
},
"compat": {
"supportsReasoningEffort": true,
"supportedReasoningEfforts": [
"none",
"low",
"medium",
"high",
"xhigh",
"max"
],
"supportsTemperature": false,
"codeMode": "preferred"
}
},
{
"id": "gpt-5.6-sol",
"name": "GPT-5.6 Sol",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 5,
"output": 30,
"cacheRead": .5,
"cacheWrite": 6.25
},
"thinkingLevelMap": {
"off": "none",
"xhigh": "xhigh",
"max": "max"
},
"compat": {
"supportsReasoningEffort": true,
"supportedReasoningEfforts": [
"none",
"low",
"medium",
"high",
"xhigh",
"max"
],
"supportsTemperature": false,
"codeMode": "preferred"
}
},
{
"id": "gpt-5.6-terra",
"name": "GPT-5.6 Terra",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 2.5,
"output": 15,
"cacheRead": .25,
"cacheWrite": 3.125
},
"thinkingLevelMap": {
"off": "none",
"xhigh": "xhigh",
"max": "max"
},
"compat": {
"supportsReasoningEffort": true,
"supportedReasoningEfforts": [
"none",
"low",
"medium",
"high",
"xhigh",
"max"
],
"supportsTemperature": false,
"codeMode": "preferred"
}
},
{
"id": "gpt-5.6-luna",
"name": "GPT-5.6 Luna",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 1,
"output": 6,
"cacheRead": .1,
"cacheWrite": 1.25
},
"thinkingLevelMap": {
"off": "none",
"xhigh": "xhigh",
"max": "max"
},
"compat": {
"supportsReasoningEffort": true,
"supportedReasoningEfforts": [
"none",
"low",
"medium",
"high",
"xhigh",
"max"
],
"supportsTemperature": false,
"codeMode": "preferred"
}
},
{
"id": "gpt-5.5",
"name": "GPT-5.5",
"status": "deprecated",
"replacedBy": "gpt-5.6-sol",
"reasoning": true,
"input": ["text", "image"],
"mediaInput": { "image": {
"maxSidePx": 6e3,
"preferredSidePx": 2048,
"tokenMode": "detail"
} },
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 5,
"output": 30,
"cacheRead": .5,
"cacheWrite": 0
},
"compat": { "codeMode": "preferred" }
},
{
"id": "gpt-5.5-pro",
"name": "gpt-5.5-pro",
"status": "deprecated",
"replacedBy": "gpt-5.6-sol",
"reasoning": true,
"input": ["text", "image"],
"mediaInput": { "image": {
"maxSidePx": 6e3,
"preferredSidePx": 2048,
"tokenMode": "detail"
} },
"contextWindow": 105e4,
"contextTokens": 272e3,
"maxTokens": 128e3,
"cost": {
"input": 30,
"output": 180,
"cacheRead": 0,
"cacheWrite": 0
},
"compat": { "codeMode": "preferred" }
},
{
"id": "gpt-5.4",
"name": "GPT-5.4",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"maxTokens": 128e3,
"cost": {
"input": 2.5,
"output": 15,
"cacheRead": .25,
"cacheWrite": 0
}
},
{
"id": "gpt-5.4-pro",
"name": "GPT-5.4 Pro",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 105e4,
"maxTokens": 128e3,
"cost": {
"input": 30,
"output": 180,
"cacheRead": 0,
"cacheWrite": 0
}
},
{
"id": "gpt-5.4-mini",
"name": "GPT-5.4 Mini",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 4e5,
"maxTokens": 128e3,
"cost": {
"input": .75,
"output": 4.5,
"cacheRead": .075,
"cacheWrite": 0
}
},
{
"id": "gpt-5.4-nano",
"name": "GPT-5.4 Nano",
"reasoning": true,
"input": ["text", "image"],
"contextWindow": 4e5,
"maxTokens": 128e3,
"cost": {
"input": .2,
"output": 1.25,
"cacheRead": .02,
"cacheWrite": 0
}
}
]
} },
"aliases": { "azure-openai-responses": {
"provider": "openai",
"api": "azure-openai-responses"
} },
"discovery": { "openai": "runtime" },
"suppressions": [
{
"provider": "openai",
"model": "gpt-5.4",
"reason": "GPT-5.4 has retired from the ChatGPT-account Codex route.",
"retirement": { "replacedBy": "gpt-5.6-terra" },
"when": { "baseUrlHosts": ["chatgpt.com"] }
},
{
"provider": "openai",
"model": "gpt-5.4-mini",
"reason": "GPT-5.4 Mini has retired from the ChatGPT-account Codex route.",
"retirement": { "replacedBy": "gpt-5.6-luna" },
"when": { "baseUrlHosts": ["chatgpt.com"] }
},
{
"provider": "openai",
"model": "gpt-5.3-codex-spark",
"reason": "gpt-5.3-codex-spark is available only through ChatGPT/Codex OAuth. Run `openclaw models auth login --provider openai` and use openai/gpt-5.3-codex-spark with that OAuth profile; OpenAI API-key auth cannot use this model.",
"when": { "baseUrlHosts": ["api.openai.com"] }
},
{
"provider": "azure-openai-responses",
"model": "gpt-5.3-codex-spark",
"reason": "gpt-5.3-codex-spark is available only through ChatGPT/Codex OAuth. Run `openclaw models auth login --provider openai` and use openai/gpt-5.3-codex-spark with that OAuth profile; Azure/OpenAI API-key auth cannot use this model."
}
]
};
//#endregion
//#region extensions/openai/thinking-policy.ts
const OPENAI_THINKING_BASE_LEVELS = [
{ id: "off" },
{ id: "minimal" },
{ id: "low" },
{ id: "medium" },
{ id: "high" }
];
const OPENAI_THINKING_LEVEL_ORDER = [
"off",
"minimal",
"low",
"medium",
"high",
"xhigh",
"max",
"ultra"
];
const OPENAI_UNIFIED_XHIGH_MODEL_IDS = [
OPENAI_GPT_56_MODEL_ID,
OPENAI_GPT_55_MODEL_ID,
OPENAI_GPT_55_PRO_MODEL_ID,
OPENAI_GPT_54_MODEL_ID,
OPENAI_GPT_54_PRO_MODEL_ID,
OPENAI_GPT_53_CODEX_SPARK_MODEL_ID,
OPENAI_GPT_54_MINI_MODEL_ID,
OPENAI_GPT_54_NANO_MODEL_ID
];
function normalizeCodexReasoningEffort(value) {
const normalized = normalizeLowercaseStringOrEmpty(value);
if (normalized === "none") return "off";
return OPENAI_THINKING_LEVEL_ORDER.find((level) => level === normalized);
}
function buildCodexLevels(efforts) {
const supported = /* @__PURE__ */ new Set();
for (const effort of efforts) {
const level = normalizeCodexReasoningEffort(effort);
if (level) supported.add(level);
}
return OPENAI_THINKING_LEVEL_ORDER.filter((level) => supported.has(level)).map((id) => ({ id }));
}
function resolveUnifiedOpenAIThinkingProfile(rawModelId, rawAgentRuntime, compat, api, thinkingLevelMap) {
const modelId = normalizeLowercaseStringOrEmpty(rawModelId);
const agentRuntime = normalizeLowercaseStringOrEmpty(rawAgentRuntime ?? "");
const codexEfforts = compat?.supportedReasoningEfforts?.map(normalizeLowercaseStringOrEmpty);
if (compat?.supportsReasoningEffort === false || codexEfforts?.length === 0) return { levels: api === "openai-completions" && (!agentRuntime || agentRuntime === "auto" || agentRuntime === "openclaw") && [
"qwen",
"qwen-chat-template",
"zai",
"deepseek",
"together"
].includes(compat?.thinkingFormat ?? "") ? OPENAI_THINKING_BASE_LEVELS : [] };
const canSynthesizeUltra = thinkingLevelMap?.max !== null;
const knownCodexEfforts = resolveOpenAICodexReasoningEfforts(modelId, void 0);
const fallbackEfforts = modelCatalog.providers.openai.models.find((model) => model.id === modelId)?.compat?.supportedReasoningEfforts;
if (OPENAI_GPT_6_MODEL_IDS.some((id) => id === modelId) || (agentRuntime !== "codex" || knownCodexEfforts === void 0) && (codexEfforts ?? fallbackEfforts) !== void 0) {
const efforts = codexEfforts ?? (agentRuntime === "codex" ? (fallbackEfforts ?? []).filter((effort) => effort !== "none") : fallbackEfforts ?? []);
const supportsUltra = [
"openclaw",
"codex",
"auto"
].includes(agentRuntime) && efforts.includes("max") && (agentRuntime === "codex" ? modelId === "gpt-6-astra" || efforts.includes("ultra") : canSynthesizeUltra);
const defaultLevel = efforts.includes("medium") ? "medium" : efforts.includes("low") ? "low" : void 0;
return {
levels: buildCodexLevels(supportsUltra ? [...efforts, "ultra"] : efforts),
...defaultLevel ? { defaultLevel } : {}
};
}
const resolvedCodexEfforts = api === void 0 || api === "openai-chatgpt-responses" ? resolveOpenAICodexReasoningEfforts(modelId, codexEfforts) : void 0;
const isGpt56Variant = knownCodexEfforts !== void 0;
const codexSupportsMax = (resolvedCodexEfforts ?? knownCodexEfforts)?.includes("max");
const supportsMax = modelId.startsWith("gpt-5.6") && (agentRuntime !== "codex" || codexSupportsMax);
const codexSupportsUltra = (resolvedCodexEfforts ?? knownCodexEfforts)?.includes("ultra");
const supportsXHigh = OPENAI_UNIFIED_XHIGH_MODEL_IDS.some((prefix) => modelId.startsWith(prefix));
const supportsUltra = (modelId === "gpt-5.6" || isGpt56Variant) && ((agentRuntime === "openclaw" || agentRuntime === "auto") && (canSynthesizeUltra || codexEfforts?.includes("ultra")) || agentRuntime === "codex" && codexSupportsUltra);
const nativeCodexNeedsAccountEffortValidation = agentRuntime === "codex" && compat?.supportedReasoningEfforts === void 0 && (api === void 0 || api === "openai-chatgpt-responses") && !supportsXHigh && !modelId.startsWith("gpt-5.6");
const defaultLevel = isGpt56Variant ? "medium" : void 0;
const fallbackLevels = [
...OPENAI_THINKING_BASE_LEVELS,
...supportsXHigh ? [{ id: "xhigh" }] : [],
...supportsMax ? [{ id: "max" }] : [],
...supportsUltra ? [{ id: "ultra" }] : [],
...nativeCodexNeedsAccountEffortValidation ? [{ id: "xhigh" }, { id: "max" }] : []
];
const levels = agentRuntime === "codex" && resolvedCodexEfforts !== void 0 ? buildCodexLevels(resolvedCodexEfforts) : fallbackLevels;
return {
levels,
...defaultLevel && levels.some((level) => level.id === defaultLevel) ? { defaultLevel } : {}
};
}
//#endregion
//#region extensions/openai/native-web-search-policy.ts
/** Shared by catalog selection and payload construction before any provider request. */
function resolveNativeWebSearch(ctx) {
const provider = ctx.config?.tools?.web?.search?.provider?.trim().toLowerCase();
return ctx.config?.tools?.web?.search?.enabled !== false && (!provider || provider === "auto" || provider === "openai") && ctx.api === "openai-responses" && ctx.provider.trim().toLowerCase() === "openai" && (!ctx.baseUrl || isOpenAIApiBaseUrl(ctx.baseUrl));
}
//#endregion
//#region extensions/openai/provider-policy-api.ts
function resolveServiceTiers(ctx) {
return ctx.runtimeId === "openclaw" ? resolveOpenAIModelServiceTiers(ctx) : void 0;
}
function resolveFastModeSupport(ctx) {
if (!ctx.api || !ctx.baseUrl || ctx.runtimeId !== "openclaw") return;
return (resolveOpenAIModelServiceTiers(ctx)?.includes("priority") ?? true) && normalizeOpenAIServiceTier(ctx.params?.serviceTier ?? ctx.params?.service_tier) === void 0 && supportsOpenAIResponsesFastMode(ctx);
}
const OPENAI_PROVIDER_ID = "openai";
/** Resolves authored OpenAI provider config without activating the runtime plugin. */
function resolveAuthoredOpenAIProviderConfig(params) {
if (params.provider.trim().toLowerCase() !== OPENAI_PROVIDER_ID) return;
const providers = Object.entries(params.config?.models?.providers ?? {});
const requestedProvider = params.provider.trim();
const providerKey = providers.find(([providerId]) => providerId.trim() === requestedProvider)?.[0].trim() ?? providers.find(([providerId]) => providerId.trim().toLowerCase() === OPENAI_PROVIDER_ID)?.[0].trim();
let providerConfig;
for (const [providerId, candidate] of providers) {
if (providerId.trim() !== providerKey || !candidate) continue;
providerConfig = providerConfig ? {
...providerConfig,
...candidate,
models: candidate.models ?? providerConfig.models
} : candidate;
}
return providerConfig;
}
function projectRealtimeVoicePublicProjection(ctx) {
const model = normalizeOptionalString(ctx.config.model) ?? ctx.providerConfig.model;
const modelId = typeof model === "string" ? model : void 0;
if (!isOpenAIGptLiveModel(modelId)) return { config: ctx.config };
if (isSupportedOpenAIGptLiveModel(modelId)) return {
config: ctx.config,
clientHints: { gatewayRelaySupported: ctx.config.consultRouting !== "force-agent-consult" && !normalizeOptionalString(ctx.providerConfig.baseUrl) && !normalizeOptionalString(ctx.providerConfig.azureEndpoint) && !normalizeOptionalString(ctx.providerConfig.azureDeployment) }
};
const { model: _model, ...publicConfig } = ctx.config;
return {
config: publicConfig,
clientHints: {
modelSource: "gateway",
gatewayRelaySupported: false
}
};
}
//#endregion
export { OPENAI_GPT_56_TERRA_MODEL_ID as A, OPENAI_CODEX_RESPONSES_BASE_URL as B, OPENAI_GPT_54_NANO_MODEL_ID as C, OPENAI_GPT_56_LUNA_MODEL_ID as D, OPENAI_GPT_55_PRO_MODEL_ID as E, isOpenAIPlatformOnlyRouteModelId as F, isOpenAIApiBaseUrl as H, isOpenAISubscriptionOnlyRouteModelId as I, normalizeOpenAIModelRouteId as L, OPENAI_GPT_6_MODEL_IDS as M, OPENAI_PROVIDER_MODERN_MODEL_IDS as N, OPENAI_GPT_56_MODEL_ID as O, buildOpenAIUnknownModelHint as P, resolveOpenAICodexReasoningEfforts as R, OPENAI_GPT_54_MODEL_ID as S, OPENAI_GPT_55_MODEL_ID as T, isOpenAICodexBaseUrl as U, classifyOpenAIBaseUrl as V, resolveOpenAIDefaultBaseUrl as W, OPENAI_CHAT_LATEST_MODEL_ID as _, resolveNativeWebSearch as a, OPENAI_GPT_54_LEGACY_MODEL_ID as b, resolveOpenAIModelServiceTiers as c, isOpenAIGptLiveApiModel as d, isOpenAIGptLiveModel as f, OPENAI_CHATGPT_MODERN_MODEL_IDS as g, resolveOpenAIQuicksilverVoiceCapabilities as h, resolveServiceTiers as i, OPENAI_GPT_56_VARIANT_MODEL_IDS as j, OPENAI_GPT_56_SOL_MODEL_ID as k, OPENAI_GPT_LIVE_MODELS as l, resolveOpenAIQuicksilverVoice as m, resolveAuthoredOpenAIProviderConfig as n, resolveUnifiedOpenAIThinkingProfile as o, isOpenAIGptLiveSubscriptionModel as p, resolveFastModeSupport as r, modelCatalog as s, projectRealtimeVoicePublicProjection as t, OPENAI_QUICKSILVER_CAPABILITIES as u, OPENAI_DAYBREAK_MODEL_IDS as v, OPENAI_GPT_54_PRO_MODEL_ID as w, OPENAI_GPT_54_MINI_MODEL_ID as x, OPENAI_GPT_53_CODEX_SPARK_MODEL_ID as y, OPENAI_CODEX_MODELS_ENDPOINT as z };