mirror of
https://github.com/langgenius/dify.git
synced 2026-09-19 10:11:30 +08:00
fix(agent-v2): accept composer UI ids on manual metadata filter conditions (#40171)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
autofix-ci[bot]
parent
d362bdbb4e
commit
2a742486c5
@@ -836,7 +836,12 @@ def _knowledge_metadata_filtering_config(
|
||||
return DifyKnowledgeMetadataFilteringConfig(
|
||||
mode=metadata_filtering.mode,
|
||||
model_config=_knowledge_model_config(metadata_filtering.metadata_model_config),
|
||||
conditions=cast(Any, metadata_filtering.conditions.model_dump(mode="json"))
|
||||
conditions=cast(
|
||||
Any,
|
||||
metadata_filtering.conditions.model_dump(
|
||||
mode="json", exclude={"conditions": {"__all__": {"id", "metadata_id"}}}
|
||||
),
|
||||
)
|
||||
if metadata_filtering.conditions is not None
|
||||
else None,
|
||||
)
|
||||
|
||||
@@ -420,8 +420,19 @@ class AgentKnowledgeRetrievalConfig(BaseModel):
|
||||
|
||||
|
||||
class AgentKnowledgeMetadataCondition(BaseModel):
|
||||
"""One manual metadata filter clause.
|
||||
|
||||
``id`` and ``metadata_id`` are UI-only bookkeeping the composer sends on
|
||||
every save (a stable row key and a reference to the selected metadata
|
||||
field). They are persisted here for round-tripping the composer's draft
|
||||
state but are stripped before building the Agent runtime request, whose
|
||||
DTO only accepts ``name``/``comparison_operator``/``value``.
|
||||
"""
|
||||
|
||||
model_config = ConfigDict(extra="forbid")
|
||||
|
||||
id: str | None = None
|
||||
metadata_id: str | None = None
|
||||
name: str = Field(min_length=1, max_length=255)
|
||||
comparison_operator: SupportedComparisonOperator
|
||||
value: ConditionValue = None
|
||||
|
||||
@@ -14302,9 +14302,19 @@ the current roster/workflow APIs scoped to Dify Agent.
|
||||
|
||||
#### AgentKnowledgeMetadataCondition
|
||||
|
||||
One manual metadata filter clause.
|
||||
|
||||
``id`` and ``metadata_id`` are UI-only bookkeeping the composer sends on
|
||||
every save (a stable row key and a reference to the selected metadata
|
||||
field). They are persisted here for round-tripping the composer's draft
|
||||
state but are stripped before building the Agent runtime request, whose
|
||||
DTO only accepts ``name``/``comparison_operator``/``value``.
|
||||
|
||||
| Name | Type | Description | Required |
|
||||
| ---- | ---- | ----------- | -------- |
|
||||
| comparison_operator | string, <br>**Available values:** "<", "=", ">", "after", "before", "contains", "empty", "end with", "in", "is", "is not", "not contains", "not empty", "not in", "start with", "≠", "≤", "≥" | *Enum:* `"<"`, `"="`, `">"`, `"after"`, `"before"`, `"contains"`, `"empty"`, `"end with"`, `"in"`, `"is"`, `"is not"`, `"not contains"`, `"not empty"`, `"not in"`, `"start with"`, `"≠"`, `"≤"`, `"≥"` | Yes |
|
||||
| id | string | | No |
|
||||
| metadata_id | string | | No |
|
||||
| name | string | | Yes |
|
||||
| value | string<br>[ string ]<br>number | | No |
|
||||
|
||||
|
||||
@@ -744,7 +744,13 @@ def test_build_maps_agent_soul_knowledge_to_knowledge_layer_config():
|
||||
"conditions": {
|
||||
"logical_operator": "and",
|
||||
"conditions": [
|
||||
{"name": "category", "comparison_operator": "contains", "value": "auth"}
|
||||
{
|
||||
"id": "cond-1",
|
||||
"metadata_id": "meta-1",
|
||||
"name": "category",
|
||||
"comparison_operator": "contains",
|
||||
"value": "auth",
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -365,6 +365,51 @@ def test_knowledge_runtime_requirements_block_publish_but_not_draft_save(knowled
|
||||
ComposerConfigValidator.validate_publish_payload(publish_payload)
|
||||
|
||||
|
||||
def test_manual_metadata_filtering_condition_accepts_composer_ui_identifiers():
|
||||
"""The composer's condition editor always sends ``id`` (list row key) and
|
||||
``metadata_id`` (selected metadata field reference) alongside every
|
||||
condition. Rejecting them as unknown fields broke every save of a manual
|
||||
metadata filter (see GH issue #40169)."""
|
||||
payload = ComposerSavePayload.model_validate(
|
||||
{
|
||||
"variant": ComposerVariant.AGENT_APP,
|
||||
"save_strategy": ComposerSaveStrategy.SAVE_TO_CURRENT_VERSION,
|
||||
"agent_soul": {
|
||||
"knowledge": {
|
||||
"sets": [
|
||||
{
|
||||
"id": "support",
|
||||
"name": "Support KB",
|
||||
"datasets": [{"id": "dataset-1"}],
|
||||
"query": {"mode": "generated_query"},
|
||||
"retrieval": {"mode": "multiple", "top_k": 4},
|
||||
"metadata_filtering": {
|
||||
"mode": "manual",
|
||||
"conditions": {
|
||||
"logical_operator": "and",
|
||||
"conditions": [
|
||||
{
|
||||
"id": "b149eceb-191a-40a2-9f11-61cf21ebd147",
|
||||
"metadata_id": "ad6cf326-eadf-46e8-a2d5-9cb892d2cc84",
|
||||
"name": "category",
|
||||
"comparison_operator": "is",
|
||||
"value": "auth",
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
condition = payload.agent_soul.knowledge.sets[0].metadata_filtering.conditions.conditions[0]
|
||||
assert condition.id == "b149eceb-191a-40a2-9f11-61cf21ebd147"
|
||||
assert condition.metadata_id == "ad6cf326-eadf-46e8-a2d5-9cb892d2cc84"
|
||||
|
||||
|
||||
def test_agent_soul_model_config_is_first_class_without_credentials():
|
||||
config = AgentSoulConfig(
|
||||
model=AgentSoulModelConfig(
|
||||
|
||||
Reference in New Issue
Block a user