Repository navigation
feat: agents spec - #78
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (6)
📒 Files selected for processing (2)
Disabled knowledge base sources:
WalkthroughAdds a reusable-agents subsystem: embedded bundled AGENT.md fixtures, discovery/validation of AGENT.md and mcp.json across workspace/global scopes, execution-context resolution and composite system-prompt assembly, reserved MCP server construction and stdio-serving, run_agent engine with nesting/depth/cycle checks, CLI commands/flags, install flows, lifecycle events, model/ACP plumbing for MCP servers, and extensive tests. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as User/CLI
participant Registry as Agent Registry
participant ExecCtx as ExecutionContext
participant Prepare as Job Prep
participant MCP as Session MCP Builder
participant Client as Agent Client
CLI->>Registry: Discover(workspaceRoot)
Registry-->>CLI: Catalog + Problems
CLI->>ExecCtx: ResolveExecutionContext(cfg)
ExecCtx->>Registry: Resolve(agentName)
Registry-->>ExecCtx: ResolvedAgent
ExecCtx-->>Prepare: SystemPrompt, runtime defaults
Prepare->>MCP: BuildSessionMCPServers(execution, ctx)
MCP-->>Prepare: [reserved stdio, agent-local servers]
Prepare->>Client: CreateSession(prompt + MCP servers)
Client-->>Prepare: session ready / runID
sequenceDiagram
participant Parent as Parent Session
participant MCPsrv as MCP run_agent tool
participant Engine as RunAgent Engine
participant Registry as Agent Registry
participant ChildClient as Child Agent Client
Parent->>MCPsrv: call run_agent(name, input)
MCPsrv->>Engine: RunAgent(host, req)
Engine->>Registry: resolve child agent
alt resolved
Engine->>Engine: build child MCP servers (reserved + local)
Engine->>ChildClient: ExecutePreparedPrompt(child cfg, prompt, MCP list)
ChildClient-->>Engine: output + runID
Engine-->>MCPsrv: RunAgentResult{success, output, runID}
else blocked/invalid
Engine-->>MCPsrv: RunAgentResult{blocked, reason, error}
end
MCPsrv-->>Parent: tool result
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 20
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
pkg/compozy/events/docs_test.go (1)
11-56:⚠️ Potential issue | 🟠 MajorWrap each event-kind assertion in
t.Run("Should...")subtests.This test violates the mandatory guideline requiring subtests for all test cases in
*_test.gofiles. Currently, if any assertion fails witht.Fatalf(), the remaining 33 kinds are not tested. Each kind should be isolated in its own subtest witht.Parallel():Proposed refactor
func TestEventsDocumentationEnumeratesAllPublicKinds(t *testing.T) { t.Parallel() content := readEventsDocumentation(t) for _, kind := range []EventKind{ EventKindRunQueued, @@ EventKindShutdownRequested, EventKindShutdownDraining, EventKindShutdownTerminated, } { - want := "`" + string(kind) + "`" - if !strings.Contains(content, want) { - t.Fatalf("expected docs/events.md to mention %s", kind) - } + kind := kind + t.Run("Should document "+string(kind), func(t *testing.T) { + t.Parallel() + want := "`" + string(kind) + "`" + if !strings.Contains(content, want) { + t.Fatalf("expected docs/events.md to mention %s", kind) + } + }) } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pkg/compozy/events/docs_test.go` around lines 11 - 56, The test TestEventsDocumentationEnumeratesAllPublicKinds currently iterates over multiple EventKind values in a single test so a failure aborts the rest; convert the loop so each EventKind is validated inside its own subtest using t.Run with a descriptive name (e.g., the kind string), call t.Parallel() at the start of each subtest, and perform the strings.Contains check inside that subtest (keeping the same failure assertion but scoped to the subtest) to ensure each kind is tested independently and in parallel.internal/core/run/exec/exec.go (1)
237-263:⚠️ Potential issue | 🟠 MajorPersisted exec resume does not lock reusable-agent identity.
This now resolves the current
--agentand feeds its system prompt/MCP servers into the resumed job, but persisted exec compatibility still only checks IDE/model/access settings. Resuming the samerun-idwith a different agent will silently attach a different reusable-agent configuration to the existing ACP session.The fix should live in the persisted exec contract: store the resolved agent identity/config when the run starts, then reject resume when it changes. Based on learnings: Prioritize system boundaries and ownership - ensure clear ownership and API contracts between system components.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/core/run/exec/exec.go` around lines 237 - 263, The persisted exec resume flow currently doesn't bind the resolved reusable-agent identity to the run, allowing resumes with a different agent; fix this by persisting the resolved agent identity/config at run start and validating it on resume: when creating a new run, capture the resolved agent info returned by reusableagents.ResolveExecutionContext (agentExecution) and write a stable identifier/config snapshot into the run record (e.g., in prepareExecRunState/state.writeStarted where runArtifacts/record are persisted); then update validateExecResumeCompatibility to load and compare that persisted agent identity/config from state.record against the current ResolveExecutionContext result and return an error if they differ so newExecRuntimeJob/resume cannot attach a different agent to an existing run.internal/setup/install.go (1)
268-305:⚠️ Potential issue | 🟠 MajorPreserve source file permissions when copying bundled assets.
This helper now backs generic bundle installs, but every copied file is recreated as
0644. Any executable bundled asset will lose its execute bit in copy mode and in the symlink fallback path, which breaks post-install execution.Proposed fix
func copyBundleDirectory(bundle fs.FS, rootDir, dest string, subject string) error { return fs.WalkDir(bundle, rootDir, func(current string, entry fs.DirEntry, err error) error { if err != nil { return err } @@ source, err := bundle.Open(current) if err != nil { return fmt.Errorf("copy %s %s: %w", subject, rootDir, err) } defer source.Close() - file, err := os.OpenFile(target, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644) + mode := fs.FileMode(0o644) + if info, statErr := fs.Stat(bundle, current); statErr == nil { + mode = info.Mode().Perm() + } + file, err := os.OpenFile(target, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, mode) if err != nil { return fmt.Errorf("copy %s %s: %w", subject, rootDir, err) } defer file.Close()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/setup/install.go` around lines 268 - 305, copyBundleDirectory currently recreates files with fixed 0644 and directories with 0755, losing execute bits; fix by reading the source file/directory mode via Stat on the opened bundle entry (use the existing bundle.Open(current) / source.Stat() to get FileInfo.Mode()), then use that mode when creating directories (os.MkdirAll(target, fi.Mode().Perm())) and when creating files (os.OpenFile(target, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, fi.Mode().Perm())); also after copying, ensure the target file mode is set (file.Chmod(fi.Mode().Perm()) if needed) so executable bits on source entries are preserved (apply changes around the existing variables current, entry, source, file inside copyBundleDirectory).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/cli/agents_commands_test.go`:
- Around line 24-30: The tests calling withWorkingDir (e.g.,
TestExecCommandPassesSelectedAgentIntoWorkflowConfig) mutate the process-wide
working directory while marked t.Parallel(), causing racey failures; fix by
either removing t.Parallel() from any test that calls withWorkingDir (and the
other affected tests at the indicated ranges) or, better, change the helper and
command invocations to avoid os.Chdir: update withWorkingDir and any command
execution to set the working directory locally (use exec.Command.Dir or
equivalent) so tests can remain parallel-safe and no longer rely on process-wide
cwd.
In `@internal/cli/agents_commands.go`:
- Around line 62-65: The agents command group never registers the hidden
mcp-serve subcommand, so newMCPServeCommand() is defined but unreachable; add
newMCPServeCommand() to the cmd.AddCommand call in the same scope where
newAgentsListCommand() and newAgentsInspectCommand() are registered (i.e.,
include newMCPServeCommand() alongside the existing commands), ensuring any
required hidden flag/state set by newMCPServeCommand() remains unchanged.
- Around line 442-449: The helper optionalExistingPath currently returns "" for
any os.Stat error, hiding useful paths on permission errors or broken symlinks;
change it so it only returns "" when the path is blank or when os.Stat returns
an IsNotExist error (os.IsNotExist(err)); for any other non-nil error return the
original path so callers (e.g., agents inspect) can show the actual path and
surface the underlying failure; update function optionalExistingPath to use
os.IsNotExist(err) to distinguish the ENOENT case.
In `@internal/cli/reusable_agents_doc_examples_test.go`:
- Around line 17-20: Set HOME and XDG_CONFIG_HOME to isolated temp dirs before
running the CLI fixture so global agent discovery cannot influence resolution;
specifically, in the test(s) that create workspaceRoot and call
writeCLIWorkspaceConfig, copyCLIDocumentedAgentFixture("reviewer") and
withWorkingDir, create two temp dirs, set os.Setenv("HOME", tmpHome) and
os.Setenv("XDG_CONFIG_HOME", tmpXdg) before invoking the CLI actions, and
restore the original env values (defer reset) after the test; apply the same
change to the other similar test that uses the same sequence of
workspaceRoot/writeCLIWorkspaceConfig/copyCLIDocumentedAgentFixture/withWorkingDir
calls.
In `@internal/core/agent/client_test.go`:
- Around line 845-846: The test is flaky because req.McpServers vs
a.scenario.ExpectedNewSessionMCPServers can differ only by ordering of Env
slices; before the DeepEqual checks (for req.McpServers and the similar check at
871-872), normalize ordering deterministically by sorting each server's Env
slice and then sorting the server slice itself (e.g., by a stable key like
Host/Port or Name) so comparisons are order-insensitive; update the assertions
to compare these normalized copies of req.McpServers and
a.scenario.ExpectedNewSessionMCPServers (and the other pair) instead of the raw
values.
In `@internal/core/agent/client.go`:
- Around line 765-789: toACPMCPServers currently drops MCPServer entries with
nil Stdio, allowing invalid/partial MCP configurations to proceed; change it to
fail fast by returning an error when any src[i].Stdio == nil (include
identifying info such as index or server name from model.MCPServer in the error
message). Update the function signature from toACPMCPServers(src
[]model.MCPServer) []acp.McpServer to return ([]acp.McpServer, error) (or
perform equivalent upstream validation before calling it), and ensure callers
handle and propagate the error so create/resume rejects unsupported transports
instead of silently omitting them.
In `@internal/core/agents/agents_test.go`:
- Around line 14-506: Multiple standalone tests (e.g.,
TestDiscoverParsesValidAgentDefinition,
TestDiscoverRejectsReservedAndInvalidAgentNames,
TestDiscoverRejectsUnsupportedDeferredMetadataFields, etc.) must be converted to
a single table-driven test using t.Run("Should ...") subtests; refactor by
creating a TestDiscover (or consolidate within an existing TestDiscover*) that
defines a slice of cases (name, setup parameters like homeDir/workspaceRoot,
agent files via writeWorkspaceAgent/writeGlobalAgent, expected
catalog/Problems/assertions) and loops over them calling t.Run("Should
<behavior>", func(t *testing.T){ /* run per-case setup using newTestRegistry,
call registry.Discover, and perform the existing assertions */ }); reuse helpers
newTestRegistry, writeWorkspaceAgent, writeGlobalAgent, validAgentMarkdown, and
problemsByName to remove duplicated setup and preserve each original case's
assertions inside the corresponding subtest.
In `@internal/core/agents/agents.go`:
- Around line 212-219: The discovery currently aborts when r.globalAgentsRoot()
(called from Discover) fails, making workspace agent discovery unavailable;
change the logic so Discover treats failure to resolve the global root as
non-fatal: if r.globalAgentsRoot() returns an error, set globalCandidates and
globalProblems to empty (or nil) and proceed to call scanScope only when a valid
root is present, rather than returning the error; update the handling around
r.globalAgentsRoot(), scanScope, and the variables
globalCandidates/globalProblems so the Discover function continues discovering
workspace-local agents even when global lookup fails.
In `@internal/core/agents/execution.go`:
- Around line 109-145: The agent metadata is injected raw into the prompt tags
and can break framing or allow prompt injection; update buildAgentMetadataBlock,
buildAvailableAgentsBlock and formatDiscoveryCatalogEntry to escape/serialize
agent.Name, agent.Metadata.Title and agent.Metadata.Description before
concatenating into the XML-like blocks (e.g., JSON-serialize the strings or
escape control characters and angle-brackets/newlines), and use the escaped
values in the returned strings so tags like </agent_metadata> or newlines in
fields cannot break the host-owned prompt structure.
In `@internal/core/agents/mcpserver/server.go`:
- Around line 121-129: The loader function loadHostContextFromEnv currently
returns a zero HostContext when the reserved env var
reusableagents.RunAgentContextEnvVar is missing, causing fail-open behavior;
change loadHostContextFromEnv so that if lookupEnv reports the var absent or
blank it returns a non-nil error (with a clear message referencing the missing
COMPOZY_RUN_AGENT_CONTEXT) instead of HostContext{}, and ensure callers (e.g.,
server startup that may call RunStdio) propagate or handle that error (tests
should call RunStdio with an explicit HostContext to continue exercising the
server).
In `@internal/core/plan/prepare_test.go`:
- Around line 387-389: The test currently sets workspaceRoot and homeDir but
only overrides HOME, so ResolveExecutionContext may still read a pre-existing
XDG_CONFIG_HOME; create a separate temp dir (e.g., xdgConfigDir := t.TempDir())
and call t.Setenv("XDG_CONFIG_HOME", xdgConfigDir) alongside t.Setenv("HOME",
homeDir) (references: workspaceRoot, homeDir) to isolate config discovery and
prevent flaky catalog assertions.
In `@internal/core/run/exec/prompt_exec.go`:
- Around line 51-60: After writeStarted succeeds but buildMCPServers fails,
route the error through the same terminal-completion path by invoking
completeTurn (using state and cfg) with a failure result before returning;
specifically, in the buildMCPServers error branch (the call to
buildMCPServers(state.runArtifacts.RunID)), call completeTurn to mark the run as
completed/failed and persist the terminal state, then return
PreparedPromptResult{} with the original error — ensuring the branch mirrors the
execution-error handling rather than returning early and leaving a started run
hanging.
In `@internal/core/run/internal/acpshared/command_io.go`:
- Around line 125-136: The current call to emitReusableAgentSetupLifecycle (with
req.Context, req.RunJournal, req.Config.RunArtifacts.RunID, req.Job) aborts
setup on error by closing outFile/errFile, closing client, calling
releaseClient(), and returning the error; change this to best-effort: invoke
emitReusableAgentSetupLifecycle and if it returns an error, log a warning with
the error details but do NOT close outFile/errFile, do NOT close or release the
client, and do NOT return; allow the ACP session to continue (optionally spawn a
non-blocking retry/report task), so failures in telemetry emission degrade to
warnings instead of failing session startup.
In `@internal/core/run/internal/acpshared/reusable_agent_lifecycle.go`:
- Around line 159-177: The code is mutating h.nestedToolCalls before calling
submitReusableAgentLifecycle, which can leave the map out-of-sync if
runJournal.Submit fails; update handleNestedReusableAgentToolUse so it calls
submitReusableAgentLifecycle first and only inserts the nestedToolCalls entry
after the submit succeeds (or, alternatively, perform the insert then roll it
back if submit returns an error), and apply the same change to the analogous
block referenced at lines 219-223 (handleNestedReusableAgentToolResult deletion)
so deletions are performed only after a successful submit or are reverted on
submit failure; use the nestedToolCalls map, submitReusableAgentLifecycle,
handleNestedReusableAgentToolUse and handleNestedReusableAgentToolResult
identifiers to locate and update the logic.
In `@internal/core/run/internal/acpshared/session_handler.go`:
- Around line 109-112: The call to h.emitReusableAgentLifecycleFromUpdate after
h.applySessionUpdate must not abort the parent session on failure; instead,
catch the error from emitReusableAgentLifecycleFromUpdate, log a warning that
includes concrete failure modes (e.g., "decoding error", "submission error",
"journal hiccup") and relevant context (session id, update id), and continue
normal execution so the parent session stays healthy; update the code around
applySessionUpdate/emitReusableAgentLifecycleFromUpdate to handle the error
non-fatally (log + continue) rather than returning it.
In `@internal/core/run/internal/runshared/config.go`:
- Line 48: The Job.ReusableAgent field is declared but not propagated in
NewJobs, so Job.ReusableAgent remains nil for cloned jobs; update the
NewJobs/job cloning code that maps from the source "item" (the constructor
creating new Job instances) to copy item.ReusableAgent into the new
Job.ReusableAgent, performing a deep copy if ReusableAgent is a mutable struct
or contains pointers/slices (e.g., call a Clone/DeepCopy method or manually copy
nested fields) to avoid shared mutable state; ensure the new mapping uses the
exact symbol names Job.ReusableAgent, item.ReusableAgent and the
NewJobs/job-constructor function so downstream consumers receive an independent
copy.
In `@internal/setup/bundle.go`:
- Around line 35-38: The current code returns nil, err after calling
InstallBundledReusableAgents (successes, failures, err), discarding the
accumulated result of successful installs; instead populate or update the
existing result variable with the successes/failures and return that result
along with a wrapped error (preserving err) so partial phase-one results are
returned on phase-two failure; locate InstallBundledReusableAgents, the
successes/failures variables, and the result variable and change the return from
nil, err to return result, wrappedErr (using the project's error-wrapping
convention) so callers receive both the partial result and the error.
In `@internal/setup/install_test.go`:
- Around line 145-207: Both tests hardcode the expected number of bundled
reusable agents (6) and duplicate setup/assertion logic; change them to a single
table-driven test with two subtests ("preview" and "install") that share setup
and derive the expected roster dynamically from the source of truth for bundled
agents (e.g., call whichever function or variable your package exposes that
lists bundled reusable agents — reference PreviewBundledReusableAgentInstall and
InstallBundledReusableAgents to run the respective flows), assert len(results)
== len(bundledRoster) rather than == 6, and keep the existing per-item path
assertions (TargetPath and success.Path) inside the subtests. Ensure you replace
the two test functions
TestPreviewBundledReusableAgentInstallUsesGlobalCompozyAgentsDir and
TestInstallBundledReusableAgentsCopiesCouncilRosterIntoGlobalCompozyAgentsDir
with the consolidated table-driven t.Run structure and derive expected counts
from the bundled roster.
In `@internal/setup/reusable_agents.go`:
- Around line 121-141: The current install flow deletes/cleans the final target
(cleanAndCreateDirectory on targetPath) before copying, which can leave a
partial or missing agent if copyBundleDirectory fails; change the flow to create
a sibling temp directory (e.g., tempTarget := targetPath + ".tmp" or use
ioutil.TempDir in the same parent), call cleanAndCreateDirectory on that
tempTarget, then call copyBundleDirectory into tempTarget; if copy succeeds,
atomically replace the old installation by renaming tempTarget to targetPath
(os.Rename) and if it fails remove tempTarget and append the
ReusableAgentFailureItem with Error set to the copy error; ensure you still use
reusableAgent.Directory and bundledagents.FS for the copy and preserve existing
failure handling for cleanup and continue.
In `@pkg/compozy/events/kinds/reusable_agent.go`:
- Around line 48-53: The JSON tags on the ReusableAgent event struct currently
use `omitempty` for fields whose zero values are meaningful; remove `omitempty`
from NestedDepth, MaxNestedDepth, Success, and Blocked (fields named
NestedDepth, MaxNestedDepth, Success, Blocked in reusable_agent.go) so
zero/false values are preserved in serialized payloads; update the struct tags
to plain `json:"nested_depth"`, `json:"max_nested_depth"`, `json:"success"`, and
`json:"blocked"` and run tests/serialization checks to ensure downstream
consumers receive explicit zero/false values.
---
Outside diff comments:
In `@internal/core/run/exec/exec.go`:
- Around line 237-263: The persisted exec resume flow currently doesn't bind the
resolved reusable-agent identity to the run, allowing resumes with a different
agent; fix this by persisting the resolved agent identity/config at run start
and validating it on resume: when creating a new run, capture the resolved agent
info returned by reusableagents.ResolveExecutionContext (agentExecution) and
write a stable identifier/config snapshot into the run record (e.g., in
prepareExecRunState/state.writeStarted where runArtifacts/record are persisted);
then update validateExecResumeCompatibility to load and compare that persisted
agent identity/config from state.record against the current
ResolveExecutionContext result and return an error if they differ so
newExecRuntimeJob/resume cannot attach a different agent to an existing run.
In `@internal/setup/install.go`:
- Around line 268-305: copyBundleDirectory currently recreates files with fixed
0644 and directories with 0755, losing execute bits; fix by reading the source
file/directory mode via Stat on the opened bundle entry (use the existing
bundle.Open(current) / source.Stat() to get FileInfo.Mode()), then use that mode
when creating directories (os.MkdirAll(target, fi.Mode().Perm())) and when
creating files (os.OpenFile(target, os.O_CREATE|os.O_TRUNC|os.O_WRONLY,
fi.Mode().Perm())); also after copying, ensure the target file mode is set
(file.Chmod(fi.Mode().Perm()) if needed) so executable bits on source entries
are preserved (apply changes around the existing variables current, entry,
source, file inside copyBundleDirectory).
In `@pkg/compozy/events/docs_test.go`:
- Around line 11-56: The test TestEventsDocumentationEnumeratesAllPublicKinds
currently iterates over multiple EventKind values in a single test so a failure
aborts the rest; convert the loop so each EventKind is validated inside its own
subtest using t.Run with a descriptive name (e.g., the kind string), call
t.Parallel() at the start of each subtest, and perform the strings.Contains
check inside that subtest (keeping the same failure assertion but scoped to the
subtest) to ensure each kind is tested independently and in parallel.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b4e764f3-cb0c-465c-8fa5-fd0b13bf3b47
⛔ Files ignored due to path filters (35)
.agents/skills/council/SKILL.mdis excluded by!**/*.md,!.agents/**.agents/skills/council/references/archetypes.mdis excluded by!**/*.md,!.agents/**.codex/ledger/2026-04-10-MEMORY-council-agent-setup.mdis excluded by!**/*.md.compozy/tasks/agents/_meta.mdis excluded by!**/*.md.compozy/tasks/agents/_tasks.mdis excluded by!**/*.md.compozy/tasks/agents/_techspec.mdis excluded by!**/*.md.compozy/tasks/agents/adrs/adr-003.mdis excluded by!**/*.md.compozy/tasks/agents/memory/MEMORY.mdis excluded by!**/*.md.compozy/tasks/agents/memory/task_01.mdis excluded by!**/*.md.compozy/tasks/agents/memory/task_02.mdis excluded by!**/*.md.compozy/tasks/agents/memory/task_03.mdis excluded by!**/*.md.compozy/tasks/agents/memory/task_04.mdis excluded by!**/*.md.compozy/tasks/agents/memory/task_05.mdis excluded by!**/*.md.compozy/tasks/agents/memory/task_06.mdis excluded by!**/*.md.compozy/tasks/agents/task_01.mdis excluded by!**/*.md.compozy/tasks/agents/task_02.mdis excluded by!**/*.md.compozy/tasks/agents/task_03.mdis excluded by!**/*.md.compozy/tasks/agents/task_04.mdis excluded by!**/*.md.compozy/tasks/agents/task_05.mdis excluded by!**/*.md.compozy/tasks/agents/task_06.mdis excluded by!**/*.mdREADME.mdis excluded by!**/*.mdbundledagents/architect-advisor/AGENT.mdis excluded by!**/*.mdbundledagents/devils-advocate/AGENT.mdis excluded by!**/*.mdbundledagents/pragmatic-engineer/AGENT.mdis excluded by!**/*.mdbundledagents/product-mind/AGENT.mdis excluded by!**/*.mdbundledagents/security-advocate/AGENT.mdis excluded by!**/*.mdbundledagents/the-thinker/AGENT.mdis excluded by!**/*.mddocs/events.mdis excluded by!**/*.mddocs/examples/agents/repo-copilot/AGENT.mdis excluded by!**/*.mddocs/examples/agents/repo-copilot/mcp.jsonis excluded by!**/*.jsondocs/examples/agents/reviewer/AGENT.mdis excluded by!**/*.mddocs/reusable-agents.mdis excluded by!**/*.mdgo.sumis excluded by!**/*.sumskills/cy-idea-factory/SKILL.mdis excluded by!**/*.mdskills/cy-idea-factory/references/council.mdis excluded by!**/*.md
📒 Files selected for processing (62)
bundledagents/embed.gogo.modinternal/cli/agents_commands.gointernal/cli/agents_commands_test.gointernal/cli/commands.gointernal/cli/reusable_agents_doc_examples_test.gointernal/cli/root.gointernal/cli/root_command_execution_test.gointernal/cli/root_test.gointernal/cli/run.gointernal/cli/setup.gointernal/cli/setup_test.gointernal/cli/state.gointernal/cli/testdata/exec_help.goldeninternal/core/agent/client.gointernal/core/agent/client_test.gointernal/core/agents/agents.gointernal/core/agents/agents_test.gointernal/core/agents/doc_examples_test.gointernal/core/agents/execution.gointernal/core/agents/execution_test.gointernal/core/agents/mcpserver/engine.gointernal/core/agents/mcpserver/engine_test.gointernal/core/agents/mcpserver/server.gointernal/core/agents/mcpserver/server_test.gointernal/core/agents/reasons.gointernal/core/agents/session_mcp.gointernal/core/agents/session_mcp_test.gointernal/core/api.gointernal/core/kernel/commands/commands_test.gointernal/core/model/mcp.gointernal/core/model/preparation.gointernal/core/model/runtime_config.gointernal/core/plan/prepare.gointernal/core/plan/prepare_test.gointernal/core/run/exec/aliases.gointernal/core/run/exec/exec.gointernal/core/run/exec/exec_integration_test.gointernal/core/run/exec/exec_test.gointernal/core/run/exec/prompt_exec.gointernal/core/run/exec/run_agent_engine_integration_test.gointernal/core/run/exec/test_helpers_test.gointernal/core/run/executor/execution_acp_integration_test.gointernal/core/run/internal/acpshared/aliases.gointernal/core/run/internal/acpshared/command_io.gointernal/core/run/internal/acpshared/command_io_test.gointernal/core/run/internal/acpshared/reusable_agent_lifecycle.gointernal/core/run/internal/acpshared/session_handler.gointernal/core/run/internal/acpshared/session_handler_test.gointernal/core/run/internal/runshared/config.gointernal/core/run/internal/runshared/types.gointernal/core/run/test_hooks.gointernal/setup/bundle.gointernal/setup/bundle_test.gointernal/setup/install.gointernal/setup/install_test.gointernal/setup/reusable_agents.gointernal/setup/types.gopkg/compozy/events/docs_test.gopkg/compozy/events/event.gopkg/compozy/events/event_test.gopkg/compozy/events/kinds/reusable_agent.go
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (3)
internal/setup/reusable_agents.go (1)
221-225: Consider logging instead of failing when backup cleanup fails.After line 220, the new agent is successfully installed in
targetPath. IfremoveReusableAgentPath(backupPath)fails here, the function returns an error, causing the install to be reported as failed even though the new content is in place.This leaves orphaned backup directories and misleads the caller about the install status. Consider either:
- Logging the cleanup error and returning
nil(install succeeded)- Collecting cleanup errors separately from install errors
♻️ Proposed fix
if backupPath != "" { if err := removeReusableAgentPath(backupPath); err != nil { - return fmt.Errorf("cleanup reusable agent backup %s: %w", backupPath, err) + // Log but don't fail - the install succeeded, only cleanup failed + // The orphaned backup will be cleaned up on next install + _ = err // TODO: consider structured logging for cleanup failures } } return nil🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/setup/reusable_agents.go` around lines 221 - 225, The cleanup call to removeReusableAgentPath(backupPath) can fail after the new agent is already installed to targetPath, causing the function to return an error and incorrectly signal install failure; change this to log the cleanup failure instead of returning it (or aggregate cleanup errors separately) so the function returns nil on successful install—specifically, in the block that calls removeReusableAgentPath(backupPath) avoid returning fmt.Errorf on error and instead call the appropriate logger with context about backupPath and continue, or append the cleanup error to a separate variable that does not affect the install success return.internal/core/run/internal/acpshared/reusable_agent_lifecycle.go (2)
248-264: JSON decode errors are silently swallowed.Both
decodeRunAgentToolInputanddecodeRunAgentToolResultdiscard JSON unmarshal errors. This is likely intentional for resilience against malformed tool payloads, but consider logging at debug level to aid troubleshooting when tool results don't emit expected lifecycle events.Also applies to: 266-286
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/core/run/internal/acpshared/reusable_agent_lifecycle.go` around lines 248 - 264, decodeRunAgentToolInput and decodeRunAgentToolResult currently swallow json.Unmarshal errors; update both functions to log the unmarshal error at debug level when json.Unmarshal(raw, &payload) fails (while keeping the current continue behavior) so malformed block.Input or block.RawInput are recorded for troubleshooting; reference the functions decodeRunAgentToolInput/decodeRunAgentToolResult and the variables block.Input, block.RawInput and payload when adding a debug log call that includes the error and some context (e.g., which raw field failed).
96-98: Context fallback tocontext.Background()for nil input.While the coding guidelines recommend avoiding
context.Background()outsidemainand focused tests, this fallback is a defensive measure to prevent panics if a caller passes nil. Consider whether callers should be required to provide a valid context instead, which would surface bugs earlier.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/core/run/internal/acpshared/reusable_agent_lifecycle.go` around lines 96 - 98, Remove the defensive fallback that sets ctx = context.Background() when ctx is nil; instead validate the incoming ctx variable and fail fast by returning an explicit error (e.g., return fmt.Errorf("nil context passed to <functionName>") ) or by propagating an error up the call chain from the function that currently contains the check (replace the current block that uses ctx and context.Background()). Update the function signature to return an error if needed and update its callers to provide a non-nil context (or handle the returned error), so nil contexts surface as bugs rather than being silently replaced by context.Background().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/core/agents/agents.go`:
- Around line 157-159: The current loop returns fmt.Errorf("resolve agent %q:
%w", normalized, problem.Err) which unwraps only the inner error and loses the
richer Problem diagnostics; change the wrap to use the whole Problem value
(e.g., fmt.Errorf("resolve agent %q: %w", normalized, problem)) so callers
retain Problem.Error() context and unwrapping still works; update the return in
the loop that iterates c.Problems (where problem.Name == normalized) to wrap
problem instead of problem.Err.
In `@internal/core/agents/execution_test.go`:
- Around line 11-385: These tests use flat top-level test functions instead of
the repository standard table-driven subtests; refactor each
TestResolveExecutionContextAppliesRuntimePrecedence,
TestResolveExecutionContextAppliesAgentModelWhenModelFlagIsUnset,
TestResolveExecutionContextPublicWrapperCapturesBaseRuntimeBeforeOverrides,
TestExecutionContextSystemPromptUsesCanonicalOrder,
TestExecutionContextSystemPromptKeepsDiscoveryCatalogCompact,
TestExecutionContextSystemPromptEscapesHostOwnedMetadataBlocks,
TestExecutionContextSystemPromptFallsBackToBasePromptWhenNoAgentSelected, and
TestResolveExecutionContextPreservesExistingRuntimeWhenAgentOmitsField to wrap
their assertions inside t.Run("Should <behaviour>", func(t *testing.T){ ... })
(or a table of named cases with t.Run for multiple scenarios), preserving
existing setup and assertions but moving them into appropriately named subtests
so failures report the descriptive subtest name and conform to the repository
testing pattern.
In `@internal/core/agents/mcpserver/server_test.go`:
- Around line 78-99: The test uses NewServer() and HostContext{} which can pick
up real-agent files; make the failure-path hermetic by creating a temp workspace
and config dirs and wiring them into the server/runtime before invoking handler:
set the server's BaseRuntime.WorkspaceRoot to t.TempDir() (or otherwise point
BaseRuntime on the created temp dir) and set the environment variables HOME and
XDG_CONFIG_HOME to temp dirs (via t.TempDir()) before calling
server.runAgentTool(HostContext{}) and executing handler(context.Background(),
...), ensuring the real runner workspace/config cannot resolve a
"missing-agent".
- Around line 21-187: Convert the top-level tests into t.Run subtests with
"Should..." names: create a single Test... wrapper (e.g., TestServerBehaviors)
and move the bodies of TestLoadHostContextFromEnvParsesReservedPayload,
TestLoadHostContextFromEnvRejectsMissingPayload,
TestRunAgentToolMarksStructuredFailuresAsToolErrors,
TestNewServerAppliesOptionsAndDefaults,
TestLoadHostContextFromEnvUsesProcessEnvironment, and
TestServeStdioReturnsWhenContextIsCanceled into individual t.Run("Should ...",
func(t *testing.T){ ... }) blocks (keep t.Parallel() where used), rename each
subtest description to start with "Should" (e.g., "Should parse reserved payload
from env"), and remove the original top-level TestXxx functions so the file uses
the required subtest pattern while preserving all assertions and helper setup
(e.g., stdioSwapMu, ServeStdio, LoadHostContextFromEnv, NewServer,
runAgentTool).
In `@internal/core/run/exec/prompt_exec.go`:
- Around line 81-86: The current logic calls executeExecJob and then
state.completeTurn(result) but if both completeTurn and result.err are non-nil
it returns only result.err, hiding the persistence failure; change the control
flow in the block around executeExecJob / state.completeTurn so you capture the
error returned by state.completeTurn (e.g., errComplete :=
state.completeTurn(result)) and if errComplete != nil return
buildPreparedPromptResult(state, result), errComplete (before returning
result.err), otherwise proceed to return result.err if present or the successful
value; this ensures state.completeTurn failures (persistence/terminal-state
errors) are surfaced instead of being masked by result.err.
In `@pkg/compozy/events/kinds/reusable_agent_test.go`:
- Around line 9-36: The test
TestReusableAgentLifecyclePayloadJSONPreservesMeaningfulZeroValues should be
converted to a table-driven test with subtests using t.Run("Should ...") and
t.Parallel() called inside each subtest: create a slice of cases (with name and
payload), iterate cases and call t.Run(caseName, func(t *testing.T){
t.Parallel(); marshal the case.payload, assert the JSON contains the expected
fields like `"nested_depth":0`, `"max_nested_depth":0`, `"success":false`,
`"blocked":false` and use t.Fatalf on errors }), keeping the same assertions and
referencing ReusableAgentLifecyclePayload and
ReusableAgentLifecycleStageNestedCompleted to locate the payload construction.
---
Nitpick comments:
In `@internal/core/run/internal/acpshared/reusable_agent_lifecycle.go`:
- Around line 248-264: decodeRunAgentToolInput and decodeRunAgentToolResult
currently swallow json.Unmarshal errors; update both functions to log the
unmarshal error at debug level when json.Unmarshal(raw, &payload) fails (while
keeping the current continue behavior) so malformed block.Input or
block.RawInput are recorded for troubleshooting; reference the functions
decodeRunAgentToolInput/decodeRunAgentToolResult and the variables block.Input,
block.RawInput and payload when adding a debug log call that includes the error
and some context (e.g., which raw field failed).
- Around line 96-98: Remove the defensive fallback that sets ctx =
context.Background() when ctx is nil; instead validate the incoming ctx variable
and fail fast by returning an explicit error (e.g., return fmt.Errorf("nil
context passed to <functionName>") ) or by propagating an error up the call
chain from the function that currently contains the check (replace the current
block that uses ctx and context.Background()). Update the function signature to
return an error if needed and update its callers to provide a non-nil context
(or handle the returned error), so nil contexts surface as bugs rather than
being silently replaced by context.Background().
In `@internal/setup/reusable_agents.go`:
- Around line 221-225: The cleanup call to removeReusableAgentPath(backupPath)
can fail after the new agent is already installed to targetPath, causing the
function to return an error and incorrectly signal install failure; change this
to log the cleanup failure instead of returning it (or aggregate cleanup errors
separately) so the function returns nil on successful install—specifically, in
the block that calls removeReusableAgentPath(backupPath) avoid returning
fmt.Errorf on error and instead call the appropriate logger with context about
backupPath and continue, or append the cleanup error to a separate variable that
does not affect the install success return.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: a4243844-84ed-4c76-a425-d44003e1bc8b
⛔ Files ignored due to path filters (21)
.compozy/tasks/agents/reviews-001/_meta.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_001.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_002.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_003.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_004.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_005.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_006.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_007.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_008.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_009.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_010.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_011.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_012.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_013.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_014.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_015.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_016.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_017.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_018.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_019.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-001/issue_020.mdis excluded by!**/*.md
📒 Files selected for processing (24)
internal/cli/agents_commands.gointernal/cli/agents_commands_test.gointernal/cli/reusable_agents_doc_examples_test.gointernal/core/agent/client.gointernal/core/agent/client_test.gointernal/core/agents/agents.gointernal/core/agents/agents_test.gointernal/core/agents/execution.gointernal/core/agents/execution_test.gointernal/core/agents/mcpserver/server.gointernal/core/agents/mcpserver/server_test.gointernal/core/plan/prepare_test.gointernal/core/run/exec/exec_test.gointernal/core/run/exec/prompt_exec.gointernal/core/run/internal/acpshared/command_io.gointernal/core/run/internal/acpshared/command_io_test.gointernal/core/run/internal/acpshared/reusable_agent_lifecycle.gointernal/core/run/internal/acpshared/session_handler.gointernal/core/run/internal/acpshared/session_handler_test.gointernal/setup/bundle.gointernal/setup/install_test.gointernal/setup/reusable_agents.gopkg/compozy/events/kinds/reusable_agent.gopkg/compozy/events/kinds/reusable_agent_test.go
✅ Files skipped from review due to trivial changes (6)
- internal/core/run/exec/exec_test.go
- internal/cli/reusable_agents_doc_examples_test.go
- internal/core/run/internal/acpshared/command_io_test.go
- internal/cli/agents_commands.go
- internal/core/agents/agents_test.go
- pkg/compozy/events/kinds/reusable_agent.go
🚧 Files skipped from review as they are similar to previous changes (7)
- internal/core/run/internal/acpshared/session_handler_test.go
- internal/core/agent/client.go
- internal/setup/bundle.go
- internal/core/agent/client_test.go
- internal/core/agents/execution.go
- internal/cli/agents_commands_test.go
- internal/core/run/internal/acpshared/command_io.go
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
internal/core/agents/mcpserver/server_test.go (1)
21-192:⚠️ Potential issue | 🟠 MajorConvert these top-level tests into
t.Run("Should ...")subtests.This file still uses top-level
Test...functions instead of the required subtest pattern.#!/bin/bash # Verify current test shape in this file. rg -n --type=go '^func Test' internal/core/agents/mcpserver/server_test.go rg -n --type=go 't\.Run\("Should' internal/core/agents/mcpserver/server_test.goAs per coding guidelines "
**/*_test.go: MUST use t.Run("Should...") pattern for ALL test cases" and "**/*_test.go: Use table-driven tests with subtests (t.Run) as the default pattern for Go tests".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/core/agents/mcpserver/server_test.go` around lines 21 - 192, The tests are top-level functions and must be converted to subtests using the t.Run("Should ...") pattern; replace each Test... function (TestLoadHostContextFromEnvParsesReservedPayload, TestLoadHostContextFromEnvRejectsMissingPayload, TestRunAgentToolMarksStructuredFailuresAsToolErrors, TestNewServerAppliesOptionsAndDefaults, TestLoadHostContextFromEnvUsesProcessEnvironment, TestServeStdioReturnsWhenContextIsCanceled) with a single top-level TestServer (or similar) that contains t.Run("Should parse reserved payload", ...), t.Run("Should reject missing payload", ...), t.Run("Should mark structured failures as tool errors", ...), etc., moving each function body into its corresponding subtest and preserving behavior including t.Parallel() inside each subtest where applicable and keeping references to functions/types like loadHostContextFromEnv, LoadHostContextFromEnv, NewServer, server.runAgentTool, ServeStdio, reusableagents.RunAgentContextEnvVar, and others so tests still call the same code paths.
🧹 Nitpick comments (2)
internal/core/run/exec/exec_test.go (1)
459-466: Avoidpanicin this test helper; uset.Helper()and fail throughtesting.T.Line 465 panics on marshal failure, which gives poorer failure attribution than a helper-aware test failure.
Proposed fix
-func preparedPromptTextContentBlock(text string) model.ContentBlock { +func preparedPromptTextContentBlock(t *testing.T, text string) model.ContentBlock { + t.Helper() payload, err := json.Marshal(model.TextBlock{ Type: model.BlockText, Text: text, }) if err != nil { - panic(err) + t.Fatalf("marshal text block: %v", err) } return model.ContentBlock{ Type: model.BlockText, Data: payload, } }And update call sites accordingly:
-Blocks: []model.ContentBlock{preparedPromptTextContentBlock("nested reply")}, +Blocks: []model.ContentBlock{preparedPromptTextContentBlock(t, "nested reply")},As per coding guidelines:
Mark test helper functions with t.Helper() so stack traces point to the caller.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/core/run/exec/exec_test.go` around lines 459 - 466, preparedPromptTextContentBlock currently panics on json.Marshal errors; change it into a test helper that accepts t *testing.T, call t.Helper() at the top, and use t.Fatalf (or t.Fatalf with the marshal error) instead of panic to fail the test with proper attribution; update all call sites that invoked preparedPromptTextContentBlock(text) to pass the testing.T (e.g., preparedPromptTextContentBlock(t, text)) and adjust imports if needed.internal/core/run/exec/prompt_exec.go (1)
42-43: Wrap propagated errors with operation context.Several branches return raw errors (for example on Line 43, Line 48, Line 53, Line 79), which makes nested-failure diagnosis harder in callers and logs.
Proposed fix
if err := agent.EnsureAvailable(ctx, cfg); err != nil { - return PreparedPromptResult{}, err + return PreparedPromptResult{}, fmt.Errorf("execute prepared prompt: ensure runtime availability: %w", err) } state, err := prepareExecRunState(ctx, cfg) if err != nil { - return PreparedPromptResult{}, err + return PreparedPromptResult{}, fmt.Errorf("execute prepared prompt: prepare exec state: %w", err) } @@ if err := state.writeStarted(cfg); err != nil { - return PreparedPromptResult{}, err + return PreparedPromptResult{}, fmt.Errorf("execute prepared prompt: persist started turn: %w", err) } @@ execJob, err := newExecRuntimeJobWithMCP(promptText, state, agentExecution, mcpServers) if err != nil { - return PreparedPromptResult{}, err + return PreparedPromptResult{}, fmt.Errorf("execute prepared prompt: build exec job: %w", err) }As per coding guidelines:
Prefer explicit error returns with wrapped context using fmt.Errorf("context: %w", err).Also applies to: 46-49, 52-53, 77-80
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/core/run/exec/prompt_exec.go` around lines 42 - 43, The code currently returns raw errors from calls like agent.EnsureAvailable(ctx, cfg) and other branches returning PreparedPromptResult{}, which makes diagnostics hard; update each return that directly forwards err (including the EnsureAvailable call and the other branches around the Prepare/execute logic referenced in the diff) to wrap the error with operation context using fmt.Errorf("failed to ensure agent available: %w", err) (and similar contextual messages for the other operations), e.g., replace returns of the form `return PreparedPromptResult{}, err` with `return PreparedPromptResult{}, fmt.Errorf("<operation description>: %w", err)` so callers get wrapped errors with clear context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/core/agents/mcpserver/server_test.go`:
- Around line 158-190: The test currently redirects stdout to a pipe but never
consumes stdoutRead, which can cause ServeStdio to block on writes; spawn a
background goroutine that calls io.ReadAll(stdoutRead) (or otherwise
continuously drains stdoutRead) immediately after creating the pipe and before
calling ServeStdio so the pipe buffer can't fill and block the server; reference
stdoutRead/stdoutWrite and ServeStdio(ctx, HostContext{}) when adding the drain
goroutine and ensure it runs until stdoutWrite is closed.
In `@internal/core/run/exec/exec_test.go`:
- Around line 20-205: Combine the related validation cases in
TestExecutePreparedPromptValidatesInputs into a table-driven set of subtests
using t.Run("Should ...") (e.g., "Should error when config is nil", "Should
error when prompt is empty") that call ExecutePreparedPrompt and assert specific
errors using ErrorContains/ErrorAs or errors.Is/strings.Contains rather than
only checking err == nil; update other tests that currently do weak assertions
to similarly assert the expected error type/message. Also fix the helper
preparedPromptTextContentBlock to call t.Helper() and replace any panic(err)
with t.Fatalf to surface failures via the testing.T; use the function names
ExecutePreparedPrompt, TestExecutePreparedPromptValidatesInputs, and
preparedPromptTextContentBlock to locate the changes. Ensure each subtest uses
t.Parallel appropriately and preserves existing setup/cleanup semantics.
In `@internal/core/run/exec/prompt_exec.go`:
- Around line 64-67: The current branch in prompt_exec.go returns only
completeErr when both err (the MCP-builder failure) and completeErr (the
completion failure from state.completeTurn) exist and differ, which masks the
original err; change the return to preserve both errors using errors.Join(err,
completeErr) (or errors.Join(completeErr, err)) so callers see both failures,
keeping the same returned prepared result from buildPreparedPromptResult(state,
failure) and referencing state.completeTurn, buildPreparedPromptResult, err and
completeErr to locate the code to update.
---
Duplicate comments:
In `@internal/core/agents/mcpserver/server_test.go`:
- Around line 21-192: The tests are top-level functions and must be converted to
subtests using the t.Run("Should ...") pattern; replace each Test... function
(TestLoadHostContextFromEnvParsesReservedPayload,
TestLoadHostContextFromEnvRejectsMissingPayload,
TestRunAgentToolMarksStructuredFailuresAsToolErrors,
TestNewServerAppliesOptionsAndDefaults,
TestLoadHostContextFromEnvUsesProcessEnvironment,
TestServeStdioReturnsWhenContextIsCanceled) with a single top-level TestServer
(or similar) that contains t.Run("Should parse reserved payload", ...),
t.Run("Should reject missing payload", ...), t.Run("Should mark structured
failures as tool errors", ...), etc., moving each function body into its
corresponding subtest and preserving behavior including t.Parallel() inside each
subtest where applicable and keeping references to functions/types like
loadHostContextFromEnv, LoadHostContextFromEnv, NewServer, server.runAgentTool,
ServeStdio, reusableagents.RunAgentContextEnvVar, and others so tests still call
the same code paths.
---
Nitpick comments:
In `@internal/core/run/exec/exec_test.go`:
- Around line 459-466: preparedPromptTextContentBlock currently panics on
json.Marshal errors; change it into a test helper that accepts t *testing.T,
call t.Helper() at the top, and use t.Fatalf (or t.Fatalf with the marshal
error) instead of panic to fail the test with proper attribution; update all
call sites that invoked preparedPromptTextContentBlock(text) to pass the
testing.T (e.g., preparedPromptTextContentBlock(t, text)) and adjust imports if
needed.
In `@internal/core/run/exec/prompt_exec.go`:
- Around line 42-43: The code currently returns raw errors from calls like
agent.EnsureAvailable(ctx, cfg) and other branches returning
PreparedPromptResult{}, which makes diagnostics hard; update each return that
directly forwards err (including the EnsureAvailable call and the other branches
around the Prepare/execute logic referenced in the diff) to wrap the error with
operation context using fmt.Errorf("failed to ensure agent available: %w", err)
(and similar contextual messages for the other operations), e.g., replace
returns of the form `return PreparedPromptResult{}, err` with `return
PreparedPromptResult{}, fmt.Errorf("<operation description>: %w", err)` so
callers get wrapped errors with clear context.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: cc1b96dc-5bb4-4d0b-8a16-e9e21427c353
⛔ Files ignored due to path filters (11)
.compozy/tasks/agents/reviews-002/_meta.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_001.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_002.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_003.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_004.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_005.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_006.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_007.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_008.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_009.mdis excluded by!**/*.md.compozy/tasks/agents/reviews-002/issue_010.mdis excluded by!**/*.md
📒 Files selected for processing (5)
internal/core/agents/agents.gointernal/core/agents/agents_test.gointernal/core/agents/mcpserver/server_test.gointernal/core/run/exec/exec_test.gointernal/core/run/exec/prompt_exec.go
✅ Files skipped from review due to trivial changes (1)
- internal/core/agents/agents_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- internal/core/agents/agents.go
Summary by CodeRabbit
New Features
Tests
Chores