plugin-architecture-patterns

plugin architecture patterns

7,385 stars

Best use case

plugin-architecture-patterns is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

plugin architecture patterns

Teams using plugin-architecture-patterns should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/plugin-architecture-patterns/SKILL.md --create-dirs "https://raw.githubusercontent.com/kreuzberg-dev/kreuzberg/main/.ai-rulez/skills/plugin-architecture-patterns/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/plugin-architecture-patterns/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How plugin-architecture-patterns Compares

Feature / Agentplugin-architecture-patternsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

plugin architecture patterns

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

## priority: critical

# Plugin Architecture & Registration

## Plugin Types

| Type | Trait | Location |
|------|-------|----------|
| Document Extractor | `DocumentExtractor: Plugin` | `plugins/extractor/trait.rs` |
| OCR Backend | `OcrBackend: Plugin` | `plugins/ocr/trait.rs` |
| Post Processor | `PostProcessor: Plugin` | `plugins/processor/trait.rs` |
| Validator | `Validator: Plugin` | `plugins/validator/trait.rs` |

## DocumentExtractor Implementation

```rust
use crate::plugins::{DocumentExtractor, Plugin};
use async_trait::async_trait;

pub struct MyExtractor;

impl Plugin for MyExtractor {
    fn name(&self) -> &str { "my-extractor" }
    fn version(&self) -> String { env!("CARGO_PKG_VERSION").to_string() }
}

#[async_trait]
impl DocumentExtractor for MyExtractor {
    async fn extract_bytes(&self, content: &[u8], mime_type: &str, config: &ExtractionConfig)
        -> Result<ExtractionResult> { /* ... */ }

    fn supported_mime_types(&self) -> &[&str] { &["application/x-custom"] }
    fn priority(&self) -> i32 { 50 }

    // WASM support (optional)
    fn as_sync_extractor(&self) -> Option<&dyn SyncExtractor> { None }
}
```

## Priority System

| Range | Use |
|-------|-----|
| 0-25 | Fallback/low-quality |
| 26-49 | Alternative extractors |
| **50** | **Default (built-in)** |
| 51-75 | Premium/enhanced |
| 76-100 | Specialized/high-priority |

Registry selects **highest priority** extractor for each MIME type. Override built-ins with priority > 50.

## Registration

```rust
// In extractors/mod.rs → register_default_extractors()
let registry = get_document_extractor_registry();
let mut registry = registry.write()
    .map_err(|e| KreuzbergError::Other(format!("Registry lock poisoned: {}", e)))?;
registry.register(Arc::new(MyExtractor::new()))?;
```

## Feature-Gated Registration

```rust
#[cfg(feature = "office")]
{
    registry.register(Arc::new(DocxExtractor::new()))?;
    registry.register(Arc::new(PptxExtractor::new()))?;
}
```

## PostProcessor Pattern

```rust
impl PostProcessor for MyProcessor {
    async fn process(&self, result: &mut ExtractionResult, config: &ExtractionConfig)
        -> Result<()> {
        result.content = process_content(&result.content);
        Ok(())
    }
    fn stage(&self) -> ProcessorStage { ProcessorStage::Middle }
}
```

Stages: `Early` → `Middle` → `Late`. Failures isolated (don't block others).

## Critical Rules

1. All plugins **MUST be `Send + Sync`**
2. Feature gate with `#[cfg(feature = "...")]` for optional formats
3. Use `#[async_trait]` for `DocumentExtractor`
4. Initialization via `ensure_initialized()` (lazy, called before first extraction)
5. Plugin names: kebab-case (e.g., `"pdf-extractor"`)