first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
---
title: "Adding config store"
description: "Learn how to contribute a backend for the config store in Bifrost"
icon: "database"
---
The Config store in Bifrost is designed to be extensible, allowing support for different database backends. This guide outlines the philosophy, architecture, and steps to add support for a new database.
This guide will help you add a new custom backend for the config store. Currently, bifrost supports PostgreSQL and SQLite.
## Setup
We assume you have some idea about how Bifrost works and you have already [set up bifrost for local development](./setting-up-repo).
## Architecture
The system is built around a few key components:
1. **`ConfigStore` Interface**: This is the heart of the system. It defines all the methods required to read and write configuration data (e.g., `GetClientConfig`, `UpdateProvider`). Any valid store must implement this interface.
2. **`RDBConfigStore`**: A reusable implementation for Relational Databases (RDBs). It uses an ORM (GORM) to map the interface methods to SQL queries. If your target database is supported by GORM, you can likely reuse this implementation entirely.
3. **Configuration Structs**: Each database type has its own configuration struct (e.g., `SQLiteConfig`, `PostgresConfig`) that defines how to connect to it.
## Config store structure
The config store is used to save all your bifrost configurations. This can be a simple in-memory store or a postgres database. Bifrost exposes a single interface (ConfigStore) for all configuration CRUD (Create, Read, Update, Delete) operations.
Any custom backend for config store should implement the `ConfigStore` interface. The interface is defined in [configstore/store.go](https://github.com/maximhq/bifrost/blob/main/framework/configstore/store.go).
## Using GORM
It is recommended to use GORM for the config store. GORM is a popular ORM (Object-Relational Mapping) library for Go. It provides a simple and efficient way to interact with databases.
GORM provides implementations for the functions listed in the `ConfigStore` interface. This significantly simplifies the implementation of the config store (see [postgres.go](https://github.com/maximhq/bifrost/blob/main/framework/configstore/postgres.go) as an example).
## Conventions
When adding a new database, please follow these conventions:
### File Placement
* The main interface and factory method are in `framework/configstore/store.go`.
* Shared RDB implementation details are in `framework/configstore/rdb.go`.
* Create a new file for your database implementation, named after the database (e.g., `framework/configstore/postgres.go`).
### Implementation Steps
1. Add a new constant to the `ConfigStoreType` in `store.go`.
2. Define a struct in your new database file that contains all connection parameters (host, port, credentials, etc.).
3. Implement the Factory Function: Create a function that:
* Accepts the configuration struct and a logger
* Opens a GORM database connection using your database's GORM driver
* Returns an instance of `RDBConfigStore` with the database connection
* Runs migrations to ensure the schema is up-to-date
4. Update the Factory: Add a new case in the `NewConfigStore` function in `store.go` to handle your new database type.
5. If needed, update the `Config` struct's `UnmarshalJSON` method in `config.go` to properly parse your configuration.
### Error Handling
Make sure to properly handle errors during:
* Database connection establishment
* Migration execution
* Connection cleanup (especially important if migrations fail)
### Testing Considerations
* Ensure your implementation can handle concurrent access to the database
* Consider connection pooling and timeout settings appropriate for your database
* Test with both empty and populated databases
* Verify that all `ConfigStore` interface methods work correctly with your backend
## Getting Help
If you need help, please reach out to the Bifrost team on [Discord](https://discord.gg/exN5KAydbU).

View File

@@ -0,0 +1,77 @@
---
title: "Adding a log store"
description: "Learn how to contribute a backend for the log store in Bifrost"
icon: "database"
---
The Log store in Bifrost is designed to be extensible, allowing support for different database backends. This guide outlines the philosophy, architecture, and steps to add support for a new database.
This guide will help you add a new custom backend for the log store. Currently, Bifrost supports PostgreSQL and SQLite.
## Setup
We assume you have some idea about how Bifrost works and you have already [set up bifrost for local development](./setting-up-repo).
## Architecture
The system is built around a few key components:
1. **`LogStore` Interface**: This is the heart of the system. It defines all the methods required to create, read, search, and manage log entries (e.g., `Create`, `SearchLogs`, `GetStats`, `Flush`). Any valid store must implement this interface.
2. **`RDBLogStore`**: A reusable implementation for Relational Databases (RDBs). It uses an ORM (GORM) to map the interface methods to SQL queries. If your target database is supported by GORM, you can likely reuse this implementation entirely.
3. **Configuration Structs**: Each database type has its own configuration struct (e.g., `SQLiteConfig`, `PostgresConfig`) that defines how to connect to it.
## Log store structure
The log store is used to persist all request/response logs from your Bifrost proxy. This can be a lightweight SQLite database or a production-grade Postgres database. Bifrost exposes a single interface (`LogStore`) for all logging operations.
Any custom backend for log store should implement the `LogStore` interface. The interface is defined in [logstore/store.go](https://github.com/maximhq/bifrost/blob/main/framework/logstore/store.go).
## Using GORM
It is recommended to use GORM for the log store. GORM is a popular ORM (Object-Relational Mapping) library for Go. It provides a simple and efficient way to interact with databases.
GORM provides implementations for the functions listed in the `LogStore` interface. This significantly simplifies the implementation of the log store (see [postgres.go](https://github.com/maximhq/bifrost/blob/main/framework/logstore/postgres.go) as an example).
## Conventions
When adding a new database, please follow these conventions:
### File Placement
* The main interface and factory method are in `framework/logstore/store.go`.
* Shared RDB implementation details are in `framework/logstore/rdb.go`.
* Create a new file for your database implementation, named after the database (e.g., `framework/logstore/postgres.go`).
### Naming Conventions
* Define a constant for your database type in `store.go` following the pattern `LogStoreType[DatabaseName]` (e.g., `LogStoreTypePostgres`).
* Name your config struct as `[DatabaseName]Config` (e.g., `PostgresConfig`).
* Name your constructor function as `new[DatabaseName]LogStore` (e.g., `newPostgresLogStore`).
### Implementation Steps
1. Add a new constant to the `LogStoreType` in `store.go`.
2. Define a struct in your new database file that contains all connection parameters (host, port, credentials, etc.).
3. Create a function that:
* Accepts the configuration struct and a logger
* Opens a GORM database connection using your database's GORM driver
* Returns an instance of `RDBLogStore` with the database connection
* Runs migrations to ensure the schema is up-to-date
4. Add a new case in the `NewLogStore` function in `store.go` to handle your new database type.
5. If needed, update the `Config` struct's `UnmarshalJSON` method in `config.go` to properly parse your configuration.
### Error Handling
Make sure to properly handle errors during:
* Database connection establishment
* Migration execution
* Connection cleanup (especially important if migrations fail)
### Testing Considerations
* Ensure your implementation can handle concurrent access to the database
* Consider connection pooling and timeout settings appropriate for your database
* Test with both empty and populated databases
* Verify that all `LogStore` interface methods work correctly with your backend
## Getting Help
If you need help, please reach out to the Bifrost team on [Discord](https://discord.gg/exN5KAydbU).

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,114 @@
---
title: "Adding a vector store"
description: "Learn how to contribute a backend for the vector store in Bifrost"
icon: "circle-nodes"
---
The Vector store in Bifrost is designed to be extensible, allowing support for different vector database backends. This guide outlines the philosophy, architecture, and steps to add support for a new vector database.
This guide will help you add a new custom backend for the vector store. Currently, Bifrost supports Weaviate, Redis and Qdrant.
## Setup
We assume you have some idea about how Bifrost works and you have already [set up bifrost for local development](./setting-up-repo).
## Architecture
The system is built around a few key components:
1. **`VectorStore` Interface**: This is the heart of the system. It defines all the methods required for vector operations including namespace management, similarity search, CRUD operations, and filtering (e.g., `CreateNamespace`, `GetNearest`, `Add`, `Delete`). Any valid store must implement this interface.
2. **Database-Specific Stores**: Unlike relational stores, vector databases have unique characteristics. Each implementation (e.g., `WeaviateStore`, `RedisStore`) uses the native client library for that database to provide optimal performance.
3. **Configuration Structs**: Each database type has its own configuration struct (e.g., `WeaviateConfig`, `RedisConfig`) that defines connection details and database-specific settings.
4. **Query Abstraction**: The `Query` type provides a common way to express filters across different backends, with each implementation translating to its native query language.
## Vector store structure
The vector store is used for semantic search and similarity matching in Bifrost. This enables features like RAG (Retrieval-Augmented Generation) and intelligent document retrieval. Bifrost exposes a single interface (`VectorStore`) for all vector operations.
Any custom backend for vector store should implement the `VectorStore` interface. The interface is defined in [vectorstore/store.go](https://github.com/maximhq/bifrost/blob/main/framework/vectorstore/store.go).
## Key interface methods
The `VectorStore` interface includes methods for:
* **Namespace Management**: Create and delete namespaces (collections/indices)
* **Health Checks**: Ping to verify connectivity
* **Data Operations**: Add, get, and delete vector embeddings with metadata
* **Similarity Search**: Find nearest neighbors using vector similarity
* **Filtering**: Query with metadata filters and pagination
* **Batch Operations**: Retrieve or delete multiple items efficiently
## Using native clients
Unlike the config and log stores which use GORM, vector stores use native database clients. This is because:
* Vector databases have specialized APIs optimized for similarity search
* Each database has unique features (e.g., Weaviate's GraphQL, Redis's vector syntax)
* Performance is critical for vector operations
You should use the official Go client library for your target vector database.
## Conventions
When adding a new database, please follow these conventions:
### File Placement
* The main interface and factory method are in `framework/vectorstore/store.go`.
* Create a new file for your database implementation, named after the database (e.g., `framework/vectorstore/pinecone.go`).
### Naming Conventions
* Define a constant for your database type in `store.go` following the pattern `VectorStoreType[DatabaseName]` (e.g., `VectorStoreTypeWeaviate`).
* Name your config struct as `[DatabaseName]Config` (e.g., `WeaviateConfig`).
* Name your store struct as `[DatabaseName]Store` (e.g., `WeaviateStore`).
* Name your constructor function as `new[DatabaseName]Store` (e.g., `newWeaviateStore`).
### Implementation Steps
1. Add a new constant to the `VectorStoreType` in `store.go`.
2. Define a configuration struct in your new database file that contains all connection parameters (host, API keys, timeout settings, etc.).
3. Create a store struct that holds the database client, configuration, and logger.
4. Implement all methods from the `VectorStore` interface:
* Connection and health checks (`Ping`)
* Namespace/collection management (`CreateNamespace`, `DeleteNamespace`)
* Single and batch retrieval (`GetChunk`, `GetChunks`)
* Filtered queries (`GetAll` with pagination)
* Similarity search (`GetNearest`)
* Add/update operations (`Add`)
* Delete operations (`Delete`, `DeleteAll`)
* Cleanup (`Close`)
5. Implement query translation logic to convert the generic `Query` type to your database's native filter format.
6. Create a constructor function that initializes the database client and validates connectivity.
7. Update the `NewVectorStore` factory function in `store.go` to handle your new database type.
8. Update the `Config` struct's `UnmarshalJSON` method in `store.go` to properly parse your configuration.
### Query translation
Each vector database has its own query syntax. You'll need to implement functions to translate the generic `Query` type to your database's format. For example:
* Weaviate uses GraphQL-style filters
* Redis uses FT.SEARCH query syntax
Study the existing implementations (`buildWeaviateFilter`, `buildRedisQuery`) for patterns to follow.
### Error Handling
Make sure to properly handle errors during:
* Database connection establishment
* Client initialization and authentication
* Query execution (especially for complex similarity searches)
* Namespace creation and deletion
* Connection cleanup
### Testing Considerations
* Test all `VectorStore` interface methods with your backend
* Verify similarity search returns results in the correct order
* Test filtering with various query operators (Equal, GreaterThan, ContainsAny, etc.)
* Ensure pagination works correctly with cursors
* Test batch operations with different sizes
* Verify namespace isolation (data from one namespace doesn't leak to another)
* Consider performance benchmarks for large-scale vector operations
## Getting Help
If you need help, please reach out to the Bifrost team on [Discord](https://discord.gg/exN5KAydbU).

View File

@@ -0,0 +1,358 @@
---
title: "Code Conventions"
description: "Code style and convention guidelines for contributing to Bifrost."
icon: "brush"
---
## Commit Message Format
All commits to Bifrost should follow a standardized format. This ensures clear history and makes it easy to understand changes at a glance.
### Format
```
[type]: description
Optional body with more details
```
### Types
- **feat** - New feature
- **fix** - Bug fix
- **refactor** - Code refactoring (no feature change, no bug fix)
- **docs** - Documentation changes
- **test** - Test changes
- **chore** - Build, dependencies, tooling changes
- **perf** - Performance improvements
### Key Rule: Always List Affected Packages
For every commit, **explicitly mention all packages/directories that were modified**. This is crucial for understanding the scope of changes.
```
[fix]: Handle null pointer in model response
Affected packages:
- core/providers/openai/
- core/schemas/
Impact: Fixes intermittent crashes when provider returns malformed response
```
### Examples
**Good:**
```
[feat]: Add retry logic to MCP client manager
Implements exponential backoff for transient errors (connection timeouts, network issues).
Retries only for transient errors, fails immediately for permanent errors (auth, config).
Affected packages:
- core/mcp/clientmanager.go - Connection retry logic
- core/mcp/utils.go - Retry executor and error classification
- core/mcp/healthmonitor.go - Automatic reconnection
Tests:
- Added tests for retry backoff progression
- Added tests for error classification
```
**Better (if changes are significant to multiple packages):**
```
[feat]: Add resilient MCP connection handling
Commit 1: [feat]: MCP utils - Add retry executor with exponential backoff
Commit 2: [fix]: MCP client - Use retry logic for connection establishment
Commit 3: [feat]: MCP health monitor - Add automatic reconnection
```
## Go Code Conventions
### Style Guidelines
1. **Follow standard Go conventions**
- Use `gofmt` for formatting
- Run `make fmt` before committing
2. **Naming**
- Use meaningful variable names
- Avoid single letters except in loops
- Use `camelCase` for variables and functions
- Use `PascalCase` for exported types
3. **Comments**
- Comment exported functions and types
- Use clear, concise comments
- Explain *why*, not *what*
4. **Error Handling**
- Always check and handle errors
- Provide context in error messages
- Don't ignore errors with `_`
### Structure
```go
// Exported functions first
func NewClient(config Config) (*Client, error) {
// implementation
}
// Exported methods
func (c *Client) Do(ctx context.Context) error {
// implementation
}
// Unexported helper functions
func (c *Client) validate() error {
// implementation
}
```
### Documentation
Each package should have:
- A `package` comment
- Exported function/type comments
- Complex logic explanations
```go
// Package mcp provides Model Context Protocol integration
// for connecting AI models to external tools and services.
package mcp
// Client manages connections to MCP servers.
type Client struct {
// fields...
}
// Connect establishes a connection to the MCP server.
// Returns an error if the connection fails.
func (c *Client) Connect(ctx context.Context) error {
// implementation
}
```
## TypeScript/React Code Conventions
### Style Guidelines
1. **Use TypeScript** - Avoid `any` types when possible
2. **Use functional components** - No class components
3. **Props interface**
```typescript
interface ButtonProps {
onClick: () => void;
children: React.ReactNode;
}
```
4. **Naming**
- Components: `PascalCase`
- Functions/variables: `camelCase`
- Constants: `UPPER_SNAKE_CASE`
### Structure
```typescript
// Imports
import React from 'react';
import { useContext } from 'react';
// Types
interface Props {
id: string;
onSubmit: (data: FormData) => Promise<void>;
}
// Component
export const MyComponent: React.FC<Props> = ({ id, onSubmit }) => {
return (
<div>
{/* implementation */}
</div>
);
};
```
## Testing Conventions
### Go Tests
1. **Test file naming**: `*_test.go`
2. **Test function naming**: `Test<FunctionName>`
3. **Table-driven tests for multiple cases**
```go
func TestProcessRequest(t *testing.T) {
tests := []struct {
name string
input string
want string
wantErr bool
}{
{"valid input", "test", "result", false},
{"invalid input", "", "", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ProcessRequest(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("unexpected error: %v", err)
}
if got != tt.want {
t.Errorf("got %s, want %s", got, tt.want)
}
})
}
}
```
### Running Tests
```bash
# Run all tests
make test-all
# Run specific test suite
make test-core PROVIDER=openai
# Run specific test case
make test-core PROVIDER=openai TESTCASE=TestName/SubTest
```
## Documentation Conventions
### MDX Files
1. **Front matter**
```mdx
---
title: "Feature Name"
description: "Brief description of the feature"
icon: "icon-name"
---
```
2. **Headings** - Use H2 (`##`) as top level in body
3. **Code blocks** - Always include language: ` ```go`
4. **Links** - Use relative paths: `/features/caching`
### Examples
```mdx
---
title: "Semantic Caching"
description: "Intelligent response caching based on semantic similarity"
icon: "database"
---
## Overview
Semantic caching intelligently caches responses...
## Configuration
```yaml
plugins:
semantic_cache:
enabled: true
```
<Note>
This is important information that needs highlighting.
</Note>
## Benefits
- Reduces costs by 30-40%
- Improves latency for similar queries
```
## Pull Request Conventions
See [Raising a PR](/contributing/raising-a-pr) for detailed guidelines. Key points:
1. **Commit messages**: Follow `[type]: description` format
2. **Package listing**: Always mention affected packages
3. **Changelog updates**: Update `changelog.md` for each affected package
4. **Tests**: Ensure all tests pass before opening PR
5. **Documentation**: Update docs if behavior changes
## Changelog Format
For each package you modify, update its `changelog.md` file at the top with:
```
[type]: description [@Your Name](https://github.com/yourname)
```
**Example:**
```markdown
[feat]: add semantic caching support for image generation [@prathammaxim](https://github.com/prathammaxim)
[fix]: handle null pointer in response parsing [@username](https://github.com/username)
[refactor]: simplify model caching logic [@username](https://github.com/username)
```
**File locations:**
- `core/changelog.md`
- `framework/changelog.md`
- `transports/changelog.md`
- `plugins/{plugin-name}/changelog.md`
## Code Quality Standards
Before submitting code:
### Go Code
```bash
# Format code
make fmt
# Run linter
make lint
# Run tests
make test-all
```
### TypeScript/React
- Use ESLint configuration from project
- Run `npm run format` for formatting
- Ensure TypeScript compilation succeeds
## Key Principles
1. **Clarity** - Code should be easy to understand
2. **Consistency** - Follow existing patterns in codebase
3. **Testing** - All code should have tests
4. **Documentation** - Document public APIs and complex logic
5. **Simplicity** - Avoid over-engineering
6. **Performance** - Consider performance implications of changes
## Common Pitfalls
❌ **Don't:**
- Submit PRs without running tests
- Use `fmt.Println` for logging (use logger)
- Ignore error handling
- Create huge functions (>100 lines)
- Mix refactoring with feature changes
- Forget to list affected packages in commit messages
✅ **Do:**
- Run `make test-all` before opening PR
- Use structured logging
- Handle all error cases
- Keep functions focused and testable
- Make logical, focused commits
- Always mention affected packages and changes
## Getting Help
- See [Setting up the repository](/contributing/setting-up-repo) for development setup
- Check [Architecture docs](/architecture) to understand the codebase
- Ask in [Discord](https://discord.gg/exN5KAydbU) if you have questions

View File

@@ -0,0 +1,506 @@
---
title: "Raising a Pull Request"
description: "Guidelines for submitting high-quality pull requests to Bifrost."
icon: "code-pull-request"
---
## Before You Start
1. **Create an issue first** (if one doesn't exist) - Discuss the change with the maintainers
2. **Fork the repository** and create a feature branch
3. **Set up your development environment** using [these instructions](/contributing/setting-up-repo)
4. **Run tests locally** to ensure everything works
## Commit Message Format
All commits should follow a standardized format. **For each package/directory you modify, include a separate commit message line** describing the change in that package.
### Format
```
[type]: description
Additional details if needed (optional)
```
### Types
- **feat** - New feature
- **fix** - Bug fix
- **refactor** - Code refactoring (no feature change, no bug fix)
- **docs** - Documentation changes
- **test** - Test changes
- **chore** - Build, dependencies, tooling changes
- **perf** - Performance improvements
### Examples
**Single Package Change:**
```
[fix]: handle connection timeout in MCP client manager
```
**Multiple Packages:**
If your change affects multiple packages, include the package name or affected module in the description:
```
[fix]: MCP client - add retry logic to connection establishment
This fixes intermittent connection failures by implementing exponential backoff.
Affected packages:
- core/mcp/clientmanager.go
- core/mcp/healthmonitor.go
```
**Provider-Specific Changes:**
```
[fix]: OpenAI provider - handle streaming response errors
[feat]: Anthropic provider - add support for batch API
```
**Multiple Commits for Multiple Packages:**
If you're making significant changes to multiple packages, consider separate commits:
```bash
git commit -m "[feat]: Add retry mechanism to MCP core utilities"
git commit -m "[fix]: Update OpenAI integration with retry support"
git commit -m "[docs]: Document MCP resilience strategy"
```
### All Packages Modified Should Be Listed
When creating a commit, always mention which packages/components are affected:
```
[feat]: Add semantic caching plugin
Changes:
- plugins/semanticcache/ - Core caching logic
- core/bifrost.go - Plugin registration
- transports/bifrost-http/server.go - Cache middleware integration
Benefits:
- Reduces API costs by 30-40%
- Improves response latency for similar queries
```
<Tip>
Use a structured format that makes it easy to understand at a glance what changed and where.
</Tip>
## Maintaining Changelogs
For each package you modify, update the corresponding `changelog.md` file with your changes. Changelog entries are used to generate release notes and communicate changes to users.
### Changelog File Locations
Each package that receives updates should have a `changelog.md` file:
- `core/changelog.md` - Core package changes
- `framework/changelog.md` - Framework changes
- `transports/changelog.md` - Transport layer changes
- `plugins/{plugin-name}/changelog.md` - Specific plugin changes
### Changelog Entry Format
Each changelog entry follows this exact format:
```
[type]: description [@Your Name](https://github.com/yourname)
```
**Required Components:**
- **Type**: One of `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, or `perf`
- **Description**: Clear, concise description (under 100 characters)
- **Author**: Your GitHub profile link (recommended)
### Change Types Reference
| Type | Usage | Example |
|------|-------|---------|
| **feat** | New feature | `[feat]: add exponential backoff retry mechanism` |
| **fix** | Bug fix | `[fix]: handle connection timeout in MCP client` |
| **refactor** | Code refactoring (no behavior change) | `[refactor]: simplify model caching` |
| **docs** | Documentation updates | `[docs]: clarify semantic caching behavior` |
| **test** | Test additions/modifications | `[test]: add regression tests for retry logic` |
| **chore** | Build, dependencies, tooling | `[chore]: upgrade dependencies to latest versions` |
| **perf** | Performance improvements | `[perf]: optimize model lookup to O(1)` |
### Changelog Examples
**Good Examples:**
```markdown
[feat]: add exponential backoff retry mechanism [@prathammaxim](https://github.com/prathammaxim)
[fix]: handle null pointer in OpenAI response parsing [@contributor](https://github.com/contributor)
[perf]: optimize model lookup with hash map [@contributor](https://github.com/contributor)
```
**Poor Examples (avoid):**
```markdown
- update stuff
- minor changes
- fix bug
- added new thing
```
### How to Add Changelog Entries
1. **Edit the `changelog.md`** file in the affected package
2. **Add new entry at the TOP** of the file (most recent first)
3. **Follow the exact format**: `[type]: description [@name](https://github.com/user)`
4. **Include your author link** (optional but recommended)
**Example: Before and After**
**Before:**
```markdown
[feat]: added image generation request and response support
[chore]: added case-insensitive helper methods
```
**After (with new entry at top):**
```markdown
[fix]: handle connection timeout in retry logic [@your-name](https://github.com/your-name)
[feat]: add exponential backoff for transient errors [@your-name](https://github.com/your-name)
[feat]: added image generation request and response support
[chore]: added case-insensitive helper methods
```
### Multiple Package Changes
When your PR affects multiple packages, **add entries to each package's `changelog.md`**:
**Example Multi-Package Changelog:**
**core/changelog.md:**
```markdown
[feat]: add retry executor with exponential backoff [@contributor](https://github.com/contributor)
```
**transports/changelog.md:**
```markdown
[fix]: apply retry logic to connection establishment [@contributor](https://github.com/contributor)
```
**plugins/governance/changelog.md:**
```markdown
[chore]: update core dependency to latest version
```
### What to Include in Changelog
✅ **Do include:**
- Bug fixes that affect users
- New features
- Breaking changes
- Performance improvements
- Significant refactoring
- Documentation improvements
❌ **Don't include:**
- Internal code cleanup with no user impact
- Typo fixes in comments only
- Build system changes (unless significant)
- Minor test-only changes
### Changelog Best Practices
1. **Add entries at the TOP** of the `changelog.md` file (most recent first)
2. **One entry per logical change** - Don't combine unrelated changes
3. **Keep descriptions concise** - Under 100 characters
4. **Use consistent format** - `[type]: description`
5. **Include your GitHub link** - Helps recognize contributors
6. **Update all affected package changelogs** - Don't forget secondary packages
7. **Add changelog entry with your commit** - Don't wait until the end
### Format Consistency Rules
**DO's:**
- ✅ Use square brackets: `[feat]`
- ✅ Use colon separator: `[feat]:`
- ✅ Start with lowercase (unless proper noun)
- ✅ Be specific and concise
- ✅ Include GitHub profile link
- ✅ Add new entries at the top
**DON'Ts:**
- ❌ Don't use parentheses: `(feat)` or braces `{feat}`
- ❌ Don't use multiple spaces
- ❌ Don't mix formats in the same file
- ❌ Don't add entries at the bottom
- ❌ Don't use vague descriptions
### Complete PR Example with Changelogs
If your PR adds retry logic to multiple packages:
```
Commit: [feat]: Add retry logic with exponential backoff
Modified files:
- core/mcp/utils.go ← add retry executor
- core/mcp/clientmanager.go ← use retry logic
Update changelogs:
1. core/changelog.md:
[feat]: add exponential backoff retry mechanism [@your-name](https://github.com/your-name)
2. transports/changelog.md:
[fix]: apply retry logic to connection establishment [@your-name](https://github.com/your-name)
```
### Changelog Review Checklist
Before submitting a PR, verify:
- [ ] All packages modified have changelog entries
- [ ] Format is correct: `[type]: description [@name](https://github.com/user)`
- [ ] Entries are added at TOP of the file
- [ ] Author GitHub link is included
- [ ] Description is clear and concise (under 100 chars)
- [ ] Type is one of: feat, fix, refactor, docs, test, chore, perf
- [ ] Entries are added with the commit (not after)
## Pull Request Title
Keep PR titles concise and descriptive, following the same pattern:
```
[type]: Brief description of the change
```
Examples:
- `[feat]: Add rate limiting to governance plugin`
- `[fix]: Resolve deadlock in MCP retry logic`
- `[refactor]: Simplify model caching mechanism`
- `[docs]: Update contribution guidelines for commit messages`
## Pull Request Description
Use the following template for your PR description:
```markdown
## Description
Brief explanation of what this PR does and why it's needed.
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
- [ ] Refactoring
## Affected Packages
List all packages/directories modified:
- core/providers/openai/
- transports/bifrost-http/server/
- plugins/governance/
## Changes Made
- Specific change 1
- Specific change 2
- Specific change 3
## Testing
Describe how you tested these changes:
- [ ] Unit tests added/updated
- [ ] Integration tests passed
- [ ] Manual testing completed
## Checklist
- [ ] Code follows the project's code style
- [ ] Tests are passing locally (`make test-all`)
- [ ] Documentation is updated if needed
- [ ] No breaking changes (or breaking changes are documented)
- [ ] Commit messages follow the format: `[type]: description`
- [ ] All affected packages are mentioned in commit messages
## Related Issues
Closes #123
Relates to #456
```
## Best Practices
### 1. Keep PRs Focused
- One feature or fix per PR when possible
- If multiple related changes, group them logically by package
- Avoid mixing refactoring with feature changes
### 2. Commit Messages Matter
❌ **Bad:**
```
Update file
```
✅ **Good:**
```
[fix]: Handle null pointer in OpenAI response parsing
```
❌ **Bad:**
```
[feat]: Major update to semantic cache
```
✅ **Good:**
```
[feat]: Add semantic cache initialization with retry logic
Changes:
- plugins/semanticcache/ - Add retry mechanism
- core/bifrost.go - Register cache handler
- docs/ - Add usage documentation
```
### 3. Include All Affected Packages
Always explicitly list which packages/directories are modified:
```
[fix]: Resolve SSE connection issues
Affected components:
- core/mcp/clientmanager.go - Add connection validation
- core/mcp/healthmonitor.go - Improve health checks
- core/mcp/utils.go - Fix retry context handling
```
### 4. Test Thoroughly
Before opening a PR:
```bash
# Run all tests
make test-all
# Run specific test suite
make test-core PROVIDER=openai
# Format code
make fmt
# Lint code
make lint
```
### 5. Small, Reviewable PRs
- Aim for &lt;400 lines changed per PR
- If larger, break into logical commits
- Each commit should be independently reviewable
### 6. Update Documentation
- Update relevant `.mdx` files in `/docs`
- Add comments for complex logic
- Update README.md if behavior changes
## Code Review Checklist
Before requesting review, ensure:
✅ All commits follow `[type]: description` format
✅ All affected packages are explicitly mentioned
✅ No merge conflicts
✅ All tests pass (`make test-all`)
✅ Code is properly formatted (`make fmt`)
✅ No linting issues (`make lint`)
✅ Documentation is updated
✅ PR description is clear and complete
## During Code Review
- Respond to feedback promptly
- Push new commits for requested changes (don't force-push to avoid confusion)
- Mark conversations as resolved when addressed
- Ask for clarification if feedback is unclear
## Merging
Once approved:
- The maintainer will handle the merge
- Your commits will be preserved in the history
- Ensure your branch is up-to-date with `main` before final approval
## Common Pitfalls to Avoid
1. ❌ **Vague commit messages** - Always be specific about what changed
2. ❌ **Missing package information** - Always list affected packages
3. ❌ **Mixing concerns** - Keep commits focused
4. ❌ **Not running tests** - Test locally before opening PR
5. ❌ **Large PRs** - Break into smaller, reviewable chunks
6. ❌ **Not updating docs** - If behavior changes, update documentation
## Examples of Good Commits
### Example 1: Provider Fix
```
[fix]: OpenAI provider - handle streaming response errors correctly
Previously, streaming responses would sometimes fail with
"context deadline exceeded" error when network latency exceeded
timeout threshold.
Changes:
- core/providers/openai/openai.go - Add dynamic timeout
- core/providers/anthropic/anthropic.go - Align timeout logic
- tests/ - Add regression tests
Affected packages:
- core/providers/
- core/bifrost.go (minor type update)
```
### Example 2: Plugin Development
```
[feat]: Add rate limiting to governance plugin
Introduces token bucket algorithm for per-customer rate limiting.
Allows fine-grained control over request throughput.
Changes:
- plugins/governance/ratelimit/ - New package with core logic
- plugins/governance/main.go - Register rate limiter
- transports/bifrost-http/middleware.go - Apply rate limit checks
- docs/features/governance.mdx - Add usage documentation
Benefits:
- Prevents request storms
- Fair resource allocation
- Configurable per-customer
```
### Example 3: Core Refactoring
```
[refactor]: Simplify model caching to reduce complexity
Consolidate three separate caching layers into unified approach.
No behavior change - internal improvement only.
Changes:
- core/models.go - Unified cache implementation
- core/cache/ - Remove legacy cache package
- tests/ - Update cache tests
Affected packages:
- core/ (main change)
- plugins/ (minor - cache API unchanged)
```
## Need Help?
- 📚 See [Code Conventions](/contributing/code-conventions) for style guidelines
- 🏗️ Check [Architecture Docs](/architecture) to understand the codebase structure
- 💬 Ask in [Discord](https://discord.gg/exN5KAydbU) if unsure about the process
- ❓ Refer to the [Changelog Review Checklist](#changelog-review-checklist) above before submitting

View File

View File

@@ -0,0 +1,420 @@
---
title: "Setting up the repository"
description: "Complete guide to setting up the Bifrost repository for local development."
icon: "hammer"
---
This guide walks you through setting up the Bifrost repository for local development, from prerequisites to running your first development server.
## Prerequisites
Before setting up the repository, ensure you have the following tools installed:
- [Go](https://go.dev/doc/install) (1.25.5)
- [Node.js](https://nodejs.org/en/download) (>= 18.0.0) and npm
- [Make](/deployment-guides/how-to/install-make)
- [Docker](https://www.docker.com) (optional, for containerized development)
- [Air](https://github.com/air-verse/air?tab=readme-ov-file#installation) (for hot reloading, auto-installed by Makefile when needed)
- [golangci-lint](https://golangci-lint.run/usage/install/) (optional, for linting)
- [goimports](https://pkg.go.dev/golang.org/x/tools/cmd/goimports) (optional, for code formatting)
<Note>`gotestsum` and `junit-viewer` are auto-installed by make commands when needed for test reporting.</Note>
## Clone the Repository
```bash
# Clone the repository
git clone https://github.com/maximhq/bifrost.git
cd bifrost
# Verify the repository structure
ls -la
```
You should see the main directories: `core/`, `framework/`, `transports/`, `ui/`, `plugins/`, `docs/`, etc.
## Repository Structure
Bifrost uses a modular architecture with the following structure:
```
bifrost/
├── core/ # Core functionality and shared components
│ ├── providers/ # Provider-specific implementations (OpenAI, Anthropic, etc.)
│ ├── schemas/ # Interfaces and structs used throughout Bifrost
│ └── bifrost.go # Main Bifrost implementation
├── framework/ # Framework components for common functionality
│ ├── configstore/ # Configuration storages
│ ├── logstore/ # Request logging storages
│ └── vectorstore/ # Vector storages
├── transports/ # HTTP gateway and other interface layers
│ └── bifrost-http/ # HTTP transport implementation
├── ui/ # Web interface for HTTP gateway
├── plugins/ # First party plugins
├── docs/ # Documentation and guides
└── tests/ # Comprehensive test suites
```
The system uses a provider-agnostic approach with well-defined interfaces in `core/schemas/` for easy extension to new AI providers.
**Learn More About the Architecture:**
- **[Request Flow](/architecture/core/request-flow)** - Deep dive into how requests are processed from transport to provider
- **[Plugin System](/architecture/core/plugins)** - How plugins extend functionality
- **[Framework Components](/architecture/framework/what-is-framework)** - Shared storage and utilities
- **[MCP Integration](/architecture/core/mcp)** - Model Context Protocol implementation
## Development Environment Setup
### Quick Start (Recommended)
<Note>
If you're setting up the repo for the first time, you may need to build the project at least once:
```bash
make build LOCAL=1
```
</Note>
The fastest way to get started is using the complete development environment:
```bash
# Start complete development environment (UI + API with hot reload)
make dev
```
This command will:
1. Install UI dependencies automatically
2. Install Air for hot reloading
3. Set up the Go workspace with local modules
4. Start the Vite development server (port 3000)
5. Start the API server with UI proxy (port 8080)
**Access the application at:** http://localhost:8080
<Note>The `make dev` command handles all setup automatically. You can skip the manual setup steps below if this works for you.</Note>
#### Alternative: Using Pulse
If you prefer [Pulse](https://github.com/Pratham-Mishra04/pulse) over Air for hot reloading, use:
```bash
make dev-pulse
```
This runs the same development environment but uses `pulse.yaml` for hot reloading instead of `.air.toml`.
### Manual Setup (Alternative)
If you prefer to set up components manually:
#### 1. Install UI Dependencies
```bash
# Install UI dependencies and tools
make install-ui
```
#### 2. Install Air for Hot Reloading
```bash
# Install Air if not already installed
make install-air
```
#### 3. Set Up Go Workspace
```bash
# Set up Go workspace with all local modules
make setup-workspace
```
This creates a `go.work` file that links all local modules for development.
#### 4. Build the Application
```bash
# Build UI and binary
make build
# Build with local go.work modules (for development)
make build LOCAL=1
# Build with specific version
make build VERSION=1.0.0
# Cross-compile for different platforms
make build GOOS=linux GOARCH=amd64
# Build with dynamic linking (Linux only)
make build DYNAMIC=1
```
#### 5. Run the Application
```bash
# Run without hot reload
make run
# Or with hot reload (development)
make dev
```
## Available Make Commands
The Makefile provides numerous commands for development:
### Development Commands
```bash
make dev # Start complete development environment using Air for hot reloading
make dev-pulse # Start complete development environment using Pulse for hot reloading
make build # Build UI and bifrost-http binary
make run # Build and run (no hot reload)
make clean # Clean build artifacts
```
### Testing Commands
```bash
make test # Run bifrost-http tests
make test-core # Run all core tests
make test-core PROVIDER=openai # Run specific provider tests
make test-core PROVIDER=openai TESTCASE=SpeechSynthesisStreamAdvanced/MultipleVoices_Streaming/StreamingVoice_echo # Run specific test case
make test-plugins # Run plugin tests
make test-governance # Run governance tests
make test-governance TESTCASE=TestVKBudgetExceeded # Run specific governance test
make test-governance PATTERN=Budget # Run governance tests matching pattern
make test-all # Run all tests
make clean-test-reports # Clean test reports
make generate-html-reports # Convert XML to HTML reports
```
<Note>
- **TESTCASE must use forward-slash separated nested path format** (e.g., `ParentTest/SubTest/SpecificTest`)
- See the Makefile comment at line 311 for the expected format and additional examples
- HTML test reports are automatically generated when `junit-viewer` is available
- Reports are saved to `test-reports/` directory
- View with: `open test-reports/index.html`
</Note>
### Workspace Management
```bash
make setup-workspace # Set up Go workspace for local development
make work-clean # Remove local go.work files
```
<Note>`make work-init` is deprecated. Use `make setup-workspace` instead.</Note>
### UI Commands
```bash
make install-ui # Install UI dependencies
make build-ui # Build UI for production
```
### Docker Commands
```bash
make build-docker-image # Build Docker image
make docker-run # Run Docker container
```
### Documentation
```bash
make docs # Start local documentation server
```
### Code Quality
```bash
make lint # Run linter for Go code
make fmt # Format Go code
```
### Tool Installation
```bash
make install-gotestsum # Install gotestsum for test reporting
make install-junit-viewer # Install junit-viewer for HTML reports
```
## Environment Variables
You can customize the development environment with these variables:
```bash
# Server configuration
HOST=localhost # Server host (default: localhost)
PORT=8080 # Server port (default: 8080)
# Logging
LOG_STYLE=json # Logger format: json|pretty (default: json)
LOG_LEVEL=info # Logger level: debug|info|warn|error (default: info)
# Prometheus
PROMETHEUS_LABELS="env=dev" # Labels for Prometheus metrics
# App directory
APP_DIR= # App data directory (empty by default, /app/data recommended for containers)
# Build configuration
VERSION=dev-build # Build version (default: dev-build)
LOCAL= # Use local go.work for builds (e.g., make build LOCAL=1)
```
Example with custom settings:
```bash
PORT=3001 LOG_STYLE=pretty LOG_LEVEL=debug APP_DIR=/app/data make dev
```
## Understanding Bifrost Architecture
Before diving into development, it's helpful to understand how Bifrost works internally. The architecture documentation provides detailed insights into:
### Core Components
- **[Request Flow](/architecture/core/request-flow)** - How requests flow through the system from transport to provider and back
- **[Concurrency](/architecture/core/concurrency)** - Worker pools and threading model
- **[MCP Integration](/architecture/core/mcp)** - Model Context Protocol implementation
- **[Plugin System](/architecture/core/plugins)** - How plugins extend core functionality
### Framework Layer
- **[What is Framework](/architecture/framework/what-is-framework)** - Shared storage and utilities overview
- **[Config Store](/architecture/framework/config-store)** - Configuration persistence patterns
- **[Log Store](/architecture/framework/log-store)** - Request logging and analytics
- **[Vector Store](/architecture/framework/vector-store)** - Semantic search and caching
### Plugins & Transports
- **[Plugin Architecture](/architecture/core/plugins)** - Plugin development patterns and execution model
- **[Transport Layer](/architecture/transports/in-memory-store)** - HTTP and other transport implementations
<Note>Reading the architecture documentation will help you understand where to make changes and how different components interact.</Note>
## Development Workflow
### 1. Start Development Environment
```bash
make dev
```
### 2. Make Your Changes
- **Core changes**: Edit files in `core/`
- **API changes**: Edit files in `transports/bifrost-http/`
- **UI changes**: Edit files in `ui/`
- **Plugin changes**: Edit files in `plugins/`
### 3. Test Your Changes
```bash
# Run all tests
make test-all
# Run specific provider tests
make test-core PROVIDER=openai
# Run specific test case (TESTCASE must be a slash-delimited nested path matching the test hierarchy)
make test-core PROVIDER=elevenlabs TESTCASE=SpeechSynthesisStreamAdvanced/MultipleVoices_Streaming/StreamingVoice_echo
# Run HTTP transport tests
make test
# Run plugin tests
make test-plugins
# View test reports (after running tests)
open test-reports/index.html
```
### 4. Verify Code Quality
```bash
# Format code
make fmt
# Run linter
make lint
```
### 5. Build for Production
```bash
# Build everything
make build
# Or build Docker image
make build-docker-image
```
## Troubleshooting
### Common Issues
**Go workspace issues:**
```bash
# Reset the workspace
make work-clean
make setup-workspace
```
**UI dependency issues:**
```bash
# Clean and reinstall UI dependencies
rm -rf ui/node_modules
make install-ui
```
**Port conflicts:**
```bash
# Use different ports
PORT=9090 make dev
```
If an process is running on a port you need to use, you may need to terminate or kill it first:
```bash
# Kill the process on port 8080
kill -9 $(lsof -t -i:8080)
```
**Hot reload not working:**
```bash
# Ensure Air is installed
which air || go install github.com/air-verse/air@latest
# Check if .air.toml exists in transports/bifrost-http/
ls transports/bifrost-http/.air.toml
# Alternatively, use Pulse instead of Air
make dev-pulse
```
### Getting Help
- **Check logs**: Development logs appear in your terminal
- **Verify prerequisites**: Ensure Go, Node.js, and make are properly installed
- **Clean build**: Run `make clean` and try again
- **Discord**: Join our [Discord community](https://discord.gg/exN5KAydbU) for real-time help
## Next Steps
Once your development environment is running:
1. **Explore the UI**: Visit http://localhost:8080 to see the web interface
2. **Make API calls**: Test the API endpoints at http://localhost:8080/v1/
3. **Understand the architecture**: Read our [request flow documentation](/architecture/core/request-flow) to understand how Bifrost works internally
4. **Read the documentation**: Check out our [complete documentation](https://docs.getbifrost.ai)
5. **Review contribution guidelines**: See our [code conventions](/contributing/code-conventions) and [PR guidelines](/contributing/raising-a-pr)
## Quick Reference
```bash
# Essential commands for daily development
make dev # Start development environment
make test-all # Run all tests
make fmt # Format code
make clean # Clean build artifacts
make help # Show all available commands
```
Happy coding! 🚀