Agents Module
Purpose
- Define the Agent interface and registry for SDK- and command-based agents (Codex via SDK, OpenCode via SDK, Droid via SDK, Shell, etc.).
- Provide profile schema handling, profile CRUD, and agent-specific runners.
- Emit agent lifecycle events so the UI stays in sync with available agents and profiles.
Architecture
Shared Abstractions (core/src/agents/)
The agent system uses shared abstractions to minimize code duplication:
BaseProfileSchema: Zod schema with common fields (appendPrompt,inlineProfile,debug)SdkAgent<P, I>: Abstract base class implementingAgent<P>with:- Lifecycle hooks:
onRunStart(ctx, profile, mode),onRunEnd(ctx, profile, mode)wheremodeis'run'or'resume' - Default
inline()dispatch toenhance()/summarizePullRequest() - Template methods:
detectInstallation(),createClient(),startSession(),resumeSession(),handleEvent()
- Lifecycle hooks:
locateExecutable(): Unified executable discovery with env vars and PATH fallbackcreateEnhanceContext()/createPrSummaryContext(): Factory functions for inline task contexts
Agent File Structure
Each SDK agent follows a modular file structure:OpenCode Agent (core/src/agents/opencode/)
OpencodeServerManager: Manages local server instances by portcreateSessionStream(): Handles SSE subscription with idle timeout- Event filtering by
sessionIDfor multi-session environments
Codex Agent (core/src/agents/codex/)
- Thread-based sessions via
@openai/codex-sdk - Sandbox modes:
read-only,workspace-write,danger-full-access - Image support via
saveImagesToTempFiles()
Droid Agent (core/src/agents/droid/)
- Thread-based sessions via
@activade/droid-sdk - Autonomy levels and reasoning effort configuration
- Image attachments support
Data & Event Flow
- Registry (
registry.ts)registerAgentstores agents and emitsagent.registeredwhenever an agent is added.initializeAgents(agents, options?)dynamically registers agents based on availability:- Checks each agent’s optional
availability()method. - Registers only agents that return
true(or lack an availability check). - Returns
AgentInitResultwithregisteredandskippedlists. - Accepts an optional
logfunction for visibility into registration decisions.
- Checks each agent’s optional
bindAgentEventBuspublishes the full registry once the event bus is available.- Server-side initialization uses
initializeServerAgents()to register only available agents.
- Agent Availability
- Agents can implement an
availability(): Promise<boolean>method to check installation status. - Codex: checks for
codexexecutable viaCODEX_PATH_OVERRIDEorCODEX_PATHenv vars, or PATH. - Droid: checks for
droidexecutable viaDROID_PATH_OVERRIDEorDROID_PATHenv vars, or PATH. - OpenCode: always returns
true(SDK is bundled). - Agents without availability checks are registered unconditionally.
- Agents can implement an
- Profiles (
core/agents/profiles)- Shared profile CRUD lives in the
corepackage and is consumed byprojects/routes.ts. - Create/update/delete operations emit
agent.profile.changed(kind + profile metadata). - All profile schemas extend
BaseProfileSchemafor consistent field handling.
- Shared profile CRUD lives in the
- Runners
- Agents implement
Agent.run/resumeviaSdkAgentbase class. - Lifecycle hooks (
onRunStart(ctx, profile, mode),onRunEnd(ctx, profile, mode)) handle grouper setup/cleanup. Themodeparameter is'run'or'resume'. - The attempts service calls into the agent and forwards streamed events via
emit.
- Agents implement
Key Entry Points
types.ts: Agent interfaces & capabilities.sdk.ts:SdkAgent<P, I>base class with lifecycle hooks.registry.ts: Registration + event integration, includinginitializeAgents()for dynamic registration.profiles/base.ts:BaseProfileSchemaandgetEffectiveInlinePrompt().sdk/executable.ts:locateExecutable()for CLI discovery used in availability checks.sdk/context-factory.ts: Inline task context factories.codex/,opencode/,droid/,shell/,echo/: Concrete agents.server/src/agents/registry.ts: Server-side agent initialization viainitializeServerAgents().
Implementing a New SDK Agent
-
Create profile schema extending
BaseProfileSchema: -
Create agent class extending
SdkAgent<P, I>: -
Add to the agent registry:
- For server-side agents, add to the
ALL_AGENTSarray inserver/src/agents/registry.ts. - Agents are registered dynamically via
initializeServerAgents()at startup. - Optionally implement
availability(): Promise<boolean>to skip registration when dependencies are missing.
- For server-side agents, add to the
Open Tasks
- Add UI feedback (toast/badge) reacting to
agent.profile.changed/agent.registeredevents. - Provide tests covering registry event emission and profile CRUD flows.
Testing
The agent system includes comprehensive tests for availability detection and dynamic registration:core/tests/agents.availability.test.ts: Tests agent availability checks for Codex, Droid, and OpenCode.core/tests/agents.registry.test.ts: TestsinitializeAgents()behavior with various availability scenarios.