What Is the `internal/plugins/ai` Directory in Fabric? The AI Vendor Abstraction Layer Explained
The internal/plugins/ai directory is the core AI vendor abstraction layer that unifies how Fabric communicates with dozens of AI providers through a single Vendor interface.
This directory houses the plugin architecture that allows Fabric to treat OpenAI, Anthropic, Gemini, Azure, Ollama, and numerous other services as interchangeable backends. By encapsulating provider-specific HTTP clients, authentication, and request formatting behind a common contract, the internal/plugins/ai package enables Fabric’s CLI, REST API, and pattern engine to switch models with a single flag.
Core Purpose of the internal/plugins/ai Directory
The internal/plugins/ai package serves as Fabric’s AI-vendor layer, hiding the differences between disparate AI APIs behind a unified Go interface. Instead of scattering provider-specific logic throughout the codebase, Fabric centralizes it here, allowing the application to treat every AI service as a generic Vendor.
This design means adding support for a new provider requires only creating a new sub-directory that implements the Vendor interface; the rest of Fabric automatically discovers and uses it without modification.
Key Components and File Structure
The Vendor Interface (vendor.go)
At the heart of the directory is the Vendor interface defined in internal/plugins/ai/vendor.go. This contract mandates that every AI provider must implement methods for:
- Listing available models
- Streaming and non-streaming chat completions
- Reporting whether the vendor requires raw mode
By strictly defining this interface, Fabric ensures that any code importing internal/plugins/ai can interact with AI services without knowing which specific provider is configured.
Model Management Utilities (models.go)
The internal/plugins/ai/models.go file provides VendorsModels, a utility struct that aggregates models across all registered vendors. It offers helper methods for:
- Grouping models by vendor name
- Filtering by specific vendor (case-insensitive)
- Case-insensitive lookups for model names
- Pretty-printing model lists for CLI output
These utilities power Fabric’s --listmodels flag and ensure users can select models using intuitive, case-insensitive names.
Vendor Registry (vendors.go)
The internal/plugins/ai/vendors.go file acts as a central registry, aggregating constructors for every concrete vendor implementation. It dynamically exposes available providers to the rest of the application, allowing Fabric’s initialization code to discover and instantiate vendors without hard-coding provider names.
Provider Implementations
Each supported AI service resides in its own sub-directory under internal/plugins/ai/, implementing the Vendor interface with provider-specific logic:
openai/– OpenAI GPT models (openai/openai.go)anthropic/– Claude models (anthropic/anthropic.go)azure/– Azure OpenAI Service (azure/azure.go)vertexai/– Google Vertex AI (vertexai/vertexai.go)ollama/– Local Ollama instances (ollama/ollama.go)digitalocean/– DigitalOcean GenAI Platform (digitalocean/digitalocean.go)perplexity/– Perplexity API (perplexity/perplexity.go)lmstudio/– LM Studio local server (lmstudio/lmstudio.go)
Each directory contains the HTTP client configuration, request/response marshaling, authentication headers, and any provider-specific features like image generation or text-to-speech.
Dry-Run Mode (dryrun/dryrun.go)
For testing and development, internal/plugins/ai/dryrun/dryrun.go implements a special Vendor that performs no actual API calls. Instead, it returns the would-be request payload, enabling users to validate patterns and configurations using the --dry-run CLI flag without consuming API credits.
Practical Usage Examples
Listing Available Vendors via CLI
To see all registered AI providers that Fabric can use:
fabric --listvendors
This command queries the registry in vendors.go and prints every vendor that implements the Vendor interface.
Programmatic Model Selection
When building tools on top of Fabric’s Go API, use VendorsModels to handle model discovery and selection:
import (
"github.com/danielmiessler/fabric/internal/plugins/ai"
"fmt"
)
func main() {
// Initialize the model catalog
models := ai.NewVendorsModels()
// Add models from different vendors
models.AddGroupItems("OpenAI", "gpt-4o", "gpt-4-turbo")
models.AddGroupItems("Anthropic", "claude-3-opus-20240229", "claude-3-sonnet-20240229")
// Filter to specific vendor (case-insensitive)
openAIModels := models.FilterByVendor("openai")
// Find model with case-insensitive matching
modelName := openAIModels.FindModelNameCaseInsensitive("GPT-4O")
fmt.Println(modelName) // Output: gpt-4o
}
The helper methods FilterByVendor and FindModelNameCaseInsensitive are defined in internal/plugins/ai/models.go.
Direct Vendor Integration
For advanced use cases requiring direct provider access, instantiate a specific vendor implementation:
import (
"context"
"github.com/danielmiessler/fabric/internal/plugins/ai/openai"
"github.com/danielmiessler/fabric/internal/chat"
)
func chatWithOpenAI(ctx context.Context) (string, error) {
// Create the OpenAI plugin
// Constructor defined in internal/plugins/ai/openai/openai.go
plugin := openai.NewPlugin()
// Prepare messages
messages := []*chat.ChatCompletionMessage{
{Role: "user", Content: "Explain the fabric pattern system"},
}
// Send request using the Vendor interface method
response, err := plugin.Send(ctx, messages, nil)
return response, err
}
The Send method implements the Vendor interface contract defined in vendor.go.
Testing with Dry-Run Mode
Validate patterns without API costs using the dry-run implementation:
import (
"context"
"github.com/danielmiessler/fabric/internal/plugins/ai/dryrun"
"github.com/danielmiessler/fabric/internal/chat"
"fmt"
)
func previewPattern() {
// Initialize dry-run plugin
dr := dryrun.NewPlugin()
// Create test message
msg := &chat.ChatCompletionMessage{
Role: "user",
Content: "Summarize this article",
}
// Execute without network call
result, _ := dr.Send(context.Background(), []*chat.ChatCompletionMessage{msg}, nil)
fmt.Println("Would send:", result)
}
This corresponds to the --dry-run CLI flag and is implemented in internal/plugins/ai/dryrun/dryrun.go.
Summary
- The
internal/plugins/aidirectory is Fabric’s AI vendor abstraction layer, located at the heart of the plugin architecture. - It defines a strict
Vendorinterface invendor.gothat standardizes model listing, chat completion, and streaming across all providers. models.goprovides helper utilities for grouping, filtering, and case-insensitive model lookup, powering CLI commands like--listmodels.- Each AI service (OpenAI, Anthropic, Gemini, Azure, Ollama, etc.) lives in its own sub-directory, implementing the
Vendorinterface with provider-specific HTTP clients and authentication. dryrun/dryrun.goenables cost-free testing by implementing a no-network vendor that returns request payloads for the--dry-runflag.- Because the package lives under
internal/, it enforces encapsulation, ensuring vendors are only accessed through the defined interfaces, making the system modular and extensible.
Frequently Asked Questions
What is the purpose of the internal/plugins/ai directory in Fabric?
The internal/plugins/ai directory serves as Fabric’s core AI vendor abstraction layer. It defines the Vendor interface and houses concrete implementations for every supported AI provider, allowing the rest of the application to interact with OpenAI, Anthropic, Gemini, and other services through a single, standardized API without handling provider-specific details.
How does Fabric add support for a new AI provider?
To add a new AI provider, developers create a new sub-directory under internal/plugins/ai/ (for example, newprovider/) and implement the Vendor interface defined in vendor.go. This requires implementing methods for listing models, sending chat requests, and handling streaming responses. Once implemented, the provider is registered in vendors.go, making it automatically available to the CLI and API without modifying other parts of the codebase.
What is the difference between vendor.go and vendors.go in the internal/plugins/ai directory?
vendor.go defines the abstract Vendor interface that specifies the contract all AI providers must fulfill, including method signatures for chat completion and model listing. In contrast, vendors.go acts as a concrete registry that imports and aggregates all available vendor implementations (OpenAI, Anthropic, etc.), providing a central point for the application to discover and instantiate specific providers at runtime.
How can I test Fabric patterns without consuming API credits?
Fabric provides a dry-run mode through the dryrun package located at internal/plugins/ai/dryrun/dryrun.go. You can activate this via the --dry-run CLI flag, which instantiates a special Vendor implementation that returns the would-be request payload without making actual HTTP calls. This allows you to validate pattern syntax, message formatting, and vendor selection logic without incurring costs or network latency.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →