diff --git a/internal/backend/agent.go b/internal/backend/agent.go index 8cc2ada26ca737bbe79fe989cc52e4ede9712dc5..346e54bf8069af5f0f8b3bbde049aaed70e86cff 100644 --- a/internal/backend/agent.go +++ b/internal/backend/agent.go @@ -19,7 +19,7 @@ func (b *Backend) SendMessage(ctx context.Context, workspaceID string, msg proto return ErrAgentNotInitialized } - _, err = ws.AgentCoordinator.Run(ctx, msg.SessionID, msg.Prompt) + _, err = ws.AgentCoordinator.Run(ctx, msg.SessionID, msg.Prompt, proto.AttachmentsToMessage(msg.Attachments)...) return err } diff --git a/internal/client/proto.go b/internal/client/proto.go index 442a4f0f3a8ff90981ab90e24fcdcdd98adf4004..213120273e5adb849236ac346ccfb5802d1cf16c 100644 --- a/internal/client/proto.go +++ b/internal/client/proto.go @@ -335,19 +335,10 @@ func (c *Client) UpdateAgent(ctx context.Context, id string) error { // SendMessage sends a message to the agent for a workspace. func (c *Client) SendMessage(ctx context.Context, id string, sessionID, prompt string, attachments ...message.Attachment) error { - protoAttachments := make([]proto.Attachment, len(attachments)) - for i, a := range attachments { - protoAttachments[i] = proto.Attachment{ - FilePath: a.FilePath, - FileName: a.FileName, - MimeType: a.MimeType, - Content: a.Content, - } - } rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/agent", id), nil, jsonBody(proto.AgentMessage{ SessionID: sessionID, Prompt: prompt, - Attachments: protoAttachments, + Attachments: proto.AttachmentsFromMessage(attachments), }), http.Header{"Content-Type": []string{"application/json"}}) if err != nil { return fmt.Errorf("failed to send message to agent: %w", err) diff --git a/internal/proto/message.go b/internal/proto/message.go index f1ae259cf2cd3238b522c31cd46387abc4fd6173..307dd71ff2de48e942a9dce77b2a9fcb8a6507d4 100644 --- a/internal/proto/message.go +++ b/internal/proto/message.go @@ -8,6 +8,7 @@ import ( "time" "charm.land/catwalk/pkg/catwalk" + "github.com/charmbracelet/crush/internal/message" ) // CreateMessageParams represents parameters for creating a message. @@ -621,6 +622,47 @@ type Attachment struct { Content []byte `json:"content"` } +// ToMessage converts a proto Attachment to a [message.Attachment]. +func (a Attachment) ToMessage() message.Attachment { + return message.Attachment{ + FilePath: a.FilePath, + FileName: a.FileName, + MimeType: a.MimeType, + Content: a.Content, + } +} + +// AttachmentFromMessage converts a [message.Attachment] to a proto +// Attachment. +func AttachmentFromMessage(a message.Attachment) Attachment { + return Attachment{ + FilePath: a.FilePath, + FileName: a.FileName, + MimeType: a.MimeType, + Content: a.Content, + } +} + +// AttachmentsToMessage converts a slice of proto Attachments to a slice +// of [message.Attachment]. +func AttachmentsToMessage(as []Attachment) []message.Attachment { + out := make([]message.Attachment, len(as)) + for i, a := range as { + out[i] = a.ToMessage() + } + return out +} + +// AttachmentsFromMessage converts a slice of [message.Attachment] to a +// slice of proto Attachments. +func AttachmentsFromMessage(as []message.Attachment) []Attachment { + out := make([]Attachment, len(as)) + for i, a := range as { + out[i] = AttachmentFromMessage(a) + } + return out +} + // MarshalJSON implements the [json.Marshaler] interface. func (a Attachment) MarshalJSON() ([]byte, error) { type Alias Attachment