8000 feat: attach files action by dwmkerr · Pull Request #89 · dwmkerr/terminal-ai · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: attach files action #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 13 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ Attach file to the chat with the `-f` or `--file` parameter:
ai -f package.json -f package-lock.json -- "what's my package version and most complex transitive dependency?"
```

You can also attach files interactively with the [Attach File Action](#attach-file-action).

![Demo Recording of Attaching Files](./docs/casts/attach-files/ai-files.svg)

### Attaching Images
Expand All @@ -111,11 +113,14 @@ Attach images to the chat with the `--image-file` parameter:
ai -f --image-file fish.jpg -- "what is this a picture of?"
```

When you use `--image-file` rather than `--file`, the model's vision APIs will be used, meaning that in the chat you can ask questions about the content of the images.
When you use `--image-file` rather than `--file`, the model's vision APIs will be used, meaning that in the chat you can ask questions about the content of the images. You can also attach files interactively with the [Attach File Action](#attach-file-action).

![Demo Recording of Attaching Files](./docs/casts/attach-files/ai-files.svg)
![Demo Recording of Attaching Images](./docs/casts/image-files/image-file.svg)

Note that vision processing is required for the model which is being used. A reference is at [`ai-providers-and-models`](https://github.com/dwmkerr/ai-providers-and-models). If the model doesn't support vision a Compatibility Error will be raised.
Notes:

- Vision processing is required for the model which is being used. A reference is at [`ai-providers-and-models`](https://github.com/dwmkerr/ai-providers-and-models). If the model doesn't support vision a Compatibility Error will be raised.
- You can also upload images using the `--file` parameter. In this case images are base 64 encoded and will be uploaded as text in the chat - meaning that although the provider will not be able to recognise the image, it could still answer questions such as what type of file does it appear to be, what is its size and so on.

### Copying to the Clipboard or Saving to a File

Expand Down Expand Up @@ -175,29 +180,15 @@ Tips:

- Suggested models and descriptions are loaded from [`ai-providers-and-models`](https://github.com/dwmkerr/ai-providers-and-models)

### Advanced

Advanced or experimental features.

Force color output (useful if you are piping and need color codes):

```bash
# Force color output:
# - set FORCE_COLOR=1
# - ascii formatting will be applied even if stdout is not a tty
# - use 'less -r' (-r = raw, render color codes) as a way to quickly test.
FORCE_COLOR=1 ai 'show me some markdown features' | less -r
```

Example of how to interactively stage, generate a conventional commit:
## Actions

- [`aigac.sh`](./docs/casts/aigac.sh) - AI Git Add Commit shell script
When you press `Enter` in the chat prompt, the Actions menu will pop up. These actions offer additional features to work with AI.

<a href="./docs/casts/aigac.svg"><img width="480px" src="./docs/casts/aigac.svg" /></a>
### Attach File Action

## Actions
The 'Attach File' action allows you to interactively attach files to a chat message. Files can be processed as text or images (if supported by the currently selected model):

When you press `Enter` in the chat prompt, the Actions menu will pop up. These actions offer additional features to work with AI.
[Recording of the Attach File action](./docs/casts/attach-file-action/attach-file-action.svg)

### Change Model

Expand Down
20 changes: 20 additions & 0 deletions docs/advanced.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Advanced

Advanced features.

Force color output (useful if you are piping and need color codes):

```bash
# Force color output:
# - set FORCE_COLOR=1
# - ascii formatting will be applied even if stdout is not a tty
# - use 'less -r' (-r = raw, render color codes) as a way to quickly test.
FORCE_COLOR=1 ai 'show me some markdown features' | less -r
```

Example of how to interactively stage, generate a conventional commit:

- [`aigac.sh`](./docs/casts/aigac.sh) - AI Git Add Commit shell script

<a href="./docs/casts/aigac.svg"><img width="480px" src="./docs/casts/aigac.svg" /></a>

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
774 changes: 774 additions & 0 deletions docs/casts/attach-file-action/attach-file-action.cast

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/casts/attach-file-action/attach-file-action.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/casts/image-files/image-file-default.gif
6D40
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
163 changes: 163 additions & 0 deletions docs/casts/image-files/image-file.cast

Large diffs are not rendered by default.

Binary file added docs/casts/image-files/image-file.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/casts/image-files/image-file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"colors": "^1.4.0",
"commander": "^11.1.0",
"debug": "^4.3.4",
"inquirer-file-selector": "^0.6.2",
"isbinaryfile": "^5.0.4",
"js-yaml": "^4.1.0",
"langfuse": "^3.36.0",
Expand Down
50 changes: 50 additions & 0 deletions src/chat-actions/AttachFileAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { select } from "@inquirer/prompts";
import { ChatPipelineParameters } from "../chat-pipeline/ChatPipelineParameters";
import { ChatAction } from "./ChatAction";
import { ErrorCode, TerminalAIError } from "../lib/errors";

export const AttachFileAction: ChatAction = {
id: "attach_file",
displayNameInitial: "Attach File",
displayNameReply: "Attach File",
isInitialInteractionAction: true,
isDebugAction: false,
weight: 0,
execute: async (
params: ChatPipelineParameters,
): Promise<string | undefined> => {
const fileSelector = (await import("inquirer-file-selector")).default;
const path = await fileSelector({
message: "File path:",
type: "file",
});
const fileType = await select({
message: "File processing mode:",
choices: [
{
name: "Text",
value: "text",
description: "Process as text. Ideal for code, documents, etc.",
},
{
name: "Image",
value: "image",
description:
"Vision processing (model dependent). Enables image recognition, etc.",
},
],
});
if (fileType === "text") {
params.chatContext.filePathsOutbox.push(path);
} else if (fileType === "image") {
params.chatContext.imageFilePathsOutbox.push(path);
} else {
throw new TerminalAIError(
ErrorCode.InvalidOperation,
"unknown file processing '${fileType}'",
);
}

return undefined;
},
};

Check warning on line 50 in src/chat-actions/AttachFileAction.ts

View check run for this annotation

Codecov / codecov/patch

src/chat-actions/AttachFileAction.ts#L2-L50

Added lines #L2 - L50 were not covered by tests
35 changes: 0 additions & 35 deletions src/chat-actions/UploadFileAction.ts

This file was deleted.

2 changes: 2 additions & 0 deletions src/chat-actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import { ReplyAction } from "./ReplyAction";
import { SaveResponseAction } from "./SaveResponseAction";
import { ChangeModelAction } from "./ChangeModelAction";
import { AttachFileAction } from "./AttachFileAction";

Check warning on line 10 in src/chat-actions/index.ts

View check run for this annotation

Codecov / codecov/patch

src/chat-actions/index.ts#L10

Added line #L10 was not covered by tests

export const ChatActions: ChatAction[] = [
ReplyAction,
FullscreenInputAction,
AttachFileAction,

Check warning on line 15 in src/chat-actions/index.ts

View check run for this annotation

Codecov / codecov/patch

src/chat-actions/index.ts#L15

Added line #L15 was not covered by tests
ChangeModelAction,
CopyResponseAction,
SaveResponseAction,
Expand Down
0