Spaces:
Running
Running
File size: 3,086 Bytes
2a2730a b149c75 2a2730a 0b469f5 2a2730a 0b469f5 2a2730a 69ad73f b149c75 2a2730a b149c75 4e47b4d 2a2730a b149c75 2a2730a 69ad73f ea8c7bd 69ad73f a5d956c 69ad73f a5d956c 69ad73f a5d956c 69ad73f 2a2730a ea8c7bd 84c554d ea8c7bd 2a2730a 0b469f5 2a2730a b149c75 4e47b4d b149c75 2a2730a 69ad73f 2a2730a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | /**
* Headroom OpenClaw Plugin — register ContextEngine + CCR retrieval tool.
*
* Usage:
* openclaw plugins install headroom-ai/openclaw
*
* Configuration (in ~/.openclaw/config.json or ~/.clawdbot/clawdbot.json):
* {
* "plugins": {
* "slots": { "contextEngine": "headroom" },
* "entries": { "headroom": { "enabled": true } }
* }
* }
*/
/* eslint-disable @typescript-eslint/no-explicit-any */
import { HeadroomContextEngine } from "../engine.js";
import {
applyGatewayProviderBaseUrlsInPlace,
resolveGatewayProviderIds,
} from "../gateway-config.js";
import { normalizeAndValidateProxyUrl } from "../proxy-manager.js";
import { createHeadroomRetrieveTool } from "../tools/headroom-retrieve.js";
export default function headroomPlugin(api: any) {
const config = api.config?.plugins?.entries?.headroom?.config ?? {};
const logger = api.logger ?? console;
const rawProxyUrl = config.proxyUrl;
const proxyUrl =
typeof rawProxyUrl === "string" && rawProxyUrl.trim().length > 0
? normalizeAndValidateProxyUrl(rawProxyUrl)
: undefined;
const engine = new HeadroomContextEngine({ ...config, proxyUrl }, {
info: (m: string) => logger.info(m),
warn: (m: string) => logger.warn(m),
error: (m: string) => logger.error(m),
debug: (m: string) => logger.debug?.(m),
});
const gatewayProviderIds = resolveGatewayProviderIds(config);
const applyGatewayRouting = async (activeProxyUrl: string) => {
if (gatewayProviderIds.length === 0) {
return;
}
try {
const changed = applyGatewayProviderBaseUrlsInPlace(api.config, activeProxyUrl, gatewayProviderIds);
if (changed) {
logger.info(
`[headroom] Routed ${gatewayProviderIds.join(", ")} through Headroom proxy in memory at ${activeProxyUrl}`,
);
} else {
logger.info(
`[headroom] Upstream gateway already routed in memory for ${gatewayProviderIds.join(", ")} at ${activeProxyUrl}`,
);
}
} catch (error) {
logger.warn(`[headroom] Failed to configure upstream gateway routing: ${error}`);
}
};
const ensureGatewayRouting = async () => {
const activeProxyUrl = engine.getProxyUrl();
if (!activeProxyUrl) {
logger.debug?.("[headroom] Deferring upstream gateway routing until proxy is available");
engine.ensureProxyStarted();
return;
}
await applyGatewayRouting(activeProxyUrl);
};
engine.onProxyReady(async (activeProxyUrl) => {
await applyGatewayRouting(activeProxyUrl);
});
// Register as context engine
api.registerContextEngine("headroom", () => engine);
// Register CCR retrieval tool (active once proxy is running)
api.registerTool((ctx: any) => {
const activeProxyUrl = engine.getProxyUrl() ?? proxyUrl;
if (!activeProxyUrl) return null;
return createHeadroomRetrieveTool({ proxyUrl: activeProxyUrl });
});
api.on("gateway_start", async () => {
await ensureGatewayRouting();
});
void ensureGatewayRouting();
logger.info("[headroom] Plugin registered");
}
|