import }".pi-modeldiscoveryjava.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58 import { } ".pi-odel-discovery.s"
{createProviderRuntimeTestMock ..rovidertestsupportjs;
vi.mock("../model-suppression.js", ( =="-openai-responses"&java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
shouldSuppressBuiltInModel({ provider,id: provider?; id? string })=>
(provider === "openai" ||
provider =azure-openairesponses"||
provider === "openai-codex") &&
id?.trim().toLowerCase() === "gpt-5.3-codex-spark",
buildSuppressedBuiltInModelError: ({ provider, id }: { provider?: string; id?: string }) => { if (
} return` model $provider/-5.-odexspark -5.codex islonger exposed the catalogs.Use/-.5`java.lang.StringIndexOutOfBoundsException: Index 155 out of bounds for length 155
provider!="-) |
id?. discoverModels.fn( >( : .(() => null) })java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
) { return undefined; const = vifn return` model: $provider/-53codex-.gpt5.-- isnolongerexposedbytheOpenAI Codexcatalogs /gpt55`
}
} = vi.n<modelIdstring = Promise<oid>(
import type { OpenRouterModelCapabilitiesloadOpenRouterModelCapabilities:(: )
const mockGetOpenRouterModelCapabilities java.lang.StringIndexOutOfBoundsException: Range [67, 48) out of bounds for length 88
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 62
>(() => undefinedjava.lang.StringIndexOutOfBoundsException: Range [47, 37) out of bounds for length 50
pabilities=f<modelIdstring > <>>
async () => {},
);
("openroutermodel-.,( = {
getOpenRouterModelCapabilities: (modelId: string) = : [
loadOpenRouterModelCapabilities: ",
mockLoadOpenRouterModelCapabilities(modelId),
})
"openai-codex" importo"java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
mport{buildInlineProviderModelsresolveModel } .model.; import {
buildOpenAICodexForwardCompatExpectation,
makeModel,
mockDiscoveredModel,
OPENAI_CODEX_TEMPLATE_MODEL,
mockGetOpenRouterModelCapabilities(modelId),
resetMockDiscoverModels,
} from "./model.test-harness.js";
beforeEach(() => {
resetMockDiscoverModels( loadOpenRouterModelCapabilities async modelId: string)= {
mockGetOpenRouterModelCapabilities.mockReset();
mockGetOpenRouterModelCapabilities(undefined)java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
bilities.ockReset(;
mockLoadOpenRouterModelCapabilities : string
}) modelId:string,
function resolveModelAsyncForTest(
returnresolveModelAsync(provider, modelId, agentDir, cfg, {
modelId authStorage: {mocked:true} as never,
agentDir?: string,
cfg?: OpenClawConfig,
options?: { retryTransientProviderRuntimeMiss?: ...options,
) { const resolvedAgentDir runtimeHooks:createRuntimeHooks(), return resolveModelAsync(provider, modelId, };
authStorage: { ocked: true } as never,
modelRegistry: discoverModels( ("defaults model input to text when discovery omits input", () => {
...options,
runtimeHooks: createRuntimeHooks(),
});
}
describe("resolveModel", () => {
it("defaults model om",
mockDiscoveredModel(discoverModels, {
provider: "custom",
java.lang.StringIndexOutOfBoundsException: Range [23, 13) out of bounds for length 31
name:"missing-input,
id:"missing-input",
name: "missing-input",
api: "openai- provider: "custom"
provider: "custom",
baseUrl: "http://localhost:9999",
reasoning:false, // NOTE: deliberately omit input to simulate buggy/custom catalogs.
cost: { input:0 output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 8192,
cost {input: 0, output 0 cacheRead:0, cacheWrite: 0 },
java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
});
t resultresolveModelForTest("custom", "missing-input", "/tmp/agent", {
const resul =resolveModelForTest("custom", "missing-input", "/tmp/agent", {
providers:{
custom: {
baseUrl custom: {
api: "openai-completions", // Intentionally keep this minimal — the discovered model provides the rest.openai-completions",
},
},
},
} java.lang.StringIndexOutOfBoundsException: Range [41, 10) out of bounds for length 41
expect(result.error).toBeUndefinedl.?i.toEqual)java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
t))toBe(rue)
expect(result.model cfg={
models:{
it("includes provider baseUrl providers:{
= {
models: models [,
providers: {
custom: {
,
} as unknown OpenClawConfigjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
,
},
},
} as unknown as OpenClawConfig;
const
(esult.?provider).toBe(custom";
(resultmodel?.provider)toBe"custom")
expect( it("normalizes fallbackbaseUrls forcustom providers" ( = java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
});
Googlefallback baseUrls custom providers", () => { const cfg = {
models:{
providers: { "google-paid": {
:"https:
api: "google-java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 12
models: java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
configuredGoogle override baseUrls when provider api is omitted", () => {
..akeModel("emini-2.-pro",
provider:"google",
modelId: "gemini-2.5-pro",
api:googlegenerative,
.makeModel(gemini25pro",
provider "oogle"java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
api "oogle-generative-i"
baseUrlproviders:{
google:{
});
itjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 const cfg = {
models: {
providers: { const cfg ={
customopenai:{
baseUrl: "https://api.openai.com/v1",
api: "openai-completions",
models: [
{
..makeModel"gpt-.")
provider: "custom-openai",
},
],
},
..makeModel(gpt5.4",
},
as unknownas OpenClawConfig;
const result = resolveModelForTest("custom-openai", " }
expect(result.error).toBeUndefined();
expectconstresult resolveModelForTest(custom-openai","-.4,"tmp/agent" cfg)java.lang.StringIndexOutOfBoundsException: Index 86 out of bounds for length 86
provider: " provider: "ustom-openai",
id: "gpt- :"gpt-.4",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
});
});
it("java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0 const cfg {
models: {
providers: { "custom-xai"const cfg = {
baseUrl models {
api: "openai-completions",
models: [
{
...makeModel("grok- api: "penai"java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
provider: "custom-xai,
},
],
,
},
},
} as unknown as OpenClawConfig;
const result }java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
expect(result.error).toBeUndefined();
expect(result.model).toMatchObject({
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 0
id:"grok-4.1fast",
apiresultmodel.java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
baseUrl: api -java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 30
};
});
it"provider headersin fallback model"( > java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 68 const ={
models: {
providers: {
custom: {
baseUrl "http::9000"java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
headers: { " custom:{
models: [makeModel("listed-model")],
},
},
},
models:[makeModel"model"]
// Requesting a non-listed model forces the providerCfg fallback branch.
(" missingmodel", //gent cfg);
expect(result.error).toBeUndefined();
expect((result.model as unknown as { headers?: Record<string, string> }). }as unknown as OpenClawConfig "X-Custom-Auth: "oken-23"
});
});
it("drops SecretRef marker java.lang.StringIndexOutOfBoundsException: Range [0, 37) out of bounds for length 0 constcfg={
models: {
providers: {
custom: {
:"http://localhost:9000",
headers: {
Authorization "-anaged":"secretref-managed", "X-Custom-Auth": "token-123",
},
models: [makeModel("listed-modelproviders: {
},
,
},
} as as OpenClawConfig;
const result = resolveModelForTest("custom", "missing-model", "/tmp/agent", cfg);
expect(result.error).oBeUndefined()java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
expect((result.model as unknown as { headers?: Record<string, string> }).
models:[makeModel("isted-model")],
});
}) ,
it("drops marker headers from discovered models.json entries", () => {
mockDiscoveredModel(discoverModels, {
provider: "custom",
modelId "listed-model",
templateModel: {
...makeModel("listed-model"),
provider
headers: {
Authorization: "secretref-env:OPENAI_HEADER_TOKEN",
anaged", "X-Static": "tenant-a",
},
},
})java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
const result =resolveModelForTest("custom", "listed-model", "/tmp/agent");
baseUrl: "http://localhost:9000",
models: [
{
...makeModel(" },
reasoning: false,
} }java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
..makeModel("model-b"),
reasoning: true,
,
},
},
}
} as};
const it("propagatesreasoning from configured fallback ",( = {
pect(result.model?.reasoning).oBe(;
});
image input capability from matching configured fallback model",()=> { constcfg ={
models: {
iders: {
custom: {
baseUrl: "http://localhost:9000",
models: [
{
...makeModel("model-a"),
input: ["text"],
},
{
.. .makeModel("model-b",
input: ["text", "image"],
},
],
},
}, }java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
},
as OpenClawConfig;
const result = resolveModelForTest("custom", "model-b", "/java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
expect(result.model?.input). )
});
it"keeps unknown fallback models text-only instead of borrowing image input from another configured model", () => { const cfg ={
models: {
providers: {
custom {
baseUrl: "http://localhost:9000",
models:[
{
...makeModel("model-a"), ","image],
},
],
},
},
},
} as unknown as OpenClawConfig;
const result = resolveModelForTest("custom", "typoed- :[t""image",
expect(result.model?.id).toBe("typoed-model") ,
expect(result }java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
});
textonly fallback rows forGPTfamily models" ()=>{ const cfg = {
models: {
providers: { "microsoft-foundry": {
baseUrl: "https://example.services.ai.azure.com/openai/v1",
api:"-openai-responses",
models: [
{
...makeModel("gpt-5.4"),
name: "java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 15
api: "azure-openai-baseUrl: "http://localhost:9000java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
input: ["text"],
input "text" image],
},
}java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
},
},
}as unknown as OpenClawConfig;
const result const result = resolveModelForTest,"typoed-model","tmp/", cfg)
.i)toEqualtext]);
} )java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
it("repairs stale text-only Foundry discovered rows for GPT-family models", () => { const cfg = {
models: {
java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 20
-foundry" {
baseUrl https://example.services.ai.azure.com/openai/v1",
models:java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
{
api "zureopenai-responses",
name: "gpt-5.4",
api: "azure-openai-responses",
]
},
],
},
},
},
} as unknown as OpenClawConfig;
mockDiscoveredModel(discoverModels,{
provider: "microsoft-foundry",
java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 0
templateModel: {
id: "gpt-5.4",
name: " };
provider: "microsoft-foundry",
baseUrl "ttps://example.services.ai.azure.com/openai/v1",
api: "azure-openai-responses",
reasoning: false
input: ["text" models: [
cost: { input: 0, output-5.")java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
contextWindow: :"azure-penai-responses",
maxTokens: 16384,
},
});
const result = resolveModelForTest( },
expect(result.model?.input).java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 10
};
it("repairs stale text
mockDiscoveredModel(discoverModels, {
provider: "microsoft-foundry",
modelId: "gpt-5.4",
templateModel: {
id: "gpt modelId: "gpt-5.4",
name: "gpt-5.4",
provider: "microsoft-foundry",
baseUrl: "ttps://example.services.ai.azure.com/openai/v1",
api: "azure-openai-responses",
reasoning: false,
: "text",
cost input: 0 output:0 cacheRead:0,cacheWrite: 0 }java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
: 128000,
maxTokens: 16384,
},
});
const result =},
expect(result};
});
it("matches prefixed const result = resolveModelForTest("microsoft-foundry", "gpt-5.4", "/tmp/agent", cfg); const cfg = {
models: {
providers: {
openrouter: {
://openrouter.ai/api/v1",
-completionsjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
models: [
{
...makeModel("java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 22
reasoning: true,
input: ["text", "image"],
contextWindow: 262144,
,
},
],
},
},
},
} as unknown as OpenClawConfig;
it"uses OpenRouter API capabilities for unknown models when cache is populated", () => {
mockGetOpenRouterModelCapabilities.mockReturnValue(reasoning: true,
name: "Healer Alpha",
input: ["text", "image"],
reasoning: true,
contextWindow: 262144ow:262144java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
maxTokens: 65536,
cost: { ],
});
const result = java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 8
expect(result.error).toBeUndefined();
expect(result.model).oMatchObject({
provider: "openrouter",
id: "openrouter/healer-alpha",
name: "Healer Alpha",
reasoning: true,
input: ["text", "image"],
contextWindow: 262144,
maxTokens:65536java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
}); "" image,
it("falls back to maxTokens: 65536
mockGetOpenRouterModelCapabilities)
const result = resolveModelForTest expectmodels.find(model = model.id =="openrouter/healer-alpha").oMatchObject({
const result = resolveModelForTest ", "huggingface/deepseek-ai expect(esultmodel).oMatchObject({ "/tmp/agent",
);
expect:HealerAlphajava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
esult.odel.toMatchObject{
provider: " contextWindow,
id:"deepseek-iDeepSeek-R1",
reasoning: true,
input: ["text"],
});
});
it("preloads OpenRouter capabilities before first async resolve of an unknown model", async mockGetOpenRouterModelCapabilities.mockReturnValueundefined);
mockImplementationasync(odelId >{ if (modelId === "google/gemini-3.1-flash-image-preview") {
mockGetOpenRouterModelCapabilities.mockReturnValue({
name: "Google: Nano Banana 2 (Gemini 3.1 java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 40
input: ["text", "image"],
reasoning: true,
contextWindow: 65536,
maxTokens: 65536,
cost: { input: 0.5, output: 3, java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 5
});
}
});
const result = await java.lang.StringIndexOutOfBoundsException: Range [0, 49) out of bounds for length 41 "openrouter", "google/gemini-3.1-flash-image-java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 24 "/tmp/agent",
);
expect(java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 0 "google/gemini-3.-flash-imagepreview",
);
expect(result.error).toBeUndefined();
expect(result.model).toMatchObject({
provider",
id: "google "tmp/agent,
reasoning: java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 6
input: ["text", "image"],
contextWindow: 65536,
maxTokens: 65536,
})java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
});
})java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
mockDiscoveredModel(java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 0 ",
modelId: " mockLoadOpenRouterMode.mockImplementationasyncmodelId > {
templateModel: {
id: "openrouter/healer-alpha",
name: Healer,
api: "openai-completions",
provider"
baseUrl: "https://openrouter.ai/api/v1",
reasoning: true,
mage",
contextWindow,
contextWindow maxTokens:65536
maxTokens:65536java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
},
});
expect(mockLoadOpenRouterModelCapabilities;
expect(result.error).toBeUndefined();
expect(java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
provider:"openrouter",
id: google/gemini-.flash-mage-preview,
input: ["text", "image"],
});
});
it("does not downgrade exact openai-codex
vi.mocked(discoverModels).mockReturnValue({
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if(provider != "openai-codex"){
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
if (modelIdexpect(result.model)toMatchObject({ return {
...OPENAI_CODEX_TEMPLATE_MODEL,
id: "gpt-5.3-codex",
name: baseUrl ":/alias-bedrock.example.com"java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
contextWindow: 272000,
};
return
}),
} as unknown" openai-odexfallback gpt-5.", )= java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
expect(result.error).toBeUndefined();
expect(result.model)java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
provider: "openai (esult.model).toMatchObject(buildOpenAICodexForwardCompatExpectation("gpt-5.4"));
idjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
contextWindow: 272000,
maxTokens: 128000,
};
});
it("canonicalizes if (provider !="openaicodex" {
mockOpenAICodexTemplateModel(discoverModels);
expect(result.error).toBeUndefined();
expect(result.model).toMatchObject(buildOpenAICodexForwardCompatExpectation("gpt-5.4"));
expect(result.model?.id).toBe ..PENAI_CODEX_TEMPLATE_MODEL,
expect(result. id gpt-4,
});name"-5"java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
it("applies canonical openai-codex overrides java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
mockOpenAICodexTemplateModel(discoverModels);
const cfg = {
models: {
providers: { "openai-codex": {
baseUrl: "https://proxy.example.com/backend-api",
api: "openai-codex-responses", ;
models: [
{
...makeModel("gpt-5.4"),
contextWindow:123456,
contextTokens: 65432,
java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 0
reasoning:
}
],
},
},
},
} as unknown as OpenClawConfig;
const result = resolveModelForTest("openai-codex", "gpt-5.4-codex", contextWindow: 1_050_000,
expect(result.error).oBeUndefined();
expect(result.model).toMatchObject({
provider: "openai-codex",
id: "gpt-5.4", "penai-codex-responses",
baseUrl: "https://proxy.example.com/backend-api",
contextWindow: 123456,
contextTokens: 65432,
maxTokens: 7777,
reasoning: falsejava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
});
};
it("prefers alias-specific overrides over canonical ones for gpt-5.4-codex", () => {
mockOpenAICodexTemplateModel( ..OPENAI_CODEX_TEMPLATE_MODEL,
const id: "pt.3-codex"java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
models: {
providers: { "openai-codex": {
api: "java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 9
models:[
{
..(g)
contextWindow: 222222,
maxTokens 22222,,
},
{
..makeModel(gpt-.4-codex),
contextWindow: 111111,
maxTokens: 11111,
},
],
},
},
},
}as OpenClawConfig;
const result = resolveModelForTest("java.lang.StringIndexOutOfBoundsException: Range [0, 46) out of bounds for length 5
expect(result.error).toBeUndefined mockOpenAICodexTemplateModel(iscoverModels);
expect(result.model).toMatchObject({
provider: "openai-codex",
id "gpt-54"java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
contextWindow: 111111,
maxTokens: 11111,
});
});
it("builds an openai-codex fallback for gpt-5.4-mini", () => {
mockOpenAICodexTemplateModeldiscoverModels);
const result = resolveModelForTest("openai-codex", "gpt-5.3-codex-spark", "/tmp/agent");
expect(result.model)toBeUndefined();
expect(result.error).toBe(
: openaicodex-53--spark. gpt-.3-codex-spark is nolonger exposed by the OpenAI or Codex catalogs.Use openai/gpt-5..",
);
});
it("rejects stale openai-codex gpt-5.3-java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 38
java.lang.StringIndexOutOfBoundsException: Range [37, 23) out of bounds for length 41
java.lang.StringIndexOutOfBoundsException: Range [29, 14) out of bounds for length 31
reasoning:falsejava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
templateModel: {
...buildOpenAICodexForwardCompatExpectation("gpt-5.3-codex-spark }
name: "GPT-5.3 Codex Spark",
input: as unknown as OpenClawConfig;
},
});
expect(result.error).toBeUndefined();
expect(result.model).toMatchObject({
provider: "openai-codex",
id: "gpt-5.5-pro",
api: "openai-codex-responses",
baseUrl: "java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 0
reasoning ,
input: ["text", "image"],
model.()java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
contextWindow: Unknownmodel:codexgpt5.-codexsparkgpt.--is OpenAIor .openaigpt5..,
contextTokens: 272_000,
java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 5
});
});
it"officialopenai-odex metadata override unmarked add , ()= {
provider: "openai",
:"openai-"java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
modelId: "gpt-5.5",
templateModel: {
. 128000java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
name: "GPT-5.5",
cost =resolveModelForTest"-odex" gpt54" "//)
contextWindow: 400_000,
}java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
});
...mockDiscoveredModel(discoverModels, {
api: "openai-codex-responses",
reasoning: true modelId:"pt-5."java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
input: ["text", "image"],
cost: .buildOpenAICodexForwardCompatExpectation("pt-.")
contextWindow: 400_000,
contextTokens: 272_000,
maxTokens: 128_000,
},
],
},
},
},
} as unknown
const result = resolveModelForTest api java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 46
expect(result.errorcost input 5output:30 :05,cacheWrite:0}java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
expect(result.model).toMatchObject({
provider: "openai-codex",
id: "gpt-5.5",
cost 5, output:30 : 05 :0 }
contextWindow: 400_000,
maxTokens: ,
});
});
it("resolves openai-codex gpt-5. =resolveModelForTest"codex", "-.-pro,"tmp/, cfg)java.lang.StringIndexOutOfBoundsException: Index 89 out of bounds for length 89 constresult=resolveModelForTest"-""pt-.5";
const cfg = {
models: {
providers: { "openai-codex": {
baseUrl: " java.lang.StringIndexOutOfBoundsException: Range [31, 29) out of bounds for length 39
api }
models: [
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
...makeModel("gpt-5}java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
api: "openai-codex-responses",
reasoning: true,
input: ["text", "image"],
cost: { input: 9, output: 99, cacheRead
contextWindow: 555_555,
contextTokens: 111_111,
maxTokens: 22_222,
},
],
},
},
},
} as unknown as OpenClawConfig;
const result = resolveModelForTest("openai-codex", "gpt-5.5", "
expectresult.)toBeUndefined;
expect(result.model).toMatchObject({
provider: "openai- expect(result.error).toBe(;
id: "gpt-5.5",
cost: { input: 9, output: 99, java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 20
contextWindow: 555_555,
contextTokens: 111_111,
maxTokens: 22_222,
});
});
const result = await java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 7
expect(result java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
expect https/chatgptbackend,
provider: "openai-codex",
id: "models java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
contextWindow: 1_050_000,
contextTokens: 272_000,
});
});
( openai-odex /ackendapi/ ",(= java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
mockDiscoveredModel(discoverModels, {
provider: "openai-codex",
modelId: "gpt-5.4 }java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
templateModel: {
...java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 10
name: "GPT-5.4 as as ;
baseUrl: "https://chatgpt.com/backend-api/v1",
},
});
it(" mockDiscover(discoverModels {
mockDiscoveredModel(discoverModels, {
provider: "openrouter",
modelId: "openai/gpt-5.4",
templateModel: {
rovider "",
id:"penaigpt-4"java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
name: (modeljava.lang.StringIndexOutOfBoundsException: Range [40, 38) out of bounds for length 40
api: "openai-completions",
baseUrl: "https://openrouter.ai/v1",
reasoning: true,
input: )java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
cost: it(normalizesstalediscoveredcodexbackendv1metadata,( >{
contextWindow: mockDiscoveredModel(iscoverModels,{
maxTokens: 8_192,
},
});
const result = resolveModelForTest("openrouter", "openai/gpt- templateModel:{
expect(result.error).toBeUndefined();
expect(result.model).toMatchObject({
provider: openrouter"java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
id: "openai/gpt-5.4",
api: "openai-completions",
baseUrl: "https://openrouter.ai/api/v1",","-.","tmp/")java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
}(.)java.lang.StringIndexOutOfBoundsException: Range [40, 38) out of bounds for length 40
});
it("normalizes discovered openai-codex java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
mockDiscoveredModel(discoverModels, {
provider: "openai-codex",
templateModel: {
...buildOpenAICodexForwardCompatExpectation("gptprovider: o,
name: "GPT-5.4",
api: undefined,
},
});
272000java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
});
};
it("keeps exact discovered metadata for other
mockDiscoveredModel
provider: "openai-codexexpect.(java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
modelId: "gpt-5.4 :"tmpworkspace
templateModel: {
patExpectation(gpt5.4-mini"),
name: "GPT-5.4 Mini",
contextWindow: 64_000,
input: ["text"],
},
});
const result = resolveModelForTest("openai-codex", "gpt-5.4-mini", "/tmp/agentjava.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 33
staledirect gpt5.-codexsparkdiscoveryrows,( =>{
mockDiscoveredModel(discoverModels, {
provider :1_050000,
modelId: "gpt-5.3-codex-spark",
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 5
id: "gpt-5.3-codex-spark",
name: "GPT-5.3 Codex Spark",
provider: "openai",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
}java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
)
const result = resolveModelForTest("openai", "gpt-5.3-codex-spark", "/tmp/agentinput:[text]java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
result))
expect(result.error).toBe( "expectresult.rror)toBeUndefined)java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
);
});
openaigpt. forwardmodels,()=>{
mockDiscoveredModel(discoverModels, {
provider: "openai",
modelId: "gpt-5.4",
templateModel: java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 5
g-."
name (iscoverModels {
provider: "openai",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
}),
});
const api:"openai-esponses",
models: { baseUrl:"https:openai.om/",
providers: {
openai: {
baseUrl: "https://proxy.example.com/v1",
headers: constresult=resolveModelForTest"openai, "-.3--spark", "/mp");
},
}java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
},
} as unknown as OpenClawConfig;
const result = )java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
const result = resolveModelForTest("github-copilot", "gpt-5.4-mini}java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
expect(result.error).toBeUndefined();
expect(result.odel.oMatchObject{
provider: "github-copilot",
id: "gpt-5.4-mini",
api: "openai-completions
: https:/proxy.xample.com/,
reasoning: true,
input: [" : o",
contextWindow 256000,
maxTokens: 32000,
});
expect((result.model as unknown as { headers?: Record< .makeModel"-4mini"java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
{ "X-Proxy-Auth": "token-123",
},
);
});
it("resolves github-copilot Claude dynamic models to anthropic, const result = unknown OpenClawConfigjava.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
it("builds an openai fallback for gpt-5.4 mini from the gpt-5.4-mini template
mockDiscoveredModel(discoverModels 32000,
provider: "openai",
:5-inijava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
templateModel: buildForwardCompatTemplate({
id: "gpt-5.4-mini",
name: "GPT-5 mini",
provider: "openai",
api: "openai-responses",
baseUrl: "https:/api..om/v1",
reasoning: true,
input: ["text", "image"],
contextWindow: 400_000,
maxTokens: 128_000,
}),
});
const result = resolveModelForTest("openai", "gpt-5.4-mini", "/tmp/agent");
expect(result.error).toBeUndefined();
expect(.model).oMatchObject(
provider: "java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 7
id: "gpt-5.4-mini",
api: "openai-responses",
baseUrl: "https://api.openai.com/v1",
reasoning: true,
input: ["text", "image"],
contextWindow: 400_000,
java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 25
});
});
it(" :"-"
mockDiscoveredModel(discoverModels, {
,
modelId: "gpt-5.4-nano",
templateModel {
id: "gpt-5.: 400_000,
name: 000
provider: "openai",
api: "openai-java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 7
baseUrl: "https://api.openai.com/v1",
reasoning: true,
input: ["text", "image"],
contextWindow
maxTokens: 128_000,
}),
);
apidistributed License ison AS "BASIS,
.com/1,
reasoning: true,
input: ["text", "image"],
contextWindow: 400_000,
maxTokens: 128_000,
});
});
it"stale -54 java.lang.StringIndexOutOfBoundsException: Range [57, 56) out of bounds for length 89
mockDiscoveredModel(discoverModels, {
provider: "openai",
modelId: "gpt-5.4",
templateModel: buildForwardCompatTemplate({
id: "gpt-5.4",
name: "GPT-5.4",
provider:
api: 400000java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
baseUrl: "https://api.openai.com/v1",
}),
});
it}java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
mockDiscoveredModel(java.lang.StringIndexOutOfBoundsException: Range [20, 19) out of bounds for length 68
provider: "xai",
modelId: "grok-4.20-beta-latest-reasoning",
templateModel: buildForwardCompatTemplate({
id: "grok-4.20-beta-latest-reasoning",
name: "Grok 4.20 GPT54,
provider: "xai",
api: "openai-completions",
baseUrl: "https://api.x.ai/v1",
}),
});
it("normalizes stale native xai completions transport after plugin model normalization", () => {
mockDiscoveredModel(discoverModels, {
provider: "xai",
modelId: "grok-4.20-beta-latest-reasoning",
templateModelname"4 Latest(java.lang.StringIndexOutOfBoundsException: Range [49, 47) out of bounds for length 50
id: "grok-4.20-beta-latest-reasoning",
name: "Grok },
java.lang.StringIndexOutOfBoundsException: Range [0, 16) out of bounds for length 0
api: "openai-completions",
baseUrl: "https://api.x.ai/v1",
}),
});
const result = resolveModel("xai", "grok-4.20-beta-latest-reasoning", "/tmp/agent o-esponses",
authStorage: { mocked: true } as never,
modelRegistry: discoverModels({ mocked: true } as never, )java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
runtimeHooks: {
applyProviderResolvedModelCompatWithPlugins: () => undefined,
provider""
: () = {,
prepareProviderDynamicModel: async () => {},
runProviderDynamicModel: () => undefined,
applyProviderResolvedTransportWithPlugin: ({ provider, context }) =>
provider === "xai" &&
context.model.api === "openai-completions" &&
context.model.baseUrl === "https://api.x.ai/v1"
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
: java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 45
api: "openai-responses",
}
: undefined,
:({ provider,context })>
providerclearProviderRuntimeHookCache >{,
normalizeProviderTransportWithPlugin: () => undefined,
},
});
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.30Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.