Vendor OpenClaw source as Adolf fork baseline
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11), free to diverge. Tree copied sans upstream .git; upstream remote added for future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19. Preserves docs/ARCHITECTURE.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
This commit is contained in:
13
extensions/cohere/README.md
Normal file
13
extensions/cohere/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# OpenClaw Cohere Provider
|
||||
|
||||
Official OpenClaw provider plugin for Cohere's OpenAI-compatible Compatibility
|
||||
API.
|
||||
|
||||
Install from OpenClaw:
|
||||
|
||||
```bash
|
||||
openclaw plugins install @openclaw/cohere-provider
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
Configure a Cohere API key, then select `cohere/command-a-03-2025`.
|
||||
121
extensions/cohere/index.test.ts
Normal file
121
extensions/cohere/index.test.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import type { StreamFn } from "openclaw/plugin-sdk/agent-core";
|
||||
import type { Context, Model } from "openclaw/plugin-sdk/llm";
|
||||
import { registerSingleProviderPlugin } from "openclaw/plugin-sdk/plugin-test-runtime";
|
||||
import { buildOpenAICompletionsParams } from "openclaw/plugin-sdk/provider-transport-runtime";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import plugin from "./index.js";
|
||||
import { buildCohereProvider } from "./provider-catalog.js";
|
||||
import { createCohereCompletionsWrapper } from "./stream.js";
|
||||
|
||||
function readManifest() {
|
||||
return JSON.parse(readFileSync(new URL("./openclaw.plugin.json", import.meta.url), "utf8")) as {
|
||||
providerAuthChoices?: Array<{ choiceId?: string; optionKey?: string; cliFlag?: string }>;
|
||||
setup?: { providers?: Array<{ id?: string; envVars?: string[] }> };
|
||||
};
|
||||
}
|
||||
|
||||
function requireCohereModel(): Model<"openai-completions"> {
|
||||
const model = buildCohereProvider().models?.[0];
|
||||
if (!model) {
|
||||
throw new Error("Cohere catalog did not provide a model");
|
||||
}
|
||||
return model as Model<"openai-completions">;
|
||||
}
|
||||
|
||||
function captureCoherePayload(context: Context): Record<string, unknown> {
|
||||
let captured: Record<string, unknown> | undefined;
|
||||
const baseStreamFn: StreamFn = (model, streamContext, options) => {
|
||||
const payload = buildOpenAICompletionsParams(
|
||||
model as Model<"openai-completions">,
|
||||
streamContext,
|
||||
{ maxTokens: 2048 } as never,
|
||||
);
|
||||
options?.onPayload?.(payload, model);
|
||||
return {} as ReturnType<StreamFn>;
|
||||
};
|
||||
|
||||
const wrappedStreamFn = createCohereCompletionsWrapper(baseStreamFn);
|
||||
if (!wrappedStreamFn) {
|
||||
throw new Error("Cohere wrapper did not return a stream function");
|
||||
}
|
||||
void wrappedStreamFn(requireCohereModel(), context, {
|
||||
onPayload: (payload) => {
|
||||
captured = payload as Record<string, unknown>;
|
||||
},
|
||||
});
|
||||
if (!captured) {
|
||||
throw new Error("Cohere payload was not captured");
|
||||
}
|
||||
return captured;
|
||||
}
|
||||
|
||||
describe("Cohere provider plugin", () => {
|
||||
it("registers the manifest-owned API key onboarding flow", async () => {
|
||||
const provider = await registerSingleProviderPlugin(plugin);
|
||||
|
||||
expect(provider.auth.map((method) => method.wizard?.choiceId)).toEqual(["cohere-api-key"]);
|
||||
expect(provider).toMatchObject({
|
||||
id: "cohere",
|
||||
envVars: ["COHERE_API_KEY"],
|
||||
});
|
||||
expect(provider.auth[0]).toMatchObject({
|
||||
id: "api-key",
|
||||
kind: "api_key",
|
||||
wizard: { choiceId: "cohere-api-key" },
|
||||
});
|
||||
expect(readManifest().providerAuthChoices).toEqual([
|
||||
expect.objectContaining({
|
||||
choiceId: "cohere-api-key",
|
||||
optionKey: "cohereApiKey",
|
||||
cliFlag: "--cohere-api-key",
|
||||
}),
|
||||
]);
|
||||
expect(readManifest().setup?.providers).toEqual([
|
||||
{ id: "cohere", envVars: ["COHERE_API_KEY"] },
|
||||
]);
|
||||
});
|
||||
|
||||
it("exposes the static Cohere catalog", () => {
|
||||
expect(buildCohereProvider()).toMatchObject({
|
||||
baseUrl: "https://api.cohere.ai/compatibility/v1",
|
||||
api: "openai-completions",
|
||||
models: [
|
||||
expect.objectContaining({
|
||||
id: "command-a-03-2025",
|
||||
compat: {
|
||||
supportsStore: false,
|
||||
supportsUsageInStreaming: false,
|
||||
maxTokensField: "max_tokens",
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("uses Cohere's OpenAI-compatible completions payload fields", () => {
|
||||
const params = captureCoherePayload({
|
||||
systemPrompt: "system",
|
||||
messages: [],
|
||||
tools: [
|
||||
{
|
||||
name: "lookup",
|
||||
description: "Look up a value",
|
||||
parameters: { type: "object", properties: {} },
|
||||
},
|
||||
],
|
||||
} as Context);
|
||||
|
||||
expect(params.max_tokens).toBe(2048);
|
||||
expect(params).not.toHaveProperty("max_completion_tokens");
|
||||
expect(params).not.toHaveProperty("store");
|
||||
expect(params).not.toHaveProperty("stream_options");
|
||||
expect(params).not.toHaveProperty("tool_choice");
|
||||
expect(params.messages).toEqual(
|
||||
expect.arrayContaining([expect.objectContaining({ role: "developer", content: "system" })]),
|
||||
);
|
||||
expect(params.messages).not.toEqual(
|
||||
expect.arrayContaining([expect.objectContaining({ role: "system", content: "system" })]),
|
||||
);
|
||||
});
|
||||
});
|
||||
37
extensions/cohere/index.ts
Normal file
37
extensions/cohere/index.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { applyCohereConfig, COHERE_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
import { buildCohereProvider } from "./provider-catalog.js";
|
||||
import { createCohereCompletionsWrapper } from "./stream.js";
|
||||
|
||||
export default defineSingleProviderPluginEntry({
|
||||
id: "cohere",
|
||||
name: "Cohere Provider",
|
||||
description: "Cohere provider plugin",
|
||||
provider: {
|
||||
label: "Cohere",
|
||||
docsPath: "/providers/cohere",
|
||||
auth: [
|
||||
{
|
||||
methodId: "api-key",
|
||||
label: "Cohere API key",
|
||||
hint: "OpenAI-compatible inference",
|
||||
optionKey: "cohereApiKey",
|
||||
flagName: "--cohere-api-key",
|
||||
envVar: "COHERE_API_KEY",
|
||||
promptMessage: "Enter Cohere API key",
|
||||
defaultModel: COHERE_DEFAULT_MODEL_REF,
|
||||
applyConfig: (cfg) => applyCohereConfig(cfg),
|
||||
wizard: {
|
||||
groupLabel: "Cohere",
|
||||
groupHint: "OpenAI-compatible inference",
|
||||
},
|
||||
},
|
||||
],
|
||||
catalog: {
|
||||
buildProvider: buildCohereProvider,
|
||||
buildStaticProvider: buildCohereProvider,
|
||||
},
|
||||
wrapStreamFn: (ctx) => createCohereCompletionsWrapper(ctx.streamFn),
|
||||
wrapSimpleCompletionStreamFn: (ctx) => createCohereCompletionsWrapper(ctx.streamFn),
|
||||
},
|
||||
});
|
||||
27
extensions/cohere/models.ts
Normal file
27
extensions/cohere/models.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Cohere 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 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;
|
||||
|
||||
export function buildCohereCatalogModels(): ModelDefinitionConfig[] {
|
||||
return buildManifestModelProviderConfig({
|
||||
providerId: "cohere",
|
||||
catalog: COHERE_MANIFEST_CATALOG,
|
||||
}).models;
|
||||
}
|
||||
|
||||
export function buildCohereModelDefinition(
|
||||
model: (typeof COHERE_MODEL_CATALOG)[number],
|
||||
): ModelDefinitionConfig {
|
||||
return buildManifestModelProviderConfig({
|
||||
providerId: "cohere",
|
||||
catalog: { ...COHERE_MANIFEST_CATALOG, models: [model] },
|
||||
}).models[0];
|
||||
}
|
||||
12
extensions/cohere/npm-shrinkwrap.json
generated
Normal file
12
extensions/cohere/npm-shrinkwrap.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/cohere-provider",
|
||||
"version": "2026.6.11",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/cohere-provider",
|
||||
"version": "2026.6.11"
|
||||
}
|
||||
}
|
||||
}
|
||||
48
extensions/cohere/onboard.test.ts
Normal file
48
extensions/cohere/onboard.test.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
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 {
|
||||
applyCohereConfig,
|
||||
COHERE_DEFAULT_MODEL_ID,
|
||||
COHERE_DEFAULT_MODEL_REF,
|
||||
} from "./onboard.js";
|
||||
|
||||
describe("Cohere onboarding", () => {
|
||||
it("registers the manifest catalog through the onboarding preset", () => {
|
||||
const result = applyCohereConfig({});
|
||||
const provider = result.models?.providers?.cohere;
|
||||
|
||||
expect(provider).toMatchObject({
|
||||
baseUrl: COHERE_BASE_URL,
|
||||
api: "openai-completions",
|
||||
});
|
||||
expect(provider?.models?.map((model) => model.id)).toEqual([COHERE_DEFAULT_MODEL_ID]);
|
||||
expect(buildCohereCatalogModels()).toHaveLength(COHERE_MODEL_CATALOG.length);
|
||||
});
|
||||
|
||||
it("sets Cohere only when there is no primary model", () => {
|
||||
const existing: OpenClawConfig = {
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "openai/gpt-5.5" },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const result = applyCohereConfig(existing);
|
||||
|
||||
expect(resolveAgentModelPrimaryValue(result.agents?.defaults?.model)).toBe("openai/gpt-5.5");
|
||||
expect(result.agents?.defaults?.models?.[COHERE_DEFAULT_MODEL_REF]).toEqual({
|
||||
alias: "Cohere Command A",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses Cohere as the first configured primary model", () => {
|
||||
const result = applyCohereConfig({});
|
||||
|
||||
expect(resolveAgentModelPrimaryValue(result.agents?.defaults?.model)).toBe(
|
||||
COHERE_DEFAULT_MODEL_REF,
|
||||
);
|
||||
});
|
||||
});
|
||||
23
extensions/cohere/onboard.ts
Normal file
23
extensions/cohere/onboard.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import {
|
||||
createModelCatalogPresetAppliers,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/provider-onboard";
|
||||
import { buildCohereModelDefinition, COHERE_BASE_URL, COHERE_MODEL_CATALOG } from "./models.js";
|
||||
|
||||
export const COHERE_DEFAULT_MODEL_ID = "command-a-03-2025";
|
||||
export const COHERE_DEFAULT_MODEL_REF = `cohere/${COHERE_DEFAULT_MODEL_ID}`;
|
||||
|
||||
const coherePresetAppliers = createModelCatalogPresetAppliers({
|
||||
primaryModelRef: COHERE_DEFAULT_MODEL_REF,
|
||||
resolveParams: (_cfg: OpenClawConfig) => ({
|
||||
providerId: "cohere",
|
||||
api: "openai-completions",
|
||||
baseUrl: COHERE_BASE_URL,
|
||||
catalogModels: COHERE_MODEL_CATALOG.map(buildCohereModelDefinition),
|
||||
aliases: [{ modelRef: COHERE_DEFAULT_MODEL_REF, alias: "Cohere Command A" }],
|
||||
}),
|
||||
});
|
||||
|
||||
export function applyCohereConfig(cfg: OpenClawConfig): OpenClawConfig {
|
||||
return coherePresetAppliers.applyConfig(cfg);
|
||||
}
|
||||
69
extensions/cohere/openclaw.plugin.json
Normal file
69
extensions/cohere/openclaw.plugin.json
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"id": "cohere",
|
||||
"name": "Cohere",
|
||||
"description": "OpenClaw Cohere provider plugin.",
|
||||
"activation": {
|
||||
"onStartup": false
|
||||
},
|
||||
"enabledByDefault": true,
|
||||
"providers": ["cohere"],
|
||||
"modelCatalog": {
|
||||
"providers": {
|
||||
"cohere": {
|
||||
"baseUrl": "https://api.cohere.ai/compatibility/v1",
|
||||
"api": "openai-completions",
|
||||
"models": [
|
||||
{
|
||||
"id": "command-a-03-2025",
|
||||
"name": "Command A",
|
||||
"input": ["text"],
|
||||
"contextWindow": 256000,
|
||||
"maxTokens": 8000,
|
||||
"cost": {
|
||||
"input": 2.5,
|
||||
"output": 10,
|
||||
"cacheRead": 0,
|
||||
"cacheWrite": 0
|
||||
},
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsUsageInStreaming": false,
|
||||
"maxTokensField": "max_tokens"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"discovery": {
|
||||
"cohere": "static"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"providers": [
|
||||
{
|
||||
"id": "cohere",
|
||||
"envVars": ["COHERE_API_KEY"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"providerAuthChoices": [
|
||||
{
|
||||
"provider": "cohere",
|
||||
"method": "api-key",
|
||||
"choiceId": "cohere-api-key",
|
||||
"choiceLabel": "Cohere API key",
|
||||
"groupId": "cohere",
|
||||
"groupLabel": "Cohere",
|
||||
"groupHint": "OpenAI-compatible inference",
|
||||
"optionKey": "cohereApiKey",
|
||||
"cliFlag": "--cohere-api-key",
|
||||
"cliOption": "--cohere-api-key <key>",
|
||||
"cliDescription": "Cohere API key"
|
||||
}
|
||||
],
|
||||
"configSchema": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {}
|
||||
}
|
||||
}
|
||||
35
extensions/cohere/package.json
Normal file
35
extensions/cohere/package.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@openclaw/cohere-provider",
|
||||
"version": "2026.6.11",
|
||||
"description": "OpenClaw Cohere 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/cohere-provider",
|
||||
"npmSpec": "@openclaw/cohere-provider",
|
||||
"defaultChoice": "npm",
|
||||
"minHostVersion": ">=2026.6.8"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.6.11"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.6.11",
|
||||
"bundledDist": true
|
||||
},
|
||||
"release": {
|
||||
"publishToClawHub": true,
|
||||
"publishToNpm": true
|
||||
}
|
||||
}
|
||||
}
|
||||
10
extensions/cohere/provider-catalog.ts
Normal file
10
extensions/cohere/provider-catalog.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildCohereCatalogModels, COHERE_BASE_URL } from "./models.js";
|
||||
|
||||
export function buildCohereProvider(): ModelProviderConfig {
|
||||
return {
|
||||
baseUrl: COHERE_BASE_URL,
|
||||
api: "openai-completions",
|
||||
models: buildCohereCatalogModels(),
|
||||
};
|
||||
}
|
||||
26
extensions/cohere/stream.ts
Normal file
26
extensions/cohere/stream.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { ProviderWrapStreamFnContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createPayloadPatchStreamWrapper } from "openclaw/plugin-sdk/provider-stream-shared";
|
||||
|
||||
function patchCoherePayload(payload: Record<string, unknown>): void {
|
||||
// Cohere's Compatibility API uses developer, not system, for instructions.
|
||||
if (Array.isArray(payload.messages)) {
|
||||
payload.messages = payload.messages.map((message) =>
|
||||
message &&
|
||||
typeof message === "object" &&
|
||||
(message as Record<string, unknown>).role === "system"
|
||||
? { ...(message as Record<string, unknown>), role: "developer" }
|
||||
: message,
|
||||
);
|
||||
}
|
||||
|
||||
// Cohere lets tool-capable models choose a tool when tool_choice is omitted.
|
||||
delete payload.tool_choice;
|
||||
}
|
||||
|
||||
export function createCohereCompletionsWrapper(
|
||||
baseStreamFn: ProviderWrapStreamFnContext["streamFn"],
|
||||
): ProviderWrapStreamFnContext["streamFn"] {
|
||||
return createPayloadPatchStreamWrapper(baseStreamFn, ({ payload }) =>
|
||||
patchCoherePayload(payload),
|
||||
);
|
||||
}
|
||||
16
extensions/cohere/tsconfig.json
Normal file
16
extensions/cohere/tsconfig.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "../tsconfig.package-boundary.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "."
|
||||
},
|
||||
"include": ["./*.ts", "./src/**/*.ts"],
|
||||
"exclude": [
|
||||
"./**/*.test.ts",
|
||||
"./dist/**",
|
||||
"./node_modules/**",
|
||||
"./src/test-support/**",
|
||||
"./src/**/*test-helpers.ts",
|
||||
"./src/**/*test-harness.ts",
|
||||
"./src/**/*test-support.ts"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user