fix: validate rule for provider scoped credentials (#41659)

This commit is contained in:
Yunlu Wen authored and GitHub committed 2026-09-02 10:07:44 +00:00
1 parent a1a10f17e3
commit b1eafb0d82
2 files changed
+47 -1

No files matched your search

+3 -1
View File
@@ -705,7 +705,9 @@ class AgentSoulDifyToolConfig(BaseModel):
if not self.provider_id and not (self.plugin_id and self.provider):
raise ValueError("Dify tool requires provider_id or plugin_id + provider")
if self.credential_type != "unauthorized" and (self.credential_ref is None or not self.credential_ref.id):
raise ValueError("credential_ref.id is required for credentialed Dify tools")
# credential resolved by provider_id, see ``ToolManager``
if self.provider_type not in {ToolProviderType.API, ToolProviderType.WORKFLOW}:
raise ValueError("credential_ref.id is required for credentialed Dify tools")
# ``name`` is reserved for a future user-rename UX. Until that lands
# the model-visible name is forced to match ``tool_name``; reject
# explicit values so a frontend bug surfaces immediately instead of
@@ -923,6 +923,50 @@ def test_rejects_unknown_provider_type_at_config_boundary():
)
@pytest.mark.parametrize("provider_type", ["api", "workflow"])
def test_provider_scoped_tool_accepts_authorized_without_credential_id(provider_type: str):
"""``api`` / ``workflow`` credentials live on the provider record, so the
runtime resolves them from ``provider_id`` alone. An authorized tool of
these types must validate without a fabricated ``credential_ref.id``."""
config = AgentSoulToolsConfig.model_validate(
{
"dify_tools": [
{
"provider_id": "api-provider-1",
"provider_type": provider_type,
"tool_name": "get_pet",
"credential_type": "api-key",
}
]
}
)
tool = config.dify_tools[0]
# No id is invented; the provider_id already locates the credential.
assert tool.credential_ref is None
assert tool.credential_type == "api-key"
@pytest.mark.parametrize("provider_type", ["plugin", "builtin"])
def test_tool_scoped_provider_still_requires_credential_id(provider_type: str):
"""Tool-level credential providers (plugin / builtin) select a specific
stored secret, so an authorized tool without a ``credential_ref.id`` is
still rejected at the config boundary."""
with pytest.raises(ValueError, match="credential_ref.id is required"):
AgentSoulToolsConfig.model_validate(
{
"dify_tools": [
{
"provider_id": "langgenius/search/search",
"provider_type": provider_type,
"tool_name": "search",
"credential_type": "api-key",
}
]
}
)
# ── provider-level entries (tool_name omitted = all tools of the provider) ───