Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add files to LLM context. #253

Merged
merged 2 commits into from
Oct 15, 2024
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
1 change: 1 addition & 0 deletions server/ai/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type BotConfig struct {
Service ServiceConfig `json:"service"`
EnableVision bool `json:"enableVision"`
DisableTools bool `json:"disableTools"`
MaxFileSize int64 `json:"maxFileSize"`
}

func (c *BotConfig) IsValid() bool {
Expand Down
64 changes: 55 additions & 9 deletions server/post_processing.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ package main
import (
"context"
"fmt"
"io"
"sort"
"strings"

"github.com/mattermost/mattermost-plugin-ai/server/ai"
"github.com/mattermost/mattermost/server/public/model"
)

const defaultMaxFileSize = int64(1024 * 1024 * 5) // 5MB

type ThreadData struct {
Posts []*model.Post
UsersByID map[string]*model.User
Expand Down Expand Up @@ -381,38 +384,81 @@ type WorkerResult struct {
return nil
}*/

func isImageMimeType(mimeType string) bool {
return strings.HasPrefix(mimeType, "image/")
}

func (p *Plugin) PostToAIPost(bot *Bot, post *model.Post) ai.Post {
var files []ai.File
if bot.cfg.EnableVision {
files = make([]ai.File, 0, len(post.FileIds))
for _, fileID := range post.FileIds {
fileInfo, err := p.pluginAPI.File.GetInfo(fileID)
var filesForUpstream []ai.File
message := ai.FormatPostBody(post)
var extractedFileContents []string

maxFileSize := defaultMaxFileSize
if bot.cfg.MaxFileSize > 0 {
maxFileSize = bot.cfg.MaxFileSize
}

for _, fileID := range post.FileIds {
fileInfo, err := p.pluginAPI.File.GetInfo(fileID)
if err != nil {
p.API.LogError("Error getting file info", "error", err)
continue
}

// Check for files that have been interpreted already by the server or are text files.
content := ""
if trimmedContent := strings.TrimSpace(fileInfo.Content); trimmedContent != "" {
content = trimmedContent
} else if strings.HasPrefix(fileInfo.MimeType, "text/") {
file, err := p.pluginAPI.File.Get(fileID)
if err != nil {
p.API.LogError("Error getting file info", "error", err)
p.API.LogError("Error getting file", "error", err)
continue
}
contentBytes, err := io.ReadAll(io.LimitReader(file, maxFileSize))
if err != nil {
p.API.LogError("Error reading file content", "error", err)
continue
}
content = string(contentBytes)
if int64(len(contentBytes)) == maxFileSize {
content += "\n... (content truncated due to size limit)"
}
}

if content != "" {
fileContent := fmt.Sprintf("File Name: %s\nContent: %s", fileInfo.Name, content)
extractedFileContents = append(extractedFileContents, fileContent)
}

if bot.cfg.EnableVision && isImageMimeType(fileInfo.MimeType) {
file, err := p.pluginAPI.File.Get(fileID)
if err != nil {
p.API.LogError("Error getting file", "error", err)
continue
}
files = append(files, ai.File{
filesForUpstream = append(filesForUpstream, ai.File{
Reader: file,
MimeType: fileInfo.MimeType,
Size: fileInfo.Size,
})
}
}

// Add structured file contents to the message
if len(extractedFileContents) > 0 {
message += "\nAttached File Contents:\n" + strings.Join(extractedFileContents, "\n\n")
}

role := ai.PostRoleUser
if p.IsAnyBot(post.UserId) {
role = ai.PostRoleBot
}

return ai.Post{
Role: role,
Message: ai.FormatPostBody(post),
Files: files,
Message: message,
Files: filesForUpstream,
}
}

Expand Down
Loading