feat: allow to send the prompt if its empty but has text attachments (#1809)

Carlos Alexandro Becker and Copilot created

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Change summary

internal/agent/agent.go        |  2 +-
internal/message/attachment.go | 12 +++++++++++-
internal/ui/chat/user.go       |  6 +++++-
internal/ui/model/ui.go        |  2 +-
4 files changed, 18 insertions(+), 4 deletions(-)

Detailed changes

internal/agent/agent.go 🔗

@@ -134,7 +134,7 @@ func NewSessionAgent(
 }
 
 func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy.AgentResult, error) {
-	if call.Prompt == "" {
+	if call.Prompt == "" && !message.ContainsTextAttachment(call.Attachments) {
 		return nil, ErrEmptyPrompt
 	}
 	if call.SessionID == "" {

internal/message/attachment.go 🔗

@@ -1,6 +1,9 @@
 package message
 
-import "strings"
+import (
+	"slices"
+	"strings"
+)
 
 type Attachment struct {
 	FilePath string
@@ -11,3 +14,10 @@ type Attachment struct {
 
 func (a Attachment) IsText() bool  { return strings.HasPrefix(a.MimeType, "text/") }
 func (a Attachment) IsImage() bool { return strings.HasPrefix(a.MimeType, "image/") }
+
+// ContainsTextAttachment returns true if any of the attachments is a text attachment.
+func ContainsTextAttachment(attachments []Attachment) bool {
+	return slices.ContainsFunc(attachments, func(a Attachment) bool {
+		return a.IsText()
+	})
+}

internal/ui/chat/user.go 🔗

@@ -60,7 +60,11 @@ func (m *UserMessageItem) Render(width int) string {
 
 	if len(m.message.BinaryContent()) > 0 {
 		attachmentsStr := m.renderAttachments(cappedWidth)
-		content = strings.Join([]string{content, "", attachmentsStr}, "\n")
+		if content == "" {
+			content = attachmentsStr
+		} else {
+			content = strings.Join([]string{content, "", attachmentsStr}, "\n")
+		}
 	}
 
 	height = lipgloss.Height(content)

internal/ui/model/ui.go 🔗

@@ -872,7 +872,7 @@ func (m *UI) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
 
 				attachments := m.attachments.List()
 				m.attachments.Reset()
-				if len(value) == 0 {
+				if len(value) == 0 && !message.ContainsTextAttachment(attachments) {
 					return nil
 				}