-
Notifications
You must be signed in to change notification settings - Fork 0
/
vx.go
94 lines (80 loc) · 2.94 KB
/
vx.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package vx
import (
"time"
"github.com/hum/vcat"
"github.com/sashabaranov/go-openai"
)
// GetVideoExplanationStreamRequests retrieves the transcription of a given URL,
// then splits the transcript into smaller segments according to the provided opts.ChunkSize.
//
// It returns a slice of openai.ChatCompletionRequest objects that can be used to interactively stream responses from the API.
func GetVideoExplanationRequests(c *openai.Client, opts VideoExplanationOpts) ([]openai.ChatCompletionRequest, error) {
transcript, err := vcat.GetTranscription(opts.Url, "en")
if err != nil {
return nil, err
}
chunks, err := chunkTranscriptByTimeDelta(transcript, opts.ChunkSize)
if err != nil {
return nil, err
}
requests := makeRequests(chunks, opts)
return requests, nil
}
// Given a single TextBucket, this function constructs an individual request object for the API
// If no model is explicitly set via opts.Model, it defaults to 'mistral-7b-instruct'.
func NewChatCompletionRequest(chunk TextBucket, opts VideoExplanationOpts) *openai.ChatCompletionRequest {
if opts.Model == nil {
model := "mistral-7b-instruct"
opts.Model = &model
}
return &openai.ChatCompletionRequest{
Model: *opts.Model,
Stream: opts.Stream,
Messages: []openai.ChatCompletionMessage{
{
Content: opts.Prompt + chunk.Text,
Role: openai.ChatMessageRoleUser,
},
},
}
}
// makeRequest takes in a slice of TextBuckets and returns API requests based on the provided opts.
func makeRequests(chunks []TextBucket, opts VideoExplanationOpts) []openai.ChatCompletionRequest {
var result = make([]openai.ChatCompletionRequest, 0, len(chunks))
for _, chunk := range chunks {
request := NewChatCompletionRequest(chunk, opts)
result = append(result, *request)
}
return result
}
// chunkTranscriptByTimeDelta takes in a whole video transcript and splits it into buckets that are the length of the provided duration parameter d.
func chunkTranscriptByTimeDelta(transcript *vcat.Transcript, d time.Duration) ([]TextBucket, error) {
var (
result = make([]TextBucket, 0)
tmp = ""
currLatestTime, _ = time.Parse(time.TimeOnly, transcript.Text[0].Start)
)
for _, text := range transcript.Text {
var (
startTime, _ = time.Parse(time.TimeOnly, text.Start)
endTime, _ = time.Parse(time.TimeOnly, text.End)
)
if startTime.After(currLatestTime.Add(d)) {
result = append(result, TextBucket{Start: currLatestTime, End: endTime, Text: tmp})
currLatestTime = startTime
tmp = ""
continue
}
tmp += " " + text.Text
}
// Append any leftover data if it did not fit within the duration
var (
startTime, _ = time.Parse(time.TimeOnly, transcript.Text[len(transcript.Text)-1].Start)
endTime, _ = time.Parse(time.TimeOnly, transcript.Text[len(transcript.Text)-1].End)
text = transcript.Text[len(transcript.Text)-1].Text
)
if tmp != "" {
result = append(result, TextBucket{Start: startTime, End: endTime, Text: text})
}
return result, nil
}