From dc5a59e3a2ec455fe815b8d20afea5d91deb121c Mon Sep 17 00:00:00 2001 From: "liuzihan.23" Date: Wed, 24 Jun 2026 16:19:56 +0800 Subject: [PATCH] [feat][evaluation] support a2a_agent and custom_agent eval target types on OpenAPI experiment-create path The web link already supports A2A Agent (a2a_agent, type=9) and the in-house long-connection agent (custom_agent, type=10), and the execution operators are registered downstream. The OpenAPI experiment-create path, however, rejected these two types: mapOpenAPIEvalTargetType only cased 6 types, so a2a_agent / custom_agent fell through to default and were blocked both by the up-front SubmitExperimentOApi validation and by the convertor. This wires the OpenAPI path to the same service layer the web link uses: - mapOpenAPIEvalTargetType: add cases a2a_agent -> A2AAgent, custom_agent -> CustomAgent. - supportedOpenAPIEvalTargetTypes: add both so the up-front validation and the error message stay in sync. No IDL change (the OpenAPI string enums and EvalTargetContent sub-fields already exist) and no operator change (already registered in the commercial DI). Meego: 7337555141 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../convertor/experiment/openapi.go | 6 +++ .../convertor/experiment/openapi_test.go | 51 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/backend/modules/evaluation/application/convertor/experiment/openapi.go b/backend/modules/evaluation/application/convertor/experiment/openapi.go index 63d5b88a43..cc31b7ce3d 100644 --- a/backend/modules/evaluation/application/convertor/experiment/openapi.go +++ b/backend/modules/evaluation/application/convertor/experiment/openapi.go @@ -226,6 +226,8 @@ var supportedOpenAPIEvalTargetTypes = []openapiEvalTarget.EvalTargetType{ openapiEvalTarget.EvalTargetTypeCozeWorkflow, openapiEvalTarget.EvalTargetTypeVolcengineAgent, openapiEvalTarget.EvalTargetTypeCustomRPCServer, + openapiEvalTarget.EvalTargetTypeA2Agent, + openapiEvalTarget.EvalTargetTypeCustomAgent, } func supportedOpenAPIEvalTargetTypesString() string { @@ -260,6 +262,10 @@ func mapOpenAPIEvalTargetType(openapiType openapiEvalTarget.EvalTargetType) (dom return domaindoEvalTarget.EvalTargetType_VolcengineAgent, nil case openapiEvalTarget.EvalTargetTypeCustomRPCServer: return domaindoEvalTarget.EvalTargetType_CustomRPCServer, nil + case openapiEvalTarget.EvalTargetTypeA2Agent: + return domaindoEvalTarget.EvalTargetType_A2AAgent, nil + case openapiEvalTarget.EvalTargetTypeCustomAgent: + return domaindoEvalTarget.EvalTargetType_CustomAgent, nil default: return 0, fmt.Errorf("unsupported eval target type: %s. supported: [%s]", openapiType, supportedOpenAPIEvalTargetTypesString()) } diff --git a/backend/modules/evaluation/application/convertor/experiment/openapi_test.go b/backend/modules/evaluation/application/convertor/experiment/openapi_test.go index f8dbb8fa16..cb1b1aa7fa 100755 --- a/backend/modules/evaluation/application/convertor/experiment/openapi_test.go +++ b/backend/modules/evaluation/application/convertor/experiment/openapi_test.go @@ -278,6 +278,8 @@ func TestMapOpenAPIEvalTargetType(t *testing.T) { {"workflow", openapiEvalTarget.EvalTargetTypeCozeWorkflow, domaindoEvalTarget.EvalTargetType_CozeWorkflow, false}, {"volcengine", openapiEvalTarget.EvalTargetTypeVolcengineAgent, domaindoEvalTarget.EvalTargetType_VolcengineAgent, false}, {"rpc", openapiEvalTarget.EvalTargetTypeCustomRPCServer, domaindoEvalTarget.EvalTargetType_CustomRPCServer, false}, + {"a2a_agent", openapiEvalTarget.EvalTargetTypeA2Agent, domaindoEvalTarget.EvalTargetType_A2AAgent, false}, + {"custom_agent", openapiEvalTarget.EvalTargetTypeCustomAgent, domaindoEvalTarget.EvalTargetType_CustomAgent, false}, {"invalid", openapiEvalTarget.EvalTargetType("invalid"), 0, true}, } @@ -2975,6 +2977,55 @@ func TestOpenAPICreateEvalTargetParamDTO2Domain_WithClusterAndAgentConnection(t } } +// TestOpenAPICreateEvalTargetParamDTO2Domain_AgentTypes verifies the OpenAPI +// experiment-create path accepts the two agent eval target types that the web +// link already supports: a2a_agent (type=9) and custom_agent (type=10, the +// in-house long-connection agent). The convertor must translate the string +// type to the int domain enum and carry the agent connection info. +func TestOpenAPICreateEvalTargetParamDTO2Domain_AgentTypes(t *testing.T) { + t.Parallel() + + // custom_agent (长链接 Agent): submitted with cluster + agent_connection. + customAgentType := openapiEvalTarget.EvalTargetTypeCustomAgent + customAgentParam := &openapi.SubmitExperimentEvalTargetParam{ + SourceTargetID: gptr.Of("custom-agent-1"), + EvalTargetType: &customAgentType, + Cluster: gptr.Of("cluster-loong"), + AgentConnection: &openapiEvalTarget.AgentConnection{ + Psm: gptr.Of("agent.psm"), + FrontierInfo: &openapiEvalTarget.FrontierInfo{ + AppID: gptr.Of(int64(100)), + }, + }, + } + convertedCustom, errCustom := OpenAPICreateEvalTargetParamDTO2Domain(customAgentParam) + assert.NoError(t, errCustom) + if assert.NotNil(t, convertedCustom) { + assert.Equal(t, domaindoEvalTarget.EvalTargetType_CustomAgent, gptr.Indirect(convertedCustom.EvalTargetType)) + assert.Equal(t, gptr.Of("cluster-loong"), convertedCustom.Cluster) + if assert.NotNil(t, convertedCustom.AgentConnection) { + assert.Equal(t, gptr.Of("agent.psm"), convertedCustom.AgentConnection.Psm) + } + } + + // a2a_agent: referenced by source_target_id (pre-registered Application). + a2aType := openapiEvalTarget.EvalTargetTypeA2Agent + a2aParam := &openapi.SubmitExperimentEvalTargetParam{ + SourceTargetID: gptr.Of("a2a-agent-1"), + EvalTargetType: &a2aType, + } + convertedA2A, errA2A := OpenAPICreateEvalTargetParamDTO2Domain(a2aParam) + assert.NoError(t, errA2A) + if assert.NotNil(t, convertedA2A) { + assert.Equal(t, domaindoEvalTarget.EvalTargetType_A2AAgent, gptr.Indirect(convertedA2A.EvalTargetType)) + assert.Equal(t, "a2a-agent-1", gptr.Indirect(convertedA2A.SourceTargetID)) + } + + // Both agent types must pass the up-front validation gate. + assert.True(t, IsSupportedOpenAPIEvalTargetType(openapiEvalTarget.EvalTargetTypeA2Agent)) + assert.True(t, IsSupportedOpenAPIEvalTargetType(openapiEvalTarget.EvalTargetTypeCustomAgent)) +} + func TestOpenapiAgentConnectionDTO2Domain_Nil(t *testing.T) { t.Parallel() assert.Nil(t, openapiAgentConnectionDTO2Domain(nil))