MemberJunction / MemberJunction/MJ

Refactor monolithic BaseAgent into a layered inheritance hierarchy

Open
#2,708 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TSQL
Stars
29
Forks
6
Avg merge
1d 8h
Merged PRs (30d)
308

Description

## Concept

The `BaseAgent` class in `@memberjunction/ai-agents` (`packages/AI/Agents/src/base-agent.ts`) has grown into a monolithic ~10k+ line single file. This issue captures the design to decompose it into a **clean, layered (linear) inheritance hierarchy** — one concern per layer — while preserving full backwards compatibility and avoiding the type-safety/runtime overheads of a composition/mixin approach.

### Why this design

A **linear inheritance chain** (rather than composition, mixins, or splitting into collaborator services) was chosen because:
- It preserves the existing public API of `BaseAgent` 1:1 — consumers and subclasses see no change.
- It keeps strong typing throughout with no `any`/casting overhead and no indirection at call sites (`this.foo()` still resolves directly).
- Each layer has a single, well-defined responsibility, so the file size per concern is manageable and the call graph stays readable.
- Subclasses can still override any method at any layer.

### Proposed layer hierarchy (bottom → top)

Files live under `packages/AI/Agents/src/base-agent/`:

1. **`BaseAgentState`** — Holds all instance variables, loggers, progress-step collectors, and state getters/setters. The root of the chain.
2. **`BaseAgentInit`** (extends `BaseAgentState`) — Coordinates initialization: engines verification, config loading, and starting-payload validation.
3. **`BaseAgentPrompt`** (extends `BaseAgentInit`) — Compiles hierarchical prompting payloads, executes LLM calls, estimates tokens, and performs context recovery / message compaction.
4. **`BaseAgentOperations`** (extends `BaseAgentPrompt`) — Handles loops (ForEach, While), sub-agent dispatch, client tool executions, and expression context-path resolution.
5. **`BaseAgentActions`** (extends `BaseAgentOperations`) — Intercepts action execution, extracts parameters/schemas, handles large binary/media replacement, and resolves media references.
6. **`BaseAgent`** (extends `BaseAgentActions`) — Orchestrates high-level execution, timeouts, and finalization. Remains the public entry point.

```
BaseAgentState
└─ BaseAgentInit
└─ BaseAgentPrompt
└─ BaseAgentOperations
└─ BaseAgentActions
└─ BaseAgent ← public class, unchanged API
```

### Scope of work (from the prototype)
- Create the new modular files under `packages/AI/Agents/src/base-agent/`.
- Slim `packages/AI/Agents/src/base-agent.ts` down to extend `BaseAgentActions`, moving the modularized methods into their layers while keeping public APIs fully compatible.
- Add an inheritance test (`packages/AI/Agents/src/__tests__/base-agent-inheritance.test.ts`) verifying the layer chain and subclass overriding.
- Update `packages/AI/Agents/README.md` to document the architecture with a class diagram.

## ⚠️ Important context for a future session

This concept was prototyped in **PR #2649** (`claude/baseagent-refactor-plan`), which has been **closed without merging**. The prototype compiled cleanly and passed all 798 unit tests in `@memberjunction/ai-agents` at the time.

**Do NOT lift the code from PR #2649 directly.** Significant work has since landed on the AI Agents package, so the prototype's diff is stale. The *design* (the layered hierarchy above) is what we want to carry forward. A future session should:

1. Start from the **current** state of `packages/AI/Agents/` (not the PR branch).
2. Re-apply the layering concept to the current `BaseAgent` implementation, mapping today's methods to the appropriate layer.
3. Pull from PR #2649 **only as a historical reference** for how the split was structured — and only if helpful.
4. Preserve the public API and re-verify with `npm run build` + the full `@memberjunction/ai-agents` test suite.

### References
- Closed prototype PR: https://github.com/MemberJunction/MJ/pull/2649
- Prototype branch (for historical reference only): `claude/baseagent-refactor-plan`
- Design notes from the prototype: `plans/baseagent-granularity-refactor.md` (on the PR branch)

Contributor guide

Open the contributing guide

Research direction

Start with the current packages/AI/Agents/src/base-agent.ts and map its methods to the proposed layers under packages/AI/Agents/src/base-agent/. Review the inheritance test requested at packages/AI/Agents/src/__tests__/base-agent-inheritance.test.ts, then run npm run build and the full @memberjunction/ai-agents test suite. Done means the public BaseAgent API remains compatible, the layer and override tests pass, and the README documents the hierarchy.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
ai
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.