no brain command
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
bin/
|
bin/
|
||||||
config.yml
|
config.yml
|
||||||
ask
|
ask
|
||||||
|
discord
|
||||||
|
|||||||
@@ -23,7 +23,19 @@ var (
|
|||||||
commands = []*discordgo.ApplicationCommand{
|
commands = []*discordgo.ApplicationCommand{
|
||||||
{
|
{
|
||||||
Name: "ask",
|
Name: "ask",
|
||||||
Description: "Stelle eine Frage an deinen AI Brain",
|
Description: "Stelle eine Frage an deinen AI Brain (mit Wissensdatenbank)",
|
||||||
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
|
{
|
||||||
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
|
Name: "frage",
|
||||||
|
Description: "Die Frage, die du stellen möchtest",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "asknobrain",
|
||||||
|
Description: "Stelle eine Frage direkt ans LLM (ohne Wissensdatenbank)",
|
||||||
Options: []*discordgo.ApplicationCommandOption{
|
Options: []*discordgo.ApplicationCommandOption{
|
||||||
{
|
{
|
||||||
Type: discordgo.ApplicationCommandOptionString,
|
Type: discordgo.ApplicationCommandOptionString,
|
||||||
@@ -95,19 +107,18 @@ func onReady(s *discordgo.Session, r *discordgo.Ready) {
|
|||||||
|
|
||||||
func registerCommands() {
|
func registerCommands() {
|
||||||
guildID := config.Cfg.Discord.GuildID
|
guildID := config.Cfg.Discord.GuildID
|
||||||
for _, cmd := range commands {
|
registered, err := dg.ApplicationCommandBulkOverwrite(dg.State.User.ID, guildID, commands)
|
||||||
_, err := dg.ApplicationCommandCreate(dg.State.User.ID, guildID, cmd)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("⚠️ Slash-Command /%s konnte nicht registriert werden: %v", cmd.Name, err)
|
log.Fatalf("❌ Slash-Commands konnten nicht registriert werden: %v", err)
|
||||||
} else {
|
}
|
||||||
scope := "global"
|
scope := "global"
|
||||||
if guildID != "" {
|
if guildID != "" {
|
||||||
scope = "guild " + guildID
|
scope = "guild " + guildID
|
||||||
}
|
}
|
||||||
|
for _, cmd := range registered {
|
||||||
fmt.Printf("📝 Slash-Command /%s registriert (%s)\n", cmd.Name, scope)
|
fmt.Printf("📝 Slash-Command /%s registriert (%s)\n", cmd.Name, scope)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func onInteraction(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
func onInteraction(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||||||
if i.Type != discordgo.InteractionApplicationCommand {
|
if i.Type != discordgo.InteractionApplicationCommand {
|
||||||
@@ -116,7 +127,9 @@ func onInteraction(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|||||||
|
|
||||||
switch i.ApplicationCommandData().Name {
|
switch i.ApplicationCommandData().Name {
|
||||||
case "ask":
|
case "ask":
|
||||||
handleAsk(s, i, i.ApplicationCommandData().Options[0].StringValue())
|
handleAsk(s, i, i.ApplicationCommandData().Options[0].StringValue(), true)
|
||||||
|
case "asknobrain":
|
||||||
|
handleAsk(s, i, i.ApplicationCommandData().Options[0].StringValue(), false)
|
||||||
case "ingest":
|
case "ingest":
|
||||||
handleIngest(s, i)
|
handleIngest(s, i)
|
||||||
case "remember":
|
case "remember":
|
||||||
@@ -157,13 +170,22 @@ func onMessage(s *discordgo.Session, m *discordgo.MessageCreate) {
|
|||||||
s.ChannelMessageSendReply(m.ChannelID, reply, m.Reference())
|
s.ChannelMessageSendReply(m.ChannelID, reply, m.Reference())
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleAsk(s *discordgo.Session, i *discordgo.InteractionCreate, question string) {
|
func handleAsk(s *discordgo.Session, i *discordgo.InteractionCreate, question string, useBrain bool) {
|
||||||
// Sofort mit "Denke nach..." antworten (Discord-Timeout: 3s)
|
|
||||||
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||||||
Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
|
Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
|
||||||
})
|
})
|
||||||
|
|
||||||
reply := queryAndFormat(question)
|
var reply string
|
||||||
|
if useBrain {
|
||||||
|
reply = queryAndFormat(question)
|
||||||
|
} else {
|
||||||
|
answer, err := brain.ChatDirect(question)
|
||||||
|
if err != nil {
|
||||||
|
reply = fmt.Sprintf("❌ Fehler: %v", err)
|
||||||
|
} else {
|
||||||
|
reply = fmt.Sprintf("💬 **Antwort:** _%s_\n\n%s", question, answer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
|
s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{
|
||||||
Content: &reply,
|
Content: &reply,
|
||||||
@@ -190,7 +212,14 @@ func handleRemember(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
text := i.ApplicationCommandData().Options[0].StringValue()
|
text := i.ApplicationCommandData().Options[0].StringValue()
|
||||||
author := i.Member.User.Username
|
var author string
|
||||||
|
if i.Member != nil {
|
||||||
|
author = i.Member.User.Username
|
||||||
|
} else if i.User != nil {
|
||||||
|
author = i.User.Username
|
||||||
|
} else {
|
||||||
|
author = "unknown"
|
||||||
|
}
|
||||||
source := fmt.Sprintf("discord/#%s", i.ChannelID)
|
source := fmt.Sprintf("discord/#%s", i.ChannelID)
|
||||||
|
|
||||||
err := brain.IngestChatMessage(text, author, source)
|
err := brain.IngestChatMessage(text, author, source)
|
||||||
|
|||||||
@@ -169,4 +169,38 @@ func buildContext(chunks []KnowledgeChunk) string {
|
|||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ChatDirect stellt eine Frage direkt an das LLM ohne Datenbankkontext.
|
||||||
|
func ChatDirect(question string) (string, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
chatClient := config.NewChatClient()
|
||||||
|
|
||||||
|
systemPrompt := `Du bist ein hilfreicher persönlicher Assistent. Antworte auf Deutsch, präzise und direkt.`
|
||||||
|
|
||||||
|
stream, err := chatClient.CreateChatCompletionStream(ctx, openai.ChatCompletionRequest{
|
||||||
|
Model: config.Cfg.Chat.Model,
|
||||||
|
Messages: []openai.ChatCompletionMessage{
|
||||||
|
{Role: openai.ChatMessageRoleSystem, Content: systemPrompt},
|
||||||
|
{Role: openai.ChatMessageRoleUser, Content: question},
|
||||||
|
},
|
||||||
|
Temperature: 0.7,
|
||||||
|
MaxTokens: 500,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("LLM Fehler: %w", err)
|
||||||
|
}
|
||||||
|
defer stream.Close()
|
||||||
|
|
||||||
|
var answer strings.Builder
|
||||||
|
for {
|
||||||
|
response, err := stream.Recv()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if len(response.Choices) > 0 {
|
||||||
|
answer.WriteString(response.Choices[0].Delta.Content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return answer.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func floatPtr(f float32) *float32 { return &f }
|
func floatPtr(f float32) *float32 { return &f }
|
||||||
|
|||||||
Reference in New Issue
Block a user