From 04c35d7f6d6bb7c0a87ff50023590565a12bcc8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BE=84=E6=BD=AD?= Date: Sun, 1 Feb 2026 21:57:45 +0800 Subject: [PATCH] feat: integrate higress-ai-gateway plugin into higress-clawdbot-integration skill (#3437) --- .../higress-clawdbot-integration/SKILL.md | 185 ++++++++++++ .../scripts/plugin/README.md | 92 ++++++ .../scripts/plugin/index.ts | 284 ++++++++++++++++++ .../scripts/plugin/openclaw.plugin.json | 10 + .../scripts/plugin/package.json | 22 ++ 5 files changed, 593 insertions(+) create mode 100644 .claude/skills/higress-clawdbot-integration/scripts/plugin/README.md create mode 100644 .claude/skills/higress-clawdbot-integration/scripts/plugin/index.ts create mode 100644 .claude/skills/higress-clawdbot-integration/scripts/plugin/openclaw.plugin.json create mode 100644 .claude/skills/higress-clawdbot-integration/scripts/plugin/package.json diff --git a/.claude/skills/higress-clawdbot-integration/SKILL.md b/.claude/skills/higress-clawdbot-integration/SKILL.md index 64f1bb5bb..075eee87b 100644 --- a/.claude/skills/higress-clawdbot-integration/SKILL.md +++ b/.claude/skills/higress-clawdbot-integration/SKILL.md @@ -407,3 +407,188 @@ Configuration has been hot-reloaded (no restart needed). - Verify the API key is correct - Check provider documentation for key format - Some providers require additional configuration (e.g., Azure, Bedrock) + +## Clawdbot/OpenClaw Plugin Integration + +The Higress AI Gateway plugin enables Clawdbot and OpenClaw to use Higress as a model provider with full support for auto-routing and model management. + +### Installation + +The plugin is automatically available as part of this skill. To install it into your Clawdbot/OpenClaw environment: + +```bash +# Detect runtime and set variables +if command -v clawdbot &> /dev/null; then + RUNTIME="clawdbot" + RUNTIME_DIR="$HOME/.clawdbot" +elif command -v openclaw &> /dev/null; then + RUNTIME="openclaw" + RUNTIME_DIR="$HOME/.openclaw" +else + echo "Error: Neither clawdbot nor openclaw is installed" + exit 1 +fi + +# Install the plugin +PLUGIN_SRC_DIR="scripts/plugin" +PLUGIN_DEST_DIR="$RUNTIME_DIR/extensions/higress-ai-gateway" + +if [ ! -d "$PLUGIN_SRC_DIR" ]; then + echo "Error: Plugin source not found at $PLUGIN_SRC_DIR" + exit 1 +fi + +echo "Installing Higress AI Gateway plugin for $RUNTIME..." +mkdir -p "$(dirname "$PLUGIN_DEST_DIR")" +if [ -d "$PLUGIN_DEST_DIR" ]; then + echo "Plugin already exists, updating..." + rm -rf "$PLUGIN_DEST_DIR" +fi + +cp -r "$PLUGIN_SRC_DIR" "$PLUGIN_DEST_DIR" +echo "✓ Higress AI Gateway plugin installed at: $PLUGIN_DEST_DIR" + +echo +echo "To configure the provider, run:" +echo " $RUNTIME models auth login --provider higress" +``` + +### Configuration + +After installation, configure Higress as a model provider: + +```bash +# For Clawdbot +clawdbot models auth login --provider higress + +# For OpenClaw +openclaw models auth login --provider higress +``` + +The plugin will guide you through an interactive setup: + +1. **Gateway URL**: HTTP endpoint for Higress AI Gateway (default: `http://localhost:8080`) +2. **Console URL**: Higress Console endpoint for routing config (default: `http://localhost:8001`) +3. **API Key**: Optional API key for authentication (leave empty for local deployments) +4. **Model List**: Comma-separated model IDs (plugin auto-detects available models) +5. **Auto-routing**: If you include `higress/auto` in the model list, configure the default fallback model + +### Plugin Features + +#### 1. Auto-routing Support + +The plugin provides first-class support for Higress auto-routing: + +- Use `higress/auto` as the model ID to enable intelligent routing +- Configure default fallback model during setup +- Auto-routing rules are managed separately via the `higress-auto-router` skill + +#### 2. Dynamic Model Discovery + +During configuration, the plugin: +- Tests connectivity to the gateway +- Fetches available models from the Console API +- Pre-populates the model list with discovered models +- Allows customization of the model list + +#### 3. Smart URL Normalization + +The plugin automatically: +- Strips trailing slashes from URLs +- Appends `/v1` suffix if missing +- Validates URL format before saving + +#### 4. Profile Management + +Creates appropriate credential profiles: +- `higress:local` - for local deployments without API key +- `higress:default` - for remote deployments with API key + +### Plugin Structure + +``` +scripts/plugin/ +├── index.ts # Plugin implementation (TypeScript) +├── package.json # NPM package metadata +└── openclaw.plugin.json # OpenClaw plugin manifest +``` + +**index.ts**: Main plugin code implementing the provider registration and authentication flow. + +**package.json**: Declares the plugin as an OpenClaw extension with proper metadata. + +**openclaw.plugin.json**: Plugin manifest describing supported providers and configuration schema. + +### Integration with Skills + +The plugin works seamlessly with related skills: + +#### higress-auto-router +After plugin setup, use this skill to configure routing rules: +```bash +./get-ai-gateway.sh route add --model claude-opus-4.5 --trigger "深入思考" +``` + +See: [higress-auto-router](../higress-auto-router/SKILL.md) + +#### agent-session-monitor +Track token usage and costs across sessions using gateway access logs: +```bash +python3 agent-session-monitor/scripts/webserver.py --log-path ./higress/logs/access.log +``` + +See: [agent-session-monitor](../agent-session-monitor/SKILL.md) + +### Example: Full Setup Flow + +```bash +# 1. Deploy Higress AI Gateway (via get-ai-gateway.sh) +./get-ai-gateway.sh start --non-interactive \ + --dashscope-key sk-xxx \ + --auto-routing + +# 2. Detect and install plugin +if command -v clawdbot &> /dev/null; then + RUNTIME="clawdbot" + RUNTIME_DIR="$HOME/.clawdbot" +else + RUNTIME="openclaw" + RUNTIME_DIR="$HOME/.openclaw" +fi + +mkdir -p "$RUNTIME_DIR/extensions" +cp -r scripts/plugin "$RUNTIME_DIR/extensions/higress-ai-gateway" + +# 3. Configure provider +$RUNTIME models auth login --provider higress +# Follow interactive prompts to configure gateway URL, models, etc. + +# 4. Test the integration +$RUNTIME chat --model higress/auto "Hello, test auto-routing!" + +# 5. Configure routing rules (optional) +./get-ai-gateway.sh route add --model claude-opus-4.5 --trigger "深入思考" +``` + +### Troubleshooting + +#### Plugin not recognized +- Verify plugin is installed at `~/.clawdbot/extensions/higress-ai-gateway` or `~/.openclaw/extensions/higress-ai-gateway` +- Check `package.json` contains correct `openclaw.extensions` field +- Restart Clawdbot/OpenClaw after installation + +#### Gateway connection fails +- Ensure Higress AI Gateway container is running: `docker ps` +- Verify gateway URL is accessible: `curl http://localhost:8080/v1/models` +- Check firewall/network settings if using remote gateway + +#### Models not available +- Run `clawdbot models list` or `openclaw models list` to verify provider is configured +- Check gateway logs: `docker logs higress-ai-gateway` +- Verify API keys are correctly configured in gateway + +#### Auto-routing not working +- Confirm `higress/auto` is in your model list +- Check routing rules exist: `./get-ai-gateway.sh route list` +- Verify default model is configured +- Check gateway logs for routing decisions diff --git a/.claude/skills/higress-clawdbot-integration/scripts/plugin/README.md b/.claude/skills/higress-clawdbot-integration/scripts/plugin/README.md new file mode 100644 index 000000000..3c05277dd --- /dev/null +++ b/.claude/skills/higress-clawdbot-integration/scripts/plugin/README.md @@ -0,0 +1,92 @@ +# Higress AI Gateway Plugin + +OpenClaw/Clawdbot model provider plugin for Higress AI Gateway with auto-routing support. + +## What is this? + +This is a TypeScript-based provider plugin that enables Clawdbot and OpenClaw to use Higress AI Gateway as a model provider. It provides: + +- **Auto-routing support**: Use `higress/auto` to intelligently route requests based on message content +- **Dynamic model discovery**: Auto-detect available models from Higress Console +- **Smart URL handling**: Automatic URL normalization and validation +- **Flexible authentication**: Support for both local and remote gateway deployments + +## Files + +- **index.ts**: Main plugin implementation +- **package.json**: NPM package metadata and OpenClaw extension declaration +- **openclaw.plugin.json**: Plugin manifest for OpenClaw + +## Installation + +This plugin is automatically installed when you use the `higress-clawdbot-integration` skill. See the parent SKILL.md for complete installation instructions. + +### Manual Installation + +If you need to install manually: + +```bash +# Detect runtime +if command -v clawdbot &> /dev/null; then + RUNTIME_DIR="$HOME/.clawdbot" +elif command -v openclaw &> /dev/null; then + RUNTIME_DIR="$HOME/.openclaw" +else + echo "Error: Neither clawdbot nor openclaw is installed" + exit 1 +fi + +# Copy plugin files +mkdir -p "$RUNTIME_DIR/extensions/higress-ai-gateway" +cp -r ./* "$RUNTIME_DIR/extensions/higress-ai-gateway/" + +# Configure provider +clawdbot models auth login --provider higress +# or +openclaw models auth login --provider higress +``` + +## Usage + +After installation, configure Higress as a model provider: + +```bash +clawdbot models auth login --provider higress +``` + +The plugin will prompt for: +1. Gateway URL (default: http://localhost:8080) +2. Console URL (default: http://localhost:8001) +3. API Key (optional for local deployments) +4. Model list (auto-detected or manually specified) +5. Auto-routing default model (if using higress/auto) + +## Auto-routing + +To use auto-routing, include `higress/auto` in your model list during configuration. Then use it in your conversations: + +```bash +# Use auto-routing +clawdbot chat --model higress/auto "深入思考 这个问题应该怎么解决?" + +# The gateway will automatically route to the appropriate model based on: +# - Message content triggers (configured via higress-auto-router skill) +# - Fallback to default model if no rule matches +``` + +## Related Resources + +- **Parent Skill**: [higress-clawdbot-integration](../SKILL.md) +- **Auto-routing Configuration**: [higress-auto-router](../../higress-auto-router/SKILL.md) +- **Session Monitoring**: [agent-session-monitor](../../agent-session-monitor/SKILL.md) +- **Higress AI Gateway**: https://github.com/higress-group/higress-standalone + +## Compatibility + +- **OpenClaw**: v2.0.0+ +- **Clawdbot**: v2.0.0+ +- **Higress AI Gateway**: All versions + +## License + +Apache-2.0 diff --git a/.claude/skills/higress-clawdbot-integration/scripts/plugin/index.ts b/.claude/skills/higress-clawdbot-integration/scripts/plugin/index.ts new file mode 100644 index 000000000..caf91b2ec --- /dev/null +++ b/.claude/skills/higress-clawdbot-integration/scripts/plugin/index.ts @@ -0,0 +1,284 @@ +import { emptyPluginConfigSchema } from "openclaw/plugin-sdk"; + +const DEFAULT_GATEWAY_URL = "http://localhost:8080"; +const DEFAULT_CONSOLE_URL = "http://localhost:8001"; +const DEFAULT_CONTEXT_WINDOW = 128_000; +const DEFAULT_MAX_TOKENS = 8192; + +// Common models that Higress AI Gateway typically supports +const DEFAULT_MODEL_IDS = [ + // Auto-routing special model + "higress/auto", + // OpenAI models + "gpt-5.2", + "gpt-5-mini", + "gpt-5-nano", + // Anthropic models + "claude-opus-4.5", + "claude-sonnet-4.5", + "claude-haiku-4.5", + // Qwen models + "qwen3-turbo", + "qwen3-plus", + "qwen3-max", + "qwen3-coder-480b-a35b-instruct", + // DeepSeek models + "deepseek-chat", + "deepseek-reasoner", + // Other common models + "kimi-k2.5", + "glm-4.7", + "MiniMax-M2.1", +] as const; + +function normalizeBaseUrl(value: string): string { + const trimmed = value.trim(); + if (!trimmed) return DEFAULT_GATEWAY_URL; + let normalized = trimmed; + while (normalized.endsWith("/")) normalized = normalized.slice(0, -1); + if (!normalized.endsWith("/v1")) normalized = `${normalized}/v1`; + return normalized; +} + +function validateUrl(value: string): string | undefined { + const normalized = normalizeBaseUrl(value); + try { + new URL(normalized); + } catch { + return "Enter a valid URL"; + } + return undefined; +} + +function parseModelIds(input: string): string[] { + const parsed = input + .split(/[\n,]/) + .map((model) => model.trim()) + .filter(Boolean); + return Array.from(new Set(parsed)); +} + +function buildModelDefinition(modelId: string) { + const isAutoModel = modelId === "higress/auto"; + return { + id: modelId, + name: isAutoModel ? "Higress Auto Router" : modelId, + api: "openai-completions", + reasoning: false, + input: ["text", "image"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: DEFAULT_CONTEXT_WINDOW, + maxTokens: DEFAULT_MAX_TOKENS, + }; +} + +async function testGatewayConnection(gatewayUrl: string): Promise { + try { + const response = await fetch(`${gatewayUrl}/v1/models`, { + method: "GET", + headers: { "Content-Type": "application/json" }, + signal: AbortSignal.timeout(5000), + }); + return response.ok || response.status === 401; // 401 means gateway is up but needs auth + } catch { + return false; + } +} + +async function fetchAvailableModels(consoleUrl: string): Promise { + try { + // Try to get models from Higress Console API + const response = await fetch(`${consoleUrl}/v1/ai/routes`, { + method: "GET", + headers: { "Content-Type": "application/json" }, + signal: AbortSignal.timeout(5000), + }); + if (response.ok) { + const data = (await response.json()) as { data?: { model?: string }[] }; + if (data.data && Array.isArray(data.data)) { + return data.data + .map((route: { model?: string }) => route.model) + .filter((m): m is string => typeof m === "string"); + } + } + } catch { + // Ignore errors, use defaults + } + return []; +} + +const higressPlugin = { + id: "higress-ai-gateway", + name: "Higress AI Gateway", + description: "Model provider plugin for Higress AI Gateway with auto-routing support", + configSchema: emptyPluginConfigSchema(), + register(api) { + api.registerProvider({ + id: "higress", + label: "Higress AI Gateway", + docsPath: "/providers/models", + aliases: ["higress-gateway", "higress-ai"], + auth: [ + { + id: "api-key", + label: "API Key", + hint: "Configure Higress AI Gateway endpoint with optional API key", + kind: "custom", + run: async (ctx) => { + // Step 1: Get Gateway URL + const gatewayUrlInput = await ctx.prompter.text({ + message: "Higress AI Gateway URL", + initialValue: DEFAULT_GATEWAY_URL, + validate: validateUrl, + }); + const gatewayUrl = normalizeBaseUrl(gatewayUrlInput); + + // Step 2: Get Console URL (for auto-router configuration) + const consoleUrlInput = await ctx.prompter.text({ + message: "Higress Console URL (for auto-router config)", + initialValue: DEFAULT_CONSOLE_URL, + validate: validateUrl, + }); + const consoleUrl = normalizeBaseUrl(consoleUrlInput); + + // Step 3: Test connection (create a new spinner) + const spin = ctx.prompter.progress("Testing gateway connection…"); + const isConnected = await testGatewayConnection(gatewayUrl); + if (!isConnected) { + spin.stop("Gateway connection failed"); + await ctx.prompter.note( + [ + "Could not connect to Higress AI Gateway.", + "Make sure the gateway is running and the URL is correct.", + "", + `Tried: ${gatewayUrl}/v1/models`, + ].join("\n"), + "Connection Warning", + ); + } else { + spin.stop("Gateway connected"); + } + + // Step 4: Get API Key (optional for local gateway) + const apiKeyInput = await ctx.prompter.text({ + message: "API Key (leave empty if not required)", + initialValue: "", + }) || ''; + const apiKey = apiKeyInput.trim() || "higress-local"; + + // Step 5: Fetch available models (create a new spinner) + const spin2 = ctx.prompter.progress("Fetching available models…"); + const fetchedModels = await fetchAvailableModels(consoleUrl); + const defaultModels = fetchedModels.length > 0 + ? ["higress/auto", ...fetchedModels] + : DEFAULT_MODEL_IDS; + spin2.stop(); + + // Step 6: Let user customize model list + const modelInput = await ctx.prompter.text({ + message: "Model IDs (comma-separated, higress/auto enables auto-routing)", + initialValue: defaultModels.slice(0, 10).join(", "), + validate: (value) => + parseModelIds(value).length > 0 ? undefined : "Enter at least one model id", + }); + + const modelIds = parseModelIds(modelInput); + const hasAutoModel = modelIds.includes("higress/auto"); + + // FIX: Avoid double prefix - if modelId already starts with provider, don't add prefix again + const defaultModelId = hasAutoModel + ? "higress/auto" + : (modelIds[0] ?? "qwen-turbo"); + const defaultModelRef = defaultModelId.startsWith("higress/") + ? defaultModelId + : `higress/${defaultModelId}`; + + // Step 7: Configure default model for auto-routing + let autoRoutingDefaultModel = "qwen-turbo"; + if (hasAutoModel) { + const autoRoutingModelInput = await ctx.prompter.text({ + message: "Default model for auto-routing (when no rule matches)", + initialValue: "qwen-turbo", + }); + autoRoutingDefaultModel = autoRoutingModelInput.trim(); // FIX: Add trim() here + } + + return { + profiles: [ + { + profileId: `higress:${apiKey === "higress-local" ? "local" : "default"}`, + credential: { + type: "token", + provider: "higress", + token: apiKey, + }, + }, + ], + configPatch: { + models: { + providers: { + higress: { + baseUrl: `${gatewayUrl}/v1`, + apiKey: apiKey, + api: "openai-completions", + authHeader: apiKey !== "higress-local", + models: modelIds.map((modelId) => buildModelDefinition(modelId)), + }, + }, + }, + agents: { + defaults: { + models: Object.fromEntries( + modelIds.map((modelId) => { + // FIX: Avoid double prefix - only add provider prefix if not already present + const modelRef = modelId.startsWith("higress/") + ? modelId + : `higress/${modelId}`; + return [modelRef, {}]; + }), + ), + }, + }, + plugins: { + entries: { + "higress-ai-gateway": { + enabled: true, + config: { + gatewayUrl, + consoleUrl, + autoRoutingDefaultModel, + }, + }, + }, + }, + }, + defaultModel: defaultModelRef, + notes: [ + "Higress AI Gateway is now configured as a model provider.", + hasAutoModel + ? `Auto-routing enabled: use model "higress/auto" to route based on message content.` + : "Add 'higress/auto' to models to enable auto-routing.", + `Gateway endpoint: ${gatewayUrl}/v1/chat/completions`, + `Console: ${consoleUrl}`, + "", + "🎯 Recommended Skills (install via Clawdbot conversation):", + "", + "1. Auto-Routing Skill:", + " Configure automatic model routing based on message content", + " https://github.com/alibaba/higress/tree/main/.claude/skills/higress-auto-router", + ' Say: "Install higress-auto-router skill"', + "", + "2. Agent Session Monitor Skill:", + " Track token usage and monitor conversation history", + " https://github.com/alibaba/higress/tree/main/.claude/skills/agent-session-monitor", + ' Say: "Install agent-session-monitor skill"', + ], + }; + }, + }, + ], + }); + }, +}; + +export default higressPlugin; diff --git a/.claude/skills/higress-clawdbot-integration/scripts/plugin/openclaw.plugin.json b/.claude/skills/higress-clawdbot-integration/scripts/plugin/openclaw.plugin.json new file mode 100644 index 000000000..2573d41bf --- /dev/null +++ b/.claude/skills/higress-clawdbot-integration/scripts/plugin/openclaw.plugin.json @@ -0,0 +1,10 @@ +{ + "id": "higress-ai-gateway", + "name": "Higress AI Gateway", + "description": "Model provider plugin for Higress AI Gateway with auto-routing support", + "providers": ["higress"], + "configSchema": { + "type": "object", + "additionalProperties": true + } +} diff --git a/.claude/skills/higress-clawdbot-integration/scripts/plugin/package.json b/.claude/skills/higress-clawdbot-integration/scripts/plugin/package.json new file mode 100644 index 000000000..47a9b3735 --- /dev/null +++ b/.claude/skills/higress-clawdbot-integration/scripts/plugin/package.json @@ -0,0 +1,22 @@ +{ + "name": "@higress/higress-ai-gateway", + "version": "1.0.0", + "description": "Higress AI Gateway model provider plugin for OpenClaw with auto-routing support", + "main": "index.ts", + "openclaw": { + "extensions": ["./index.ts"] + }, + "keywords": [ + "openclaw", + "higress", + "ai-gateway", + "model-router", + "auto-routing" + ], + "author": "Higress Team", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/alibaba/higress" + } +}