ask-cli-ai 1.0.12 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -18
- package/dist/app.js +15 -3
- package/dist/commands/ask.js +84 -55
- package/dist/commands/clearHistory.js +1 -1
- package/dist/commands/config.js +87 -0
- package/dist/commands/connect.js +112 -0
- package/dist/commands/selectModel.js +11 -17
- package/dist/components/command.js +58 -0
- package/dist/components/commands.js +14 -0
- package/dist/components/provider.js +88 -22
- package/dist/components/providers.js +32 -30
- package/dist/components/selectModel.js +92 -54
- package/dist/components/testProvider.js +14 -0
- package/dist/components/textField.js +6 -26
- package/dist/components/textInput.js +136 -0
- package/dist/components/welcome.js +4 -15
- package/dist/hooks/useExit.js +17 -0
- package/dist/hooks/useField.js +20 -0
- package/dist/hooks/useTestProvider.js +63 -0
- package/dist/install.js +5 -0
- package/dist/migrations/1-settings-1.1.0.js +56 -0
- package/dist/migrations/2-add-providers-1.2.0.js +60 -0
- package/dist/stores/config.js +59 -40
- package/dist/stores/history.js +43 -28
- package/dist/stores/store.js +16 -22
- package/dist/templates/instructions.js +6 -4
- package/dist/types/setting.js +3 -0
- package/dist/utils/defaultConfig.js +58 -0
- package/dist/utils/getDataDir.js +17 -0
- package/dist/utils/paths.js +7 -0
- package/dist/utils/validateUrl.js +10 -0
- package/package.json +74 -70
- package/dist/components/apiKeyField.js +0 -13
- package/dist/providers.js +0 -35
- package/dist/utils/dataDir.js +0 -19
- package/dist/utils/root.js +0 -3
package/README.md
CHANGED
|
@@ -17,11 +17,11 @@ Forget about switching between applications to know how to use a command or fix
|
|
|
17
17
|
## Content
|
|
18
18
|
|
|
19
19
|
- [Why use Ask CLI?](#why-use-ask-cli)
|
|
20
|
-
- [For whom is Ask CLI?](#for-whom-is-ask-cli)
|
|
21
20
|
- [Installation](#installation)
|
|
22
21
|
- [Usage](#usage)
|
|
23
22
|
- [Select model](#select-model)
|
|
24
23
|
- [Supported models](#supported-models)
|
|
24
|
+
- [Connect to local or external providers](#connect-to-local-or-external-providers)
|
|
25
25
|
- [Reference](#reference)
|
|
26
26
|
|
|
27
27
|
## Why use Ask CLI?
|
|
@@ -31,15 +31,8 @@ Why use Ask CLI and not an AI agent like Claude or Gemini?
|
|
|
31
31
|
- Ask CLI was created to do one thing and do it well: help you with commands, coding, apps and more from your terminal.
|
|
32
32
|
- The AI models it uses are optimized to generate short, precise and fast answers.
|
|
33
33
|
- No risk of prompt injection, Ask CLI cannot run commands or access your files by default.
|
|
34
|
-
- No risk of running dangerous commands on your computer
|
|
35
|
-
|
|
36
|
-
## For whom is Ask CLI?
|
|
37
|
-
|
|
38
|
-
- Students who want to learn how to use commands and the terminal.
|
|
39
|
-
- Developers who want to be more productive and avoid context switching.
|
|
40
|
-
- Sysadmins who need quick help with commands and troubleshooting.
|
|
41
|
-
- DevOps engineers who want to automate tasks and get help with commands.
|
|
42
|
-
- Anyone working in production environments where security is critical.
|
|
34
|
+
- No risk of running dangerous commands on your computer. See [Running commands](#running-commands) for more details.
|
|
35
|
+
- Designed for anyone who wants fast, secure, and precise help directly in the terminal.
|
|
43
36
|
|
|
44
37
|
## Installation
|
|
45
38
|
|
|
@@ -49,7 +42,7 @@ npm install -g ask-cli-ai
|
|
|
49
42
|
|
|
50
43
|
## Usage
|
|
51
44
|
|
|
52
|
-
> To use Ask CLI, you first need to set up the API key. See
|
|
45
|
+
> To use Ask CLI, you first need to set up the API key. See [Select model](#select-model) to learn how.
|
|
53
46
|
|
|
54
47
|
### Ask questions
|
|
55
48
|
|
|
@@ -58,9 +51,9 @@ npm install -g ask-cli-ai
|
|
|
58
51
|
ask <your question>
|
|
59
52
|
|
|
60
53
|
# Examples
|
|
61
|
-
ask how to
|
|
62
|
-
ask what is a promise
|
|
63
|
-
ask how to create a
|
|
54
|
+
ask how to terminate a linux process
|
|
55
|
+
ask what is a javascript promise
|
|
56
|
+
ask how to create a git branch
|
|
64
57
|
|
|
65
58
|
# Using quotes
|
|
66
59
|
ask 'What does this command do: git config user.name "Ask CLI"?'
|
|
@@ -68,7 +61,7 @@ ask 'What does this command do: git config user.name "Ask CLI"?'
|
|
|
68
61
|
|
|
69
62
|
### Aliases
|
|
70
63
|
|
|
71
|
-
You can use
|
|
64
|
+
You can use **`how`** and **`what`** as aliases for the **`ask`** command:
|
|
72
65
|
|
|
73
66
|
```bash
|
|
74
67
|
# Using 'how' alias
|
|
@@ -80,7 +73,7 @@ what is the difference between git merge and rebase
|
|
|
80
73
|
|
|
81
74
|
### Running commands
|
|
82
75
|
|
|
83
|
-
By default, Ask CLI cannot run commands on your computer. However, you can use the
|
|
76
|
+
By default, Ask CLI cannot run commands on your computer. However, you can use the **`-c`** or **`--command`** option to execute a command and include its output in your question. This allows Ask CLI to analyze errors, logs, or any command output and provide context-aware answers.
|
|
84
77
|
|
|
85
78
|
```bash
|
|
86
79
|
# Analyze an error
|
|
@@ -95,7 +88,7 @@ ask what is wrong here -c "git status"
|
|
|
95
88
|
|
|
96
89
|
## Select model
|
|
97
90
|
|
|
98
|
-
You can select a model using the
|
|
91
|
+
You can select a model using the **`ask /models`** command. This will list all the available models and let you select the model you want to use.
|
|
99
92
|
|
|
100
93
|

|
|
101
94
|
|
|
@@ -126,12 +119,18 @@ You can select a model using the `ask /models` command. This will list all the a
|
|
|
126
119
|
- Claude Sonnet 4.5
|
|
127
120
|
- Claude Opus 4.5
|
|
128
121
|
|
|
122
|
+
## Connect to local or external providers
|
|
123
|
+
|
|
124
|
+
You can use the **`ask /connect`** command to connect to local models or external providers, using an **OpenAI-compatible API**, like llama.cpp, Ollama, Hugging Face, etc.
|
|
125
|
+
|
|
126
|
+

|
|
127
|
+
|
|
129
128
|
## Reference
|
|
130
129
|
|
|
131
130
|
```
|
|
132
131
|
AI CLI to help you with commands, coding, apps and more.
|
|
133
132
|
|
|
134
|
-
Version: 1.0
|
|
133
|
+
Version: 1.2.0
|
|
135
134
|
|
|
136
135
|
Usage: ask <prompt..>
|
|
137
136
|
|
|
@@ -139,6 +138,8 @@ Commands:
|
|
|
139
138
|
ask <prompt..> Ask something. Alias: what, how [default]
|
|
140
139
|
ask /models Select a model
|
|
141
140
|
ask /providers Setup providers
|
|
141
|
+
ask /config Configuration
|
|
142
|
+
ask /connect Connect to an external provider using OpenAI-compatible API
|
|
142
143
|
ask /history List the chat history
|
|
143
144
|
ask /clear Clear the chat history
|
|
144
145
|
|
package/dist/app.js
CHANGED
|
@@ -7,10 +7,12 @@ import { listHistory } from "./commands/listHistory.js";
|
|
|
7
7
|
import { clearHistory } from "./commands/clearHistory.js";
|
|
8
8
|
import { providers } from "./commands/providers.js";
|
|
9
9
|
import { logo } from "./utils/logo.js";
|
|
10
|
+
import { config } from "./commands/config.js";
|
|
11
|
+
import { connect } from "./commands/connect.js";
|
|
10
12
|
void yargs(hideBin(process.argv))
|
|
11
13
|
.scriptName('ask')
|
|
12
|
-
.usage(`${logo}\nAI CLI to help you with commands, coding, apps and more.\n\nVersion: 1.0
|
|
13
|
-
.version('1.0
|
|
14
|
+
.usage(`${logo}\nAI CLI to help you with commands, coding, apps and more.\n\nVersion: 1.2.0\n\nUsage: $0 <prompt..>`)
|
|
15
|
+
.version('1.2.0')
|
|
14
16
|
.locale('en')
|
|
15
17
|
.example('$0 how to run a docker container', '')
|
|
16
18
|
.example('how to setup my git account', '')
|
|
@@ -39,6 +41,16 @@ void yargs(hideBin(process.argv))
|
|
|
39
41
|
command: '/providers',
|
|
40
42
|
describe: 'Setup providers',
|
|
41
43
|
handler: () => providers()
|
|
44
|
+
})
|
|
45
|
+
.command({
|
|
46
|
+
command: '/config',
|
|
47
|
+
describe: 'Configuration',
|
|
48
|
+
handler: () => config()
|
|
49
|
+
})
|
|
50
|
+
.command({
|
|
51
|
+
command: '/connect',
|
|
52
|
+
describe: 'Connect to an external provider using OpenAI-compatible API',
|
|
53
|
+
handler: () => connect()
|
|
42
54
|
})
|
|
43
55
|
.command({
|
|
44
56
|
command: '/history',
|
|
@@ -51,4 +63,4 @@ void yargs(hideBin(process.argv))
|
|
|
51
63
|
handler: () => clearHistory()
|
|
52
64
|
})
|
|
53
65
|
.parse();
|
|
54
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
66
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDeEMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLG1CQUFvQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwyQkFBNEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzFELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBMEIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHNCQUF1QixDQUFDO0FBQy9DLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx1QkFBd0IsQ0FBQztBQUVqRCxLQUFLLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQzlCLFVBQVUsQ0FBQyxLQUFLLENBQUM7S0FDakIsS0FBSyxDQUFDLEdBQUcsSUFBSSxzR0FBc0csQ0FBQztLQUNwSCxPQUFPLENBQUMsT0FBTyxDQUFDO0tBQ2hCLE1BQU0sQ0FBQyxJQUFJLENBQUM7S0FDWixPQUFPLENBQUMsa0NBQWtDLEVBQUUsRUFBRSxDQUFDO0tBQy9DLE9BQU8sQ0FBQyw2QkFBNkIsRUFBRSxFQUFFLENBQUM7S0FDMUMsT0FBTyxDQUFDLDJCQUEyQixFQUFFLEVBQUUsQ0FBQztLQUN4QyxPQUFPLENBQUMsNENBQTRDLEVBQUUsRUFBRSxDQUFDO0tBQ3pELElBQUksRUFBRTtLQUNOLE9BQU8sQ0FBQztJQUNQLE9BQU8sRUFBRSxlQUFlO0lBQ3hCLFFBQVEsRUFBRSxpQ0FBaUM7SUFDM0MsT0FBTyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSztTQUNwQixVQUFVLENBQUMsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztTQUN6RSxNQUFNLENBQUMsU0FBUyxFQUFFO1FBQ2pCLEtBQUssRUFBRSxDQUFDLEdBQUcsQ0FBQztRQUNaLElBQUksRUFBRSxRQUFRO1FBQ2QsV0FBVyxFQUFFLG9CQUFvQjtRQUNqQyxXQUFXLEVBQUUsSUFBSTtLQUNsQixDQUFDO0lBQ0osT0FBTyxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQztDQUM1RCxDQUFDO0tBQ0QsT0FBTyxDQUFDO0lBQ1AsT0FBTyxFQUFFLFNBQVM7SUFDbEIsUUFBUSxFQUFFLGdCQUFnQjtJQUMxQixPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsV0FBVyxFQUFFO0NBQzdCLENBQUM7S0FDRCxPQUFPLENBQUM7SUFDUCxPQUFPLEVBQUUsWUFBWTtJQUNyQixRQUFRLEVBQUUsaUJBQWlCO0lBQzNCLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxTQUFTLEVBQUU7Q0FDM0IsQ0FBQztLQUNELE9BQU8sQ0FBQztJQUNQLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFFBQVEsRUFBRSxlQUFlO0lBQ3pCLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUU7Q0FDeEIsQ0FBQztLQUNELE9BQU8sQ0FBQztJQUNQLE9BQU8sRUFBRSxVQUFVO0lBQ25CLFFBQVEsRUFBRSw2REFBNkQ7SUFDdkUsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRTtDQUN6QixDQUFDO0tBQ0QsT0FBTyxDQUFDO0lBQ1AsT0FBTyxFQUFFLFVBQVU7SUFDbkIsUUFBUSxFQUFFLHVCQUF1QjtJQUNqQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsV0FBVyxFQUFFO0NBQzdCLENBQUM7S0FDRCxPQUFPLENBQUM7SUFDUCxPQUFPLEVBQUUsUUFBUTtJQUNqQixRQUFRLEVBQUUsd0JBQXdCO0lBQ2xDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxZQUFZLEVBQUU7Q0FDOUIsQ0FBQztLQUNELEtBQUssRUFBRSxDQUFDIn0=
|
package/dist/commands/ask.js
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import util from 'node:util';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import fs from 'node:fs/promises';
|
|
5
|
-
import { exec as execCb } from 'node:child_process';
|
|
6
3
|
import findProcess from 'find-process';
|
|
7
4
|
import chalk from 'chalk';
|
|
5
|
+
import { exec as execCb } from 'node:child_process';
|
|
8
6
|
import { useEffect, useState } from 'react';
|
|
9
|
-
import { Box, render, Static, Text
|
|
7
|
+
import { Box, render, Static, Text } from 'ink';
|
|
10
8
|
import { ChatGoogleGenerativeAI } from '@langchain/google-genai';
|
|
11
9
|
import { configStore } from "../stores/config.js";
|
|
12
10
|
import { historyStore } from "../stores/history.js";
|
|
13
11
|
import { Welcome } from "../components/welcome.js";
|
|
14
12
|
import { Loading } from "../components/loading.js";
|
|
15
|
-
import { root } from "../utils/root.js";
|
|
16
13
|
import { ChatAnthropic } from '@langchain/anthropic';
|
|
17
14
|
import { ChatOpenAI } from '@langchain/openai';
|
|
18
15
|
import { instructions } from "../templates/instructions.js";
|
|
19
|
-
import {
|
|
16
|
+
import { useExit } from "../hooks/useExit.js";
|
|
17
|
+
import { SelectModel } from "../components/selectModel.js";
|
|
20
18
|
const exec = util.promisify(execCb);
|
|
21
19
|
const config = await configStore.get();
|
|
22
20
|
const history = await historyStore.get();
|
|
@@ -25,81 +23,80 @@ export function ask(prompt, command) {
|
|
|
25
23
|
}
|
|
26
24
|
function Ask(props) {
|
|
27
25
|
const { prompt, command } = props;
|
|
28
|
-
const { exit } = useApp();
|
|
29
26
|
const [view, setView] = useState('ask');
|
|
30
27
|
const [sending, setSending] = useState(false);
|
|
31
28
|
const [response, setResponse] = useState('');
|
|
32
|
-
const [
|
|
29
|
+
const [meta, setMeta] = useState();
|
|
30
|
+
const [_, setExit] = useExit();
|
|
33
31
|
const [isFirstRun, setIsFirstRun] = useState(false);
|
|
34
32
|
useEffect(() => {
|
|
35
33
|
void (async () => {
|
|
36
|
-
if (config.
|
|
37
|
-
|
|
34
|
+
if (config.isFirstExecution) {
|
|
35
|
+
setView('welcome');
|
|
36
|
+
setIsFirstRun(true);
|
|
37
|
+
}
|
|
38
|
+
else if (!config.model) {
|
|
39
|
+
setView('select-model');
|
|
38
40
|
}
|
|
39
41
|
else {
|
|
40
|
-
|
|
42
|
+
await send(config);
|
|
41
43
|
}
|
|
42
44
|
})();
|
|
43
45
|
}, []);
|
|
44
46
|
useEffect(() => {
|
|
45
|
-
|
|
46
|
-
setTimeout(() => exit(), 0);
|
|
47
|
-
}
|
|
48
|
-
}, [exitCode]);
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
(async () => {
|
|
51
|
-
const dirPath = path.join(root, '/data/chats');
|
|
52
|
-
const fileNames = await fs.readdir(dirPath);
|
|
53
|
-
const files = await Promise.all(fileNames.map(async (name) => {
|
|
54
|
-
const filePath = path.join(dirPath, name);
|
|
55
|
-
const stats = await fs.stat(filePath);
|
|
56
|
-
return { path: filePath, time: stats.ctimeMs };
|
|
57
|
-
}));
|
|
58
|
-
const sortedFiles = files
|
|
59
|
-
.sort((a, b) => b.time - a.time)
|
|
60
|
-
.slice(10);
|
|
61
|
-
await Promise.all(sortedFiles.map(file => fs.unlink(file.path)));
|
|
62
|
-
})().catch(() => { });
|
|
47
|
+
void historyStore.deleteOldHistory();
|
|
63
48
|
}, []);
|
|
64
49
|
async function handleSend() {
|
|
65
|
-
setIsFirstRun(true);
|
|
66
50
|
setView('ask');
|
|
67
51
|
const config = await configStore.get();
|
|
52
|
+
config.isFirstExecution = false;
|
|
53
|
+
await configStore.save(config);
|
|
68
54
|
await send(config);
|
|
69
55
|
}
|
|
70
56
|
async function send(config) {
|
|
71
|
-
const modelId = config.model.
|
|
72
|
-
const providerId = config.model.
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
57
|
+
const modelId = config.model.id;
|
|
58
|
+
const providerId = config.model.providerId;
|
|
59
|
+
const provider = config.providers[providerId];
|
|
60
|
+
const model = provider?.models.find(model => model.id === modelId);
|
|
61
|
+
if (!model) {
|
|
62
|
+
console.error(`Error: model ${chalk.bold(modelId)} not found`);
|
|
63
|
+
setExit(true);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (provider.type !== 'openai-compatible' && !provider.key) {
|
|
67
|
+
console.error(`No API key found for the model ${chalk.bold(`(${provider.name}) ${model.name}`)}.\n`);
|
|
78
68
|
console.error(`Use the command ${chalk.cyan(chalk.bold('ask /providers'))} to set the API key for the provider ${chalk.bold(provider.name)}.`);
|
|
79
|
-
|
|
69
|
+
setExit(true);
|
|
80
70
|
return;
|
|
81
71
|
}
|
|
82
72
|
try {
|
|
83
73
|
setSending(true);
|
|
84
74
|
const prompt = await getPrompt();
|
|
85
|
-
const
|
|
86
|
-
const
|
|
75
|
+
const modelClient = getModel(provider, model);
|
|
76
|
+
const startTime = Date.now();
|
|
77
|
+
const response = await modelClient.invoke([
|
|
87
78
|
{ role: 'system', content: instructions },
|
|
88
79
|
...history.map(item => ({ ...item })),
|
|
89
80
|
{ role: 'human', content: prompt }
|
|
90
81
|
]);
|
|
82
|
+
const endTime = Date.now();
|
|
91
83
|
await historyStore.add([
|
|
92
84
|
{ role: 'human', content: prompt },
|
|
93
85
|
{ role: 'ai', content: response.text }
|
|
94
86
|
]);
|
|
95
87
|
setResponse(response.text.replaceAll('\\x1b', '\x1b').replaceAll('\\n', '\n').concat('\x1b[0m'));
|
|
88
|
+
setMeta({
|
|
89
|
+
model: model.name,
|
|
90
|
+
time: endTime - startTime,
|
|
91
|
+
tokens: (response.usage_metadata?.input_tokens || 0) + (response.usage_metadata?.output_tokens || 0)
|
|
92
|
+
});
|
|
96
93
|
setSending(false);
|
|
97
|
-
|
|
94
|
+
setExit(true);
|
|
98
95
|
}
|
|
99
96
|
catch (err) {
|
|
100
|
-
console.error(`Error running model ${chalk.bold(
|
|
97
|
+
console.error(`Error running model ${chalk.bold(`(${provider.name}) ${model.name}`)}:\n\n${err.message}`);
|
|
101
98
|
setSending(false);
|
|
102
|
-
|
|
99
|
+
setExit(true);
|
|
103
100
|
}
|
|
104
101
|
}
|
|
105
102
|
async function getPrompt() {
|
|
@@ -110,14 +107,39 @@ function Ask(props) {
|
|
|
110
107
|
}
|
|
111
108
|
return result;
|
|
112
109
|
}
|
|
113
|
-
function getModel(
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
110
|
+
function getModel(provider, model) {
|
|
111
|
+
const maxOutputTokens = config.settings.maxOutputTokens.value;
|
|
112
|
+
switch (provider.type) {
|
|
113
|
+
case 'openai':
|
|
114
|
+
return new ChatOpenAI({
|
|
115
|
+
model: model.id,
|
|
116
|
+
apiKey: provider.key,
|
|
117
|
+
maxTokens: maxOutputTokens,
|
|
118
|
+
...model?.config
|
|
119
|
+
});
|
|
120
|
+
case 'gemini':
|
|
121
|
+
return new ChatGoogleGenerativeAI({
|
|
122
|
+
model: model.id,
|
|
123
|
+
apiKey: provider.key,
|
|
124
|
+
maxOutputTokens,
|
|
125
|
+
...model?.config
|
|
126
|
+
});
|
|
127
|
+
case 'anthropic':
|
|
128
|
+
return new ChatAnthropic({
|
|
129
|
+
model: model.id,
|
|
130
|
+
apiKey: provider.key,
|
|
131
|
+
maxTokens: maxOutputTokens,
|
|
132
|
+
...model?.config
|
|
133
|
+
});
|
|
134
|
+
case 'openai-compatible':
|
|
135
|
+
return new ChatOpenAI({
|
|
136
|
+
model: model.id,
|
|
137
|
+
apiKey: provider.key,
|
|
138
|
+
configuration: { baseURL: provider.url },
|
|
139
|
+
maxTokens: maxOutputTokens
|
|
140
|
+
});
|
|
141
|
+
default:
|
|
142
|
+
throw new Error('Model not found');
|
|
121
143
|
}
|
|
122
144
|
}
|
|
123
145
|
async function runCommand(command) {
|
|
@@ -128,14 +150,21 @@ function Ask(props) {
|
|
|
128
150
|
}
|
|
129
151
|
catch (err) {
|
|
130
152
|
const { stdout, stderr } = err;
|
|
131
|
-
return `Error executing command
|
|
153
|
+
return `Error executing command:\n\n${stdout}\n\n${stderr}`;
|
|
132
154
|
}
|
|
133
155
|
}
|
|
156
|
+
function formatTime(time) {
|
|
157
|
+
return time < 1000 * 60
|
|
158
|
+
? `${(time / 1000).toFixed(1)}s`
|
|
159
|
+
: `${(time / (1000 * 60)).toFixed(1)}m`;
|
|
160
|
+
}
|
|
134
161
|
return (_jsxs(Box, { children: [view === 'welcome' &&
|
|
135
|
-
_jsx(Welcome, { onSend: handleSend }), view === '
|
|
162
|
+
_jsx(Welcome, { onSend: handleSend }), view === 'select-model' &&
|
|
163
|
+
_jsx(SelectModel, { onSelect: handleSend }), view === 'ask' &&
|
|
136
164
|
_jsxs(Box, { children: [isFirstRun &&
|
|
137
165
|
_jsx(Static, { items: [''], children: item => _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: [_jsx(Text, { color: 'cyan', bold: true, children: "Prompt:" }), " ", prompt] }) }, item) }), sending &&
|
|
138
166
|
_jsx(Loading, {}), !sending && response &&
|
|
139
|
-
_jsx(Static, { items: [''], children: item => _jsx(Text, { children: response },
|
|
167
|
+
_jsx(Static, { items: [''], children: item => _jsxs(Box, { flexDirection: 'column', children: [_jsx(Text, { children: response }), config.settings.metadata.value && meta &&
|
|
168
|
+
_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: 'gray', dimColor: true, children: ["Model: ", meta.model, ", Time: ", formatTime(meta.time), ", Tokens: ", meta.tokens] }) })] }, item) })] })] }));
|
|
140
169
|
}
|
|
141
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
170
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2Fzay50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUM3QixPQUFPLFdBQVcsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDNUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEtBQUssQ0FBQztBQUNoRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSwwQkFBMkIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sMEJBQTJCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFJNUQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBK0IsQ0FBQztBQUU1RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBRXBDLE1BQU0sTUFBTSxHQUFHLE1BQU0sV0FBVyxDQUFD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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { historyStore } from "../stores/history.js";
|
|
2
2
|
export async function clearHistory() {
|
|
3
3
|
await historyStore.clear();
|
|
4
|
-
console.log('Conversation history
|
|
4
|
+
console.log('Conversation history deleted.');
|
|
5
5
|
}
|
|
6
6
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xlYXJIaXN0b3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2NsZWFySGlzdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFcEQsTUFBTSxDQUFDLEtBQUssVUFBVSxZQUFZO0lBQ2hDLE1BQU0sWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzNCLE9BQU8sQ0FBQyxHQUFHLENBQUMsK0JBQStCLENBQUMsQ0FBQztBQUMvQyxDQUFDIn0=
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Box, render, Text } from 'ink';
|
|
4
|
+
import { ScrollView } from 'ink-scroll-view';
|
|
5
|
+
import { configStore } from "../stores/config.js";
|
|
6
|
+
import { TextInput } from "../components/textInput.js";
|
|
7
|
+
import { Commands } from "../components/commands.js";
|
|
8
|
+
import { Command } from "../components/command.js";
|
|
9
|
+
import { useExit } from "../hooks/useExit.js";
|
|
10
|
+
const height = process.stdout.rows - 4;
|
|
11
|
+
const initialConfig = await configStore.get();
|
|
12
|
+
const initialSettings = Object.entries(initialConfig.settings).map(([key, setting]) => ({
|
|
13
|
+
key,
|
|
14
|
+
edit: false,
|
|
15
|
+
setting
|
|
16
|
+
}));
|
|
17
|
+
export function config() {
|
|
18
|
+
render(_jsx(Config, {}));
|
|
19
|
+
}
|
|
20
|
+
export function Config() {
|
|
21
|
+
const [currentIndex, setCurrentIndex] = useState(0);
|
|
22
|
+
const [settingItems, setSettingItems] = useState(initialSettings);
|
|
23
|
+
const [saved, setSaved] = useState(false);
|
|
24
|
+
const [exit, setExit] = useExit();
|
|
25
|
+
function handleUp() {
|
|
26
|
+
unselect();
|
|
27
|
+
setCurrentIndex(index => Math.max(0, index - 1));
|
|
28
|
+
}
|
|
29
|
+
function handleDown() {
|
|
30
|
+
unselect();
|
|
31
|
+
setCurrentIndex(index => Math.min(settingItems.length - 1, index + 1));
|
|
32
|
+
}
|
|
33
|
+
function handleEnter() {
|
|
34
|
+
for (const settingItem of settingItems) {
|
|
35
|
+
settingItem.edit = false;
|
|
36
|
+
}
|
|
37
|
+
const settingItem = settingItems[currentIndex];
|
|
38
|
+
settingItem.edit = true;
|
|
39
|
+
if (settingItem.setting.type === 'boolean') {
|
|
40
|
+
settingItem.setting.value = !settingItem.setting.value;
|
|
41
|
+
}
|
|
42
|
+
setSettingItems([...settingItems]);
|
|
43
|
+
}
|
|
44
|
+
function handleInputChange(key, value) {
|
|
45
|
+
const setting = settingItems.find(setting => setting.key === key).setting;
|
|
46
|
+
if (value === '') {
|
|
47
|
+
setting.value = '';
|
|
48
|
+
}
|
|
49
|
+
else if (!isNaN(parseInt(value)) && parseInt(value) < setting.max) {
|
|
50
|
+
setting.value = parseInt(value);
|
|
51
|
+
}
|
|
52
|
+
setSettingItems([...settingItems]);
|
|
53
|
+
}
|
|
54
|
+
async function handleSave() {
|
|
55
|
+
const config = await configStore.get();
|
|
56
|
+
config.settings = settingItems.reduce((obj, item) => ({
|
|
57
|
+
...obj,
|
|
58
|
+
[item.key]: item.setting
|
|
59
|
+
}), {});
|
|
60
|
+
await configStore.save(config);
|
|
61
|
+
setSaved(true);
|
|
62
|
+
setTimeout(() => setSaved(false), 500);
|
|
63
|
+
}
|
|
64
|
+
function handleExit() {
|
|
65
|
+
setExit(true);
|
|
66
|
+
}
|
|
67
|
+
function unselect() {
|
|
68
|
+
for (const item of settingItems) {
|
|
69
|
+
item.edit = false;
|
|
70
|
+
if (item.setting.type === 'number') {
|
|
71
|
+
if (!item.setting.value || (typeof item.setting.value === 'number' && item.setting.value < item.setting.min)) {
|
|
72
|
+
item.setting.value = item.setting.min;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
setSettingItems([...settingItems]);
|
|
77
|
+
}
|
|
78
|
+
if (exit)
|
|
79
|
+
return null;
|
|
80
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: 'whiteBright', bold: true, children: "Configuration" }), _jsx(Box, { height: settingItems.length > height ? height : undefined, borderStyle: 'single', borderColor: 'cyan', borderTop: false, borderRight: false, borderBottom: false, marginTop: 1, paddingLeft: 1, children: _jsx(ScrollView, { children: settingItems.map((item, index) => (_jsxs(Box, { width: 80, gap: 1, backgroundColor: index === currentIndex ? 'black' : undefined, children: [_jsx(Box, { minWidth: 20, children: _jsxs(Text, { children: [item.setting.title, ":"] }) }), _jsxs(Box, { minWidth: 6, children: [item.setting.type === 'boolean' &&
|
|
81
|
+
_jsx(Text, { color: 'cyan', inverse: item.edit, children: item.setting.value ? 'true' : 'false' }), item.setting.type === 'number' &&
|
|
82
|
+
_jsxs(Box, { children: [item.edit &&
|
|
83
|
+
_jsx(Text, { inverse: true, color: 'cyan', children: _jsx(TextInput, { value: item.setting.value.toString(), onChange: value => handleInputChange(item.key, value) }) }), !item.edit &&
|
|
84
|
+
_jsx(Text, { color: 'cyan', inverse: item.edit, children: item.setting.value })] })] }), _jsx(Box, { children: _jsx(Text, { color: 'gray', dimColor: index !== currentIndex, children: item.setting.description }) })] }, item.key))) }) }), _jsxs(Box, { flexDirection: 'row', gap: 1, children: [_jsxs(Commands, { children: [_jsx(Command, { title: 'Esc (Exit)', esc: true, onPress: handleExit }), _jsx(Command, { title: 'Enter (Select)', enter: true, onPress: handleEnter }), _jsx(Command, { title: 'Ctrl+S (Save)', ctrl: true, inputKey: 's', onPress: handleSave }), _jsx(Command, { up: true, onPress: handleUp }), _jsx(Command, { down: true, onPress: handleDown })] }), saved &&
|
|
85
|
+
_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: 'cyan', bold: true, children: "Saved!" }) })] })] }));
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2NvbmZpZy50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDakMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM3QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDRCQUE2QixDQUFDO0FBQ3hELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSwyQkFBNEIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sMEJBQTJCLENBQUM7QUFFcEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRTlDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQztBQUN2QyxNQUFNLGFBQWEsR0FBRyxNQUFNLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUU5QyxNQUFNLGVBQWUsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN0RixHQUFHO0lBQ0gsSUFBSSxFQUFFLEtBQUs7SUFDWCxPQUFPO0NBQ1IsQ0FBQyxDQUFDLENBQUM7QUFFSixNQUFNLFVBQVUsTUFBTTtJQUNwQixNQUFNLENBQUMsS0FBQyxNQUFNLEtBQUcsQ0FBQyxDQUFDO0FBQ3JCLENBQUM7QUFFRCxNQUFNLFVBQVUsTUFBTTtJQUVwQixNQUFNLENBQUMsWUFBWSxFQUFFLGVBQWUsQ0FB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
|