Skip to content

Commit de728c3

Browse files
committed
Add helpers for showing notifications
Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
1 parent 4d54245 commit de728c3

4 files changed

Lines changed: 34 additions & 26 deletions

File tree

pkg/tui/components/notification/notification.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
tea "charm.land/bubbletea/v2"
99
"charm.land/lipgloss/v2"
1010

11+
"github.com/docker/cagent/pkg/tui/core"
1112
"github.com/docker/cagent/pkg/tui/styles"
1213
)
1314

@@ -38,6 +39,27 @@ type HideMsg struct {
3839
ID uint64 // If 0, hides all notifications (backward compatibility)
3940
}
4041

42+
func SuccessCmd(text string) tea.Cmd {
43+
return core.CmdHandler(ShowMsg{
44+
Text: text,
45+
Type: TypeSuccess,
46+
})
47+
}
48+
49+
func WarningCmd(text string) tea.Cmd {
50+
return core.CmdHandler(ShowMsg{
51+
Text: text,
52+
Type: TypeWarning,
53+
})
54+
}
55+
56+
func ErrorCmd(text string) tea.Cmd {
57+
return core.CmdHandler(ShowMsg{
58+
Text: text,
59+
Type: TypeError,
60+
})
61+
}
62+
4163
// notificationItem represents a single notification
4264
type notificationItem struct {
4365
ID uint64

pkg/tui/page/chat/chat.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,7 @@ func (p *chatPage) Update(msg tea.Msg) (layout.Model, tea.Cmd) {
305305
cmd := p.messages.AddShellOutputMessage(msg.Output)
306306
return p, cmd
307307
case *runtime.WarningEvent:
308-
cmd := core.CmdHandler(notification.ShowMsg{Text: msg.Message, Type: notification.TypeWarning})
309-
return p, cmd
308+
return p, notification.WarningCmd(msg.Message)
310309
case *runtime.RAGIndexingStartedEvent, *runtime.RAGIndexingProgressEvent, *runtime.RAGIndexingCompletedEvent:
311310
// Forward RAG events to sidebar
312311
slog.Debug("Chat page forwarding RAG event to sidebar", "event_type", fmt.Sprintf("%T", msg))

pkg/tui/page/chat/editor.go

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
tea "charm.land/bubbletea/v2"
1111

1212
"github.com/docker/cagent/pkg/tui/components/notification"
13-
"github.com/docker/cagent/pkg/tui/core"
1413
)
1514

1615
// editorDoneMsg is sent when the external editor finishes to trigger a TUI refresh.
@@ -24,20 +23,14 @@ func (p *chatPage) openExternalEditor() tea.Cmd {
2423
// Create a temporary file with the current content
2524
tmpFile, err := os.CreateTemp("", "cagent-*.md")
2625
if err != nil {
27-
return core.CmdHandler(notification.ShowMsg{
28-
Text: fmt.Sprintf("Failed to create temp file: %v", err),
29-
Type: notification.TypeError,
30-
})
26+
return notification.ErrorCmd(fmt.Sprintf("Failed to create temp file: %v", err))
3127
}
3228
tmpPath := tmpFile.Name()
3329

3430
if _, err := tmpFile.WriteString(content); err != nil {
3531
tmpFile.Close()
3632
os.Remove(tmpPath)
37-
return core.CmdHandler(notification.ShowMsg{
38-
Text: fmt.Sprintf("Failed to write temp file: %v", err),
39-
Type: notification.TypeError,
40-
})
33+
return notification.ErrorCmd(fmt.Sprintf("Failed to write temp file: %v", err))
4134
}
4235
tmpFile.Close()
4336

@@ -63,20 +56,14 @@ func (p *chatPage) openExternalEditor() tea.Cmd {
6356
return tea.ExecProcess(cmd, func(err error) tea.Msg {
6457
if err != nil {
6558
os.Remove(tmpPath)
66-
return core.CmdHandler(notification.ShowMsg{
67-
Type: notification.TypeError,
68-
Text: fmt.Sprintf("Editor error: %v", err),
69-
})
59+
return notification.ErrorCmd(fmt.Sprintf("Editor error: %v", err))
7060
}
7161

7262
updatedContent, readErr := os.ReadFile(tmpPath)
7363
os.Remove(tmpPath)
7464

7565
if readErr != nil {
76-
return core.CmdHandler(notification.ShowMsg{
77-
Text: fmt.Sprintf("Failed to read edited file: %v", readErr),
78-
Type: notification.TypeError,
79-
})
66+
return notification.ErrorCmd(fmt.Sprintf("Failed to read edited file: %v", readErr))
8067
}
8168

8269
// Trim trailing newline that editors often add

pkg/tui/tui.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,22 +210,22 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
210210

211211
case messages.EvalSessionMsg:
212212
evalFile, _ := evaluation.Save(a.application.Session(), msg.Filename)
213-
return a, core.CmdHandler(notification.ShowMsg{Text: fmt.Sprintf("Eval saved to file %s", evalFile)})
213+
return a, notification.SuccessCmd(fmt.Sprintf("Eval saved to file %s", evalFile))
214214

215215
case messages.CompactSessionMsg:
216216
return a, a.chatPage.CompactSession()
217217

218218
case messages.CopySessionToClipboardMsg:
219219
transcript := a.application.PlainTextTranscript()
220220
if transcript == "" {
221-
return a, core.CmdHandler(notification.ShowMsg{Text: "Conversation is empty; nothing copied."})
221+
return a, notification.SuccessCmd("Conversation is empty; nothing copied.")
222222
}
223223

224224
if err := clipboard.WriteAll(transcript); err != nil {
225-
return a, core.CmdHandler(notification.ShowMsg{Text: "Failed to copy conversation: " + err.Error(), Type: notification.TypeError})
225+
return a, notification.ErrorCmd("Failed to copy conversation: " + err.Error())
226226
}
227227

228-
return a, core.CmdHandler(notification.ShowMsg{Text: "Conversation copied to clipboard."})
228+
return a, notification.SuccessCmd("Conversation copied to clipboard.")
229229

230230
case messages.ToggleYoloMsg:
231231
sess := a.application.Session()
@@ -236,7 +236,7 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
236236
} else {
237237
statusText = "Yolo mode disabled: tools will require confirmation"
238238
}
239-
return a, core.CmdHandler(notification.ShowMsg{Text: statusText})
239+
return a, notification.SuccessCmd(statusText)
240240

241241
case messages.AgentCommandMsg:
242242
resolvedCommand := a.application.ResolveCommand(context.Background(), msg.Command)
@@ -246,7 +246,7 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
246246
// Convert the interface{} back to mcptools.PromptInfo
247247
promptInfo, ok := msg.PromptInfo.(mcptools.PromptInfo)
248248
if !ok {
249-
return a, core.CmdHandler(notification.ShowMsg{Text: "Invalid prompt info"})
249+
return a, notification.ErrorCmd("Invalid prompt info")
250250
}
251251
// Show the MCP prompt input dialog
252252
return a, core.CmdHandler(dialog.OpenDialogMsg{
@@ -258,7 +258,7 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
258258
promptContent, err := a.application.ExecuteMCPPrompt(context.Background(), msg.PromptName, msg.Arguments)
259259
if err != nil {
260260
errorMsg := fmt.Sprintf("Error executing MCP prompt '%s': %v", msg.PromptName, err)
261-
return a, core.CmdHandler(notification.ShowMsg{Text: errorMsg})
261+
return a, notification.ErrorCmd(errorMsg)
262262
}
263263
return a, core.CmdHandler(editor.SendMsg{Content: promptContent})
264264

0 commit comments

Comments
 (0)