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
11 changes: 6 additions & 5 deletions transports/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
FROM golang:1.24-alpine AS builder
WORKDIR /app

# Install dependencies in a single layer
RUN apk add --no-cache upx
# Install dependencies including gcc for CGO and sqlite
RUN apk add --no-cache upx gcc musl-dev sqlite-dev
Comment on lines +5 to +6
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Dependencies added for CGO and static SQLite linking.

The addition of gcc, musl-dev, and sqlite-dev packages is appropriate for enabling CGO and static SQLite linking. Consider pinning package versions for reproducible builds and security compliance.

🧰 Tools
🪛 Hadolint (2.12.0)

[warning] 6-6: Pin versions in apk add. Instead of apk add <package> use apk add <package>=<version>

(DL3018)

🤖 Prompt for AI Agents
In transports/Dockerfile at lines 5 to 6, the RUN command installs gcc,
musl-dev, and sqlite-dev without specifying versions, which can lead to
non-reproducible builds. Modify the apk add command to pin specific package
versions by appending the version numbers to each package name, ensuring
consistent and secure builds.


# Set environment for static build
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64
# Set environment for CGO-enabled build (required for go-sqlite3)
ENV CGO_ENABLED=1 GOOS=linux

# Define build-time variables
ARG TRANSPORT_TYPE=http
Expand All @@ -16,10 +16,11 @@ ARG TAG_VERSION=latest
RUN go mod init bifrost-build && \
go get github.com/maximhq/bifrost/transports/bifrost-${TRANSPORT_TYPE}@${TAG_VERSION}

# Build the binary locally
# Build the binary with CGO enabled and static SQLite linking
RUN go build \
-ldflags="-w -s -extldflags '-static'" \
-a -trimpath \
-tags "sqlite_static" \
-o /app/main \
github.com/maximhq/bifrost/transports/bifrost-${TRANSPORT_TYPE}

Expand Down
2 changes: 1 addition & 1 deletion transports/bifrost-http/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ func main() {
// Apply CORS middleware to all routes
corsHandler := corsMiddleware(r.Handler)

log.Printf("Starting server on port %s", port)
log.Printf("Successfully started bifrost. Serving UI on http://localhost:%s", port)
if err := fasthttp.ListenAndServe(":"+port, corsHandler); err != nil {
log.Fatalf("Error starting server: %v", err)
}
Expand Down
14 changes: 0 additions & 14 deletions transports/bifrost-http/plugins/logging/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ type UpdateLogData struct {
OutputMessage *schemas.BifrostMessage
ToolCalls *[]schemas.ToolCall
ErrorDetails *schemas.BifrostError
ExtraFields map[string]interface{}
Model string // May be different from request
Object string // May be different from request
}
Expand All @@ -85,7 +84,6 @@ type LogEntry struct {
TokenUsage *schemas.LLMUsage `json:"token_usage,omitempty"`
Status string `json:"status"` // "processing", "success", or "error"
ErrorDetails *schemas.BifrostError `json:"error_details,omitempty"`
ExtraFields map[string]interface{} `json:"extra_fields,omitempty"`
CreatedAt time.Time `json:"created_at"`
}

Expand Down Expand Up @@ -233,7 +231,6 @@ func (p *LoggerPlugin) createTables() error {
tool_calls TEXT,
params TEXT,
error_details TEXT,
extra_fields TEXT,

-- For content search
content_summary TEXT,
Expand Down Expand Up @@ -499,17 +496,6 @@ func (p *LoggerPlugin) PostHook(ctx *context.Context, result *schemas.BifrostRes
updateData.ToolCalls = result.Choices[0].Message.AssistantMessage.ToolCalls
}
}

// Extra fields if available
if result.ExtraFields.Provider != "" || result.ExtraFields.Params.MaxTokens != nil {
updateData.ExtraFields = map[string]interface{}{
"provider": result.ExtraFields.Provider,
"params": result.ExtraFields.Params,
"latency": result.ExtraFields.Latency,
"billed_usage": result.ExtraFields.BilledUsage,
"raw_response": result.ExtraFields.RawResponse,
}
}
}

logMsg.UpdateData = updateData
Expand Down
35 changes: 13 additions & 22 deletions transports/bifrost-http/plugins/logging/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,6 @@ func (p *LoggerPlugin) updateLogEntry(requestID string, timestamp time.Time, dat
args = append(args, string(errorDetailsJSON))
}

// Update extra fields
if data.ExtraFields != nil {
extraFieldsJSON, _ := json.Marshal(data.ExtraFields)
setParts = append(setParts, "extra_fields = ?")
args = append(args, string(extraFieldsJSON))
}

// Add the WHERE clause parameter
args = append(args, requestID)

Expand Down Expand Up @@ -161,13 +154,13 @@ func (p *LoggerPlugin) getLogEntry(requestID string) (*LogEntry, error) {
SELECT id, timestamp, provider, model, object_type, status, latency,
prompt_tokens, completion_tokens, total_tokens,
input_history, output_message, tools, tool_calls,
params, error_details, extra_fields, created_at
params, error_details, created_at
FROM logs WHERE id = ?`

var entry LogEntry
var timestampUnix, createdAtUnix int64
var inputHistoryJSON, outputMessageJSON, toolsJSON, toolCallsJSON sql.NullString
var paramsJSON, errorDetailsJSON, extraFieldsJSON sql.NullString
var paramsJSON, errorDetailsJSON sql.NullString
var promptTokens, completionTokens, totalTokensRow sql.NullInt64
var latency sql.NullFloat64

Expand All @@ -176,7 +169,7 @@ func (p *LoggerPlugin) getLogEntry(requestID string) (*LogEntry, error) {
&entry.Object, &entry.Status, &latency,
&promptTokens, &completionTokens, &totalTokensRow,
&inputHistoryJSON, &outputMessageJSON, &toolsJSON, &toolCallsJSON,
&paramsJSON, &errorDetailsJSON, &extraFieldsJSON,
&paramsJSON, &errorDetailsJSON,
&createdAtUnix,
)
if err != nil {
Expand Down Expand Up @@ -226,9 +219,6 @@ func (p *LoggerPlugin) getLogEntry(requestID string) (*LogEntry, error) {
if errorDetailsJSON.Valid {
json.Unmarshal([]byte(errorDetailsJSON.String), &entry.ErrorDetails)
}
if extraFieldsJSON.Valid {
json.Unmarshal([]byte(extraFieldsJSON.String), &entry.ExtraFields)
}

return &entry, nil
}
Expand Down Expand Up @@ -335,9 +325,9 @@ func (p *LoggerPlugin) SearchLogs(filters *SearchFilters, pagination *Pagination

for rows.Next() {
var entry LogEntry
var timestampUnix int64
var timestampUnix sql.NullInt64
var inputHistoryJSON, outputMessageJSON, toolsJSON, toolCallsJSON sql.NullString
var paramsJSON, errorDetailsJSON, extraFieldsJSON sql.NullString
var paramsJSON, errorDetailsJSON sql.NullString
var promptTokens, completionTokens, totalTokensRow sql.NullInt64
var latency sql.NullFloat64

Expand All @@ -346,14 +336,18 @@ func (p *LoggerPlugin) SearchLogs(filters *SearchFilters, pagination *Pagination
&entry.Object, &entry.Status, &latency,
&promptTokens, &completionTokens, &totalTokensRow,
&inputHistoryJSON, &outputMessageJSON, &toolsJSON, &toolCallsJSON,
&paramsJSON, &errorDetailsJSON, &extraFieldsJSON,
&paramsJSON, &errorDetailsJSON,
)
if err != nil {
return nil, fmt.Errorf("failed to scan row: %w", err)
}

// Convert timestamp
entry.Timestamp = time.Unix(timestampUnix/1e9, timestampUnix%1e9) // Convert from nanoseconds
// Convert timestamp (handle NULL values)
if timestampUnix.Valid {
entry.Timestamp = time.Unix(timestampUnix.Int64/1e9, timestampUnix.Int64%1e9) // Convert from nanoseconds
} else {
entry.Timestamp = time.Time{} // Set to zero time if NULL
}

// Handle latency
if latency.Valid {
Expand Down Expand Up @@ -394,9 +388,6 @@ func (p *LoggerPlugin) SearchLogs(filters *SearchFilters, pagination *Pagination
if errorDetailsJSON.Valid {
json.Unmarshal([]byte(errorDetailsJSON.String), &entry.ErrorDetails)
}
if extraFieldsJSON.Valid {
json.Unmarshal([]byte(extraFieldsJSON.String), &entry.ExtraFields)
}

logs = append(logs, entry)
}
Expand Down Expand Up @@ -433,7 +424,7 @@ func (p *LoggerPlugin) buildSearchQuery(filters *SearchFilters, pagination *Pagi
SELECT id, timestamp, provider, model, object_type, status, latency,
prompt_tokens, completion_tokens, total_tokens,
input_history, output_message, tools, tool_calls,
params, error_details, extra_fields
params, error_details
FROM logs`

countQuery := "SELECT COUNT(*) FROM logs"
Expand Down
4 changes: 2 additions & 2 deletions transports/bifrost-http/ui/404.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions transports/bifrost-http/ui/404/index.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

This file was deleted.

Loading