From 1af535a1738d4c43af7583e0df9ce677cfd78834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=8E=AE=20=28Jade=20Lin=29?= Date: Thu, 2 Jul 2026 15:07:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(agent-v2):=20preserve=20oauth2=20credential?= =?UTF-8?q?=20refs=20when=20converting=20tool=20c=E2=80=A6=20(#38303)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent-composer/__tests__/store.spec.ts | 73 +++++++++++++++++++ .../agent-v2/agent-composer/conversions.ts | 19 +++-- 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/web/features/agent-v2/agent-composer/__tests__/store.spec.ts b/web/features/agent-v2/agent-composer/__tests__/store.spec.ts index 17483a2560d..de441d8fcba 100644 --- a/web/features/agent-v2/agent-composer/__tests__/store.spec.ts +++ b/web/features/agent-v2/agent-composer/__tests__/store.spec.ts @@ -382,6 +382,79 @@ describe('agent composer store conversions', () => { ]) }) + it('should preserve oauth2 credential references when saving tool config', () => { + const baseConfig = { + tools: { + dify_tools: [ + { + provider: 'google', + provider_id: 'google', + provider_type: 'builtin', + tool_name: 'search', + credential_type: 'oauth2', + credential_ref: { + id: 'credential-oauth', + provider: 'google', + type: 'provider', + }, + }, + ], + }, + } satisfies AgentSoulConfig + const formState = agentSoulConfigToFormState(baseConfig) + const publishConfig = formStateToAgentSoulConfig({ baseConfig, formState }) + + expect(formState.tools).toEqual([ + expect.objectContaining({ + credentialId: 'credential-oauth', + credentialType: 'oauth2', + credentialVariant: 'authorized', + }), + ]) + expect(publishConfig.tools?.dify_tools).toEqual([ + expect.objectContaining({ + credential_type: 'oauth2', + credential_ref: { + id: 'credential-oauth', + provider: 'google', + type: 'provider', + }, + }), + ]) + }) + + it('should not save credentialed tool config without a credential reference', () => { + const baseConfig = { + tools: { + dify_tools: [ + { + provider: 'google', + provider_id: 'google', + provider_type: 'builtin', + tool_name: 'search', + credential_type: 'oauth2', + }, + ], + }, + } satisfies AgentSoulConfig + const formState = agentSoulConfigToFormState(baseConfig) + const publishConfig = formStateToAgentSoulConfig({ baseConfig, formState }) + + expect(formState.tools).toEqual([ + expect.objectContaining({ + credentialId: undefined, + credentialType: 'oauth2', + credentialVariant: 'unauthorized', + }), + ]) + expect(publishConfig.tools?.dify_tools).toEqual([ + expect.objectContaining({ + credential_type: 'unauthorized', + credential_ref: undefined, + }), + ]) + }) + it('should derive model plugin_id from the selected provider when publishing', () => { const publishConfig = formStateToAgentSoulConfig({ baseConfig: { diff --git a/web/features/agent-v2/agent-composer/conversions.ts b/web/features/agent-v2/agent-composer/conversions.ts index 9ca67a2a1a4..9e9ec8c359c 100644 --- a/web/features/agent-v2/agent-composer/conversions.ts +++ b/web/features/agent-v2/agent-composer/conversions.ts @@ -171,13 +171,18 @@ const toToolRuntimeParameters = (settings: Record | undefined) const getDifyToolActionId = (tool: AgentSoulDifyToolConfig) => `${tool.provider_id ?? tool.provider ?? tool.plugin_id ?? 'provider'}:${tool.tool_name ?? tool.name ?? 'tool'}` -const toCredentialVariant = (credentialType: AgentSoulDifyToolConfig['credential_type']) => { - if (credentialType === 'api-key') - return 'authorized' as const +const toCredentialVariant = (tool: AgentSoulDifyToolConfig) => { + const credentialType = tool.credential_type if (credentialType === 'unauthorized') return 'unauthorized' as const + if (tool.credential_ref?.id) + return 'authorized' as const + + if (credentialType === 'api-key' || credentialType === 'oauth2') + return 'unauthorized' as const + return 'none' as const } @@ -222,7 +227,7 @@ const toProviderToolFormState = (config?: AgentSoulConfig): { ? 'agentDetail.configure.tools.credential.authOne' : undefined, credentialType: tool.credential_type, - credentialVariant: toCredentialVariant(tool.credential_type), + credentialVariant: toCredentialVariant(tool), actions: [action], }) } @@ -240,6 +245,10 @@ const toDifyToolConfigs = ( if (tool.kind !== 'provider') return [] + const credentialType = tool.credentialId + ? tool.credentialType ?? 'api-key' + : 'unauthorized' + return tool.actions.map(action => ({ enabled: true, provider: tool.name, @@ -247,7 +256,7 @@ const toDifyToolConfigs = ( provider_type: tool.providerType ?? 'builtin', tool_name: action.toolName, runtime_parameters: toToolRuntimeParameters(toolSettings[action.id]), - credential_type: tool.credentialType ?? (tool.credentialVariant === 'authorized' ? 'api-key' as const : 'unauthorized' as const), + credential_type: credentialType, credential_ref: tool.credentialId ? { id: tool.credentialId,