Add AI-powered evidence description generation
Introduce a background worker that automatically generates compliance-focused descriptions for uploaded evidence files using configurable LLM providers. Descriptions are surfaced across all interfaces: GraphQL API, MCP API, CLI, and the console UI. Key changes: - Multi-provider LLM config with per-agent settings (pointer types for Temperature/MaxTokens to preserve zero values) - Evidence description worker with bounded concurrency - EvidenceDescriptionStatus typed enum with PostgreSQL enum type - New `prb evidence` CLI commands (list, view, delete) - Evidence description displayed in console table and preview - Migration only marks evidences without files as completed Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
@@ -16,10 +16,13 @@ package openai
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/openai/openai-go"
|
||||
@@ -188,6 +191,8 @@ func buildMessages(messages []llm.Message) []openai.ChatCompletionMessageParamUn
|
||||
},
|
||||
),
|
||||
)
|
||||
case llm.FilePart:
|
||||
parts = append(parts, buildFilePart(p))
|
||||
}
|
||||
}
|
||||
out = append(out, openai.UserMessage(parts))
|
||||
@@ -450,3 +455,23 @@ func mapChunkToEvent(chunk *openai.ChatCompletionChunk) llm.ChatCompletionStream
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
func buildFilePart(p llm.FilePart) openai.ChatCompletionContentPartUnionParam {
|
||||
switch {
|
||||
case strings.HasPrefix(p.MimeType, "image/"):
|
||||
return openai.ImageContentPart(openai.ChatCompletionContentPartImageImageURLParam{
|
||||
URL: fmt.Sprintf("data:%s;base64,%s", p.MimeType, p.Data),
|
||||
})
|
||||
case strings.HasPrefix(p.MimeType, "text/"):
|
||||
decoded, err := base64.StdEncoding.DecodeString(p.Data)
|
||||
if err != nil {
|
||||
return openai.TextContentPart(fmt.Sprintf("[file: %s, type: %s, error decoding content]", p.Filename, p.MimeType))
|
||||
}
|
||||
return openai.TextContentPart(fmt.Sprintf("File: %s\n\n%s", p.Filename, string(decoded)))
|
||||
default:
|
||||
return openai.FileContentPart(openai.ChatCompletionContentPartFileFileParam{
|
||||
FileData: param.NewOpt(fmt.Sprintf("data:%s;base64,%s", p.MimeType, p.Data)),
|
||||
Filename: param.NewOpt(p.Filename),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user