fix: rewrite tag_assign dspy with explicit return
This commit is contained in:
parent
b322c4533e
commit
5d0ec6f3c4
@ -11,7 +11,6 @@ import json
|
||||
base_url = entire_url('/tag_assign/index.dspy')
|
||||
|
||||
async with db.sqlorContext(dbname) as sor:
|
||||
# Handle assign/unassign actions
|
||||
if action and media_id and tag_id:
|
||||
import uuid
|
||||
try:
|
||||
@ -27,37 +26,24 @@ async with db.sqlorContext(dbname) as sor:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Get knowledge bases
|
||||
kbs = await sor.R('knowledge_bases', {})
|
||||
|
||||
# Get media items
|
||||
media_items = []
|
||||
if kb_id:
|
||||
if media_type == 'document':
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT id, file_name, file_type FROM documents WHERE kb_id=${kb_id}$ ORDER BY created_at DESC LIMIT 100",
|
||||
{"kb_id": kb_id})
|
||||
recs = await sor.sqlExe("SELECT id, file_name, file_type FROM documents WHERE kb_id=${kb_id}$ ORDER BY created_at DESC LIMIT 100", {"kb_id": kb_id})
|
||||
media_items = [{"id": r.id, "name": r.file_name, "type": r.file_type} for r in recs]
|
||||
elif media_type == 'face':
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT id, name, description FROM entities WHERE kb_id=${kb_id}$ AND entity_type='person' AND face_embedding_id IS NOT NULL ORDER BY created_at DESC LIMIT 100",
|
||||
{"kb_id": kb_id})
|
||||
recs = await sor.sqlExe("SELECT id, name, description FROM entities WHERE kb_id=${kb_id}$ AND entity_type='person' AND face_embedding_id IS NOT NULL ORDER BY created_at DESC LIMIT 100", {"kb_id": kb_id})
|
||||
media_items = [{"id": r.id, "name": r.name or '人脸#'+r.id[:8], "type": "face"} for r in recs]
|
||||
elif media_type == 'voice':
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT id, name, description FROM entities WHERE kb_id=${kb_id}$ AND entity_type='voice' AND voice_embedding_id IS NOT NULL ORDER BY created_at DESC LIMIT 100",
|
||||
{"kb_id": kb_id})
|
||||
recs = await sor.sqlExe("SELECT id, name, description FROM entities WHERE kb_id=${kb_id}$ AND entity_type='voice' AND voice_embedding_id IS NOT NULL ORDER BY created_at DESC LIMIT 100", {"kb_id": kb_id})
|
||||
media_items = [{"id": r.id, "name": r.name or '声纹#'+r.id[:8], "type": "voice"} for r in recs]
|
||||
|
||||
# Get current tags for selected media
|
||||
current_tags = []
|
||||
if media_id:
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT t.id, t.name, t.color FROM media_tags mt JOIN tags t ON mt.tag_id=t.id WHERE mt.media_type=${type}$ AND mt.media_id=${mid}$",
|
||||
{"type": media_type, "mid": media_id})
|
||||
recs = await sor.sqlExe("SELECT t.id, t.name, t.color FROM media_tags mt JOIN tags t ON mt.tag_id=t.id WHERE mt.media_type=${type}$ AND mt.media_id=${mid}$", {"type": media_type, "mid": media_id})
|
||||
current_tags = [{"id": r.id, "name": r.name, "color": r.color} for r in recs]
|
||||
|
||||
# Get all available tags
|
||||
all_tags = []
|
||||
if kb_id:
|
||||
tag_recs = await sor.R('tags', {'kb_id': kb_id})
|
||||
@ -65,93 +51,44 @@ async with db.sqlorContext(dbname) as sor:
|
||||
|
||||
current_tag_ids = {t['id'] for t in current_tags}
|
||||
|
||||
# Build available tag buttons
|
||||
tag_buttons = []
|
||||
for t in all_tags:
|
||||
is_assigned = t['id'] in current_tag_ids
|
||||
if is_assigned:
|
||||
act = 'unassign'
|
||||
lbl = '✓ ' + t['name']
|
||||
bg = t['color']
|
||||
clr = '#fff'
|
||||
else:
|
||||
act = 'assign'
|
||||
lbl = '+ ' + t['name']
|
||||
bg = '#e5e7eb'
|
||||
clr = '#666'
|
||||
act = 'unassign' if is_assigned else 'assign'
|
||||
lbl = ('✓ ' if is_assigned else '+ ') + t['name']
|
||||
bg = t['color'] if is_assigned else '#e5e7eb'
|
||||
clr = '#fff' if is_assigned else '#666'
|
||||
tag_url = base_url + '?kb_id=' + kb_id + '&media_type=' + media_type + '&media_id=' + media_id + '&action=' + act + '&tag_id=' + t['id']
|
||||
tag_buttons.append({
|
||||
"widgettype": "Button",
|
||||
"options": {"label": lbl, "bgcolor": bg, "color": clr, "cfontsize": 12, "padding": "4px 12px", "marginRight": "6px", "marginBottom": "6px"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace", "options": {"url": tag_url}}]
|
||||
})
|
||||
tag_buttons.append({"widgettype": "Button", "options": {"label": lbl, "bgcolor": bg, "color": clr, "cfontsize": 12, "padding": "4px 12px", "marginRight": "6px", "marginBottom": "6px"}, "binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace", "options": {"url": tag_url}}]})
|
||||
|
||||
# Build media list buttons
|
||||
media_buttons = []
|
||||
for m in media_items:
|
||||
murl = base_url + '?kb_id=' + kb_id + '&media_type=' + media_type + '&media_id=' + m['id']
|
||||
is_current = m['id'] == media_id
|
||||
media_buttons.append({
|
||||
"widgettype": "Button",
|
||||
"options": {
|
||||
"label": ('📄' if media_type=='document' else ('👤' if media_type=='face' else '🎤')) + ' ' + m['name'],
|
||||
"bgcolor": "#dbeafe" if is_current else "#f9fafb",
|
||||
"color": "#1e40af" if is_current else "#666",
|
||||
"cfontsize": 12,
|
||||
"padding": "6px 12px",
|
||||
"marginBottom": "4px",
|
||||
"halign": "left"
|
||||
},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace", "options": {"url": murl}}]
|
||||
})
|
||||
icon = '📄' if media_type == 'document' else ('👤' if media_type == 'face' else '🎤')
|
||||
media_buttons.append({"widgettype": "Button", "options": {"label": icon + ' ' + m['name'], "bgcolor": "#dbeafe" if is_current else "#f9fafb", "color": "#1e40af" if is_current else "#666", "cfontsize": 12, "padding": "6px 12px", "marginBottom": "4px", "halign": "left"}, "binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace", "options": {"url": murl}}]})
|
||||
|
||||
# KB buttons
|
||||
kb_buttons = []
|
||||
for k in kbs:
|
||||
kb_buttons.append({
|
||||
"widgettype": "Button",
|
||||
"options": {"label": k.name, "bgcolor": "#3b82f6" if k.id==kb_id else "#e5e7eb", "color": "#fff" if k.id==kb_id else "#666", "cfontsize": 12, "padding": "6px 14px", "marginRight": "6px", "marginBottom": "4px"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace",
|
||||
"options": {"url": base_url + '?kb_id=' + k.id + '&media_type=' + media_type}}]}
|
||||
)
|
||||
kb_buttons.append({"widgettype": "Button", "options": {"label": k.name, "bgcolor": "#3b82f6" if k.id == kb_id else "#e5e7eb", "color": "#fff" if k.id == kb_id else "#666", "cfontsize": 12, "padding": "6px 14px", "marginRight": "6px", "marginBottom": "4px"}, "binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace", "options": {"url": base_url + '?kb_id=' + k.id + '&media_type=' + media_type}}]})
|
||||
|
||||
# Type tabs
|
||||
type_tabs = []
|
||||
for mt, mt_label in [('document', '📄 文档'), ('face', '👤 人脸'), ('voice', '🎤 声纹')]:
|
||||
type_tabs.append({
|
||||
"widgettype": "Button",
|
||||
"options": {"label": mt_label, "bgcolor": "#3b82f6" if mt==media_type else "#e5e7eb", "color": "#fff" if mt==media_type else "#666", "cfontsize": 12, "padding": "6px 16px", "marginRight": "4px"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace",
|
||||
"options": {"url": base_url + '?kb_id=' + kb_id + '&media_type=' + mt}}]}
|
||||
)
|
||||
type_tabs.append({"widgettype": "Button", "options": {"label": mt_label, "bgcolor": "#3b82f6" if mt == media_type else "#e5e7eb", "color": "#fff" if mt == media_type else "#666", "cfontsize": 12, "padding": "6px 16px", "marginRight": "4px"}, "binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace", "options": {"url": base_url + '?kb_id=' + kb_id + '&media_type=' + mt}}]})
|
||||
|
||||
result = {
|
||||
"widgettype": "VBox",
|
||||
"options": {"cheight": 40, "width": "100%", "padding": "16px", "spacing": "12px"},
|
||||
"subwidgets": [
|
||||
result = json.dumps({"widgettype": "VBox", "options": {"cheight": 40, "width": "100%", "padding": "16px", "spacing": "12px"}, "subwidgets": [
|
||||
{"widgettype": "Text", "options": {"text": "🏷️ 标签分配", "cfontsize": 20, "fontWeight": "bold", "color": "#333"}},
|
||||
{"widgettype": "Text", "options": {"text": "为文档、人脸、声纹设置标签", "cfontsize": 13, "color": "#888"}},
|
||||
# KB
|
||||
{"widgettype": "Text", "options": {"text": "知识库:", "cfontsize": 13, "color": "#555", "marginTop": "8px"}},
|
||||
{"widgettype": "HBox", "options": {"spacing": "4px", "wrap": True}, "subwidgets": kb_buttons},
|
||||
# Media type
|
||||
{"widgettype": "Text", "options": {"text": "媒体类型:", "cfontsize": 13, "color": "#555", "marginTop": "4px"}},
|
||||
{"widgettype": "HBox", "options": {"spacing": "4px"}, "subwidgets": type_tabs},
|
||||
# Media list
|
||||
{"widgettype": "Text", "options": {"text": '选择' + ('文档' if media_type=='document' else ('人脸' if media_type=='face' else '声纹')) + ':', "cfontsize": 13, "color": "#555", "marginTop": "8px"}},
|
||||
{"widgettype": "Text", "options": {"text": "选择" + ('文档' if media_type == 'document' else ('人脸' if media_type == 'face' else '声纹')) + ":", "cfontsize": 13, "color": "#555", "marginTop": "8px"}},
|
||||
{"widgettype": "VBox", "options": {"cheight": 12, "bgcolor": "#fafafa", "padding": "8px", "border": "1px solid #e0e0e0", "overflowY": "auto"}, "subwidgets": media_buttons},
|
||||
# Current tags
|
||||
{"widgettype": "Text", "options": {"text": "当前标签:", "cfontsize": 13, "color": "#555", "marginTop": "8px"}},
|
||||
{"widgettype": "HBox", "options": {"spacing": "4px", "wrap": True}, "subwidgets": [
|
||||
{"widgettype": "Button", "options": {"label": t['name'], "bgcolor": t['color'], "color": "#fff", "cfontsize": 11, "padding": "3px 10px", "marginRight": "4px", "marginBottom": "4px"},
|
||||
"binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace",
|
||||
"options": {"url": base_url + '?kb_id=' + kb_id + '&media_type=' + media_type + '&media_id=' + media_id + '&action=unassign&tag_id=' + t['id']}}]}
|
||||
for t in current_tags] if current_tags else [{"widgettype": "Text", "options": {"text": "(无)", "color": "#aaa", "cfontsize": 12}}]},
|
||||
# Available tags
|
||||
{"widgettype": "HBox", "options": {"spacing": "4px", "wrap": True}, "subwidgets": current_tags and [{"widgettype": "Button", "options": {"label": t['name'], "bgcolor": t['color'], "color": "#fff", "cfontsize": 11, "padding": "3px 10px", "marginRight": "4px", "marginBottom": "4px"}, "binds": [{"wid": "self", "event": "click", "actiontype": "urlwidget", "target": "app.rag_main_content", "mode": "replace", "options": {"url": base_url + '?kb_id=' + kb_id + '&media_type=' + media_type + '&media_id=' + media_id + '&action=unassign&tag_id=' + t['id']}}]} for t in current_tags] or [{"widgettype": "Text", "options": {"text": "(无)", "color": "#aaa", "cfontsize": 12}}]},
|
||||
{"widgettype": "Text", "options": {"text": "可用标签 (点击切换):", "cfontsize": 13, "color": "#555", "marginTop": "4px"}},
|
||||
{"widgettype": "HBox", "options": {"spacing": "4px", "wrap": True}, "subwidgets": tag_buttons} if media_id else [
|
||||
{"widgettype": "Text", "options": {"text": "请先选择媒体文件", "color": "#aaa", "cfontsize": 12, "padding": "12px 0"}}
|
||||
]
|
||||
]
|
||||
}
|
||||
result
|
||||
{"widgettype": "HBox", "options": {"spacing": "4px", "wrap": True}, "subwidgets": tag_buttons} if media_id else [{"widgettype": "Text", "options": {"text": "请先选择媒体文件", "color": "#aaa", "cfontsize": 12, "padding": "12px 0"}}]
|
||||
]})
|
||||
|
||||
return json.loads(result)
|
||||
|
||||
@ -99,4 +99,4 @@ async with db.sqlorContext(dbname) as sor:
|
||||
{"widgettype": "VBox", "options": {"spacing": "4px"}, "subwidgets": results_widgets}
|
||||
]
|
||||
}
|
||||
result
|
||||
return result
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user