GenAI Project Context
Defines a Go library that wraps Gemini, OpenAI, and Ollama under a single interface with built-in tools and retry logic.
What this file does
Defines a Go library that wraps Gemini, OpenAI, and Ollama under a single interface with built-in tools and retry logic.
When to use it
- Building a Go application that needs to switch between multiple AI providers
- Adding file, GitHub, or memory tools to an AI-powered Go service
- Creating a reusable AI client wrapper for a monorepo or SDK
- Setting up a new Go project with structured provider and tool abstractions
Assumes this stack
GenAI Project Context
Project Overview
This is a Go library that provides a unified wrapper interface for various Generative AI providers. The library allows developers to easily switch between different AI providers (like Gemini, OpenAI, Ollama) while maintaining consistent interfaces for model interactions and tool usage.
Key Features
- Multi-provider Support: Unified interface for Gemini, OpenAI, Ollama, and planned support for Anthropic and Azure
- Tool Integration: Built-in tools for file operations, GitHub interactions, and extensible tool categories
- Chat and Generation APIs: Both streaming chat interfaces and simple text generation
- Automatic Retries: Built-in retry mechanisms for rate-limited or failed API calls
- Structured Tool Definitions: Strongly typed tool definitions with parameter specifications
Main Components
- Providers: Abstraction layer for different AI service providers
- Models: Interface for interacting with specific AI models
- Clients: Low-level API clients for each provider
- Tools: Pre-built functions that AI models can invoke
- Chats: Streaming conversation interface
Project Structure
.
├── client.go # Client implementations for each provider
├── gemini.go # Gemini-specific functionality and retry logic
├── model.go # Model abstraction and parameter handling
├── ollama.go # Ollama-specific implementations
├── openai.go # OpenAI-specific implementations
├── provider.go # Provider abstraction and main interfaces
├── tools/ # Tool implementations (file operations, GitHub, memory, etc.)
├── examples/ # Usage examples for each provider
└── go.mod # Go module dependencies
Supported Providers
Currently supported:
- Gemini (Google)
- OpenAI
- Ollama
Planned support:
- Anthropic
- Azure
Available Tools
File Operations
readFile- Read the contents of a filewriteFile- Write content to a filelistFiles- List files in a directorytree- Display directory tree structurepwd- Get current working directory
GitHub Operations
get_issues- Retrieve GitHub issuescreate_issue- Create a new GitHub issueupdate_issue- Update an existing GitHub issuedelete_issue- Delete a GitHub issuegetAssignedIssues- Get issues assigned to a usergetAssignedPRs- Get pull requests assigned to a user- And more...
Memory Operations
memory_store- Store a memory with content and optional metadatamemory_retrieve- Retrieve memories based on semantic similarity to a querymemory_update- Update an existing memory by IDmemory_delete- Delete a memory by IDmemory_operation- Single tool with operation parameter for all memory functions
Planned Tool Categories
- Slack integration
- Code linting, formatting, and testing tools
Building and Running
Prerequisites
- Go 1.23.6 or later
- API keys for the providers you intend to use
Dependencies
Main dependencies include:
github.com/google/generative-ai-go- Google Gemini SDKgithub.com/ollama/ollama- Ollama API clientgithub.com/openai/openai-go- OpenAI SDKgithub.com/go-git/go-git/v5- Git operationsgithub.com/google/go-github/v60- GitHub API clientgithub.com/lib/pq- PostgreSQL driver (for Memory Tool)github.com/pgvector/pgvector-go- Go bindings for pgvector (for Memory Tool)
Install dependencies with:
go mod tidy
Environment Variables
Set API keys for the providers you're using:
export GEMINI_API_KEY="your-gemini-api-key"
export OPENAI_API_KEY="your-openai-api-key"
For the Memory Tool, you'll also need a PostgreSQL database with the pgvector extension:
export DATABASE_URL="postgresql://user:password@localhost:5432/database_name"
Usage Examples
Basic Text Generation
provider, err := genai.NewProvider(genai.GEMINI, genai.ProviderOptions{
APIKey: os.Getenv("GEMINI_API_KEY"),
})
if err != nil {
panic(err)
}
response, err := provider.Generate(genai.ModelOptions{
ModelName: "gemini-2.0-flash-exp",
}, "Hello, world!")
Chat Interface with Tools
tools, err := tools.GetTools([]string{"getAssignedIssues", "pwd", "listFiles"})
if err != nil {
panic(err)
}
chat := provider.Chat(genai.ModelOptions{
ModelName: "gemini-2.0-flash-exp",
}, tools)
go func() {
for msg := range chat.Recv {
fmt.Println(msg)
chat.Done <- true
}
}()
chat.Send <- "What issues am I assigned to?"
<-chat.Done
Memory Tool Usage
// In a real application, you would create an embedding provider and pass it to InitializeMemoryTool
// For example:
// embeddingProvider, err := genai.NewProvider(genai.OPENAI, genai.ProviderOptions{
// APIKey: os.Getenv("OPENAI_API_KEY"),
// })
// if err != nil {
// log.Fatal(err)
// }
// Initialize the memory tool
config := tools.MemoryConfig{
DatabaseURL: os.Getenv("DATABASE_URL"),
EmbeddingProvider: "openai",
EmbeddingModel: "text-embedding-ada-002",
EmbeddingDims: 1536,
DefaultTopK: 5,
}
// Pass the embedding provider to InitializeMemoryTool
err = tools.InitializeMemoryTool(config, embeddingProvider)
//if err != nil {
// log.Fatal(err)
//}
// Store a memory
storeArgs := map[string]any{
"content": "User preference: prefers dark mode UI",
"metadata": map[string]any{
"type": "user_preference",
"user_id": "12345",
},
}
storeResult, err := tools.GetTool("memory_store")
if err != nil {
log.Fatal(err)
}
result, err := storeResult.Run(storeArgs)
if err != nil {
log.Fatal(err)
}
memoryID := result["id"].(string)
fmt.Printf("Stored memory with ID: %s\n", memoryID)
Development Conventions
Code Structure
- Each provider has its own implementation file (
gemini.go,ollama.go, etc.) - Tools are organized by category in the
tools/directory - Retry logic is implemented for resilient API calls
- Logging is done through the
logrinterface
Adding New Providers
- Create a new provider constant in
provider.go - Implement provider-specific client logic
- Add provider-specific model handling in
model.go - Implement any provider-specific tool integrations
Adding New Tools
- Define the tool in the appropriate category file in
tools/ - Register the tool in the
toolMapintools/tool.go - Implement provider-specific tool adapters if needed
- Add validation and error handling
Memory Tool
The Memory Tool provides persistent storage and retrieval of contextual information using vector embeddings. It leverages PostgreSQL with the pgvector extension to provide semantic search capabilities across conversation histories, document embeddings, and other contextual data.
Key features:
- Persistent Storage: Store text content with associated metadata
- Semantic Search: Retrieve memories based on semantic similarity
- Memory Management: Update and delete memory entries
- Configurable Embeddings: Customizable embedding dimensions and models
The Memory Tool has been refactored to be part of the tools package, eliminating the redundant standalone memory package while maintaining all existing functionality.
When adding new features to the Memory Tool:
- Extend the
MemoryToolstruct and its methods intools/memory.go - Update the tool wrapper functions if new operations are added
- Ensure proper error handling and context usage
- Update the example in
examples/memory/main.goif applicable
Testing
Run tests with:
go test ./...
Note: Some tests may require valid API keys to run integration tests against actual services.
What's inside
7 sections covering project overview, structure, providers, tools, usage, conventions, and testing with 6 code examples
Change this for your project
- Replace
jbutlerdev/genaiwith your own module path - Replace
GEMINI_API_KEYandOPENAI_API_KEYwith your own environment variable names - Replace
gemini-2.0-flash-expwith the model identifier you intend to use - Replace
text-embedding-ada-002and1536with your embedding model and dimensions
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Organising providers into separate files with a shared interface for easy swapping
- Grouping tools by category (file, GitHub, memory) with a central registration map
- Using a memory tool backed by vector embeddings for persistent semantic search
Related Documents
Zig 0.16.0 Context Document for LLMs
Documents breaking changes from Zig 0.13/0.14 to 0.16.0, covering syntax, I/O, build system, and standard library updates.
绘制对比图片 KITTI
Documents the topic remapping and data flow needed to connect Fast-LIO2 frontend with SC-PGO backend for KITTI evaluation.
Beads Workflow Context
Guides when to use bd graph-based issue tracker versus TodoWrite for session vs multi-session work, with commands and workflows.
EPIC: usda-data-crush-stats
Maps a multi-year USDA grape crush data pipeline from raw downloads through bronze, silver, and gold layers to final CSV fact and dimension tables.