on main help sign in
fix(server): support attachments in client-server mode
27a35c9Christian Rocha
internal/backend/agent.go+1−1
@@ -19,7 +19,7 @@ func (b *Backend) SendMessage(ctx context.Context, workspaceID string, msg proto
19 return ErrAgentNotInitialized
19 return ErrAgentNotInitialized
20 }
20 }
21
21
22− _, err = ws.AgentCoordinator.Run(ctx, msg.SessionID, msg.Prompt)
22+ _, err = ws.AgentCoordinator.Run(ctx, msg.SessionID, msg.Prompt, proto.AttachmentsToMessage(msg.Attachments)...)
23 return err
23 return err
24}
24}
25
25
internal/client/proto.go+1−10
@@ -335,19 +335,10 @@ func (c *Client) UpdateAgent(ctx context.Context, id string) error {
335
335
336// SendMessage sends a message to the agent for a workspace.
336// SendMessage sends a message to the agent for a workspace.
337func (c *Client) SendMessage(ctx context.Context, id string, sessionID, prompt string, attachments ...message.Attachment) error {
337func (c *Client) SendMessage(ctx context.Context, id string, sessionID, prompt string, attachments ...message.Attachment) error {
338− protoAttachments := make([]proto.Attachment, len(attachments))
339− for i, a := range attachments {
340− protoAttachments[i] = proto.Attachment{
341− FilePath: a.FilePath,
342− FileName: a.FileName,
343− MimeType: a.MimeType,
344− Content: a.Content,
345− }
346− }
347 rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent", id), nil, jsonBody(proto.AgentMessage{
338 rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent", id), nil, jsonBody(proto.AgentMessage{
348 SessionID: sessionID,
339 SessionID: sessionID,
349 Prompt: prompt,
340 Prompt: prompt,
350− Attachments: protoAttachments,
341+ Attachments: proto.AttachmentsFromMessage(attachments),
351 }), http.Header{"Content-Type": []string{"application/json"}})
342 }), http.Header{"Content-Type": []string{"application/json"}})
352 if err != nil {
343 if err != nil {
353 return fmt.Errorf("failed to send message to agent: %w", err)
344 return fmt.Errorf("failed to send message to agent: %w", err)
internal/proto/message.go+42
@@ -8,6 +8,7 @@ import (
8 "time"
8 "time"
9
9
10 "charm.land/catwalk/pkg/catwalk"
10 "charm.land/catwalk/pkg/catwalk"
11+ "github.com/charmbracelet/crush/internal/message"
11)
12)
12
13
13// CreateMessageParams represents parameters for creating a message.
14// CreateMessageParams represents parameters for creating a message.
@@ -621,6 +622,47 @@ type Attachment struct {
621 Content []byte `json:"content"`
622 Content []byte `json:"content"`
622}
623}
623
624
625+// ToMessage converts a proto Attachment to a [message.Attachment].
626+func (a Attachment) ToMessage() message.Attachment {
627+ return message.Attachment{
628+ FilePath: a.FilePath,
629+ FileName: a.FileName,
630+ MimeType: a.MimeType,
631+ Content: a.Content,
632+ }
633+}
634+
635+// AttachmentFromMessage converts a [message.Attachment] to a proto
636+// Attachment.
637+func AttachmentFromMessage(a message.Attachment) Attachment {
638+ return Attachment{
639+ FilePath: a.FilePath,
640+ FileName: a.FileName,
641+ MimeType: a.MimeType,
642+ Content: a.Content,
643+ }
644+}
645+
646+// AttachmentsToMessage converts a slice of proto Attachments to a slice
647+// of [message.Attachment].
648+func AttachmentsToMessage(as []Attachment) []message.Attachment {
649+ out := make([]message.Attachment, len(as))
650+ for i, a := range as {
651+ out[i] = a.ToMessage()
652+ }
653+ return out
654+}
655+
656+// AttachmentsFromMessage converts a slice of [message.Attachment] to a
657+// slice of proto Attachments.
658+func AttachmentsFromMessage(as []message.Attachment) []Attachment {
659+ out := make([]Attachment, len(as))
660+ for i, a := range as {
661+ out[i] = AttachmentFromMessage(a)
662+ }
663+ return out
664+}
665+
624// MarshalJSON implements the [json.Marshaler] interface.
666// MarshalJSON implements the [json.Marshaler] interface.
625func (a Attachment) MarshalJSON() ([]byte, error) {
667func (a Attachment) MarshalJSON() ([]byte, error) {
626 type Alias Attachment
668 type Alias Attachment