Files
openclaw/extensions/longcat/doctor-contract-api.test.ts
ffyuuu efe5d8d76e fix(longcat): correct cache pricing and add provider icon (#121369)
* longcat: align baseUrl with docs, fix cacheWrite pricing, add brand icon

- Point baseUrl at the documented https://api.longcat.chat/openai/v1 path
  instead of the undocumented unversioned alias route.
- Fix cacheWrite pricing to 0: the LongCat pricing page has no separate
  cache-write charge (matches deepseek/moonshot/zai catalog conventions).
- Update the pricing page link to the current docs path.
- Add the official LongCat brand icon (provenance recorded in
  ATTRIBUTION.md) and display-name mapping so the Control UI shows proper
  branding instead of the letter-badge fallback.
- Migrate the persisted legacy default baseUrl via a plugin-owned doctor
  configRepair contract: onboarding persists
  models.providers.longcat.baseUrl and the runtime reads the stored value,
  so the contract rewrites exactly the former default to /openai/v1,
  preserves custom endpoints, and warns via a legacy-config rule.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(longcat): correct provider metadata

* fix(longcat): migrate persisted stock pricing

* style(longcat): format doctor repair

* fix(longcat): preserve doctor migration after compat cleanup

* fix(longcat): avoid map spread in doctor repair

---------

Co-authored-by: yuzehui02 <yuzehui02@meituan.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
2026-08-10 20:15:18 -07:00

100 lines
3.2 KiB
TypeScript

// LongCat tests cover the plugin-owned persisted catalog repair.
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { describe, expect, it } from "vitest";
import { legacyConfigRules, normalizeCompatibilityConfig } from "./doctor-contract-api.js";
const LEGACY_STOCK_MODEL = {
id: "LongCat-2.0",
name: "LongCat 2.0",
reasoning: true,
input: ["text"],
contextWindow: 1_048_576,
maxTokens: 131_072,
cost: { input: 0.75, output: 2.95, cacheRead: 0.015, cacheWrite: 0.75 },
compat: {
supportsStore: false,
supportsDeveloperRole: false,
supportsReasoningEffort: false,
supportsUsageInStreaming: false,
supportsStrictMode: false,
maxTokensField: "max_tokens",
requiresReasoningContentOnAssistantMessages: true,
thinkingFormat: "deepseek",
},
};
function longcatConfig(models: unknown[]): OpenClawConfig {
return {
models: {
providers: {
longcat: {
baseUrl: "https://api.longcat.chat/openai",
api: "openai-completions",
models,
},
},
},
} as OpenClawConfig;
}
describe("LongCat doctor contract", () => {
it("repairs only the exact historical stock row", () => {
const custom = {
...LEGACY_STOCK_MODEL,
name: "My LongCat",
cost: { ...LEGACY_STOCK_MODEL.cost },
};
const other = { id: "custom-model", name: "Custom" };
const config = longcatConfig([structuredClone(LEGACY_STOCK_MODEL), custom, other]);
expect(legacyConfigRules[0]?.match?.(config.models?.providers?.longcat?.models)).toBe(true);
const result = normalizeCompatibilityConfig({ cfg: config });
expect(result.changes).toEqual([
"Updated the historical stock LongCat-2.0 cache-write price from $0.75 to $0.",
]);
expect(result.config.models?.providers?.longcat?.models).toEqual([
{
...LEGACY_STOCK_MODEL,
cost: { ...LEGACY_STOCK_MODEL.cost, cacheWrite: 0 },
},
custom,
other,
]);
expect(config.models?.providers?.longcat?.models?.[0]?.cost.cacheWrite).toBe(0.75);
expect(normalizeCompatibilityConfig({ cfg: result.config })).toEqual({
config: result.config,
changes: [],
});
});
it("repairs the historical row after core Doctor removes catalog-owned compat", () => {
const { compat: _compat, ...normalizedLegacyStockModel } = LEGACY_STOCK_MODEL;
const custom = {
...normalizedLegacyStockModel,
compat: { supportsStore: true },
};
const config = longcatConfig([normalizedLegacyStockModel, custom]);
const result = normalizeCompatibilityConfig({ cfg: config });
expect(result.config.models?.providers?.longcat?.models).toEqual([
{
...normalizedLegacyStockModel,
cost: { ...normalizedLegacyStockModel.cost, cacheWrite: 0 },
},
custom,
]);
});
it("preserves customized prices and already-correct rows", () => {
for (const cacheWrite of [0, 0.5]) {
const model = {
...LEGACY_STOCK_MODEL,
cost: { ...LEGACY_STOCK_MODEL.cost, cacheWrite },
};
const config = longcatConfig([model]);
expect(normalizeCompatibilityConfig({ cfg: config })).toEqual({ config, changes: [] });
}
});
});