mirror of
https://github.com/langgenius/dify.git
synced 2026-05-31 22:26:19 +08:00
Adds POST /console/api/apps/<id>/agent-features, a dedicated write surface for an Agent App's PRD "Misc Legacy" presentation features. The legacy /model-config endpoint also writes model / prompt / agent tools, which an Agent App owns through its Soul, so reusing it would be semantically wrong and let a caller override Soul-owned config. AgentAppFeatureConfigService validates only the allowed feature subset (opening_statement, suggested_questions, suggested_questions_after_answer, speech_to_text, text_to_speech, retriever_resource, sensitive_word_avoidance), fills disabled/empty defaults, and writes a new app_model_config version with model / prompt / agent_mode left NULL. Soul-owned keys (model, pre_prompt, agent_mode, tools, user_input_form) are dropped, so App.is_agent stays False and the app mode is never mutated. Live-verified: posting opener + follow-up + citations (with model/agent_mode smuggled in) persists a new config row with model=None/agent_mode=None, surfaces through /v1/parameters, keeps mode=agent, and streaming chat still works. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
81 lines
3.7 KiB
Python
81 lines
3.7 KiB
Python
"""Agent App presentation-feature configuration endpoint.
|
|
|
|
The new Agent App type keeps model / prompt / tools in its bound Agent Soul, so
|
|
the legacy ``/model-config`` surface (which writes model, prompt and agent tool
|
|
config) is the wrong place to configure its app-level presentation features.
|
|
This endpoint exposes only the PRD "Misc Legacy" feature subset — conversation
|
|
opener, follow-up suggestions, citations, content moderation and speech — and
|
|
persists them onto the app's ``app_model_config`` without touching anything the
|
|
Soul owns.
|
|
"""
|
|
|
|
from typing import Any
|
|
|
|
from flask_restx import Resource
|
|
from pydantic import BaseModel, Field
|
|
|
|
from controllers.common.fields import SimpleResultResponse
|
|
from controllers.common.schema import register_response_schema_models, register_schema_models
|
|
from controllers.console import console_ns
|
|
from controllers.console.app.wraps import get_app_model
|
|
from controllers.console.wraps import account_initialization_required, edit_permission_required, setup_required
|
|
from events.app_event import app_model_config_was_updated
|
|
from libs.login import current_account_with_tenant, login_required
|
|
from models.model import App, AppMode
|
|
from services.agent_app_feature_service import AgentAppFeatureConfigService
|
|
|
|
|
|
class AgentAppFeaturesRequest(BaseModel):
|
|
"""Presentation features configurable on an Agent App.
|
|
|
|
All fields are optional; an omitted field is reset to its disabled/empty
|
|
default (the config form sends the full desired feature state on save).
|
|
"""
|
|
|
|
opening_statement: str | None = Field(default=None, description="Conversation opener shown before the first turn")
|
|
suggested_questions: list[str] | None = Field(
|
|
default=None, description="Preset questions shown alongside the opener"
|
|
)
|
|
suggested_questions_after_answer: dict[str, Any] | None = Field(
|
|
default=None, description="Follow-up suggestions config, e.g. {'enabled': true}"
|
|
)
|
|
speech_to_text: dict[str, Any] | None = Field(default=None, description="Speech-to-text config")
|
|
text_to_speech: dict[str, Any] | None = Field(default=None, description="Text-to-speech config")
|
|
retriever_resource: dict[str, Any] | None = Field(
|
|
default=None, description="Citations / attributions config, e.g. {'enabled': true}"
|
|
)
|
|
sensitive_word_avoidance: dict[str, Any] | None = Field(default=None, description="Content moderation config")
|
|
|
|
|
|
register_schema_models(console_ns, AgentAppFeaturesRequest)
|
|
register_response_schema_models(console_ns, SimpleResultResponse)
|
|
|
|
|
|
@console_ns.route("/apps/<uuid:app_id>/agent-features")
|
|
class AgentAppFeatureConfigResource(Resource):
|
|
@console_ns.doc("update_agent_app_features")
|
|
@console_ns.doc(description="Update an Agent App's presentation features (opener, follow-up, citations, ...)")
|
|
@console_ns.doc(params={"app_id": "Application ID"})
|
|
@console_ns.expect(console_ns.models[AgentAppFeaturesRequest.__name__])
|
|
@console_ns.response(200, "Features updated successfully", console_ns.models[SimpleResultResponse.__name__])
|
|
@console_ns.response(400, "Invalid configuration")
|
|
@console_ns.response(404, "App not found")
|
|
@setup_required
|
|
@login_required
|
|
@edit_permission_required
|
|
@account_initialization_required
|
|
@get_app_model(mode=[AppMode.AGENT])
|
|
def post(self, app_model: App):
|
|
args = AgentAppFeaturesRequest.model_validate(console_ns.payload)
|
|
current_user, _ = current_account_with_tenant()
|
|
|
|
new_app_model_config = AgentAppFeatureConfigService.update_features(
|
|
app_model=app_model,
|
|
account=current_user,
|
|
config=args.model_dump(exclude_none=True),
|
|
)
|
|
|
|
app_model_config_was_updated.send(app_model, app_model_config=new_app_model_config)
|
|
|
|
return {"result": "success"}
|