Spaces:
Sleeping
Sleeping
| import json | |
| from agent_build_sdk.server.server import EndpointServer | |
| from chinatown.chinatown_agent import ChinatownLLMAgent | |
| from fastapi.responses import HTMLResponse | |
| import html as html_lib | |
| def register_debug_endpoints(server: EndpointServer): | |
| agent = server.agent | |
| def get_requests(): | |
| history = agent.get_req_resp_history() | |
| return { | |
| "success": True, | |
| "total": len(history), | |
| "history": history, | |
| } | |
| def view_requests(): | |
| history = agent.get_req_resp_history() | |
| html_items = "" | |
| for i, item in enumerate(reversed(history)): | |
| req_data = item.get("req", {}) | |
| resp_data = item.get("resp", {}) | |
| req_type = item.get("type", "?") | |
| status = req_data.get("status", "?") | |
| round_num = req_data.get("round", "?") | |
| action = resp_data.get("action", "-") if resp_data else "-" | |
| html_items += f""" | |
| <div class='req-item'> | |
| <div class='header'> | |
| <span class='type'>{req_type}</span> | |
| <span class='meta'>{html_lib.escape(str(status))} | Round {html_lib.escape(str(round_num))} | Action: {html_lib.escape(str(action))}</span> | |
| </div> | |
| <details> | |
| <summary>Request</summary> | |
| <pre>{html_lib.escape(str(req_data))}</pre> | |
| </details> | |
| <details> | |
| <summary>Response</summary> | |
| <pre>{html_lib.escape(str(resp_data))}</pre> | |
| </details> | |
| </div> | |
| """ | |
| return HTMLResponse(content=f""" | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset='UTF-8'> | |
| <title>Request/Response History</title> | |
| <style> | |
| body {{ font-family: monospace; margin: 20px; background: #f5f5f5; }} | |
| .req-item {{ background: white; margin: 10px 0; padding: 15px; border-radius: 5px; }} | |
| .header {{ display: flex; justify-content: space-between; margin-bottom: 10px; }} | |
| .type {{ font-weight: bold; color: #333; }} | |
| .meta {{ color: #666; font-size: 0.9em; }} | |
| details {{ margin: 5px 0; }} | |
| summary {{ cursor: pointer; color: #0066cc; font-weight: bold; }} | |
| pre {{ background: #f0f0f0; padding: 10px; overflow-x: auto; white-space: pre-wrap; font-size: 0.85em; }} | |
| </style> | |
| </head> | |
| <body> | |
| <h2>Request/Response History ({len(history)} items)</h2> | |
| {html_items} | |
| </body> | |
| </html> | |
| """) | |
| def clear_requests(): | |
| agent.clear_req_resp_history() | |
| return {"success": True, "message": "请求历史已清空"} | |
| if hasattr(agent, 'get_prompt_history') and callable(getattr(agent, 'get_prompt_history')): | |
| def get_prompts(): | |
| history = agent.get_prompt_history() | |
| return { | |
| "success": True, | |
| "total": len(history), | |
| "prompts": history, | |
| } | |
| def view_prompts(): | |
| history = agent.get_prompt_history() | |
| def format_content(data) -> str: | |
| """将请求体/响应体格式化为带换行标记的 HTML""" | |
| if isinstance(data, (dict, list)): | |
| text = json.dumps(data, ensure_ascii=False, indent=2) | |
| else: | |
| text = str(data) | |
| escaped = html_lib.escape(text) | |
| return escaped.replace("\\n", '<span class="nl">\\n</span>\n') | |
| html_items = "" | |
| for i, item in enumerate(reversed(history)): | |
| request_data = item.get("request") | |
| response_data = item.get("response", "") | |
| html_items += f""" | |
| <div class='prompt-item'> | |
| <div class='header'> | |
| <span class='meta'>{html_lib.escape(str(item.get('elapsed_sec', 0)))}s | {html_lib.escape(str(item.get('timestamp', '')))}</span> | |
| </div> | |
| <details> | |
| <summary>Request</summary> | |
| <pre>{format_content(request_data)}</pre> | |
| </details> | |
| <details> | |
| <summary>Response</summary> | |
| <pre>{format_content(response_data)}</pre> | |
| </details> | |
| </div> | |
| """ | |
| return HTMLResponse(content=f""" | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset='UTF-8'> | |
| <title>LLM Call History</title> | |
| <style> | |
| body {{ font-family: monospace; margin: 20px; background: #f5f5f5; }} | |
| .prompt-item {{ background: white; margin: 10px 0; padding: 15px; border-radius: 5px; }} | |
| .header {{ display: flex; justify-content: space-between; margin-bottom: 10px; }} | |
| .meta {{ color: #666; font-size: 0.9em; }} | |
| details {{ margin: 5px 0; }} | |
| summary {{ cursor: pointer; color: #0066cc; font-weight: bold; }} | |
| pre {{ background: #f0f0f0; padding: 10px; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word; line-height: 1.5; }} | |
| .nl {{ color: #ccc; font-size: 0.75em; user-select: none; }} | |
| </style> | |
| </head> | |
| <body> | |
| <h2>LLM Call History ({len(history)} items)</h2> | |
| {html_items} | |
| </body> | |
| </html> | |
| """) | |
| def clear_prompts(): | |
| agent.clear_prompt_history() | |
| return {"success": True, "message": "提示词历史已清空"} | |
| if __name__ == '__main__': | |
| name = 'chinatown' | |
| agent = ChinatownLLMAgent(player_id="") | |
| server = EndpointServer(agent) | |
| register_debug_endpoints(server) | |
| server.start() | |