V3.5 精细化运营升级:用量统计/接口库/团队/对话/工作目录/流式超时
1. 精细化统计:cost_records 新增 calls/cached_tokens/latency_ms/first_token_ms;
用量明细报表(项目×智能体矩阵) + 成本报表细化(输入/输出/缓存命中/调用次数)
2. 从参考项目中新建:内置3个测试项目(文案/Python/调研),一键复制目标+任务
3. 大模型接口库(llm_endpoints):专门配置接口(地址/密钥/模型/定价),
计费支持按token(逐模型)与按调用次数;创建AI Worker直接选用;
AI Worker团队(worker_teams):打包Worker,对话/建项目可直接选团队
4. 对话导航融合仪表盘:可选大模型/AI Worker/团队,默认主力AI Worker(⭐可设),SSE流式
5. 系统工作目录:默认data/workspace可改绝对路径;项目与多Agent协作均在其下
建唯一工作目录;手动输入目录已存在则列出信息并需手动确认
6. 任务执行超时改为流式单token返回超时+首字延迟超时,设置页可配;
所有模型输出SSE按token接收
This commit is contained in:
+82
-6
@@ -18,9 +18,9 @@ from email.mime.application import MIMEApplication
|
||||
from email.utils import formataddr
|
||||
|
||||
import db
|
||||
from config import DATA_DIR, EMAIL, PUBLIC_BASE_URL
|
||||
from config import DATA_DIR, EMAIL, PUBLIC_BASE_URL, DEFAULT_WORKSPACE_ROOT
|
||||
|
||||
WORKSPACE_ROOT = os.path.join(DATA_DIR, 'workspace')
|
||||
WORKSPACE_ROOT = DEFAULT_WORKSPACE_ROOT
|
||||
DEMO_ROOT = os.path.join(DATA_DIR, 'demo')
|
||||
PACKAGE_ROOT = os.path.join(DATA_DIR, 'packages')
|
||||
|
||||
@@ -29,14 +29,70 @@ BLOCKER_DEDUP_SECONDS = 1800
|
||||
|
||||
|
||||
def ensure_dirs():
|
||||
for d in (WORKSPACE_ROOT, DEMO_ROOT, PACKAGE_ROOT):
|
||||
for d in (DEMO_ROOT, PACKAGE_ROOT):
|
||||
os.makedirs(d, exist_ok=True)
|
||||
os.makedirs(get_workspace_root(), exist_ok=True)
|
||||
|
||||
|
||||
def get_workspace_root():
|
||||
"""系统工作目录(V3.5):默认 data/workspace,可在设置中改成任意绝对路径(无则创建,已存在需确认)。
|
||||
所有项目工作目录与多 Agent 协作工作目录都建在此目录下。"""
|
||||
root = (db.get_setting('sys_workspace_root', '') or '').strip() or WORKSPACE_ROOT
|
||||
if not os.path.isabs(root):
|
||||
root = os.path.join(DATA_DIR, root.lstrip('/'))
|
||||
try:
|
||||
os.makedirs(root, exist_ok=True)
|
||||
except Exception:
|
||||
root = WORKSPACE_ROOT
|
||||
os.makedirs(root, exist_ok=True)
|
||||
return root
|
||||
|
||||
|
||||
def dir_info(path):
|
||||
"""已存在目录的相关信息:文件数 / 总大小 / 最近修改 / 样例列表(供确认提醒)。不存在返回 None。"""
|
||||
if not path or not os.path.isdir(path):
|
||||
return None
|
||||
n = total = 0
|
||||
newest = 0
|
||||
sample = []
|
||||
try:
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
dirnames[:] = [d for d in dirnames if not d.startswith('.')]
|
||||
for fn in sorted(filenames):
|
||||
if fn.startswith('.'):
|
||||
continue
|
||||
full = os.path.join(dirpath, fn)
|
||||
try:
|
||||
st = os.stat(full)
|
||||
except OSError:
|
||||
continue
|
||||
n += 1
|
||||
total += st.st_size
|
||||
if st.st_mtime > newest:
|
||||
newest = st.st_mtime
|
||||
if len(sample) < 40:
|
||||
sample.append(os.path.relpath(full, path))
|
||||
except Exception:
|
||||
pass
|
||||
return {'exists': True, 'path': path, 'files': n, 'size': total,
|
||||
'newest_mtime': int(newest), 'sample': sample}
|
||||
|
||||
|
||||
def workspace_path(project):
|
||||
"""项目工作目录绝对路径(不存在则创建)"""
|
||||
pid = project['id'] if isinstance(project, dict) else project
|
||||
d = os.path.join(WORKSPACE_ROOT, f'project_{pid}')
|
||||
"""项目工作目录绝对路径(V3.5:支持自定义 workspace_dir,相对系统工作目录或绝对路径;不存在则创建)"""
|
||||
if isinstance(project, dict):
|
||||
p = project
|
||||
pid = p['id']
|
||||
else:
|
||||
pid = project
|
||||
p = db.q('SELECT workspace_dir FROM projects WHERE id=?', (pid,), one=True)
|
||||
wd = ((p or {}).get('workspace_dir') or '').strip() if p else ''
|
||||
if not wd:
|
||||
wd = f'project_{pid}'
|
||||
if os.path.isabs(wd):
|
||||
d = wd
|
||||
else:
|
||||
d = os.path.join(get_workspace_root(), wd)
|
||||
os.makedirs(d, exist_ok=True)
|
||||
return d
|
||||
|
||||
@@ -52,6 +108,26 @@ def package_dir():
|
||||
return PACKAGE_ROOT
|
||||
|
||||
|
||||
def agent_workspace(run_id):
|
||||
"""多 Agent 协作运行的工作目录:在系统工作目录下新建 agent_run_<id>(唯一,不存在则创建)"""
|
||||
d = os.path.join(get_workspace_root(), f'agent_run_{run_id}')
|
||||
os.makedirs(d, exist_ok=True)
|
||||
return d
|
||||
|
||||
|
||||
def write_agent_context(run_id, topic, context=''):
|
||||
"""在协作运行工作目录写入运行说明文件"""
|
||||
d = agent_workspace(run_id)
|
||||
try:
|
||||
with open(os.path.join(d, 'run_context.md'), 'w', encoding='utf-8') as fh:
|
||||
fh.write(f'# 多 Agent 协作运行 #{run_id}\n\n')
|
||||
fh.write(f'## 主题\n{topic}\n\n')
|
||||
fh.write(f'## 背景上下文\n{context or "(无)"}\n')
|
||||
except Exception:
|
||||
pass
|
||||
return d
|
||||
|
||||
|
||||
def _safe_relpath(relpath):
|
||||
"""路径穿越防护:仅允许工作目录内的相对路径"""
|
||||
relpath = (relpath or '').replace('\\', '/').strip('/')
|
||||
|
||||
Reference in New Issue
Block a user