Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .github/workflows/scripts/release-core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,11 @@ go build ./...
cd ..
echo "✅ Core build validation successful"

# Run core provider tests
# Run core tests
echo "🔧 Running core tests..."
cd core
# go test -v ./...
go test -v ./...
cd ..
echo "🔧 Running core provider tests..."
cd tests/core-providers
go test -v -run .
cd ../..

# Capturing changelog
CHANGELOG_BODY=$(cat core/changelog.md)
Expand Down
44 changes: 31 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,10 @@ test-core: install-gotestsum ## Run core tests (Usage: make test-core PROVIDER=o
REPORT_FILE=""; \
if [ -n "$(PROVIDER)" ]; then \
echo "$(CYAN)Running tests for provider: $(PROVIDER)$(NC)"; \
if [ ! -f "tests/core-providers/$(PROVIDER)_test.go" ]; then \
echo "$(RED)Error: Provider test file '$(PROVIDER)_test.go' not found$(NC)"; \
if [ ! -f "core/providers/$(PROVIDER)/$(PROVIDER)_test.go" ]; then \
echo "$(RED)Error: Provider test file '$(PROVIDER)_test.go' not found in core/providers/$(PROVIDER)/$(NC)"; \
echo "$(YELLOW)Available providers:$(NC)"; \
ls tests/core-providers/*_test.go 2>/dev/null | grep -v cross_provider | xargs -n 1 basename | sed 's/_test\.go//' | sed 's/^/ - /'; \
find core/providers -name "*_test.go" -type f 2>/dev/null | sed 's|core/providers/\([^/]*\)/.*|\1|' | sort -u | sed 's/^/ - /'; \
exit 1; \
fi; \
fi; \
Expand All @@ -335,11 +335,11 @@ test-core: install-gotestsum ## Run core tests (Usage: make test-core PROVIDER=o
CLEAN_TESTCASE=$$(echo "$$CLEAN_TESTCASE" | sed 's|^Test[A-Z][A-Za-z]*/[A-Z][A-Za-z]*Tests/||'); \
echo "$(CYAN)Running Test$${PROVIDER_TEST_NAME}/$${PROVIDER_TEST_NAME}Tests/$$CLEAN_TESTCASE...$(NC)"; \
REPORT_FILE="$(TEST_REPORTS_DIR)/core-$(PROVIDER)-$$(echo $$CLEAN_TESTCASE | sed 's|/|_|g').xml"; \
cd tests/core-providers && GOWORK=off gotestsum \
cd core/providers/$(PROVIDER) && GOWORK=off gotestsum \
--format=$(GOTESTSUM_FORMAT) \
--junitfile=../../$$REPORT_FILE \
--junitfile=../../../$$REPORT_FILE \
-- -v -run "^Test$${PROVIDER_TEST_NAME}$$/.*Tests/$$CLEAN_TESTCASE$$" || TEST_FAILED=1; \
cd ../..; \
cd ../../..; \
$(MAKE) cleanup-junit-xml REPORT_FILE=$$REPORT_FILE; \
if [ -z "$$CI" ] && [ -z "$$GITHUB_ACTIONS" ] && [ -z "$$GITLAB_CI" ] && [ -z "$$CIRCLECI" ] && [ -z "$$JENKINS_HOME" ]; then \
if which junit-viewer > /dev/null 2>&1; then \
Expand All @@ -359,11 +359,11 @@ test-core: install-gotestsum ## Run core tests (Usage: make test-core PROVIDER=o
else \
echo "$(CYAN)Running Test$${PROVIDER_TEST_NAME}...$(NC)"; \
REPORT_FILE="$(TEST_REPORTS_DIR)/core-$(PROVIDER).xml"; \
cd tests/core-providers && GOWORK=off gotestsum \
cd core/providers/$(PROVIDER) && GOWORK=off gotestsum \
--format=$(GOTESTSUM_FORMAT) \
--junitfile=../../$$REPORT_FILE \
--junitfile=../../../$$REPORT_FILE \
-- -v -run "^Test$${PROVIDER_TEST_NAME}$$" || TEST_FAILED=1; \
cd ../..; \
cd ../../..; \
$(MAKE) cleanup-junit-xml REPORT_FILE=$$REPORT_FILE; \
if [ -z "$$CI" ] && [ -z "$$GITHUB_ACTIONS" ] && [ -z "$$GITLAB_CI" ] && [ -z "$$CIRCLECI" ] && [ -z "$$JENKINS_HOME" ]; then \
if which junit-viewer > /dev/null 2>&1; then \
Expand All @@ -388,11 +388,11 @@ test-core: install-gotestsum ## Run core tests (Usage: make test-core PROVIDER=o
exit 1; \
fi; \
REPORT_FILE="$(TEST_REPORTS_DIR)/core-all.xml"; \
cd tests/core-providers && GOWORK=off gotestsum \
cd core && GOWORK=off gotestsum \
--format=$(GOTESTSUM_FORMAT) \
--junitfile=../../$$REPORT_FILE \
-- -v ./... || TEST_FAILED=1; \
cd ../..; \
--junitfile=../$$REPORT_FILE \
-- -v ./providers/... || TEST_FAILED=1; \
cd ..; \
$(MAKE) cleanup-junit-xml REPORT_FILE=$$REPORT_FILE; \
if [ -z "$$CI" ] && [ -z "$$GITHUB_ACTIONS" ] && [ -z "$$GITLAB_CI" ] && [ -z "$$CIRCLECI" ] && [ -z "$$JENKINS_HOME" ]; then \
if which junit-viewer > /dev/null 2>&1; then \
Expand Down Expand Up @@ -525,6 +525,24 @@ test-all: test-core test-plugins test ## Run all tests
echo ""; \
fi

test-chatbot: ## Run interactive chatbot integration test (Usage: RUN_CHATBOT_TEST=1 make test-chatbot)
@echo "$(GREEN)Running interactive chatbot integration test...$(NC)"
@if [ -z "$(RUN_CHATBOT_TEST)" ]; then \
echo "$(YELLOW)⚠️ This is an interactive test. Set RUN_CHATBOT_TEST=1 to run it.$(NC)"; \
echo "$(CYAN)Usage: RUN_CHATBOT_TEST=1 make test-chatbot$(NC)"; \
echo ""; \
echo "$(YELLOW)Required environment variables:$(NC)"; \
echo " - OPENAI_API_KEY (required)"; \
echo " - ANTHROPIC_API_KEY (optional)"; \
echo " - Additional provider keys as needed"; \
exit 0; \
fi
@if [ -f .env ]; then \
echo "$(YELLOW)Loading environment variables from .env...$(NC)"; \
set -a; . ./.env; set +a; \
fi
@cd core && RUN_CHATBOT_TEST=1 go test -v -run TestChatbot

# Quick start with example config
quick-start: ## Quick start with example config and maxim plugin
@echo "$(GREEN)Quick starting Bifrost with example configuration...$(NC)"
Expand Down
19 changes: 12 additions & 7 deletions core/bifrost.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,21 @@ import (
"time"

"github.com/google/uuid"
"github.com/maximhq/bifrost/core/providers"
"github.com/maximhq/bifrost/core/providers/anthropic"
"github.com/maximhq/bifrost/core/providers/azure"
"github.com/maximhq/bifrost/core/providers/bedrock"
"github.com/maximhq/bifrost/core/providers/cerebras"
"github.com/maximhq/bifrost/core/providers/cohere"
"github.com/maximhq/bifrost/core/providers/elevenlabs"
"github.com/maximhq/bifrost/core/providers/gemini"
"github.com/maximhq/bifrost/core/providers/groq"
"github.com/maximhq/bifrost/core/providers/mistral"
"github.com/maximhq/bifrost/core/providers/ollama"
"github.com/maximhq/bifrost/core/providers/openai"
"github.com/maximhq/bifrost/core/providers/openrouter"
"github.com/maximhq/bifrost/core/providers/parasail"
"github.com/maximhq/bifrost/core/providers/perplexity"
"github.com/maximhq/bifrost/core/providers/sgl"
providerUtils "github.com/maximhq/bifrost/core/providers/utils"
"github.com/maximhq/bifrost/core/providers/vertex"
schemas "github.com/maximhq/bifrost/core/schemas"
Expand Down Expand Up @@ -1301,21 +1306,21 @@ func (bifrost *Bifrost) createBaseProvider(providerKey schemas.ModelProvider, co
case schemas.Mistral:
return mistral.NewMistralProvider(config, bifrost.logger), nil
case schemas.Ollama:
return providers.NewOllamaProvider(config, bifrost.logger)
return ollama.NewOllamaProvider(config, bifrost.logger)
case schemas.Groq:
return providers.NewGroqProvider(config, bifrost.logger)
return groq.NewGroqProvider(config, bifrost.logger)
case schemas.SGL:
return providers.NewSGLProvider(config, bifrost.logger)
return sgl.NewSGLProvider(config, bifrost.logger)
case schemas.Parasail:
return providers.NewParasailProvider(config, bifrost.logger)
return parasail.NewParasailProvider(config, bifrost.logger)
case schemas.Perplexity:
return perplexity.NewPerplexityProvider(config, bifrost.logger)
case schemas.Cerebras:
return providers.NewCerebrasProvider(config, bifrost.logger)
return cerebras.NewCerebrasProvider(config, bifrost.logger)
case schemas.Gemini:
return gemini.NewGeminiProvider(config, bifrost.logger), nil
case schemas.OpenRouter:
return providers.NewOpenRouterProvider(config, bifrost.logger), nil
return openrouter.NewOpenRouterProvider(config, bifrost.logger), nil
case schemas.Elevenlabs:
return elevenlabs.NewElevenlabsProvider(config, bifrost.logger), nil
default:
Expand Down
25 changes: 19 additions & 6 deletions tests/core-chatbot/main.go → core/chatbot_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package bifrost_test

import (
"bufio"
Expand All @@ -10,6 +10,7 @@ import (
"strings"
"sync"
"syscall"
"testing"
"time"

bifrost "github.com/maximhq/bifrost/core"
Expand Down Expand Up @@ -581,7 +582,7 @@ func (s *ChatSession) handleToolCalls(assistantMessage schemas.ChatMessage) (str
errorResult := schemas.ChatMessage{
Role: schemas.ChatMessageRoleTool,
Content: &schemas.ChatMessageContent{
ContentStr: bifrost.Ptr(fmt.Sprintf("Error executing tool: %v", err)),
ContentStr: bifrost.Ptr(fmt.Sprintf("Error executing tool: %v", err)),
},
ChatToolMessage: &schemas.ChatToolMessage{
ToolCallID: toolCall.ID,
Expand Down Expand Up @@ -630,9 +631,11 @@ func (s *ChatSession) synthesizeToolResults() (string, error) {

// Create synthesis request
synthesisRequest := &schemas.BifrostChatRequest{
Input: conversationWithSynthesis,
Params: &schemas.ChatParameters{
Temperature: s.config.Temperature,
Provider: s.config.Provider,
Model: s.config.Model,
Input: conversationWithSynthesis,
Params: &schemas.ChatParameters{
Temperature: s.config.Temperature,
MaxCompletionTokens: s.config.MaxTokens,
},
}
Comment thread
akshaydeo marked this conversation as resolved.
Expand Down Expand Up @@ -826,7 +829,7 @@ func stopLoader(stopChan chan bool, wg *sync.WaitGroup) {
wg.Wait()
}

func main() {
func runChatbot() {
// Check for required environment variables
if os.Getenv("OPENAI_API_KEY") == "" {
fmt.Println("❌ Error: OPENAI_API_KEY environment variable is required")
Expand Down Expand Up @@ -934,3 +937,13 @@ func main() {
// Cleanup
session.Cleanup()
}

// TestChatbot is the test wrapper for the interactive chatbot
func TestChatbot(t *testing.T) {
// Skip by default as this is an interactive integration test
if os.Getenv("RUN_CHATBOT_TEST") == "" {
t.Skip("Skipping interactive chatbot test. Set RUN_CHATBOT_TEST=1 to run")
}

runChatbot()
}
2 changes: 1 addition & 1 deletion core/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/google/uuid v1.6.0
github.com/mark3labs/mcp-go v0.41.1
github.com/rs/zerolog v1.34.0
github.com/stretchr/testify v1.11.1
github.com/valyala/fasthttp v1.67.0
golang.org/x/oauth2 v0.32.0
)
Expand Down Expand Up @@ -43,7 +44,6 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Package config provides comprehensive test account and configuration management for the Bifrost system.
// Package testutil provides comprehensive test account and configuration management for the Bifrost system.
// It implements account functionality for testing purposes, supporting multiple AI providers
// and comprehensive test scenarios.
package config
package testutil

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package scenarios
package testutil

import (
"context"
"os"
"strings"
"testing"

"github.com/maximhq/bifrost/tests/core-providers/config"

bifrost "github.com/maximhq/bifrost/core"
"github.com/maximhq/bifrost/core/schemas"
)

// RunAutomaticFunctionCallingTest executes the automatic function calling test scenario using dual API testing framework
func RunAutomaticFunctionCallingTest(t *testing.T, client *bifrost.Bifrost, ctx context.Context, testConfig config.ComprehensiveTestConfig) {
func RunAutomaticFunctionCallingTest(t *testing.T, client *bifrost.Bifrost, ctx context.Context, testConfig ComprehensiveTestConfig) {
if !testConfig.Scenarios.AutomaticFunctionCall {
t.Logf("Automatic function calling not supported for provider %s", testConfig.Provider)
return
Expand Down Expand Up @@ -161,11 +159,12 @@ func RunAutomaticFunctionCallingTest(t *testing.T, client *bifrost.Bifrost, ctx
}

func validateAutomaticToolCall(t *testing.T, toolCalls []ToolCallInfo, apiName string) {
foundValidToolCall := false

// Validation for tool call already happened inside WithDualAPITestRetry
// If we reach here, the tool call was successful
// This function just provides additional logging for tool call details

for _, toolCall := range toolCalls {
if toolCall.Name == string(SampleToolTypeTime) {
foundValidToolCall = true
t.Logf("✅ %s automatic function call: %s", apiName, toolCall.Arguments)

// Additional validation for timezone argument
Expand All @@ -178,8 +177,4 @@ func validateAutomaticToolCall(t *testing.T, toolCalls []ToolCallInfo, apiName s
break
}
}

if !foundValidToolCall {
t.Fatalf("Expected %s API to have automatic tool call for 'time'", apiName)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package scenarios
package testutil

import (
"context"
Expand All @@ -8,14 +8,13 @@ import (
"testing"
"time"

"github.com/maximhq/bifrost/tests/core-providers/config"

bifrost "github.com/maximhq/bifrost/core"
"github.com/maximhq/bifrost/core/schemas"
)

// RunChatCompletionStreamTest executes the chat completion stream test scenario
func RunChatCompletionStreamTest(t *testing.T, client *bifrost.Bifrost, ctx context.Context, testConfig config.ComprehensiveTestConfig) {
func RunChatCompletionStreamTest(t *testing.T, client *bifrost.Bifrost, ctx context.Context, testConfig ComprehensiveTestConfig) {
if !testConfig.Scenarios.CompletionStream {
t.Logf("Chat completion stream not supported for provider %s", testConfig.Provider)
return
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package scenarios
package testutil

import (
"context"
"os"
"strings"
"testing"

"github.com/maximhq/bifrost/tests/core-providers/config"

bifrost "github.com/maximhq/bifrost/core"
"github.com/maximhq/bifrost/core/schemas"
)

// RunCompleteEnd2EndTest executes the complete end-to-end test scenario
func RunCompleteEnd2EndTest(t *testing.T, client *bifrost.Bifrost, ctx context.Context, testConfig config.ComprehensiveTestConfig) {
func RunCompleteEnd2EndTest(t *testing.T, client *bifrost.Bifrost, ctx context.Context, testConfig ComprehensiveTestConfig) {
if !testConfig.Scenarios.CompleteEnd2End {
t.Logf("Complete end-to-end not supported for provider %s", testConfig.Provider)
return
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package scenarios
package testutil

import (
"context"
Expand Down
Loading