Skip to content

feat: add declarative workflow subagents (Sequential, Parallel, Loop)#1743

Open
jsonmp-k8 wants to merge 7 commits intokagent-dev:mainfrom
jsonmp-k8:feat/workflow-subagents
Open

feat: add declarative workflow subagents (Sequential, Parallel, Loop)#1743
jsonmp-k8 wants to merge 7 commits intokagent-dev:mainfrom
jsonmp-k8:feat/workflow-subagents

Conversation

@jsonmp-k8
Copy link
Copy Markdown
Contributor

Summary

  • Add declarative workflow patterns (Sequential, Parallel, Loop) to the Agent CRD, enabling deterministic multi-agent orchestration via YAML
  • Sub-agents run in-process within a single pod, sharing session state — powered by Google ADK's SequentialAgent, ParallelAgent, and LoopAgent
  • Each sub-agent can have its own system message, model config, and MCP tools
  • Both Python and Go runtimes fully supported

Example

apiVersion: kagent.dev/v1alpha2
kind: Agent
metadata:
  name: writer-critic
spec:
  type: Declarative
  description: Sequential write-then-review workflow
  declarative:
    modelConfig: default-model-config
    workflow:
      type: Sequential
      subAgents:
        - name: writer
          systemMessage: You are a creative writer.
        - name: critic
          systemMessage: You are a writing critic. Review and improve the content.

Changes

Layer Files What
Design doc design/EP-991-workflow-subagents.md Enhancement proposal
CRD go/api/v1alpha2/agent_types.go WorkflowSpec, InlineAgentSpec, WorkflowType + CEL validation
CRD codegen zz_generated.deepcopy.go, CRD YAML bases Auto-generated
ADK types go/api/adk/types.go WorkflowAgentConfig, SubAgentConfig
Translator compiler.go, adk_api_translator.go translateWorkflowAgent, translateMCPServerTool, validation
Python runtime types.py _build_workflow_agent(), _build_sub_agent()
Go runtime agent.go, adapter.go CreateWorkflowAgent(), createInProcessSubAgent()
Tests Golden tests (sequential, loop) + Python unit tests (6 cases) Full coverage

Closes #991

Test plan

  • All 35 translator golden tests pass (including 2 new workflow tests)
  • 6 Python unit tests pass (sequential, parallel, loop, loop-no-max, unknown-type, no-workflow)
  • golangci-lint passes with 0 issues
  • gofmt clean on all changed files
  • Deploy a Sequential workflow agent to a cluster and verify sub-agents execute in order
  • Deploy a Loop workflow agent and verify it exits on escalation or max iterations

Copilot AI review requested due to automatic review settings April 24, 2026 04:26
@github-actions github-actions Bot added enhancement-proposal Indicates that this PR is for an enhancement proposal enhancement New feature or request labels Apr 24, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class declarative workflow orchestration to the Agent CRD (Sequential / Parallel / Loop) and wires it through the translator and both runtimes so in-process sub-agents can be defined via YAML and executed deterministically.

Changes:

  • Extend the v1alpha2 Agent CRD with workflow (type + inline subAgents + optional maxIterations) plus validations and codegen updates.
  • Update the Go translator to emit workflow-aware ADK config and add golden test fixtures for sequential + loop workflows.
  • Add Python and Go runtime support to construct ADK workflow agents from the translated config, plus Python unit tests.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
python/packages/kagent-adk/tests/unittests/test_workflow_agents.py Adds unit tests validating workflow agent construction (sequential/parallel/loop).
python/packages/kagent-adk/src/kagent/adk/types.py Introduces workflow/sub-agent config types and builds ADK workflow agents/sub-agents.
go/core/internal/controller/translator/agent/testdata/outputs/agent_with_workflow_sequential.json Golden output for sequential workflow translation.
go/core/internal/controller/translator/agent/testdata/outputs/agent_with_workflow_loop.json Golden output for loop workflow translation (with max_iterations).
go/core/internal/controller/translator/agent/testdata/inputs/agent_with_workflow_sequential.yaml Golden input YAML for sequential workflow Agent.
go/core/internal/controller/translator/agent/testdata/inputs/agent_with_workflow_loop.yaml Golden input YAML for loop workflow Agent.
go/core/internal/controller/translator/agent/compiler.go Adds workflow validation + translation path and sub-agent MCP tool translation.
go/core/internal/controller/translator/agent/adk_api_translator.go Factors MCP server translation into a reusable helper returning tool configs.
go/api/v1alpha2/zz_generated.deepcopy.go Generated deepcopy updates for new workflow-related types/fields.
go/api/v1alpha2/agent_types.go CRD type additions: WorkflowSpec, InlineAgentSpec, WorkflowType, plus CEL validation.
go/api/config/crd/bases/kagent.dev_sandboxagents.yaml Generated CRD schema update to include workflow.
go/api/config/crd/bases/kagent.dev_agents.yaml Generated CRD schema update to include workflow.
go/api/adk/types.go Adds workflow JSON config types and embeds them into AgentConfig.
go/adk/pkg/runner/adapter.go Routes workflow configs to a workflow-agent creation path.
go/adk/pkg/agent/agent.go Implements CreateWorkflowAgent and in-process sub-agent creation for Go runtime.
design/EP-991-workflow-subagents.md Design/EP document describing the feature, constraints, and examples.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread python/packages/kagent-adk/src/kagent/adk/types.py
Comment thread python/packages/kagent-adk/src/kagent/adk/types.py
Comment on lines +316 to +321
def to_agent(self, name: str, sts_integration: Optional[ADKTokenPropagationPlugin] = None) -> BaseAgent:
if self.workflow is not None:
return self._build_workflow_agent(name, sts_integration)
return self._build_llm_agent(name, sts_integration)

def _build_llm_agent(self, name: str, sts_integration: Optional[ADKTokenPropagationPlugin] = None) -> Agent:
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When workflow is set, to_agent() returns _build_workflow_agent() and bypasses _build_llm_agent(), so memory configuration is never applied (no memory tools injected and no auto-save callback). Either explicitly disallow memory for workflow agents at the schema/validation layer, or propagate/apply memory configuration to workflow sub-agents.

Copilot uses AI. Check for mistakes.
Comment thread go/api/v1alpha2/agent_types.go Outdated
Comment thread go/core/internal/controller/translator/agent/compiler.go
Comment thread go/adk/pkg/runner/adapter.go
Copy link
Copy Markdown
Contributor

@jeffspahr jeffspahr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found two workflow-agent issues that should be fixed before merge. I also noticed a Helm values-path regression in my fetched PR worktree, but GitHub's current PR diff does not include helm/kagent/Chart-template.yaml, so I could not attach that as an inline comment here.

Verification performed:

  • go test ./core/internal/controller/translator/agent ./adk/pkg/agent ./adk/pkg/runner passed.
  • cd python && uv run --extra dev pytest packages/kagent-adk/tests/unittests/test_workflow_agents.py -q passed.
  • Manual Python repro confirmed content-writer is accepted by the CRD shape but rejected by ADK runtime as an invalid agent name.

Comment thread go/adk/pkg/agent/agent.go
Comment thread go/api/v1alpha2/agent_types.go
Add support for declarative workflow patterns that deterministically
orchestrate in-process sub-agents using Google ADK's SequentialAgent,
ParallelAgent, and LoopAgent primitives.

Sub-agents are defined inline within the parent Agent CRD and run
in-process within the same pod, sharing session state. Each sub-agent
can have its own system message, model config, and MCP tools.

Changes:
- CRD: Add WorkflowSpec, InlineAgentSpec types with CEL validation
- ADK types: Add WorkflowAgentConfig, SubAgentConfig for runtime config
- Translator: Add translateWorkflowAgent with model/tool resolution
- Python runtime: Refactor to_agent() to dispatch workflow agents
- Go runtime: Add CreateWorkflowAgent() with all three workflow types
- Tests: Golden tests for sequential/loop, Python unit tests

Closes kagent-dev#991

Signed-off-by: Jaison Paul <paul.jaison@gmail.com>
Import BaseAgent at module level instead of using deferred string
annotations that ruff cannot resolve.

Signed-off-by: Jaison Paul <paul.jaison@gmail.com>
- Add tool approval handling (before_tool_callback, before_model_callback)
  to workflow sub-agents so require_approval is enforced
- Add AskUserTool() to workflow sub-agents so they can ask clarifying
  questions like regular agents
- Add CEL validation making workflow mutually exclusive with memory,
  context, and executeCodeBlocks to prevent silent feature dropping
- Fix maxIterations doc comment: when unset, loop runs indefinitely
  until a sub-agent escalates (not defaulting to 10)

Signed-off-by: Jaison Paul <paul.jaison@gmail.com>
Signed-off-by: Jaison Paul <paul.jaison@gmail.com>
Signed-off-by: Jaison Paul <paul.jaison@gmail.com>
- Wire MakeApprovalCallback, tool logging callbacks, and
  MakeStripConfirmationPartsCallback into Go workflow sub-agents
  so requireApproval is enforced (matching regular agent behavior)
- Add CRD pattern validation on InlineAgentSpec.Name requiring valid
  Python identifiers (^[A-Za-z_][A-Za-z0-9_]*$) to reject names
  like "content-writer" at admission time instead of runtime

Signed-off-by: Jaison Paul <paul.jaison@gmail.com>
Copy link
Copy Markdown
Contributor

@supreme-gg-gg supreme-gg-gg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First doing a high level review, but we should definitely discuss this (and the following points) during community meeting.

  1. Workflow agents are fundamentally different type of agent from LLM agent, embedding its configuration inside DeclarativeAgent CRD doesn't seem good to me. I personally prefer an API that provides a separate agent type like WorkflowAgentSpec

  2. What is the expected UX when a user continues a chat session with a workflow agent after the initial invocation? kagent’s UI is primarily interactive/chat-oriented, but workflow agents seem closer to single-run pipelines. FYI this was something I noticed when adding CrewAI before, which is also workflow-oriented. Could be something to discuss next

  3. I'm mildly surprised at how this will work since I don't see you setting things like output_key and exit_loop which is required for sequential and loop to work properly according to the docs? Subsequently, how to let users configure these (to share / pass state and to terminal execution) will be another point of discussion.

@supreme-gg-gg supreme-gg-gg self-assigned this Apr 24, 2026
@dimetron
Copy link
Copy Markdown
Contributor

First thank you @jsonmp-k8 @jeffspahr - this is very relevant and important PR. I would like to see how we could cover all scenarios and patterns as described here: https://developers.googleblog.com/developers-guide-to-multi-agent-patterns-in-adk/

In addition I'd like to see how we could cover dynamic FanOut cases.

Few comments:

    1. No state passing between sub‑agents. ADK's Sequential/Loop patterns are useless without output_key + {state_key}
    1. No loop termination mechanism. How to escalate / exit_loop or maxIterations
    1. No hierarchical / routing pattern. Where a central LlmAgent (Coordinator) manages several specialized sub_agents
    1. Workflow Agents can be nested within one another, for example placing a Parallel Agent inside a Sequential Agent.
    1. Embedding under DeclarativeAgentSpec is the wrong shape. @supreme-gg-gg is right: a workflow agent has no system message, no memory, no context, no tools at the parent level
    1. Chat‑session UX is undefined. Multi‑turn semantics for an in‑process pipeline need a deliberate answer (rerun pipeline? resume from sub‑agent? fork session?).

@EItanya
Copy link
Copy Markdown
Contributor

EItanya commented Apr 30, 2026

I agree that we should allow for nested sub-agents, up to some sane default, maybe 10 levels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request enhancement-proposal Indicates that this PR is for an enhancement proposal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Implement Workflow Subagents with ADK Patterns

6 participants