Part data model (#950)
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -364,55 +365,76 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
case opencode.EventListResponseEventSessionDeleted:
|
||||
if a.app.Session != nil && msg.Properties.Info.ID == a.app.Session.ID {
|
||||
a.app.Session = &opencode.Session{}
|
||||
a.app.Messages = []opencode.MessageUnion{}
|
||||
a.app.Messages = []app.Message{}
|
||||
}
|
||||
return a, toast.NewSuccessToast("Session deleted successfully")
|
||||
case opencode.EventListResponseEventSessionUpdated:
|
||||
if msg.Properties.Info.ID == a.app.Session.ID {
|
||||
a.app.Session = &msg.Properties.Info
|
||||
}
|
||||
case opencode.EventListResponseEventMessagePartUpdated:
|
||||
slog.Info("message part updated", "message", msg.Properties.Part.MessageID, "part", msg.Properties.Part.ID)
|
||||
if msg.Properties.Part.SessionID == a.app.Session.ID {
|
||||
messageIndex := slices.IndexFunc(a.app.Messages, func(m app.Message) bool {
|
||||
switch casted := m.Info.(type) {
|
||||
case opencode.UserMessage:
|
||||
return casted.ID == msg.Properties.Part.MessageID
|
||||
case opencode.AssistantMessage:
|
||||
return casted.ID == msg.Properties.Part.MessageID
|
||||
}
|
||||
return false
|
||||
})
|
||||
if messageIndex > -1 {
|
||||
message := a.app.Messages[messageIndex]
|
||||
partIndex := slices.IndexFunc(message.Parts, func(p opencode.PartUnion) bool {
|
||||
switch casted := p.(type) {
|
||||
case opencode.TextPart:
|
||||
return casted.ID == msg.Properties.Part.ID
|
||||
case opencode.FilePart:
|
||||
return casted.ID == msg.Properties.Part.ID
|
||||
case opencode.ToolPart:
|
||||
return casted.ID == msg.Properties.Part.ID
|
||||
case opencode.StepStartPart:
|
||||
return casted.ID == msg.Properties.Part.ID
|
||||
case opencode.StepFinishPart:
|
||||
return casted.ID == msg.Properties.Part.ID
|
||||
}
|
||||
return false
|
||||
})
|
||||
if partIndex > -1 {
|
||||
message.Parts[partIndex] = msg.Properties.Part.AsUnion()
|
||||
}
|
||||
if partIndex == -1 {
|
||||
message.Parts = append(message.Parts, msg.Properties.Part.AsUnion())
|
||||
}
|
||||
a.app.Messages[messageIndex] = message
|
||||
}
|
||||
}
|
||||
case opencode.EventListResponseEventMessageUpdated:
|
||||
if msg.Properties.Info.SessionID == a.app.Session.ID {
|
||||
exists := false
|
||||
optimisticReplaced := false
|
||||
matchIndex := slices.IndexFunc(a.app.Messages, func(m app.Message) bool {
|
||||
switch casted := m.Info.(type) {
|
||||
case opencode.UserMessage:
|
||||
return casted.ID == msg.Properties.Info.ID
|
||||
case opencode.AssistantMessage:
|
||||
return casted.ID == msg.Properties.Info.ID
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// First check if this is replacing an optimistic message
|
||||
if msg.Properties.Info.Role == opencode.MessageRoleUser {
|
||||
// Look for optimistic messages to replace
|
||||
for i, m := range a.app.Messages {
|
||||
switch m := m.(type) {
|
||||
case opencode.UserMessage:
|
||||
if strings.HasPrefix(m.ID, "optimistic-") && m.Role == opencode.UserMessageRoleUser {
|
||||
// Replace the optimistic message with the real one
|
||||
a.app.Messages[i] = msg.Properties.Info.AsUnion()
|
||||
exists = true
|
||||
optimisticReplaced = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if matchIndex > -1 {
|
||||
match := a.app.Messages[matchIndex]
|
||||
a.app.Messages[matchIndex] = app.Message{
|
||||
Info: msg.Properties.Info.AsUnion(),
|
||||
Parts: match.Parts,
|
||||
}
|
||||
}
|
||||
|
||||
// If not replacing optimistic, check for existing message with same ID
|
||||
if !optimisticReplaced {
|
||||
for i, m := range a.app.Messages {
|
||||
var id string
|
||||
switch m := m.(type) {
|
||||
case opencode.UserMessage:
|
||||
id = m.ID
|
||||
case opencode.AssistantMessage:
|
||||
id = m.ID
|
||||
}
|
||||
if id == msg.Properties.Info.ID {
|
||||
a.app.Messages[i] = msg.Properties.Info.AsUnion()
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !exists {
|
||||
a.app.Messages = append(a.app.Messages, msg.Properties.Info.AsUnion())
|
||||
if matchIndex == -1 {
|
||||
a.app.Messages = append(a.app.Messages, app.Message{
|
||||
Info: msg.Properties.Info.AsUnion(),
|
||||
Parts: []opencode.PartUnion{},
|
||||
})
|
||||
}
|
||||
}
|
||||
case opencode.EventListResponseEventSessionError:
|
||||
@@ -473,10 +495,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return a, toast.NewErrorToast("Failed to open session")
|
||||
}
|
||||
a.app.Session = msg
|
||||
a.app.Messages = make([]opencode.MessageUnion, 0)
|
||||
for _, message := range messages {
|
||||
a.app.Messages = append(a.app.Messages, message.AsUnion())
|
||||
}
|
||||
a.app.Messages = messages
|
||||
return a, util.CmdHandler(app.SessionLoadedMsg{})
|
||||
case app.ModelSelectedMsg:
|
||||
a.app.Provider = &msg.Provider
|
||||
@@ -837,7 +856,7 @@ func (a appModel) executeCommand(command commands.Command) (tea.Model, tea.Cmd)
|
||||
return a, nil
|
||||
}
|
||||
a.app.Session = &opencode.Session{}
|
||||
a.app.Messages = []opencode.MessageUnion{}
|
||||
a.app.Messages = []app.Message{}
|
||||
cmds = append(cmds, util.CmdHandler(app.SessionClearedMsg{}))
|
||||
case commands.SessionListCommand:
|
||||
sessionDialog := dialog.NewSessionDialog(a.app)
|
||||
|
||||
Reference in New Issue
Block a user