lcode-cli 0.33.0__py3-none-any.whl → 0.34.0__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.
- lcode/__init__.py +1 -1
- lcode/agent.py +32 -5
- lcode/screenshots.py +1086 -0
- lcode/tools.py +112 -1
- {lcode_cli-0.33.0.dist-info → lcode_cli-0.34.0.dist-info}/METADATA +11 -10
- {lcode_cli-0.33.0.dist-info → lcode_cli-0.34.0.dist-info}/RECORD +9 -8
- {lcode_cli-0.33.0.dist-info → lcode_cli-0.34.0.dist-info}/WHEEL +0 -0
- {lcode_cli-0.33.0.dist-info → lcode_cli-0.34.0.dist-info}/entry_points.txt +0 -0
- {lcode_cli-0.33.0.dist-info → lcode_cli-0.34.0.dist-info}/licenses/LICENSE +0 -0
lcode/__init__.py
CHANGED
lcode/agent.py
CHANGED
|
@@ -48,7 +48,7 @@ from lcode.config import format_tokens
|
|
|
48
48
|
from lcode.jobs import Jobs
|
|
49
49
|
from lcode.mcp import McpManager
|
|
50
50
|
from lcode.ollama import Ollama, OllamaError
|
|
51
|
-
from lcode.permissions import Permissions
|
|
51
|
+
from lcode.permissions import LEADING_CD, Permissions
|
|
52
52
|
from lcode.render import MarkdownStreamer
|
|
53
53
|
from lcode.repeats import Repeats
|
|
54
54
|
from lcode.sandbox import Sandbox, SandboxError, project_root
|
|
@@ -122,7 +122,7 @@ SYSTEM_PROMPT = """You are lcode, an autonomous software-engineering agent runni
|
|
|
122
122
|
# Verifying your work
|
|
123
123
|
- A syntax check or an import only shows that code loads. Run what you changed the way it will be used (the script, the tests, the app) and fix what fails.
|
|
124
124
|
- To fix a bug, first reproduce each problem the user reports with a test, a command or a short script, then run the same checks to show they're gone.
|
|
125
|
-
- For what you can't see, like a GUI, a web page or a layout,
|
|
125
|
+
- For what you can't see, like a GUI, a web page or a layout, use the screenshot tool: it runs the program (or opens the page) without a screen and returns what it shows, with the sizes of windows, widgets or the page measured{look}. Measure instead of assuming.
|
|
126
126
|
- Never claim something works, mark a todo done, or call it tested unless you ran it. If you couldn't check something, say so and tell the user exactly what to look for. If something fails, say so and show the relevant error.{checks}
|
|
127
127
|
|
|
128
128
|
# Communication
|
|
@@ -131,7 +131,7 @@ SYSTEM_PROMPT = """You are lcode, an autonomous software-engineering agent runni
|
|
|
131
131
|
|
|
132
132
|
# Environment
|
|
133
133
|
- Working directory: {cwd}
|
|
134
|
-
- OS: {os}; shell: bash; Python command:
|
|
134
|
+
- OS: {os}; shell: bash; Python command: {python}
|
|
135
135
|
- Date: {date}
|
|
136
136
|
- Git: {git}
|
|
137
137
|
|
|
@@ -218,6 +218,30 @@ def call_arguments(call: dict) -> dict:
|
|
|
218
218
|
return args if isinstance(args, dict) else {}
|
|
219
219
|
|
|
220
220
|
|
|
221
|
+
VENV_DIRS = (".venv", "venv", "env")
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def project_python(cwd: Path) -> Path | None:
|
|
225
|
+
"""The project's virtual environment's Python (.venv, venv or env, here or up to the repository's root)."""
|
|
226
|
+
for folder in [cwd, *cwd.parents][:4]:
|
|
227
|
+
for name in VENV_DIRS:
|
|
228
|
+
path = folder / name / "bin" / "python"
|
|
229
|
+
if path.exists() and (folder / name / "pyvenv.cfg").exists():
|
|
230
|
+
return path
|
|
231
|
+
if (folder / ".git").exists():
|
|
232
|
+
break # not beyond the repository
|
|
233
|
+
return None
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def python_line(cwd: Path) -> str:
|
|
237
|
+
"""How the system prompt names the Python command."""
|
|
238
|
+
venv = project_python(cwd)
|
|
239
|
+
if venv is None:
|
|
240
|
+
return f"`{'python' if shutil.which('python') else 'python3'}`"
|
|
241
|
+
shown = venv.relative_to(cwd) if cwd in venv.parents else venv
|
|
242
|
+
return f"`{shown}` (the project's virtual environment: plain python lacks its packages)"
|
|
243
|
+
|
|
244
|
+
|
|
221
245
|
class Progress:
|
|
222
246
|
"""The status line under a running request.
|
|
223
247
|
|
|
@@ -372,7 +396,7 @@ class Agent:
|
|
|
372
396
|
model=self.settings.model,
|
|
373
397
|
cwd=self.cwd,
|
|
374
398
|
os=f"{platform.system()} {platform.release()} ({platform.machine()})",
|
|
375
|
-
python=
|
|
399
|
+
python=python_line(self.cwd),
|
|
376
400
|
date=dt.date.today().isoformat(),
|
|
377
401
|
git=git_info(self.cwd),
|
|
378
402
|
tree=tree(self.cwd, depth=1, limit=120),
|
|
@@ -383,7 +407,7 @@ class Agent:
|
|
|
383
407
|
skills=extensions.skills_prompt(self.extensions().skills, self.settings.context),
|
|
384
408
|
code=self.code_prompt(),
|
|
385
409
|
map=self.map_prompt(),
|
|
386
|
-
look="
|
|
410
|
+
look="; look at other images with view_image" if self.vision_model() else "",
|
|
387
411
|
checks=self.checks_prompt(),
|
|
388
412
|
)
|
|
389
413
|
|
|
@@ -1000,6 +1024,9 @@ class Agent:
|
|
|
1000
1024
|
return f"agent({args.get('type', '')}: {args.get('description') or str(args.get('task', ''))[:50]})"
|
|
1001
1025
|
if name == "bash":
|
|
1002
1026
|
return f"$ {str(args.get('command', ''))[:60]}"
|
|
1027
|
+
if name == "screenshot":
|
|
1028
|
+
what = args.get("url") or LEADING_CD.sub("", str(args.get("command") or ""))
|
|
1029
|
+
return f"screenshot({what[:60]})"
|
|
1003
1030
|
if name in ("web_search", "web_fetch", "view_image"):
|
|
1004
1031
|
return f"{name}({args.get('query') or args.get('url') or args.get('path') or ''})"
|
|
1005
1032
|
if self.mcp and self.mcp.owns(name):
|