feat: add builtin agent harness provider#2236
Conversation
📝 WalkthroughWalkthroughThis PR adds support for a new "builtin" harness provider that executes Dagu's in-process agent executor, complementing existing CLI-based harness providers (codex, etc.). It includes core provider predicates, agent config parsing, builtin execution in the harness executor, chat message wiring, step runner integration for message persistence, validation updates, comprehensive tests, and documentation changes. ChangesBuilt-in Agent Harness Provider
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
internal/cmn/schema/dag.schema.json (1)
4514-4567: ⚡ Quick winClarify pass-through wording for
provider: builtinconfigs.These sections now define builtin-specific fields, but the descriptions still imply unknown/non-reserved keys are generally passed through to CLI flags. That conflicts with builtin-provider validation (allowlist-based) and can mislead users. Please scope the wording to CLI providers and explicitly note builtin keys are validated.
Also applies to: 4576-4635
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/cmn/schema/dag.schema.json` around lines 4514 - 4567, Update the descriptions for the harness provider configuration (the object keyed by "provider" with properties like "model", "tools", "memory", "max_iterations", "safe_mode", "skills", "soul", "web_search" and the "additionalProperties" referencing "harnessConfigValue") to clarify that only CLI-style providers pass unknown/non-reserved keys through as CLI flags, and explicitly state that when "provider" is "builtin" the listed keys are validated against the builtin allowlist (i.e., builtin-specific fields are validated and not blindly passed through); apply the same wording change to the equivalent block referenced around the second occurrence noted (lines 4576-4635).internal/runtime/builtin/harness/harness.go (1)
730-732: 💤 Low valueConsider using the predicate for consistency.
This uses direct string comparison with
core.HarnessProviderBuiltin, whilevalidateHarnessProviderConfigindag.gousescore.IsBuiltinAgentHarnessProvider(). Using the predicate here would ensure consistent behavior if the predicate logic ever changes (e.g., trimming, case handling).Suggested change
- if providerStr == core.HarnessProviderBuiltin { + if core.IsBuiltinAgentHarnessProvider(providerStr) { return core.ValidateBuiltinAgentHarnessConfig(cfg) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/runtime/builtin/harness/harness.go` around lines 730 - 732, The code currently compares providerStr to core.HarnessProviderBuiltin directly; update it to use the shared predicate core.IsBuiltinAgentHarnessProvider(providerStr) for consistency with validateHarnessProviderConfig in dag.go and to preserve any normalization logic; if the predicate returns true, call core.ValidateBuiltinAgentHarnessConfig(cfg) as before (keeping cfg and the same return behavior).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/core/harness.go`:
- Around line 81-103: The validation in ValidateBuiltinAgentHarnessConfig uses
builtinAgentHarnessConfigKeys with underscore names (e.g., "max_iterations") but
keys are canonicalized to kebab-case by NormalizeBuiltinHarnessFlagKeys, causing
valid keys to be rejected; fix this by either normalizing incoming cfg keys back
to the underscore form before the lookup in ValidateBuiltinAgentHarnessConfig or
by expanding builtinAgentHarnessConfigKeys to include the kebab-case equivalents
(e.g., "max-iterations", "safe-mode", "web-search"); update the check inside
ValidateBuiltinAgentHarnessConfig to perform the same normalization/mapping used
elsewhere so both formats pass.
In `@internal/runtime/builtin/harness/builtin.go`:
- Around line 59-78: After calling agentExec.Run(runCtx) in the harness, detect
parent-context cancellation by checking runCtx.Err() (or ctx.Err()) and treat it
the same as e.builtinStopped: if runCtx.Err() == context.Canceled (or ctx.Err()
== context.Canceled) set e.exitCode = 124, call cleanupStdoutSpool(stdout) and
return nil, context.Canceled; keep existing cancel() and the e.mu protected
updates to e.cancelBuiltin/e.builtinStopped, but ensure the cancellation branch
is evaluated after Run and before falling through to a successful return so the
canceled run does not return the spool as success (refer to runCtx, ctx,
agentExec.Run, e.builtinStopped, e.exitCode, cleanupStdoutSpool).
---
Nitpick comments:
In `@internal/cmn/schema/dag.schema.json`:
- Around line 4514-4567: Update the descriptions for the harness provider
configuration (the object keyed by "provider" with properties like "model",
"tools", "memory", "max_iterations", "safe_mode", "skills", "soul", "web_search"
and the "additionalProperties" referencing "harnessConfigValue") to clarify that
only CLI-style providers pass unknown/non-reserved keys through as CLI flags,
and explicitly state that when "provider" is "builtin" the listed keys are
validated against the builtin allowlist (i.e., builtin-specific fields are
validated and not blindly passed through); apply the same wording change to the
equivalent block referenced around the second occurrence noted (lines
4576-4635).
In `@internal/runtime/builtin/harness/harness.go`:
- Around line 730-732: The code currently compares providerStr to
core.HarnessProviderBuiltin directly; update it to use the shared predicate
core.IsBuiltinAgentHarnessProvider(providerStr) for consistency with
validateHarnessProviderConfig in dag.go and to preserve any normalization logic;
if the predicate returns true, call core.ValidateBuiltinAgentHarnessConfig(cfg)
as before (keeping cfg and the same return behavior).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 472cb9c6-7bc9-46d8-b2c9-212eb81db023
📒 Files selected for processing (17)
README.mdimplementation-notes.mdinternal/cmn/schema/dag.schema.jsoninternal/core/harness.gointernal/core/harness_test.gointernal/core/spec/builder_test.gointernal/core/spec/dag.gointernal/core/spec/step.gointernal/runtime/builtin/agentstep/executor.gointernal/runtime/builtin/harness/agent_config.gointernal/runtime/builtin/harness/builtin.gointernal/runtime/builtin/harness/harness.gointernal/runtime/builtin/harness/harness_test.gointernal/runtime/builtin/harness/schema.gointernal/runtime/export_test.gointernal/runtime/runner.gointernal/runtime/runner_test.go
There was a problem hiding this comment.
1 issue found across 17 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
Summary
provider: builtinforharness.runas in-process syntax sugar over the existing agent executorbuiltinis not treated as a binary-backed providerTesting
go test ./internal/core ./internal/core/spec ./internal/runtime ./internal/runtime/builtin/harness ./internal/runtime/builtin/agentstep ./internal/cmn/schema ./internal/cmd -count=1git diff --checkSummary by cubic
Adds a built-in agent provider to
harness.runviaprovider: builtin, so you can run Dagu’s agent in-process without a CLI. Includes DAG-level defaults, mixed fallbacks, strict validation, and chat history/push-back for builtin runs; README updated and implementation notes removed.New Features
provider: builtinexecutes the agent in-process by delegating to the existing agent executor (no external binary).harnessconfig can set builtin defaults; steps inherit and can override.builtinand CLI providers infallbackwith ordered execution.max-iterations,safe-mode,web-search), including nestedtools.bash_policy,memory.enabled,web_search,skills,soul,model,max_iterations,safe_mode.builtin; cancellation handling reports canceled runs correctly.implementation-notes.md.Migration
provider: builtinunderharness:or stepwith:to run the in-process agent.builtinunderharnesses:; it’s reserved and will fail validation.full-auto) are rejected withbuiltin; use agent fields likemodel,tools, andmax_iterationsinstead.Written for commit 68811a5. Summary will update on new commits.
Summary by CodeRabbit
New Features
provider: builtinin harness configuration, enabling users to run Dagu's built-in agent directly via harness actions.Documentation