code-lm 0.2.1__tar.gz → 0.2.3__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.
- {code_lm-0.2.1/src/code_lm.egg-info → code_lm-0.2.3}/PKG-INFO +3 -3
- {code_lm-0.2.1 → code_lm-0.2.3}/README.md +2 -2
- {code_lm-0.2.1 → code_lm-0.2.3}/pyproject.toml +1 -1
- {code_lm-0.2.1 → code_lm-0.2.3}/setup.py +1 -1
- {code_lm-0.2.1 → code_lm-0.2.3/src/code_lm.egg-info}/PKG-INFO +3 -3
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/models/openrouter.py +3 -3
- code_lm-0.2.3/src/gemini_cli/tools/directory_tools.py +31 -0
- code_lm-0.2.1/src/gemini_cli/tools/directory_tools.py +0 -120
- {code_lm-0.2.1 → code_lm-0.2.3}/MANIFEST.in +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/setup.cfg +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/code_lm.egg-info/SOURCES.txt +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/code_lm.egg-info/dependency_links.txt +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/code_lm.egg-info/entry_points.txt +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/code_lm.egg-info/requires.txt +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/code_lm.egg-info/top_level.txt +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/__init__.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/config.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/main.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/models/__init__.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/models/gemini.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/tools/__init__.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/tools/base.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/tools/file_tools.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/tools/quality_tools.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/tools/summarizer_tool.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/tools/system_tools.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/tools/task_complete_tool.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/tools/test_runner.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/tools/tree_tool.py +0 -0
- {code_lm-0.2.1 → code_lm-0.2.3}/src/gemini_cli/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: code-lm
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: An AI coding assistant using various LLM models.
|
|
5
5
|
Home-page: https://github.com/Panagiotis897/lm-code
|
|
6
6
|
Author: Panagiotis897
|
|
@@ -28,7 +28,7 @@ Dynamic: requires-python
|
|
|
28
28
|
|
|
29
29
|
# LM Code
|
|
30
30
|
|
|
31
|
-
LM Code is a powerful AI coding assistant for your terminal
|
|
31
|
+
LM Code is a powerful AI coding assistant for your terminal supporting multiple LLM models like Qwen, DeepSeek, and Gemini. With LM Code, you can interactively work on coding tasks, automate file operations, and improve your workflow directly from the command line.
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -55,7 +55,7 @@ LM Code is a powerful AI coding assistant for your terminal, leveraging the Open
|
|
|
55
55
|
### Method 1: Install from PyPI (Recommended)
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
pip install
|
|
58
|
+
pip install code-lm
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
### Method 2: Install from Source
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# LM Code
|
|
2
2
|
|
|
3
|
-
LM Code is a powerful AI coding assistant for your terminal
|
|
3
|
+
LM Code is a powerful AI coding assistant for your terminal supporting multiple LLM models like Qwen, DeepSeek, and Gemini. With LM Code, you can interactively work on coding tasks, automate file operations, and improve your workflow directly from the command line.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -27,7 +27,7 @@ LM Code is a powerful AI coding assistant for your terminal, leveraging the Open
|
|
|
27
27
|
### Method 1: Install from PyPI (Recommended)
|
|
28
28
|
|
|
29
29
|
```bash
|
|
30
|
-
pip install
|
|
30
|
+
pip install code-lm
|
|
31
31
|
```
|
|
32
32
|
|
|
33
33
|
### Method 2: Install from Source
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="code-lm",
|
|
5
|
-
version="0.2.
|
|
5
|
+
version="0.2.3",
|
|
6
6
|
description="A CLI for interacting with various LLM models using OpenRouter and other APIs.",
|
|
7
7
|
long_description=open("README.md").read(),
|
|
8
8
|
long_description_content_type="text/markdown",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: code-lm
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: An AI coding assistant using various LLM models.
|
|
5
5
|
Home-page: https://github.com/Panagiotis897/lm-code
|
|
6
6
|
Author: Panagiotis897
|
|
@@ -28,7 +28,7 @@ Dynamic: requires-python
|
|
|
28
28
|
|
|
29
29
|
# LM Code
|
|
30
30
|
|
|
31
|
-
LM Code is a powerful AI coding assistant for your terminal
|
|
31
|
+
LM Code is a powerful AI coding assistant for your terminal supporting multiple LLM models like Qwen, DeepSeek, and Gemini. With LM Code, you can interactively work on coding tasks, automate file operations, and improve your workflow directly from the command line.
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -55,7 +55,7 @@ LM Code is a powerful AI coding assistant for your terminal, leveraging the Open
|
|
|
55
55
|
### Method 1: Install from PyPI (Recommended)
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
-
pip install
|
|
58
|
+
pip install code-lm
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
### Method 2: Install from Source
|
|
@@ -67,7 +67,7 @@ class OpenRouterModel:
|
|
|
67
67
|
self.initial_model_name = model_name
|
|
68
68
|
self.current_model_name = model_name
|
|
69
69
|
self.console = console
|
|
70
|
-
self.base_url = "https://openrouter.ai/api/v1
|
|
70
|
+
self.base_url = "https://openrouter.ai/api/v1"
|
|
71
71
|
|
|
72
72
|
self.headers = {
|
|
73
73
|
"Authorization": f"Bearer {api_key}",
|
|
@@ -484,7 +484,7 @@ class OpenRouterModel:
|
|
|
484
484
|
}
|
|
485
485
|
if hasattr(declaration.parameters, 'required') and declaration.parameters.required:
|
|
486
486
|
schema["required"] = declaration.parameters.required
|
|
487
|
-
|
|
487
|
+
|
|
488
488
|
declarations.append(FunctionDeclaration(
|
|
489
489
|
name=getattr(declaration, 'name', 'unknown'),
|
|
490
490
|
description=getattr(declaration, 'description', ''),
|
|
@@ -495,7 +495,7 @@ class OpenRouterModel:
|
|
|
495
495
|
log.warning(f"Tool {tool_name} has 'get_function_declaration' but it returned None.")
|
|
496
496
|
else:
|
|
497
497
|
log.warning(f"Tool {tool_name} does not have a 'get_function_declaration' method. Skipping.")
|
|
498
|
-
|
|
498
|
+
|
|
499
499
|
log.info(f"Created {len(declarations)} function declarations for native tool use.")
|
|
500
500
|
return declarations if declarations else None
|
|
501
501
|
# --- System Prompt Helper ---
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Directory tools for interacting with the file system.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import platform
|
|
7
|
+
import subprocess
|
|
8
|
+
import logging
|
|
9
|
+
|
|
10
|
+
log = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
class LsTool:
|
|
13
|
+
"""Tool for listing directory contents."""
|
|
14
|
+
|
|
15
|
+
def execute(self, path: str = ".") -> str:
|
|
16
|
+
"""List the contents of a directory."""
|
|
17
|
+
try:
|
|
18
|
+
# Check the operating system and use the appropriate command
|
|
19
|
+
if platform.system() == "Windows":
|
|
20
|
+
# Use dir command on Windows
|
|
21
|
+
result = subprocess.run(["cmd", "/c", "dir", path], capture_output=True, text=True, check=True)
|
|
22
|
+
else:
|
|
23
|
+
# Use ls command on Unix-based systems
|
|
24
|
+
result = subprocess.run(["ls", path], capture_output=True, text=True, check=True)
|
|
25
|
+
return result.stdout
|
|
26
|
+
except FileNotFoundError:
|
|
27
|
+
log.error("'ls' or 'dir' command not found. Ensure it is installed or in PATH.")
|
|
28
|
+
raise
|
|
29
|
+
except subprocess.CalledProcessError as e:
|
|
30
|
+
log.error(f"Error executing directory listing: {e}")
|
|
31
|
+
raise
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Tools for directory operations.
|
|
3
|
-
"""
|
|
4
|
-
import os
|
|
5
|
-
import logging
|
|
6
|
-
import subprocess
|
|
7
|
-
from .base import BaseTool
|
|
8
|
-
|
|
9
|
-
log = logging.getLogger(__name__)
|
|
10
|
-
|
|
11
|
-
class CreateDirectoryTool(BaseTool):
|
|
12
|
-
"""Tool to create a new directory."""
|
|
13
|
-
name = "create_directory"
|
|
14
|
-
description = "Creates a new directory, including any necessary parent directories."
|
|
15
|
-
|
|
16
|
-
def execute(self, dir_path: str) -> str:
|
|
17
|
-
"""
|
|
18
|
-
Creates a directory.
|
|
19
|
-
|
|
20
|
-
Args:
|
|
21
|
-
dir_path: The path of the directory to create.
|
|
22
|
-
|
|
23
|
-
Returns:
|
|
24
|
-
A success or error message.
|
|
25
|
-
"""
|
|
26
|
-
try:
|
|
27
|
-
# Basic path safety
|
|
28
|
-
if ".." in dir_path.split(os.path.sep):
|
|
29
|
-
log.warning(f"Attempted to access parent directory in create_directory path: {dir_path}")
|
|
30
|
-
return f"Error: Invalid path '{dir_path}'. Cannot access parent directories."
|
|
31
|
-
|
|
32
|
-
target_path = os.path.abspath(os.path.expanduser(dir_path))
|
|
33
|
-
log.info(f"Attempting to create directory: {target_path}")
|
|
34
|
-
|
|
35
|
-
if os.path.exists(target_path):
|
|
36
|
-
if os.path.isdir(target_path):
|
|
37
|
-
log.warning(f"Directory already exists: {target_path}")
|
|
38
|
-
return f"Directory already exists: {dir_path}"
|
|
39
|
-
else:
|
|
40
|
-
log.error(f"Path exists but is not a directory: {target_path}")
|
|
41
|
-
return f"Error: Path exists but is not a directory: {dir_path}"
|
|
42
|
-
|
|
43
|
-
os.makedirs(target_path, exist_ok=True) # exist_ok=True handles race conditions slightly better
|
|
44
|
-
log.info(f"Successfully created directory: {target_path}")
|
|
45
|
-
return f"Successfully created directory: {dir_path}"
|
|
46
|
-
|
|
47
|
-
except OSError as e:
|
|
48
|
-
log.error(f"Error creating directory '{dir_path}': {e}", exc_info=True)
|
|
49
|
-
return f"Error creating directory: {str(e)}"
|
|
50
|
-
except Exception as e:
|
|
51
|
-
log.error(f"Unexpected error creating directory '{dir_path}': {e}", exc_info=True)
|
|
52
|
-
return f"Error creating directory: {str(e)}"
|
|
53
|
-
|
|
54
|
-
class LsTool(BaseTool):
|
|
55
|
-
"""Tool to list directory contents using 'ls -lA'."""
|
|
56
|
-
name = "ls"
|
|
57
|
-
description = "Lists the contents of a specified directory (long format, including hidden files)."
|
|
58
|
-
args_schema: dict = {
|
|
59
|
-
"path": {
|
|
60
|
-
"type": "string",
|
|
61
|
-
"description": "Optional path to a specific directory relative to the workspace root. If omitted, uses the current directory.",
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
required_args: list[str] = []
|
|
65
|
-
|
|
66
|
-
def execute(self, path: str | None = None) -> str:
|
|
67
|
-
"""Executes the 'ls -lA' command."""
|
|
68
|
-
target_path = "." # Default to current directory
|
|
69
|
-
if path:
|
|
70
|
-
# Basic path safety - prevent navigating outside workspace root if needed
|
|
71
|
-
# For simplicity, assuming relative paths are okay for now
|
|
72
|
-
target_path = os.path.normpath(path) # Normalize path
|
|
73
|
-
if target_path.startswith(".."):
|
|
74
|
-
log.warning(f"Attempted to access parent directory in ls path: {path}")
|
|
75
|
-
return f"Error: Invalid path '{path}'. Cannot access parent directories."
|
|
76
|
-
|
|
77
|
-
command = ['ls', '-lA', target_path]
|
|
78
|
-
log.info(f"Executing ls command: {' '.join(command)}")
|
|
79
|
-
|
|
80
|
-
try:
|
|
81
|
-
process = subprocess.run(
|
|
82
|
-
command,
|
|
83
|
-
capture_output=True,
|
|
84
|
-
text=True,
|
|
85
|
-
check=False, # Don't raise exception on non-zero exit code
|
|
86
|
-
timeout=15 # Add a timeout
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
if process.returncode == 0:
|
|
90
|
-
log.info(f"ls command successful for path '{target_path}'.")
|
|
91
|
-
# Limit output size? ls -l can be long.
|
|
92
|
-
output = process.stdout.strip()
|
|
93
|
-
# Example truncation (adjust as needed)
|
|
94
|
-
if len(output.splitlines()) > 100:
|
|
95
|
-
log.warning(f"ls output for '{target_path}' exceeded 100 lines. Truncating.")
|
|
96
|
-
output = "\n".join(output.splitlines()[:100]) + "\n... (output truncated)"
|
|
97
|
-
return output
|
|
98
|
-
else:
|
|
99
|
-
# Handle cases like directory not found specifically if possible
|
|
100
|
-
stderr_lower = process.stderr.lower()
|
|
101
|
-
if "no such file or directory" in stderr_lower:
|
|
102
|
-
log.error(f"ls command failed: Directory not found '{target_path}'. Stderr: {process.stderr.strip()}")
|
|
103
|
-
return f"Error: Directory not found: '{target_path}'"
|
|
104
|
-
else:
|
|
105
|
-
log.error(f"ls command failed with return code {process.returncode}. Path: '{target_path}'. Stderr: {process.stderr.strip()}")
|
|
106
|
-
error_detail = process.stderr.strip() if process.stderr else "(No stderr)"
|
|
107
|
-
return f"Error executing ls command (Code: {process.returncode}): {error_detail}"
|
|
108
|
-
|
|
109
|
-
except FileNotFoundError:
|
|
110
|
-
# This means 'ls' itself wasn't found - unlikely but possible
|
|
111
|
-
log.error("'ls' command not found (FileNotFoundError). It might not be installed or in PATH.")
|
|
112
|
-
return "Error: 'ls' command not found. Please ensure it is installed and in the system's PATH."
|
|
113
|
-
except subprocess.TimeoutExpired:
|
|
114
|
-
log.error(f"ls command timed out for path '{target_path}' after 15 seconds.")
|
|
115
|
-
return f"Error: ls command timed out for path '{target_path}'."
|
|
116
|
-
except Exception as e:
|
|
117
|
-
log.exception(f"An unexpected error occurred while executing ls command for path '{target_path}': {e}")
|
|
118
|
-
return f"An unexpected error occurred while executing ls: {str(e)}"
|
|
119
|
-
|
|
120
|
-
# Assuming BaseTool provides a working get_function_declaration implementation
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|