mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
refactor(providers): shared manifest row builder and fleet default-model adoption (#113879)
* feat(plugin-sdk): add manifest model row builder * refactor(providers): share manifest model row building * refactor(providers): source defaults from manifests * refactor(providers): drop unconsumed builder aliases * fix(providers): keep Cohere catalog internal
This commit is contained in:
committed by
GitHub
parent
5402ef192d
commit
e30217d25c
@@ -5,7 +5,6 @@ export {
|
||||
BASETEN_DEFAULT_MODEL_REF,
|
||||
BASETEN_MODEL_CATALOG,
|
||||
buildBasetenModelCompat,
|
||||
buildBasetenModelDefinition,
|
||||
buildStaticBasetenModels,
|
||||
discoverBasetenModels,
|
||||
projectBasetenLiveModels,
|
||||
|
||||
@@ -5,7 +5,10 @@ import {
|
||||
getCachedLiveProviderModelRows,
|
||||
type LiveModelCatalogFetchGuard,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-live-runtime";
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import {
|
||||
buildManifestModelDefinition,
|
||||
readManifestProviderDefaultModelRef,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type {
|
||||
ModelCompatConfig,
|
||||
ModelDefinitionConfig,
|
||||
@@ -49,9 +52,9 @@ const BASE_COMPAT: ModelCompatConfig = {
|
||||
/** Base URL for Baseten's OpenAI-compatible Model APIs. */
|
||||
export const BASETEN_BASE_URL = BASETEN_MANIFEST_CATALOG.baseUrl;
|
||||
/** Default Baseten model id used for onboarding. */
|
||||
export const BASETEN_DEFAULT_MODEL_ID = "thinkingmachines/inkling";
|
||||
export const BASETEN_DEFAULT_MODEL_ID = BASETEN_MANIFEST_CATALOG.defaultModel;
|
||||
/** Default Baseten model ref used for onboarding. */
|
||||
export const BASETEN_DEFAULT_MODEL_REF = `baseten/${BASETEN_DEFAULT_MODEL_ID}`;
|
||||
export const BASETEN_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(manifest, "baseten")!;
|
||||
/** Bundled fallback rows for all Baseten Model APIs available at release time. */
|
||||
export const BASETEN_MODEL_CATALOG = BASETEN_MANIFEST_CATALOG.models;
|
||||
|
||||
@@ -110,27 +113,18 @@ export function buildBasetenModelCompat(modelId: string): ModelCompatConfig {
|
||||
};
|
||||
}
|
||||
|
||||
/** Builds one normalized Baseten model definition from a manifest entry. */
|
||||
export function buildBasetenModelDefinition(
|
||||
model: (typeof BASETEN_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
const provider = buildManifestModelProviderConfig({
|
||||
providerId: "baseten",
|
||||
catalog: { ...BASETEN_MANIFEST_CATALOG, models: [model] },
|
||||
});
|
||||
const normalized = provider.models[0];
|
||||
if (!normalized) {
|
||||
throw new Error(`Missing normalized Baseten model ${model.id}`);
|
||||
}
|
||||
return {
|
||||
...normalized,
|
||||
compat: buildBasetenModelCompat(normalized.id),
|
||||
};
|
||||
}
|
||||
|
||||
/** Builds the network-free fallback catalog. */
|
||||
export function buildStaticBasetenModels(): ModelDefinitionConfig[] {
|
||||
return BASETEN_MODEL_CATALOG.map(buildBasetenModelDefinition);
|
||||
return BASETEN_MODEL_CATALOG.map(
|
||||
buildManifestModelDefinition({
|
||||
providerId: "baseten",
|
||||
catalog: BASETEN_MANIFEST_CATALOG,
|
||||
decorate: (normalized) => ({
|
||||
...normalized,
|
||||
compat: buildBasetenModelCompat(normalized.id),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
type BasetenLiveModelRow = {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"baseten": {
|
||||
"baseUrl": "https://inference.baseten.co/v1",
|
||||
"api": "openai-completions",
|
||||
"defaultModel": "thinkingmachines/inkling",
|
||||
"models": [
|
||||
{
|
||||
"id": "deepseek-ai/DeepSeek-V4-Pro",
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
export { buildBytePlusCodingProvider, buildBytePlusProvider } from "./provider-catalog.js";
|
||||
export {
|
||||
buildBytePlusModelDefinition,
|
||||
BYTEPLUS_BASE_URL,
|
||||
BYTEPLUS_CODING_BASE_URL,
|
||||
BYTEPLUS_CODING_MODEL_CATALOG,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { BYTEPLUS_CODING_MODEL_CATALOG, BYTEPLUS_MODEL_CATALOG } from "./models.
|
||||
describe("byteplus plugin", () => {
|
||||
it("augments the catalog with bundled standard and plan models", async () => {
|
||||
const provider = await registerSingleProviderPlugin(plugin);
|
||||
expect(provider.auth?.[0]?.starterModel).toBe("byteplus-plan/ark-code-latest");
|
||||
const standardModel = expectDefined(BYTEPLUS_MODEL_CATALOG[0], "BytePlus standard model");
|
||||
const codingModel = expectDefined(BYTEPLUS_CODING_MODEL_CATALOG[0], "BytePlus coding model");
|
||||
const entries = await provider.augmentModelCatalog?.({
|
||||
|
||||
@@ -4,12 +4,14 @@
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import { buildOpenAICompatibleLiveModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-live-runtime";
|
||||
import { readManifestProviderDefaultModelRef } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { ensureModelAllowlistEntry } from "openclaw/plugin-sdk/provider-onboard";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
import { BYTEPLUS_PROVIDER_CATALOG_ENTRIES } from "./provider-catalog.js";
|
||||
import { buildBytePlusVideoGenerationProvider } from "./video-generation-provider.js";
|
||||
|
||||
const PROVIDER_ID = "byteplus";
|
||||
const BYTEPLUS_DEFAULT_MODEL_REF = "byteplus-plan/ark-code-latest";
|
||||
const BYTEPLUS_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(manifest, "byteplus-plan")!;
|
||||
|
||||
export default definePluginEntry({
|
||||
id: PROVIDER_ID,
|
||||
|
||||
@@ -25,12 +25,3 @@ export const BYTEPLUS_MODEL_CATALOG: ModelDefinitionConfig[] = BYTEPLUS_MANIFEST
|
||||
/** BytePlus coding/planning model catalog entries. */
|
||||
export const BYTEPLUS_CODING_MODEL_CATALOG: ModelDefinitionConfig[] =
|
||||
BYTEPLUS_CODING_MANIFEST_PROVIDER.models;
|
||||
|
||||
/** Clones one manifest model definition so callers can mutate safely. */
|
||||
export function buildBytePlusModelDefinition(entry: ModelDefinitionConfig): ModelDefinitionConfig {
|
||||
return {
|
||||
...entry,
|
||||
input: [...entry.input],
|
||||
cost: { ...entry.cost },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
"byteplus-plan": {
|
||||
"baseUrl": "https://ark.ap-southeast.bytepluses.com/api/coding/v3",
|
||||
"api": "openai-completions",
|
||||
"defaultModel": "ark-code-latest",
|
||||
"models": [
|
||||
{
|
||||
"id": "ark-code-latest",
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
/**
|
||||
* Public Cerebras provider plugin API exports.
|
||||
*/
|
||||
export {
|
||||
buildCerebrasModelDefinition,
|
||||
CEREBRAS_BASE_URL,
|
||||
CEREBRAS_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
export { buildCerebrasCatalogModels, CEREBRAS_BASE_URL, CEREBRAS_MODEL_CATALOG } from "./models.js";
|
||||
export { buildCerebrasProvider } from "./provider-catalog.js";
|
||||
export { applyCerebrasConfig, CEREBRAS_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Cerebras model catalog helpers derived from the plugin manifest.
|
||||
*/
|
||||
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { buildManifestModelDefinition } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
@@ -15,19 +14,7 @@ export const CEREBRAS_MODEL_CATALOG = CEREBRAS_MANIFEST_CATALOG.models;
|
||||
|
||||
/** Builds normalized Cerebras catalog model definitions. */
|
||||
export function buildCerebrasCatalogModels(): ModelDefinitionConfig[] {
|
||||
return buildManifestModelProviderConfig({
|
||||
providerId: "cerebras",
|
||||
catalog: CEREBRAS_MANIFEST_CATALOG,
|
||||
}).models;
|
||||
}
|
||||
|
||||
/** Builds one normalized Cerebras model definition from a manifest entry. */
|
||||
export function buildCerebrasModelDefinition(
|
||||
model: (typeof CEREBRAS_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
const providerConfig = buildManifestModelProviderConfig({
|
||||
providerId: "cerebras",
|
||||
catalog: { ...CEREBRAS_MANIFEST_CATALOG, models: [model] },
|
||||
});
|
||||
return expectDefined(providerConfig.models.at(0), "normalized Cerebras manifest model");
|
||||
return CEREBRAS_MODEL_CATALOG.map(
|
||||
buildManifestModelDefinition({ providerId: "cerebras", catalog: CEREBRAS_MANIFEST_CATALOG }),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,7 @@ import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import {
|
||||
buildCerebrasModelDefinition,
|
||||
CEREBRAS_BASE_URL,
|
||||
CEREBRAS_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
import { buildCerebrasCatalogModels, CEREBRAS_BASE_URL } from "./models.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
export const CEREBRAS_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(
|
||||
@@ -21,7 +17,7 @@ const cerebrasPresetAppliers = createModelCatalogPresetAppliers({
|
||||
providerId: "cerebras",
|
||||
api: "openai-completions",
|
||||
baseUrl: CEREBRAS_BASE_URL,
|
||||
catalogModels: CEREBRAS_MODEL_CATALOG.map(buildCerebrasModelDefinition),
|
||||
catalogModels: buildCerebrasCatalogModels(),
|
||||
aliases: [{ modelRef: CEREBRAS_DEFAULT_MODEL_REF, alias: "Cerebras GPT OSS 120B" }],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
export {
|
||||
buildChutesModelDefinition,
|
||||
CHUTES_BASE_URL,
|
||||
CHUTES_MODEL_CATALOG,
|
||||
discoverChutesModels,
|
||||
} from "./models.js";
|
||||
export { CHUTES_BASE_URL, CHUTES_MODEL_CATALOG, discoverChutesModels } from "./models.js";
|
||||
export { buildChutesProvider } from "./provider-catalog.js";
|
||||
export {
|
||||
applyChutesApiKeyConfig,
|
||||
|
||||
@@ -3,11 +3,7 @@ import { expectDefined } from "@openclaw/normalization-core";
|
||||
import { clearLiveCatalogCacheForTests } from "openclaw/plugin-sdk/provider-catalog-live-runtime";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { CHUTES_DEFAULT_MODEL_ID } from "./api.js";
|
||||
import {
|
||||
buildChutesModelDefinition,
|
||||
CHUTES_MODEL_CATALOG,
|
||||
discoverChutesModels,
|
||||
} from "./models.js";
|
||||
import { CHUTES_MODEL_CATALOG, discoverChutesModels } from "./models.js";
|
||||
import { applyChutesConfig, CHUTES_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
@@ -102,9 +98,9 @@ describe("chutes-models", () => {
|
||||
clearLiveCatalogCacheForTests();
|
||||
});
|
||||
|
||||
it("buildChutesModelDefinition returns config with required fields", () => {
|
||||
it("builds static definitions with required fields", () => {
|
||||
const entry = expectDefined(CHUTES_MODEL_CATALOG[0], "first Chutes catalog model");
|
||||
const def = buildChutesModelDefinition(entry);
|
||||
const def = entry;
|
||||
expect(def.id).toBe(entry.id);
|
||||
expect(def.name).toBe(entry.name);
|
||||
expect(def.reasoning).toBe(entry.reasoning);
|
||||
@@ -126,7 +122,7 @@ describe("chutes-models", () => {
|
||||
if (!model) {
|
||||
throw new Error(`expected ${id}`);
|
||||
}
|
||||
expect(buildChutesModelDefinition(model).input).toContain("image");
|
||||
expect(model.input).toContain("image");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+15
-13
@@ -6,7 +6,7 @@ import {
|
||||
getCachedLiveProviderModelRows,
|
||||
LiveModelCatalogHttpError,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-live-runtime";
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { buildManifestModelDefinition } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import {
|
||||
@@ -23,22 +23,15 @@ import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
const log = createSubsystemLogger("chutes-models");
|
||||
|
||||
const CHUTES_MANIFEST_PROVIDER = buildManifestModelProviderConfig({
|
||||
providerId: "chutes",
|
||||
catalog: manifest.modelCatalog.providers.chutes,
|
||||
});
|
||||
const CHUTES_MANIFEST_CATALOG = manifest.modelCatalog.providers.chutes;
|
||||
|
||||
/** Base URL for Chutes OpenAI-compatible inference. */
|
||||
export const CHUTES_BASE_URL = CHUTES_MANIFEST_PROVIDER.baseUrl;
|
||||
export const CHUTES_BASE_URL = CHUTES_MANIFEST_CATALOG.baseUrl;
|
||||
|
||||
const CHUTES_DEFAULT_CONTEXT_WINDOW = 128000;
|
||||
const CHUTES_DEFAULT_MAX_TOKENS = 4096;
|
||||
|
||||
/** Bundled fallback Chutes model catalog, normalized from the plugin manifest. */
|
||||
export const CHUTES_MODEL_CATALOG = CHUTES_MANIFEST_PROVIDER.models;
|
||||
|
||||
/** Adds Chutes provider compat metadata to one model catalog entry. */
|
||||
export function buildChutesModelDefinition(model: ModelDefinitionConfig): ModelDefinitionConfig {
|
||||
function decorateChutesModelDefinition(model: ModelDefinitionConfig): ModelDefinitionConfig {
|
||||
return {
|
||||
...model,
|
||||
compat: {
|
||||
@@ -48,6 +41,15 @@ export function buildChutesModelDefinition(model: ModelDefinitionConfig): ModelD
|
||||
};
|
||||
}
|
||||
|
||||
/** Bundled fallback Chutes model catalog, normalized from the plugin manifest. */
|
||||
export const CHUTES_MODEL_CATALOG: ModelDefinitionConfig[] = CHUTES_MANIFEST_CATALOG.models.map(
|
||||
buildManifestModelDefinition({
|
||||
providerId: "chutes",
|
||||
catalog: CHUTES_MANIFEST_CATALOG,
|
||||
decorate: decorateChutesModelDefinition,
|
||||
}),
|
||||
);
|
||||
|
||||
interface ChutesModelEntry {
|
||||
id: string;
|
||||
name?: string;
|
||||
@@ -87,10 +89,10 @@ export async function discoverChutesModels(accessToken?: string): Promise<ModelD
|
||||
const trimmedKey = normalizeOptionalString(accessToken) ?? "";
|
||||
|
||||
if (isChutesModelDiscoveryTestEnvironment()) {
|
||||
return CHUTES_MODEL_CATALOG.map(buildChutesModelDefinition);
|
||||
return structuredClone(CHUTES_MODEL_CATALOG);
|
||||
}
|
||||
|
||||
const staticCatalog = () => CHUTES_MODEL_CATALOG.map(buildChutesModelDefinition);
|
||||
const staticCatalog = () => structuredClone(CHUTES_MODEL_CATALOG);
|
||||
|
||||
try {
|
||||
const data = await fetchChutesModelRows(trimmedKey || undefined);
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import { CHUTES_BASE_URL, CHUTES_MODEL_CATALOG, buildChutesModelDefinition } from "./models.js";
|
||||
import { CHUTES_BASE_URL, CHUTES_MODEL_CATALOG } from "./models.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
export const CHUTES_DEFAULT_MODEL_ID = manifest.modelCatalog.providers.chutes.defaultModel;
|
||||
@@ -16,7 +16,7 @@ const chutesPresetAppliers = createModelCatalogPresetAppliers({
|
||||
providerId: "chutes",
|
||||
api: "openai-completions",
|
||||
baseUrl: CHUTES_BASE_URL,
|
||||
catalogModels: CHUTES_MODEL_CATALOG.map(buildChutesModelDefinition),
|
||||
catalogModels: structuredClone(CHUTES_MODEL_CATALOG),
|
||||
aliases: [
|
||||
...CHUTES_MODEL_CATALOG.map((model) => `chutes/${model.id}`),
|
||||
{
|
||||
|
||||
@@ -2,19 +2,14 @@
|
||||
* Chutes provider builders for static and dynamically discovered catalogs.
|
||||
*/
|
||||
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
CHUTES_BASE_URL,
|
||||
CHUTES_MODEL_CATALOG,
|
||||
buildChutesModelDefinition,
|
||||
discoverChutesModels,
|
||||
} from "./models.js";
|
||||
import { CHUTES_BASE_URL, CHUTES_MODEL_CATALOG, discoverChutesModels } from "./models.js";
|
||||
|
||||
/** Builds the static Chutes provider catalog from bundled model metadata. */
|
||||
export function buildStaticChutesProvider(): ModelProviderConfig {
|
||||
return {
|
||||
baseUrl: CHUTES_BASE_URL,
|
||||
api: "openai-completions",
|
||||
models: CHUTES_MODEL_CATALOG.map(buildChutesModelDefinition),
|
||||
models: structuredClone(CHUTES_MODEL_CATALOG),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -28,6 +23,6 @@ export async function buildChutesProvider(accessToken?: string): Promise<ModelPr
|
||||
return {
|
||||
baseUrl: CHUTES_BASE_URL,
|
||||
api: "openai-completions",
|
||||
models: models.length > 0 ? models : CHUTES_MODEL_CATALOG.map(buildChutesModelDefinition),
|
||||
models: models.length > 0 ? models : structuredClone(CHUTES_MODEL_CATALOG),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
/**
|
||||
* Cohere model catalog helpers derived from the plugin manifest.
|
||||
*/
|
||||
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { buildManifestModelDefinition } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
const COHERE_MANIFEST_CATALOG = manifest.modelCatalog.providers.cohere;
|
||||
|
||||
export const COHERE_BASE_URL = COHERE_MANIFEST_CATALOG.baseUrl;
|
||||
export const COHERE_MODEL_CATALOG = COHERE_MANIFEST_CATALOG.models;
|
||||
const COHERE_MODEL_CATALOG = COHERE_MANIFEST_CATALOG.models;
|
||||
const COHERE_COMMAND_A_PLUS_MODEL_ID = "command-a-plus-05-2026";
|
||||
const COHERE_COMMAND_A_REASONING_MODEL_ID = "command-a-reasoning-08-2025";
|
||||
const COHERE_NORTH_MINI_CODE_MODEL_ID = "north-mini-code-1-0";
|
||||
@@ -26,18 +25,7 @@ export function isModernCohereModelId(modelId: string): boolean {
|
||||
}
|
||||
|
||||
export function buildCohereCatalogModels(): ModelDefinitionConfig[] {
|
||||
return buildManifestModelProviderConfig({
|
||||
providerId: "cohere",
|
||||
catalog: COHERE_MANIFEST_CATALOG,
|
||||
}).models;
|
||||
}
|
||||
|
||||
export function buildCohereModelDefinition(
|
||||
model: (typeof COHERE_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
const providerConfig = buildManifestModelProviderConfig({
|
||||
providerId: "cohere",
|
||||
catalog: { ...COHERE_MANIFEST_CATALOG, models: [model] },
|
||||
});
|
||||
return expectDefined(providerConfig.models.at(0), "normalized Cohere manifest model");
|
||||
return COHERE_MODEL_CATALOG.map(
|
||||
buildManifestModelDefinition({ providerId: "cohere", catalog: COHERE_MANIFEST_CATALOG }),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
|
||||
import { resolveAgentModelPrimaryValue } from "openclaw/plugin-sdk/provider-onboard";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildCohereCatalogModels, COHERE_BASE_URL, COHERE_MODEL_CATALOG } from "./models.js";
|
||||
import { buildCohereCatalogModels, COHERE_BASE_URL } from "./models.js";
|
||||
import { applyCohereConfig, COHERE_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
const COHERE_DEFAULT_MODEL_ID = "command-a-plus-05-2026";
|
||||
const COHERE_COMMAND_A_REASONING_MODEL_ID = "command-a-reasoning-08-2025";
|
||||
@@ -25,7 +26,9 @@ describe("Cohere onboarding", () => {
|
||||
COHERE_COMMAND_A_VISION_MODEL_ID,
|
||||
COHERE_NORTH_MINI_CODE_MODEL_ID,
|
||||
]);
|
||||
expect(buildCohereCatalogModels()).toHaveLength(COHERE_MODEL_CATALOG.length);
|
||||
expect(buildCohereCatalogModels()).toHaveLength(
|
||||
manifest.modelCatalog.providers.cohere.models.length,
|
||||
);
|
||||
});
|
||||
|
||||
it("sets Cohere only when there is no primary model", () => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import { buildCohereModelDefinition, COHERE_BASE_URL, COHERE_MODEL_CATALOG } from "./models.js";
|
||||
import { buildCohereCatalogModels, COHERE_BASE_URL } from "./models.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
export const COHERE_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(manifest, "cohere")!;
|
||||
@@ -14,7 +14,7 @@ const coherePresetAppliers = createModelCatalogPresetAppliers({
|
||||
providerId: "cohere",
|
||||
api: "openai-completions",
|
||||
baseUrl: COHERE_BASE_URL,
|
||||
catalogModels: COHERE_MODEL_CATALOG.map(buildCohereModelDefinition),
|
||||
catalogModels: buildCohereCatalogModels(),
|
||||
aliases: [{ modelRef: COHERE_DEFAULT_MODEL_REF, alias: "Cohere Command A+" }],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
// Deepseek API module exposes the plugin public contract.
|
||||
export {
|
||||
buildDeepSeekModelDefinition,
|
||||
DEEPSEEK_BASE_URL,
|
||||
DEEPSEEK_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
export { DEEPSEEK_BASE_URL, DEEPSEEK_MODEL_CATALOG } from "./models.js";
|
||||
export { buildDeepSeekProvider } from "./provider-catalog.js";
|
||||
export { createDeepSeekV4ThinkingWrapper } from "./stream.js";
|
||||
|
||||
@@ -1,25 +1,18 @@
|
||||
// Deepseek plugin module implements models behavior.
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { buildManifestModelDefinition } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
const DEEPSEEK_MANIFEST_PROVIDER = buildManifestModelProviderConfig({
|
||||
providerId: "deepseek",
|
||||
catalog: manifest.modelCatalog.providers.deepseek,
|
||||
});
|
||||
const DEEPSEEK_MANIFEST_CATALOG = manifest.modelCatalog.providers.deepseek;
|
||||
export const DEEPSEEK_BASE_URL = DEEPSEEK_MANIFEST_CATALOG.baseUrl;
|
||||
|
||||
export const DEEPSEEK_BASE_URL = DEEPSEEK_MANIFEST_PROVIDER.baseUrl;
|
||||
|
||||
export const DEEPSEEK_MODEL_CATALOG: ModelDefinitionConfig[] = DEEPSEEK_MANIFEST_PROVIDER.models;
|
||||
|
||||
export function buildDeepSeekModelDefinition(
|
||||
model: (typeof DEEPSEEK_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
return {
|
||||
...model,
|
||||
api: "openai-completions",
|
||||
};
|
||||
}
|
||||
export const DEEPSEEK_MODEL_CATALOG: ModelDefinitionConfig[] = DEEPSEEK_MANIFEST_CATALOG.models.map(
|
||||
buildManifestModelDefinition({
|
||||
providerId: "deepseek",
|
||||
catalog: DEEPSEEK_MANIFEST_CATALOG,
|
||||
decorate: (model) => ({ ...model, api: "openai-completions" }),
|
||||
}),
|
||||
);
|
||||
|
||||
const DEEPSEEK_V4_MODEL_IDS = new Set(["deepseek-v4-flash", "deepseek-v4-pro"]);
|
||||
|
||||
|
||||
@@ -3,11 +3,7 @@ import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import {
|
||||
buildDeepSeekModelDefinition,
|
||||
DEEPSEEK_BASE_URL,
|
||||
DEEPSEEK_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
import { DEEPSEEK_BASE_URL, DEEPSEEK_MODEL_CATALOG } from "./models.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
export const DEEPSEEK_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(
|
||||
@@ -21,7 +17,7 @@ const deepSeekPresetAppliers = createModelCatalogPresetAppliers({
|
||||
providerId: "deepseek",
|
||||
api: "openai-completions",
|
||||
baseUrl: DEEPSEEK_BASE_URL,
|
||||
catalogModels: DEEPSEEK_MODEL_CATALOG.map(buildDeepSeekModelDefinition),
|
||||
catalogModels: structuredClone(DEEPSEEK_MODEL_CATALOG),
|
||||
aliases: [{ modelRef: DEEPSEEK_DEFAULT_MODEL_REF, alias: "DeepSeek" }],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
// Deepseek provider module implements model/runtime integration.
|
||||
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
buildDeepSeekModelDefinition,
|
||||
DEEPSEEK_BASE_URL,
|
||||
DEEPSEEK_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
import { DEEPSEEK_BASE_URL, DEEPSEEK_MODEL_CATALOG } from "./models.js";
|
||||
|
||||
export function buildDeepSeekProvider(): ModelProviderConfig {
|
||||
return {
|
||||
baseUrl: DEEPSEEK_BASE_URL,
|
||||
api: "openai-completions",
|
||||
models: DEEPSEEK_MODEL_CATALOG.map(buildDeepSeekModelDefinition),
|
||||
models: structuredClone(DEEPSEEK_MODEL_CATALOG),
|
||||
};
|
||||
}
|
||||
|
||||
+14
-16
@@ -1,20 +1,18 @@
|
||||
// Gmi plugin module implements models behavior.
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import {
|
||||
buildManifestModelDefinition,
|
||||
readManifestProviderDefaultModelRef,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
const GMI_MANIFEST_PROVIDER = buildManifestModelProviderConfig({
|
||||
providerId: "gmi",
|
||||
catalog: manifest.modelCatalog.providers.gmi,
|
||||
});
|
||||
|
||||
export const GMI_BASE_URL = GMI_MANIFEST_PROVIDER.baseUrl;
|
||||
export const GMI_MODEL_CATALOG: ModelDefinitionConfig[] = GMI_MANIFEST_PROVIDER.models;
|
||||
export const GMI_DEFAULT_MODEL_REF = "gmi/openai/gpt-5.6-sol";
|
||||
|
||||
export function buildGmiModelDefinition(model: ModelDefinitionConfig): ModelDefinitionConfig {
|
||||
return {
|
||||
...model,
|
||||
api: "openai-completions",
|
||||
};
|
||||
}
|
||||
const GMI_MANIFEST_CATALOG = manifest.modelCatalog.providers.gmi;
|
||||
export const GMI_BASE_URL = GMI_MANIFEST_CATALOG.baseUrl;
|
||||
export const GMI_MODEL_CATALOG: ModelDefinitionConfig[] = GMI_MANIFEST_CATALOG.models.map(
|
||||
buildManifestModelDefinition({
|
||||
providerId: "gmi",
|
||||
catalog: GMI_MANIFEST_CATALOG,
|
||||
decorate: (model) => ({ ...model, api: "openai-completions" }),
|
||||
}),
|
||||
);
|
||||
export const GMI_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(manifest, "gmi")!;
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
"gmi": {
|
||||
"baseUrl": "https://api.gmi-serving.com/v1",
|
||||
"api": "openai-completions",
|
||||
"defaultModel": "openai/gpt-5.6-sol",
|
||||
"models": [
|
||||
{
|
||||
"id": "zai-org/GLM-5.2-FP8",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// Gmi provider module implements model/runtime integration.
|
||||
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { GMI_BASE_URL, GMI_MODEL_CATALOG, buildGmiModelDefinition } from "./models.js";
|
||||
import { GMI_BASE_URL, GMI_MODEL_CATALOG } from "./models.js";
|
||||
|
||||
export function buildGmiProvider(): ModelProviderConfig {
|
||||
return {
|
||||
baseUrl: GMI_BASE_URL,
|
||||
api: "openai-completions",
|
||||
models: GMI_MODEL_CATALOG.map(buildGmiModelDefinition),
|
||||
models: structuredClone(GMI_MODEL_CATALOG),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
/**
|
||||
* Public Meta provider plugin API exports.
|
||||
*/
|
||||
export {
|
||||
buildMetaCatalogModels,
|
||||
buildMetaModelDefinition,
|
||||
META_BASE_URL,
|
||||
META_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
export { buildMetaCatalogModels, META_BASE_URL, META_MODEL_CATALOG } from "./models.js";
|
||||
export { buildMetaProvider } from "./provider-catalog.js";
|
||||
export { applyMetaConfig, META_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
|
||||
@@ -30,6 +30,7 @@ describe("meta provider", () => {
|
||||
id: "api-key",
|
||||
kind: "api_key",
|
||||
label: "Meta API key",
|
||||
starterModel: "meta/muse-spark-1.1",
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/**
|
||||
* Meta model catalog helpers derived from the plugin manifest.
|
||||
*/
|
||||
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { buildManifestModelDefinition } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
@@ -15,19 +14,7 @@ export const META_MODEL_CATALOG = META_MANIFEST_CATALOG.models;
|
||||
|
||||
/** Builds normalized Meta catalog model definitions. */
|
||||
export function buildMetaCatalogModels(): ModelDefinitionConfig[] {
|
||||
return buildManifestModelProviderConfig({
|
||||
providerId: "meta",
|
||||
catalog: META_MANIFEST_CATALOG,
|
||||
}).models;
|
||||
}
|
||||
|
||||
/** Builds one normalized Meta model definition from a manifest entry. */
|
||||
export function buildMetaModelDefinition(
|
||||
model: (typeof META_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
const providerConfig = buildManifestModelProviderConfig({
|
||||
providerId: "meta",
|
||||
catalog: { ...META_MANIFEST_CATALOG, models: [model] },
|
||||
});
|
||||
return expectDefined(providerConfig.models.at(0), "normalized Meta manifest model");
|
||||
return META_MODEL_CATALOG.map(
|
||||
buildManifestModelDefinition({ providerId: "meta", catalog: META_MANIFEST_CATALOG }),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
/**
|
||||
* Meta onboarding config helpers.
|
||||
*/
|
||||
import { readManifestProviderDefaultModelRef } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import { buildMetaModelDefinition, META_BASE_URL, META_MODEL_CATALOG } from "./models.js";
|
||||
import { buildMetaCatalogModels, META_BASE_URL } from "./models.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
/** Default Meta model reference used after onboarding. */
|
||||
export const META_DEFAULT_MODEL_REF = "meta/muse-spark-1.1";
|
||||
export const META_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(manifest, "meta")!;
|
||||
|
||||
const metaPresetAppliers = createModelCatalogPresetAppliers({
|
||||
primaryModelRef: META_DEFAULT_MODEL_REF,
|
||||
@@ -16,7 +18,7 @@ const metaPresetAppliers = createModelCatalogPresetAppliers({
|
||||
providerId: "meta",
|
||||
api: "openai-responses",
|
||||
baseUrl: META_BASE_URL,
|
||||
catalogModels: META_MODEL_CATALOG.map(buildMetaModelDefinition),
|
||||
catalogModels: buildMetaCatalogModels(),
|
||||
aliases: [{ modelRef: META_DEFAULT_MODEL_REF, alias: "Muse Spark 1.1" }],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
"meta": {
|
||||
"baseUrl": "https://api.meta.ai/v1",
|
||||
"api": "openai-responses",
|
||||
"defaultModel": "muse-spark-1.1",
|
||||
"models": [
|
||||
{
|
||||
"id": "muse-spark-1.1",
|
||||
|
||||
+14
-15
@@ -1,20 +1,19 @@
|
||||
// Novita plugin module implements models behavior.
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import {
|
||||
buildManifestModelDefinition,
|
||||
readManifestProviderDefaultModelRef,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
const NOVITA_MANIFEST_PROVIDER = buildManifestModelProviderConfig({
|
||||
providerId: "novita",
|
||||
catalog: manifest.modelCatalog.providers.novita,
|
||||
});
|
||||
const NOVITA_MANIFEST_CATALOG = manifest.modelCatalog.providers.novita;
|
||||
|
||||
export const NOVITA_BASE_URL = NOVITA_MANIFEST_PROVIDER.baseUrl;
|
||||
export const NOVITA_MODEL_CATALOG: ModelDefinitionConfig[] = NOVITA_MANIFEST_PROVIDER.models;
|
||||
export const NOVITA_DEFAULT_MODEL_REF = "novita/deepseek/deepseek-v4-pro";
|
||||
|
||||
export function buildNovitaModelDefinition(model: ModelDefinitionConfig): ModelDefinitionConfig {
|
||||
return {
|
||||
...model,
|
||||
api: "openai-completions",
|
||||
};
|
||||
}
|
||||
export const NOVITA_BASE_URL = NOVITA_MANIFEST_CATALOG.baseUrl;
|
||||
export const NOVITA_MODEL_CATALOG: ModelDefinitionConfig[] = NOVITA_MANIFEST_CATALOG.models.map(
|
||||
buildManifestModelDefinition({
|
||||
providerId: "novita",
|
||||
catalog: NOVITA_MANIFEST_CATALOG,
|
||||
decorate: (model) => ({ ...model, api: "openai-completions" }),
|
||||
}),
|
||||
);
|
||||
export const NOVITA_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(manifest, "novita")!;
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
"novita": {
|
||||
"baseUrl": "https://api.novita.ai/openai/v1",
|
||||
"api": "openai-completions",
|
||||
"defaultModel": "deepseek/deepseek-v4-pro",
|
||||
"models": [
|
||||
{
|
||||
"id": "moonshotai/kimi-k3",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// Novita provider module implements model/runtime integration.
|
||||
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { NOVITA_BASE_URL, NOVITA_MODEL_CATALOG, buildNovitaModelDefinition } from "./models.js";
|
||||
import { NOVITA_BASE_URL, NOVITA_MODEL_CATALOG } from "./models.js";
|
||||
|
||||
export function buildNovitaProvider(): ModelProviderConfig {
|
||||
return {
|
||||
baseUrl: NOVITA_BASE_URL,
|
||||
api: "openai-completions",
|
||||
models: NOVITA_MODEL_CATALOG.map(buildNovitaModelDefinition),
|
||||
models: structuredClone(NOVITA_MODEL_CATALOG),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Tencent API module exposes the plugin public contract.
|
||||
export {
|
||||
buildTokenHubModelDefinition,
|
||||
buildTokenPlanModelDefinition,
|
||||
TOKENHUB_BASE_URL,
|
||||
TOKENHUB_MODEL_CATALOG,
|
||||
TOKENHUB_PROVIDER_ID,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Tencent plugin module implements models behavior.
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { buildManifestModelDefinition } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
@@ -7,42 +7,29 @@ import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
export const TOKENHUB_PROVIDER_ID = "tencent-tokenhub";
|
||||
|
||||
const TOKENHUB_MANIFEST_PROVIDER = buildManifestModelProviderConfig({
|
||||
providerId: TOKENHUB_PROVIDER_ID,
|
||||
catalog: manifest.modelCatalog.providers[TOKENHUB_PROVIDER_ID],
|
||||
});
|
||||
export const TOKENHUB_BASE_URL = manifest.modelCatalog.providers[TOKENHUB_PROVIDER_ID].baseUrl;
|
||||
|
||||
export const TOKENHUB_BASE_URL = TOKENHUB_MANIFEST_PROVIDER.baseUrl;
|
||||
|
||||
export const TOKENHUB_MODEL_CATALOG: ModelDefinitionConfig[] = TOKENHUB_MANIFEST_PROVIDER.models;
|
||||
|
||||
export function buildTokenHubModelDefinition(
|
||||
model: (typeof TOKENHUB_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
return {
|
||||
...model,
|
||||
api: "openai-completions",
|
||||
};
|
||||
}
|
||||
const TOKENHUB_MANIFEST_CATALOG = manifest.modelCatalog.providers[TOKENHUB_PROVIDER_ID];
|
||||
export const TOKENHUB_MODEL_CATALOG: ModelDefinitionConfig[] = TOKENHUB_MANIFEST_CATALOG.models.map(
|
||||
buildManifestModelDefinition({
|
||||
providerId: TOKENHUB_PROVIDER_ID,
|
||||
catalog: TOKENHUB_MANIFEST_CATALOG,
|
||||
decorate: (model) => ({ ...model, api: "openai-completions" }),
|
||||
}),
|
||||
);
|
||||
|
||||
// ---------- TokenPlan provider ----------
|
||||
|
||||
export const TOKENPLAN_PROVIDER_ID = "tencent-tokenplan";
|
||||
|
||||
const TOKENPLAN_MANIFEST_PROVIDER = buildManifestModelProviderConfig({
|
||||
providerId: TOKENPLAN_PROVIDER_ID,
|
||||
catalog: manifest.modelCatalog.providers[TOKENPLAN_PROVIDER_ID],
|
||||
});
|
||||
export const TOKENPLAN_BASE_URL = manifest.modelCatalog.providers[TOKENPLAN_PROVIDER_ID].baseUrl;
|
||||
|
||||
export const TOKENPLAN_BASE_URL = TOKENPLAN_MANIFEST_PROVIDER.baseUrl;
|
||||
|
||||
export const TOKENPLAN_MODEL_CATALOG: ModelDefinitionConfig[] = TOKENPLAN_MANIFEST_PROVIDER.models;
|
||||
|
||||
export function buildTokenPlanModelDefinition(
|
||||
model: (typeof TOKENPLAN_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
return {
|
||||
...model,
|
||||
api: "openai-completions",
|
||||
};
|
||||
}
|
||||
const TOKENPLAN_MANIFEST_CATALOG = manifest.modelCatalog.providers[TOKENPLAN_PROVIDER_ID];
|
||||
export const TOKENPLAN_MODEL_CATALOG: ModelDefinitionConfig[] =
|
||||
TOKENPLAN_MANIFEST_CATALOG.models.map(
|
||||
buildManifestModelDefinition({
|
||||
providerId: TOKENPLAN_PROVIDER_ID,
|
||||
catalog: TOKENPLAN_MANIFEST_CATALOG,
|
||||
decorate: (model) => ({ ...model, api: "openai-completions" }),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -4,8 +4,6 @@ import {
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import {
|
||||
buildTokenHubModelDefinition,
|
||||
buildTokenPlanModelDefinition,
|
||||
TOKENHUB_BASE_URL,
|
||||
TOKENHUB_MODEL_CATALOG,
|
||||
TOKENHUB_PROVIDER_ID,
|
||||
@@ -27,7 +25,7 @@ const tokenHubPresetAppliers = createModelCatalogPresetAppliers({
|
||||
providerId: TOKENHUB_PROVIDER_ID,
|
||||
api: "openai-completions",
|
||||
baseUrl: TOKENHUB_BASE_URL,
|
||||
catalogModels: TOKENHUB_MODEL_CATALOG.map(buildTokenHubModelDefinition),
|
||||
catalogModels: structuredClone(TOKENHUB_MODEL_CATALOG),
|
||||
aliases: [
|
||||
{ modelRef: TOKENHUB_DEFAULT_MODEL_REF, alias: "Hy3 (TokenHub)" },
|
||||
{ modelRef: TOKENHUB_PREVIEW_MODEL_REF, alias: "Hy3 preview (TokenHub)" },
|
||||
@@ -50,7 +48,7 @@ const tokenPlanPresetAppliers = createModelCatalogPresetAppliers({
|
||||
providerId: TOKENPLAN_PROVIDER_ID,
|
||||
api: "openai-completions",
|
||||
baseUrl: TOKENPLAN_BASE_URL,
|
||||
catalogModels: TOKENPLAN_MODEL_CATALOG.map(buildTokenPlanModelDefinition),
|
||||
catalogModels: structuredClone(TOKENPLAN_MODEL_CATALOG),
|
||||
aliases: [{ modelRef: TOKENPLAN_DEFAULT_MODEL_REF, alias: "Hy3 (TokenPlan)" }],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Tencent provider module implements model/runtime integration.
|
||||
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
buildTokenHubModelDefinition,
|
||||
buildTokenPlanModelDefinition,
|
||||
TOKENHUB_BASE_URL,
|
||||
TOKENHUB_MODEL_CATALOG,
|
||||
TOKENPLAN_BASE_URL,
|
||||
@@ -13,7 +11,7 @@ export function buildTokenHubProvider(): ModelProviderConfig {
|
||||
return {
|
||||
baseUrl: TOKENHUB_BASE_URL,
|
||||
api: "openai-completions",
|
||||
models: TOKENHUB_MODEL_CATALOG.map(buildTokenHubModelDefinition),
|
||||
models: structuredClone(TOKENHUB_MODEL_CATALOG),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,6 +19,6 @@ export function buildTokenPlanProvider(): ModelProviderConfig {
|
||||
return {
|
||||
baseUrl: TOKENPLAN_BASE_URL,
|
||||
api: "openai-completions",
|
||||
models: TOKENPLAN_MODEL_CATALOG.map(buildTokenPlanModelDefinition),
|
||||
models: structuredClone(TOKENPLAN_MODEL_CATALOG),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
// Together API module exposes the plugin public contract.
|
||||
export {
|
||||
buildTogetherModelDefinition,
|
||||
TOGETHER_BASE_URL,
|
||||
TOGETHER_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
export { TOGETHER_BASE_URL, TOGETHER_MODEL_CATALOG } from "./models.js";
|
||||
export { buildTogetherProvider } from "./provider-catalog.js";
|
||||
export { applyTogetherConfig, TOGETHER_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
// Together plugin module implements models behavior.
|
||||
import { buildManifestModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { buildManifestModelDefinition } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
const TOGETHER_MANIFEST_PROVIDER = buildManifestModelProviderConfig({
|
||||
providerId: "together",
|
||||
catalog: manifest.modelCatalog.providers.together,
|
||||
});
|
||||
const TOGETHER_MANIFEST_CATALOG = manifest.modelCatalog.providers.together;
|
||||
export const TOGETHER_BASE_URL = TOGETHER_MANIFEST_CATALOG.baseUrl;
|
||||
|
||||
export const TOGETHER_BASE_URL = TOGETHER_MANIFEST_PROVIDER.baseUrl;
|
||||
|
||||
export const TOGETHER_MODEL_CATALOG: ModelDefinitionConfig[] = TOGETHER_MANIFEST_PROVIDER.models;
|
||||
|
||||
export function buildTogetherModelDefinition(
|
||||
model: (typeof TOGETHER_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
return {
|
||||
...model,
|
||||
api: "openai-completions",
|
||||
input: [...model.input],
|
||||
cost: { ...model.cost },
|
||||
};
|
||||
}
|
||||
export const TOGETHER_MODEL_CATALOG: ModelDefinitionConfig[] = TOGETHER_MANIFEST_CATALOG.models.map(
|
||||
buildManifestModelDefinition({
|
||||
providerId: "together",
|
||||
catalog: TOGETHER_MANIFEST_CATALOG,
|
||||
decorate: (model) => ({ ...model, api: "openai-completions" }),
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { resolveAgentModelPrimaryValue } from "openclaw/plugin-sdk/provider-onboard";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { TOGETHER_MODEL_CATALOG } from "./models.js";
|
||||
import { applyTogetherConfig, TOGETHER_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
describe("Together onboarding", () => {
|
||||
it("applies the manifest catalog, default, and alias", () => {
|
||||
const config = applyTogetherConfig({});
|
||||
|
||||
expect(config.models?.providers?.together?.models.map((model) => model.id)).toEqual(
|
||||
TOGETHER_MODEL_CATALOG.map((model) => model.id),
|
||||
);
|
||||
expect(resolveAgentModelPrimaryValue(config.agents?.defaults?.model)).toBe(
|
||||
TOGETHER_DEFAULT_MODEL_REF,
|
||||
);
|
||||
expect(TOGETHER_DEFAULT_MODEL_REF).toBe(
|
||||
`together/${manifest.modelCatalog.providers.together.defaultModel}`,
|
||||
);
|
||||
expect(config.agents?.defaults?.models?.[TOGETHER_DEFAULT_MODEL_REF]).toEqual({
|
||||
alias: "Together AI",
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,15 +1,16 @@
|
||||
// Together setup module handles plugin onboarding behavior.
|
||||
import { readManifestProviderDefaultModelRef } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import {
|
||||
buildTogetherModelDefinition,
|
||||
TOGETHER_BASE_URL,
|
||||
TOGETHER_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
import { TOGETHER_BASE_URL, TOGETHER_MODEL_CATALOG } from "./models.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
export const TOGETHER_DEFAULT_MODEL_REF = "together/meta-llama/Llama-3.3-70B-Instruct-Turbo";
|
||||
export const TOGETHER_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(
|
||||
manifest,
|
||||
"together",
|
||||
)!;
|
||||
|
||||
const togetherPresetAppliers = createModelCatalogPresetAppliers({
|
||||
primaryModelRef: TOGETHER_DEFAULT_MODEL_REF,
|
||||
@@ -17,7 +18,7 @@ const togetherPresetAppliers = createModelCatalogPresetAppliers({
|
||||
providerId: "together",
|
||||
api: "openai-completions",
|
||||
baseUrl: TOGETHER_BASE_URL,
|
||||
catalogModels: TOGETHER_MODEL_CATALOG.map(buildTogetherModelDefinition),
|
||||
catalogModels: structuredClone(TOGETHER_MODEL_CATALOG),
|
||||
aliases: [{ modelRef: TOGETHER_DEFAULT_MODEL_REF, alias: "Together AI" }],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
"together": {
|
||||
"baseUrl": "https://api.together.xyz/v1",
|
||||
"api": "openai-completions",
|
||||
"defaultModel": "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
||||
"models": [
|
||||
{
|
||||
"id": "moonshotai/Kimi-K2.6",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Venice API module exposes the plugin public contract.
|
||||
export {
|
||||
buildVeniceModelDefinition,
|
||||
discoverVeniceModels,
|
||||
VENICE_BASE_URL,
|
||||
VENICE_DEFAULT_MODEL_REF,
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
import { expectDefined } from "@openclaw/normalization-core";
|
||||
import { clearLiveCatalogCacheForTests } from "openclaw/plugin-sdk/provider-catalog-live-runtime";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
buildVeniceModelDefinition,
|
||||
discoverVeniceModels,
|
||||
VENICE_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
import { discoverVeniceModels, VENICE_MODEL_CATALOG } from "./models.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
const ORIGINAL_NODE_ENV = process.env.NODE_ENV;
|
||||
@@ -119,9 +115,9 @@ describe("venice-models", () => {
|
||||
restoreDiscoveryEnv();
|
||||
});
|
||||
|
||||
it("buildVeniceModelDefinition returns config with required fields", () => {
|
||||
it("builds static definitions with required fields", () => {
|
||||
const entry = expectDefined(VENICE_MODEL_CATALOG[0], "first Venice catalog model");
|
||||
const def = buildVeniceModelDefinition(entry);
|
||||
const def = entry;
|
||||
expect(def.id).toBe(entry.id);
|
||||
expect(def.name).toBe(entry.name);
|
||||
expect(def.reasoning).toBe(entry.reasoning);
|
||||
@@ -241,9 +237,7 @@ describe("venice-models", () => {
|
||||
});
|
||||
|
||||
it("keeps tools enabled for DeepSeek V3.2", () => {
|
||||
const model = buildVeniceModelDefinition(
|
||||
VENICE_MODEL_CATALOG.find((entry) => entry.id === "deepseek-v3.2")!,
|
||||
);
|
||||
const model = VENICE_MODEL_CATALOG.find((entry) => entry.id === "deepseek-v3.2")!;
|
||||
expect(model.compat?.supportsTools).toBeUndefined();
|
||||
});
|
||||
|
||||
|
||||
+26
-24
@@ -3,7 +3,7 @@ import {
|
||||
LiveModelCatalogHttpError,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-live-runtime";
|
||||
import {
|
||||
buildManifestModelProviderConfig,
|
||||
buildManifestModelDefinition,
|
||||
readManifestProviderDefaultModelRef,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import type { ModelDefinitionConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
@@ -12,13 +12,9 @@ import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coer
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
|
||||
const log = createSubsystemLogger("venice-models");
|
||||
const VENICE_MANIFEST_CATALOG = manifest.modelCatalog.providers.venice;
|
||||
|
||||
const VENICE_MANIFEST_PROVIDER = buildManifestModelProviderConfig({
|
||||
providerId: "venice",
|
||||
catalog: manifest.modelCatalog.providers.venice,
|
||||
});
|
||||
|
||||
export const VENICE_BASE_URL = VENICE_MANIFEST_PROVIDER.baseUrl;
|
||||
export const VENICE_BASE_URL = VENICE_MANIFEST_CATALOG.baseUrl;
|
||||
export const VENICE_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(manifest, "venice")!;
|
||||
const VENICE_ALLOWED_HOSTNAMES = ["api.venice.ai"];
|
||||
|
||||
@@ -51,11 +47,7 @@ const VENICE_DISCOVERY_RETRYABLE_NETWORK_CODES = new Set([
|
||||
"UND_ERR_SOCKET",
|
||||
]);
|
||||
|
||||
export const VENICE_MODEL_CATALOG: ModelDefinitionConfig[] = VENICE_MANIFEST_PROVIDER.models;
|
||||
|
||||
type VeniceCatalogEntry = ModelDefinitionConfig;
|
||||
|
||||
export function buildVeniceModelDefinition(entry: VeniceCatalogEntry): ModelDefinitionConfig {
|
||||
function decorateVeniceModelDefinition(entry: ModelDefinitionConfig): ModelDefinitionConfig {
|
||||
return {
|
||||
id: entry.id,
|
||||
name: entry.name,
|
||||
@@ -71,6 +63,15 @@ export function buildVeniceModelDefinition(entry: VeniceCatalogEntry): ModelDefi
|
||||
};
|
||||
}
|
||||
|
||||
/** Venice's decorated network-free fallback catalog. */
|
||||
export const VENICE_MODEL_CATALOG: ModelDefinitionConfig[] = VENICE_MANIFEST_CATALOG.models.map(
|
||||
buildManifestModelDefinition({
|
||||
providerId: "venice",
|
||||
catalog: VENICE_MANIFEST_CATALOG,
|
||||
decorate: decorateVeniceModelDefinition,
|
||||
}),
|
||||
);
|
||||
|
||||
interface VeniceModelSpec {
|
||||
name: string;
|
||||
privacy: "private" | "anonymized";
|
||||
@@ -88,10 +89,6 @@ interface VeniceModel {
|
||||
model_spec?: VeniceModelSpec;
|
||||
}
|
||||
|
||||
function staticVeniceModelDefinitions(): ModelDefinitionConfig[] {
|
||||
return VENICE_MODEL_CATALOG.map(buildVeniceModelDefinition);
|
||||
}
|
||||
|
||||
function hasRetryableNetworkCode(err: unknown): boolean {
|
||||
const queue: unknown[] = [err];
|
||||
const seen = new Set<unknown>();
|
||||
@@ -177,7 +174,7 @@ export async function discoverVeniceModels(
|
||||
options: VeniceModelDiscoveryOptions = {},
|
||||
): Promise<ModelDefinitionConfig[]> {
|
||||
if (process.env.NODE_ENV === "test" || process.env.VITEST) {
|
||||
return staticVeniceModelDefinitions();
|
||||
return structuredClone(VENICE_MODEL_CATALOG);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -203,11 +200,11 @@ export async function discoverVeniceModels(
|
||||
|
||||
if (data.length === 0) {
|
||||
log.warn("No models found from API, using static catalog");
|
||||
return staticVeniceModelDefinitions();
|
||||
return structuredClone(VENICE_MODEL_CATALOG);
|
||||
}
|
||||
|
||||
const catalogById = new Map<string, VeniceCatalogEntry>(
|
||||
VENICE_MODEL_CATALOG.map((m) => [m.id, m]),
|
||||
const catalogById = new Map<string, ModelDefinitionConfig>(
|
||||
structuredClone(VENICE_MODEL_CATALOG).map((model) => [model.id, model]),
|
||||
);
|
||||
const models: ModelDefinitionConfig[] = [];
|
||||
|
||||
@@ -219,7 +216,12 @@ export async function discoverVeniceModels(
|
||||
});
|
||||
const apiSupportsTools = resolveApiSupportsTools(apiModel);
|
||||
if (catalogEntry) {
|
||||
const definition = buildVeniceModelDefinition(catalogEntry);
|
||||
const definition: ModelDefinitionConfig = {
|
||||
...catalogEntry,
|
||||
input: [...catalogEntry.input],
|
||||
cost: { ...catalogEntry.cost },
|
||||
...(catalogEntry.compat ? { compat: { ...catalogEntry.compat } } : {}),
|
||||
};
|
||||
if (apiMaxTokens !== undefined) {
|
||||
definition.maxTokens = apiMaxTokens;
|
||||
}
|
||||
@@ -258,13 +260,13 @@ export async function discoverVeniceModels(
|
||||
}
|
||||
}
|
||||
|
||||
return models.length > 0 ? models : staticVeniceModelDefinitions();
|
||||
return models.length > 0 ? models : structuredClone(VENICE_MODEL_CATALOG);
|
||||
} catch (error) {
|
||||
if (error instanceof LiveModelCatalogHttpError) {
|
||||
log.warn(`Failed to discover models: HTTP ${error.status}, using static catalog`);
|
||||
return staticVeniceModelDefinitions();
|
||||
return structuredClone(VENICE_MODEL_CATALOG);
|
||||
}
|
||||
log.warn(`Discovery failed: ${String(error)}, using static catalog`);
|
||||
return staticVeniceModelDefinitions();
|
||||
return structuredClone(VENICE_MODEL_CATALOG);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,7 @@ import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import {
|
||||
buildVeniceModelDefinition,
|
||||
VENICE_BASE_URL,
|
||||
VENICE_DEFAULT_MODEL_REF,
|
||||
VENICE_MODEL_CATALOG,
|
||||
} from "./api.js";
|
||||
import { VENICE_BASE_URL, VENICE_DEFAULT_MODEL_REF, VENICE_MODEL_CATALOG } from "./api.js";
|
||||
|
||||
const venicePresetAppliers = createModelCatalogPresetAppliers({
|
||||
primaryModelRef: VENICE_DEFAULT_MODEL_REF,
|
||||
@@ -16,7 +11,7 @@ const venicePresetAppliers = createModelCatalogPresetAppliers({
|
||||
providerId: "venice",
|
||||
api: "openai-completions",
|
||||
baseUrl: VENICE_BASE_URL,
|
||||
catalogModels: VENICE_MODEL_CATALOG.map(buildVeniceModelDefinition),
|
||||
catalogModels: structuredClone(VENICE_MODEL_CATALOG),
|
||||
aliases: [{ modelRef: VENICE_DEFAULT_MODEL_REF, alias: "Kimi K2.6" }],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -50,7 +50,6 @@ export function applyVolcengineToolSchemaCompat<T extends { compat?: ModelCompat
|
||||
|
||||
export { buildDoubaoCodingProvider, buildDoubaoProvider } from "./provider-catalog.js";
|
||||
export {
|
||||
buildDoubaoModelDefinition,
|
||||
DOUBAO_BASE_URL,
|
||||
DOUBAO_CODING_BASE_URL,
|
||||
DOUBAO_CODING_MODEL_CATALOG,
|
||||
|
||||
@@ -13,6 +13,7 @@ import { DOUBAO_CODING_MODEL_CATALOG, DOUBAO_MODEL_CATALOG } from "./models.js";
|
||||
describe("volcengine plugin", () => {
|
||||
it("augments the catalog with bundled standard and plan models", async () => {
|
||||
const provider = await registerSingleProviderPlugin(plugin);
|
||||
expect(provider.auth?.[0]?.starterModel).toBe("volcengine-plan/ark-code-latest");
|
||||
const entries = await provider.augmentModelCatalog?.({
|
||||
env: process.env,
|
||||
entries: [],
|
||||
|
||||
@@ -2,13 +2,18 @@
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import { buildOpenAICompatibleLiveModelProviderConfig } from "openclaw/plugin-sdk/provider-catalog-live-runtime";
|
||||
import { readManifestProviderDefaultModelRef } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { ensureModelAllowlistEntry } from "openclaw/plugin-sdk/provider-onboard";
|
||||
import { applyVolcengineToolSchemaCompat } from "./api.js";
|
||||
import manifest from "./openclaw.plugin.json" with { type: "json" };
|
||||
import { VOLCENGINE_PROVIDER_CATALOG_ENTRIES } from "./provider-catalog.js";
|
||||
import { buildVolcengineSpeechProvider } from "./speech-provider.js";
|
||||
|
||||
const PROVIDER_ID = "volcengine";
|
||||
const VOLCENGINE_DEFAULT_MODEL_REF = "volcengine-plan/ark-code-latest";
|
||||
const VOLCENGINE_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef(
|
||||
manifest,
|
||||
"volcengine-plan",
|
||||
)!;
|
||||
|
||||
export default definePluginEntry({
|
||||
id: PROVIDER_ID,
|
||||
|
||||
@@ -19,11 +19,3 @@ export const DOUBAO_CODING_BASE_URL = DOUBAO_CODING_MANIFEST_PROVIDER.baseUrl;
|
||||
export const DOUBAO_MODEL_CATALOG: ModelDefinitionConfig[] = DOUBAO_MANIFEST_PROVIDER.models;
|
||||
export const DOUBAO_CODING_MODEL_CATALOG: ModelDefinitionConfig[] =
|
||||
DOUBAO_CODING_MANIFEST_PROVIDER.models;
|
||||
|
||||
export function buildDoubaoModelDefinition(entry: ModelDefinitionConfig): ModelDefinitionConfig {
|
||||
return {
|
||||
...entry,
|
||||
input: [...entry.input],
|
||||
cost: { ...entry.cost },
|
||||
};
|
||||
}
|
||||
|
||||
@@ -230,6 +230,7 @@
|
||||
"volcengine-plan": {
|
||||
"baseUrl": "https://ark.cn-beijing.volces.com/api/coding/v3",
|
||||
"api": "openai-completions",
|
||||
"defaultModel": "ark-code-latest",
|
||||
"models": [
|
||||
{
|
||||
"id": "ark-code-latest",
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { ModelCatalogProvider } from "@openclaw/model-catalog-core/model-ca
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
applyProviderNativeStreamingUsageCompat,
|
||||
buildManifestModelDefinition,
|
||||
buildManifestModelProviderConfig,
|
||||
clearLiveCatalogCacheForTests,
|
||||
getCachedLiveCatalogValue,
|
||||
@@ -376,6 +377,20 @@ describe("provider-catalog-shared manifest provider configs", () => {
|
||||
"example",
|
||||
),
|
||||
).toBe("example/example-model");
|
||||
|
||||
expect(
|
||||
buildManifestModelDefinition({
|
||||
providerId: "example",
|
||||
catalog,
|
||||
decorate: (model) => ({
|
||||
...model,
|
||||
compat: { ...model.compat, supportsUsageInStreaming: false },
|
||||
}),
|
||||
})(catalog.models[0]),
|
||||
).toEqual({
|
||||
...buildManifestModelProviderConfig({ providerId: "example", catalog }).models[0],
|
||||
compat: { supportsUsageInStreaming: false },
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes retired nested Gemini ids before emitting manifest provider config", () => {
|
||||
|
||||
@@ -246,6 +246,32 @@ export function buildManifestModelProviderConfig(params: {
|
||||
};
|
||||
}
|
||||
|
||||
/** Builds one normalized runtime model row from a provider manifest catalog entry. */
|
||||
export function buildManifestModelDefinition(params: {
|
||||
/** Provider id that owns the manifest catalog row. */
|
||||
providerId: string;
|
||||
/** Raw manifest modelCatalog provider block that contains the row. */
|
||||
catalog: unknown;
|
||||
/** Optional provider policy applied after manifest normalization. */
|
||||
decorate?: (model: ModelDefinitionConfig) => ModelDefinitionConfig;
|
||||
}): (model: unknown) => ModelDefinitionConfig {
|
||||
if (!params.catalog || typeof params.catalog !== "object" || Array.isArray(params.catalog)) {
|
||||
throw new Error(`Missing modelCatalog.providers.${params.providerId}`);
|
||||
}
|
||||
const catalog = params.catalog;
|
||||
return (rawModel) => {
|
||||
const provider = buildManifestModelProviderConfig({
|
||||
providerId: params.providerId,
|
||||
catalog: { ...catalog, models: [rawModel] },
|
||||
});
|
||||
const model = provider.models[0];
|
||||
if (!model) {
|
||||
throw new Error(`Missing modelCatalog.providers.${params.providerId}.models[0]`);
|
||||
}
|
||||
return params.decorate?.(model) ?? model;
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeConfiguredCatalogModelInput(
|
||||
input: unknown,
|
||||
): ConfiguredProviderCatalogEntry["input"] | undefined {
|
||||
|
||||
Reference in New Issue
Block a user