Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9404e22
initial remote agent crd translation setup
inFocus7 Aug 27, 2025
a9dd0a3
add remote agent to agent creation ui
inFocus7 Aug 27, 2025
e201039
update message handler to display finalized messages that are not inc…
inFocus7 Aug 27, 2025
d9a9286
create new recording task manager for remote agent a2a chat storage
inFocus7 Aug 27, 2025
74cf718
reverse requirements of agent card v. agent server
inFocus7 Aug 28, 2025
cf3b890
return error on createErrorResponse so errors don't get ignored
inFocus7 Aug 28, 2025
c5b74ce
add error on remote agent-as-tool request
inFocus7 Aug 28, 2025
79d1cc9
store remote agent card in database to preview agent information
inFocus7 Aug 28, 2025
3529d3c
Merge branch 'main' into feat/remote-agent-type
inFocus7 Sep 10, 2025
5422baa
minor code fixes - post merge
inFocus7 Sep 15, 2025
63c0f56
Merge branch 'main' into feat/remote-agent-type
inFocus7 Sep 15, 2025
699cbd7
store metadata for remote agents (e.g. token usage) and support stric…
inFocus7 Sep 15, 2025
6205b9e
add (failing) remote agent testing
inFocus7 Sep 15, 2025
71305ca
read x-user-id in e2e remote agent setup
inFocus7 Sep 16, 2025
f3f6dad
fix up remote agent e2e test + simplify recording manager to simply s…
inFocus7 Sep 16, 2025
4b2a73c
remove comment + console log
inFocus7 Sep 16, 2025
ecaff46
update Makefile to push remote Agent for e2e test
inFocus7 Sep 16, 2025
b5a47a9
add todo
inFocus7 Sep 16, 2025
1ad4330
Merge branch 'main' into feat/remote-agent-type
inFocus7 Sep 17, 2025
5b38f8c
remove unecessary messageHandler additions
inFocus7 Sep 17, 2025
e3598a9
update e2e remote test + clean up messageHandlers.ts
inFocus7 Sep 17, 2025
9a645ad
add message case with basic log
inFocus7 Sep 17, 2025
9578013
pr feedback: get pre-existing session before creating + remove dbClie…
inFocus7 Sep 17, 2025
ffb208f
match session check logic between OnSendMessage and OnSendMessageStream
inFocus7 Sep 17, 2025
6674a25
move network request for remote agent from translator to reconciler
inFocus7 Sep 18, 2025
aa2c5f1
support remote-agent-as-tool
inFocus7 Sep 18, 2025
808db25
simplify remote definition to remove url overwrite - resolves a2a iss…
inFocus7 Sep 18, 2025
594c639
wip
peterj Sep 18, 2025
15801b4
Merge branch 'main' into pr/inFocus7/821
peterj Sep 18, 2025
3b0c818
wip
peterj Sep 19, 2025
ccffd74
fix issue with creating remote agents through the ui
peterj Sep 19, 2025
43f6c7b
set the agent name, ui fixes
peterj Sep 19, 2025
f5e1a48
fix: remove external remote translation
EItanya Sep 22, 2025
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
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,12 @@ build-all: buildx-create

.PHONY: push-test-agent
push-test-agent: build-kagent-adk
@echo "Pushing BYO test Agent"
$(DOCKER_BUILDER) build --push --build-arg DOCKER_REGISTRY=$(DOCKER_REGISTRY) --build-arg VERSION=$(VERSION) -t $(DOCKER_REGISTRY)/kebab:latest -f go/test/e2e/agents/kebab/Dockerfile ./go/test/e2e/agents/kebab
kubectl apply --namespace kagent --context kind-$(KIND_CLUSTER_NAME) -f go/test/e2e/agents/kebab/agent.yaml
@echo "Pushing Remote test Agent"
$(DOCKER_BUILDER) build --push --build-arg DOCKER_REGISTRY=$(DOCKER_REGISTRY) --build-arg VERSION=$(VERSION) -t $(DOCKER_REGISTRY)/remote-kebab:latest -f go/test/e2e/agents/remote-kebab/Dockerfile ./go/test/e2e/agents/remote-kebab
kubectl apply --namespace kagent --context kind-$(KIND_CLUSTER_NAME) -f go/test/e2e/agents/remote-kebab/agent.yaml

.PHONY: create-kind-cluster
create-kind-cluster:
Expand Down
18 changes: 14 additions & 4 deletions go/api/v1alpha2/agent_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,30 @@ import (
)

// AgentType represents the agent type
// +kubebuilder:validation:Enum=Declarative;BYO
// +kubebuilder:validation:Enum=Declarative;BYO;Remote
type AgentType string

const (
AgentType_Declarative AgentType = "Declarative"
AgentType_BYO AgentType = "BYO"
AgentType_Remote AgentType = "Remote"
)

// AgentSpec defines the desired state of Agent.
// +kubebuilder:validation:XValidation:message="type must be specified",rule="has(self.type)"
// +kubebuilder:validation:XValidation:message="type must be either Declarative or BYO",rule="self.type == 'Declarative' || self.type == 'BYO'"
// +kubebuilder:validation:XValidation:message="declarative must be specified if type is Declarative, or byo must be specified if type is BYO",rule="(self.type == 'Declarative' && has(self.declarative)) || (self.type == 'BYO' && has(self.byo))"
// +kubebuilder:validation:XValidation:message="type must be either Declarative, BYO, or Remote",rule="self.type == 'Declarative' || self.type == 'BYO' || self.type == 'Remote'"
// +kubebuilder:validation:XValidation:message="declarative must be specified if type is Declarative, or byo must be specified if type is BYO, or remote must be specified if type is Remote",rule="(self.type == 'Declarative' && has(self.declarative)) || (self.type == 'BYO' && has(self.byo)) || (self.type == 'Remote' && has(self.remote))"
type AgentSpec struct {
// +kubebuilder:validation:Enum=Declarative;BYO
// +kubebuilder:validation:Enum=Declarative;BYO;Remote
// +kubebuilder:default=Declarative
Type AgentType `json:"type"`

// +optional
BYO *BYOAgentSpec `json:"byo,omitempty"`
// +optional
Declarative *DeclarativeAgentSpec `json:"declarative,omitempty"`
// +optional
Remote *RemoteAgentSpec `json:"remote,omitempty"`

// +optional
Description string `json:"description,omitempty"`
Expand Down Expand Up @@ -111,6 +114,13 @@ type ByoDeploymentSpec struct {
SharedDeploymentSpec `json:",inline"`
}

type RemoteAgentSpec struct {
// DiscoveryURL is the URL of the agent server.
// The Agent Card is infered from the well known path.
// +kubebuilder:validation:MinLength=1
DiscoveryURL string `json:"discoveryUrl,omitempty"`
}

type SharedDeploymentSpec struct {
// If not specified, the default value is 1.
// +optional
Expand Down
20 changes: 20 additions & 0 deletions go/api/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion go/cli/internal/cli/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,3 @@ func checkHelmAvailable() error {
}
return nil
}

24 changes: 19 additions & 5 deletions go/config/crd/bases/kagent.dev_agents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6779,7 +6779,8 @@ spec:
If not specified, the default value is true.
type: boolean
systemMessage:
minLength: 1
description: SystemMessage is a string specifying the system message
for the agent
type: string
systemMessageFrom:
description: SystemMessageFrom is a reference to a ConfigMap or
Expand Down Expand Up @@ -6905,14 +6906,25 @@ spec:
rule: '!has(self.systemMessage) || !has(self.systemMessageFrom)'
description:
type: string
remote:
properties:
discoveryUrl:
description: |-
DiscoveryURL is the URL of the agent server.
The Agent Card is infered from the well known path.
minLength: 1
type: string
type: object
type:
allOf:
- enum:
- Declarative
- BYO
- Remote
- enum:
- Declarative
- BYO
- Remote
default: Declarative
description: AgentType represents the agent type
type: string
Expand All @@ -6922,12 +6934,14 @@ spec:
x-kubernetes-validations:
- message: type must be specified
rule: has(self.type)
- message: type must be either Declarative or BYO
rule: self.type == 'Declarative' || self.type == 'BYO'
- message: type must be either Declarative, BYO, or Remote
rule: self.type == 'Declarative' || self.type == 'BYO' || self.type
== 'Remote'
- message: declarative must be specified if type is Declarative, or byo
must be specified if type is BYO
must be specified if type is BYO, or remote must be specified if type
is Remote
rule: (self.type == 'Declarative' && has(self.declarative)) || (self.type
== 'BYO' && has(self.byo))
== 'BYO' && has(self.byo)) || (self.type == 'Remote' && has(self.remote))
status:
description: AgentStatus defines the observed state of Agent.
properties:
Expand Down
104 changes: 51 additions & 53 deletions go/config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,54 @@ kind: ClusterRole
metadata:
name: manager-role
rules:
- apiGroups:
- ""
resources:
- configmaps
- secrets
- services
verbs:
- get
- list
- watch
- apiGroups:
- kagent.dev
resources:
- agents
- memories
- modelconfigs
- remotemcpservers
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- kagent.dev
resources:
- agents/finalizers
- memories/finalizers
- modelconfigs/finalizers
- remotemcpservers/finalizers
verbs:
- update
- apiGroups:
- kagent.dev
resources:
- agents/status
- memories/status
- modelconfigs/status
- remotemcpservers/status
verbs:
- get
- patch
- update
- apiGroups:
- kagent.dev
resources:
- mcpservers
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- kagent.dev
resources:
- agents
- memories
- modelconfigs
- remotemcpservers
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- kagent.dev
resources:
- agents/finalizers
- memories/finalizers
- modelconfigs/finalizers
- remotemcpservers/finalizers
verbs:
- update
- apiGroups:
- kagent.dev
resources:
- agents/status
- memories/status
- modelconfigs/status
- remotemcpservers/status
verbs:
- get
- patch
- update
- apiGroups:
- kagent.dev
resources:
- mcpservers
verbs:
- get
- list
- watch
18 changes: 16 additions & 2 deletions go/internal/a2a/a2a_handler_mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import (
"sync"

"github.com/gorilla/mux"
"github.com/kagent-dev/kagent/go/api/v1alpha2"
"github.com/kagent-dev/kagent/go/internal/database"
authimpl "github.com/kagent-dev/kagent/go/internal/httpserver/auth"
common "github.com/kagent-dev/kagent/go/internal/utils"
"github.com/kagent-dev/kagent/go/pkg/auth"
"trpc.group/trpc-go/trpc-a2a-go/client"
"trpc.group/trpc-go/trpc-a2a-go/server"
"trpc.group/trpc-go/trpc-a2a-go/taskmanager"
)

// A2AHandlerMux is an interface that defines methods for adding, getting, and removing agentic task handlers.
Expand All @@ -19,6 +22,7 @@ type A2AHandlerMux interface {
agentRef string,
client *client.A2AClient,
card server.AgentCard,
agentType v1alpha2.AgentType,
) error
RemoveAgentHandler(
agentRef string,
Expand All @@ -31,24 +35,34 @@ type handlerMux struct {
lock sync.RWMutex
basePathPrefix string
authenticator auth.AuthProvider
dbClient database.Client
}

var _ A2AHandlerMux = &handlerMux{}

func NewA2AHttpMux(pathPrefix string, authenticator auth.AuthProvider) *handlerMux {
func NewA2AHttpMux(pathPrefix string, authenticator auth.AuthProvider, dbClient database.Client) *handlerMux {
return &handlerMux{
handlers: make(map[string]http.Handler),
basePathPrefix: pathPrefix,
authenticator: authenticator,
dbClient: dbClient,
}
}

func (a *handlerMux) SetAgentHandler(
agentRef string,
client *client.A2AClient,
card server.AgentCard,
agentType v1alpha2.AgentType,
) error {
srv, err := server.NewA2AServer(card, NewPassthroughManager(client), server.WithMiddleWare(authimpl.NewA2AAuthenticator(a.authenticator)))
var manager taskmanager.TaskManager
if agentType == v1alpha2.AgentType_Remote {
manager = NewRecordingManager(client, a.dbClient, agentRef)
} else {
manager = NewPassthroughManager(client)
}

srv, err := server.NewA2AServer(card, manager, server.WithMiddleWare(authimpl.NewA2AAuthenticator(a.authenticator)))
if err != nil {
return fmt.Errorf("failed to create A2A server: %w", err)
}
Expand Down
2 changes: 2 additions & 0 deletions go/internal/a2a/a2a_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ func ExtractText(message protocol.Message) string {
for _, part := range message.Parts {
if textPart, ok := part.(*protocol.TextPart); ok {
builder.WriteString(textPart.Text)
} else if textPart, ok := part.(protocol.TextPart); ok {
builder.WriteString(textPart.Text)
}
}
return builder.String()
Expand Down
File renamed without changes.
Loading