makima-cli 0.2.1__tar.gz → 1.2.2__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.
- {makima_cli-0.2.1 → makima_cli-1.2.2}/LICENSE +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/PKG-INFO +2 -2
- {makima_cli-0.2.1 → makima_cli-1.2.2}/README.md +1 -1
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/__init__.py +0 -0
- makima_cli-1.2.2/makima/config.py +18 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/core/__init__.py +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/core/agent.py +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/core/config_manager.py +52 -1
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/core/context.py +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/core/memory.py +0 -0
- makima_cli-1.2.2/makima/main.py +14 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/providers/base.py +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/providers/groq_provider.py +17 -2
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/setup.py +2 -1
- makima_cli-1.2.2/makima/test.py +49 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/tools/__init__.py +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/tools/file_tools.py +0 -0
- makima_cli-1.2.2/makima/tools/git_tools.py +72 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima/tools/registry.py +0 -0
- makima_cli-1.2.2/makima/tools/shell_tools.py +13 -0
- makima_cli-1.2.2/makima/ui/__init__.py +0 -0
- makima_cli-1.2.2/makima/ui/app.py +175 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima_cli.egg-info/PKG-INFO +2 -2
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima_cli.egg-info/SOURCES.txt +4 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima_cli.egg-info/dependency_links.txt +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima_cli.egg-info/entry_points.txt +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima_cli.egg-info/requires.txt +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/makima_cli.egg-info/top_level.txt +0 -0
- {makima_cli-0.2.1 → makima_cli-1.2.2}/pyproject.toml +1 -1
- {makima_cli-0.2.1 → makima_cli-1.2.2}/setup.cfg +0 -0
- makima_cli-0.2.1/makima/config.py +0 -20
- makima_cli-0.2.1/makima/main.py +0 -8
- makima_cli-0.2.1/makima/tools/shell_tools.py +0 -20
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: makima-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: AI coding assistant for your terminal
|
|
5
5
|
Author: Kanhaiya
|
|
6
6
|
License: MIT License
|
|
@@ -52,7 +52,7 @@ An AI-powered coding assistant that runs in your terminal. Point it at any codeb
|
|
|
52
52
|
|
|
53
53
|
## Install
|
|
54
54
|
|
|
55
|
-
git clone https://github.com/
|
|
55
|
+
git clone https://github.com/kanhaiya-ML/makima-cli.git
|
|
56
56
|
cd makima-cli
|
|
57
57
|
pip install -r requirements.txt
|
|
58
58
|
|
|
@@ -14,7 +14,7 @@ An AI-powered coding assistant that runs in your terminal. Point it at any codeb
|
|
|
14
14
|
|
|
15
15
|
## Install
|
|
16
16
|
|
|
17
|
-
git clone https://github.com/
|
|
17
|
+
git clone https://github.com/kanhaiya-ML/makima-cli.git
|
|
18
18
|
cd makima-cli
|
|
19
19
|
pip install -r requirements.txt
|
|
20
20
|
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from dotenv import load_dotenv
|
|
7
|
+
load_dotenv()
|
|
8
|
+
|
|
9
|
+
config_file = Path.home() / ".makima" / "config.json"
|
|
10
|
+
config = {}
|
|
11
|
+
if config_file.exists():
|
|
12
|
+
with open(config_file, "r") as f:
|
|
13
|
+
config = json.load(f)
|
|
14
|
+
|
|
15
|
+
GROQ_API_KEY = config.get("groq_api_key") or os.getenv("GROQ_API_KEY")
|
|
16
|
+
MODEL_NAME = config.get("model") or "qwen/qwen3.6-27b"
|
|
17
|
+
TOKEN_LIMIT = 6000
|
|
18
|
+
PROJECT_ROOT = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
|
|
File without changes
|
|
File without changes
|
|
@@ -122,4 +122,55 @@ def handle_config():
|
|
|
122
122
|
if choice == "Change model":
|
|
123
123
|
change_model()
|
|
124
124
|
elif choice == "Change API key":
|
|
125
|
-
change_api_key()
|
|
125
|
+
change_api_key()
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
from makima.tools.git_tools import get_git_diff, generate_commit_message, clean_message
|
|
129
|
+
import subprocess
|
|
130
|
+
import os
|
|
131
|
+
|
|
132
|
+
def commit_only(message):
|
|
133
|
+
message = clean_message(message)
|
|
134
|
+
cmd = f'git add -A && git commit -m "{message}"'
|
|
135
|
+
result = subprocess.run(cmd, shell=True, text=True, capture_output=True)
|
|
136
|
+
if result.returncode == 0:
|
|
137
|
+
return "✓ Committed locally"
|
|
138
|
+
return f"✗ Failed: {result.stderr}"
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def analyze_changes():
|
|
142
|
+
diff = get_git_diff()
|
|
143
|
+
|
|
144
|
+
if not diff.strip():
|
|
145
|
+
return None, None
|
|
146
|
+
message = generate_commit_message(diff)
|
|
147
|
+
return diff, message
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def handle_commit():
|
|
151
|
+
diff = get_git_diff()
|
|
152
|
+
|
|
153
|
+
if not diff.strip():
|
|
154
|
+
console.print("[yellow]No changes to commit.[/]")
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
commit_message = generate_commit_message(diff=diff)
|
|
158
|
+
console.print(f"[white] {commit_message}")
|
|
159
|
+
|
|
160
|
+
# choice = questionary.select(
|
|
161
|
+
# "What action you want?: ",
|
|
162
|
+
# choices = [
|
|
163
|
+
# "commit_and_push",
|
|
164
|
+
# "commit only",
|
|
165
|
+
# "cancle"
|
|
166
|
+
# ]
|
|
167
|
+
# ).ask()
|
|
168
|
+
|
|
169
|
+
# if choice == "commit_and_push":
|
|
170
|
+
# result = commit_and_push(message=commit_message)
|
|
171
|
+
# console.print(f"[green]{result}[/]")
|
|
172
|
+
# elif choice == "commit only":
|
|
173
|
+
# result = commit_only(diff)
|
|
174
|
+
# console.print(f"[green]{result}[/]")
|
|
175
|
+
|
|
176
|
+
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from makima.core.agent import run_agent
|
|
2
|
+
import sys
|
|
3
|
+
from makima.ui.app import run_ui
|
|
4
|
+
from makima.setup import setup_api_key, setup_model
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def main():
|
|
8
|
+
# run_agent()
|
|
9
|
+
setup_model()
|
|
10
|
+
setup_api_key()
|
|
11
|
+
run_ui()
|
|
12
|
+
|
|
13
|
+
if __name__ == "__main__":
|
|
14
|
+
main()
|
|
File without changes
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
from groq import Groq
|
|
2
2
|
from makima.providers.base import LLMProvider
|
|
3
|
-
from makima.config import
|
|
3
|
+
from makima.config import MODEL_NAME
|
|
4
|
+
import os
|
|
5
|
+
import json
|
|
6
|
+
from pathlib import Path
|
|
4
7
|
|
|
5
8
|
class GroqProvider(LLMProvider):
|
|
6
9
|
|
|
7
10
|
def __init__(self):
|
|
8
|
-
|
|
11
|
+
# read fresh from config file
|
|
12
|
+
key = self._load_key()
|
|
13
|
+
self.client = Groq(api_key=key)
|
|
14
|
+
|
|
15
|
+
def _load_key(self):
|
|
16
|
+
config_file = Path.home() / ".makima" / "config.json"
|
|
17
|
+
if config_file.exists():
|
|
18
|
+
with open(config_file, "r") as f:
|
|
19
|
+
data = json.load(f)
|
|
20
|
+
key = data.get("groq_api_key")
|
|
21
|
+
if key:
|
|
22
|
+
return key
|
|
23
|
+
return os.getenv("GROQ_API_KEY")
|
|
9
24
|
|
|
10
25
|
def chat(self, messages: list, tools: list) -> object:
|
|
11
26
|
return self.client.chat.completions.create(
|
|
@@ -28,7 +28,7 @@ def setup_api_key():
|
|
|
28
28
|
with open(config_file, "r") as f:
|
|
29
29
|
data = json.load(f)
|
|
30
30
|
key = data.get("groq_api_key")
|
|
31
|
-
if key:
|
|
31
|
+
if key and validate_key(key):
|
|
32
32
|
return key
|
|
33
33
|
|
|
34
34
|
import os
|
|
@@ -83,6 +83,7 @@ def setup_model():
|
|
|
83
83
|
|
|
84
84
|
existing["model"] = model
|
|
85
85
|
|
|
86
|
+
config_dir.mkdir(exist_ok=True)
|
|
86
87
|
with open(config_file,"w") as f:
|
|
87
88
|
json.dump(existing,f)
|
|
88
89
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from textual.app import App
|
|
2
|
+
from textual.widgets import Header, Footer, Input, RichLog
|
|
3
|
+
from rich.text import Text
|
|
4
|
+
|
|
5
|
+
from makima.providers.groq_provider import GroqProvider
|
|
6
|
+
from makima.core.memory import Memory
|
|
7
|
+
|
|
8
|
+
SYSTEM_PROMPT = "..."
|
|
9
|
+
class Makima(App):
|
|
10
|
+
|
|
11
|
+
def on_mount(self):
|
|
12
|
+
self.provider = GroqProvider()
|
|
13
|
+
self.memory = Memory(system_prompt=SYSTEM_PROMPT)
|
|
14
|
+
|
|
15
|
+
def compose(self):
|
|
16
|
+
yield Header()
|
|
17
|
+
|
|
18
|
+
yield RichLog(id="chat")
|
|
19
|
+
|
|
20
|
+
yield Input(
|
|
21
|
+
placeholder="Ask Makima...",
|
|
22
|
+
id="input"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
yield Footer()
|
|
26
|
+
|
|
27
|
+
def on_input_submitted(self, event: Input.Submitted):
|
|
28
|
+
chat = self.query_one("#chat", RichLog)
|
|
29
|
+
|
|
30
|
+
user_input = event.value.strip()
|
|
31
|
+
|
|
32
|
+
if not user_input:
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
chat.write(
|
|
36
|
+
Text(f"You: {user_input}",style="bold cyan")
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
event.input.value = ""
|
|
41
|
+
|
|
42
|
+
chat.write(
|
|
43
|
+
Text("Makima: Hello! I'm alive", style="bold green")
|
|
44
|
+
)
|
|
45
|
+
# chat.write("[bold green]Makima:[/] Hello! I'm alive")
|
|
46
|
+
|
|
47
|
+
if __name__ == "__main__":
|
|
48
|
+
app = Makima()
|
|
49
|
+
app.run()
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from groq import Groq
|
|
3
|
+
from makima.config import GROQ_API_KEY, PROJECT_ROOT
|
|
4
|
+
import re
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_git_diff():
|
|
8
|
+
diff = subprocess.run("git diff", shell=True, text=True, capture_output=True)
|
|
9
|
+
status = subprocess.run("git status", shell=True, text=True, capture_output=True)
|
|
10
|
+
|
|
11
|
+
return f"STATUS:\n{status.stdout}\n\nDIFF:\n{diff.stdout}"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def generate_commit_message(diff):
|
|
15
|
+
prompt = f"""Generate ONE git commit message for this diff.
|
|
16
|
+
Format: type(scope): description
|
|
17
|
+
Types: feat/fix/refactor/docs/chore
|
|
18
|
+
Rules: max 72 chars, no quotes, no backticks, no explanation
|
|
19
|
+
Return ONLY the commit message line, nothing else.
|
|
20
|
+
|
|
21
|
+
{diff[:3000]}"""
|
|
22
|
+
|
|
23
|
+
try:
|
|
24
|
+
client = Groq(api_key=GROQ_API_KEY)
|
|
25
|
+
result = client.chat.completions.create(
|
|
26
|
+
model="qwen/qwen3.6-27b",
|
|
27
|
+
messages=[{
|
|
28
|
+
"role": "user",
|
|
29
|
+
"content": prompt
|
|
30
|
+
}]
|
|
31
|
+
)
|
|
32
|
+
except Exception as e:
|
|
33
|
+
print(f"Message Generator Failed!\n {e}")
|
|
34
|
+
return f"Failed to generate message: {e}"
|
|
35
|
+
|
|
36
|
+
content = result.choices[0].message.content
|
|
37
|
+
if "</think>" in content:
|
|
38
|
+
content = content.split("</think>")[-1].strip()
|
|
39
|
+
content = re.sub(r'[`\n]', '', content).strip()
|
|
40
|
+
return content
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def commit_and_push(message):
|
|
44
|
+
try:
|
|
45
|
+
message = clean_message(message)
|
|
46
|
+
cmd = f'git add -A && git commit -m "{message}" && git push origin main'
|
|
47
|
+
result = subprocess.run(
|
|
48
|
+
cmd,
|
|
49
|
+
shell=True,
|
|
50
|
+
text=True,
|
|
51
|
+
capture_output=True,
|
|
52
|
+
timeout=120,
|
|
53
|
+
cwd=PROJECT_ROOT
|
|
54
|
+
)
|
|
55
|
+
if result.returncode == 0:
|
|
56
|
+
return f"✓ Committed and pushed: {message}"
|
|
57
|
+
else:
|
|
58
|
+
return f"✗ Failed: {result.stderr}"
|
|
59
|
+
except Exception as e:
|
|
60
|
+
return f"✗ Error: {e}"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def clean_message(message):
|
|
65
|
+
# remove thinking blocks
|
|
66
|
+
if "</think>" in message:
|
|
67
|
+
message = message.split("</think>")[-1].strip()
|
|
68
|
+
# remove backticks, quotes, special shell characters
|
|
69
|
+
message = re.sub(r'[`"\'\n]', '', message)
|
|
70
|
+
# remove any remaining markdown
|
|
71
|
+
message = message.strip()
|
|
72
|
+
return message
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
from textual.app import App, ComposeResult
|
|
2
|
+
from textual.widgets import Header, Footer, Input, RichLog
|
|
3
|
+
from makima.config import PROJECT_ROOT
|
|
4
|
+
from makima.tools import TOOL_REGISTRY
|
|
5
|
+
from makima.tools.registry import TOOL_SCHEMAS
|
|
6
|
+
from makima.core.config_manager import handle_config, analyze_changes, commit_only
|
|
7
|
+
from makima.tools.git_tools import commit_and_push
|
|
8
|
+
from rich.text import Text
|
|
9
|
+
import asyncio
|
|
10
|
+
import json
|
|
11
|
+
|
|
12
|
+
from makima.providers.groq_provider import GroqProvider
|
|
13
|
+
from makima.core.memory import Memory
|
|
14
|
+
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
SYSTEM_PROMPT = f"""
|
|
19
|
+
You are a coding assistant. The project is at: {PROJECT_ROOT}
|
|
20
|
+
|
|
21
|
+
Rules:
|
|
22
|
+
- Always use list_files first to find exact paths
|
|
23
|
+
- Always use read_file before editing any file
|
|
24
|
+
- Use full absolute paths always
|
|
25
|
+
- Be concise and direct
|
|
26
|
+
- old_str must be an exact match of multiple lines from the file
|
|
27
|
+
- Never explain what you are about to do. Never say "Let me..." or "I'll first...".
|
|
28
|
+
- Just call the tool immediately and silently.
|
|
29
|
+
- Only speak in plain text when you have a FINAL answer for the user.
|
|
30
|
+
- Call only ONE tool per response. Wait for the tool result before calling the next tool.
|
|
31
|
+
- Never output multiple tool calls in one response.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class MakimaApp(App):
|
|
36
|
+
CSS_PATH = Path(__file__).parent / "app.tcss"
|
|
37
|
+
|
|
38
|
+
def __init__(self):
|
|
39
|
+
super().__init__()
|
|
40
|
+
self.memory = Memory(system_prompt=SYSTEM_PROMPT)
|
|
41
|
+
self.provider = GroqProvider()
|
|
42
|
+
self.pending_commit = None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def compose(self) -> ComposeResult:
|
|
46
|
+
yield Header()
|
|
47
|
+
yield RichLog(id="chat",markup=True, highlight=True)
|
|
48
|
+
yield Input(placeholder="Ask anything... (type 'exit' to quit)")
|
|
49
|
+
yield Footer()
|
|
50
|
+
|
|
51
|
+
def on_mount(self):
|
|
52
|
+
# focus the input so user can type immediately
|
|
53
|
+
self.query_one(Input).focus()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
async def on_input_submitted(self, event: Input.Submitted) -> None:
|
|
57
|
+
user_input = event.value.strip()
|
|
58
|
+
|
|
59
|
+
if not user_input:
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
chat = self.query_one(RichLog)
|
|
63
|
+
input_box = self.query_one(Input)
|
|
64
|
+
|
|
65
|
+
chat.write(Text.from_markup(f"[bold blue]You:[/] {user_input}"))
|
|
66
|
+
input_box.clear()
|
|
67
|
+
|
|
68
|
+
if user_input == "exit":
|
|
69
|
+
self.exit()
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
if user_input == "/config":
|
|
73
|
+
# config runs in background thread
|
|
74
|
+
await asyncio.to_thread(handle_config)
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
if user_input == "/commit":
|
|
78
|
+
chat.write("[dim]Analyzing changes...[/]")
|
|
79
|
+
diff, message = await asyncio.to_thread(analyze_changes)
|
|
80
|
+
|
|
81
|
+
if not diff:
|
|
82
|
+
chat.write("[yellow]No changes to commit.[/]")
|
|
83
|
+
return
|
|
84
|
+
|
|
85
|
+
chat.write(Text.from_markup(f"[white]Generated message: {message}[/]"))
|
|
86
|
+
chat.write(Text.from_markup(f"[yellow]Type 'push' to commit and push, 'commit' to commit only, or 'cancel'[/]"))
|
|
87
|
+
|
|
88
|
+
self.pending_commit = {"diff": diff, "message": message}
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
if user_input == "push" and self.pending_commit:
|
|
92
|
+
result = await asyncio.to_thread(commit_and_push, self.pending_commit["message"])
|
|
93
|
+
chat.write(Text.from_markup(f"[green]{result}[/]"))
|
|
94
|
+
self.pending_commit = None
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
if user_input == "commit" and self.pending_commit:
|
|
98
|
+
result = await asyncio.to_thread(commit_only, self.pending_commit["message"])
|
|
99
|
+
chat.write(f"[green]{result}[/]")
|
|
100
|
+
self.pending_commit = None
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
if user_input == "cancel" and self.pending_commit:
|
|
104
|
+
chat.write("[yellow]Commit cancelled.[/]")
|
|
105
|
+
self.pending_commit = None
|
|
106
|
+
return
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# show thinking indicator
|
|
110
|
+
chat.write(Text.from_markup("[dim]thinking...[/]"))
|
|
111
|
+
|
|
112
|
+
# run agent in background thread
|
|
113
|
+
response = await asyncio.to_thread(self.process_message, user_input)
|
|
114
|
+
|
|
115
|
+
# remove "thinking..." and show response
|
|
116
|
+
from rich.markdown import Markdown
|
|
117
|
+
chat.write(Text.from_markup(f"[bold green]Agent:[/]"))
|
|
118
|
+
chat.write(Markdown(response))
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def process_message(self, user_input):
|
|
122
|
+
self.memory.add_user(user_input)
|
|
123
|
+
|
|
124
|
+
while True:
|
|
125
|
+
stream = self.provider.stream_chat(
|
|
126
|
+
messages=self.memory.get(),
|
|
127
|
+
tools=TOOL_SCHEMAS
|
|
128
|
+
)
|
|
129
|
+
chunks = list(stream)
|
|
130
|
+
|
|
131
|
+
# collect chunks
|
|
132
|
+
text_buffer = ""
|
|
133
|
+
tool_name = ""
|
|
134
|
+
tool_args = ""
|
|
135
|
+
tool_call_id = ""
|
|
136
|
+
is_tool_call = False
|
|
137
|
+
|
|
138
|
+
for chunk in chunks:
|
|
139
|
+
delta = chunk.choices[0].delta
|
|
140
|
+
if delta.content:
|
|
141
|
+
text_buffer += delta.content
|
|
142
|
+
if delta.tool_calls:
|
|
143
|
+
is_tool_call = True
|
|
144
|
+
tc = delta.tool_calls[0]
|
|
145
|
+
if tc.id:
|
|
146
|
+
tool_call_id = tc.id
|
|
147
|
+
if tc.function.name:
|
|
148
|
+
tool_name += tc.function.name
|
|
149
|
+
if tc.function.arguments:
|
|
150
|
+
tool_args += tc.function.arguments
|
|
151
|
+
|
|
152
|
+
if is_tool_call:
|
|
153
|
+
args = json.loads(tool_args)
|
|
154
|
+
tool_fn = TOOL_REGISTRY.get(tool_name)
|
|
155
|
+
result = tool_fn(**args) if tool_fn else "Unknown tool"
|
|
156
|
+
|
|
157
|
+
self.memory.add_raw({
|
|
158
|
+
"role": "assistant",
|
|
159
|
+
"tool_calls": [{
|
|
160
|
+
"id": tool_call_id,
|
|
161
|
+
"type": "function",
|
|
162
|
+
"function": {
|
|
163
|
+
"name": tool_name,
|
|
164
|
+
"arguments": tool_args
|
|
165
|
+
}
|
|
166
|
+
}]
|
|
167
|
+
})
|
|
168
|
+
self.memory.add_tool_result(tool_call_id, str(result))
|
|
169
|
+
|
|
170
|
+
else:
|
|
171
|
+
self.memory.add_assistant(text_buffer)
|
|
172
|
+
return text_buffer
|
|
173
|
+
def run_ui():
|
|
174
|
+
app = MakimaApp()
|
|
175
|
+
app.run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: makima-cli
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.2.2
|
|
4
4
|
Summary: AI coding assistant for your terminal
|
|
5
5
|
Author: Kanhaiya
|
|
6
6
|
License: MIT License
|
|
@@ -52,7 +52,7 @@ An AI-powered coding assistant that runs in your terminal. Point it at any codeb
|
|
|
52
52
|
|
|
53
53
|
## Install
|
|
54
54
|
|
|
55
|
-
git clone https://github.com/
|
|
55
|
+
git clone https://github.com/kanhaiya-ML/makima-cli.git
|
|
56
56
|
cd makima-cli
|
|
57
57
|
pip install -r requirements.txt
|
|
58
58
|
|
|
@@ -5,6 +5,7 @@ makima/__init__.py
|
|
|
5
5
|
makima/config.py
|
|
6
6
|
makima/main.py
|
|
7
7
|
makima/setup.py
|
|
8
|
+
makima/test.py
|
|
8
9
|
makima/core/__init__.py
|
|
9
10
|
makima/core/agent.py
|
|
10
11
|
makima/core/config_manager.py
|
|
@@ -14,8 +15,11 @@ makima/providers/base.py
|
|
|
14
15
|
makima/providers/groq_provider.py
|
|
15
16
|
makima/tools/__init__.py
|
|
16
17
|
makima/tools/file_tools.py
|
|
18
|
+
makima/tools/git_tools.py
|
|
17
19
|
makima/tools/registry.py
|
|
18
20
|
makima/tools/shell_tools.py
|
|
21
|
+
makima/ui/__init__.py
|
|
22
|
+
makima/ui/app.py
|
|
19
23
|
makima_cli.egg-info/PKG-INFO
|
|
20
24
|
makima_cli.egg-info/SOURCES.txt
|
|
21
25
|
makima_cli.egg-info/dependency_links.txt
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
from makima.setup import setup_api_key,setup_model
|
|
4
|
-
from dotenv import load_dotenv
|
|
5
|
-
load_dotenv()
|
|
6
|
-
|
|
7
|
-
GROQ_API_KEY = setup_api_key()
|
|
8
|
-
# GROQ_API_KEY = os.getenv("GROQ_API_KEY")
|
|
9
|
-
MODEL_NAME = setup_model()
|
|
10
|
-
TOKEN_LIMIT = 10000
|
|
11
|
-
# PROJECT_ROOT = os.getcwd()
|
|
12
|
-
PROJECT_ROOT = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
|
|
13
|
-
|
|
14
|
-
if not GROQ_API_KEY:
|
|
15
|
-
print("Error: GROQ_API_KEY not set.")
|
|
16
|
-
print("Run this command first:")
|
|
17
|
-
print(' Windows: setx GROQ_API_KEY "your-key-here"')
|
|
18
|
-
print(' Linux/Mac: export GROQ_API_KEY="your-key-here"')
|
|
19
|
-
print("Get a free key at: https://console.groq.com")
|
|
20
|
-
sys.exit(1)
|
makima_cli-0.2.1/makima/main.py
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import subprocess
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def run_command(cmd):
|
|
5
|
-
# print(f"Commands going to Run: {cmd}")
|
|
6
|
-
# User_answer = input("Run This? (Y/N): ")
|
|
7
|
-
# User_answer = User_answer.lower()
|
|
8
|
-
|
|
9
|
-
# if User_answer != "y":
|
|
10
|
-
# return "Command cancelled"
|
|
11
|
-
|
|
12
|
-
result = subprocess.run(
|
|
13
|
-
cmd,
|
|
14
|
-
shell=True,
|
|
15
|
-
capture_output=True,
|
|
16
|
-
text=True,
|
|
17
|
-
timeout=30
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
return result.stdout + result.stderr
|