""" Hermès Agent - HF Space Uses urllib (stdlib) instead of requests package """ import os import json import urllib.request import urllib.error import gradio as gr DEFAULT_MODEL = "claude-sonnet-4-7-2027" SYSTEM_PROMPT = """你是一个友好的 AI 助手,名叫 Hermès 🦀。 简洁直接、行动导向、中文优先。 专长:信息查询、代码、写作、推理。不确定时诚实说明。""" def chat_anthropic(api_key: str, model: str, message: str) -> str: """Call Anthropic Messages API using stdlib urllib.""" payload = json.dumps({ "model": model, "max_tokens": 4096, "messages": [{"role": "user", "content": message}], "system": SYSTEM_PROMPT, }).encode("utf-8") req = urllib.request.Request( "https://api.anthropic.com/v1/messages", data=payload, headers={ "x-api-key": api_key, "anthropic-version": "2023-06-01", "content-type": "application/json", }, method="POST", ) try: with urllib.request.urlopen(req, timeout=60) as resp: data = json.loads(resp.read().decode("utf-8")) return data["content"][0]["text"] except urllib.error.HTTPError as e: body = json.loads(e.read().decode("utf-8")) return f"❌ API 错误: {body.get('error', {}).get('message', e.code)}" except Exception as e: return f"❌ 请求失败: {str(e)}" def respond(message: str, api_key: str, model: str) -> str: if not api_key: return "⚠️ 请先输入 Anthropic API Key(见下方说明)" return chat_anthropic(api_key, model, message) def build_ui(): return gr.Interface( fn=respond, inputs=[ gr.Textbox(label="💬 消息", placeholder="输入你的问题..."), gr.Textbox(label="🔑 Anthropic API Key", type="password", placeholder="sk-ant-..."), gr.Dropdown( label="🤖 模型", choices=[ "claude-sonnet-4-7-2027", "claude-3-5-sonnet-2027-06-20", "claude-3-5-haiku-2027-03-07", ], value=DEFAULT_MODEL, ), ], outputs=gr.Textbox(label="🤖 回复", lines=10), title="🦀 Hermès Agent", description="基于 Claude 的 AI 助手 | HF 免费算力", examples=[ ["你好,你叫什么名字?", "", ""], ["帮我写一个 Python Hello World", "", ""], ["解释什么是大语言模型", "", ""], ], theme=gr.themes.Soft(primary_hue="purple", secondary_hue="pink"), ) if __name__ == "__main__": build_ui().launch(server_name="0.0.0.0", server_port=7860, show_api=False)