- 989 行单文件拆为 server/context/ 9 模块(identity/broadcast/personalization/usage/upload/conversation/resources/decorators/reaper)+ __init__.py 兼容 re-export,外部 import 路径不变 - 新增 RuntimeIdentity 显式身份快照(identity.py),get_user_resources 支持参数化身份驱动,为任务线程拆除 Flask 隐式上下文做准备 - 测试 patch 目标随迁至 server.context.personalization;新增 test_runtime_identity_resources 覆盖 web/host/api 身份路由矩阵
59 lines
2.1 KiB
Python
59 lines
2.1 KiB
Python
"""HTTP 适配层装饰器与 socket 连接资源解析。"""
|
||
from __future__ import annotations
|
||
|
||
from functools import wraps
|
||
from typing import Optional
|
||
|
||
from flask import request, jsonify
|
||
|
||
from server import state
|
||
from server.auth_helpers import get_current_username
|
||
from server.context.identity import NoWorkspaceError
|
||
from server.context.resources import get_user_resources
|
||
|
||
|
||
def with_terminal(func):
|
||
"""注入用户专属终端和工作区。
|
||
|
||
请求携带 conversation_id(query 参数或 JSON body)时返回该对话的对话级 terminal,
|
||
否则返回工作区级服务 terminal。
|
||
"""
|
||
@wraps(func)
|
||
def wrapper(*args, **kwargs):
|
||
username = get_current_username()
|
||
conversation_id = None
|
||
try:
|
||
conversation_id = (request.args.get("conversation_id") or "").strip() or None
|
||
if not conversation_id and request.is_json:
|
||
body = request.get_json(silent=True) or {}
|
||
if isinstance(body, dict):
|
||
conversation_id = (body.get("conversation_id") or "").strip() or None
|
||
except Exception:
|
||
conversation_id = None
|
||
try:
|
||
terminal, workspace = get_user_resources(username, conversation_id=conversation_id)
|
||
except NoWorkspaceError as exc:
|
||
return jsonify({"error": str(exc), "code": "no_workspace"}), 503
|
||
except RuntimeError as exc:
|
||
return jsonify({"error": str(exc), "code": "resource_busy"}), 503
|
||
if not terminal or not workspace:
|
||
return jsonify({"error": "System not initialized"}), 503
|
||
kwargs.update({
|
||
'terminal': terminal,
|
||
'workspace': workspace,
|
||
'username': username
|
||
})
|
||
return func(*args, **kwargs)
|
||
return wrapper
|
||
|
||
|
||
def get_terminal_for_sid(sid: str, conversation_id: Optional[str] = None):
|
||
username = state.connection_users.get(sid)
|
||
if not username:
|
||
return None, None, None
|
||
try:
|
||
terminal, workspace = get_user_resources(username, conversation_id=conversation_id)
|
||
except RuntimeError:
|
||
return username, None, None
|
||
return username, terminal, workspace
|