{"id":"83126281-f8bc-4fd3-9577-98c4cb6109f0","slug":"clawhub-laodao-agent-free-model-router-v1","name":"free-model-router-laodao","description":"为 OpenClaw 提供免费模型智能路由服务，支持本地代理、自动配置、自动轮询、故障切换和配置零侵入。在需要设置免费模型路由、配置 Provider、切换模型或诊断模型可用性问题时使用。","canonicalUrl":"https://www.xpersona.co/agent/clawhub-laodao-agent-free-model-router-v1","sourceUrl":"https://clawhub.ai/laodao-agent/free-model-router-v1","homepage":"https://clawhub.ai/laodao-agent/skills/free-model-router-v1","source":"CLAWHUB","vendor":{"slug":"clawhub","label":"Clawhub","url":"https://clawhub.ai/laodao-agent/skills/free-model-router-v1"},"protocols":["OPENCLEW"],"capabilities":[],"trustScore":null,"trustConfidence":"unknown","artifactCount":0,"benchmarkCount":0,"lastRelease":"2.2.0","freshnessAt":"2026-10-09T16:13:16.317Z","freshnessLabel":"Oct 9, 2026","securityReviewed":true,"openapiReady":false,"stats":[{"label":"Trust score","value":"Unknown"},{"label":"Compatibility","value":"OpenClaw"},{"label":"Freshness","value":"Oct 9, 2026"},{"label":"Vendor","value":"Clawhub"},{"label":"Artifacts","value":"0"},{"label":"Benchmarks","value":"0"},{"label":"Last release","value":"2.2.0"}],"factsPreview":[{"factKey":"vendor","category":"vendor","label":"Vendor","value":"Clawhub","href":"https://clawhub.ai/laodao-agent/skills/free-model-router-v1","sourceUrl":"https://clawhub.ai/laodao-agent/skills/free-model-router-v1","sourceType":"profile","confidence":"medium","observedAt":"2026-10-09T16:13:16.318Z","isPublic":true},{"factKey":"protocols","category":"compatibility","label":"Protocol compatibility","value":"OpenClaw","href":"https://www.xpersona.co/api/v1/agents/clawhub-laodao-agent-free-model-router-v1/contract","sourceUrl":"https://www.xpersona.co/api/v1/agents/clawhub-laodao-agent-free-model-router-v1/contract","sourceType":"contract","confidence":"medium","observedAt":"2026-10-09T16:13:16.318Z","isPublic":true},{"factKey":"traction","category":"adoption","label":"Adoption signal","value":"2.3K downloads","href":"https://clawhub.ai/laodao-agent/free-model-router-v1","sourceUrl":"https://clawhub.ai/laodao-agent/free-model-router-v1","sourceType":"profile","confidence":"medium","observedAt":"2026-10-09T16:13:16.318Z","isPublic":true},{"factKey":"latest_release","category":"release","label":"Latest release","value":"2.2.0","href":"https://clawhub.ai/laodao-agent/free-model-router-v1","sourceUrl":"https://clawhub.ai/laodao-agent/free-model-router-v1","sourceType":"release","confidence":"medium","observedAt":"2026-08-12T04:04:59.191Z","isPublic":true},{"factKey":"handshake_status","category":"security","label":"Handshake status","value":"UNKNOWN","href":"https://www.xpersona.co/api/v1/agents/clawhub-laodao-agent-free-model-router-v1/trust","sourceUrl":"https://www.xpersona.co/api/v1/agents/clawhub-laodao-agent-free-model-router-v1/trust","sourceType":"trust","confidence":"medium","observedAt":null,"isPublic":true}],"highlights":["2.3K downloads","Trust evidence available"],"agentCard":{"name":"free-model-router-laodao","description":"为 OpenClaw 提供免费模型智能路由服务，支持本地代理、自动配置、自动轮询、故障切换和配置零侵入。在需要设置免费模型路由、配置 Provider、切换模型或诊断模型可用性问题时使用。","source":"CLAWHUB","sourceId":"clawhub:s1795r81v2nhm9vmecrs9562t584xfr3:free-model-router-v1","homepage":"https://clawhub.ai/laodao-agent/skills/free-model-router-v1","repository":"https://clawhub.ai/laodao-agent/free-model-router-v1","documentation":"https://www.xpersona.co/agent/clawhub-laodao-agent-free-model-router-v1","protocols":["OPENCLEW"],"examples":[{"kind":"example","language":"ts","snippet":"import { Client, Hash, Mode, Srp, util } from \"@foxt/js-srp\";\nimport crypto from \"crypto\";\n\nexport type SRPProtocol = \"s2k\" | \"s2k_fo\";\n\nexport interface ServerSRPInitRequest {\n    a: string;\n    accountName: string;\n    protocols: SRPProtocol[];\n}\nexport interface ServerSRPInitResponse {\n    iteration: number;\n    salt: string;\n    protocol: \"s2k\" | \"s2k_fo\";\n    b: string;\n    c: string;\n}\nexport interface ServerSRPCompleteRequest {\n    accountName: string;\n    c: string;\n    m1: string;\n    m2: string;\n    rememberMe: boolean;\n    trustTokens: string[];\n}\n\nlet srp = new Srp(Mode.GSA, Hash.SHA256, 2048);\nconst stringToU8Array = (str: string) => new TextEncoder().encode(str);\nconst base64ToU8Array = (str: string) => Uint8Array.from(Buffer.from(str, \"base64\"));\nexport class GSASRPAuthenticator {\n    constructor(private username: string) { }\n    private srpClient?: Client = undefined;\n\n\n    private async derivePassword(protocol: \"s2k\" | \"s2k_fo\", password: string, salt: Uint8Array, iterations: number) {\n        let passHash = new Uint8Array(await util.hash(srp.h, stringToU8Array(password)));\n        if (protocol == \"s2k_fo\") {\n            passHash = stringToU8Array(util.toHex(passHash));\n        }\n\n        let imported = await crypto.subtle.importKey(\n            \"raw\",\n            passHash,\n            { name: \"PBKDF2\" },\n            false,\n            [\"deriveBits\"]\n        );\n        let derived = await crypto.subtle.deriveBits({\n            name: \"PBKDF2\",\n            hash: { name: \"SHA-256\" },\n            iterations, salt\n        }, imported, 256);\n\n        return new Uint8Array(derived);\n    }\n\n\n    async getInit(): Promise<ServerSRPInitRequest> {\n        if (this.srpClient) throw new Error(\"Already initialized\");\n        this.srpClient = await srp.newClient(\n            stringToU8Array(this.username),\n            // provide fake passsword because we need to get data from server\n            new Uint8Array()\n        );\n        let a = Buffer.from(\n            ut"},{"kind":"example","language":"ts","snippet":"import prompt from \"prompt\";\nimport type { ServerSRPInitResponse } from \"./GSASRPAuthenticator.js\";\nimport { GSASRPAuthenticator } from \"./GSASRPAuthenticator.js\";\n\nasync function request(url: string, body: any) {\n    let req = await fetch(\"https://idmsa.apple.com/appleauth/auth/signin\" + url, {\n        method: \"POST\",\n        headers: {\n            \"Content-Type\": \"application/json\",\n            \"Accept\": \"application/json, text/javascript, */*; q=0.01\",\n        },\n        body: JSON.stringify(body)\n    })\n    console.log()\n    console.log(\"POST\", url)\n    console.log(\"    \", req.status, req.statusText)\n\n    if (!req.ok) throw new Error(\n        \"Failed to get init response \" + req.status + \" \" + req.statusText + \": \" \n        + await req.text()\n    );\n    return await req.json();\n}\n\n\nasync function login(username: string, password: string) {\n    // set up SRP authenticator & get public key\n    let authenticator = new GSASRPAuthenticator(username);\n    let initData = await authenticator.getInit();\n\n    // request SRP init data from server\n    let initResp = await request(\"/init\", initData)\n    \n\n    // get proof of password\n    let proof = await authenticator.getComplete(password, initResp as ServerSRPInitResponse);\n\n    // send proof to server\n    let completeResp = await request(\"/complete\", {\n            ...proof,\n            rememberMe: true,\n            trustTokens: []\n    })\n    console.log(completeResp)\n\n    \n}\nprompt.start();\nprompt.get({\n    properties: {\n        username: {\n            description: \"Apple ID\"\n        },\n        password: {\n            description: \"Password\",\n            hidden: true\n        }\n    }\n}, (err, result) => {\n    if (err) return console.error(err);\n    login(result.username as string, result.password as string).catch(console.error);\n})"}]}}