mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-27 04:47:03 -06:00
fix(providers): publish Meta provider (#103070)
(cherry picked from commit 266ca5b3a2)
This commit is contained in:
@@ -458,6 +458,11 @@
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/longcat/**"
|
||||
- "docs/providers/longcat.md"
|
||||
"extensions: meta":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/meta/**"
|
||||
- "docs/providers/meta.md"
|
||||
"extensions: minimax":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
|
||||
@@ -1483,6 +1483,7 @@
|
||||
"providers/litellm",
|
||||
"providers/lmstudio",
|
||||
"providers/longcat",
|
||||
"providers/meta",
|
||||
"providers/minimax",
|
||||
"providers/mistral",
|
||||
"providers/moonshot",
|
||||
|
||||
+11
-2
@@ -6352,6 +6352,15 @@ Do not edit it by hand; run `pnpm docs:map:gen`.
|
||||
- H2: Surface
|
||||
- H2: Related docs
|
||||
|
||||
## plugins/reference/meta.md
|
||||
|
||||
- Route: /plugins/reference/meta
|
||||
- Headings:
|
||||
- H1: Meta plugin
|
||||
- H2: Distribution
|
||||
- H2: Surface
|
||||
- H2: Related docs
|
||||
|
||||
## plugins/reference/microsoft-foundry.md
|
||||
|
||||
- Route: /plugins/reference/microsoft-foundry
|
||||
@@ -7634,9 +7643,9 @@ Do not edit it by hand; run `pnpm docs:map:gen`.
|
||||
- H2: Troubleshooting
|
||||
- H2: Related
|
||||
|
||||
## providers/meta-model-api.md
|
||||
## providers/meta.md
|
||||
|
||||
- Route: /providers/meta-model-api
|
||||
- Route: /providers/meta
|
||||
- Headings:
|
||||
- H2: Getting started
|
||||
- H2: Non-interactive setup
|
||||
|
||||
@@ -51,7 +51,7 @@ Each entry lists the package, distribution route, and description.
|
||||
|
||||
## Core npm package
|
||||
|
||||
61 plugins
|
||||
62 plugins
|
||||
|
||||
- **[admin-http-rpc](/plugins/reference/admin-http-rpc)** (`@openclaw/admin-http-rpc`) - included in OpenClaw. OpenClaw admin HTTP RPC endpoint.
|
||||
|
||||
@@ -111,6 +111,8 @@ Each entry lists the package, distribution route, and description.
|
||||
|
||||
- **[memory-wiki](/plugins/reference/memory-wiki)** (`@openclaw/memory-wiki`) - included in OpenClaw. Persistent wiki compiler and Obsidian-friendly knowledge vault for OpenClaw.
|
||||
|
||||
- **[meta](/plugins/reference/meta)** (`@openclaw/meta-provider`) - included in OpenClaw; npm; ClawHub: `clawhub:@openclaw/meta-provider`. Adds Meta model provider support to OpenClaw.
|
||||
|
||||
- **[microsoft](/plugins/reference/microsoft)** (`@openclaw/microsoft-speech`) - included in OpenClaw. Adds text-to-speech provider support.
|
||||
|
||||
- **[microsoft-foundry](/plugins/reference/microsoft-foundry)** (`@openclaw/microsoft-foundry`) - included in OpenClaw. Adds Microsoft Foundry model provider support to OpenClaw.
|
||||
|
||||
@@ -15,5 +15,5 @@ This page is generated from `extensions/*/package.json` and
|
||||
pnpm plugins:inventory:gen
|
||||
```
|
||||
|
||||
Use [Plugin inventory](/plugins/plugin-inventory) to browse all 133
|
||||
Use [Plugin inventory](/plugins/plugin-inventory) to browse all 134
|
||||
generated plugin reference pages by distribution, package, and description.
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
summary: "Adds Meta model provider support to OpenClaw."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the meta plugin
|
||||
title: "Meta plugin"
|
||||
---
|
||||
|
||||
# Meta plugin
|
||||
|
||||
Adds Meta model provider support to OpenClaw.
|
||||
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/meta-provider`
|
||||
- Install route: included in OpenClaw; npm; ClawHub: `clawhub:@openclaw/meta-provider`
|
||||
|
||||
## Surface
|
||||
|
||||
providers: meta
|
||||
|
||||
## Related docs
|
||||
|
||||
- [meta](/providers/meta)
|
||||
@@ -1,26 +1,26 @@
|
||||
---
|
||||
summary: "Meta Model API setup (auth + muse-spark-1.1 model selection)"
|
||||
title: "Meta Model API"
|
||||
summary: "Meta setup (auth + muse-spark-1.1 model selection)"
|
||||
title: "Meta"
|
||||
read_when:
|
||||
- You want to use the Meta Model API with OpenClaw
|
||||
- You want to use Meta with OpenClaw
|
||||
- You need the MODEL_API_KEY env var or CLI auth choice
|
||||
---
|
||||
|
||||
The **Meta Model API** uses the OpenAI-compatible **Responses API** (`POST /v1/responses`)
|
||||
The **Meta API** uses the OpenAI-compatible **Responses API** (`POST /v1/responses`)
|
||||
for the `muse-spark-1.1` reasoning model. The provider ships as a bundled OpenClaw
|
||||
plugin.
|
||||
|
||||
| Property | Value |
|
||||
| ----------------- | -------------------------------------- |
|
||||
| Provider id | `meta-model-api` |
|
||||
| Plugin | bundled provider |
|
||||
| Auth env var | `MODEL_API_KEY` |
|
||||
| Onboarding flag | `--auth-choice meta-model-api-api-key` |
|
||||
| Direct CLI flag | `--meta-model-api-key <key>` |
|
||||
| API | Responses API (`openai-responses`) |
|
||||
| Base URL | `https://api.ai.meta.com/v1` |
|
||||
| Default model | `meta-model-api/muse-spark-1.1` |
|
||||
| Default reasoning | `high` (`reasoning.effort`) |
|
||||
| Property | Value |
|
||||
| ----------------- | ---------------------------------- |
|
||||
| Provider id | `meta` |
|
||||
| Plugin | bundled provider |
|
||||
| Auth env var | `MODEL_API_KEY` |
|
||||
| Onboarding flag | `--auth-choice meta-api-key` |
|
||||
| Direct CLI flag | `--meta-api-key <key>` |
|
||||
| API | Responses API (`openai-responses`) |
|
||||
| Base URL | `https://api.ai.meta.com/v1` |
|
||||
| Default model | `meta/muse-spark-1.1` |
|
||||
| Default reasoning | `high` (`reasoning.effort`) |
|
||||
|
||||
## Getting started
|
||||
|
||||
@@ -29,13 +29,13 @@ plugin.
|
||||
<CodeGroup>
|
||||
|
||||
```bash Onboarding
|
||||
openclaw onboard --auth-choice meta-model-api-api-key
|
||||
openclaw onboard --auth-choice meta-api-key
|
||||
```
|
||||
|
||||
```bash Direct flag
|
||||
openclaw onboard --non-interactive --accept-risk \
|
||||
--auth-choice meta-model-api-api-key \
|
||||
--meta-model-api-key "$MODEL_API_KEY"
|
||||
--auth-choice meta-api-key \
|
||||
--meta-api-key "$MODEL_API_KEY"
|
||||
```
|
||||
|
||||
```bash Env only
|
||||
@@ -47,7 +47,7 @@ export MODEL_API_KEY=<key>
|
||||
</Step>
|
||||
<Step title="Verify models are available">
|
||||
```bash
|
||||
openclaw models list --provider meta-model-api
|
||||
openclaw models list --provider meta
|
||||
```
|
||||
|
||||
Lists the static `muse-spark-1.1` catalog entry. If `MODEL_API_KEY` is unresolved,
|
||||
@@ -62,15 +62,15 @@ export MODEL_API_KEY=<key>
|
||||
```bash
|
||||
openclaw onboard --non-interactive --accept-risk \
|
||||
--mode local \
|
||||
--auth-choice meta-model-api-api-key \
|
||||
--meta-model-api-key "$MODEL_API_KEY"
|
||||
--auth-choice meta-api-key \
|
||||
--meta-api-key "$MODEL_API_KEY"
|
||||
```
|
||||
|
||||
## Built-in catalog
|
||||
|
||||
| Model ref | Name | Reasoning | Context window | Max output |
|
||||
| ------------------------------- | -------------- | --------- | -------------- | ---------- |
|
||||
| `meta-model-api/muse-spark-1.1` | Muse Spark 1.1 | yes | 1,048,576 | 128,000 |
|
||||
| Model ref | Name | Reasoning | Context window | Max output |
|
||||
| --------------------- | -------------- | --------- | -------------- | ---------- |
|
||||
| `meta/muse-spark-1.1` | Muse Spark 1.1 | yes | 1,048,576 | 128,000 |
|
||||
|
||||
Capabilities:
|
||||
|
||||
@@ -86,7 +86,7 @@ Capabilities:
|
||||
|
||||
<Note>
|
||||
Until `muse-spark-1.1` is deployed, smoke tests and manual checks can use the
|
||||
deployed `muse-spark` model id: `--model meta-model-api/muse-spark`.
|
||||
deployed `muse-spark` model id: `--model meta/muse-spark`.
|
||||
</Note>
|
||||
|
||||
## Manual config
|
||||
@@ -96,9 +96,9 @@ deployed `muse-spark` model id: `--model meta-model-api/muse-spark`.
|
||||
env: { MODEL_API_KEY: "<key>" },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "meta-model-api/muse-spark-1.1" },
|
||||
model: { primary: "meta/muse-spark-1.1" },
|
||||
models: {
|
||||
"meta-model-api/muse-spark-1.1": { alias: "Muse Spark 1.1" },
|
||||
"meta/muse-spark-1.1": { alias: "Muse Spark 1.1" },
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -118,8 +118,8 @@ separately.
|
||||
```bash
|
||||
export MODEL_API_KEY=<key>
|
||||
export OPENCLAW_LIVE_TEST=1
|
||||
export META_MODEL_API_LIVE_TEST=1
|
||||
pnpm test extensions/meta-model-api/meta-model-api.live.test.ts
|
||||
export META_LIVE_TEST=1
|
||||
pnpm test extensions/meta/meta.live.test.ts
|
||||
```
|
||||
|
||||
Live tests use deployed `muse-spark` against `POST /v1/responses`.
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Public Meta Model API provider plugin API exports.
|
||||
*/
|
||||
export {
|
||||
buildMetaModelApiCatalogModels,
|
||||
buildMetaModelApiModelDefinition,
|
||||
META_MODEL_API_BASE_URL,
|
||||
META_MODEL_API_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
export { buildMetaModelApiProvider } from "./provider-catalog.js";
|
||||
export { applyMetaModelApiConfig, META_MODEL_API_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* Meta Model API provider plugin entrypoint.
|
||||
*/
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { applyMetaModelApiConfig, META_MODEL_API_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
import { buildMetaModelApiProvider } from "./provider-catalog.js";
|
||||
import { wrapMetaModelApiProviderStream } from "./stream.js";
|
||||
import { resolveMetaModelApiThinkingProfile } from "./thinking.js";
|
||||
|
||||
const PROVIDER_ID = "meta-model-api";
|
||||
|
||||
export default defineSingleProviderPluginEntry({
|
||||
id: PROVIDER_ID,
|
||||
name: "Meta Model API Provider",
|
||||
description: "Bundled Meta Model API provider plugin",
|
||||
provider: {
|
||||
label: "Meta Model API",
|
||||
docsPath: "/providers/meta-model-api",
|
||||
auth: [
|
||||
{
|
||||
methodId: "api-key",
|
||||
label: "Meta Model API key",
|
||||
hint: "Meta Model API (Responses API)",
|
||||
optionKey: "metaModelApiKey",
|
||||
flagName: "--meta-model-api-key",
|
||||
envVar: "MODEL_API_KEY",
|
||||
promptMessage: "Enter Meta Model API key",
|
||||
defaultModel: META_MODEL_API_DEFAULT_MODEL_REF,
|
||||
applyConfig: (cfg) => applyMetaModelApiConfig(cfg),
|
||||
noteMessage: ["Meta Model API provides Responses API inference."].join("\n"),
|
||||
noteTitle: "Meta Model API",
|
||||
wizard: {
|
||||
groupLabel: "Meta Model API",
|
||||
groupHint: "Meta Model API (Responses API)",
|
||||
},
|
||||
},
|
||||
],
|
||||
catalog: {
|
||||
buildProvider: buildMetaModelApiProvider,
|
||||
buildStaticProvider: buildMetaModelApiProvider,
|
||||
},
|
||||
...OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
wrapStreamFn: wrapMetaModelApiProviderStream,
|
||||
resolveThinkingProfile: ({ modelId }) => resolveMetaModelApiThinkingProfile(modelId),
|
||||
},
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* Meta Model API model catalog helpers derived from the plugin manifest.
|
||||
*/
|
||||
import { buildManifestModelProviderConfig } 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 META_MODEL_API_MANIFEST_CATALOG = manifest.modelCatalog.providers["meta-model-api"];
|
||||
|
||||
/** Base URL for Meta Model API OpenAI-compatible inference. */
|
||||
export const META_MODEL_API_BASE_URL = META_MODEL_API_MANIFEST_CATALOG.baseUrl;
|
||||
/** Meta Model API model catalog entries from the plugin manifest. */
|
||||
export const META_MODEL_API_MODEL_CATALOG = META_MODEL_API_MANIFEST_CATALOG.models;
|
||||
|
||||
/** Builds normalized Meta Model API catalog model definitions. */
|
||||
export function buildMetaModelApiCatalogModels(): ModelDefinitionConfig[] {
|
||||
return buildManifestModelProviderConfig({
|
||||
providerId: "meta-model-api",
|
||||
catalog: META_MODEL_API_MANIFEST_CATALOG,
|
||||
}).models;
|
||||
}
|
||||
|
||||
/** Builds one normalized Meta Model API model definition from a manifest entry. */
|
||||
export function buildMetaModelApiModelDefinition(
|
||||
model: (typeof META_MODEL_API_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
const providerConfig = buildManifestModelProviderConfig({
|
||||
providerId: "meta-model-api",
|
||||
catalog: { ...META_MODEL_API_MANIFEST_CATALOG, models: [model] },
|
||||
});
|
||||
return providerConfig.models[0];
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* Meta Model API onboarding config helpers.
|
||||
*/
|
||||
import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import {
|
||||
buildMetaModelApiModelDefinition,
|
||||
META_MODEL_API_BASE_URL,
|
||||
META_MODEL_API_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
|
||||
/** Default Meta Model API model reference used after onboarding. */
|
||||
export const META_MODEL_API_DEFAULT_MODEL_REF = "meta-model-api/muse-spark-1.1";
|
||||
|
||||
const metaModelApiPresetAppliers = createModelCatalogPresetAppliers({
|
||||
primaryModelRef: META_MODEL_API_DEFAULT_MODEL_REF,
|
||||
resolveParams: (_cfg: OpenClawConfig) => ({
|
||||
providerId: "meta-model-api",
|
||||
api: "openai-responses",
|
||||
baseUrl: META_MODEL_API_BASE_URL,
|
||||
catalogModels: META_MODEL_API_MODEL_CATALOG.map(buildMetaModelApiModelDefinition),
|
||||
aliases: [{ modelRef: META_MODEL_API_DEFAULT_MODEL_REF, alias: "Muse Spark 1.1" }],
|
||||
}),
|
||||
});
|
||||
|
||||
/** Applies Meta Model API provider/catalog config and default model aliases. */
|
||||
export function applyMetaModelApiConfig(cfg: OpenClawConfig): OpenClawConfig {
|
||||
return metaModelApiPresetAppliers.applyConfig(cfg);
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"name": "@openclaw/meta-model-api-provider",
|
||||
"version": "2026.6.11",
|
||||
"private": true,
|
||||
"description": "OpenClaw Meta Model API provider plugin.",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* Meta Model API model provider builder.
|
||||
*/
|
||||
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildMetaModelApiCatalogModels, META_MODEL_API_BASE_URL } from "./models.js";
|
||||
|
||||
/** Builds the Meta Model API OpenAI-compatible model provider config. */
|
||||
export function buildMetaModelApiProvider(): ModelProviderConfig {
|
||||
return {
|
||||
baseUrl: META_MODEL_API_BASE_URL,
|
||||
api: "openai-responses",
|
||||
models: buildMetaModelApiCatalogModels(),
|
||||
};
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// Meta Model API plugin module implements thinking behavior.
|
||||
import type { ProviderThinkingProfile } from "openclaw/plugin-sdk/plugin-entry";
|
||||
|
||||
const META_MODEL_API_REASONING_MODEL_IDS = new Set(["muse-spark", "muse-spark-1.1"]);
|
||||
|
||||
function isMetaModelApiReasoningModelId(modelId: string): boolean {
|
||||
return META_MODEL_API_REASONING_MODEL_IDS.has(modelId.toLowerCase());
|
||||
}
|
||||
|
||||
const META_THINKING_LEVEL_IDS = ["off", "minimal", "low", "medium", "high", "xhigh"] as const;
|
||||
|
||||
const META_THINKING_PROFILE = {
|
||||
levels: META_THINKING_LEVEL_IDS.map((id) => ({ id })),
|
||||
defaultLevel: "high",
|
||||
} satisfies ProviderThinkingProfile;
|
||||
|
||||
export function resolveMetaModelApiThinkingProfile(
|
||||
modelId: string,
|
||||
): ProviderThinkingProfile | undefined {
|
||||
return isMetaModelApiReasoningModelId(modelId) ? META_THINKING_PROFILE : undefined;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# Meta Model API provider
|
||||
# Meta provider
|
||||
|
||||
Bundled OpenClaw provider plugin for the **Meta Model API** — an OpenAI-compatible
|
||||
Bundled OpenClaw provider plugin for the **Meta API** — an OpenAI-compatible
|
||||
**Responses API** endpoint (`POST /v1/responses`).
|
||||
|
||||
- **Base URL:** `https://api.ai.meta.com/v1`
|
||||
@@ -25,13 +25,13 @@ export MODEL_API_KEY=<key>
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "meta-model-api/muse-spark-1.1" },
|
||||
model: { primary: "meta/muse-spark-1.1" },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Or run onboarding and choose **Meta Model API**.
|
||||
Or run onboarding and choose **Meta**.
|
||||
|
||||
## Thinking / reasoning
|
||||
|
||||
@@ -41,15 +41,15 @@ not accept `none`.
|
||||
|
||||
## Docs
|
||||
|
||||
See `docs/providers/meta-model-api.md` for setup, onboarding, and smoke tests.
|
||||
See `docs/providers/meta.md` for setup, onboarding, and smoke tests.
|
||||
|
||||
## Live test
|
||||
|
||||
```bash
|
||||
export MODEL_API_KEY=<key>
|
||||
export OPENCLAW_LIVE_TEST=1
|
||||
export META_MODEL_API_LIVE_TEST=1
|
||||
pnpm test extensions/meta-model-api/meta-model-api.live.test.ts
|
||||
export META_LIVE_TEST=1
|
||||
pnpm test extensions/meta/meta.live.test.ts
|
||||
```
|
||||
|
||||
Live tests call `muse-spark` on `/v1/responses`.
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Public Meta provider plugin API exports.
|
||||
*/
|
||||
export {
|
||||
buildMetaCatalogModels,
|
||||
buildMetaModelDefinition,
|
||||
META_BASE_URL,
|
||||
META_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
export { buildMetaProvider } from "./provider-catalog.js";
|
||||
export { applyMetaConfig, META_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
@@ -1,40 +1,40 @@
|
||||
// Meta Model API tests cover plugin registration and catalog shape.
|
||||
// Meta tests cover plugin registration and catalog shape.
|
||||
import { capturePluginRegistration } from "openclaw/plugin-sdk/plugin-test-runtime";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildMetaModelApiProvider } from "./api.js";
|
||||
import { buildMetaProvider } from "./api.js";
|
||||
import plugin from "./index.js";
|
||||
|
||||
function requireThinkingProfileResolver(
|
||||
provider: ReturnType<typeof capturePluginRegistration>["providers"][number],
|
||||
) {
|
||||
if (!provider.resolveThinkingProfile) {
|
||||
throw new Error("Expected resolveThinkingProfile on Meta Model API provider");
|
||||
throw new Error("Expected resolveThinkingProfile on Meta provider");
|
||||
}
|
||||
return provider.resolveThinkingProfile;
|
||||
}
|
||||
|
||||
describe("meta-model-api provider", () => {
|
||||
it("registers the Meta Model API provider with api-key auth", () => {
|
||||
describe("meta provider", () => {
|
||||
it("registers the Meta provider with api-key auth", () => {
|
||||
const captured = capturePluginRegistration(plugin);
|
||||
const [provider] = captured.providers;
|
||||
if (!provider) {
|
||||
throw new Error("Expected Meta Model API provider");
|
||||
throw new Error("Expected Meta provider");
|
||||
}
|
||||
expect(provider).toMatchObject({
|
||||
id: "meta-model-api",
|
||||
label: "Meta Model API",
|
||||
docsPath: "/providers/meta-model-api",
|
||||
id: "meta",
|
||||
label: "Meta",
|
||||
docsPath: "/providers/meta",
|
||||
});
|
||||
expect(provider.auth).toHaveLength(1);
|
||||
expect(provider.auth[0]).toMatchObject({
|
||||
id: "api-key",
|
||||
kind: "api_key",
|
||||
label: "Meta Model API key",
|
||||
label: "Meta API key",
|
||||
});
|
||||
});
|
||||
|
||||
it("builds the muse-spark-1.1 catalog entry over openai-responses", () => {
|
||||
const providerConfig = buildMetaModelApiProvider();
|
||||
const providerConfig = buildMetaProvider();
|
||||
expect(providerConfig.baseUrl).toBe("https://api.ai.meta.com/v1");
|
||||
expect(providerConfig.api).toBe("openai-responses");
|
||||
const model = providerConfig.models.find((m) => m.id === "muse-spark-1.1");
|
||||
@@ -50,11 +50,11 @@ describe("meta-model-api provider", () => {
|
||||
const captured = capturePluginRegistration(plugin);
|
||||
const [provider] = captured.providers;
|
||||
if (!provider) {
|
||||
throw new Error("Expected Meta Model API provider");
|
||||
throw new Error("Expected Meta provider");
|
||||
}
|
||||
const resolveThinkingProfile = requireThinkingProfileResolver(provider);
|
||||
const profile = resolveThinkingProfile({
|
||||
provider: "meta-model-api",
|
||||
provider: "meta",
|
||||
modelId: "muse-spark-1.1",
|
||||
} as never);
|
||||
expect(profile?.defaultLevel).toBe("high");
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Meta provider plugin entrypoint.
|
||||
*/
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { applyMetaConfig, META_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
import { buildMetaProvider } from "./provider-catalog.js";
|
||||
import { wrapMetaProviderStream } from "./stream.js";
|
||||
import { resolveMetaThinkingProfile } from "./thinking.js";
|
||||
|
||||
const PROVIDER_ID = "meta";
|
||||
|
||||
export default defineSingleProviderPluginEntry({
|
||||
id: PROVIDER_ID,
|
||||
name: "Meta Provider",
|
||||
description: "Bundled Meta provider plugin",
|
||||
provider: {
|
||||
label: "Meta",
|
||||
docsPath: "/providers/meta",
|
||||
auth: [
|
||||
{
|
||||
methodId: "api-key",
|
||||
label: "Meta API key",
|
||||
hint: "Meta (Responses API)",
|
||||
optionKey: "metaApiKey",
|
||||
flagName: "--meta-api-key",
|
||||
envVar: "MODEL_API_KEY",
|
||||
promptMessage: "Enter Meta API key",
|
||||
defaultModel: META_DEFAULT_MODEL_REF,
|
||||
applyConfig: (cfg) => applyMetaConfig(cfg),
|
||||
noteMessage: ["Meta provides Responses API inference."].join("\n"),
|
||||
noteTitle: "Meta",
|
||||
wizard: {
|
||||
groupLabel: "Meta",
|
||||
groupHint: "Meta (Responses API)",
|
||||
},
|
||||
},
|
||||
],
|
||||
catalog: {
|
||||
buildProvider: buildMetaProvider,
|
||||
buildStaticProvider: buildMetaProvider,
|
||||
},
|
||||
...OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
wrapStreamFn: wrapMetaProviderStream,
|
||||
resolveThinkingProfile: ({ modelId }) => resolveMetaThinkingProfile(modelId),
|
||||
},
|
||||
});
|
||||
+11
-11
@@ -1,25 +1,25 @@
|
||||
// Meta Model API live tests prove muse-spark auth and Responses API completion.
|
||||
// Meta live tests prove muse-spark auth and Responses API completion.
|
||||
import { streamSimple, type Model } from "openclaw/plugin-sdk/llm";
|
||||
import { extractNonEmptyAssistantText, isLiveTestEnabled } from "openclaw/plugin-sdk/test-env";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildMetaModelApiProvider } from "./provider-catalog.js";
|
||||
import { wrapMetaModelApiProviderStream } from "./stream.js";
|
||||
import { buildMetaProvider } from "./provider-catalog.js";
|
||||
import { wrapMetaProviderStream } from "./stream.js";
|
||||
|
||||
const MODEL_API_KEY = process.env.MODEL_API_KEY?.trim() ?? "";
|
||||
const LIVE_MODEL_ID = "muse-spark";
|
||||
const LIVE =
|
||||
isLiveTestEnabled(["META_MODEL_API_LIVE_TEST", "MODEL_API_LIVE_TEST"]) &&
|
||||
isLiveTestEnabled(["META_LIVE_TEST", "MODEL_API_LIVE_TEST"]) &&
|
||||
MODEL_API_KEY.length > 0;
|
||||
const describeLive = LIVE ? describe : describe.skip;
|
||||
|
||||
function resolveLiveModel(): Model<"openai-responses"> {
|
||||
const provider = buildMetaModelApiProvider();
|
||||
const provider = buildMetaProvider();
|
||||
const catalogModel = provider.models?.find((entry) => entry.id === "muse-spark-1.1");
|
||||
if (!catalogModel) {
|
||||
throw new Error("Meta Model API catalog does not include muse-spark-1.1");
|
||||
throw new Error("Meta catalog does not include muse-spark-1.1");
|
||||
}
|
||||
return {
|
||||
provider: "meta-model-api",
|
||||
provider: "meta",
|
||||
baseUrl: provider.baseUrl,
|
||||
...catalogModel,
|
||||
id: LIVE_MODEL_ID,
|
||||
@@ -30,8 +30,8 @@ function resolveLiveModel(): Model<"openai-responses"> {
|
||||
function resolveLiveStreamFn() {
|
||||
const model = resolveLiveModel();
|
||||
return (
|
||||
wrapMetaModelApiProviderStream({
|
||||
provider: "meta-model-api",
|
||||
wrapMetaProviderStream({
|
||||
provider: "meta",
|
||||
modelId: model.id,
|
||||
model,
|
||||
streamFn: streamSimple,
|
||||
@@ -39,7 +39,7 @@ function resolveLiveStreamFn() {
|
||||
);
|
||||
}
|
||||
|
||||
describeLive("meta-model-api plugin live", () => {
|
||||
describeLive("meta plugin live", () => {
|
||||
it("lists muse-spark via the /models endpoint", async () => {
|
||||
const response = await fetch("https://api.ai.meta.com/v1/models", {
|
||||
headers: { Authorization: `Bearer ${MODEL_API_KEY}` },
|
||||
@@ -76,7 +76,7 @@ describeLive("meta-model-api plugin live", () => {
|
||||
const result = await stream.result();
|
||||
|
||||
if (result.stopReason === "error") {
|
||||
throw new Error(result.errorMessage || "Meta Model API returned an error");
|
||||
throw new Error(result.errorMessage || "Meta returned an error");
|
||||
}
|
||||
|
||||
expect(capturedPayload?.store).toBe(false);
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Meta model catalog helpers derived from the plugin manifest.
|
||||
*/
|
||||
import { buildManifestModelProviderConfig } 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 META_MANIFEST_CATALOG = manifest.modelCatalog.providers["meta"];
|
||||
|
||||
/** Base URL for Meta OpenAI-compatible inference. */
|
||||
export const META_BASE_URL = META_MANIFEST_CATALOG.baseUrl;
|
||||
/** Meta model catalog entries from the plugin manifest. */
|
||||
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 providerConfig.models[0];
|
||||
}
|
||||
Generated
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/meta-provider",
|
||||
"version": "2026.6.11",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/meta-provider",
|
||||
"version": "2026.6.11"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Meta onboarding config helpers.
|
||||
*/
|
||||
import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import {
|
||||
buildMetaModelDefinition,
|
||||
META_BASE_URL,
|
||||
META_MODEL_CATALOG,
|
||||
} from "./models.js";
|
||||
|
||||
/** Default Meta model reference used after onboarding. */
|
||||
export const META_DEFAULT_MODEL_REF = "meta/muse-spark-1.1";
|
||||
|
||||
const metaPresetAppliers = createModelCatalogPresetAppliers({
|
||||
primaryModelRef: META_DEFAULT_MODEL_REF,
|
||||
resolveParams: (_cfg: OpenClawConfig) => ({
|
||||
providerId: "meta",
|
||||
api: "openai-responses",
|
||||
baseUrl: META_BASE_URL,
|
||||
catalogModels: META_MODEL_CATALOG.map(buildMetaModelDefinition),
|
||||
aliases: [{ modelRef: META_DEFAULT_MODEL_REF, alias: "Muse Spark 1.1" }],
|
||||
}),
|
||||
});
|
||||
|
||||
/** Applies Meta provider/catalog config and default model aliases. */
|
||||
export function applyMetaConfig(cfg: OpenClawConfig): OpenClawConfig {
|
||||
return metaPresetAppliers.applyConfig(cfg);
|
||||
}
|
||||
+19
-19
@@ -1,26 +1,26 @@
|
||||
{
|
||||
"id": "meta-model-api",
|
||||
"id": "meta",
|
||||
"activation": {
|
||||
"onStartup": false
|
||||
},
|
||||
"enabledByDefault": true,
|
||||
"providers": ["meta-model-api"],
|
||||
"providers": ["meta"],
|
||||
"providerEndpoints": [
|
||||
{
|
||||
"endpointClass": "meta-model-api-native",
|
||||
"endpointClass": "meta-native",
|
||||
"hosts": ["api.ai.meta.com"]
|
||||
}
|
||||
],
|
||||
"providerRequest": {
|
||||
"providers": {
|
||||
"meta-model-api": {
|
||||
"family": "meta-model-api"
|
||||
"meta": {
|
||||
"family": "meta"
|
||||
}
|
||||
}
|
||||
},
|
||||
"modelCatalog": {
|
||||
"providers": {
|
||||
"meta-model-api": {
|
||||
"meta": {
|
||||
"baseUrl": "https://api.ai.meta.com/v1",
|
||||
"api": "openai-responses",
|
||||
"models": [
|
||||
@@ -61,13 +61,13 @@
|
||||
}
|
||||
},
|
||||
"discovery": {
|
||||
"meta-model-api": "static"
|
||||
"meta": "static"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"providers": [
|
||||
{
|
||||
"id": "meta-model-api",
|
||||
"id": "meta",
|
||||
"authMethods": ["api-key"],
|
||||
"envVars": ["MODEL_API_KEY"]
|
||||
}
|
||||
@@ -75,20 +75,20 @@
|
||||
},
|
||||
"providerAuthChoices": [
|
||||
{
|
||||
"provider": "meta-model-api",
|
||||
"provider": "meta",
|
||||
"method": "api-key",
|
||||
"choiceId": "meta-model-api-api-key",
|
||||
"choiceId": "meta-api-key",
|
||||
"appGuidedSecret": true,
|
||||
"choiceLabel": "Meta Model API key",
|
||||
"choiceHint": "Meta Model API (Responses API)",
|
||||
"groupId": "meta-model-api",
|
||||
"groupLabel": "Meta Model API",
|
||||
"groupHint": "Meta Model API (Responses API)",
|
||||
"choiceLabel": "Meta API key",
|
||||
"choiceHint": "Meta (Responses API)",
|
||||
"groupId": "meta",
|
||||
"groupLabel": "Meta",
|
||||
"groupHint": "Meta (Responses API)",
|
||||
"onboardingFeatured": true,
|
||||
"optionKey": "metaModelApiKey",
|
||||
"cliFlag": "--meta-model-api-key",
|
||||
"cliOption": "--meta-model-api-key <key>",
|
||||
"cliDescription": "Meta Model API key"
|
||||
"optionKey": "metaApiKey",
|
||||
"cliFlag": "--meta-api-key",
|
||||
"cliOption": "--meta-api-key <key>",
|
||||
"cliDescription": "Meta API key"
|
||||
}
|
||||
],
|
||||
"configSchema": {
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@openclaw/meta-provider",
|
||||
"version": "2026.6.11",
|
||||
"description": "OpenClaw Meta provider plugin.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/openclaw/openclaw"
|
||||
},
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@openclaw/plugin-sdk": "workspace:*"
|
||||
},
|
||||
"openclaw": {
|
||||
"extensions": [
|
||||
"./index.ts"
|
||||
],
|
||||
"install": {
|
||||
"clawhubSpec": "clawhub:@openclaw/meta-provider",
|
||||
"npmSpec": "@openclaw/meta-provider",
|
||||
"defaultChoice": "npm",
|
||||
"minHostVersion": ">=2026.6.11"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.11"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.11",
|
||||
"bundledDist": true
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
"publishToNpm": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Meta model provider builder.
|
||||
*/
|
||||
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildMetaCatalogModels, META_BASE_URL } from "./models.js";
|
||||
|
||||
/** Builds the Meta OpenAI-compatible model provider config. */
|
||||
export function buildMetaProvider(): ModelProviderConfig {
|
||||
return {
|
||||
baseUrl: META_BASE_URL,
|
||||
api: "openai-responses",
|
||||
models: buildMetaCatalogModels(),
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Meta Model API plugin module implements stream behavior.
|
||||
// Meta plugin module implements stream behavior.
|
||||
import type { StreamFn } from "openclaw/plugin-sdk/agent-core";
|
||||
import { streamSimple } from "openclaw/plugin-sdk/llm";
|
||||
import type { ProviderWrapStreamFnContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
@@ -18,11 +18,11 @@ function ensureMetaResponsesReplayFields(payloadObj: Record<string, unknown>): v
|
||||
payloadObj.store = false;
|
||||
}
|
||||
|
||||
export function createMetaModelApiResponsesWrapper(baseStreamFn: StreamFn | undefined): StreamFn {
|
||||
export function createMetaResponsesWrapper(baseStreamFn: StreamFn | undefined): StreamFn {
|
||||
const underlying = baseStreamFn ?? streamSimple;
|
||||
return (model, context, options) =>
|
||||
streamWithPayloadPatch(underlying, model, context, options, (payloadObj) => {
|
||||
if (model.provider !== "meta-model-api" || model.api !== "openai-responses") {
|
||||
if (model.provider !== "meta" || model.api !== "openai-responses") {
|
||||
return;
|
||||
}
|
||||
if (!model.reasoning) {
|
||||
@@ -32,11 +32,11 @@ export function createMetaModelApiResponsesWrapper(baseStreamFn: StreamFn | unde
|
||||
});
|
||||
}
|
||||
|
||||
export function wrapMetaModelApiProviderStream(
|
||||
export function wrapMetaProviderStream(
|
||||
ctx: ProviderWrapStreamFnContext,
|
||||
): StreamFn | undefined {
|
||||
if (ctx.provider !== "meta-model-api" || ctx.model?.api !== "openai-responses") {
|
||||
if (ctx.provider !== "meta" || ctx.model?.api !== "openai-responses") {
|
||||
return undefined;
|
||||
}
|
||||
return createMetaModelApiResponsesWrapper(ctx.streamFn);
|
||||
return createMetaResponsesWrapper(ctx.streamFn);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Meta plugin module implements thinking behavior.
|
||||
import type { ProviderThinkingProfile } from "openclaw/plugin-sdk/plugin-entry";
|
||||
|
||||
const META_REASONING_MODEL_IDS = new Set(["muse-spark", "muse-spark-1.1"]);
|
||||
|
||||
function isMetaReasoningModelId(modelId: string): boolean {
|
||||
return META_REASONING_MODEL_IDS.has(modelId.toLowerCase());
|
||||
}
|
||||
|
||||
const META_THINKING_LEVEL_IDS = ["off", "minimal", "low", "medium", "high", "xhigh"] as const;
|
||||
|
||||
const META_THINKING_PROFILE = {
|
||||
levels: META_THINKING_LEVEL_IDS.map((id) => ({ id })),
|
||||
defaultLevel: "high",
|
||||
} satisfies ProviderThinkingProfile;
|
||||
|
||||
export function resolveMetaThinkingProfile(
|
||||
modelId: string,
|
||||
): ProviderThinkingProfile | undefined {
|
||||
return isMetaReasoningModelId(modelId) ? META_THINKING_PROFILE : undefined;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ function getApiKeyEnvVars(provider: string): readonly string[] | undefined {
|
||||
|
||||
const envMap: Record<string, string> = {
|
||||
openai: "OPENAI_API_KEY",
|
||||
"meta-model-api": "MODEL_API_KEY",
|
||||
"meta": "MODEL_API_KEY",
|
||||
"azure-openai-responses": "AZURE_OPENAI_API_KEY",
|
||||
deepseek: "DEEPSEEK_API_KEY",
|
||||
google: "GEMINI_API_KEY",
|
||||
|
||||
Generated
+1
-1
@@ -1119,7 +1119,7 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../..
|
||||
|
||||
extensions/meta-model-api:
|
||||
extensions/meta:
|
||||
devDependencies:
|
||||
'@openclaw/plugin-sdk':
|
||||
specifier: workspace:*
|
||||
|
||||
@@ -682,6 +682,55 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "@openclaw/meta-provider",
|
||||
"description": "OpenClaw Meta provider plugin.",
|
||||
"source": "official",
|
||||
"kind": "provider",
|
||||
"openclaw": {
|
||||
"plugin": {
|
||||
"id": "meta",
|
||||
"label": "Meta"
|
||||
},
|
||||
"providerEndpoints": [
|
||||
{
|
||||
"endpointClass": "meta-native",
|
||||
"hosts": ["api.ai.meta.com"]
|
||||
}
|
||||
],
|
||||
"providers": [
|
||||
{
|
||||
"id": "meta",
|
||||
"name": "Meta",
|
||||
"docs": "/providers/meta",
|
||||
"categories": ["cloud", "llm"],
|
||||
"envVars": ["MODEL_API_KEY"],
|
||||
"authChoices": [
|
||||
{
|
||||
"method": "api-key",
|
||||
"choiceId": "meta-api-key",
|
||||
"choiceLabel": "Meta API key",
|
||||
"choiceHint": "Meta (Responses API)",
|
||||
"groupId": "meta",
|
||||
"groupLabel": "Meta",
|
||||
"groupHint": "Meta (Responses API)",
|
||||
"optionKey": "metaApiKey",
|
||||
"cliFlag": "--meta-api-key",
|
||||
"cliOption": "--meta-api-key <key>",
|
||||
"cliDescription": "Meta API key",
|
||||
"onboardingScopes": ["text-inference"]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"install": {
|
||||
"clawhubSpec": "clawhub:@openclaw/meta-provider",
|
||||
"npmSpec": "@openclaw/meta-provider",
|
||||
"defaultChoice": "npm",
|
||||
"minHostVersion": ">=2026.6.11"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "@openclaw/groq-provider",
|
||||
"description": "OpenClaw Groq media-understanding provider.",
|
||||
|
||||
@@ -16,7 +16,7 @@ export const BUILT_IN_PROVIDER_DISPLAY_NAMES: Record<string, string> = {
|
||||
groq: "Groq",
|
||||
huggingface: "Hugging Face",
|
||||
"kimi-coding": "Kimi For Coding",
|
||||
"meta-model-api": "Meta Model API",
|
||||
"meta": "Meta",
|
||||
mistral: "Mistral",
|
||||
minimax: "MiniMax",
|
||||
"minimax-cn": "MiniMax (China)",
|
||||
|
||||
@@ -468,7 +468,7 @@ const BUILT_IN_MODEL_PROVIDER_OVERLAY_IDS = new Set([
|
||||
"kimi-coding",
|
||||
"litellm",
|
||||
"lmstudio",
|
||||
"meta-model-api",
|
||||
"meta",
|
||||
"microsoft-foundry",
|
||||
"minimax",
|
||||
"minimax-portal",
|
||||
|
||||
@@ -24,7 +24,6 @@ const CORE_PROVIDER_AUTH_ENV_VAR_CANDIDATES = {
|
||||
openai: ["CODEX_API_KEY", "OPENAI_API_KEY"],
|
||||
voyage: ["VOYAGE_API_KEY"],
|
||||
cerebras: ["CEREBRAS_API_KEY"],
|
||||
"meta-model-api": ["MODEL_API_KEY"],
|
||||
"anthropic-openai": ["ANTHROPIC_API_KEY"],
|
||||
"qwen-dashscope": ["DASHSCOPE_API_KEY"],
|
||||
} as const;
|
||||
|
||||
@@ -123,7 +123,7 @@ describe("scripts/test-live-shard", () => {
|
||||
]);
|
||||
expect(selectLiveShardFiles("native-live-extensions-l-n", allFiles)).toEqual([
|
||||
"extensions/memory-lancedb/memory-lancedb.live.test.ts",
|
||||
"extensions/meta-model-api/meta-model-api.live.test.ts",
|
||||
"extensions/meta/meta.live.test.ts",
|
||||
"extensions/microsoft/microsoft.live.test.ts",
|
||||
"extensions/mistral/mistral.live.test.ts",
|
||||
]);
|
||||
|
||||
Reference in New Issue
Block a user