Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ push-test-agent: buildx-create build-kagent-adk
kubectl apply --namespace kagent --context kind-$(KIND_CLUSTER_NAME) -f go/core/test/e2e/agents/kebab/agent.yaml
$(DOCKER_BUILDER) build --push $(BUILD_ARGS) $(TOOLS_IMAGE_BUILD_ARGS) -t $(DOCKER_REGISTRY)/poem-flow:latest -f python/samples/crewai/poem_flow/Dockerfile ./python
$(DOCKER_BUILDER) build --push $(BUILD_ARGS) $(TOOLS_IMAGE_BUILD_ARGS) -t $(DOCKER_REGISTRY)/basic-openai:latest -f python/samples/openai/basic_agent/Dockerfile ./python
$(DOCKER_BUILDER) build --push $(BUILD_ARGS) $(TOOLS_IMAGE_BUILD_ARGS) -t $(DOCKER_REGISTRY)/langgraph-currency:latest -f python/samples/langgraph/currency/Dockerfile ./python

.PHONY: push-test-skill
push-test-skill: buildx-create
Expand Down
111 changes: 102 additions & 9 deletions go/core/test/e2e/invoke_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,43 @@ func generateOpenAIAgent(baseURL string) *v1alpha2.Agent {
}
}

func generateLangGraphAgent(baseURL string) *v1alpha2.Agent {
return &v1alpha2.Agent{
ObjectMeta: metav1.ObjectMeta{
Name: "currency-converter-test",
Namespace: "kagent",
},
Spec: v1alpha2.AgentSpec{
Description: "A currency converter LangGraph agent that can convert currencies",
Type: v1alpha2.AgentType_BYO,
BYO: &v1alpha2.BYOAgentSpec{
Deployment: &v1alpha2.ByoDeploymentSpec{
Image: "localhost:5001/langgraph-currency:latest",
SharedDeploymentSpec: v1alpha2.SharedDeploymentSpec{
Env: []corev1.EnvVar{
{
Name: "OPENAI_API_KEY",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: "kagent-openai",
},
Key: "OPENAI_API_KEY",
},
},
},
{
Name: "OPENAI_API_BASE",
Value: baseURL + "/v1",
},
},
},
},
},
},
}
}

func generateCrewAIAgent(baseURL string) *v1alpha2.Agent {
return &v1alpha2.Agent{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -716,13 +753,12 @@ func TestE2EInvokeOpenAIAgent(t *testing.T) {
// Setup Kubernetes client
cli := setupK8sClient(t, false)

// Setup specific resources
modelCfg := setupModelConfig(t, cli, baseURL)
agent := generateOpenAIAgent(baseURL)

// Create the agent on the cluster
err := cli.Create(t.Context(), agent)
require.NoError(t, err)
cleanup(t, cli, agent)

// Wait for agent to be ready
args := []string{
Expand All @@ -744,11 +780,6 @@ func TestE2EInvokeOpenAIAgent(t *testing.T) {
// Poll until the A2A endpoint is actually serving requests through the proxy
waitForEndpoint(t, agent.Namespace, agent.Name)

defer func() {
cli.Delete(t.Context(), agent) //nolint:errcheck
cli.Delete(t.Context(), modelCfg) //nolint:errcheck
}()

// Setup A2A client - use the agent's actual name
a2aURL := a2aUrl("kagent", "basic-openai-test-agent")
a2aClient, err := a2aclient.NewA2AClient(a2aURL)
Expand All @@ -764,6 +795,69 @@ func TestE2EInvokeOpenAIAgent(t *testing.T) {
})
}

func TestE2EInvokeLangGraphAgent(t *testing.T) {
baseURL, stopServer := setupMockServer(t, "mocks/invoke_langgraph_agent.json")
defer stopServer()

cfg, err := config.GetConfig()
require.NoError(t, err)

scheme := k8s_runtime.NewScheme()
err = v1alpha2.AddToScheme(scheme)
require.NoError(t, err)
err = corev1.AddToScheme(scheme)
require.NoError(t, err)

cli, err := client.New(cfg, client.Options{
Scheme: scheme,
})
require.NoError(t, err)

// Clean up any leftover agent from a previous failed run
_ = cli.Delete(t.Context(), &v1alpha2.Agent{ObjectMeta: metav1.ObjectMeta{Name: "currency-converter-test", Namespace: "kagent"}})

// Generate the LangGraph agent and inject the mock server's URL
agent := generateLangGraphAgent(baseURL)

// Create the agent on the cluster
err = cli.Create(t.Context(), agent)
require.NoError(t, err)
cleanup(t, cli, agent)

// Wait for the agent to become Ready
args := []string{
"wait",
"--for",
"condition=Ready",
"--timeout=1m",
"agents.kagent.dev",
agent.Name,
"-n",
agent.Namespace,
}

cmd := exec.CommandContext(t.Context(), "kubectl", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
require.NoError(t, cmd.Run())

// Poll until the A2A endpoint is actually serving requests through the proxy
waitForEndpoint(t, agent.Namespace, agent.Name)

// Setup A2A client
a2aURL := a2aUrl(agent.Namespace, agent.Name)
a2aClient, err := a2aclient.NewA2AClient(a2aURL)
require.NoError(t, err)

t.Run("sync_invocation", func(t *testing.T) {
runSyncTest(t, a2aClient, "What is the exchange rate from USD to EUR?", "0.92", nil)
})

t.Run("streaming_invocation", func(t *testing.T) {
runStreamingTest(t, a2aClient, "What is the exchange rate from USD to EUR?", "0.92")
})
}

func TestE2EInvokeCrewAIAgent(t *testing.T) {
mockllmCfg, err := mockllm.LoadConfigFromFile("mocks/invoke_crewai_agent.json", mocks)
require.NoError(t, err)
Expand Down Expand Up @@ -802,6 +896,7 @@ func TestE2EInvokeCrewAIAgent(t *testing.T) {
// Create the agent on the cluster
err = cli.Create(t.Context(), agent)
require.NoError(t, err)
cleanup(t, cli, agent)

// Wait for the agent to become Ready
args := []string{
Expand Down Expand Up @@ -842,8 +937,6 @@ func TestE2EInvokeCrewAIAgent(t *testing.T) {
t.Run("streaming_invocation", func(t *testing.T) {
runStreamingTest(t, a2aClient, "Generate a poem about CrewAI", "CrewAI is awesome, it makes coding fun.")
})

cli.Delete(t.Context(), agent) //nolint:errcheck
}

func TestE2EInvokeSTSIntegration(t *testing.T) {
Expand Down
66 changes: 66 additions & 0 deletions go/core/test/e2e/mocks/invoke_langgraph_agent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"openai": [
{
"name": "exchange_rate_tool_call",
"match": {
"match_type": "contains",
"message": {
"content": "What is the exchange rate from USD to EUR?",
"role": "user"
}
},
"response": {
"id": "chatcmpl-langgraph-1",
"object": "chat.completion",
"created": 1677652288,
"model": "gpt-4o-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_lg001",
"type": "function",
"function": {
"name": "_get_exchange_rate",
"arguments": "{\"currency_from\": \"USD\", \"currency_to\": \"EUR\", \"currency_date\": \"latest\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
]
}
},
{
"name": "exchange_rate_tool_result",
"match": {
"match_type": "contains",
"message": {
"content": "USD",
"role": "tool"
}
},
"response": {
"id": "chatcmpl-langgraph-2",
"object": "chat.completion",
"created": 1677652289,
"model": "gpt-4o-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "The current exchange rate from USD to EUR is 0.92."
},
"finish_reason": "stop"
}
]
}
}
]
}
Loading
Loading