# Can PrimeAgent Be Extended with Custom Modules? A Complete Guide to the Plugin Architecture

> Discover how to extend PrimeAgent with custom modules using its plugin architecture. Learn about AI providers, coding skills, TUI components, and config hooks to add functionality easily.

- Repository: [Prime Intellect/prime-agent](https://github.com/PrimeIntellect-ai/prime-agent)
- Tags: how-to-guide
- Published: 2026-09-08

---

**Yes, PrimeAgent is designed as a modular, plugin-friendly platform with four official extension points—AI providers, coding-agent skills, TUI components, and configuration hooks—that let developers add functionality without modifying core source code.**

PrimeAgent separates its **core services** (AI provider handling, coding-agent orchestration, and terminal UI rendering) from **extension points** discovered at startup through glob patterns. This architecture, implemented in the `PrimeIntellect-ai/prime-agent` repository, enables dynamic loading of custom modules from the `plugins/` directory without requiring a full rebuild.

---

## AI Providers: Adding Custom LLM Backends

The AI provider system in [`packages/ai/src/providers/register-builtins.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/providers/register-builtins.ts) uses a lazy-loading registration pattern. You implement a standard interface and register your provider by name.

### Provider Interface Requirements

Your provider must export two streaming functions:

- `stream(model, messages, opts)` — full streaming with metadata
- `streamSimple(model, messages, opts)` — simplified text-only streaming

Both return `AssistantMessageEventStream` objects defined in `packages/ai/src/types`.

### Implementation Example

```typescript
// packages/ai/src/providers/my-custom-provider.ts
import {
  AssistantMessageEventStream,
  StreamOptions,
} from "../types";

export interface MyProviderOptions extends StreamOptions {
  temperature?: number;
}

export async function stream(
  model: string,
  messages: any[],
  opts: MyProviderOptions,
): Promise<AssistantMessageEventStream> {
  // Translate your LLM's response format to AssistantMessageEventStream
  return new ReadableStream({
    start(controller) {
      // Stream events matching the expected shape
    }
  });
}

export async function streamSimple(
  model: string,
  messages: any[],
  opts: MyProviderOptions
): Promise<ReadableStream<string>> {
  // Simplified text-only output
}

```

### Registration

Lazy-load your provider in the registry to avoid initialization overhead:

```typescript
// packages/ai/src/providers/register-builtins.ts
import { registerBuiltinProvider } from "./registry";

registerBuiltinProvider("my-custom-api", async () =>
  import("./my-custom-provider")
);

```

When a user specifies `api: "my-custom-api"` in their configuration, PrimeAgent dynamically imports and instantiates your provider.

---

## Coding-Agent Skills: Adding Custom Commands

Skills extend PrimeAgent's command vocabulary. The package manager in [`packages/coding-agent/src/package-manager.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/package-manager.ts) scans `plugins/*/skills` at startup and auto-discovers modules matching the skill interface.

### Skill Structure

Each skill requires:
- [`SKILL.md`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/SKILL.md) — documentation for the LLM and users
- [`skill.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/skill.ts) — TypeScript module exporting a `Skill` object

### Complete Skill Example

```typescript
// plugins/pdf-to-markdown/skills/pdf-to-markdown/skill.ts
import { Skill } from "coding-agent";

export const skill: Skill = {
  name: "pdf-to-markdown",
  description: "Convert a PDF file to Markdown text",
  async run({ args, context }) {
    const [pdfPath] = args;
    if (!pdfPath) {
      throw new Error("Usage: pdf-to-markdown <path>");
    }
    // Your conversion logic here
    const markdown = await convertPdf(pdfPath);
    return { output: markdown };
  },
};

```

```markdown
<!-- plugins/pdf-to-markdown/skills/pdf-to-markdown/SKILL.md -->

# pdf-to-markdown

Converts a PDF document to Markdown.

## Usage

```

pdf-to-markdown <file-path>

```

## Examples

Convert a research paper:

```

pdf-to-markdown ./paper.pdf

```

```

Upon restart, PrimeAgent recognizes `/run pdf-to-markdown ./doc.pdf` as a valid command in both CLI and TUI modes.

---

## TUI Components: Extending the Terminal Interface

PrimeAgent's terminal UI, built on Blessed, exposes extension points in [`packages/tui/src/index.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/tui/src/index.ts) for custom widgets and key bindings.

### Widget Implementation

```typescript
// packages/tui/src/custom-status.ts
import { Box } from "blessed";

export function createStatusWidget(): Box {
  const widget = new Box({
    top: "100%-1",
    left: 0,
    width: "100%",
    height: 1,
    style: { bg: "gray", fg: "white" },
    tags: true,
    content: "{center}Custom Provider: Ready{/center}",
  });

  // Expose update method for external callers
  (widget as any).setStatus = (text: string) => {
    widget.setContent(`{center}${text}{/center}`);
    widget.screen.render();
  };

  return widget;
}

```

### Integration Point

```typescript
// packages/tui/src/index.ts
import { createStatusWidget } from "./custom-status";
import { DEFAULT_EDITOR_KEYBINDINGS } from "./keys";

export function init(screen: blessed.Widgets.Screen) {
  const status = createStatusWidget();
  screen.append(status);

  // Add custom key binding
  DEFAULT_EDITOR_KEYBINDINGS["C-x"] = () => {
    status.setStatus("Action triggered!");
  };

  // ... existing initialization
}

```

The widget integrates immediately because `screen.append()` registers it with Blessed's rendering loop.

---

## Configuration Hooks: Runtime Behavior Modification

PrimeAgent's configuration system supports extension through environment variables and JSON configuration, resolved in two key files:

| File | Purpose | Extension Method |
|------|---------|------------------|
| [`packages/ai/src/env-api-keys.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/env-api-keys.ts) | API key resolution | Add new provider API key patterns |
| [`packages/coding-agent/src/core/model-resolver.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/model-resolver.ts) | Default model mapping | Register defaults for custom providers |

Both files use dynamic property access, so new environment variables or config keys become automatically available throughout the system without type definition changes.

---

## Key Architectural Files for PrimeAgent Extension

Understanding these files clarifies how the plugin system operates:

- **[`packages/ai/src/providers/register-builtins.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/providers/register-builtins.ts)** — Central AI provider registry with lazy-loading infrastructure

- **[`packages/coding-agent/src/package-manager.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/package-manager.ts)** — Skill discovery engine; implements `plugins/*/skills` glob scanning

- **[`packages/tui/src/index.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/tui/src/index.ts)** — TUI initialization hub; mounting point for custom components

- **[`packages/ai/src/env-api-keys.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/ai/src/env-api-keys.ts)** — Environment-based configuration resolver

- **[`packages/coding-agent/src/core/model-resolver.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/core/model-resolver.ts)** — Model-to-provider mapping defaults

---

## Summary

PrimeAgent's extension architecture enables custom module integration through four mechanisms:

- **AI providers** — Implement `stream`/`streamSimple` interfaces and register in [`register-builtins.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/register-builtins.ts) for lazy-loaded LLM support
- **Skills** — Create `plugins/<name>/skills/<skill>/` directories with [`skill.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/skill.ts) and [`SKILL.md`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/SKILL.md) for auto-discovered commands
- **TUI widgets** — Export Blessed components from `packages/tui/src/` and append to the screen instance
- **Configuration** — Extend [`env-api-keys.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/env-api-keys.ts) or [`model-resolver.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/model-resolver.ts) for runtime behavior customization

All extension points use **dynamic `import()`** and **glob-based discovery**, enabling drop-in functionality without recompiling the core project.

---

## Frequently Asked Questions

### Does PrimeAgent require rebuilding to add custom modules?

No. The package manager and provider registry use dynamic `import()` statements with glob patterns (`plugins/*/skills`). Place your code in the correct directory structure and restart PrimeAgent—the new functionality loads automatically without a build step.

### What interface must a custom AI provider implement?

Your provider must export `stream(model, messages, opts)` and `streamSimple(model, messages, opts)` functions returning `AssistantMessageEventStream` or `ReadableStream<string>` respectively, as defined in `packages/ai/src/types`. Register via `registerBuiltinProvider()` in [`register-builtins.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/register-builtins.ts).

### Can skills access the full PrimeAgent context?

Yes. The `Skill.run` method receives a context object containing `args` (parsed arguments), `fs` (sandboxed filesystem access), and `llm` (query interface to the active provider). Check [`packages/coding-agent/src/types.ts`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/packages/coding-agent/src/types.ts) for the complete `SkillContext` interface.

### How do I debug a skill that isn't loading?

Verify three things: (1) your file path matches `plugins/*/skills/<name>/skill.ts`, (2) the file exports `skill` as a named export matching the `Skill` interface, and (3) [`SKILL.md`](https://github.com/PrimeIntellect-ai/prime-agent/blob/main/SKILL.md) exists in the same directory. The package manager logs discovery results when `DEBUG=prime-agent` is set in your environment.