修复llmusage展示脚本500错误并优化CRUD性能
- 将llmusage_ioinfo_display.ui和llmusage_usages_display.ui从Jinja模板改为.dspy脚本 - 在utils.py中添加get_llmusage_by_id和read_ioinfo_content两个函数 - 重写get_llmusage.dspy,避免sqlPaging子查询包装,分离count和data查询 - 为llmusage表添加use_time索引提升排序性能 - 更新load_path.py和json/llmusage.json引用新的.dspy文件
This commit is contained in:
parent
a6efef56e9
commit
6c2ccda2c7
@ -31,7 +31,7 @@
|
|||||||
"height": "70%"
|
"height": "70%"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('../llmusage_usages_display.ui')}}?id=${id}$"
|
"url": "{{entire_url('../llmusage_usages_display.dspy')}}?id=${id}$"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -45,7 +45,7 @@
|
|||||||
"height": "70%"
|
"height": "70%"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('../llmusage_ioinfo_display.ui')}}?id=${id}$"
|
"url": "{{entire_url('../llmusage_ioinfo_display.dspy')}}?id=${id}$"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@ -149,6 +149,32 @@ async def write_llmio(luid, io_dic):
|
|||||||
webpath = await fs.save(name, s, userid='llmio')
|
webpath = await fs.save(name, s, userid='llmio')
|
||||||
return webpath
|
return webpath
|
||||||
|
|
||||||
|
async def get_llmusage_by_id(usage_id):
|
||||||
|
"""从数据库获取 llmusage 记录"""
|
||||||
|
env = ServerEnv()
|
||||||
|
async with get_sor_context(env, 'llmage') as sor:
|
||||||
|
sql = "select id, llmid, ioinfo, usages from llmusage where id = ${id}$"
|
||||||
|
recs = await sor.sqlExe(sql, {'id': usage_id})
|
||||||
|
if recs and len(recs) > 0:
|
||||||
|
return dict(recs[0])
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
async def read_ioinfo_content(ioinfo_webpath):
|
||||||
|
"""从 FileStorage 读取交互信息文件内容"""
|
||||||
|
if not ioinfo_webpath:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
fs = FileStorage()
|
||||||
|
real_path = fs.realPath(ioinfo_webpath)
|
||||||
|
async with aiofiles.open(real_path, 'rb') as f:
|
||||||
|
bin_data = await f.read()
|
||||||
|
return json.loads(bin_data.decode('utf-8'))
|
||||||
|
except Exception as e:
|
||||||
|
debug(f'read_ioinfo_content error: {e}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def llm_query_orders(userorgid, page, pagerows=80):
|
async def llm_query_orders(userorgid, page, pagerows=80):
|
||||||
env = ServerEnv()
|
env = ServerEnv()
|
||||||
async with get_sor_context(env, 'llmage') as sor:
|
async with get_sor_context(env, 'llmage') as sor:
|
||||||
|
|||||||
@ -151,6 +151,13 @@
|
|||||||
"userorgid",
|
"userorgid",
|
||||||
"use_time"
|
"use_time"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "idx_llmusage_usetime",
|
||||||
|
"idxtype": "index",
|
||||||
|
"idxfields": [
|
||||||
|
"use_time"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"codes": [
|
"codes": [
|
||||||
@ -193,4 +200,4 @@
|
|||||||
"cond": "parentid='accounting_status'"
|
"cond": "parentid='accounting_status'"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -155,8 +155,8 @@ PATHS_LOGINED = [
|
|||||||
f"/{MOD}/llmusage/delete_llmusage.dspy",
|
f"/{MOD}/llmusage/delete_llmusage.dspy",
|
||||||
f"/{MOD}/llmusage/get_llmusage.dspy",
|
f"/{MOD}/llmusage/get_llmusage.dspy",
|
||||||
f"/{MOD}/llmusage/update_llmusage.dspy",
|
f"/{MOD}/llmusage/update_llmusage.dspy",
|
||||||
f"/{MOD}/llmusage_usages_display.ui",
|
f"/{MOD}/llmusage_usages_display.dspy",
|
||||||
f"/{MOD}/llmusage_ioinfo_display.ui",
|
f"/{MOD}/llmusage_ioinfo_display.dspy",
|
||||||
|
|
||||||
# CRUD 子目录 — llmusage_accounting_failed/
|
# CRUD 子目录 — llmusage_accounting_failed/
|
||||||
f"/{MOD}/llmusage_accounting_failed/index.ui",
|
f"/{MOD}/llmusage_accounting_failed/index.ui",
|
||||||
|
|||||||
48
wwwroot/llmusage_ioinfo_display.dspy
Normal file
48
wwwroot/llmusage_ioinfo_display.dspy
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import json
|
||||||
|
from llmage.utils import get_llmusage_by_id, read_ioinfo_content
|
||||||
|
|
||||||
|
usage_id = params_kw.get('id')
|
||||||
|
if not usage_id:
|
||||||
|
return {"widgettype": "Message", "options": {"message": "缺少 id 参数", "type": "error"}}
|
||||||
|
|
||||||
|
record = await get_llmusage_by_id(usage_id)
|
||||||
|
if not record:
|
||||||
|
return {"widgettype": "Message", "options": {"message": "未找到记录", "type": "error"}}
|
||||||
|
|
||||||
|
llmid = record.get('llmid', '')
|
||||||
|
ioinfo_webpath = record.get('ioinfo', '')
|
||||||
|
|
||||||
|
ioinfo_content = await read_ioinfo_content(ioinfo_webpath) if ioinfo_webpath else None
|
||||||
|
ioinfo_text = json.dumps(ioinfo_content, ensure_ascii=False, indent=2) if ioinfo_content else "无交互内容"
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype": "VScrollPanel",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"height": "100%"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"padding": "16px",
|
||||||
|
"spacing": 12
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Title4",
|
||||||
|
"options": {
|
||||||
|
"text": f"Model: {llmid}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": ioinfo_text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,35 +0,0 @@
|
|||||||
{% set sor = db.sqlorContext() %}
|
|
||||||
{% set row = sor.execute_sql('select llmid, ioinfo from llmusage where id = ${id}$').first() %}
|
|
||||||
{% set ioinfo = row.ioinfo if row and row.ioinfo else '' %}
|
|
||||||
{% set model_id = row.llmid if row else '' %}
|
|
||||||
{
|
|
||||||
"widgettype": "VScrollPanel",
|
|
||||||
"options": {
|
|
||||||
"width": "100%",
|
|
||||||
"height": "100%"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"width": "100%",
|
|
||||||
"padding": "16px",
|
|
||||||
"spacing": 12
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Title4",
|
|
||||||
"options": {
|
|
||||||
"text": "Model: {{ model_id }}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"text": {{ ioinfo | tojson }}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
52
wwwroot/llmusage_usages_display.dspy
Normal file
52
wwwroot/llmusage_usages_display.dspy
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import json
|
||||||
|
from llmage.utils import get_llmusage_by_id
|
||||||
|
|
||||||
|
usage_id = params_kw.get('id')
|
||||||
|
if not usage_id:
|
||||||
|
return {"widgettype": "Message", "options": {"message": "缺少 id 参数", "type": "error"}}
|
||||||
|
|
||||||
|
record = await get_llmusage_by_id(usage_id)
|
||||||
|
if not record:
|
||||||
|
return {"widgettype": "Message", "options": {"message": "未找到记录", "type": "error"}}
|
||||||
|
|
||||||
|
llmid = record.get('llmid', '')
|
||||||
|
usages_raw = record.get('usages', '')
|
||||||
|
|
||||||
|
try:
|
||||||
|
usages_obj = json.loads(usages_raw) if isinstance(usages_raw, str) else usages_raw
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
usages_obj = usages_raw
|
||||||
|
|
||||||
|
usages_text = json.dumps(usages_obj, ensure_ascii=False, indent=2) if usages_obj else "无使用信息"
|
||||||
|
|
||||||
|
return {
|
||||||
|
"widgettype": "VScrollPanel",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"height": "100%"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"padding": "16px",
|
||||||
|
"spacing": 12
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Title4",
|
||||||
|
"options": {
|
||||||
|
"text": f"Model: {llmid}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": usages_text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -1,35 +0,0 @@
|
|||||||
{% set sor = db.sqlorContext() %}
|
|
||||||
{% set row = sor.execute_sql('select llmid, usages from llmusage where id = ${id}$').first() %}
|
|
||||||
{% set usages = row.usages if row and row.usages else '' %}
|
|
||||||
{% set model_id = row.llmid if row else '' %}
|
|
||||||
{
|
|
||||||
"widgettype": "VScrollPanel",
|
|
||||||
"options": {
|
|
||||||
"width": "100%",
|
|
||||||
"height": "100%"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"width": "100%",
|
|
||||||
"padding": "16px",
|
|
||||||
"spacing": 12
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Title4",
|
|
||||||
"options": {
|
|
||||||
"text": "Model: {{ model_id }}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Text",
|
|
||||||
"options": {
|
|
||||||
"text": {{ usages | tojson }}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user