how-cli 0.1.0__tar.gz
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.
- how_cli-0.1.0/LICENSE +21 -0
- how_cli-0.1.0/MANIFEST.in +2 -0
- how_cli-0.1.0/PKG-INFO +103 -0
- how_cli-0.1.0/README.md +87 -0
- how_cli-0.1.0/how/__init__.py +1 -0
- how_cli-0.1.0/how/__main__.py +4 -0
- how_cli-0.1.0/how/core/__init__.py +6 -0
- how_cli-0.1.0/how/core/chains.py +4 -0
- how_cli-0.1.0/how/core/config.py +50 -0
- how_cli-0.1.0/how/core/llm.py +9 -0
- how_cli-0.1.0/how/core/parser.py +4 -0
- how_cli-0.1.0/how/core/prompts.py +50 -0
- how_cli-0.1.0/how/core/providers.py +8 -0
- how_cli-0.1.0/how/core/schema.py +6 -0
- how_cli-0.1.0/how/core/template.py +19 -0
- how_cli-0.1.0/how/formatting.py +36 -0
- how_cli-0.1.0/how/how.py +82 -0
- how_cli-0.1.0/how/infer.py +28 -0
- how_cli-0.1.0/how_cli.egg-info/PKG-INFO +103 -0
- how_cli-0.1.0/how_cli.egg-info/SOURCES.txt +25 -0
- how_cli-0.1.0/how_cli.egg-info/dependency_links.txt +1 -0
- how_cli-0.1.0/how_cli.egg-info/entry_points.txt +2 -0
- how_cli-0.1.0/how_cli.egg-info/requires.txt +3 -0
- how_cli-0.1.0/how_cli.egg-info/top_level.txt +1 -0
- how_cli-0.1.0/requirements.txt +3 -0
- how_cli-0.1.0/setup.cfg +4 -0
- how_cli-0.1.0/setup.py +31 -0
how_cli-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Rudransh Joshi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
how_cli-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: how-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: An AI-based CLI assistant to help you with command line & shell.
|
|
5
|
+
Home-page: https://github.com/FireHead90544/how-cli
|
|
6
|
+
Author: Rudransh Joshi (FireHead90544)
|
|
7
|
+
Author-email: rudranshjoshi1806@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Issue Tracker, https://github.com/FireHead90544/how-cli/issues
|
|
10
|
+
Platform: any
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: typer
|
|
14
|
+
Requires-Dist: langchain
|
|
15
|
+
Requires-Dist: langchain-google-genai
|
|
16
|
+
|
|
17
|
+
# how-cli
|
|
18
|
+
An AI-based CLI assistant to help you with command line & shell.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Demo
|
|
22
|
+
Would be adding install instructions and better demo soon, until then check this out.
|
|
23
|
+
### Setup
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
### Inferences
|
|
27
|
+

|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
**1. Using `pip`**
|
|
33
|
+
- Ensure python is installed on your system. (Tested against Python 3.11+)
|
|
34
|
+
- Install the package using pip.
|
|
35
|
+
```bash
|
|
36
|
+
pip install -U how-cli
|
|
37
|
+
```
|
|
38
|
+
**2. Manual Installation**
|
|
39
|
+
- Clone the repository & cd into it
|
|
40
|
+
```bash
|
|
41
|
+
git clone https://github.com/FireHead90544/how-cli && cd how-cli
|
|
42
|
+
```
|
|
43
|
+
- Ensure you're in a virtual environment.
|
|
44
|
+
- Install the application.
|
|
45
|
+
```bash
|
|
46
|
+
pip install -e .
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## Usage
|
|
51
|
+
```console
|
|
52
|
+
$ how [OPTIONS] COMMAND [ARGS]...
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Options**:
|
|
56
|
+
* `-v, --version`: Shows the version of the application
|
|
57
|
+
* `--install-completion`: Install completion for the current shell.
|
|
58
|
+
* `--show-completion`: Show completion for the current shell, to copy it or customize the installation.
|
|
59
|
+
* `--help`: Show this message and exit.
|
|
60
|
+
|
|
61
|
+
**Commands**:
|
|
62
|
+
* `setup`: Sets up the configuration required to run...
|
|
63
|
+
* `to`: Sends the task to the LLM for analysis.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## `how setup`
|
|
67
|
+
Sets up the configuration required to run the application.
|
|
68
|
+
Set the LLM Provider & the corresponding API Key.
|
|
69
|
+
|
|
70
|
+
**Usage**:
|
|
71
|
+
```console
|
|
72
|
+
$ how setup [OPTIONS]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Options**:
|
|
76
|
+
* `--interactive / --no-interactive`: Whether to use interactive mode for setting up configuration? [default: interactive]
|
|
77
|
+
* `--provider TEXT`: The LLM Provider, needs to be passed explicitly if using --no-interactive mode.
|
|
78
|
+
* `--api-key TEXT`: The API Key for the LLM provider, needs to be passed explicitly if using --no-interactive mode.
|
|
79
|
+
* `--help`: Show this message and exit.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## `how to`
|
|
83
|
+
Sends the task to the LLM for analysis.
|
|
84
|
+
Returns the commands to be executed in order to achieve that.
|
|
85
|
+
|
|
86
|
+
**Usage**:
|
|
87
|
+
```console
|
|
88
|
+
$ how to [OPTIONS] TASK
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Arguments**:
|
|
92
|
+
* `TASK`: The command line task to perform. [required]
|
|
93
|
+
|
|
94
|
+
**Options**:
|
|
95
|
+
* `--help`: Show this message and exit.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## Providers
|
|
99
|
+
`how-cli` uses ChatModels as they support chat messages as opposed to TextModels and below model providers and their corresponding models are available to use.
|
|
100
|
+
|
|
101
|
+
| Provider | Model | Package |
|
|
102
|
+
|:--------:|:-----:|:-------:|
|
|
103
|
+
| Google | `gemini-1.5-flash` | `langchain-google-genai` |
|
how_cli-0.1.0/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# how-cli
|
|
2
|
+
An AI-based CLI assistant to help you with command line & shell.
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
## Demo
|
|
6
|
+
Would be adding install instructions and better demo soon, until then check this out.
|
|
7
|
+
### Setup
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
### Inferences
|
|
11
|
+

|
|
12
|
+

|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
**1. Using `pip`**
|
|
17
|
+
- Ensure python is installed on your system. (Tested against Python 3.11+)
|
|
18
|
+
- Install the package using pip.
|
|
19
|
+
```bash
|
|
20
|
+
pip install -U how-cli
|
|
21
|
+
```
|
|
22
|
+
**2. Manual Installation**
|
|
23
|
+
- Clone the repository & cd into it
|
|
24
|
+
```bash
|
|
25
|
+
git clone https://github.com/FireHead90544/how-cli && cd how-cli
|
|
26
|
+
```
|
|
27
|
+
- Ensure you're in a virtual environment.
|
|
28
|
+
- Install the application.
|
|
29
|
+
```bash
|
|
30
|
+
pip install -e .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
```console
|
|
36
|
+
$ how [OPTIONS] COMMAND [ARGS]...
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Options**:
|
|
40
|
+
* `-v, --version`: Shows the version of the application
|
|
41
|
+
* `--install-completion`: Install completion for the current shell.
|
|
42
|
+
* `--show-completion`: Show completion for the current shell, to copy it or customize the installation.
|
|
43
|
+
* `--help`: Show this message and exit.
|
|
44
|
+
|
|
45
|
+
**Commands**:
|
|
46
|
+
* `setup`: Sets up the configuration required to run...
|
|
47
|
+
* `to`: Sends the task to the LLM for analysis.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## `how setup`
|
|
51
|
+
Sets up the configuration required to run the application.
|
|
52
|
+
Set the LLM Provider & the corresponding API Key.
|
|
53
|
+
|
|
54
|
+
**Usage**:
|
|
55
|
+
```console
|
|
56
|
+
$ how setup [OPTIONS]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Options**:
|
|
60
|
+
* `--interactive / --no-interactive`: Whether to use interactive mode for setting up configuration? [default: interactive]
|
|
61
|
+
* `--provider TEXT`: The LLM Provider, needs to be passed explicitly if using --no-interactive mode.
|
|
62
|
+
* `--api-key TEXT`: The API Key for the LLM provider, needs to be passed explicitly if using --no-interactive mode.
|
|
63
|
+
* `--help`: Show this message and exit.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## `how to`
|
|
67
|
+
Sends the task to the LLM for analysis.
|
|
68
|
+
Returns the commands to be executed in order to achieve that.
|
|
69
|
+
|
|
70
|
+
**Usage**:
|
|
71
|
+
```console
|
|
72
|
+
$ how to [OPTIONS] TASK
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Arguments**:
|
|
76
|
+
* `TASK`: The command line task to perform. [required]
|
|
77
|
+
|
|
78
|
+
**Options**:
|
|
79
|
+
* `--help`: Show this message and exit.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## Providers
|
|
83
|
+
`how-cli` uses ChatModels as they support chat messages as opposed to TextModels and below model providers and their corresponding models are available to use.
|
|
84
|
+
|
|
85
|
+
| Provider | Model | Package |
|
|
86
|
+
|:--------:|:-----:|:-------:|
|
|
87
|
+
| Google | `gemini-1.5-flash` | `langchain-google-genai` |
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from how.core import __version__, __author__
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
class Config:
|
|
5
|
+
"""
|
|
6
|
+
Manages the configuration of the application.
|
|
7
|
+
Config file is stored in the user's home directory.
|
|
8
|
+
"""
|
|
9
|
+
def __init__(self):
|
|
10
|
+
self.config_dir = Path.home() / ".how"
|
|
11
|
+
self.config_file = self.config_dir / "config.json"
|
|
12
|
+
self.__init_config()
|
|
13
|
+
|
|
14
|
+
def __init_config(self):
|
|
15
|
+
"""
|
|
16
|
+
Initialize the configuration directory & file if they don't exist.
|
|
17
|
+
"""
|
|
18
|
+
if not self.config_dir.exists():
|
|
19
|
+
self.config_dir.mkdir()
|
|
20
|
+
|
|
21
|
+
if not self.config_file.exists():
|
|
22
|
+
with open(self.config_file, "w") as f:
|
|
23
|
+
json.dump({"provider": "", "api_key": ""}, f, indent=4)
|
|
24
|
+
|
|
25
|
+
def setup(self, provider: str, api_key: str):
|
|
26
|
+
"""
|
|
27
|
+
Set the LLM Provider & the corresponding API Key.
|
|
28
|
+
"""
|
|
29
|
+
with open(self.config_file, "w") as f:
|
|
30
|
+
json.dump({"provider": provider, "api_key": api_key}, f, indent=4)
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def values(self):
|
|
34
|
+
"""
|
|
35
|
+
Get the configuration values.
|
|
36
|
+
"""
|
|
37
|
+
with open(self.config_file) as f:
|
|
38
|
+
return json.load(f)
|
|
39
|
+
|
|
40
|
+
def is_ready(self):
|
|
41
|
+
"""
|
|
42
|
+
Check if the configuration file is ready to use.
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
assert self.values.get("provider")
|
|
46
|
+
assert self.values.get("api_key")
|
|
47
|
+
except:
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
return True
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from how.core.config import Config
|
|
2
|
+
from how.core.providers import LLM_PROVIDERS
|
|
3
|
+
|
|
4
|
+
llm_config = Config().values
|
|
5
|
+
|
|
6
|
+
LLM = LLM_PROVIDERS.get(llm_config.get("provider"))['provider'](
|
|
7
|
+
model = LLM_PROVIDERS.get(llm_config.get("provider"))['model'],
|
|
8
|
+
api_key = llm_config.get("api_key")
|
|
9
|
+
)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import platform
|
|
3
|
+
|
|
4
|
+
SYSTEM_PROMPT = f"""You're a command line assistant, your goal is to help users by giving them a series of cli commands to run to achieve a certain task.
|
|
5
|
+
You should only provide the series of commands to run and not the explanation of what each command does and they should be specific to system's user first, unless asked explicitly for another system.
|
|
6
|
+
If you can't provide the commands, DO NOT TRY TO MAKE UP the commands, instead, set a lower confidence score and return the status.
|
|
7
|
+
|
|
8
|
+
System Info: {platform.system()} {platform.release()}
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
FEW_SHOT_EXAMPLES = [
|
|
12
|
+
{
|
|
13
|
+
"task": "search for a string in a file",
|
|
14
|
+
"output": json.dumps(
|
|
15
|
+
{
|
|
16
|
+
"status": "success",
|
|
17
|
+
"commands": ["cat <filename> | grep <string>"],
|
|
18
|
+
"confidence": 1.0,
|
|
19
|
+
}
|
|
20
|
+
),
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"task": "create a new branch and push that to remote",
|
|
24
|
+
"output": json.dumps(
|
|
25
|
+
{
|
|
26
|
+
"status": "success",
|
|
27
|
+
"commands": [
|
|
28
|
+
"git checkout -b <brach_name>",
|
|
29
|
+
"git push origin <branch_name>",
|
|
30
|
+
],
|
|
31
|
+
"confidence": 1.0,
|
|
32
|
+
}
|
|
33
|
+
),
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"task": "use someone else's dotfiles",
|
|
37
|
+
"output": json.dumps(
|
|
38
|
+
{
|
|
39
|
+
"status": "success",
|
|
40
|
+
"commands": [
|
|
41
|
+
"git clone <repo_url>",
|
|
42
|
+
"cd <repo_name>",
|
|
43
|
+
"cp .* ~",
|
|
44
|
+
"source ~/.*",
|
|
45
|
+
],
|
|
46
|
+
"confidence": 0.87,
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
}
|
|
50
|
+
]
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from langchain_core.pydantic_v1 import BaseModel, Field
|
|
2
|
+
|
|
3
|
+
class Result(BaseModel):
|
|
4
|
+
commands: list[str] = Field(description="Commands to run in sequential order")
|
|
5
|
+
confidence: float = Field(description="Value between 0-1 (with precision of two decimal places) representing a confidence score about the success rate, not leading to any errors or interventions.")
|
|
6
|
+
status: str = Field(description="Status of the response (can be 'success' or anything else in case of error)")
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from how.core.prompts import SYSTEM_PROMPT, FEW_SHOT_EXAMPLES
|
|
2
|
+
from how.core.parser import PARSER
|
|
3
|
+
from langchain_core.prompts import ChatPromptTemplate, FewShotChatMessagePromptTemplate
|
|
4
|
+
|
|
5
|
+
example_template = ChatPromptTemplate.from_messages([
|
|
6
|
+
("human", "How to {task}?"),
|
|
7
|
+
("ai", "{output}")
|
|
8
|
+
])
|
|
9
|
+
|
|
10
|
+
few_shot_examples_template = FewShotChatMessagePromptTemplate(
|
|
11
|
+
example_prompt=example_template,
|
|
12
|
+
examples=FEW_SHOT_EXAMPLES
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
PROMPT_TEMPLATE = ChatPromptTemplate.from_messages([
|
|
16
|
+
("system", SYSTEM_PROMPT + "\n{format_instructions}"),
|
|
17
|
+
few_shot_examples_template,
|
|
18
|
+
("human", "How to {task}?")
|
|
19
|
+
]).partial(format_instructions=PARSER.get_format_instructions())
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from rich.console import Console
|
|
2
|
+
from rich.panel import Panel
|
|
3
|
+
from rich.text import Text
|
|
4
|
+
from rich.table import Table
|
|
5
|
+
from rich import box
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def display_result(task: str, result: dict):
|
|
9
|
+
console = Console()
|
|
10
|
+
|
|
11
|
+
task_panel = Panel(
|
|
12
|
+
Text(task, style="bold magenta"),
|
|
13
|
+
title="Task",
|
|
14
|
+
border_style="cyan",
|
|
15
|
+
expand=False,
|
|
16
|
+
)
|
|
17
|
+
console.print(task_panel)
|
|
18
|
+
|
|
19
|
+
if result["status"] != "success":
|
|
20
|
+
console.print(f"Status: [bold red]{result['status']}[/bold red]")
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
command_table = Table(box=box.ROUNDED, expand=True, show_header=False)
|
|
24
|
+
command_table.add_column("Commands", style="green")
|
|
25
|
+
for command in result["commands"]:
|
|
26
|
+
command_table.add_row(command)
|
|
27
|
+
|
|
28
|
+
confidence_panel = Panel(
|
|
29
|
+
f"{result['confidence']:.2%}",
|
|
30
|
+
title="Confidence Score",
|
|
31
|
+
border_style="yellow",
|
|
32
|
+
expand=False,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
console.print(Panel(command_table, title="Commands", border_style="green"))
|
|
36
|
+
console.print(confidence_panel)
|
how_cli-0.1.0/how/how.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from typing_extensions import Annotated
|
|
3
|
+
from rich.prompt import Prompt
|
|
4
|
+
from how.core.config import Config
|
|
5
|
+
from how.formatting import display_result
|
|
6
|
+
from how import __version__
|
|
7
|
+
|
|
8
|
+
app = typer.Typer(
|
|
9
|
+
name="how",
|
|
10
|
+
help="An AI-based CLI assistant to help you with command line & shell.",
|
|
11
|
+
)
|
|
12
|
+
config = Config()
|
|
13
|
+
|
|
14
|
+
def get_version(value: bool):
|
|
15
|
+
"""
|
|
16
|
+
Callback to get the version of the application.
|
|
17
|
+
"""
|
|
18
|
+
if value:
|
|
19
|
+
typer.echo(f"v{__version__}")
|
|
20
|
+
raise typer.Exit()
|
|
21
|
+
|
|
22
|
+
@app.callback()
|
|
23
|
+
def show_version(
|
|
24
|
+
version: bool = typer.Option(False, "--version", "-v", help="Shows the version of the application", callback=get_version)
|
|
25
|
+
):
|
|
26
|
+
"""
|
|
27
|
+
Shows the version of the application.
|
|
28
|
+
"""
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@app.command()
|
|
33
|
+
def to(
|
|
34
|
+
task: Annotated[str, typer.Argument(help="The command line task to perform.")]
|
|
35
|
+
):
|
|
36
|
+
"""
|
|
37
|
+
Sends the task to the LLM for analysis.
|
|
38
|
+
Returns the commands to be executed in order to achieve that.
|
|
39
|
+
"""
|
|
40
|
+
if not config.is_ready():
|
|
41
|
+
typer.secho("Please setup the configuration first using `how setup`", fg="red", bold=True)
|
|
42
|
+
raise typer.Abort()
|
|
43
|
+
|
|
44
|
+
from how.infer import get_result
|
|
45
|
+
result = get_result(task)
|
|
46
|
+
display_result(task, result)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@app.command()
|
|
50
|
+
def setup(
|
|
51
|
+
interactive: Annotated[bool, typer.Option(help="Whether to use interactive mode for setting up configuration?")] = True,
|
|
52
|
+
provider: Annotated[str, typer.Option(help="The LLM Provider, needs to be passed explicitly if using --no-interactive mode.")] = "",
|
|
53
|
+
api_key: Annotated[str, typer.Option(help="The API Key for the LLM provider, needs to be passed explicitly if using --no-interactive mode.")] = ""
|
|
54
|
+
):
|
|
55
|
+
"""
|
|
56
|
+
Sets up the configuration required to run the application.
|
|
57
|
+
Set the LLM Provider & the corresponding API Key.
|
|
58
|
+
"""
|
|
59
|
+
from how.core.providers import LLM_PROVIDERS
|
|
60
|
+
|
|
61
|
+
if not interactive:
|
|
62
|
+
if not provider or not api_key:
|
|
63
|
+
typer.secho("Please set the --provider and --api-key", fg="red", bold=True)
|
|
64
|
+
raise typer.Abort()
|
|
65
|
+
if provider not in LLM_PROVIDERS.keys():
|
|
66
|
+
typer.secho("LLM Provider not available yet. Please select from the available options.", fg="red", bold=True)
|
|
67
|
+
raise typer.Abort()
|
|
68
|
+
else:
|
|
69
|
+
provider = Prompt.ask("Select the LLM Provider", choices=list(LLM_PROVIDERS.keys()))
|
|
70
|
+
api_key = Prompt.ask(f"Enter {provider} API Key", password=True)
|
|
71
|
+
|
|
72
|
+
typer.confirm("Do you want to save the configuration?", abort=True)
|
|
73
|
+
|
|
74
|
+
# Test the API Key & Save the configuration only if it works
|
|
75
|
+
try:
|
|
76
|
+
llm = LLM_PROVIDERS.get(provider)["provider"](model=LLM_PROVIDERS.get(provider)['model'], api_key=api_key)
|
|
77
|
+
llm.invoke("Hi!")
|
|
78
|
+
except:
|
|
79
|
+
typer.secho("Invalid API Key for the given provider. Please try again.", fg="red", bold=True)
|
|
80
|
+
raise typer.Abort()
|
|
81
|
+
|
|
82
|
+
config.setup(provider, api_key)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from how.core.chains import HOW_CLI_CHAIN
|
|
3
|
+
from how.core.parser import PARSER
|
|
4
|
+
|
|
5
|
+
def get_result(task: str) -> dict[str, str | list | float]:
|
|
6
|
+
"""Invokes the chain with the given task and returns the result.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
task (str): The task to perform.
|
|
10
|
+
|
|
11
|
+
Returns:
|
|
12
|
+
dict: The result of the chain.
|
|
13
|
+
"""
|
|
14
|
+
tries = 3
|
|
15
|
+
parsed = {"status": "error", "commands": [], "confidence": 0.0}
|
|
16
|
+
|
|
17
|
+
while tries > 0:
|
|
18
|
+
with warnings.catch_warnings():
|
|
19
|
+
warnings.simplefilter("ignore")
|
|
20
|
+
res = HOW_CLI_CHAIN.invoke({ "task": task })
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
parsed = PARSER.invoke(res)
|
|
24
|
+
break
|
|
25
|
+
except Exception as e:
|
|
26
|
+
tries -= 1
|
|
27
|
+
|
|
28
|
+
return parsed
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: how-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: An AI-based CLI assistant to help you with command line & shell.
|
|
5
|
+
Home-page: https://github.com/FireHead90544/how-cli
|
|
6
|
+
Author: Rudransh Joshi (FireHead90544)
|
|
7
|
+
Author-email: rudranshjoshi1806@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Issue Tracker, https://github.com/FireHead90544/how-cli/issues
|
|
10
|
+
Platform: any
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: typer
|
|
14
|
+
Requires-Dist: langchain
|
|
15
|
+
Requires-Dist: langchain-google-genai
|
|
16
|
+
|
|
17
|
+
# how-cli
|
|
18
|
+
An AI-based CLI assistant to help you with command line & shell.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## Demo
|
|
22
|
+
Would be adding install instructions and better demo soon, until then check this out.
|
|
23
|
+
### Setup
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
### Inferences
|
|
27
|
+

|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
**1. Using `pip`**
|
|
33
|
+
- Ensure python is installed on your system. (Tested against Python 3.11+)
|
|
34
|
+
- Install the package using pip.
|
|
35
|
+
```bash
|
|
36
|
+
pip install -U how-cli
|
|
37
|
+
```
|
|
38
|
+
**2. Manual Installation**
|
|
39
|
+
- Clone the repository & cd into it
|
|
40
|
+
```bash
|
|
41
|
+
git clone https://github.com/FireHead90544/how-cli && cd how-cli
|
|
42
|
+
```
|
|
43
|
+
- Ensure you're in a virtual environment.
|
|
44
|
+
- Install the application.
|
|
45
|
+
```bash
|
|
46
|
+
pip install -e .
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## Usage
|
|
51
|
+
```console
|
|
52
|
+
$ how [OPTIONS] COMMAND [ARGS]...
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Options**:
|
|
56
|
+
* `-v, --version`: Shows the version of the application
|
|
57
|
+
* `--install-completion`: Install completion for the current shell.
|
|
58
|
+
* `--show-completion`: Show completion for the current shell, to copy it or customize the installation.
|
|
59
|
+
* `--help`: Show this message and exit.
|
|
60
|
+
|
|
61
|
+
**Commands**:
|
|
62
|
+
* `setup`: Sets up the configuration required to run...
|
|
63
|
+
* `to`: Sends the task to the LLM for analysis.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## `how setup`
|
|
67
|
+
Sets up the configuration required to run the application.
|
|
68
|
+
Set the LLM Provider & the corresponding API Key.
|
|
69
|
+
|
|
70
|
+
**Usage**:
|
|
71
|
+
```console
|
|
72
|
+
$ how setup [OPTIONS]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Options**:
|
|
76
|
+
* `--interactive / --no-interactive`: Whether to use interactive mode for setting up configuration? [default: interactive]
|
|
77
|
+
* `--provider TEXT`: The LLM Provider, needs to be passed explicitly if using --no-interactive mode.
|
|
78
|
+
* `--api-key TEXT`: The API Key for the LLM provider, needs to be passed explicitly if using --no-interactive mode.
|
|
79
|
+
* `--help`: Show this message and exit.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## `how to`
|
|
83
|
+
Sends the task to the LLM for analysis.
|
|
84
|
+
Returns the commands to be executed in order to achieve that.
|
|
85
|
+
|
|
86
|
+
**Usage**:
|
|
87
|
+
```console
|
|
88
|
+
$ how to [OPTIONS] TASK
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Arguments**:
|
|
92
|
+
* `TASK`: The command line task to perform. [required]
|
|
93
|
+
|
|
94
|
+
**Options**:
|
|
95
|
+
* `--help`: Show this message and exit.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## Providers
|
|
99
|
+
`how-cli` uses ChatModels as they support chat messages as opposed to TextModels and below model providers and their corresponding models are available to use.
|
|
100
|
+
|
|
101
|
+
| Provider | Model | Package |
|
|
102
|
+
|:--------:|:-----:|:-------:|
|
|
103
|
+
| Google | `gemini-1.5-flash` | `langchain-google-genai` |
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README.md
|
|
4
|
+
requirements.txt
|
|
5
|
+
setup.py
|
|
6
|
+
how/__init__.py
|
|
7
|
+
how/__main__.py
|
|
8
|
+
how/formatting.py
|
|
9
|
+
how/how.py
|
|
10
|
+
how/infer.py
|
|
11
|
+
how/core/__init__.py
|
|
12
|
+
how/core/chains.py
|
|
13
|
+
how/core/config.py
|
|
14
|
+
how/core/llm.py
|
|
15
|
+
how/core/parser.py
|
|
16
|
+
how/core/prompts.py
|
|
17
|
+
how/core/providers.py
|
|
18
|
+
how/core/schema.py
|
|
19
|
+
how/core/template.py
|
|
20
|
+
how_cli.egg-info/PKG-INFO
|
|
21
|
+
how_cli.egg-info/SOURCES.txt
|
|
22
|
+
how_cli.egg-info/dependency_links.txt
|
|
23
|
+
how_cli.egg-info/entry_points.txt
|
|
24
|
+
how_cli.egg-info/requires.txt
|
|
25
|
+
how_cli.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
how
|
how_cli-0.1.0/setup.cfg
ADDED
how_cli-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from how import __version__, __author__
|
|
2
|
+
from setuptools import setup, find_packages
|
|
3
|
+
|
|
4
|
+
with open("README.md", "r") as f:
|
|
5
|
+
readme = f.read()
|
|
6
|
+
|
|
7
|
+
with open("requirements.txt", "r") as f:
|
|
8
|
+
requirements = f.read().strip().splitlines()
|
|
9
|
+
|
|
10
|
+
setup(
|
|
11
|
+
name="how-cli",
|
|
12
|
+
version=__version__,
|
|
13
|
+
description="An AI-based CLI assistant to help you with command line & shell.",
|
|
14
|
+
long_description=readme,
|
|
15
|
+
long_description_content_type="text/markdown",
|
|
16
|
+
url="https://github.com/FireHead90544/how-cli",
|
|
17
|
+
project_urls={
|
|
18
|
+
"Issue Tracker": "https://github.com/FireHead90544/how-cli/issues",
|
|
19
|
+
},
|
|
20
|
+
author=__author__,
|
|
21
|
+
author_email="rudranshjoshi1806@gmail.com",
|
|
22
|
+
platforms="any",
|
|
23
|
+
license="MIT",
|
|
24
|
+
packages=find_packages(),
|
|
25
|
+
install_requires=requirements,
|
|
26
|
+
entry_points={
|
|
27
|
+
"console_scripts": [
|
|
28
|
+
"how=how.how:app",
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
)
|