Skip to content

refactor(agents): unify dual-backend gadget builders and prompt functions#429

Merged
zbigniewsobiecki merged 2 commits intodevfrom
refactor/dual-backend-architecture
Feb 20, 2026
Merged

refactor(agents): unify dual-backend gadget builders and prompt functions#429
zbigniewsobiecki merged 2 commits intodevfrom
refactor/dual-backend-architecture

Conversation

@aaight
Copy link
Copy Markdown
Collaborator

@aaight aaight commented Feb 20, 2026

Summary

Refactors the dual-backend agent architecture to eliminate code duplication between the llmist backend (agents/base.ts) and the Claude Code backend (backends/agent-profiles.ts).

Card: https://trello.com/c/aLAQMmke/49-find-top-candidate-for-refactoring-and-plan-clean-refactoring-of-it-look-for-god-classes-modules-functions-files-and-code-duplic

What was done

  • Gadget unification (Step 2): Extracted buildWorkItemGadgets(), buildReviewGadgets(), and buildPRAgentGadgets() into src/agents/shared/gadgets.ts as the single source of truth. Both backends now call these shared factories instead of maintaining separate identical builders. The old comment "Mirrors the logic in agents/base.ts getBaseAgentGadgets()" is gone because the code is now actually shared. Net: ~130 lines of duplicated gadget builders removed.

  • Prompt builder consolidation (Step 1): Created src/agents/shared/taskPrompts.ts with canonical prompt builder functions (buildWorkItemPrompt, buildCommentResponsePrompt, buildReviewPrompt, buildCIResponsePrompt, buildPRCommentResponsePrompt, buildCheckFailurePrompt, buildDebugPrompt). Both agents/base.ts and backends/agent-profiles.ts now import from this module instead of each defining their own versions. Net: ~90 lines of duplicated prompt builders removed.

  • process.chdir() side effect removal (Step 4): Fixed fetchDirectoryListing() in agent-profiles.ts which was using process.chdir(repoDir) as a workaround. Now passes the absolute repoDir path directly to ListDirectory, eliminating the race condition.

  • Backwards compatibility: createPRAgentGadgets() is kept as a deprecated alias for buildPRAgentGadgets() to avoid breaking existing callers in the llmist agent files.

Key decisions

  • Kept agent-profiles.ts thin wrapper functions (buildWorkItemTaskPrompt, etc.) that delegate to shared builders — avoids changing the AgentProfile interface which would require updating all 10+ profile objects and their tests.
  • Used src/agents/shared/ as the location for shared code (not src/backends/) to avoid circular imports since backends/ already imports from agents/shared/.
  • buildPRAgentGadgets is now complete (includes FileMultiEdit, VerifyChanges, GetPRChecks that were missing from the old createPRAgentGadgets), making both backends produce identical gadget sets.

Testing

  • All 2202 existing tests pass
  • Added 36 new tests:
    • tests/unit/agents/shared/taskPrompts.test.ts — 20 tests for all prompt builder functions
    • tests/unit/agents/shared/gadgets.test.ts — 16 tests verifying gadget factory behavior per capability flags

🤖 Generated with Claude Code

@nhopeatall
Copy link
Copy Markdown
Collaborator

🔍 Reviewing PR...

Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

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

Summary

LGTM — clean deduplication refactoring that extracts shared gadget builders and prompt functions into src/agents/shared/, eliminating ~220 lines of duplicated code between the llmist and Claude Code backends. All changes are structurally sound.

Notes

Prompt text change (intentional): The llmist backend's buildPrompt() previously included richer text ("...title, description, checklists, attachments, comments...Review it and proceed with your task.") while the Claude Code backend used a shorter version. The PR unifies to the shorter version. This is a minor behavioral change for the llmist path but is consistent with the stated goal of making both backends produce identical outputs.

Gadget set expansion (intentional, correct): createPRAgentGadgets() (now buildPRAgentGadgets()) gains FileMultiEdit, VerifyChanges, and GetPRChecks that agent-profiles.ts already had. The three llmist agent files (respond-to-ci, respond-to-review, respond-to-pr-comment) that call the deprecated alias will now get these additional gadgets — this is the intended parity fix per the PR description.

process.chdir() removal: The fix is correct. ListDirectory.execute() calls path.resolve(process.cwd(), directoryPath), and since repoDir is absolute, path.resolve uses it directly regardless of cwd. The race condition is eliminated.

Backwards compatibility: createPRAgentGadgets is kept as a thin deprecated alias, and the three existing callers in src/agents/ continue to work unchanged.

Tests: 36 new tests cover all shared builders with proper mocking. CI passes (4/4 checks green).

Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

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

Review completed - see previous review submission.

@zbigniewsobiecki zbigniewsobiecki merged commit 114567a into dev Feb 20, 2026
4 checks passed
@zbigniewsobiecki zbigniewsobiecki deleted the refactor/dual-backend-architecture branch March 16, 2026 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants