From 52312b0a061b64d4e8e495f337da07aed5bb1ca3 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Thu, 11 Jun 2026 19:22:17 +0800 Subject: [PATCH] feat: llm_dialog.ui catelog tabs + get_llm_catelogs + inference passes catelogid - utils.py: get_llmcatelogid -> get_llm_catelogs (returns ALL catelogs with name+isdefault) - llmclient.py: inference() passes params_kw.llmcatelogid to get_llm() - llm_dialog.ui: renders catelog tab buttons when model has multiple catelogs, defaults to isdefaultcatelog, passes llmcatelogid to both LlmIO models and list_models_url - init.py: export get_llm_catelogs --- llmage/init.py | 4 +-- llmage/llmclient.py | 3 +- llmage/utils.py | 19 ++++++---- wwwroot/llm_dialog.ui | 83 ++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 95 insertions(+), 14 deletions(-) diff --git a/llmage/init.py b/llmage/init.py index b7bd79f..a582746 100644 --- a/llmage/init.py +++ b/llmage/init.py @@ -19,7 +19,7 @@ from .utils import ( get_llmproviders, get_llm, get_llmage_llm, - get_llmcatelogid, + get_llm_catelogs, invalidate_uapi_cache, ) @@ -66,7 +66,7 @@ def load_llmage(): env.query_task_status = query_task_status env.get_llm = get_llm env.get_llmage_llm = get_llmage_llm - env.get_llmcatelogid = get_llmcatelogid + env.get_llm_catelogs = get_llm_catelogs env.invalidate_uapi_cache = invalidate_uapi_cache env.inference = inference env.get_user_tpac = get_user_tpac diff --git a/llmage/llmclient.py b/llmage/llmclient.py index 6ed461c..0c60b8d 100644 --- a/llmage/llmclient.py +++ b/llmage/llmclient.py @@ -116,8 +116,9 @@ async def _inference_generator(request, callerid, callerorgid, if not params_kw.transno: params_kw.transno = getID() llmid = params_kw.llmid + catelogid = params_kw.get('llmcatelogid', None) f = None - llm = await get_llm(llmid) + llm = await get_llm(llmid, catelogid) if llm is None: errmsg = f'{{"status": "FAILED", "error":"llmid:{llmid}没找到模型"}}\n' exception(errmsg) diff --git a/llmage/utils.py b/llmage/utils.py index 57ee688..2bfc334 100644 --- a/llmage/utils.py +++ b/llmage/utils.py @@ -361,16 +361,21 @@ async def get_llms_by_catelog(catelogid=None, orderby='providerid'): return d return [] -async def get_llmcatelogid(llmid): - """Get the first llmcatelogid for a given llmid from llm_api_map""" +async def get_llm_catelogs(llmid): + """Get all catelog entries for a given llmid from llm_api_map + llmcatelog. + Returns list of {catelogid, catelogname, isdefaultcatelog} + """ if not llmid: - return None + return [] llmage_dbname = get_serverenv('get_module_dbname')('llmage') async with DBPools().sqlorContext(llmage_dbname) as sor: - recs = await sor.sqlExe("select llmcatelogid from llm_api_map where llmid=${llmid}$ limit 1", {'llmid': llmid}) - if recs: - return recs[0].llmcatelogid - return None + sql = """select m.llmcatelogid as catelogid, lc.name as catelogname, m.isdefaultcatelog +from llm_api_map m +join llmcatelog lc on m.llmcatelogid = lc.id +where m.llmid = ${llmid}$ +order by m.isdefaultcatelog desc""" + recs = await sor.sqlExe(sql, {'llmid': llmid}) + return [dict(catelogid=r.catelogid, catelogname=r.catelogname, isdefault=r.isdefaultcatelog == '1') for r in recs] async def get_llm(llmid, catelogid=None): diff --git a/wwwroot/llm_dialog.ui b/wwwroot/llm_dialog.ui index 1a89082..aa1751d 100644 --- a/wwwroot/llm_dialog.ui +++ b/wwwroot/llm_dialog.ui @@ -3,11 +3,82 @@ {% set userorgid = get_userorgid() %} {% if params_kw.id %} {% if checkCustomerBalance(params_kw.id, userid, userorgid) %} -{% set llm = get_llm(params_kw.id) %} -{% set oops=debug(json.dumps(llm, ensure_ascii=Fasle)) %} +{% set catelogs = get_llm_catelogs(params_kw.id) %} +{% set active_catelogid = params_kw.get('catelogid', '') %} +{% if not active_catelogid and catelogs %} +{% for c in catelogs %}{% if c.isdefault %}{% set active_catelogid = c.catelogid %}{% endif %}{% endfor %} +{% if not active_catelogid and catelogs %}{% set active_catelogid = catelogs[0].catelogid %}{% endif %} +{% endif %} +{% set llm = get_llm(params_kw.id, active_catelogid) %} {% set kdbs = get_user_kdbs(request) %} -{% set llmcatelogid = get_llmcatelogid(params_kw.id) %} {% if llm %} +{% if len(catelogs) > 1 %} +{ + "widgettype":"VBox", + "options":{ + "width":"100%", + "height":"100%" + }, + "subwidgets":[ + { + "widgettype":"HBox", + "options":{ + "cheight":3, + "css":"card", + "padding":"8px" + }, + "subwidgets":[ +{% for c in catelogs %} + { + "widgettype":"Button", + "options":{ + "label":"{{c.catelogname}}", + "actiontype":"link", +{% if c.catelogid == active_catelogid %} + "css":"primary", +{% endif %} + "url":"{{entire_url('/llmage/llm_dialog.ui')}}?id={{params_kw.id}}&catelogid={{c.catelogid}}" + } + }{% if not loop.last %},{% endif %} +{% endfor %} + ] + }, + { + "widgettype":"LlmIO", + "options":{ + "width":"100%", + "height":"100%", + "title":"{{llm.name}}", +{% if len(kdbs) > 0 %} + "enabled_kdb": true, + "kdb_setting":{}, + "get_kdb_url": "{{entire_url('/rag/get_my_kdbs.dspy')}}", +{% endif %} + "list_models_url":"{{entire_url('list_paging_catelog_llms.dspy')}}?llmcatelogid={{active_catelogid}}", + "estimate_url":"{{entire_url('model_estimate.dspy')}}", + "input_fields":{{llm.input_fields}}, + "models":[ + { + "llmid":"{{llm.id}}", + "llmcatelogid":"{{active_catelogid}}", + "response_mode": "{{llm.stream}}", + "icon":"{{entire_url('/appbase/show_icon.dspy')}}?id={{llm.iconid}}", + "url":"{{entire_url('/llmage/llminference.dspy')}}", +{% if llm.stream == 'stream' %} + "stream": true, +{% endif %} +{% if llm.stream =='async' %} + "query_url": "{{entire_url('/llmage/tasks')}}", +{% endif %} + "model":"{{llm.model}}", + "modelname":"{{llm.name}}" + } + ] + } + } + ] +} +{% else %} { "widgettype":"LlmIO", "options":{ @@ -19,12 +90,15 @@ "kdb_setting":{}, "get_kdb_url": "{{entire_url('/rag/get_my_kdbs.dspy')}}", {% endif %} - "list_models_url":"{{entire_url('list_paging_catelog_llms.dspy')}}{% if llmcatelogid %}?llmcatelogid={{llmcatelogid}}{% endif %}", + "list_models_url":"{{entire_url('list_paging_catelog_llms.dspy')}}{% if active_catelogid %}?llmcatelogid={{active_catelogid}}{% endif %}", "estimate_url":"{{entire_url('model_estimate.dspy')}}", "input_fields":{{llm.input_fields}}, "models":[ { "llmid":"{{llm.id}}", +{% if active_catelogid %} + "llmcatelogid":"{{active_catelogid}}", +{% endif %} "response_mode": "{{llm.stream}}", "icon":"{{entire_url('/appbase/show_icon.dspy')}}?id={{llm.iconid}}", "url":"{{entire_url('/llmage/llminference.dspy')}}", @@ -40,6 +114,7 @@ ] } } +{% endif %} {% else %} { "widgettype":"Text",