修复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%"
|
||||
},
|
||||
"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%"
|
||||
},
|
||||
"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')
|
||||
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):
|
||||
env = ServerEnv()
|
||||
async with get_sor_context(env, 'llmage') as sor:
|
||||
|
||||
@ -151,6 +151,13 @@
|
||||
"userorgid",
|
||||
"use_time"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "idx_llmusage_usetime",
|
||||
"idxtype": "index",
|
||||
"idxfields": [
|
||||
"use_time"
|
||||
]
|
||||
}
|
||||
],
|
||||
"codes": [
|
||||
@ -193,4 +200,4 @@
|
||||
"cond": "parentid='accounting_status'"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -155,8 +155,8 @@ PATHS_LOGINED = [
|
||||
f"/{MOD}/llmusage/delete_llmusage.dspy",
|
||||
f"/{MOD}/llmusage/get_llmusage.dspy",
|
||||
f"/{MOD}/llmusage/update_llmusage.dspy",
|
||||
f"/{MOD}/llmusage_usages_display.ui",
|
||||
f"/{MOD}/llmusage_ioinfo_display.ui",
|
||||
f"/{MOD}/llmusage_usages_display.dspy",
|
||||
f"/{MOD}/llmusage_ioinfo_display.dspy",
|
||||
|
||||
# CRUD 子目录 — llmusage_accounting_failed/
|
||||
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