Ana içeriğe atla

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

Use this file to discover all available pages before exploring further.

Bu kılavuz, OpenClaw’a bir model sağlayıcısı (LLM) ekleyen bir sağlayıcı Plugin’i oluşturmayı adım adım anlatır. Sonunda model kataloğu, API anahtarı kimlik doğrulaması ve dinamik model çözümlemesi olan bir sağlayıcınız olacak.
Daha önce hiç OpenClaw Plugin’i oluşturmadıysanız, temel paket yapısı ve manifest kurulumu için önce Başlarken bölümünü okuyun.
Sağlayıcı Plugin’leri, OpenClaw’ın normal çıkarım döngüsüne modeller ekler. Modelin iş parçacıklarını, Compaction’ı veya araç olaylarını sahiplenen yerel bir ajan daemon’u üzerinden çalışması gerekiyorsa, daemon protokol ayrıntılarını çekirdeğe koymak yerine sağlayıcıyı bir ajan harness’ı ile eşleştirin.

İzlenecek Yol

1

Paket ve manifest

1. Adım: Paket ve manifest

{
  "name": "@myorg/openclaw-acme-ai",
  "version": "1.0.0",
  "type": "module",
  "openclaw": {
    "extensions": ["./index.ts"],
    "providers": ["acme-ai"],
    "compat": {
      "pluginApi": ">=2026.3.24-beta.2",
      "minGatewayVersion": "2026.3.24-beta.2"
    },
    "build": {
      "openclawVersion": "2026.3.24-beta.2",
      "pluginSdkVersion": "2026.3.24-beta.2"
    }
  }
}
Manifest, OpenClaw’ın Plugin çalışma zamanınızı yüklemeden kimlik bilgilerini algılayabilmesi için providerAuthEnvVars bildirir. Bir sağlayıcı varyantının başka bir sağlayıcı kimliğinin kimlik doğrulamasını yeniden kullanması gerektiğinde providerAuthAliases ekleyin. modelSupport isteğe bağlıdır ve çalışma zamanı hook’ları var olmadan önce OpenClaw’ın sağlayıcı Plugin’inizi acme-large gibi kısa model kimliklerinden otomatik yüklemesini sağlar. Sağlayıcıyı ClawHub’da yayımlarsanız, package.json içindeki bu openclaw.compat ve openclaw.build alanları zorunludur.
2

Sağlayıcıyı kaydet

En küçük metin sağlayıcısı için bir id, label, auth ve catalog gerekir. catalog, sağlayıcıya ait çalışma zamanı/yapılandırma hook’udur; canlı satıcı API’lerini çağırabilir ve models.providers girdileri döndürür.
index.ts
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";

export default definePluginEntry({
  id: "acme-ai",
  name: "Acme AI",
  description: "Acme AI model provider",
  register(api) {
    api.registerProvider({
      id: "acme-ai",
      label: "Acme AI",
      docsPath: "/providers/acme-ai",
      envVars: ["ACME_AI_API_KEY"],

      auth: [
        createProviderApiKeyAuthMethod({
          providerId: "acme-ai",
          methodId: "api-key",
          label: "Acme AI API key",
          hint: "API key from your Acme AI dashboard",
          optionKey: "acmeAiApiKey",
          flagName: "--acme-ai-api-key",
          envVar: "ACME_AI_API_KEY",
          promptMessage: "Enter your Acme AI API key",
          defaultModel: "acme-ai/acme-large",
        }),
      ],

      catalog: {
        order: "simple",
        run: async (ctx) => {
          const apiKey =
            ctx.resolveProviderApiKey("acme-ai").apiKey;
          if (!apiKey) return null;
          return {
            provider: {
              baseUrl: "https://api.acme-ai.com/v1",
              apiKey,
              api: "openai-completions",
              models: [
                {
                  id: "acme-large",
                  name: "Acme Large",
                  reasoning: true,
                  input: ["text", "image"],
                  cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
                  contextWindow: 200000,
                  maxTokens: 32768,
                },
                {
                  id: "acme-small",
                  name: "Acme Small",
                  reasoning: false,
                  input: ["text"],
                  cost: { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
                  contextWindow: 128000,
                  maxTokens: 8192,
                },
              ],
            },
          };
        },
      },
    });

    api.registerModelCatalogProvider({
      provider: "acme-ai",
      kinds: ["text"],
      liveCatalog: async (ctx) => {
        const apiKey = ctx.resolveProviderApiKey("acme-ai").apiKey;
        if (!apiKey) return null;
        return [
          {
            kind: "text",
            provider: "acme-ai",
            model: "acme-large",
            label: "Acme Large",
            source: "live",
          },
        ];
      },
    });
  },
});
registerModelCatalogProvider, liste/yardım/seçici UI’si için daha yeni kontrol düzlemi katalog yüzeyidir. Bunu metin, görüntü oluşturma, video oluşturma ve müzik oluşturma satırları için kullanın. Satıcı uç nokta çağrılarını ve yanıt eşlemesini Plugin içinde tutun; paylaşılan satır şekli, kaynak etiketleri ve yardım işlemesini OpenClaw sahiplenir.Bu, çalışan bir sağlayıcıdır. Kullanıcılar artık openclaw onboard --acme-ai-api-key <key> çalıştırabilir ve model olarak acme-ai/acme-large seçebilir.Üst sağlayıcı OpenClaw’dan farklı kontrol token’ları kullanıyorsa, akış yolunu değiştirmek yerine küçük bir çift yönlü metin dönüşümü ekleyin:
api.registerTextTransforms({
  input: [
    { from: /red basket/g, to: "blue basket" },
    { from: /paper ticket/g, to: "digital ticket" },
    { from: /left shelf/g, to: "right shelf" },
  ],
  output: [
    { from: /blue basket/g, to: "red basket" },
    { from: /digital ticket/g, to: "paper ticket" },
    { from: /right shelf/g, to: "left shelf" },
  ],
});
input, aktarım öncesinde son sistem istemini ve metin mesajı içeriğini yeniden yazar. output, OpenClaw kendi kontrol işaretleyicilerini veya kanal teslimini ayrıştırmadan önce asistan metin deltalarını ve son metni yeniden yazar.Yalnızca API anahtarı kimlik doğrulamalı tek bir metin sağlayıcısı ve tek bir katalog destekli çalışma zamanı kaydeden yerleşik sağlayıcılar için daha dar defineSingleProviderPluginEntry(...) yardımcısını tercih edin:
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";

export default defineSingleProviderPluginEntry({
  id: "acme-ai",
  name: "Acme AI",
  description: "Acme AI model provider",
  provider: {
    label: "Acme AI",
    docsPath: "/providers/acme-ai",
    auth: [
      {
        methodId: "api-key",
        label: "Acme AI API key",
        hint: "API key from your Acme AI dashboard",
        optionKey: "acmeAiApiKey",
        flagName: "--acme-ai-api-key",
        envVar: "ACME_AI_API_KEY",
        promptMessage: "Enter your Acme AI API key",
        defaultModel: "acme-ai/acme-large",
      },
    ],
    catalog: {
      buildProvider: () => ({
        api: "openai-completions",
        baseUrl: "https://api.acme-ai.com/v1",
        models: [{ id: "acme-large", name: "Acme Large" }],
      }),
      buildStaticProvider: () => ({
        api: "openai-completions",
        baseUrl: "https://api.acme-ai.com/v1",
        models: [{ id: "acme-large", name: "Acme Large" }],
      }),
    },
  },
});
buildProvider, OpenClaw gerçek sağlayıcı kimlik doğrulamasını çözümleyebildiğinde kullanılan canlı katalog yoludur. Sağlayıcıya özgü keşif gerçekleştirebilir. buildStaticProvider yalnızca kimlik doğrulaması yapılandırılmadan önce gösterilmesi güvenli olan çevrimdışı satırlar için kullanın; kimlik bilgileri gerektirmemeli veya ağ istekleri yapmamalıdır. OpenClaw’ın models list --all gösterimi şu anda statik katalogları yalnızca yerleşik sağlayıcı Plugin’leri için, boş yapılandırma, boş ortam ve ajan/çalışma alanı yolları olmadan çalıştırır.Kimlik doğrulama akışınızın onboarding sırasında models.providers.*, alias’lar ve ajan varsayılan modelini de yamalaması gerekiyorsa, openclaw/plugin-sdk/provider-onboard içindeki hazır ayar yardımcılarını kullanın. En dar yardımcılar createDefaultModelPresetAppliers(...), createDefaultModelsPresetAppliers(...) ve createModelCatalogPresetAppliers(...) şeklindedir.Bir sağlayıcının yerel uç noktası normal openai-completions aktarımında akışlı kullanım bloklarını desteklediğinde, sağlayıcı kimliği kontrollerini sabit kodlamak yerine openclaw/plugin-sdk/provider-catalog-shared içindeki paylaşılan katalog yardımcılarını tercih edin. supportsNativeStreamingUsageCompat(...) ve applyProviderNativeStreamingUsageCompat(...), desteği uç nokta yetenek haritasından algılar; böylece yerel Moonshot/DashScope tarzı uç noktalar, bir Plugin özel sağlayıcı kimliği kullanıyor olsa bile yine de dahil olur.
3

Dinamik model çözümlemesi ekle

Sağlayıcınız rastgele model kimliklerini kabul ediyorsa (proxy veya router gibi), resolveDynamicModel ekleyin:
api.registerProvider({
  // ... id, label, auth, catalog from above

  resolveDynamicModel: (ctx) => ({
    id: ctx.modelId,
    name: ctx.modelId,
    provider: "acme-ai",
    api: "openai-completions",
    baseUrl: "https://api.acme-ai.com/v1",
    reasoning: false,
    input: ["text"],
    cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
    contextWindow: 128000,
    maxTokens: 8192,
  }),
});
Çözümleme bir ağ çağrısı gerektiriyorsa async ısınma için prepareDynamicModel kullanın - resolveDynamicModel tamamlandıktan sonra yeniden çalışır.
4

Çalışma zamanı hook'ları ekle (gerektiğinde)

Çoğu sağlayıcı yalnızca catalog + resolveDynamicModel gerektirir. Sağlayıcınız ihtiyaç duydukça hook’ları kademeli olarak ekleyin.Paylaşılan yardımcı oluşturucular artık en yaygın yeniden oynatma/araç uyumluluğu ailelerini kapsar; bu nedenle Plugin’lerin genellikle her hook’u tek tek elle bağlaması gerekmez:
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream";
import { buildProviderToolCompatFamilyHooks } from "openclaw/plugin-sdk/provider-tools";

const GOOGLE_FAMILY_HOOKS = {
  ...buildProviderReplayFamilyHooks({ family: "google-gemini" }),
  ...buildProviderStreamFamilyHooks("google-thinking"),
  ...buildProviderToolCompatFamilyHooks("gemini"),
};

api.registerProvider({
  id: "acme-gemini-compatible",
  // ...
  ...GOOGLE_FAMILY_HOOKS,
});
Bugün kullanılabilen yeniden oynatma aileleri:
AileNeleri bağlarBirlikte gelen örnekler
openai-compatibleAraç çağrısı kimliği temizleme, assistant-first sıralama düzeltmeleri ve taşımanın ihtiyaç duyduğu yerlerde genel Gemini-turn doğrulaması dahil, OpenAI uyumlu taşımalar için paylaşılan OpenAI tarzı yeniden oynatma ilkesimoonshot, ollama, xai, zai
anthropic-by-modelmodelId tarafından seçilen Claude-aware yeniden oynatma ilkesi; böylece Anthropic-message taşımaları, çözümlenen model gerçekten bir Claude kimliği olduğunda yalnızca Claude’a özgü thinking-block temizliği alıramazon-bedrock, anthropic-vertex
google-geminiYerel Gemini yeniden oynatma ilkesi, ayrıca bootstrap yeniden oynatma temizliği ve etiketli reasoning-output modugoogle, google-gemini-cli
passthrough-geminiOpenAI uyumlu proxy taşımaları üzerinden çalışan Gemini modelleri için Gemini thought-signature temizliği; yerel Gemini yeniden oynatma doğrulamasını veya bootstrap yeniden yazımlarını etkinleştirmezopenrouter, kilocode, opencode, opencode-go
hybrid-anthropic-openaiAnthropic-message ve OpenAI uyumlu model yüzeylerini tek bir plugin içinde karıştıran sağlayıcılar için hibrit ilke; isteğe bağlı yalnızca Claude thinking-block bırakma Anthropic tarafıyla sınırlı kalırminimax
Bugün kullanılabilir akış aileleri:
AileNeleri bağlarBirlikte gelen örnekler
google-thinkingPaylaşılan akış yolunda Gemini thinking yükü normalleştirmesigoogle, google-gemini-cli
kilocode-thinkingPaylaşılan proxy akış yolunda Kilo reasoning sarmalayıcısı; kilo/auto ve desteklenmeyen proxy reasoning kimlikleri enjekte edilen thinking’i atlarkilocode
moonshot-thinkingYapılandırma + /think düzeyinden Moonshot ikili yerel thinking yükü eşlememoonshot
minimax-fast-modePaylaşılan akış yolunda MiniMax fast-mode model yeniden yazımıminimax, minimax-portal
openai-responses-defaultsPaylaşılan yerel OpenAI/Codex Responses sarmalayıcıları: attribution başlıkları, /fast/serviceTier, metin ayrıntı düzeyi, yerel Codex web araması, reasoning uyumluluk yükü şekillendirmesi ve Responses bağlam yönetimiopenai, openai-codex
openrouter-thinkingProxy rotaları için OpenRouter reasoning sarmalayıcısı; desteklenmeyen model/auto atlamaları merkezi olarak işleniropenrouter
tool-stream-default-onAçıkça devre dışı bırakılmadıkça araç akışı isteyen Z.AI gibi sağlayıcılar için varsayılan olarak açık tool_stream sarmalayıcısızai
Her aile oluşturucu, aynı paketten dışa aktarılan daha düşük düzeyli genel yardımcılarla oluşturulur; bir sağlayıcının ortak kalıbın dışına çıkması gerektiğinde bunlara başvurabilirsiniz:
  • openclaw/plugin-sdk/provider-model-shared - ProviderReplayFamily, buildProviderReplayFamilyHooks(...) ve ham yeniden oynatma oluşturucuları (buildOpenAICompatibleReplayPolicy, buildAnthropicReplayPolicyForModel, buildGoogleGeminiReplayPolicy, buildHybridAnthropicOrOpenAIReplayPolicy). Ayrıca Gemini yeniden oynatma yardımcılarını (sanitizeGoogleGeminiReplayHistory, resolveTaggedReasoningOutputMode) ve uç nokta/model yardımcılarını (resolveProviderEndpoint, normalizeProviderId, normalizeGooglePreviewModelId) dışa aktarır.
  • openclaw/plugin-sdk/provider-stream - ProviderStreamFamily, buildProviderStreamFamilyHooks(...), composeProviderStreamWrappers(...), ayrıca paylaşılan OpenAI/Codex sarmalayıcıları (createOpenAIAttributionHeadersWrapper, createOpenAIFastModeWrapper, createOpenAIServiceTierWrapper, createOpenAIResponsesContextManagementWrapper, createCodexNativeWebSearchWrapper), DeepSeek V4 OpenAI uyumlu sarmalayıcı (createDeepSeekV4OpenAICompatibleThinkingWrapper), Anthropic Messages thinking prefill temizliği (createAnthropicThinkingPrefillPayloadWrapper) ve paylaşılan proxy/sağlayıcı sarmalayıcıları (createOpenRouterWrapper, createToolStreamWrapper, createMinimaxFastModeWrapper).
  • openclaw/plugin-sdk/provider-tools - ProviderToolCompatFamily, buildProviderToolCompatFamilyHooks("gemini") ve alttaki Gemini şema yardımcıları (normalizeGeminiToolSchemas, inspectGeminiToolSchemas).
Bazı akış yardımcıları bilinçli olarak sağlayıcıya yerel kalır. @openclaw/anthropic-provider, wrapAnthropicProviderStream, resolveAnthropicBetas, resolveAnthropicFastMode, resolveAnthropicServiceTier ve daha düşük düzeyli Anthropic sarmalayıcı oluşturucularını kendi genel api.ts / contract-api.ts birleşim noktasında tutar, çünkü bunlar Claude OAuth beta işlemesini ve context1m geçitlemesini kodlar. xAI plugin’i de yerel xAI Responses şekillendirmesini kendi wrapStreamFn içinde tutar (/fast takma adları, varsayılan tool_stream, desteklenmeyen katı araç temizliği, xAI’ye özgü reasoning yükü kaldırma).Aynı paket kökü kalıbı @openclaw/openai-provider (sağlayıcı oluşturucuları, varsayılan model yardımcıları, gerçek zamanlı sağlayıcı oluşturucuları) ve @openclaw/openrouter-provider (sağlayıcı oluşturucu ile onboarding/yapılandırma yardımcıları) için de temel oluşturur.
Her çıkarım çağrısından önce token değişimine ihtiyaç duyan sağlayıcılar için:
prepareRuntimeAuth: async (ctx) => {
  const exchanged = await exchangeToken(ctx.apiKey);
  return {
    apiKey: exchanged.token,
    baseUrl: exchanged.baseUrl,
    expiresAt: exchanged.expiresAt,
  };
},
OpenClaw hook’ları bu sırayla çağırır. Çoğu sağlayıcı yalnızca 2-3 tanesini kullanır: OpenClaw’ın artık çağırmadığı, ProviderPlugin.capabilities ve suppressBuiltInModel gibi yalnızca uyumluluk amaçlı sağlayıcı alanları burada listelenmez.
#HookNe zaman kullanılır
1catalogModel kataloğu veya temel URL varsayılanları
2applyConfigDefaultsYapılandırma maddeleştirmesi sırasında sağlayıcıya ait global varsayılanlar
3normalizeModelIdAramadan önce eski/önizleme model kimliği takma adı temizliği
4normalizeTransportGenel model derlemesinden önce sağlayıcı ailesi api / baseUrl temizliği
5normalizeConfigmodels.providers.<id> yapılandırmasını normalleştir
6applyNativeStreamingUsageCompatYapılandırma sağlayıcıları için yerel akış kullanımı uyumluluk yeniden yazımları
7resolveConfigApiKeySağlayıcıya ait env-marker kimlik doğrulama çözümlemesi
8resolveSyntheticAuthYerel/self-hosted veya yapılandırma destekli sentetik kimlik doğrulama
9shouldDeferSyntheticProfileAuthSentetik saklanan profil yer tutucularını env/yapılandırma kimlik doğrulamasının arkasına indir
10resolveDynamicModelRastgele upstream model kimliklerini kabul et
11prepareDynamicModelÇözümlemeden önce eşzamansız meta veri getirme
12normalizeResolvedModelRunner’dan önce taşıma yeniden yazımları
13contributeResolvedModelCompatBaşka bir uyumlu taşımanın arkasındaki vendor modelleri için uyumluluk bayrakları
14normalizeToolSchemasKayıttan önce sağlayıcıya ait araç şeması temizliği
15inspectToolSchemasSağlayıcıya ait araç şeması tanılamaları
16resolveReasoningOutputModeEtiketli ve yerel reasoning-output sözleşmesi
17prepareExtraParamsVarsayılan istek parametreleri
18createStreamFnTamamen özel StreamFn taşıması
19wrapStreamFnNormal akış yolunda özel başlık/gövde sarmalayıcıları
20resolveTransportTurnStateYerel tur başına başlıklar/meta veriler
21resolveWebSocketSessionPolicyYerel WS oturum başlıkları/cool-down
22formatApiKeyÖzel çalışma zamanı token şekli
23refreshOAuthÖzel OAuth yenileme
24buildAuthDoctorHintKimlik doğrulama onarım rehberliği
25matchesContextOverflowErrorSağlayıcıya ait taşma algılama
26classifyFailoverReasonSağlayıcıya ait rate-limit/overload sınıflandırması
27isCacheTtlEligiblePrompt cache TTL geçitlemesi
28buildMissingAuthMessageÖzel eksik kimlik doğrulama ipucu
29augmentModelCatalogSentetik ileri uyumluluk satırları
30resolveThinkingProfileModele özgü /think seçenek kümesi
31isBinaryThinkingİkili thinking açık/kapalı uyumluluğu
32supportsXHighThinkingxhigh reasoning desteği uyumluluğu
33resolveDefaultThinkingLevelVarsayılan /think ilkesi uyumluluğu
34isModernModelRefCanlı/smoke model eşleştirme
35prepareRuntimeAuthÇıkarımdan önce token değişimi
36resolveUsageAuthÖzel kullanım kimlik bilgisi ayrıştırma
37fetchUsageSnapshotÖzel kullanım uç noktası
38createEmbeddingProviderBellek/arama için sağlayıcıya ait embedding adaptörü
39buildReplayPolicyÖzel transcript yeniden oynatma/compaction ilkesi
40sanitizeReplayHistoryGenel temizlikten sonra sağlayıcıya özgü yeniden oynatma yeniden yazımları
41validateReplayTurnsGömülü runner’dan önce katı replay-turn doğrulaması
42onModelSelectedSeçim sonrası geri çağırma (ör. telemetri)
Çalışma zamanı fallback notları:
  • normalizeConfig önce eşleşen sağlayıcıyı, ardından yapılandırmayı gerçekten değiştiren biri çıkana kadar diğer hook destekli sağlayıcı plugin’lerini denetler. Hiçbir sağlayıcı hook’u desteklenen bir Google ailesi yapılandırma girdisini yeniden yazmazsa, birlikte gelen Google yapılandırma normalleştiricisi yine de uygulanır.
  • resolveConfigApiKey, sunulduğunda sağlayıcı hook’unu kullanır. Birlikte gelen amazon-bedrock yolunda ayrıca burada yerleşik bir AWS env-marker çözümleyicisi vardır; Bedrock çalışma zamanı kimlik doğrulamasının kendisi hâlâ AWS SDK varsayılan zincirini kullansa da.
  • resolveSystemPromptContribution, bir sağlayıcının bir model ailesi için önbellek farkındalıklı sistem prompt’u rehberliği enjekte etmesini sağlar. Davranış tek bir sağlayıcı/model ailesine ait olduğunda ve kararlı/dinamik önbellek ayrımını koruması gerektiğinde bunu before_prompt_build yerine tercih edin.
Ayrıntılı açıklamalar ve gerçek dünya örnekleri için bkz. İç Yapılar: Sağlayıcı Çalışma Zamanı Hook’ları.
5

Ek yetenekler ekle (isteğe bağlı)

Adım 5: Ek yetenekler ekle

Bir sağlayıcı plugin’i, metin çıkarımıyla birlikte konuşma, gerçek zamanlı transkripsiyon, gerçek zamanlı ses, medya anlama, görüntü oluşturma, video oluşturma, web getirme ve web aramayı kaydedebilir. OpenClaw bunu hibrit-yetenek plugin’i olarak sınıflandırır - şirket plugin’leri için önerilen desen budur (tedarikçi başına bir plugin). Bkz. Dahili Bilgiler: Yetenek Sahipliği.Her yeteneği, mevcut api.registerProvider(...) çağrınızın yanında register(api) içinde kaydedin. Yalnızca ihtiyacınız olan sekmeleri seçin:
import {
  assertOkOrThrowProviderError,
  postJsonRequest,
} from "openclaw/plugin-sdk/provider-http";

api.registerSpeechProvider({
  id: "acme-ai",
  label: "Acme Speech",
  isConfigured: ({ config }) => Boolean(config.messages?.tts),
  synthesize: async (req) => {
    const { response, release } = await postJsonRequest({
      url: "https://api.example.com/v1/speech",
      headers: new Headers({ "Content-Type": "application/json" }),
      body: { text: req.text },
      timeoutMs: req.timeoutMs,
      fetchFn: fetch,
      auditContext: "acme speech",
    });
    try {
      await assertOkOrThrowProviderError(response, "Acme Speech API error");
      return {
        audioBuffer: Buffer.from(await response.arrayBuffer()),
        outputFormat: "mp3",
        fileExtension: ".mp3",
        voiceCompatible: false,
      };
    } finally {
      await release();
    }
  },
});
Sağlayıcı HTTP hataları için assertOkOrThrowProviderError(...) kullanın; böylece plugin’ler sınırlı hata-gövdesi okumalarını, JSON hata ayrıştırmayı ve istek kimliği soneklerini paylaşır.
6

Test

Adım 6: Test

src/provider.test.ts
import { describe, it, expect } from "vitest";
// Export your provider config object from index.ts or a dedicated file
import { acmeProvider } from "./provider.js";

describe("acme-ai provider", () => {
  it("resolves dynamic models", () => {
    const model = acmeProvider.resolveDynamicModel!({
      modelId: "acme-beta-v3",
    } as any);
    expect(model.id).toBe("acme-beta-v3");
    expect(model.provider).toBe("acme-ai");
  });

  it("returns catalog when key is available", async () => {
    const result = await acmeProvider.catalog!.run({
      resolveProviderApiKey: () => ({ apiKey: "test-key" }),
    } as any);
    expect(result?.provider?.models).toHaveLength(2);
  });

  it("returns null catalog when no key", async () => {
    const result = await acmeProvider.catalog!.run({
      resolveProviderApiKey: () => ({ apiKey: undefined }),
    } as any);
    expect(result).toBeNull();
  });
});

ClawHub’a Yayınlama

Sağlayıcı plugin’leri, diğer tüm harici kod plugin’leriyle aynı şekilde yayınlanır:
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
Burada eski yalnızca-skill yayın takma adını kullanmayın; plugin paketleri clawhub package publish kullanmalıdır.

Dosya yapısı

<bundled-plugin-root>/acme-ai/
├── package.json              # openclaw.providers metadata
├── openclaw.plugin.json      # Manifest with provider auth metadata
├── index.ts                  # definePluginEntry + registerProvider
└── src/
    ├── provider.test.ts      # Tests
    └── usage.ts              # Usage endpoint (optional)

Katalog sırası başvurusu

catalog.order, kataloğunuzun yerleşik sağlayıcılara göre ne zaman birleştirileceğini kontrol eder:
SıraNe zamanKullanım durumu
simpleİlk geçişDüz API anahtarı sağlayıcıları
profilesimple sonrasıKimlik doğrulama profilleriyle sınırlandırılmış sağlayıcılar
pairedprofile sonrasıBirden çok ilişkili girdiyi sentezle
lateSon geçişMevcut sağlayıcıları geçersiz kıl (çakışmada kazanır)

Sonraki adımlar

İlgili