Skip to content

Commit

Permalink
feat: upgrade sum command (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
namnhce authored Aug 22, 2024
1 parent b5385e2 commit 0ba5c6d
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 65 deletions.
9 changes: 9 additions & 0 deletions pkg/adapter/adapter.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package adapter

import (
"github.com/dwarvesf/fortress-discord/pkg/adapter/dify"
"github.com/dwarvesf/fortress-discord/pkg/adapter/fortress"
"github.com/dwarvesf/fortress-discord/pkg/adapter/mochi"
"github.com/dwarvesf/fortress-discord/pkg/adapter/openai"
Expand All @@ -18,6 +19,8 @@ type subAdapter struct {
Mochi mochi.MochiAdapter
OpenAI openai.OpenAIAdapter
Tono tono.TonoAdapter
Reddit reddit.Adapter
Dify dify.DifyAdapter
}

func New(cfg *config.Config, l logger.Logger) IAdapter {
Expand All @@ -27,6 +30,8 @@ func New(cfg *config.Config, l logger.Logger) IAdapter {
Mochi: mochi.New(cfg.Endpoint.Mochi),
OpenAI: openai.New(cfg.OpenAI.APIKey),
Tono: tono.New(cfg),
Reddit: reddit,
Dify: dify.New(cfg.Dify.BaseURL, cfg.Dify.SummarizerAppToken),
},
}
}
Expand All @@ -47,3 +52,7 @@ func (a *Adapter) OpenAI() openai.OpenAIAdapter {
func (a *Adapter) Tono() tono.TonoAdapter {
return a.subAdapter.Tono
}

func (a *Adapter) Dify() dify.DifyAdapter {
return a.subAdapter.Dify
}
154 changes: 154 additions & 0 deletions pkg/adapter/dify/dify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package dify

import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)

type Dify struct {
BaseURL string
SummarizerAppToken string
}

// New function return dify service
func New(baseURL, summarizerAppToken string) DifyAdapter {
return &Dify{
BaseURL: baseURL,
SummarizerAppToken: summarizerAppToken,
}
}

// BaseEvent represents the common fields in the event
type BaseEvent struct {
Event string `json:"event,omitempty"`
ConversationID string `json:"conversation_id,omitempty"`
MessageID string `json:"message_id,omitempty"`
CreatedAt int64 `json:"created_at,omitempty"`
TaskID string `json:"task_id,omitempty"`
ID string `json:"id,omitempty"`
Position int `json:"position,omitempty"`
}

// AgentThought represents the specific fields for agent_thought events
type AgentThought struct {
BaseEvent
Thought string `json:"thought,omitempty"`
Observation string `json:"observation,omitempty"`
Tool string `json:"tool,omitempty"`
ToolLabels interface{} `json:"tool_labels,omitempty"`
ToolInput string `json:"tool_input,omitempty"`
MessageFiles interface{} `json:"message_files,omitempty"`
}

// AgentMessage represents the specific fields for agent_message events
type AgentMessage struct {
BaseEvent
Answer string `json:"answer,omitempty"`
}

func (d *Dify) SummarizeArticle(url string) (content string, err error) {
// Define the URL and request body
requestBody, err := json.Marshal(map[string]interface{}{
"inputs": map[string]interface{}{},
"query": url,
"response_mode": "streaming",
"conversation_id": "",
"user": "fortress",
})
if err != nil {
return "", err
}

// Create the HTTP request
req, err := http.NewRequest(http.MethodPost, d.BaseURL, bytes.NewBuffer(requestBody))
if err != nil {
return "", nil
}

// Set the required headers
req.Header.Set("Authorization", "Bearer "+d.SummarizerAppToken)
req.Header.Set("Content-Type", "application/json")

client := &http.Client{
Timeout: 5 * time.Minute,
}

resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()

// Check the response status
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("unexpected status code: %d", resp.StatusCode)
}

// Handle streaming response
var thoughts []AgentThought
reader := bufio.NewReader(resp.Body)
for {
line, err := reader.ReadBytes('\n')
if err != nil {
if err == io.EOF {
break
}
return "", err
}

// Remove the "data: " prefix
line = bytes.TrimPrefix(line, []byte("data: "))
line = bytes.TrimSpace(line)
if len(line) == 0 {
continue
}

// Parse the JSON event to a map to determine the event type
var rawEvent map[string]interface{}
err = json.Unmarshal(line, &rawEvent)
if err != nil {
fmt.Printf("Error unmarshal: %v\n", string(line))
continue
}

eventType, ok := rawEvent["event"].(string)
if !ok {
fmt.Println("Error: event type is missing or not a string")
continue
}

// Process specific event types
switch eventType {
case "agent_thought":
var event AgentThought
err = json.Unmarshal(line, &event)
if err != nil {
fmt.Printf("Error parsing agent_thought JSON: %v\n", err)
continue
}
thoughts = append(thoughts, event)
case "agent_message":
// just ignore agent_message event
default:
}
}

// get the last event
if len(thoughts) == 0 {
return "", fmt.Errorf("no thought found")
}

for i := len(thoughts) - 1; i >= 0; i-- {
if thoughts[i].Thought != "" {
content = thoughts[i].Thought
break
}
}

return content, nil
}
5 changes: 5 additions & 0 deletions pkg/adapter/dify/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package dify

type DifyAdapter interface {
SummarizeArticle(youtubeURL string) (content string, err error)
}
3 changes: 3 additions & 0 deletions pkg/adapter/interface.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package adapter

import (
"github.com/dwarvesf/fortress-discord/pkg/adapter/dify"
"github.com/dwarvesf/fortress-discord/pkg/adapter/fortress"
"github.com/dwarvesf/fortress-discord/pkg/adapter/mochi"
"github.com/dwarvesf/fortress-discord/pkg/adapter/openai"
Expand All @@ -12,4 +13,6 @@ type IAdapter interface {
Mochi() mochi.MochiAdapter
OpenAI() openai.OpenAIAdapter
Tono() tono.TonoAdapter
Reddit() reddit.Adapter
Dify() dify.DifyAdapter
}
9 changes: 9 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Config struct {
OpenAI OpenAI
Discord Discord
Reddit Reddit
Dify Dify

Endpoint Endpoint
}
Expand Down Expand Up @@ -59,6 +60,10 @@ type ApiServer struct {
AllowedOrigins string
}

type Dify struct {
BaseURL string
SummarizerAppToken string
}
type ENV interface {
GetBool(string) bool
GetString(string) string
Expand Down Expand Up @@ -98,6 +103,10 @@ func Generate(v ENV) *Config {
Username: v.GetString("REDDIT_USERNAME"),
Password: v.GetString("REDDIT_PASSWORD"),
},
Dify: Dify{
BaseURL: v.GetString("DIFY_BASE_URL"),
SummarizerAppToken: v.GetString("DIFY_SUMMARIZER_APP_TOKEN"),
},
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/discord/command/sum/sum.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (e *Sum) Sum(message *model.DiscordMessage) error {
// 1. get data from service
data, err := e.svc.Sum().SummarizeArticle(url)
if err != nil {
e.L.Error(err, "can't get list of weekly icy distribution")
e.L.Error(err, "failed to summarize the given article")
return err
}

Expand Down
75 changes: 37 additions & 38 deletions pkg/discord/interaction_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"time"

"github.com/bwmarrin/discordgo"
"github.com/dwarvesf/fortress-discord/pkg/constant"
"github.com/dwarvesf/fortress-discord/pkg/discord/view/base"
"github.com/dwarvesf/fortress-discord/pkg/model"
)
Expand Down Expand Up @@ -60,27 +59,27 @@ func (d *Discord) onInteractionCreate(s *discordgo.Session, i *discordgo.Interac

return
case "enter_withdraw_value_btn" + i.Interaction.User.ID:
cond, err := d.Command.S.Withdrawal().CheckWithdrawCondition(i.Interaction.User.ID)
if err != nil {
d.L.Error(err, "failed to check withdraw condition "+i.Interaction.User.ID)
d.Command.View.Withdraw().ErrorWithdraw(&model.DiscordMessage{
ChannelId: i.ChannelID,
Author: i.Interaction.User,
}, err)
return
}
//cond, err := d.Command.S.Withdrawal().CheckWithdrawCondition(i.Interaction.User.ID)
//if err != nil {
// d.L.Error(err, "failed to check withdraw condition "+i.Interaction.User.ID)
// d.Command.View.Withdraw().ErrorWithdraw(&model.DiscordMessage{
// ChannelId: i.ChannelID,
// Author: i.Interaction.User,
// }, err)
// return
//}

bankSwiftCode := i.ModalSubmitData().Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value
bankAccountNumber := i.ModalSubmitData().Components[1].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value
bankAccountOwner := i.ModalSubmitData().Components[2].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value
icyAmount := i.ModalSubmitData().Components[3].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value
//bankSwiftCode := i.ModalSubmitData().Components[0].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value
//bankAccountNumber := i.ModalSubmitData().Components[1].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value
//bankAccountOwner := i.ModalSubmitData().Components[2].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value
//icyAmount := i.ModalSubmitData().Components[3].(*discordgo.ActionsRow).Components[0].(*discordgo.TextInput).Value

fmt.Println(i.Interaction.User.ID)
fmt.Println(bankSwiftCode)
fmt.Println(bankAccountNumber)
fmt.Println(bankAccountOwner)
fmt.Println(icyAmount)
fmt.Println(cond)
//fmt.Println(i.Interaction.User.ID)
//fmt.Println(bankSwiftCode)
//fmt.Println(bankAccountNumber)
//fmt.Println(bankAccountOwner)
//fmt.Println(icyAmount)
//fmt.Println(cond)

// TODO: Send this payload to Fortress for transfer request.

Expand All @@ -105,24 +104,24 @@ func (d *Discord) onInteractionCreate(s *discordgo.Session, i *discordgo.Interac
// }
//}()

s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseUpdateMessage,
Data: &discordgo.InteractionResponseData{
Embeds: []*discordgo.MessageEmbed{
base.Normalize(s, &discordgo.MessageEmbed{
Title: "Request Approved!\n",
Description: fmt.Sprint(
"Your ICY is on the way, we will notify you shortly\n\n",
fmt.Sprintf("`Amount. ` %s\n", fmt.Sprintf("%s **%s ICY**", constant.GetEmoji("ICY"), icyAmount)),
fmt.Sprintf("`Receiver.` %s\n", fmt.Sprintf("<@%s>", i.Interaction.User.ID)),
"try $bals in Mochi app to see your balance",
),
}),
},
},
})

return
//s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
// Type: discordgo.InteractionResponseUpdateMessage,
// Data: &discordgo.InteractionResponseData{
// Embeds: []*discordgo.MessageEmbed{
// base.Normalize(s, &discordgo.MessageEmbed{
// Title: "Request Approved!\n",
// Description: fmt.Sprint(
// "Your ICY is on the way, we will notify you shortly\n\n",
// fmt.Sprintf("`Amount. ` %s\n", fmt.Sprintf("%s **%s ICY**", constant.GetEmoji("ICY"), icyAmount)),
// fmt.Sprintf("`Receiver.` %s\n", fmt.Sprintf("<@%s>", i.Interaction.User.ID)),
// "try $bals in Mochi app to see your balance",
// ),
// }),
// },
// },
//})
//
//return
}
}

Expand Down
Loading

0 comments on commit 0ba5c6d

Please sign in to comment.