fix: validate chutes model token metadata · openclaw/openclaw@ef7ad6f
steipete
·
2026-05-29
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -145,6 +145,41 @@ describe("chutes-models", () => {
|
145 | 145 | }); |
146 | 146 | }); |
147 | 147 | |
| 148 | +it("falls back from malformed live token metadata", async () => { |
| 149 | +const mockFetch = vi.fn().mockResolvedValue({ |
| 150 | +ok: true, |
| 151 | +json: async () => ({ |
| 152 | +data: [ |
| 153 | +{ |
| 154 | +id: "provider/bad-window", |
| 155 | +context_length: -1, |
| 156 | +max_output_length: 16384.5, |
| 157 | +}, |
| 158 | +{ |
| 159 | +id: "provider/bad-max-output", |
| 160 | +context_length: Number.POSITIVE_INFINITY, |
| 161 | +max_output_length: 0, |
| 162 | +}, |
| 163 | +], |
| 164 | +}), |
| 165 | +}); |
| 166 | + |
| 167 | +await withLiveChutesDiscovery(mockFetch, async () => { |
| 168 | +const models = await discoverChutesModels("malformed-token-metadata"); |
| 169 | + |
| 170 | +expect(requireChutesModel(models, 0)).toMatchObject({ |
| 171 | +id: "provider/bad-window", |
| 172 | +contextWindow: 128000, |
| 173 | +maxTokens: 4096, |
| 174 | +}); |
| 175 | +expect(requireChutesModel(models, 1)).toMatchObject({ |
| 176 | +id: "provider/bad-max-output", |
| 177 | +contextWindow: 128000, |
| 178 | +maxTokens: 4096, |
| 179 | +}); |
| 180 | +}); |
| 181 | +}); |
| 182 | + |
148 | 183 | it("discoverChutesModels retries without auth on 401", async () => { |
149 | 184 | const mockFetch = vi.fn().mockImplementation((url, init) => { |
150 | 185 | if (init?.headers?.Authorization === "Bearer test-token-error") { |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -5,6 +5,7 @@ import {
|
5 | 5 | ssrfPolicyFromHttpBaseUrlAllowedHostname, |
6 | 6 | } from "openclaw/plugin-sdk/ssrf-runtime"; |
7 | 7 | import { |
| 8 | +asPositiveSafeInteger, |
8 | 9 | normalizeLowercaseStringOrEmpty, |
9 | 10 | normalizeOptionalString, |
10 | 11 | } from "openclaw/plugin-sdk/string-coerce-runtime"; |
@@ -616,8 +617,9 @@ export async function discoverChutesModels(accessToken?: string): Promise<ModelD
|
616 | 617 | cacheRead: 0, |
617 | 618 | cacheWrite: 0, |
618 | 619 | }, |
619 | | -contextWindow: entry.context_length || CHUTES_DEFAULT_CONTEXT_WINDOW, |
620 | | -maxTokens: entry.max_output_length || CHUTES_DEFAULT_MAX_TOKENS, |
| 620 | +contextWindow: |
| 621 | +asPositiveSafeInteger(entry.context_length) ?? CHUTES_DEFAULT_CONTEXT_WINDOW, |
| 622 | +maxTokens: asPositiveSafeInteger(entry.max_output_length) ?? CHUTES_DEFAULT_MAX_TOKENS, |
621 | 623 | compat: { |
622 | 624 | supportsUsageInStreaming: false, |
623 | 625 | }, |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。