blob: b1e8bcd681798d7688e338283967038dcf15428e [file] [log] [blame]
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"context"
"golang.org/x/oscar/internal/llm"
"golang.org/x/oscar/internal/llmapp"
"golang.org/x/oscar/internal/storage"
)
// IssueOverviewResult is the result of [IssueOverview].
// It contains the generated overview and metadata about
// the issue.
type IssueOverviewResult struct {
URL string // the issue's URL
NumComments int // number of comments for this issue
Overview string // the LLM-generated issue and comment summary
Prompt []string // the prompt(s) used to generate the result
}
// IssueOverview returns an LLM-generated overview of the issue and its comments.
// It does not make any requests to GitHub; the issue and comment data must already
// be stored in db.
func IssueOverview(ctx context.Context, g llm.TextGenerator, db storage.DB, project string, issue int64) (*IssueOverviewResult, error) {
var docs []*llmapp.Doc
var m issueMetadata
for e := range events(db, project, issue, issue) {
m.update(e)
doc := e.toLLMDoc()
if doc == nil {
continue
}
docs = append(docs, doc)
}
overview, err := llmapp.Overview(ctx, g, llmapp.PostAndComments, docs...)
if err != nil {
return nil, err
}
return &IssueOverviewResult{
URL: m.url,
NumComments: m.numComments,
Overview: overview,
Prompt: llmapp.OverviewPrompt(llmapp.PostAndComments, docs),
}, nil
}
type issueMetadata struct {
url string
numComments int
}
// update updates the issueMetadata given the event.
func (m *issueMetadata) update(e *Event) {
switch v := e.Typed.(type) {
case *Issue:
m.url = v.HTMLURL
case *IssueComment:
m.numComments++
}
}
// toLLMDoc converts an Event to a format that can be used as
// an input to an LLM.
// It returns nil if the Event cannot be converted to a document.
func (e *Event) toLLMDoc() *llmapp.Doc {
switch v := e.Typed.(type) {
case *Issue:
return &llmapp.Doc{
Type: "issue",
URL: v.HTMLURL,
Author: v.User.Login,
Title: v.Title,
Text: v.Body,
}
case *IssueComment:
return &llmapp.Doc{
Type: "issue comment",
URL: v.HTMLURL,
Author: v.User.Login,
// no title
Text: v.Body,
}
}
return nil
}