Compare commits
No commits in common. "5b3c7d4d029ab153a1d0f49c5418634e38af09e7" and "ca21d5cf25061386698a671cca3a0cf9620591c8" have entirely different histories.
5b3c7d4d02
...
ca21d5cf25
15
json/llm_catelog_rel.json
Normal file
15
json/llm_catelog_rel.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"tblname": "llm_catelog_rel",
|
||||||
|
"title":"模型类型",
|
||||||
|
"params": {
|
||||||
|
"browserfields": {
|
||||||
|
"exclouded": ["id", "llmid"],
|
||||||
|
"alters": {}
|
||||||
|
},
|
||||||
|
"editexclouded": [
|
||||||
|
"id",
|
||||||
|
"llmid"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
Metadata-Version: 2.1
|
|
||||||
Name: llmage
|
|
||||||
Version: 0.0.1
|
|
||||||
Summary: Your project description
|
|
||||||
Home-page: UNKNOWN
|
|
||||||
Author: "yu moqing"
|
|
||||||
Author-email: "yumoqing@gmail.com"
|
|
||||||
License: "MIT"
|
|
||||||
Platform: UNKNOWN
|
|
||||||
|
|
||||||
UNKNOWN
|
|
||||||
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
README.md
|
|
||||||
pyproject.toml
|
|
||||||
setup.cfg
|
|
||||||
llmage/__init__.py
|
|
||||||
llmage/accounting.py
|
|
||||||
llmage/asyncinference.py
|
|
||||||
llmage/callback.py
|
|
||||||
llmage/init.py
|
|
||||||
llmage/jimeng.py
|
|
||||||
llmage/keling.py
|
|
||||||
llmage/llmclient.py
|
|
||||||
llmage/messages.py
|
|
||||||
llmage/syncinference.py
|
|
||||||
llmage/utils.py
|
|
||||||
llmage.egg-info/PKG-INFO
|
|
||||||
llmage.egg-info/SOURCES.txt
|
|
||||||
llmage.egg-info/dependency_links.txt
|
|
||||||
llmage.egg-info/requires.txt
|
|
||||||
llmage.egg-info/top_level.txt
|
|
||||||
@ -1 +0,0 @@
|
|||||||
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
aiohttp
|
|
||||||
aiohttp
|
|
||||||
aiohttp_socks
|
|
||||||
asyncio
|
|
||||||
asyncssh
|
|
||||||
bcrypt
|
|
||||||
brotli
|
|
||||||
bs4
|
|
||||||
cryptography
|
|
||||||
eventpy
|
|
||||||
jinja2
|
|
||||||
nanoid
|
|
||||||
numpy
|
|
||||||
psutil
|
|
||||||
pyzmq
|
|
||||||
requests
|
|
||||||
rsa
|
|
||||||
ujson
|
|
||||||
xlrd
|
|
||||||
xlwt
|
|
||||||
@ -1 +0,0 @@
|
|||||||
llmage
|
|
||||||
Binary file not shown.
Binary file not shown.
@ -51,10 +51,10 @@ def _bind_llmage_events(dbpools, dbname):
|
|||||||
(f'{dbname}.llmcatelog:c:after', BufferedLLMs.clear_cache),
|
(f'{dbname}.llmcatelog:c:after', BufferedLLMs.clear_cache),
|
||||||
(f'{dbname}.llmcatelog:u:after', BufferedLLMs.clear_cache),
|
(f'{dbname}.llmcatelog:u:after', BufferedLLMs.clear_cache),
|
||||||
(f'{dbname}.llmcatelog:d:after', BufferedLLMs.clear_cache),
|
(f'{dbname}.llmcatelog:d:after', BufferedLLMs.clear_cache),
|
||||||
# llm_api_map 关联表变更:清除缓存
|
# llm_catalog_rel 关联表变更:清除缓存
|
||||||
(f'{dbname}.llm_api_map:c:after', BufferedLLMs.clear_cache),
|
(f'{dbname}.llm_catalog_rel:c:after', BufferedLLMs.clear_cache),
|
||||||
(f'{dbname}.llm_api_map:u:after', BufferedLLMs.clear_cache),
|
(f'{dbname}.llm_catalog_rel:u:after', BufferedLLMs.clear_cache),
|
||||||
(f'{dbname}.llm_api_map:d:after', BufferedLLMs.clear_cache),
|
(f'{dbname}.llm_catalog_rel:d:after', BufferedLLMs.clear_cache),
|
||||||
]
|
]
|
||||||
for event_name, handler in bindings:
|
for event_name, handler in bindings:
|
||||||
dbpools.bind(event_name, handler)
|
dbpools.bind(event_name, handler)
|
||||||
|
|||||||
@ -207,11 +207,11 @@ async def get_llms_by_catelog_to_customer(catelogid=None, orderby='providerid'):
|
|||||||
env = ServerEnv()
|
env = ServerEnv()
|
||||||
async with get_sor_context(env, 'llmage') as sor:
|
async with get_sor_context(env, 'llmage') as sor:
|
||||||
today = curDateString()
|
today = curDateString()
|
||||||
# Join with llm_api_map to get catalog relationship
|
# Join with llm_catalog_rel to support multiple catalogs per LLM
|
||||||
sql = """select distinct a.*, b.name as catelogname, m.llmcatelogid as catelog_id
|
sql = """select a.*, b.name as catelogname, rel.llmcatelogid as catelog_id
|
||||||
from llm a
|
from llm a
|
||||||
join llm_api_map m on a.id = m.llmid
|
join llm_catalog_rel rel on a.id = rel.llmid
|
||||||
join llmcatelog b on m.llmcatelogid = b.id
|
join llmcatelog b on rel.llmcatelogid = b.id
|
||||||
where a.enabled_date <= ${today}$
|
where a.enabled_date <= ${today}$
|
||||||
and a.ppid is not null
|
and a.ppid is not null
|
||||||
and a.expired_date > ${today}$
|
and a.expired_date > ${today}$
|
||||||
@ -219,7 +219,7 @@ async def get_llms_by_catelog_to_customer(catelogid=None, orderby='providerid'):
|
|||||||
sortstr='catelog_id, ' + orderby
|
sortstr='catelog_id, ' + orderby
|
||||||
params = {'today': today, 'sort': sortstr}
|
params = {'today': today, 'sort': sortstr}
|
||||||
if catelogid:
|
if catelogid:
|
||||||
sql += " and m.llmcatelogid = ${catelogid}$"
|
sql += " and rel.llmcatelogid = ${catelogid}$"
|
||||||
params['catelogid'] = catelogid
|
params['catelogid'] = catelogid
|
||||||
|
|
||||||
debug(f'{sql=}')
|
debug(f'{sql=}')
|
||||||
@ -246,19 +246,19 @@ async def get_llms_by_catelog(catelogid=None, orderby='providerid'):
|
|||||||
env = ServerEnv()
|
env = ServerEnv()
|
||||||
async with get_sor_context(env, 'llmage') as sor:
|
async with get_sor_context(env, 'llmage') as sor:
|
||||||
today = curDateString()
|
today = curDateString()
|
||||||
# Join with llm_api_map to get catalog relationship
|
# Join with llm_catalog_rel to support multiple catalogs per LLM
|
||||||
sql = """select distinct a.*, b.name as catelogname, m.llmcatelogid as catelog_id
|
sql = """select a.*, b.name as catelogname, rel.llmcatelogid as catelog_id
|
||||||
from llm a
|
from llm a
|
||||||
join llm_api_map m on a.id = m.llmid
|
join llm_catalog_rel rel on a.id = rel.llmid
|
||||||
join llmcatelog b on m.llmcatelogid = b.id
|
join llmcatelog b on rel.llmcatelogid = b.id
|
||||||
where a.enabled_date <= ${today}$
|
where a.enabled_date <= ${today}$
|
||||||
and a.expired_date > ${today}$"""
|
and a.expired_date > ${today}$"""
|
||||||
params = {'today': today, 'sort': orderby}
|
params = {'today': today, 'sort': orderby}
|
||||||
if catelogid:
|
if catelogid:
|
||||||
sql += " and m.llmcatelogid = ${catelogid}$"
|
sql += " and rel.llmcatelogid = ${catelogid}$"
|
||||||
params['catelogid'] = catelogid
|
params['catelogid'] = catelogid
|
||||||
|
|
||||||
sql += " order by m.llmcatelogid, a.id"
|
sql += " order by rel.llmcatelogid, a.id"
|
||||||
|
|
||||||
recs = await sor.sqlExe(sql, params)
|
recs = await sor.sqlExe(sql, params)
|
||||||
d = []
|
d = []
|
||||||
|
|||||||
56
models/llm_catelog_rel.json
Normal file
56
models/llm_catelog_rel.json
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"summary": [
|
||||||
|
{
|
||||||
|
"name": "llm_catelog_rel",
|
||||||
|
"title": "模型分类对照表",
|
||||||
|
"primary": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"catelog": "relation"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"title": "id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "llmid",
|
||||||
|
"title": "模型id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "llmcatelogid",
|
||||||
|
"title": "模型分类id",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"name": "idx_uniue_llm_catelogid",
|
||||||
|
"idxtype": "unique",
|
||||||
|
"idxfields": [
|
||||||
|
"llmid",
|
||||||
|
"llmcatelogid"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"codes": [
|
||||||
|
{
|
||||||
|
"field": "llmid",
|
||||||
|
"table": "llm",
|
||||||
|
"valuefield": "id",
|
||||||
|
"textfield": "name"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"field": "llmcatelogid",
|
||||||
|
"table": "llmcatelog",
|
||||||
|
"valuefield": "id",
|
||||||
|
"textfield": "name"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
models/llm_catelog_rel.xlsx
Normal file
BIN
models/llm_catelog_rel.xlsx
Normal file
Binary file not shown.
@ -20,11 +20,8 @@ def generate_migration_sql(llm_records, catalog_rel_records=None):
|
|||||||
Generate INSERT statements for llm_api_map from existing llm data.
|
Generate INSERT statements for llm_api_map from existing llm data.
|
||||||
|
|
||||||
For each llm record:
|
For each llm record:
|
||||||
- If catalog info provided: create one llm_api_map per (llmid, llmcatelogid)
|
- If llm_catalog_rel exists: create one llm_api_map per (llmid, llmcatelogid)
|
||||||
- If no catalog info: use llm's llmcatelogid field (legacy)
|
- If no catalog_rel: create one llm_api_map with the llm's default catalog
|
||||||
|
|
||||||
NOTE: llm_catalog_rel has been deprecated. Catalog relationship is now
|
|
||||||
maintained directly in llm_api_map table.
|
|
||||||
"""
|
"""
|
||||||
inserts = []
|
inserts = []
|
||||||
|
|
||||||
@ -100,7 +97,7 @@ def main():
|
|||||||
parser.add_argument('--input', '-i',
|
parser.add_argument('--input', '-i',
|
||||||
help='Input JSON file with llm records (for offline mode)')
|
help='Input JSON file with llm records (for offline mode)')
|
||||||
parser.add_argument('--catalog-rel', '-c',
|
parser.add_argument('--catalog-rel', '-c',
|
||||||
help='Input JSON file with catalog records (deprecated, use llm_api_map instead)')
|
help='Input JSON file with llm_catalog_rel records')
|
||||||
parser.add_argument('--output', '-o', default='-',
|
parser.add_argument('--output', '-o', default='-',
|
||||||
help='Output file for SQL statements (default: stdout)')
|
help='Output file for SQL statements (default: stdout)')
|
||||||
parser.add_argument('--dry-run', action='store_true',
|
parser.add_argument('--dry-run', action='store_true',
|
||||||
|
|||||||
@ -4,7 +4,7 @@ llm_api_map 数据库迁移脚本
|
|||||||
直接操作数据库,完成以下任务:
|
直接操作数据库,完成以下任务:
|
||||||
1. 创建 llm_api_map 表(如不存在)
|
1. 创建 llm_api_map 表(如不存在)
|
||||||
2. 从 llm 表迁移 apiname/query_apiname/query_period/ppid 到 llm_api_map
|
2. 从 llm 表迁移 apiname/query_apiname/query_period/ppid 到 llm_api_map
|
||||||
3. 分类关系已从 llm 表迁移(llmcatelogid 字段已移除)
|
3. 关联 llm_catalog_rel 获取 llmcatelogid
|
||||||
4. 可选:删除 llm 表中的旧字段(需用户确认)
|
4. 可选:删除 llm 表中的旧字段(需用户确认)
|
||||||
|
|
||||||
运行位置:Sage 虚拟环境
|
运行位置:Sage 虚拟环境
|
||||||
@ -126,12 +126,7 @@ CREATE TABLE IF NOT EXISTS llm_api_map (
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
# Build catalog_rel lookup
|
# Build catalog_rel lookup
|
||||||
# NOTE: llm_catalog_rel has been deprecated; catalog relationship is now in llm_api_map.
|
rels = await sor.sqlExe("SELECT llmid, llmcatelogid FROM llm_catalog_rel", {})
|
||||||
# This lookup is kept for backward compatibility with old migrations.
|
|
||||||
try:
|
|
||||||
rels = await sor.sqlExe("SELECT llmid, llmcatelogid FROM llm_catalog_rel", {})
|
|
||||||
except Exception:
|
|
||||||
rels = []
|
|
||||||
catelog_map = {}
|
catelog_map = {}
|
||||||
for r in (rels or []):
|
for r in (rels or []):
|
||||||
catelog_map.setdefault(r['llmid'], []).append(r['llmcatelogid'])
|
catelog_map.setdefault(r['llmid'], []).append(r['llmcatelogid'])
|
||||||
@ -145,7 +140,7 @@ CREATE TABLE IF NOT EXISTS llm_api_map (
|
|||||||
catelog_ids = catelog_map.get(llmid)
|
catelog_ids = catelog_map.get(llmid)
|
||||||
|
|
||||||
if not catelog_ids:
|
if not catelog_ids:
|
||||||
print(f" [SKIP] llm '{llm.get('name', llmid)}' has no catalog entry (llm_catalog_rel deprecated)")
|
print(f" [SKIP] llm '{llm.get('name', llmid)}' has no catalog_rel entry")
|
||||||
skipped += 1
|
skipped += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
32
wwwroot/api/llm_catalog_rel_create.dspy
Normal file
32
wwwroot/api/llm_catalog_rel_create.dspy
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import json
|
||||||
|
|
||||||
|
result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': 'Invalid', 'type': 'error'}}
|
||||||
|
|
||||||
|
try:
|
||||||
|
dbname = get_module_dbname('llmage')
|
||||||
|
llmid = params_kw.get('llmid', '')
|
||||||
|
catelogid = params_kw.get('llmcatelogid', '')
|
||||||
|
|
||||||
|
if not llmid or not catelogid:
|
||||||
|
result['options'] = {'title': 'Error', 'message': '请选择模型和目录', 'type': 'error'}
|
||||||
|
else:
|
||||||
|
from appPublic.uniqueID import getID
|
||||||
|
new_id = getID()
|
||||||
|
|
||||||
|
async with DBPools().sqlorContext(dbname) as sor:
|
||||||
|
# 检查是否已存在
|
||||||
|
check_sql = "select id from llm_catalog_rel where llmid = ${llmid}$ and llmcatelogid = ${catelogid}$"
|
||||||
|
exists = await sor.sqlExe(check_sql, {'llmid': llmid, 'catelogid': catelogid})
|
||||||
|
|
||||||
|
if exists:
|
||||||
|
result['options'] = {'title': '提示', 'message': '该关联已存在', 'type': 'warning'}
|
||||||
|
else:
|
||||||
|
data = {'id': new_id, 'llmid': llmid, 'llmcatelogid': catelogid}
|
||||||
|
await sor.C('llm_catalog_rel', data)
|
||||||
|
result['options'] = {'title': 'Success', 'message': '添加成功', 'type': 'success'}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
result['options'] = {'title': 'Error', 'message': f'添加失败: {str(e)}', 'type': 'error'}
|
||||||
|
|
||||||
|
return json.dumps(result, ensure_ascii=False)
|
||||||
20
wwwroot/api/llm_catalog_rel_delete.dspy
Normal file
20
wwwroot/api/llm_catalog_rel_delete.dspy
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import json
|
||||||
|
|
||||||
|
result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': 'Invalid', 'type': 'error'}}
|
||||||
|
|
||||||
|
try:
|
||||||
|
dbname = get_module_dbname('llmage')
|
||||||
|
rel_id = params_kw.get('id', '')
|
||||||
|
|
||||||
|
if not rel_id:
|
||||||
|
result['options'] = {'title': 'Error', 'message': '缺少ID参数', 'type': 'error'}
|
||||||
|
else:
|
||||||
|
async with DBPools().sqlorContext(dbname) as sor:
|
||||||
|
await sor.sqlExe("delete from llm_catalog_rel where id = ${id}$", {'id': rel_id})
|
||||||
|
result['options'] = {'title': 'Success', 'message': '删除成功', 'type': 'success'}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
result['options'] = {'title': 'Error', 'message': f'删除失败: {str(e)}', 'type': 'error'}
|
||||||
|
|
||||||
|
return json.dumps(result, ensure_ascii=False)
|
||||||
25
wwwroot/api/llm_catalog_rel_list.dspy
Normal file
25
wwwroot/api/llm_catalog_rel_list.dspy
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import json
|
||||||
|
|
||||||
|
result = {'success': False, 'rows': [], 'total': 0}
|
||||||
|
|
||||||
|
try:
|
||||||
|
dbname = get_module_dbname('llmage')
|
||||||
|
sql = """
|
||||||
|
select r.id, r.llmid, l.name as llm_name, r.llmcatelogid, c.name as catelog_name
|
||||||
|
from llm_catalog_rel r
|
||||||
|
join llm l on r.llmid = l.id
|
||||||
|
join llmcatelog c on r.llmcatelogid = c.id
|
||||||
|
order by l.name, c.name
|
||||||
|
"""
|
||||||
|
|
||||||
|
async with DBPools().sqlorContext(dbname) as sor:
|
||||||
|
rows = await sor.sqlExe(sql, {})
|
||||||
|
result['rows'] = [dict(r) for r in (rows or [])]
|
||||||
|
result['total'] = len(result['rows'])
|
||||||
|
result['success'] = True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
result['error'] = str(e)
|
||||||
|
|
||||||
|
return json.dumps(result, ensure_ascii=False, default=str)
|
||||||
@ -12,7 +12,7 @@ try:
|
|||||||
else:
|
else:
|
||||||
async with DBPools().sqlorContext(dbname) as sor:
|
async with DBPools().sqlorContext(dbname) as sor:
|
||||||
# 检查是否有模型关联此类型
|
# 检查是否有模型关联此类型
|
||||||
check_sql = "select count(*) as cnt from llm_api_map where llmcatelogid=${id}$"
|
check_sql = "select count(*) as cnt from llm_catalog_rel where llmcatelogid=${id}$"
|
||||||
rel_count = await sor.sqlExe(check_sql, {'id': id})
|
rel_count = await sor.sqlExe(check_sql, {'id': id})
|
||||||
cnt = rel_count[0]['cnt'] if rel_count else 0
|
cnt = rel_count[0]['cnt'] if rel_count else 0
|
||||||
if cnt > 0:
|
if cnt > 0:
|
||||||
|
|||||||
@ -3,9 +3,9 @@ lt = '文生视频'
|
|||||||
if params_kw.type in ['文生视频', '参考生视频', '图生视频']:
|
if params_kw.type in ['文生视频', '参考生视频', '图生视频']:
|
||||||
lt = params_kw.type
|
lt = params_kw.type
|
||||||
async with get_sor_context(request._run_ns, 'llmage') as sor:
|
async with get_sor_context(request._run_ns, 'llmage') as sor:
|
||||||
sql = '''select distinct a.*, e.input_fields from llm a
|
sql = '''select a.*, e.input_fields from llm a
|
||||||
join llm_api_map m on a.id = m.llmid
|
join llm_catalog_rel rel on a.id = rel.llmid
|
||||||
join llmcatelog b on m.llmcatelogid = b.id
|
join llmcatelog b on rel.llmcatelogid = b.id
|
||||||
join upapp c on a.upappid = c.id
|
join upapp c on a.upappid = c.id
|
||||||
join uapi d on c.apisetid = d.apisetid and a.apiname = d.name
|
join uapi d on c.apisetid = d.apisetid and a.apiname = d.name
|
||||||
join uapiio e on d.ioid = e.id
|
join uapiio e on d.ioid = e.id
|
||||||
|
|||||||
@ -68,6 +68,53 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"backgroundColor": "#1e3a5f",
|
||||||
|
"padding": "24px",
|
||||||
|
"cursor": "pointer",
|
||||||
|
"borderRadius": "8px"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "click",
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"target": "app.llmage_content",
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('/llmage/llm_catalog_rel_manage.ui')}}"
|
||||||
|
},
|
||||||
|
"mode": "replace"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Svg",
|
||||||
|
"options": {
|
||||||
|
"svg": "<svg width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#ce93d8\" stroke-width=\"2\"><path d=\"M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\"/></svg>",
|
||||||
|
"width": "40px",
|
||||||
|
"height": "40px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Title4",
|
||||||
|
"options": {
|
||||||
|
"text": "模型-类型关联",
|
||||||
|
"color": "#ffffff",
|
||||||
|
"marginTop": "12px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "管理模型与类型的多对多关系",
|
||||||
|
"color": "#ce93d8",
|
||||||
|
"fontSize": "14px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"widgettype": "VBox",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
dbname = get_module_dbname('llmage')
|
dbname = get_module_dbname('llmage')
|
||||||
db = DBPools()
|
db = DBPools()
|
||||||
async with db.sqlorContext(dbname) as sor:
|
async with db.sqlorContext(dbname) as sor:
|
||||||
sql = """select distinct a.* from llm a
|
sql = """select * from llm a
|
||||||
join llm_api_map m on a.id = m.llmid
|
join llm_catalog_rel rel on a.id = rel.llmid
|
||||||
where m.llmcatelogid = ${llmcatelogid}$ and a.id != ${llmid}$"""
|
where rel.llmcatelogid = ${llmcatelogid}$ and a.id != ${llmid}$"""
|
||||||
ns = params_kw.copy()
|
ns = params_kw.copy()
|
||||||
recs = await sor.sqlExe(sql, ns)
|
recs = await sor.sqlExe(sql, ns)
|
||||||
for r in recs.get('rows', []):
|
for r in recs.get('rows', []):
|
||||||
|
|||||||
@ -12,15 +12,15 @@ y.system_message,
|
|||||||
y.user_message,
|
y.user_message,
|
||||||
y.assisant_message
|
y.assisant_message
|
||||||
from (
|
from (
|
||||||
select distinct a.*, b.hfid, e.ioid, e.stream
|
select a.*, b.hfid, e.ioid, e.stream
|
||||||
from llm a
|
from llm a
|
||||||
join llm_api_map m on a.id = m.llmid
|
join llm_catalog_rel rel on a.id = rel.llmid
|
||||||
join llmcatelog b on m.llmcatelogid = b.id
|
join llmcatelog b on rel.llmcatelogid = b.id
|
||||||
join upapp c on a.upappid = c.id
|
join upapp c on a.upappid = c.id
|
||||||
join uapi e on c.apisetid = e.apisetid and a.apiname = e.name
|
join uapi e on c.apisetid = e.apisetid and a.apiname = e.name
|
||||||
) x left join historyformat y on x.hfid = y.id
|
) x left join historyformat y on x.hfid = y.id
|
||||||
left join uapiio z on x.ioid = z.id
|
left join uapiio z on x.ioid = z.id
|
||||||
where m.llmcatelogid = ${llmcatelogid}$
|
where rel.llmcatelogid = ${llmcatelogid}$
|
||||||
and x.id != ${llmid}$
|
and x.id != ${llmid}$
|
||||||
"""
|
"""
|
||||||
ns = params_kw.copy()
|
ns = params_kw.copy()
|
||||||
|
|||||||
@ -14,106 +14,101 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"widgettype": "VScrollPanel",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"height": "500px"
|
"width": "calc(100% - 40px)",
|
||||||
|
"margin": "0 20px",
|
||||||
|
"padding": "16px",
|
||||||
|
"bgcolor": "#f5f5f5",
|
||||||
|
"spacing": 12
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "VBox",
|
"widgettype": "Text",
|
||||||
"options": {
|
"options": {
|
||||||
"width": "calc(100% - 40px)",
|
"text": "添加新映射",
|
||||||
"margin": "0 20px",
|
"fontSize": "16px",
|
||||||
"padding": "16px",
|
"fontWeight": "bold"
|
||||||
"bgcolor": "#f5f5f5",
|
}
|
||||||
"spacing": 12
|
},
|
||||||
},
|
{
|
||||||
"subwidgets": [
|
"widgettype": "Form",
|
||||||
{
|
"id": "add_form",
|
||||||
"widgettype": "Text",
|
"options": {
|
||||||
"options": {
|
"layout": "horizontal",
|
||||||
"text": "添加新映射",
|
"cols": 3,
|
||||||
"fontSize": "16px",
|
"fields": [
|
||||||
"fontWeight": "bold"
|
{
|
||||||
}
|
"name": "llmid",
|
||||||
},
|
"label": "选择模型",
|
||||||
{
|
"uitype": "select",
|
||||||
"widgettype": "Form",
|
"dataurl": "{{entire_url('./api/llm_api_map_options.dspy')}}",
|
||||||
"id": "add_form",
|
"data_field": "llms",
|
||||||
"options": {
|
"placeholder": "请选择模型"
|
||||||
"layout": "horizontal",
|
|
||||||
"cols": 3,
|
|
||||||
"fields": [
|
|
||||||
{
|
|
||||||
"name": "llmid",
|
|
||||||
"uitype": "hidden",
|
|
||||||
"value": "{{params_kw.llmid}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "llmcatelogid",
|
|
||||||
"label": "选择分类",
|
|
||||||
"uitype": "code",
|
|
||||||
"dataurl": "{{entire_url('./api/llm_api_map_options.dspy')}}",
|
|
||||||
"data_field": "catelogs",
|
|
||||||
"placeholder": "请选择分类"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "apiname",
|
|
||||||
"label": "API接口",
|
|
||||||
"uitype": "code",
|
|
||||||
"dataurl": "{{entire_url('./api/llm_api_map_options.dspy')}}",
|
|
||||||
"data_field": "apis",
|
|
||||||
"placeholder": "请选择API接口"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "query_apiname",
|
|
||||||
"label": "查询API",
|
|
||||||
"uitype": "str",
|
|
||||||
"placeholder": "异步查询API名,多个用逗号分隔"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "query_period",
|
|
||||||
"label": "查询间隔(秒)",
|
|
||||||
"uitype": "int",
|
|
||||||
"placeholder": "默认30"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "ppid",
|
|
||||||
"label": "计费项目",
|
|
||||||
"uitype": "code",
|
|
||||||
"dataurl": "{{entire_url('./api/llm_api_map_options.dspy')}}",
|
|
||||||
"data_field": "ppids",
|
|
||||||
"placeholder": "请选择计费项目"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"buttons": [
|
|
||||||
{
|
|
||||||
"name": "add_btn",
|
|
||||||
"label": "添加映射",
|
|
||||||
"variant": "primary"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"binds": [
|
{
|
||||||
{
|
"name": "llmcatelogid",
|
||||||
"wid": "add_btn",
|
"label": "选择分类",
|
||||||
"event": "click",
|
"uitype": "select",
|
||||||
"actiontype": "urlwidget",
|
"dataurl": "{{entire_url('./api/llm_api_map_options.dspy')}}",
|
||||||
"target": "PopupWindow",
|
"data_field": "catelogs",
|
||||||
"popup_options": {"archor": "cc", "width": "30%", "height": "20%"},
|
"placeholder": "请选择分类"
|
||||||
"options": {
|
},
|
||||||
"url": "{{entire_url('./api/llm_api_map_create.dspy')}}",
|
{
|
||||||
"params": {
|
"name": "apiname",
|
||||||
"llmid": "$[add_form.llmid]$",
|
"label": "API接口",
|
||||||
"llmcatelogid": "$[add_form.llmcatelogid]$",
|
"uitype": "select",
|
||||||
"apiname": "$[add_form.apiname]$",
|
"dataurl": "{{entire_url('./api/llm_api_map_options.dspy')}}",
|
||||||
"query_apiname": "$[add_form.query_apiname]$",
|
"data_field": "apis",
|
||||||
"query_period": "$[add_form.query_period]$",
|
"placeholder": "请选择API接口"
|
||||||
"ppid": "$[add_form.ppid]$"
|
},
|
||||||
}
|
{
|
||||||
}
|
"name": "query_apiname",
|
||||||
|
"label": "查询API",
|
||||||
|
"uitype": "text",
|
||||||
|
"placeholder": "异步查询API名,多个用逗号分隔"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "query_period",
|
||||||
|
"label": "查询间隔(秒)",
|
||||||
|
"uitype": "number",
|
||||||
|
"placeholder": "默认30"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ppid",
|
||||||
|
"label": "计费项目",
|
||||||
|
"uitype": "select",
|
||||||
|
"dataurl": "{{entire_url('./api/llm_api_map_options.dspy')}}",
|
||||||
|
"data_field": "ppids",
|
||||||
|
"placeholder": "请选择计费项目"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buttons": [
|
||||||
|
{
|
||||||
|
"name": "add_btn",
|
||||||
|
"label": "添加映射",
|
||||||
|
"variant": "primary"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "add_btn",
|
||||||
|
"event": "click",
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"target": "PopupWindow",
|
||||||
|
"popup_options": {"archor": "cc", "width": "30%", "height": "20%"},
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('./api/llm_api_map_create.dspy')}}",
|
||||||
|
"params": {
|
||||||
|
"llmid": "$[add_form.llmid]$",
|
||||||
|
"llmcatelogid": "$[add_form.llmcatelogid]$",
|
||||||
|
"apiname": "$[add_form.apiname]$",
|
||||||
|
"query_apiname": "$[add_form.query_apiname]$",
|
||||||
|
"query_period": "$[add_form.query_period]$",
|
||||||
|
"ppid": "$[add_form.ppid]$"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
145
wwwroot/llm_catalog_rel_manage.ui
Normal file
145
wwwroot/llm_catalog_rel_manage.ui
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"height": "100%",
|
||||||
|
"spacing": 16
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Title2",
|
||||||
|
"options": {
|
||||||
|
"text": "LLM 目录关联管理",
|
||||||
|
"halign": "left"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "calc(100% - 40px)",
|
||||||
|
"margin": "0 20px",
|
||||||
|
"padding": "16px",
|
||||||
|
"bgcolor": "#f5f5f5",
|
||||||
|
"spacing": 12
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "添加新关联",
|
||||||
|
"fontSize": "16px",
|
||||||
|
"fontWeight": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Form",
|
||||||
|
"id": "add_form",
|
||||||
|
"options": {
|
||||||
|
"layout": "horizontal",
|
||||||
|
"cols": 3,
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "llmid",
|
||||||
|
"label": "选择模型",
|
||||||
|
"uitype": "select",
|
||||||
|
"dataurl": "{{entire_url('./api/llm_catelog_options.dspy')}}",
|
||||||
|
"data_field": "llms",
|
||||||
|
"placeholder": "请选择模型"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "llmcatelogid",
|
||||||
|
"label": "选择目录",
|
||||||
|
"uitype": "select",
|
||||||
|
"dataurl": "{{entire_url('./api/llm_catelog_options.dspy')}}",
|
||||||
|
"data_field": "catelogs",
|
||||||
|
"placeholder": "请选择目录"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buttons": [
|
||||||
|
{
|
||||||
|
"name": "add_btn",
|
||||||
|
"label": "添加关联",
|
||||||
|
"variant": "primary"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "add_btn",
|
||||||
|
"event": "click",
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"target": "PopupWindow",
|
||||||
|
"popup_options": {"archor": "cc", "width": "30%", "height": "20%"},
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('./api/llm_catalog_rel_create.dspy')}}",
|
||||||
|
"params": {
|
||||||
|
"llmid": "$[add_form.llmid]$",
|
||||||
|
"llmcatelogid": "$[add_form.llmcatelogid]$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "calc(100% - 40px)",
|
||||||
|
"margin": "0 20px",
|
||||||
|
"spacing": 12
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "当前关联列表",
|
||||||
|
"fontSize": "16px",
|
||||||
|
"fontWeight": "bold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Tabular",
|
||||||
|
"id": "rel_table",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"height": "400px",
|
||||||
|
"data_url": "{{entire_url('./api/llm_catalog_rel_list.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"page_rows": 20,
|
||||||
|
"row_options": {
|
||||||
|
"fields": [
|
||||||
|
{"name": "llm_name", "title": "模型名称", "width": 200},
|
||||||
|
{"name": "catelog_name", "title": "目录名称", "width": 150},
|
||||||
|
{
|
||||||
|
"name": "actions",
|
||||||
|
"title": "操作",
|
||||||
|
"width": 100,
|
||||||
|
"uitype": "button",
|
||||||
|
"data": [
|
||||||
|
{"text": "删除", "event": "delete_rel"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "delete_rel",
|
||||||
|
"actiontype": "urlwidget",
|
||||||
|
"target": "PopupWindow",
|
||||||
|
"popup_options": {"archor": "cc", "width": "30%", "height": "20%"},
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('./api/llm_catalog_rel_delete.dspy')}}",
|
||||||
|
"params": {
|
||||||
|
"id": "$[event.params.id]$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -31,6 +31,11 @@
|
|||||||
"name":"llm",
|
"name":"llm",
|
||||||
"label":"模型",
|
"label":"模型",
|
||||||
"url":"{{entire_url('/llmage/llm')}}"
|
"url":"{{entire_url('/llmage/llm')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"llmcatelog_rel",
|
||||||
|
"label":"类型关联",
|
||||||
|
"url":"{{entire_url('/llmage/llm_catalog_rel_manage.ui')}}"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,9 +17,9 @@ if not params_kw.prompt:
|
|||||||
return json_response(d, status=400)
|
return json_response(d, status=400)
|
||||||
env = request._run_ns
|
env = request._run_ns
|
||||||
async with get_sor_context(env, 'llmage') as sor:
|
async with get_sor_context(env, 'llmage') as sor:
|
||||||
sql = """select distinct a.* from llm a
|
sql = """select a.* from llm a
|
||||||
join llm_api_map m on a.id = m.llmid
|
join llm_catalog_rel rel on a.id = rel.llmid
|
||||||
join llmcatelog b on m.llmcatelogid = b.id
|
join llmcatelog b on rel.llmcatelogid = b.id
|
||||||
where b.name = ${lctype}$
|
where b.name = ${lctype}$
|
||||||
and a.model=${model}$"""
|
and a.model=${model}$"""
|
||||||
recs = await sor.sqlExe(sql, {
|
recs = await sor.sqlExe(sql, {
|
||||||
|
|||||||
@ -30,9 +30,9 @@ if not params_kw.prompt and not params_kw.messages:
|
|||||||
return json_response(d, status=400)
|
return json_response(d, status=400)
|
||||||
env = request._run_ns
|
env = request._run_ns
|
||||||
async with get_sor_context(env, 'llmage') as sor:
|
async with get_sor_context(env, 'llmage') as sor:
|
||||||
sql = """select distinct a.* from llm a
|
sql = """select a.* from llm a
|
||||||
join llm_api_map m on a.id = m.llmid
|
join llm_catalog_rel rel on a.id = rel.llmid
|
||||||
join llmcatelog b on m.llmcatelogid = b.id
|
join llmcatelog b on rel.llmcatelogid = b.id
|
||||||
where b.name = ${lctype}$
|
where b.name = ${lctype}$
|
||||||
and a.model=${model}$"""
|
and a.model=${model}$"""
|
||||||
recs = await sor.sqlExe(sql, {
|
recs = await sor.sqlExe(sql, {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user