diff --git a/internal/tui/components/chat/editor/editor.go b/internal/tui/components/chat/editor/editor.go index a355dad512a9772ef8bcd0d954a44e0f6d5aefcd..72be82c7e1ee88fe8ae367e65c577b1b423dbdb8 100644 --- a/internal/tui/components/chat/editor/editor.go +++ b/internal/tui/components/chat/editor/editor.go @@ -240,6 +240,10 @@ func isExtOfAllowedImageType(path string) bool { type ResolveAbs func(path string) (string, error) +func onPaste(msg tea.PasteMsg) tea.Msg { + return filepicker.OnPaste(filepicker.ResolveFS, string(msg)) +} + func activeModelHasImageSupport() (bool, string) { agentCfg := config.Get().Agents["coder"] model := config.Get().GetModelByType(agentCfg.Model) @@ -279,6 +283,13 @@ func (m *editorCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case OpenEditorMsg: m.textarea.SetValue(msg.Text) m.textarea.MoveToEnd() + case tea.PasteMsg: + agentCfg := config.Get().Agents["coder"] + model := config.Get().GetModelByType(agentCfg.Model) + if !model.SupportsImages { + return m, util.ReportWarn("File attachments are not supported by the current model: " + model.Name) + } + return m, util.CmdHandler(onPaste(msg)) // inject fsys accessible from PWD case commands.ToggleYoloModeMsg: m.setEditorPrompt() return m, nil diff --git a/internal/tui/components/dialogs/filepicker/filepicker.go b/internal/tui/components/dialogs/filepicker/filepicker.go index 9da2922b1712671e4f9b1a3c497d1b2c9b83299e..810cf91bd0a862010c7d062aaef6d3e6c71abb47 100644 --- a/internal/tui/components/dialogs/filepicker/filepicker.go +++ b/internal/tui/components/dialogs/filepicker/filepicker.go @@ -130,7 +130,7 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // Get the path of the selected file. return m, tea.Sequence( util.CmdHandler(dialogs.CloseDialogMsg{}), - onPaste(resolveFS, path), + OnPaste(ResolveFS, path), ) } m.image, cmd = m.image.Update(msg) @@ -138,11 +138,11 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, tea.Batch(cmds...) } -func resolveFS(baseDirPath string) fs.FS { +func ResolveFS(baseDirPath string) fs.FS { return os.DirFS(baseDirPath) } -func onPaste(resolveFsys func(path string) fs.FS, path string) func() tea.Msg { +func OnPaste(resolveFsys func(path string) fs.FS, path string) func() tea.Msg { fsys := resolveFsys(filepath.Dir(path)) name := filepath.Base(path) return func() tea.Msg { diff --git a/internal/tui/components/dialogs/filepicker/filepicker_test.go b/internal/tui/components/dialogs/filepicker/filepicker_test.go index 45e04b9da9e7af0e04e62c538375f4ebe7fc0a1e..b32c20d6d8fe0406949cd55f5be7260c96ba633f 100644 --- a/internal/tui/components/dialogs/filepicker/filepicker_test.go +++ b/internal/tui/components/dialogs/filepicker/filepicker_test.go @@ -35,7 +35,7 @@ func TestOnPasteMockFSWithValidPath(t *testing.T) { } // Test with the first file - cmd := onPaste(resolveTestFS, makePathCanonical("/home/testuser/images/image1.png")) + cmd := OnPaste(resolveTestFS, makePathCanonical("/home/testuser/images/image1.png")) msg := cmd() assert.Equal(t, makePathCanonical("/home/testuser/images"), mockedFSPath) @@ -61,7 +61,7 @@ func TestOnPasteMockFSWithInvalidPath(t *testing.T) { } // Test with the first file - cmd, ok := onPaste(resolveTestFS, makePathCanonical("/home/testuser/images/nonexistent.png"))().(tea.Cmd) + cmd, ok := OnPaste(resolveTestFS, makePathCanonical("/home/testuser/images/nonexistent.png"))().(tea.Cmd) require.True(t, ok) msg := cmd()