local adapter = {} adapter.name = "kimicode" adapter.version = "1.0.0" adapter.endpoint = "/v1/chat/completions" adapter.headers = {} -- KimiCode / Kimi K2 属于 OpenAI 兼容协议;但部分云端 API 会校验调用方 -- "app"(只放行特定 agent),要求每次请求带上按 secret 计算的应用签名。 -- 这里演示 build_headers 钩子:基于 timestamp + 请求体哈希生成签名头。 -- -- 配置要求(source.meta): -- meta: -- app_id: <申请到的 app id> -- app_key: <你的 key(由网关的 base_url 复用 api_key 亦可)> -- app_secret: <签名密钥> -- app_agent: code-agent # 若云端要求声明 agent 身份 function adapter.transform_request(raw_body) local ok, req = pcall(json.decode, raw_body) if not ok then return raw_body end req.model = req.model or "kimi-k2" -- The gateway's private control fields are GONE from the body (v2): the -- neutral `thinking` field carries that intent and each adapter maps it in -- its own protocol terms. These upstreams have no thinking switch at all, -- so the field is simply dropped here — which is what the nil-ing below -- used to do, except the field being dropped is no longer the kernel's -- private one. req.thinking = nil req.extra_body = nil return json.encode(req) end -- 可选的动态签名钩子。meta 由 Go 注入: -- meta.url / meta.method / meta.body / meta.api_key / meta.timestamp / meta.source.meta function adapter.build_headers(meta) local h = { ["Content-Type"] = "application/json", ["X-App-Id"] = tostring((meta.source.meta or {}).app_id or ""), ["X-Timestamp"] = tostring(meta.timestamp), } local agent = (meta.source.meta or {}).app_agent if agent and agent ~= "" then h["X-Agent"] = agent end -- 校验 app:通常要求 Authorization 用 app secret 派生签名 local secret = (meta.source.meta or {}).app_secret local api_key = meta.source.meta and meta.source.meta.api_key or meta.api_key if secret and secret ~= "" then local body_hash = sha256_hex(meta.body) local sign_string = tostring(meta.timestamp) .. meta.method .. meta.url .. body_hash local sign = hmac_sha256_hex(secret, sign_string) h["Authorization"] = "Bearer " .. api_key h["X-App-Sign"] = sign else h["Authorization"] = "Bearer " .. api_key end return h end function adapter.transform_response(raw_body) -- 非流式 OpenAI 响应 → 统一信封。此前在 openai/groq/kimicode/mistral/github -- 五个适配器里**逐字节相同**(各 2206B,diff 为空),已抽到共享前导。 return __prelude.openai_response(raw_body) end function adapter.transform_stream_chunk(raw_chunk) -- 标准 OpenAI SSE → 统一信封。该实现此前在 groq/kimicode/mistral/github -- 四个适配器里**逐字节重复**(各 2211B),已抽到共享前导。 return __prelude.openai_stream_chunk(raw_chunk) end -- 错误收敛:kimi 网关为 OpenAI 风格 {error:{message,...}} function adapter.transform_error(status, body) -- OpenAI 风格错误体抽消息。此前在 deepseek/github/groq/kimicode/ -- openai/sensenova 六个适配器里逐字节相同(各 293B),已抽到共享前导。 return __prelude.openai_error(status, body) end return adapter