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:
@@ -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)),
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user