mini-code-cli 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl
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.
- mini_code_cli/__init__.py +0 -0
- mini_code_cli/agent_loop.py +138 -0
- mini_code_cli/prompts.py +51 -0
- mini_code_cli/tools.py +124 -0
- mini_code_cli/utils.py +111 -0
- {mini_code_cli-0.0.2.dist-info → mini_code_cli-0.0.4.dist-info}/METADATA +3 -3
- mini_code_cli-0.0.4.dist-info/RECORD +11 -0
- mini_code_cli-0.0.4.dist-info/entry_points.txt +2 -0
- mini_code_cli-0.0.4.dist-info/top_level.txt +1 -0
- mini_code_cli-0.0.2.dist-info/RECORD +0 -6
- mini_code_cli-0.0.2.dist-info/entry_points.txt +0 -2
- mini_code_cli-0.0.2.dist-info/top_level.txt +0 -1
- {mini_code_cli-0.0.2.dist-info → mini_code_cli-0.0.4.dist-info}/WHEEL +0 -0
- {mini_code_cli-0.0.2.dist-info → mini_code_cli-0.0.4.dist-info}/licenses/LICENSE +0 -0
|
File without changes
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
import prompts
|
|
5
|
+
import tools
|
|
6
|
+
import utils
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
# ANSI escape codes for colors and bold
|
|
12
|
+
BOLD = '\033[1m'
|
|
13
|
+
RED = '\033[91m'
|
|
14
|
+
GREEN = '\033[92m'
|
|
15
|
+
YELLOW = '\033[93m'
|
|
16
|
+
BLUE = '\033[94m'
|
|
17
|
+
MAGENTA = '\033[95m'
|
|
18
|
+
CYAN = '\033[96m'
|
|
19
|
+
RESET = '\033[0m'
|
|
20
|
+
|
|
21
|
+
def save_history(messages):
|
|
22
|
+
# Save messages to history.json
|
|
23
|
+
with open("history.json", "w") as f:
|
|
24
|
+
json.dump(messages, f, indent=2)
|
|
25
|
+
|
|
26
|
+
def parse_args():
|
|
27
|
+
parser = argparse.ArgumentParser(description="Agent loop for interacting with a language model")
|
|
28
|
+
parser.add_argument("--url", type=str, default="http://0.0.0.0:30000", help="API host")
|
|
29
|
+
parser.add_argument("--api-key", type=str, default=None, help="API key for authentication")
|
|
30
|
+
parser.add_argument("--allowed-dir", type=str, default=".", help="Allowed directory for file operations")
|
|
31
|
+
parser.add_argument("--max-tokens", type=int, default=2048, help="Maximum tokens for LLM response")
|
|
32
|
+
parser.add_argument("--temperature", type=float, default=0.0, help="Temperature for LLM")
|
|
33
|
+
parser.add_argument("--model", type=str, default="default", help="Model name")
|
|
34
|
+
args = parser.parse_args()
|
|
35
|
+
return args
|
|
36
|
+
|
|
37
|
+
def main():
|
|
38
|
+
args = parse_args()
|
|
39
|
+
|
|
40
|
+
allowed_dir = os.path.abspath(args.allowed_dir)
|
|
41
|
+
server_url = f"{args.url}"
|
|
42
|
+
|
|
43
|
+
tools_dict = tools.util_get_tools_dict()
|
|
44
|
+
llm_tools_dict = tools.util_get_tools()
|
|
45
|
+
|
|
46
|
+
system_prompt = prompts.system_prompt(tools_dict=tools_dict, allowed_dir=allowed_dir)
|
|
47
|
+
|
|
48
|
+
messages = [{"role": "system", "content": system_prompt}]
|
|
49
|
+
|
|
50
|
+
print(f"""
|
|
51
|
+
╔═══════════════════════════════════════════════════════════════════╗
|
|
52
|
+
║ Coding Agent Loop Started\t\t\t\t\t║
|
|
53
|
+
║ Type 'quit' or 'exit' to exit the loop.\t\t\t\t║
|
|
54
|
+
║ Allowed dir: {allowed_dir}\t║
|
|
55
|
+
╚═══════════════════════════════════════════════════════════════════╝
|
|
56
|
+
""")
|
|
57
|
+
|
|
58
|
+
while True:
|
|
59
|
+
llm_response_flag = False
|
|
60
|
+
llm_tool_response_flag = False
|
|
61
|
+
try:
|
|
62
|
+
print("-"*30)
|
|
63
|
+
user_input = input(f"{BOLD}{CYAN}You:{RESET} ")
|
|
64
|
+
if user_input.lower() in ["quit", "exit"]:
|
|
65
|
+
print("\nThank you. Goodbye! Saving history...")
|
|
66
|
+
save_history(messages)
|
|
67
|
+
break
|
|
68
|
+
except KeyboardInterrupt:
|
|
69
|
+
print("\nThank you. Goodbye! Saving history...")
|
|
70
|
+
save_history(messages)
|
|
71
|
+
break
|
|
72
|
+
|
|
73
|
+
messages.append({"role": "user", "content": user_input})
|
|
74
|
+
|
|
75
|
+
response_text, tool_calls = utils.call_openai_server(
|
|
76
|
+
messages,
|
|
77
|
+
max_tokens=args.max_tokens,
|
|
78
|
+
temperature=args.temperature,
|
|
79
|
+
model=args.model,
|
|
80
|
+
server_url=server_url,
|
|
81
|
+
tools=llm_tools_dict
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
if response_text:
|
|
85
|
+
print(f"{BOLD}{GREEN}Assistant:{RESET} {response_text}")
|
|
86
|
+
messages.append({"role": "assistant", "content": response_text})
|
|
87
|
+
else:
|
|
88
|
+
llm_response_flag = True
|
|
89
|
+
|
|
90
|
+
if tool_calls:
|
|
91
|
+
# Tool call parsing and execution
|
|
92
|
+
print(f"{BOLD}{YELLOW}Tool Call:{RESET} LLM is trying to call {len(tool_calls)} tools.")
|
|
93
|
+
if tool_calls:
|
|
94
|
+
for call in tool_calls:
|
|
95
|
+
call_id = call.get("id", "")
|
|
96
|
+
name = call.get("function", {}).get("name", "")
|
|
97
|
+
params_str = call.get("function", {}).get("arguments", "{}")
|
|
98
|
+
try:
|
|
99
|
+
tool_params = json.loads(params_str)
|
|
100
|
+
except json.JSONDecodeError:
|
|
101
|
+
print(f"{BOLD}{RED}Warning:{RESET} Error parsing arguments for tool {name}")
|
|
102
|
+
continue
|
|
103
|
+
|
|
104
|
+
if name in tools_dict:
|
|
105
|
+
# Check allowed directory for file operations
|
|
106
|
+
if name in ["read_file", "write_file", "grep", "glob"]:
|
|
107
|
+
filepath = tool_params.get("filepath", "")
|
|
108
|
+
if name == "write_file":
|
|
109
|
+
filepath = tool_params.get("filepath", "")
|
|
110
|
+
if filepath and not os.path.abspath(filepath).startswith(allowed_dir):
|
|
111
|
+
print(f"{BOLD}{RED}Warning:{RESET} File operation not allowed outside allowed directory: {allowed_dir}")
|
|
112
|
+
continue
|
|
113
|
+
|
|
114
|
+
func = tools_dict[name]["function"]
|
|
115
|
+
result = func(**tool_params)
|
|
116
|
+
# Limiting output to 300 characters for readability
|
|
117
|
+
result_str = str(result)
|
|
118
|
+
if len(result_str) > 300:
|
|
119
|
+
result_str = result_str[:300] + "... (truncated to 300 chars)"
|
|
120
|
+
print(f"{BOLD}{MAGENTA}Tool '{name}' returned:{RESET} {result_str}")
|
|
121
|
+
|
|
122
|
+
messages.append({
|
|
123
|
+
"role": "tool",
|
|
124
|
+
"tool_call_id": call_id,
|
|
125
|
+
"content": str(result)
|
|
126
|
+
})
|
|
127
|
+
else:
|
|
128
|
+
print(f"{BOLD}{RED}Warning:{RESET} Unknown tool: {name}")
|
|
129
|
+
else:
|
|
130
|
+
llm_tool_response_flag = True
|
|
131
|
+
|
|
132
|
+
if llm_response_flag and llm_tool_response_flag:
|
|
133
|
+
print(f"{BOLD}{RED}Warning:{RESET} No response was given by the LLM.")
|
|
134
|
+
|
|
135
|
+
save_history(messages)
|
|
136
|
+
|
|
137
|
+
if __name__ == "__main__":
|
|
138
|
+
main()
|
mini_code_cli/prompts.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# System prompt defining available tools and compaction behavior
|
|
2
|
+
def system_prompt(tools_dict=None, allowed_dir=None):
|
|
3
|
+
"""
|
|
4
|
+
Takes a list of tool names and returns a system prompt string.
|
|
5
|
+
"""
|
|
6
|
+
allowed_dir_prompt = ""
|
|
7
|
+
if allowed_dir:
|
|
8
|
+
allowed_dir_prompt = f"\nThe path you are allowed to operate in is called: {allowed_dir}"
|
|
9
|
+
if tools_dict:
|
|
10
|
+
tool_descriptions = "\n".join([f"{name} : {data['description']}" for name, data in tools_dict.items()])
|
|
11
|
+
base_prompt = "You are a helpful AI coding assistant with access to the following tools:\n"
|
|
12
|
+
end_prompt = "\n\nWhen answering, first use available tools if needed, then provide a compact summary of the results."
|
|
13
|
+
else:
|
|
14
|
+
tool_descriptions = ""
|
|
15
|
+
base_prompt = "You are a helpful AI coding assistant without any tools."
|
|
16
|
+
end_prompt = ""
|
|
17
|
+
|
|
18
|
+
prompt = f"""
|
|
19
|
+
{base_prompt}
|
|
20
|
+
{tool_descriptions}{end_prompt}{allowed_dir_prompt}
|
|
21
|
+
Keep responses concise and focused.
|
|
22
|
+
"""
|
|
23
|
+
return prompt.strip()
|
|
24
|
+
|
|
25
|
+
def compaction_prompt(messages):
|
|
26
|
+
"""
|
|
27
|
+
Takes a messages list and returns a compact prompt string summarizing the conversation.
|
|
28
|
+
"""
|
|
29
|
+
conversation = "\n".join([f"{msg['role']}: {msg['content']}" for msg in messages])
|
|
30
|
+
prompt = f"""
|
|
31
|
+
Please analyze the following conversation and output a concise summary covering:
|
|
32
|
+
1. Key topics discussed
|
|
33
|
+
2. Any decisions made
|
|
34
|
+
3. Important information or facts provided
|
|
35
|
+
4. Action items or next steps (if any)
|
|
36
|
+
|
|
37
|
+
Keep the summary to 2-3 sentences.
|
|
38
|
+
|
|
39
|
+
Conversation:
|
|
40
|
+
{conversation}
|
|
41
|
+
"""
|
|
42
|
+
return prompt.strip()
|
|
43
|
+
|
|
44
|
+
if __name__=="__main__":
|
|
45
|
+
import tools
|
|
46
|
+
tools_dict = tools.util_get_tools_dict()
|
|
47
|
+
print(system_prompt(tools_dict))
|
|
48
|
+
|
|
49
|
+
print("="*30)
|
|
50
|
+
|
|
51
|
+
print(system_prompt())
|
mini_code_cli/tools.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import glob as glob_module
|
|
3
|
+
import subprocess
|
|
4
|
+
import urllib.parse
|
|
5
|
+
import urllib.request
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
def read_file(filepath):
|
|
9
|
+
"""Read the contents of a file and return as a string. Param: filepath"""
|
|
10
|
+
try:
|
|
11
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
12
|
+
return f.read()
|
|
13
|
+
except Exception as e:
|
|
14
|
+
print(f"Error: {e}")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def write_file(filepath, content):
|
|
18
|
+
"""Write content to a file. Overwrites if file exists. Param: filepath, content"""
|
|
19
|
+
try:
|
|
20
|
+
with open(filepath, 'w', encoding='utf-8') as f:
|
|
21
|
+
f.write(content)
|
|
22
|
+
except Exception as e:
|
|
23
|
+
print(f"Error: {e}")
|
|
24
|
+
return f"Wrote to file: {filepath}, content: {content}."
|
|
25
|
+
|
|
26
|
+
def grep(pattern, filepath):
|
|
27
|
+
"""Search for a pattern in a file using grep and return matching lines. Param: pattern, filepath"""
|
|
28
|
+
try:
|
|
29
|
+
result = subprocess.run(['grep', pattern, filepath], capture_output=True, text=True, check=False)
|
|
30
|
+
return result.stdout
|
|
31
|
+
except Exception as e:
|
|
32
|
+
return f"Error: {e}"
|
|
33
|
+
|
|
34
|
+
def glob(pattern):
|
|
35
|
+
"""Return list of file paths matching the given glob pattern. Param: pattern"""
|
|
36
|
+
try:
|
|
37
|
+
return glob_module.glob(pattern)
|
|
38
|
+
except Exception as e:
|
|
39
|
+
return f"Error: {e}"
|
|
40
|
+
|
|
41
|
+
def web_search(query):
|
|
42
|
+
"""Perform a simple web search using DuckDuckGo's API and return top results. Param: query"""
|
|
43
|
+
query_encoded = urllib.parse.quote(query)
|
|
44
|
+
url = f"https://api.duckduckgo.com/?q={query_encoded}&format=json&no_html=1"
|
|
45
|
+
try:
|
|
46
|
+
with urllib.request.urlopen(url) as response:
|
|
47
|
+
data = json.loads(response.read().decode())
|
|
48
|
+
# Extract relevant text from the response
|
|
49
|
+
results = []
|
|
50
|
+
if 'AbstractText' in data and data['AbstractText']:
|
|
51
|
+
results.append(data['AbstractText'])
|
|
52
|
+
if 'RelatedTopics' in data:
|
|
53
|
+
for topic in data['RelatedTopics']:
|
|
54
|
+
if 'Text' in topic:
|
|
55
|
+
results.append(topic['Text'])
|
|
56
|
+
return '\n'.join(results) if results else "No results found."
|
|
57
|
+
except Exception as e:
|
|
58
|
+
return f"Error: {e}"
|
|
59
|
+
|
|
60
|
+
def read_website(url):
|
|
61
|
+
"""Fetch and return the text content of a given URL (simplified, returns raw HTML). Param: url"""
|
|
62
|
+
try:
|
|
63
|
+
with urllib.request.urlopen(url) as response:
|
|
64
|
+
return response.read().decode('utf-8')
|
|
65
|
+
except Exception as e:
|
|
66
|
+
return f"Error: {e}"
|
|
67
|
+
|
|
68
|
+
def util_get_tools(tool_names=None):
|
|
69
|
+
"""Return a JSON string describing all tool functions in this file for LLM usage."""
|
|
70
|
+
import inspect
|
|
71
|
+
tools = []
|
|
72
|
+
if tool_names:
|
|
73
|
+
func_names = [name for name, obj in globals().items() if callable(obj) and obj.__module__ == __name__ and not name.startswith('util_') and not name.startswith("_") and name in tool_names]
|
|
74
|
+
else:
|
|
75
|
+
func_names = [name for name, obj in globals().items() if callable(obj) and obj.__module__ == __name__ and not name.startswith('util_') and not name.startswith("_")]
|
|
76
|
+
|
|
77
|
+
for name in func_names:
|
|
78
|
+
func = globals()[name]
|
|
79
|
+
sig = inspect.signature(func)
|
|
80
|
+
parameters = {}
|
|
81
|
+
for param_name, param in sig.parameters.items():
|
|
82
|
+
param_type = str(param.annotation) if param.annotation != inspect.Parameter.empty else "string"
|
|
83
|
+
# Simplify common types
|
|
84
|
+
if 'int' in param_type.lower() or 'integer' in param_type.lower():
|
|
85
|
+
param_type = "integer"
|
|
86
|
+
elif 'float' in param_type.lower() or 'number' in param_type.lower():
|
|
87
|
+
param_type = "number"
|
|
88
|
+
elif 'bool' in param_type.lower():
|
|
89
|
+
param_type = "boolean"
|
|
90
|
+
elif 'list' in param_type.lower() or 'array' in param_type.lower():
|
|
91
|
+
param_type = "array"
|
|
92
|
+
else:
|
|
93
|
+
param_type = "string"
|
|
94
|
+
parameters[param_name] = {"type": param_type}
|
|
95
|
+
tool = {
|
|
96
|
+
"type": "function",
|
|
97
|
+
"function": {
|
|
98
|
+
"name": name,
|
|
99
|
+
"description": func.__doc__ if func.__doc__ else f"Function {name}",
|
|
100
|
+
"parameters": {
|
|
101
|
+
"type": "object",
|
|
102
|
+
"properties": parameters,
|
|
103
|
+
"required": [p for p in sig.parameters if sig.parameters[p].default == inspect.Parameter.empty]
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
tools.append(tool)
|
|
108
|
+
return tools
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def util_get_tools_dict():
|
|
112
|
+
"""Return a dictionary mapping tool names to their function objects."""
|
|
113
|
+
result = {}
|
|
114
|
+
func_names = [name for name, obj in globals().items() if callable(obj) and obj.__module__ == __name__ and not name.startswith('util_') and not name.startswith("_")]
|
|
115
|
+
for name in func_names:
|
|
116
|
+
func = globals()[name]
|
|
117
|
+
desc = func.__doc__ if func.__doc__ else f"Function {name}"
|
|
118
|
+
result[name] = {"function": func, "description": desc}
|
|
119
|
+
return result
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
if __name__=="__main__":
|
|
123
|
+
# print(util_get_tools())
|
|
124
|
+
print(json.dumps(tools_dict, indent=4))
|
mini_code_cli/utils.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import json
|
|
3
|
+
import argparse
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def call_openai_server(messages, max_tokens=2048, temperature=0.0, top_p=0.95, model="default", server_url=None, api_key=None, tools=None,):
|
|
7
|
+
"""
|
|
8
|
+
Querying an OpenAI-compatible server (local or remote) using the requests library.
|
|
9
|
+
Supports authentication via API key if provided.
|
|
10
|
+
"""
|
|
11
|
+
url = f"{server_url}/v1/chat/completions"
|
|
12
|
+
|
|
13
|
+
headers = {
|
|
14
|
+
"Content-Type": "application/json"
|
|
15
|
+
}
|
|
16
|
+
if api_key:
|
|
17
|
+
headers["Authorization"] = f"Bearer {api_key}"
|
|
18
|
+
|
|
19
|
+
payload = {
|
|
20
|
+
"model": model,
|
|
21
|
+
"messages": messages,
|
|
22
|
+
"max_tokens": max_tokens,
|
|
23
|
+
"temperature": temperature,
|
|
24
|
+
"top_p": top_p
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if tools:
|
|
28
|
+
payload["tools"] = tools
|
|
29
|
+
payload["tool_choice"] = "auto"
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
response = requests.post(
|
|
33
|
+
url,
|
|
34
|
+
headers=headers,
|
|
35
|
+
json=payload,
|
|
36
|
+
timeout=60
|
|
37
|
+
)
|
|
38
|
+
response.raise_for_status()
|
|
39
|
+
|
|
40
|
+
result = response.json().get("choices", [{}])[0].get("message", {})
|
|
41
|
+
content = result.get("content", "")
|
|
42
|
+
tool_calls = result.get("tool_calls", [])
|
|
43
|
+
|
|
44
|
+
return content, tool_calls
|
|
45
|
+
|
|
46
|
+
except requests.exceptions.RequestException as e:
|
|
47
|
+
print(f"Error calling OpenAI Server...: {e}")
|
|
48
|
+
return None, None
|
|
49
|
+
except (json.JSONDecodeError, KeyError, IndexError) as e:
|
|
50
|
+
print(f"Error processing response: {e}")
|
|
51
|
+
return None, None
|
|
52
|
+
|
|
53
|
+
# Alternative: use the newer SGLang API format (v0.3+)
|
|
54
|
+
def call_openai_server_prompt(prompt, max_tokens=1024, temperature=0.0, top_p=0.95, model="default", server_url=None, api_key=None, tools=None):
|
|
55
|
+
"""
|
|
56
|
+
OpenAI compatible call, pre-creating the messages object.
|
|
57
|
+
"""
|
|
58
|
+
messages = [
|
|
59
|
+
{"role": "user", "content": prompt}
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
return call_openai_server(messages, max_tokens, temperature, top_p, model, server_url=server_url, api_key=api_key, tools=tools)
|
|
63
|
+
|
|
64
|
+
def parse_args():
|
|
65
|
+
parser = argparse.ArgumentParser(description="Agent loop for interacting with a language model")
|
|
66
|
+
parser.add_argument("--host", type=str, default="localhost", help="API host")
|
|
67
|
+
parser.add_argument("--port", type=int, default=30000, help="API port")
|
|
68
|
+
parser.add_argument("--prompt", type=str, default="What is the purpose of life?", help="prompt")
|
|
69
|
+
parser.add_argument("--api-key", type=str, default=None, help="API key for authentication (optional)")
|
|
70
|
+
|
|
71
|
+
return parser.parse_args()
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if __name__ == '__main__':
|
|
75
|
+
import tools
|
|
76
|
+
tools_dict = tools.util_get_tools()
|
|
77
|
+
|
|
78
|
+
args = parse_args()
|
|
79
|
+
# Configuration for local SGLang deployment
|
|
80
|
+
server_url=f"http://{args.host}:{args.port}"
|
|
81
|
+
|
|
82
|
+
print("="*60)
|
|
83
|
+
print("Entering LLM call:")
|
|
84
|
+
print("-"*30)
|
|
85
|
+
prompt = args.prompt
|
|
86
|
+
|
|
87
|
+
print(f"Prompt:\n{prompt}")
|
|
88
|
+
print("---")
|
|
89
|
+
|
|
90
|
+
response_text, tool_calls = call_openai_server_prompt(prompt, server_url=server_url, api_key=args.api_key, tools=tools_dict)
|
|
91
|
+
print(f"Response:\n{response_text}")
|
|
92
|
+
print("---")
|
|
93
|
+
print(f"Tools:\n{tool_calls}")
|
|
94
|
+
print("---")
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# #################################
|
|
99
|
+
# Test call to DeepSeek endpoint
|
|
100
|
+
# #################################
|
|
101
|
+
|
|
102
|
+
# deepseek_server_url = "https://api.deepseek.com"
|
|
103
|
+
# deepseek_model = "deepseek-v4-flash"
|
|
104
|
+
# print("="*60)
|
|
105
|
+
# print("Entering DeepSeek call:")
|
|
106
|
+
# print("-"*30)
|
|
107
|
+
# response_text_ds, tools_ds = call_openai_server_prompt(prompt, server_url=deepseek_server_url, api_key=args.api_key, model=deepseek_model, tools=tools_dict)
|
|
108
|
+
# print(f"DeepSeek Response:\n{response_text_ds}")
|
|
109
|
+
# print("---")
|
|
110
|
+
# print(f"Tools:\n{tools_ds}")
|
|
111
|
+
# print("---")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mini-code-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Minimal Coding CLI
|
|
5
5
|
Author-email: Nikolai Rozanov <nikolai.rozanov@gmail.com>
|
|
6
6
|
License: The MIT License (MIT)
|
|
@@ -30,8 +30,8 @@ pip3 install mini-code-cli
|
|
|
30
30
|
|
|
31
31
|
2. Run agent: (get LLM running via SGLang or Vllm)
|
|
32
32
|
```bash
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
mini-code #run the agent loop
|
|
34
|
+
mini-code --url "https://api.deepseek.com" --model "deepseek-v4-flash" --api-key "sk-dummy" --allowed-dir ./experiments/
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
mini_code_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
mini_code_cli/agent_loop.py,sha256=uuAeiqbiy3PE3r8Vs_dDkcbDKVmcxkefhUdXbWifPzE,5683
|
|
3
|
+
mini_code_cli/prompts.py,sha256=bMWPLsD0SCQK4oDru4MYSSUf2KQq8EO4ZD55PpdlR_I,1730
|
|
4
|
+
mini_code_cli/tools.py,sha256=i46l8IvsrXJgqt7r8rKAMTGKNGAGffxKTFlwmAuWoD0,4926
|
|
5
|
+
mini_code_cli/utils.py,sha256=KmI-hfVsuopVRr5lLXiW2T24RZawtGKHOy9n8Ak1UC4,3636
|
|
6
|
+
mini_code_cli-0.0.4.dist-info/licenses/LICENSE,sha256=WCkMINUFi--UtEg_alEE2FBKPtNKkzi7dGzaxzchifc,1088
|
|
7
|
+
mini_code_cli-0.0.4.dist-info/METADATA,sha256=thK7lq5Z6h2h934eeFcBpzWgV-LH9Q4p4YdO411fMpg,1943
|
|
8
|
+
mini_code_cli-0.0.4.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
9
|
+
mini_code_cli-0.0.4.dist-info/entry_points.txt,sha256=MwDp5UbXpI7wodSmOSYL8_nKutnBiyp96ZDDtaX7x14,60
|
|
10
|
+
mini_code_cli-0.0.4.dist-info/top_level.txt,sha256=3Hb6PpNkJYXvzDKXuuFJRvzCdsTRh0TuRWz-ScJ6qV0,14
|
|
11
|
+
mini_code_cli-0.0.4.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
mini_code_cli
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
mini_code_cli-0.0.2.dist-info/licenses/LICENSE,sha256=WCkMINUFi--UtEg_alEE2FBKPtNKkzi7dGzaxzchifc,1088
|
|
2
|
-
mini_code_cli-0.0.2.dist-info/METADATA,sha256=SccCYdxuHXjx1ASjSn3fZnvy3fOxQr3E6S0O1e9fp0s,1965
|
|
3
|
-
mini_code_cli-0.0.2.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
4
|
-
mini_code_cli-0.0.2.dist-info/entry_points.txt,sha256=ZPwaUZnKtV8ZwNPZPoocL-y2x6gkb3ZN5tYDlsNRIng,53
|
|
5
|
-
mini_code_cli-0.0.2.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
6
|
-
mini_code_cli-0.0.2.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
File without changes
|
|
File without changes
|