agent-code 2.0.1__tar.gz → 2.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.
Files changed (81) hide show
  1. {agent_code-2.0.1/src/agent_code.egg-info → agent_code-2.1.0}/PKG-INFO +3 -3
  2. {agent_code-2.0.1 → agent_code-2.1.0}/README.md +2 -2
  3. {agent_code-2.0.1 → agent_code-2.1.0}/docs/skills.html +16 -5
  4. {agent_code-2.0.1 → agent_code-2.1.0}/pyproject.toml +1 -1
  5. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/__init__.py +1 -1
  6. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/addons.py +13 -5
  7. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/agent.py +449 -53
  8. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/loader.py +325 -216
  9. agent_code-2.1.0/src/agent_code/provider_compat.py +109 -0
  10. agent_code-2.1.0/src/agent_code/runtime.py +343 -0
  11. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/skill_manager.py +29 -1
  12. agent_code-2.1.0/src/agent_code/tool_namespace.py +142 -0
  13. agent_code-2.1.0/src/agent_code/tui.py +1261 -0
  14. {agent_code-2.0.1 → agent_code-2.1.0/src/agent_code.egg-info}/PKG-INFO +3 -3
  15. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code.egg-info/SOURCES.txt +8 -0
  16. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_addons.py +5 -4
  17. agent_code-2.1.0/tests/test_agent_loop_regex_scope.py +18 -0
  18. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_core_mode.py +1 -1
  19. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_doctor.py +1 -1
  20. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_plan_completion_signal.py +2 -2
  21. agent_code-2.1.0/tests/test_provider_metadata.py +67 -0
  22. agent_code-2.1.0/tests/test_runtime_guard.py +95 -0
  23. agent_code-2.1.0/tests/test_skill_namespacing.py +54 -0
  24. agent_code-2.1.0/tests/test_tool_namespace.py +37 -0
  25. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_tui_input_timeout.py +49 -0
  26. agent_code-2.1.0/tests/test_ui_crash_regressions.py +68 -0
  27. agent_code-2.0.1/src/agent_code/tui.py +0 -721
  28. agent_code-2.0.1/tests/test_ui_crash_regressions.py +0 -38
  29. {agent_code-2.0.1 → agent_code-2.1.0}/LICENSE +0 -0
  30. {agent_code-2.0.1 → agent_code-2.1.0}/MANIFEST.in +0 -0
  31. {agent_code-2.0.1 → agent_code-2.1.0}/docs/addons.html +0 -0
  32. {agent_code-2.0.1 → agent_code-2.1.0}/docs/index.html +0 -0
  33. {agent_code-2.0.1 → agent_code-2.1.0}/setup.cfg +0 -0
  34. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/__main__.py +0 -0
  35. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/advanced_features.py +0 -0
  36. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/cli.py +0 -0
  37. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/icons/agent-code.ico +0 -0
  38. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/icons/agent-code.png +0 -0
  39. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/skills/browser/skill.md +0 -0
  40. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/skills/browser/skill.py +0 -0
  41. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/skills/filesystem/skill.md +0 -0
  42. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/skills/filesystem/skill.py +0 -0
  43. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/skills/public_api/skill.md +0 -0
  44. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/skills/public_api/skill.py +0 -0
  45. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/skills/temp_mail/skill.md +0 -0
  46. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/data/skills/temp_mail/skill.py +0 -0
  47. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/doctor.py +0 -0
  48. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/mcp_manager.py +0 -0
  49. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/paths.py +0 -0
  50. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code/projects.py +0 -0
  51. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code.egg-info/dependency_links.txt +0 -0
  52. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code.egg-info/entry_points.txt +0 -0
  53. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code.egg-info/requires.txt +0 -0
  54. {agent_code-2.0.1 → agent_code-2.1.0}/src/agent_code.egg-info/top_level.txt +0 -0
  55. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_activity_labels.py +0 -0
  56. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_activity_visibility.py +0 -0
  57. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_advanced_features.py +0 -0
  58. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_api_key_routing.py +0 -0
  59. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_async_subagent_contract.py +0 -0
  60. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_browser_detection.py +0 -0
  61. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_chat_loading.py +0 -0
  62. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_composer_experience.py +0 -0
  63. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_cross_platform.py +0 -0
  64. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_global_paths.py +0 -0
  65. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_markdown_spacing.py +0 -0
  66. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_mcp_manager.py +0 -0
  67. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_new_project_creation.py +0 -0
  68. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_podman_error_compaction.py +0 -0
  69. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_podman_full_linux.py +0 -0
  70. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_provider_presets.py +0 -0
  71. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_research_and_model_picker.py +0 -0
  72. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_saved_provider_endpoint_dedup.py +0 -0
  73. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_secure_credential_storage.py +0 -0
  74. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_server_archive_safety.py +0 -0
  75. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_skill_command_dispatch.py +0 -0
  76. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_skill_store_auth_flow.py +0 -0
  77. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_skill_store_safety.py +0 -0
  78. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_skill_store_theme.py +0 -0
  79. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_ssh_quick_connect.py +0 -0
  80. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_three_click_force_stop.py +0 -0
  81. {agent_code-2.0.1 → agent_code-2.1.0}/tests/test_token_efficiency.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-code
3
- Version: 2.0.1
3
+ Version: 2.1.0
4
4
  Summary: Local AI agent with optional browser automation, sandboxed shell, and plug-and-play skills
5
5
  Author: minecraftbefile-maker
6
6
  License-Expression: MIT
@@ -38,7 +38,7 @@ Dynamic: license-file
38
38
 
39
39
  <p align="center">
40
40
  <img src="src/agent_code/data/icons/agent-code.png" width="145" alt="Agent Code Logo">
41
- </p><h1 align="center">Agent Code 2.0</h1><h3 align="center">⚡ Your AI coding agent. Your tools. Your environment.</h3><p align="center">
41
+ </p><h1 align="center">Agent Code 2.1</h1><h3 align="center">⚡ Your AI coding agent. Your tools. Your environment.</h3><p align="center">
42
42
  An open-source, extensible AI coding agent built with Python and CustomTkinter.
43
43
  <br>
44
44
  Build, modify, debug, and manage projects using AI — with customizable Skills, application Add-ons, and MCP integrations.
@@ -1035,7 +1035,7 @@ See:
1035
1035
 
1036
1036
  <p align="center">
1037
1037
  <img src="src/agent_code/data/icons/agent-code.png" width="65" alt="Agent Code">
1038
- </p><h2 align="center">⚡ Agent Code 2.0</h2><p align="center">
1038
+ </p><h2 align="center">⚡ Agent Code 2.1</h2><p align="center">
1039
1039
  <b>Your AI coding agent. Your tools. Your environment.</b>
1040
1040
  <br><br>
1041
1041
  <a href="https://github.com/agent-code-dev/agent-code">GitHub</a>
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
2
  <img src="src/agent_code/data/icons/agent-code.png" width="145" alt="Agent Code Logo">
3
- </p><h1 align="center">Agent Code 2.0</h1><h3 align="center">⚡ Your AI coding agent. Your tools. Your environment.</h3><p align="center">
3
+ </p><h1 align="center">Agent Code 2.1</h1><h3 align="center">⚡ Your AI coding agent. Your tools. Your environment.</h3><p align="center">
4
4
  An open-source, extensible AI coding agent built with Python and CustomTkinter.
5
5
  <br>
6
6
  Build, modify, debug, and manage projects using AI — with customizable Skills, application Add-ons, and MCP integrations.
@@ -997,7 +997,7 @@ See:
997
997
 
998
998
  <p align="center">
999
999
  <img src="src/agent_code/data/icons/agent-code.png" width="65" alt="Agent Code">
1000
- </p><h2 align="center">⚡ Agent Code 2.0</h2><p align="center">
1000
+ </p><h2 align="center">⚡ Agent Code 2.1</h2><p align="center">
1001
1001
  <b>Your AI coding agent. Your tools. Your environment.</b>
1002
1002
  <br><br>
1003
1003
  <a href="https://github.com/agent-code-dev/agent-code">GitHub</a>
@@ -18,7 +18,7 @@ def greet(name: str = "there") -> str:
18
18
  TOOL_SCHEMAS = [{
19
19
  "type": "function",
20
20
  "function": {
21
- "name": "hello_world_greet",
21
+ "name": "greet",
22
22
  "description": "Greet a person by name.",
23
23
  "parameters": {
24
24
  "type": "object",
@@ -31,9 +31,9 @@ TOOL_SCHEMAS = [{
31
31
  }]
32
32
 
33
33
  TOOL_CALLABLES = {
34
- "hello_world_greet": greet,
34
+ "greet": greet,
35
35
  }</code></pre>
36
- <h2>4. Schema and callable rules</h2><ul><li>Every <code>function.name</code> must exactly match a key in <code>TOOL_CALLABLES</code>.</li><li>Use unique tool names across all enabled Skills and Add-ons.</li><li>Use JSON Schema types supported by your provider (string, number, integer, boolean, object, array).</li><li>Validate arguments inside the Python function too; model-provided JSON is untrusted input.</li><li>Return concise, useful text or JSON-serializable values.</li><li>Catch expected errors and return a helpful error message rather than crashing the loader.</li></ul>
36
+ <h2>4. Schema and callable rules</h2><ul><li>Every <code>function.name</code> must exactly match a key in <code>TOOL_CALLABLES</code>.</li><li>Use short local names. Agent Code automatically prefixes each tool with its source namespace (for example <code>filesystem_write_file</code>); identical local names in different Skills are safe.</li><li>Use JSON Schema types supported by your provider (string, number, integer, boolean, object, array).</li><li>Validate arguments inside the Python function too; model-provided JSON is untrusted input.</li><li>Return concise, useful text or JSON-serializable values.</li><li>Catch expected errors and return a helpful error message rather than crashing the loader.</li></ul>
37
37
  <h2>5. Optional commands</h2><pre><code>def configure(args, log):
38
38
  # args is a list of words after the command.
39
39
  log("Configuration command received", "dim")
@@ -59,5 +59,16 @@ Use this skill to greet a person by name.</code></pre><p>The text after the YAML
59
59
  <h2>8. Package and share a Skill</h2><pre><code>cd ~/.local/share/agent-code/skills
60
60
  zip -r hello_world-1.0.0.zip hello_world \
61
61
  -x '*/__pycache__/*' '*.pyc'</code></pre><p>Include only the skill folder, documentation and required assets. Document external dependencies and installation steps. Do not include API keys, tokens, personal data, virtual environments or caches.</p>
62
- <h2>9. Security and runtime</h2><div class="note"><strong>Important:</strong> Skills are imported as Python modules by the local Agent Code process. Their code runs with the current user's operating-system permissions. The shell Podman sandbox does not automatically sandbox Skill Python code. A Skill that needs remote execution must implement that transport itself and clearly identify where its code and data run.</div><ul><li>Never use <code>eval</code> or <code>exec</code> on model-supplied strings.</li><li>Validate file paths and restrict operations to the intended workspace.</li><li>Keep secrets in the OS credential store or user configuration, not in the skill source.</li><li>Use network timeouts and bounded retries.</li><li>Explain what data is sent to external services.</li><li>Review dependencies and pin versions where practical.</li></ul>
63
- <h2>10. Current contract boundaries</h2><p>Native Skills support <code>SKILL</code>, <code>TOOL_SCHEMAS</code>, <code>TOOL_CALLABLES</code>, optional <code>COMMANDS</code>, and optional <code>HELP</code>. This guide documents the loader contract implemented in this release; it does not promise an automatic dependency installer or per-Skill Local/Sandbox/SSH routing.</p><p><a href="addons.html">Next: Build an Add-on →</a></p></main><footer><a href="index.html">Agent Code docs home</a></footer></body></html>
62
+ <h2>9. Execution environments</h2><p>Set the execution target in the <code>SKILL</code> metadata. The default is <code>host</code>. Per-tool overrides in <code>execution.tools</code> may select different remote targets (Sandbox/SSH), but mixing Host and remote tools in one Skill is rejected so remote-only code is never imported on Host. Remote Skills must define literal <code>SKILL</code> and <code>TOOL_SCHEMAS</code> data. Agent Code routes each call to the declared environment and never silently falls back to Host when a requested environment is unavailable.</p><pre><code>SKILL = {
63
+ "name": "desktop_tools",
64
+ "description": "Desktop automation tools",
65
+ "execution": {
66
+ "target": "host",
67
+ "allowed": ["host"],
68
+ "tools": {
69
+ "inspect_remote": {"target": "ssh"}
70
+ },
71
+ "ssh_workspace": "/srv/project"
72
+ }
73
+ }</code></pre><ul><li><code>host</code>: runs in the Agent Code process; use for desktop APIs and local GUI automation.</li><li><code>sandbox</code>: runs inside the managed Alpine Podman container. The Skills directory is mounted read-only. The container must be recreated once to gain this mount.</li><li><code>ssh</code>: transfers a bounded temporary Skill snapshot over the established SSH connection, executes it remotely, then removes the temporary files.</li><li><code>auto</code>: uses the configured default target and still obeys the Skill's <code>allowed</code> list.</li></ul><div class="note"><strong>Important:</strong> Host is the default. Select the narrowest environment required. Sandbox/SSH failures are fail-closed; Agent Code does not rerun a Skill on the Host to hide an environment error.</div><ul><li>Never use <code>eval</code> or <code>exec</code> on model-supplied strings.</li><li>Validate file paths and restrict operations to the intended workspace.</li><li>Keep secrets in the OS credential store or user configuration, not in the skill source.</li><li>Use network timeouts and bounded retries.</li><li>Explain what data is sent to external services.</li><li>Review dependencies and pin versions where practical.</li></ul>
74
+ <h2>10. Current contract boundaries</h2><p>Native Skills support <code>SKILL</code>, <code>TOOL_SCHEMAS</code>, <code>TOOL_CALLABLES</code>, optional <code>COMMANDS</code>, and optional <code>HELP</code>. Tool names are registered through the global Unified Tool Namespace alongside Core, MCP and Add-on tools. Agent Code does not automatically install Skill dependencies; declare and document them.</p><p><a href="addons.html">Next: Build an Add-on →</a></p></main><footer><a href="index.html">Agent Code docs home</a></footer></body></html>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "agent-code"
7
- version = "2.0.1"
7
+ version = "2.1.0"
8
8
  description = "Local AI agent with optional browser automation, sandboxed shell, and plug-and-play skills"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,2 +1,2 @@
1
1
  """Agent + Skill Store — local AI agent with headless browser and skills."""
2
- __version__ = "2.0.1"
2
+ __version__ = "2.1.0"
@@ -11,6 +11,7 @@ import json
11
11
  import re
12
12
  import sys
13
13
  import traceback
14
+ from .tool_namespace import make_tool_name
14
15
  from dataclasses import dataclass, field
15
16
  from pathlib import Path
16
17
  from typing import Any, Callable
@@ -114,6 +115,7 @@ class AddonManager:
114
115
  self.apis: list[AddonAPI] = []
115
116
  self.schemas: list[dict] = []
116
117
  self.callables: dict[str, Callable] = {}
118
+ self.tool_identities: dict[str, dict] = {}
117
119
  self.commands: dict[str, dict] = {}
118
120
  self.actions: list[dict] = []
119
121
  self.ui_contributions: list[dict] = []
@@ -145,7 +147,7 @@ class AddonManager:
145
147
  return found
146
148
 
147
149
  def load(self):
148
- self.apis.clear(); self.schemas.clear(); self.callables.clear()
150
+ self.apis.clear(); self.schemas.clear(); self.callables.clear(); self.tool_identities.clear()
149
151
  self.commands.clear(); self.actions.clear(); self.ui_contributions.clear()
150
152
  self.services.clear(); self._loaded_modules.clear()
151
153
  for info in self.discover():
@@ -169,11 +171,17 @@ class AddonManager:
169
171
  if not callable(register):
170
172
  raise TypeError("addon.py must export register(api)")
171
173
  register(api)
174
+ used_names = set(self.callables)
172
175
  for schema, handler in api.tools:
173
- name = schema["function"]["name"]
174
- if name in self.callables:
175
- raise ValueError(f"duplicate add-on tool name: {name}")
176
- self.schemas.append(schema); self.callables[name] = handler
176
+ original = schema["function"]["name"]
177
+ name = make_tool_name(info.name, original, used_names)
178
+ normalized = dict(schema)
179
+ normalized["function"] = {**schema["function"], "name": name}
180
+ self.schemas.append(normalized)
181
+ self.callables[name] = handler
182
+ self.tool_identities[name] = {"namespace": info.name,
183
+ "original_name": original,
184
+ "source_type": "addon"}
177
185
  for name, definition in api.commands.items():
178
186
  if name in self.commands:
179
187
  raise ValueError(f"duplicate add-on command: {name}")