Compare commits
No commits in common. 'zhu1ku1' and 'main' have entirely different histories.
@ -1,7 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.12" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,10 +1,8 @@
|
||||
{
|
||||
"default_provider": "SparkAI",
|
||||
"default_chat_model": "4.0Ultra",
|
||||
"default_structured_model": "4.0Ultra",
|
||||
"default_provider": "OpenAI",
|
||||
"default_chat_model": "gpt-4o",
|
||||
"default_structured_model": "gpt-4o",
|
||||
"request_timeout": 30,
|
||||
"SPARKAI_APP_ID": "7eaa68c4",
|
||||
"SPARKAI_API_SECRET": "ZDRlYjA5MmZjZjkwODIxYTA0MjM3ZmRi",
|
||||
"SPARKAI_API_KEY": "61bbbe0cb7b562612dc3841f583594bd",
|
||||
"SPARKAI_BASE_URL": "wss://spark-api.xf-yun.com/v3.5/chat"
|
||||
"OPENAI_API_KEY": "your-openai-api-key-here",
|
||||
"OPENAI_BASE_URL": "https://api.openai.com/v1"
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,152 +0,0 @@
|
||||
"""
|
||||
讯飞星火AI服务模块
|
||||
"""
|
||||
import json
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import time
|
||||
from datetime import datetime
|
||||
from urllib.parse import urlparse
|
||||
import ssl
|
||||
from dateutil import parser
|
||||
from websocket import create_connection
|
||||
import websocket
|
||||
import threading
|
||||
from typing import Dict, Any, Optional, List
|
||||
|
||||
|
||||
class SparkAIClient:
|
||||
"""讯飞星火AI客户端"""
|
||||
|
||||
def __init__(self, app_id: str, api_key: str, api_secret: str, domain: str = "4.0Ultra"):
|
||||
self.app_id = app_id
|
||||
self.api_key = api_key
|
||||
self.api_secret = api_secret
|
||||
self.domain = domain
|
||||
self.base_url = "wss://spark-api.xf-yun.com/v4.0/chat"
|
||||
|
||||
def _create_auth_url(self) -> str:
|
||||
"""创建认证URL"""
|
||||
from urllib.parse import urlparse, urlencode
|
||||
import time
|
||||
|
||||
# 生成RFC1123格式的时间戳
|
||||
now = time.time()
|
||||
date = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(now))
|
||||
|
||||
# 解析URL
|
||||
url_parts = urlparse(self.base_url)
|
||||
host = url_parts.hostname
|
||||
path = url_parts.path
|
||||
|
||||
# 生成签名原始字符串
|
||||
signature_origin = f"host: {host}\ndate: {date}\nGET {path} HTTP/1.1"
|
||||
|
||||
# 使用API Secret进行HMAC-SHA256加密
|
||||
signature_sha = hmac.new(
|
||||
self.api_secret.encode('utf-8'),
|
||||
signature_origin.encode('utf-8'),
|
||||
digestmod=hashlib.sha256
|
||||
).digest()
|
||||
|
||||
# Base64编码
|
||||
signature = base64.b64encode(signature_sha).decode('utf-8')
|
||||
|
||||
# 构建Authorization参数
|
||||
authorization_origin = f'api_key="{self.api_key}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature}"'
|
||||
authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode('utf-8')
|
||||
|
||||
# 构建请求URL
|
||||
params = {
|
||||
"authorization": authorization,
|
||||
"date": date,
|
||||
"host": host
|
||||
}
|
||||
|
||||
auth_url = f"{self.base_url}?{urlencode(params)}"
|
||||
return auth_url
|
||||
|
||||
def chat_completion(self, messages: List[Dict], temperature: float = 0.7, max_tokens: int = 2048) -> Dict[str, Any]:
|
||||
"""与讯飞星火进行对话"""
|
||||
try:
|
||||
# 创建认证URL
|
||||
auth_url = self._create_auth_url()
|
||||
|
||||
# 创建WebSocket连接
|
||||
ws = create_connection(auth_url)
|
||||
|
||||
# 构建请求数据
|
||||
request_data = {
|
||||
"header": {
|
||||
"app_id": self.app_id
|
||||
},
|
||||
"parameter": {
|
||||
"chat": {
|
||||
"domain": self.domain,
|
||||
"temperature": temperature,
|
||||
"max_tokens": max_tokens
|
||||
}
|
||||
},
|
||||
"payload": {
|
||||
"message": {
|
||||
"text": messages
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 发送请求
|
||||
ws.send(json.dumps(request_data))
|
||||
|
||||
# 接收响应
|
||||
full_response = ""
|
||||
while True:
|
||||
result = ws.recv()
|
||||
data = json.loads(result)
|
||||
|
||||
# 检查错误
|
||||
if data["header"]["code"] != 0:
|
||||
error_msg = data["header"]["message"]
|
||||
raise Exception(f"讯飞星火API错误: {error_msg}")
|
||||
|
||||
# 累加文本内容
|
||||
if "text" in data["payload"]["choices"]:
|
||||
for text in data["payload"]["choices"]["text"]:
|
||||
full_response += text["content"]
|
||||
|
||||
# 检查是否结束
|
||||
if data["header"]["status"] == 2:
|
||||
break
|
||||
|
||||
ws.close()
|
||||
|
||||
return {
|
||||
"choices": [{
|
||||
"message": {
|
||||
"role": "assistant",
|
||||
"content": full_response
|
||||
}
|
||||
}],
|
||||
"usage": {
|
||||
"total_tokens": len(full_response) // 4 # 估算token数量
|
||||
}
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"讯飞星火通信失败: {str(e)}")
|
||||
|
||||
|
||||
def sync_sparkai_chat(messages: List[Dict], user_settings: Dict) -> Dict[str, Any]:
|
||||
"""同步调用讯飞星火聊天接口"""
|
||||
try:
|
||||
client = SparkAIClient(
|
||||
app_id=user_settings.get('app_id', ''),
|
||||
api_key=user_settings.get('api_key', ''),
|
||||
api_secret=user_settings.get('api_secret', ''),
|
||||
domain=user_settings.get('domain', '4.0Ultra')
|
||||
)
|
||||
|
||||
return client.chat_completion(messages)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"讯飞星火服务调用失败: {str(e)}")
|
||||
Loading…
Reference in new issue