Skip to content

Commit c821ca0

Browse files
committed
added summarization
1 parent 74504b3 commit c821ca0

File tree

4 files changed

+68
-4
lines changed

4 files changed

+68
-4
lines changed

discord-bot/pkg/bot/campaign.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@ func campaignHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
185185
if err := campaign.Close(); err != nil {
186186
slog.Warn("unexpected error while stopping campaign", "campaign", campaign.Name, "error", err)
187187
}
188+
summary, err := campaign.Summary()
189+
if err != nil {
190+
slog.Warn("could not summarize campaign transcript", "error", err)
191+
} else {
192+
s.InteractionResponseEdit(respI, &discordgo.WebhookEdit{
193+
Content: &summary,
194+
})
195+
}
188196
// Cleanup
189197
close(componentButtons[i.GuildID]["stop_campaign"])
190198
delete(componentButtons[i.GuildID], "stop_campaign")
@@ -193,7 +201,7 @@ func campaignHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
193201
s.InteractionRespond(respI, &discordgo.InteractionResponse{
194202
Type: discordgo.InteractionResponseUpdateMessage,
195203
Data: &discordgo.InteractionResponseData{
196-
Content: "Transcript finished",
204+
Content: "Transcript finished.",
197205
Files: []*discordgo.File{
198206
{
199207
Name: "transcript.txt",

discord-bot/pkg/pnp/campaign.go

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,25 @@ package pnp
22

33
import (
44
"bytes"
5+
"context"
56
"fmt"
67
"io"
78
"log/slog"
89
"math/rand"
910
"sync"
1011
"text/template"
1112

13+
"github.com/MrWong99/TaileVoices/discord_bot/pkg/oai"
1214
"github.com/MrWong99/TaileVoices/discord_bot/pkg/vecdb"
15+
"github.com/sashabaranov/go-openai"
1316
"gopkg.in/yaml.v3"
1417

1518
_ "embed"
1619
)
1720

21+
//go:embed summarization_prompt.txt
22+
var summarizationPrompt string
23+
1824
//go:embed stt_init_prompt.tpl
1925
var sttPromptText string
2026

@@ -186,11 +192,9 @@ func (c *Campaign) HandleText(name string, segment string) {
186192
}
187193

188194
go func() {
189-
c.transcriptMu.Lock()
190195
promptContext := PromptContext{
191-
CurrentTranscript: c.CurrentSessionTranscript,
196+
CurrentTranscript: c.CurrentTranscript(),
192197
}
193-
c.transcriptMu.Unlock() // don't defer as it will be a deadlock once c.HandleText() is called
194198
oldTranscripts, err := c.dbClient.SearchTranscripts(c.Name, segment)
195199
if err != nil {
196200
slog.Warn("could not search old transcripts for reference", "error", err, "collection", c.Name, "concept", segment)
@@ -210,6 +214,37 @@ func (c *Campaign) HandleText(name string, segment string) {
210214
}()
211215
}
212216

217+
// Summary of the current campaign transcript. Excludes all non pen & paper related content.
218+
// Uses a GenAI to do the summary.
219+
//
220+
// Can be called after Close() has been called.
221+
func (c *Campaign) Summary() (string, error) {
222+
resp, err := oai.Client.CreateChatCompletion(context.Background(), openai.ChatCompletionRequest{
223+
Model: openai.GPT4o,
224+
Messages: []openai.ChatCompletionMessage{
225+
{
226+
Role: openai.ChatMessageRoleSystem,
227+
Content: summarizationPrompt,
228+
},
229+
{
230+
Role: openai.ChatMessageRoleUser,
231+
Content: c.CurrentTranscript(),
232+
},
233+
},
234+
})
235+
if err != nil {
236+
return "", fmt.Errorf("failed to create chat completion: %w", err)
237+
}
238+
return resp.Choices[0].Message.Content, nil
239+
}
240+
241+
// CurrentTranscript of this session.
242+
func (c *Campaign) CurrentTranscript() string {
243+
c.transcriptMu.Lock()
244+
defer c.transcriptMu.Unlock()
245+
return c.CurrentSessionTranscript
246+
}
247+
213248
// Close this campaigns session by closing C() and storing its transcript in the vector database.
214249
func (c *Campaign) Close() error {
215250
close(c.actorResponses)

discord-bot/pkg/pnp/npc_system_prompt.tpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Other name: text line
2929
3030
Your answers should be responses in natural language that fit into the end of the current transcript.
3131
Omit your name at the beginning of the line so instead of "Name: My response" just respond "My response".
32+
Also never include lines of other speakers, just speak your next line and nothing more!
3233
Always answer in the same language as the current transcript!
3334
Keep your answers short unless the following script tells you otherwise.
3435
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
You have the task of summarising a transcription of a role-play session. Your aim is to create a step-by-step summary of this transcription. List individual scenes in a bulleted list, e.g. like this:
2+
3+
1. at the beginning, the money is in...
4+
2. a dragon appears and...
5+
3. the heroes travel back home...
6+
7+
Concentrate only on what happened in the role-play and do not include any meta-information that has nothing to do with the role-play. Try to record the events objectively, but at the same time tell an exciting story. Always answer in the language that the transcription was provided in!
8+
9+
Transcripts always have the following format:
10+
11+
12+
Character name 1: Role play text or meta question
13+
GameMaster: Narrative line or spoken line of the NPC
14+
Character name 2: Role-playing text or meta-question
15+
...
16+
17+
18+
The transcription therefore alternates between different characters, and each of them can either speak as the character they are currently playing or ask meta-questions about the current campaign.
19+
The gamemaster's job is to provide a narrative and context to the roleplay. The gamemaster can also impersonate an NPC.
20+
You will need to check each person's transcriptions and the context in which they are made to determine if they are impersonating a specific character or not roleplaying at all. Remember that the gamemaster sets most of the context for the roleplay

0 commit comments

Comments
 (0)