Add Agent capabilities and configurations across the application

- Extend the AssistantConfig model to include agent_interface_type, agent_values, and agent_secrets for enhanced agent management.
- Update ModelType to include "Agent" for broader capability support.
- Seed new agent models and configurations in the database for Dify, FastGPT, and OpenCode applications.
- Modify the Assistant routes to validate and handle agent capabilities.
- Implement agent resource resolution in the config resolver for runtime configuration.
- Enhance the interface catalog with agent-specific fields and definitions.
- Update frontend components to manage agent configurations, including form handling and state management for agent-related inputs.
This commit is contained in:
Xin Wang
2026-07-09 15:29:25 +08:00
parent 03478fa557
commit 54329aa516
11 changed files with 238 additions and 114 deletions

View File

@@ -33,6 +33,36 @@ async def _resource_for(
return resource
async def _agent_resource_for(
session: AsyncSession,
assistant_id: str,
interface_type: str,
) -> ModelResource | None:
if interface_type not in {"dify", "fastgpt", "opencode"}:
return None
binding = await session.get(AssistantModelBinding, (assistant_id, "Agent"))
resource_id = binding.model_resource_id if binding else None
resource = await session.get(ModelResource, resource_id) if resource_id else None
if (
resource
and resource.capability == "Agent"
and resource.interface_type == interface_type
):
return resource
return (
await session.execute(
select(ModelResource)
.where(
ModelResource.capability == "Agent",
ModelResource.interface_type == interface_type,
ModelResource.enabled.is_(True),
)
.order_by(ModelResource.is_default.desc(), ModelResource.id.asc())
.limit(1)
)
).scalar_one_or_none()
def _value(resource: ModelResource | None, key: str, default):
if not resource:
return default
@@ -58,6 +88,7 @@ async def resolve_runtime_config(
stt_resource = await _resource_for(session, assistant.id, "ASR")
tts_resource = await _resource_for(session, assistant.id, "TTS")
realtime_resource = await _resource_for(session, assistant.id, "Realtime")
agent_resource = await _agent_resource_for(session, assistant.id, assistant.type)
vision_resource = (
await session.get(ModelResource, assistant.vision_model_resource_id)
if assistant.vision_model_resource_id
@@ -75,9 +106,9 @@ async def resolve_runtime_config(
# workflow 图:仅 workflow 类型非空,引擎据此启用图驱动对话
graph=(assistant.graph or {}) if assistant.type == "workflow" else {},
# 外部托管类型连接信息(DB 存真 key,直接注入)
fastgpt_api_url=assistant.api_url,
fastgpt_api_key=assistant.api_key,
fastgpt_app_id=assistant.app_id,
fastgpt_api_url=str(_value(agent_resource, "apiUrl", assistant.api_url)),
fastgpt_api_key=_secret(agent_resource, "apiKey", assistant.api_key),
fastgpt_app_id=str(_value(agent_resource, "appId", assistant.app_id)),
# 模型/音色:模型资源中的配置优先
model=str(_value(llm_resource, "modelId", "")),
asr=str(_value(stt_resource, "modelId", "")),
@@ -114,6 +145,9 @@ async def resolve_runtime_config(
),
realtime_values=(realtime_resource.values or {}) if realtime_resource else {},
realtime_secrets=(realtime_resource.secrets or {}) if realtime_resource else {},
agent_interface_type=(agent_resource.interface_type if agent_resource else ""),
agent_values=(agent_resource.values or {}) if agent_resource else {},
agent_secrets=(agent_resource.secrets or {}) if agent_resource else {},
# 运行时连接信息(真 key + url):模型资源优先,否则 .env 兜底
llm_api_key=_secret(llm_resource, "apiKey", config.LLM_API_KEY),
llm_base_url=str(_value(llm_resource, "apiUrl", config.LLM_BASE_URL)),

View File

@@ -34,6 +34,10 @@ OPENAI_COMMON = [
field("apiUrl", "API URL", type_="url", required=True),
field("apiKey", "API Key", group="secrets", type_="password", required=True),
]
AGENT_COMMON = [
field("apiUrl", "API URL", type_="url", required=True),
field("apiKey", "API Key", group="secrets", type_="password", required=True),
]
XFYUN_AUTH = [
field("apiUrl", "WebSocket URL", type_="url", required=True),
field("appId", "App ID", group="secrets", type_="password", required=True),
@@ -78,6 +82,24 @@ INTERFACE_DEFINITIONS: list[dict] = [
"capability": "Realtime",
"fields": OPENAI_COMMON + [field("voice", "Voice")],
},
{
"interface_type": "dify",
"name": "Dify Agent",
"capability": "Agent",
"fields": AGENT_COMMON,
},
{
"interface_type": "fastgpt",
"name": "FastGPT Agent",
"capability": "Agent",
"fields": AGENT_COMMON + [field("appId", "App ID", required=True)],
},
{
"interface_type": "opencode",
"name": "OpenCode Agent",
"capability": "Agent",
"fields": AGENT_COMMON,
},
{
"interface_type": "stepfun-realtime",
"name": "StepFun StepAudio Realtime",