添加推理交互和模型配置:创建推理控制台UI和API,扩展config模型添加LLM模型字段(model_name/provider/api_key/temperature等)
This commit is contained in:
parent
4882ba0290
commit
3dfd935dfe
@ -81,6 +81,65 @@
|
|||||||
"nullable": "no",
|
"nullable": "no",
|
||||||
"default": "3"
|
"default": "3"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "model_name",
|
||||||
|
"title": "LLM model name (e.g. qwen3-max, claude-sonnet-4)",
|
||||||
|
"type": "str",
|
||||||
|
"length": 64,
|
||||||
|
"nullable": "yes",
|
||||||
|
"default": "qwen3-max"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "model_provider",
|
||||||
|
"title": "Model provider (e.g. openrouter, anthropic, dashscope)",
|
||||||
|
"type": "str",
|
||||||
|
"length": 32,
|
||||||
|
"nullable": "yes",
|
||||||
|
"default": "openrouter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "api_key",
|
||||||
|
"title": "API key for LLM provider",
|
||||||
|
"type": "text",
|
||||||
|
"nullable": "yes",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "api_endpoint",
|
||||||
|
"title": "API endpoint URL (optional, uses default if empty)",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"nullable": "yes",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "temperature",
|
||||||
|
"title": "LLM temperature (0.0-1.0)",
|
||||||
|
"type": "float",
|
||||||
|
"nullable": "no",
|
||||||
|
"default": "0.7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "max_output_tokens",
|
||||||
|
"title": "Maximum output tokens",
|
||||||
|
"type": "int",
|
||||||
|
"nullable": "no",
|
||||||
|
"default": "4096"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "top_p",
|
||||||
|
"title": "Top-p sampling parameter",
|
||||||
|
"type": "float",
|
||||||
|
"nullable": "no",
|
||||||
|
"default": "0.9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "system_prompt",
|
||||||
|
"title": "System prompt template for reasoning",
|
||||||
|
"type": "text",
|
||||||
|
"nullable": "yes",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "created_at",
|
"name": "created_at",
|
||||||
"title": "Creation timestamp",
|
"title": "Creation timestamp",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""Get reasoning configuration for current user"""
|
"""Get reasoning configuration for current user (includes model config)"""
|
||||||
import json
|
import json
|
||||||
|
|
||||||
result = {'success': False, 'config': {}}
|
result = {'success': False, 'config': {}}
|
||||||
@ -18,7 +18,6 @@ try:
|
|||||||
rows = await sor.sqlExe(sql, {'user_id': user_id})
|
rows = await sor.sqlExe(sql, {'user_id': user_id})
|
||||||
if rows and len(rows) > 0:
|
if rows and len(rows) > 0:
|
||||||
config = dict(rows[0])
|
config = dict(rows[0])
|
||||||
# Convert string booleans to actual booleans for UI
|
|
||||||
config['enable_cross_session_search'] = config.get('enable_cross_session_search', '1') == '1'
|
config['enable_cross_session_search'] = config.get('enable_cross_session_search', '1') == '1'
|
||||||
config['enable_skill_auto_loading'] = config.get('enable_skill_auto_loading', '1') == '1'
|
config['enable_skill_auto_loading'] = config.get('enable_skill_auto_loading', '1') == '1'
|
||||||
config['enable_error_recovery'] = config.get('enable_error_recovery', '1') == '1'
|
config['enable_error_recovery'] = config.get('enable_error_recovery', '1') == '1'
|
||||||
@ -32,7 +31,15 @@ try:
|
|||||||
'safety_mode': 'strict',
|
'safety_mode': 'strict',
|
||||||
'max_context_tokens': 4000,
|
'max_context_tokens': 4000,
|
||||||
'enable_error_recovery': True,
|
'enable_error_recovery': True,
|
||||||
'max_recovery_attempts': 3
|
'max_recovery_attempts': 3,
|
||||||
|
'model_name': 'qwen3-max',
|
||||||
|
'model_provider': 'openrouter',
|
||||||
|
'api_key': '',
|
||||||
|
'api_endpoint': '',
|
||||||
|
'temperature': 0.7,
|
||||||
|
'max_output_tokens': 4096,
|
||||||
|
'top_p': 0.9,
|
||||||
|
'system_prompt': ''
|
||||||
}
|
}
|
||||||
result['success'] = True
|
result['success'] = True
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""Save reasoning configuration for current user"""
|
"""Save reasoning configuration for current user (includes model config)"""
|
||||||
import json, uuid, time
|
import json, uuid, time
|
||||||
|
|
||||||
result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': 'Invalid request', 'type': 'error'}}
|
result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': 'Invalid request', 'type': 'error'}}
|
||||||
@ -10,6 +10,7 @@ try:
|
|||||||
user_id = await get_user()
|
user_id = await get_user()
|
||||||
now = time.strftime('%Y-%m-%d %H:%M:%S')
|
now = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
|
||||||
|
# Reasoning engine params
|
||||||
max_reasoning_steps = int(params_kw.get('max_reasoning_steps', 10))
|
max_reasoning_steps = int(params_kw.get('max_reasoning_steps', 10))
|
||||||
max_tool_calls_per_step = int(params_kw.get('max_tool_calls_per_step', 5))
|
max_tool_calls_per_step = int(params_kw.get('max_tool_calls_per_step', 5))
|
||||||
enable_cross_session_search = '1' if params_kw.get('enable_cross_session_search') == '1' else '0'
|
enable_cross_session_search = '1' if params_kw.get('enable_cross_session_search') == '1' else '0'
|
||||||
@ -19,8 +20,17 @@ try:
|
|||||||
enable_error_recovery = '1' if params_kw.get('enable_error_recovery') == '1' else '0'
|
enable_error_recovery = '1' if params_kw.get('enable_error_recovery') == '1' else '0'
|
||||||
max_recovery_attempts = int(params_kw.get('max_recovery_attempts', 3))
|
max_recovery_attempts = int(params_kw.get('max_recovery_attempts', 3))
|
||||||
|
|
||||||
|
# Model configuration
|
||||||
|
model_name = params_kw.get('model_name', 'qwen3-max').strip()
|
||||||
|
model_provider = params_kw.get('model_provider', 'openrouter').strip()
|
||||||
|
api_key = params_kw.get('api_key', '').strip()
|
||||||
|
api_endpoint = params_kw.get('api_endpoint', '').strip()
|
||||||
|
temperature = float(params_kw.get('temperature', 0.7))
|
||||||
|
max_output_tokens = int(params_kw.get('max_output_tokens', 4096))
|
||||||
|
top_p = float(params_kw.get('top_p', 0.9))
|
||||||
|
system_prompt = params_kw.get('system_prompt', '').strip()
|
||||||
|
|
||||||
async with DBPools().sqlorContext(dbname) as sor:
|
async with DBPools().sqlorContext(dbname) as sor:
|
||||||
# Check if config exists
|
|
||||||
rows = await sor.sqlExe("SELECT id FROM harnessed_reasoning_config WHERE user_id = ${user_id}$", {'user_id': user_id})
|
rows = await sor.sqlExe("SELECT id FROM harnessed_reasoning_config WHERE user_id = ${user_id}$", {'user_id': user_id})
|
||||||
|
|
||||||
if rows and len(rows) > 0:
|
if rows and len(rows) > 0:
|
||||||
@ -34,6 +44,14 @@ try:
|
|||||||
max_context_tokens = ${max_context_tokens}$,
|
max_context_tokens = ${max_context_tokens}$,
|
||||||
enable_error_recovery = ${enable_error_recovery}$,
|
enable_error_recovery = ${enable_error_recovery}$,
|
||||||
max_recovery_attempts = ${max_recovery_attempts}$,
|
max_recovery_attempts = ${max_recovery_attempts}$,
|
||||||
|
model_name = ${model_name}$,
|
||||||
|
model_provider = ${model_provider}$,
|
||||||
|
api_key = ${api_key}$,
|
||||||
|
api_endpoint = ${api_endpoint}$,
|
||||||
|
temperature = ${temperature}$,
|
||||||
|
max_output_tokens = ${max_output_tokens}$,
|
||||||
|
top_p = ${top_p}$,
|
||||||
|
system_prompt = ${system_prompt}$,
|
||||||
updated_at = ${updated_at}$
|
updated_at = ${updated_at}$
|
||||||
WHERE id = ${id}$""", {
|
WHERE id = ${id}$""", {
|
||||||
'id': config_id,
|
'id': config_id,
|
||||||
@ -45,6 +63,14 @@ try:
|
|||||||
'max_context_tokens': max_context_tokens,
|
'max_context_tokens': max_context_tokens,
|
||||||
'enable_error_recovery': enable_error_recovery,
|
'enable_error_recovery': enable_error_recovery,
|
||||||
'max_recovery_attempts': max_recovery_attempts,
|
'max_recovery_attempts': max_recovery_attempts,
|
||||||
|
'model_name': model_name,
|
||||||
|
'model_provider': model_provider,
|
||||||
|
'api_key': api_key,
|
||||||
|
'api_endpoint': api_endpoint,
|
||||||
|
'temperature': temperature,
|
||||||
|
'max_output_tokens': max_output_tokens,
|
||||||
|
'top_p': top_p,
|
||||||
|
'system_prompt': system_prompt,
|
||||||
'updated_at': now
|
'updated_at': now
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
@ -53,10 +79,14 @@ try:
|
|||||||
(id, user_id, max_reasoning_steps, max_tool_calls_per_step,
|
(id, user_id, max_reasoning_steps, max_tool_calls_per_step,
|
||||||
enable_cross_session_search, enable_skill_auto_loading, safety_mode,
|
enable_cross_session_search, enable_skill_auto_loading, safety_mode,
|
||||||
max_context_tokens, enable_error_recovery, max_recovery_attempts,
|
max_context_tokens, enable_error_recovery, max_recovery_attempts,
|
||||||
|
model_name, model_provider, api_key, api_endpoint,
|
||||||
|
temperature, max_output_tokens, top_p, system_prompt,
|
||||||
created_at, updated_at)
|
created_at, updated_at)
|
||||||
VALUES (${id}$, ${user_id}$, ${max_reasoning_steps}$, ${max_tool_calls_per_step}$,
|
VALUES (${id}$, ${user_id}$, ${max_reasoning_steps}$, ${max_tool_calls_per_step}$,
|
||||||
${enable_cross_session_search}$, ${enable_skill_auto_loading}$, ${safety_mode}$,
|
${enable_cross_session_search}$, ${enable_skill_auto_loading}$, ${safety_mode}$,
|
||||||
${max_context_tokens}$, ${enable_error_recovery}$, ${max_recovery_attempts}$,
|
${max_context_tokens}$, ${enable_error_recovery}$, ${max_recovery_attempts}$,
|
||||||
|
${model_name}$, ${model_provider}$, ${api_key}$, ${api_endpoint}$,
|
||||||
|
${temperature}$, ${max_output_tokens}$, ${top_p}$, ${system_prompt}$,
|
||||||
${created_at}$, ${updated_at}$)""", {
|
${created_at}$, ${updated_at}$)""", {
|
||||||
'id': config_id,
|
'id': config_id,
|
||||||
'user_id': user_id,
|
'user_id': user_id,
|
||||||
@ -68,6 +98,14 @@ try:
|
|||||||
'max_context_tokens': max_context_tokens,
|
'max_context_tokens': max_context_tokens,
|
||||||
'enable_error_recovery': enable_error_recovery,
|
'enable_error_recovery': enable_error_recovery,
|
||||||
'max_recovery_attempts': max_recovery_attempts,
|
'max_recovery_attempts': max_recovery_attempts,
|
||||||
|
'model_name': model_name,
|
||||||
|
'model_provider': model_provider,
|
||||||
|
'api_key': api_key,
|
||||||
|
'api_endpoint': api_endpoint,
|
||||||
|
'temperature': temperature,
|
||||||
|
'max_output_tokens': max_output_tokens,
|
||||||
|
'top_p': top_p,
|
||||||
|
'system_prompt': system_prompt,
|
||||||
'created_at': now,
|
'created_at': now,
|
||||||
'updated_at': now
|
'updated_at': now
|
||||||
})
|
})
|
||||||
|
|||||||
61
wwwroot/api/reasoning_submit.dspy
Normal file
61
wwwroot/api/reasoning_submit.dspy
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Submit reasoning request and return results"""
|
||||||
|
import json, time, uuid
|
||||||
|
|
||||||
|
result = {'widgettype': 'Message', 'options': {'title': 'Error', 'message': '推理请求失败', 'type': 'error'}}
|
||||||
|
|
||||||
|
try:
|
||||||
|
request_text = params_kw.get('request', '').strip()
|
||||||
|
if not request_text:
|
||||||
|
result['options'] = {'title': 'Error', 'message': '请输入推理请求', 'type': 'error'}
|
||||||
|
else:
|
||||||
|
user_id = await get_user()
|
||||||
|
execute_immediately = params_kw.get('execute_immediately', '1') == '1'
|
||||||
|
|
||||||
|
# Call the reasoning engine from ServerEnv
|
||||||
|
reasoning_result = await hermes_reason_and_execute(
|
||||||
|
request=request_text,
|
||||||
|
execute_immediately=execute_immediately
|
||||||
|
)
|
||||||
|
|
||||||
|
if reasoning_result.get('success'):
|
||||||
|
# Build result widget showing reasoning output
|
||||||
|
plan_items = []
|
||||||
|
for step in reasoning_result.get('execution_plan', []):
|
||||||
|
plan_items.append(f"步骤{step.get('step_number', '?')}: {step.get('description', '')}")
|
||||||
|
|
||||||
|
plan_text = '\n'.join(plan_items) if plan_items else '无执行计划'
|
||||||
|
safety_text = '\n'.join(reasoning_result.get('safety_violations', [])) or '无安全风险'
|
||||||
|
|
||||||
|
summary = (
|
||||||
|
f"请求: {request_text}\n\n"
|
||||||
|
f"上下文: {reasoning_result.get('context_summary', '无')}\n\n"
|
||||||
|
f"置信度: {reasoning_result.get('confidence_score', 0):.0%}\n\n"
|
||||||
|
f"执行计划:\n{plan_text}\n\n"
|
||||||
|
f"安全检查:\n{safety_text}\n\n"
|
||||||
|
f"状态: {reasoning_result.get('status', 'unknown')}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if reasoning_result.get('execution_results'):
|
||||||
|
summary += f"\n\n执行结果:\n{json.dumps(reasoning_result['execution_results'], ensure_ascii=False, indent=2)}"
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'widgettype': 'Message',
|
||||||
|
'options': {
|
||||||
|
'title': '推理完成',
|
||||||
|
'message': summary,
|
||||||
|
'type': 'success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
result['options'] = {
|
||||||
|
'title': '推理失败',
|
||||||
|
'message': reasoning_result.get('error', '未知错误'),
|
||||||
|
'type': 'error'
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
result['options'] = {'title': 'Error', 'message': '推理异常: ' + str(e), 'type': 'error'}
|
||||||
|
|
||||||
|
return json.dumps(result, ensure_ascii=False)
|
||||||
@ -1,14 +1,21 @@
|
|||||||
{
|
{
|
||||||
|
"widgettype": "TabPanel",
|
||||||
|
"options": {
|
||||||
|
"tab_pos": "top",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "reasoning_config",
|
||||||
|
"label": "推理引擎",
|
||||||
|
"icon": "settings",
|
||||||
|
"content": {
|
||||||
"widgettype": "VBox",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"width": "100%",
|
|
||||||
"height": "100%",
|
|
||||||
"padding": "16px"
|
"padding": "16px"
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "Form",
|
"widgettype": "Form",
|
||||||
"id": "config_form",
|
"id": "engine_config_form",
|
||||||
"options": {
|
"options": {
|
||||||
"data_url": "{{entire_url('api/config_get.dspy')}}",
|
"data_url": "{{entire_url('api/config_get.dspy')}}",
|
||||||
"data_method": "GET",
|
"data_method": "GET",
|
||||||
@ -29,14 +36,10 @@
|
|||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "enable_cross_session_search",
|
"name": "max_context_tokens",
|
||||||
"label": "启用跨会话搜索",
|
"label": "最大上下文 token 数",
|
||||||
"uitype": "check"
|
"uitype": "int",
|
||||||
},
|
"required": true
|
||||||
{
|
|
||||||
"name": "enable_skill_auto_loading",
|
|
||||||
"label": "启用技能自动加载",
|
|
||||||
"uitype": "check"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "safety_mode",
|
"name": "safety_mode",
|
||||||
@ -50,10 +53,14 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "max_context_tokens",
|
"name": "enable_cross_session_search",
|
||||||
"label": "最大上下文 token 数",
|
"label": "启用跨会话搜索",
|
||||||
"uitype": "int",
|
"uitype": "check"
|
||||||
"required": true
|
},
|
||||||
|
{
|
||||||
|
"name": "enable_skill_auto_loading",
|
||||||
|
"label": "启用技能自动加载",
|
||||||
|
"uitype": "check"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "enable_error_recovery",
|
"name": "enable_error_recovery",
|
||||||
@ -70,7 +77,7 @@
|
|||||||
"buttons": [
|
"buttons": [
|
||||||
{
|
{
|
||||||
"type": "submit",
|
"type": "submit",
|
||||||
"label": "保存配置",
|
"label": "保存引擎配置",
|
||||||
"variant": "primary"
|
"variant": "primary"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -87,3 +94,107 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "model_config",
|
||||||
|
"label": "模型配置",
|
||||||
|
"icon": "code",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"padding": "16px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Form",
|
||||||
|
"id": "model_config_form",
|
||||||
|
"options": {
|
||||||
|
"data_url": "{{entire_url('api/config_get.dspy')}}",
|
||||||
|
"data_method": "GET",
|
||||||
|
"submit_url": "{{entire_url('api/config_save.dspy')}}",
|
||||||
|
"method": "POST",
|
||||||
|
"layout": "vertical",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "model_name",
|
||||||
|
"label": "模型名称",
|
||||||
|
"uitype": "text",
|
||||||
|
"required": true,
|
||||||
|
"placeholder": "qwen3-max, claude-sonnet-4, gpt-4o..."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "model_provider",
|
||||||
|
"label": "模型提供商",
|
||||||
|
"uitype": "code",
|
||||||
|
"required": true,
|
||||||
|
"data": [
|
||||||
|
{"value": "openrouter", "text": "OpenRouter"},
|
||||||
|
{"value": "anthropic", "text": "Anthropic"},
|
||||||
|
{"value": "dashscope", "text": "Dashscope (阿里云)"},
|
||||||
|
{"value": "openai", "text": "OpenAI"},
|
||||||
|
{"value": "custom", "text": "自定义"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "api_key",
|
||||||
|
"label": "API Key",
|
||||||
|
"uitype": "password",
|
||||||
|
"required": false,
|
||||||
|
"placeholder": "输入 API Key"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "api_endpoint",
|
||||||
|
"label": "API Endpoint (可选)",
|
||||||
|
"uitype": "text",
|
||||||
|
"placeholder": "留空使用默认端点"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "temperature",
|
||||||
|
"label": "Temperature (0.0-1.0)",
|
||||||
|
"uitype": "float",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "max_output_tokens",
|
||||||
|
"label": "最大输出 token 数",
|
||||||
|
"uitype": "int",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "top_p",
|
||||||
|
"label": "Top-p (0.0-1.0)",
|
||||||
|
"uitype": "float",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "system_prompt",
|
||||||
|
"label": "系统提示词模板",
|
||||||
|
"uitype": "textarea",
|
||||||
|
"rows": 4,
|
||||||
|
"placeholder": "留空使用默认系统提示词"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buttons": [
|
||||||
|
{
|
||||||
|
"type": "submit",
|
||||||
|
"label": "保存模型配置",
|
||||||
|
"variant": "primary"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"maxWidth": "500px"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "submited",
|
||||||
|
"actiontype": "script",
|
||||||
|
"script": "await bricks.show_resp_message_or_error(event.params)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
"widgettype": "Text",
|
"widgettype": "Text",
|
||||||
"options": {
|
"options": {
|
||||||
"text": "Reasoning Engine",
|
"text": "Reasoning Engine",
|
||||||
"css": "ios-navbar-title",
|
|
||||||
"fontSize": "18px",
|
"fontSize": "18px",
|
||||||
"fontWeight": "bold",
|
"fontWeight": "bold",
|
||||||
"color": "#1E40AF"
|
"color": "#1E40AF"
|
||||||
@ -24,8 +23,7 @@
|
|||||||
{
|
{
|
||||||
"widgettype": "Text",
|
"widgettype": "Text",
|
||||||
"options": {
|
"options": {
|
||||||
"text": "Manage sessions and system configuration",
|
"text": "AI reasoning and execution planning",
|
||||||
"css": "ios-navbar-subtitle",
|
|
||||||
"fontSize": "12px",
|
"fontSize": "12px",
|
||||||
"color": "#6B7280"
|
"color": "#6B7280"
|
||||||
}
|
}
|
||||||
@ -39,6 +37,17 @@
|
|||||||
"tab_pos": "top",
|
"tab_pos": "top",
|
||||||
"css": "tabpanel",
|
"css": "tabpanel",
|
||||||
"items": [
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "console",
|
||||||
|
"label": "推理控制台",
|
||||||
|
"icon": "terminal",
|
||||||
|
"content": {
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('reasoning_console.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "sessions",
|
"name": "sessions",
|
||||||
"label": "推理会话",
|
"label": "推理会话",
|
||||||
@ -52,7 +61,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "config",
|
"name": "config",
|
||||||
"label": "推理配置",
|
"label": "配置管理",
|
||||||
"icon": "settings",
|
"icon": "settings",
|
||||||
"content": {
|
"content": {
|
||||||
"widgettype": "urlwidget",
|
"widgettype": "urlwidget",
|
||||||
|
|||||||
@ -14,6 +14,21 @@
|
|||||||
"name":"hermes_reasoning",
|
"name":"hermes_reasoning",
|
||||||
"label":"推理控制台",
|
"label":"推理控制台",
|
||||||
"url":"{{entire_url('hermes_reasoning.ui')}}"
|
"url":"{{entire_url('hermes_reasoning.ui')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"reasoning_console",
|
||||||
|
"label":"推理交互",
|
||||||
|
"url":"{{entire_url('reasoning_console.ui')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"reasoning_sessions",
|
||||||
|
"label":"推理会话",
|
||||||
|
"url":"{{entire_url('harnessed_reasoning_sessions_crud')}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"reasoning_config",
|
||||||
|
"label":"推理配置",
|
||||||
|
"url":"{{entire_url('harnessed_reasoning_config_view')}}"
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
]
|
]
|
||||||
|
|||||||
86
wwwroot/reasoning_console.ui
Normal file
86
wwwroot/reasoning_console.ui
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"height": "100%",
|
||||||
|
"padding": "16px",
|
||||||
|
"spacing": "16px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "推理控制台",
|
||||||
|
"fontSize": "20px",
|
||||||
|
"fontWeight": "bold",
|
||||||
|
"color": "#1E40AF"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Form",
|
||||||
|
"id": "reasoning_form",
|
||||||
|
"options": {
|
||||||
|
"submit_url": "{{entire_url('api/reasoning_submit.dspy')}}",
|
||||||
|
"method": "POST",
|
||||||
|
"layout": "vertical",
|
||||||
|
"fields": [
|
||||||
|
{
|
||||||
|
"name": "request",
|
||||||
|
"label": "推理请求",
|
||||||
|
"uitype": "textarea",
|
||||||
|
"required": true,
|
||||||
|
"rows": 4,
|
||||||
|
"placeholder": "请输入您的请求,例如:分析当前项目的安全问题并生成修复方案"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "execute_immediately",
|
||||||
|
"label": "提交后立即执行(否则仅生成计划)",
|
||||||
|
"uitype": "check",
|
||||||
|
"checked": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buttons": [
|
||||||
|
{
|
||||||
|
"type": "submit",
|
||||||
|
"label": "开始推理",
|
||||||
|
"variant": "primary"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"maxWidth": "700px"
|
||||||
|
},
|
||||||
|
"binds": [
|
||||||
|
{
|
||||||
|
"wid": "self",
|
||||||
|
"event": "submited",
|
||||||
|
"actiontype": "script",
|
||||||
|
"script": "await bricks.show_resp_message_or_error(event.params)"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"padding": "16px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Text",
|
||||||
|
"options": {
|
||||||
|
"text": "历史推理记录",
|
||||||
|
"fontSize": "16px",
|
||||||
|
"fontWeight": "bold",
|
||||||
|
"color": "#374151",
|
||||||
|
"marginBottom": "8px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url('harnessed_reasoning_sessions_crud')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user