LoRDxdd's picture
Add gpt4free API for Hugging Face
a4b70d9
from __future__ import annotations
import random
from typing import AsyncIterator
from .base_provider import AsyncAuthedProvider, ProviderModelMixin
from ..providers.helper import get_last_user_message
from ..requests import StreamSession, sse_stream, raise_for_status
from ..providers.response import AuthResult, TitleGeneration, JsonConversation, FinishReason
from ..typing import AsyncResult, Messages
from ..errors import MissingAuthError
class Kimi(AsyncAuthedProvider, ProviderModelMixin):
url = "https://www.kimi.com"
working = True
active_by_default = True
default_model = "kimi-k2"
models = [default_model]
model_aliases = {"moonshotai/Kimi-K2-Instruct": default_model}
@classmethod
async def on_auth_async(cls, proxy: str = None, **kwargs) -> AsyncIterator:
device_id = str(random.randint(1000000000000000, 9999999999999999))
async with StreamSession(proxy=proxy, impersonate="chrome") as session:
async with session.post(
"https://www.kimi.com/api/device/register",
json={},
headers={
"x-msh-device-id": device_id,
"x-msh-platform": "web",
"x-traffic-id": device_id
}
) as response:
await raise_for_status(response)
data = await response.json()
if not data.get("access_token"):
raise Exception("No access token received")
yield AuthResult(
api_key=data.get("access_token"),
device_id=device_id,
)
@classmethod
async def create_authed(
cls,
model: str,
messages: Messages,
auth_result: AuthResult,
proxy: str = None,
conversation: JsonConversation = None,
web_search: bool = False,
**kwargs
) -> AsyncResult:
async with StreamSession(
proxy=proxy,
impersonate="chrome",
headers={
"Authorization": f"Bearer {auth_result.api_key}",
}
) as session:
if conversation is None:
async with session.post("https://www.kimi.com/api/chat", json={
"name":"未命名会话",
"born_from":"home",
"kimiplus_id":"kimi",
"is_example":False,
"source":"web",
"tags":[]
}) as response:
try:
await raise_for_status(response)
except Exception as e:
if "匿名聊天使用次数超过" in str(e):
raise MissingAuthError("Anonymous chat usage limit exceeded")
raise e
chat_data = await response.json()
conversation = JsonConversation(chat_id=chat_data.get("id"))
yield conversation
data = {
"kimiplus_id": "kimi",
"extend": {"sidebar": True},
"model": "k2",
"use_search": web_search,
"messages": [
{
"role": "user",
"content": get_last_user_message(messages)
}
],
"refs": [],
"history": [],
"scene_labels": [],
"use_semantic_memory": False,
"use_deep_research": False
}
async with session.post(
f"https://www.kimi.com/api/chat/{conversation.chat_id}/completion/stream",
json=data
) as response:
await raise_for_status(response)
async for line in sse_stream(response):
if line.get("event") == "cmpl":
yield line.get("text")
elif line.get("event") == "rename":
yield TitleGeneration(line.get("text"))
elif line.get("event") == "all_done":
yield FinishReason("stop")
break