refactor(llm): 模型选择收敛到模型治理模块——cockpit_model_options/get_model_options改薄壳委托;set_agent_model/cockpit_agent模型解析改走llm_resolve_model_name,不再自查旧llm表
This commit is contained in:
parent
9f5fbdacfc
commit
e485d2d30d
@ -25,15 +25,12 @@ if action == 'start_agent':
|
||||
model_id = (params_kw or {}).get('model_id', '')
|
||||
role = (params_kw or {}).get('role', 'develop')
|
||||
|
||||
# model_id 兼容 llm.id 与 llm.model_id 两种取值(下拉改为传 llm.id)→
|
||||
# 统一解析为 llm.name 落库/传给引擎,保证同名不同供应商不漂移。
|
||||
# model_id 兼容 id / vendor_model_id / 注册名 → 统一走模型治理模块解析
|
||||
# (pipeline_llm.selection.resolve_model_name,唯一解析点,不再各模块自查表)
|
||||
if model_id:
|
||||
_r = await sor.sqlExe(
|
||||
"SELECT name FROM llm WHERE status='active' AND (id=${m}$ OR model_id=${m}$) LIMIT 1",
|
||||
{"m": model_id})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
if _r:
|
||||
model_id = getattr(_r[0], 'name', '') or model_id
|
||||
_resolved = await llm_resolve_model_name(model_id, org_id=org_id)
|
||||
if _resolved:
|
||||
model_id = _resolved
|
||||
|
||||
# Ensure agent config exists
|
||||
existing = await sor.sqlExe(
|
||||
|
||||
@ -1,59 +1,11 @@
|
||||
# cockpit_model_options.dspy - Returns active models with capabilities for dropdown
|
||||
# Used by cockpit model selector
|
||||
# 下拉值 = llm.id(唯一主键);显示 = llm.name。不同供应商可有相同 model_id
|
||||
# (API 模型名),只有 llm.id 唯一,避免同名供应商在下拉里被合并/解析漂移。
|
||||
# org_id 多租户隔离:非系统级机构只看到本机构的模型(不含系统级兜底)
|
||||
# selected 标记 = 当前项目的已设模型(sd_projects.default_model,产线通用、跨会话持久);
|
||||
# 项目未设模型时回退个人全局选择(default_llm_id)。前端 UiCode 按 selected 恢复选中项,
|
||||
# 不再每次重建都回退第一项。
|
||||
# cockpit_model_options.dspy — 驾驶舱模型下拉
|
||||
# 2026-09-04 收敛:实现统一在模型治理模块 pipeline_llm.selection.model_options,
|
||||
# 本文件只作 URL 入口(驾驶舱 AgentIO 的 model_dataurl 指向此处)。
|
||||
|
||||
dbname = get_module_dbname('pipeline-sdlc')
|
||||
uid = await get_user()
|
||||
org_id = (await get_userorgid()) or ''
|
||||
session_id = (params_kw or {}).get('session_id', '') or ''
|
||||
|
||||
async with DBPools().sqlorContext(dbname) as sor:
|
||||
sql = "SELECT id, name, provider, model_id, capabilities FROM llm WHERE status='active'"
|
||||
params = {}
|
||||
if org_id and org_id != '0':
|
||||
sql += " AND org_id=${org}$"
|
||||
params['org'] = org_id
|
||||
sql += " ORDER BY name"
|
||||
recs = await sor.sqlExe(sql, params)
|
||||
|
||||
# 项目级模型(优先级最高):按会话解析当前项目 → sd_projects.default_model。
|
||||
# session_id 为空/无会话记录时自动回退全局设置,与消息链路的项目解析同一函数,不漂移。
|
||||
project_model = ''
|
||||
try:
|
||||
from pipeline_service.workspace import get_session_project_id
|
||||
_pid = await get_session_project_id(sor, uid or '', session_id)
|
||||
if _pid:
|
||||
_p = await sor.sqlExe(
|
||||
"SELECT default_model FROM sd_projects WHERE id=${p}$", {"p": _pid})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
if _p:
|
||||
project_model = getattr(_p[0], 'default_model', '') or ''
|
||||
except Exception as e:
|
||||
debug(f'cockpit_model_options project_model error: {e}')
|
||||
|
||||
# 个人之前选择的默认模型(项目未设模型时的回退选中项)
|
||||
current_llm_id = ''
|
||||
if uid:
|
||||
_s = await sor.sqlExe(
|
||||
"SELECT default_llm_id FROM pipeline_agent_settings WHERE user_id=${u}$", {"u": uid})
|
||||
if _s:
|
||||
current_llm_id = getattr(_s[0], 'default_llm_id', '') or ''
|
||||
|
||||
rows = []
|
||||
for r in recs:
|
||||
rows.append({
|
||||
'value': r.id,
|
||||
'text': f"{r.name} ({r.provider})",
|
||||
'provider': r.provider,
|
||||
'model_id': r.id, # 下拉值:llm.id(唯一,区分同名不同供应商)
|
||||
'model_id_text': r.name, # 下拉显示:llm.name
|
||||
'capabilities': r.capabilities or 'text',
|
||||
'selected': (r.name == project_model) if project_model else (r.id == current_llm_id),
|
||||
})
|
||||
|
||||
rows = await llm_model_options(org_id, uid=uid or '', session_id=session_id,
|
||||
value_field='id')
|
||||
return rows
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
import json
|
||||
# get_model_options.dspy — 角色模型配置下拉(value=模型注册名)
|
||||
# 2026-09-04 收敛:实现统一在模型治理模块 pipeline_llm.selection.model_options,
|
||||
# 本文件只作 URL 入口。保留历史格式:首项「缺省(用项目默认模型)」+ value/text 两列。
|
||||
|
||||
rows = [{'value': '', 'text': '缺省(用项目默认模型)'}]
|
||||
try:
|
||||
userorgid = await get_userorgid()
|
||||
if not userorgid:
|
||||
return json.dumps([{'value': '', 'text': '缺省(用项目默认模型)'}], ensure_ascii=False)
|
||||
async with get_sor_context(request._run_ns, 'pipeline') as sor:
|
||||
rows = await sor.sqlExe("select name as value, name as text from llm where status='active' and org_id=${org}$ order by name", {'org': userorgid})
|
||||
r = [{'value': '', 'text': '缺省(用项目默认模型)'}] + list(rows)
|
||||
return json.dumps(r, ensure_ascii=False)
|
||||
org_id = await get_userorgid()
|
||||
if org_id:
|
||||
opts = await llm_model_options(org_id, value_field='name')
|
||||
rows += [{'value': r['value'], 'text': r['text']} for r in opts]
|
||||
return json.dumps(rows, ensure_ascii=False)
|
||||
except Exception as e:
|
||||
debug(f'get_model_options error: {e}')
|
||||
return json.dumps([{'value': '', 'text': '缺省(用项目默认模型)'}], ensure_ascii=False)
|
||||
return json.dumps(rows, ensure_ascii=False)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
# set_agent_model.dspy - 保存个人选择的默认模型
|
||||
# 机构人员在本机构 llm 池选模型,持久化到 pipeline_agent_settings.default_llm_id
|
||||
# 下次进入会话,缺省模型 = 个人之前选择的模型
|
||||
# set_agent_model.dspy — 保存个人选择的默认模型
|
||||
# 2026-09-04 收敛:模型存在性/机构归属校验统一走模型治理模块
|
||||
# pipeline_llm.selection.resolve_model_name(不再各模块自查表)。
|
||||
# llm_id 兼容模型 id / vendor_model_id / 注册名,解析成功后按模型 id 持久化。
|
||||
|
||||
dbname = get_module_dbname('pipeline-sdlc')
|
||||
uid = await get_user()
|
||||
@ -13,26 +14,30 @@ if not llm_id:
|
||||
|
||||
org_id = await get_userorgid() or '0'
|
||||
|
||||
# 统一解析:解析得到注册名即代表存在且属于本机构(系统级不过滤)
|
||||
name = await llm_resolve_model_name(llm_id, org_id=org_id)
|
||||
if not name:
|
||||
return json.dumps({"success": False, "error": "模型不存在或不属于本机构"}, ensure_ascii=False)
|
||||
|
||||
# 反查模型 id 持久化(个人默认选择按 id 存,与下拉 value 一致)
|
||||
_model_id = llm_id
|
||||
async with DBPools().sqlorContext(dbname) as sor:
|
||||
# 校验 llm_id 属于本机构(严格本机构隔离;超管 org_id='0' 不过滤)
|
||||
sql = "SELECT id FROM llm WHERE id=${id}$ AND status='active'"
|
||||
params = {"id": llm_id}
|
||||
if org_id and org_id != '0':
|
||||
sql += " AND org_id=${org}$"
|
||||
params['org'] = org_id
|
||||
recs = await sor.sqlExe(sql, params)
|
||||
if not recs:
|
||||
return json.dumps({"success": False, "error": "模型不存在或不属于本机构"}, ensure_ascii=False)
|
||||
_r = await sor.sqlExe(
|
||||
"SELECT id FROM llm_model WHERE status='active' "
|
||||
"AND (id=${m}$ OR vendor_model_id=${m}$ OR name=${m}$) LIMIT 1", {"m": llm_id})
|
||||
await sor.sqlExe("COMMIT", {})
|
||||
if _r:
|
||||
_model_id = getattr(_r[0], 'id', '') or llm_id
|
||||
|
||||
# upsert 到 pipeline_agent_settings(user_id 唯一键)
|
||||
await sor.sqlExe(
|
||||
"UPDATE pipeline_agent_settings SET default_llm_id=${lid}$ WHERE user_id=${uid}$",
|
||||
{"lid": llm_id, "uid": uid})
|
||||
{"lid": _model_id, "uid": uid})
|
||||
exists = await sor.sqlExe(
|
||||
"SELECT 1 FROM pipeline_agent_settings WHERE user_id=${uid}$", {"uid": uid})
|
||||
if not exists:
|
||||
await sor.C('pipeline_agent_settings', {
|
||||
'id': getID(), 'user_id': uid, 'default_llm_id': llm_id,
|
||||
'id': getID(), 'user_id': uid, 'default_llm_id': _model_id,
|
||||
})
|
||||
|
||||
return json.dumps({"success": True, "llm_id": llm_id}, ensure_ascii=False)
|
||||
return json.dumps({"success": True, "llm_id": _model_id, "name": name}, ensure_ascii=False)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user