gemcode 0.3.55__tar.gz → 0.3.57__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 (121) hide show
  1. {gemcode-0.3.55/src/gemcode.egg-info → gemcode-0.3.57}/PKG-INFO +1 -1
  2. {gemcode-0.3.55 → gemcode-0.3.57}/pyproject.toml +1 -1
  3. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/capability_routing.py +4 -0
  4. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/repl_slash.py +15 -0
  5. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/session_runtime.py +34 -3
  6. {gemcode-0.3.55 → gemcode-0.3.57/src/gemcode.egg-info}/PKG-INFO +1 -1
  7. {gemcode-0.3.55 → gemcode-0.3.57}/LICENSE +0 -0
  8. {gemcode-0.3.55 → gemcode-0.3.57}/MANIFEST.in +0 -0
  9. {gemcode-0.3.55 → gemcode-0.3.57}/README.md +0 -0
  10. {gemcode-0.3.55 → gemcode-0.3.57}/setup.cfg +0 -0
  11. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/__init__.py +0 -0
  12. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/__main__.py +0 -0
  13. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/agent.py +0 -0
  14. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/audit.py +0 -0
  15. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/autocompact.py +0 -0
  16. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/callbacks.py +0 -0
  17. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/cli.py +0 -0
  18. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/compaction.py +0 -0
  19. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/computer_use/__init__.py +0 -0
  20. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/computer_use/browser_computer.py +0 -0
  21. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/config.py +0 -0
  22. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/context_budget.py +0 -0
  23. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/context_warning.py +0 -0
  24. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/credentials.py +0 -0
  25. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/hitl_session.py +0 -0
  26. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/hooks.py +0 -0
  27. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/intent_classifier.py +0 -0
  28. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/interactions.py +0 -0
  29. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/invoke.py +0 -0
  30. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/kairos_daemon.py +0 -0
  31. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/limits.py +0 -0
  32. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/live_audio_engine.py +0 -0
  33. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/logging_config.py +0 -0
  34. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/mcp_loader.py +0 -0
  35. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/memory/__init__.py +0 -0
  36. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/memory/embedding_memory_service.py +0 -0
  37. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/memory/file_memory_service.py +0 -0
  38. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/modality_tools.py +0 -0
  39. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/model_errors.py +0 -0
  40. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/model_routing.py +0 -0
  41. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/openapi_loader.py +0 -0
  42. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/paths.py +0 -0
  43. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/permissions.py +0 -0
  44. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/plugins/__init__.py +0 -0
  45. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
  46. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
  47. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/pricing.py +0 -0
  48. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/prompt_suggestions.py +0 -0
  49. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/query/__init__.py +0 -0
  50. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/query/config.py +0 -0
  51. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/query/deps.py +0 -0
  52. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/query/engine.py +0 -0
  53. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/query/stop_hooks.py +0 -0
  54. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/query/token_budget.py +0 -0
  55. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/query/transitions.py +0 -0
  56. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/refine.py +0 -0
  57. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/repl_commands.py +0 -0
  58. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/review_agent.py +0 -0
  59. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/session_store.py +0 -0
  60. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/slash_commands.py +0 -0
  61. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/thinking.py +0 -0
  62. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tool_prompt_manifest.py +0 -0
  63. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tool_registry.py +0 -0
  64. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/__init__.py +0 -0
  65. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/bash.py +0 -0
  66. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/browser.py +0 -0
  67. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/edit.py +0 -0
  68. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/filesystem.py +0 -0
  69. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/notes.py +0 -0
  70. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/search.py +0 -0
  71. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/shell.py +0 -0
  72. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/shell_gate.py +0 -0
  73. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/subtask.py +0 -0
  74. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/think.py +0 -0
  75. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/todo.py +0 -0
  76. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools/web.py +0 -0
  77. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tools_inspector.py +0 -0
  78. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/trust.py +0 -0
  79. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tui/input_handler.py +0 -0
  80. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tui/scrollback.py +0 -0
  81. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tui/spinner.py +0 -0
  82. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tui/welcome_banner.py +0 -0
  83. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/tui/welcome_rich.py +0 -0
  84. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/version.py +0 -0
  85. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/vertex.py +0 -0
  86. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/web/__init__.py +0 -0
  87. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/web/claude_sse_adapter.py +0 -0
  88. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/web/terminal_repl.py +0 -0
  89. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode/workspace_hints.py +0 -0
  90. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode.egg-info/SOURCES.txt +0 -0
  91. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode.egg-info/dependency_links.txt +0 -0
  92. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode.egg-info/entry_points.txt +0 -0
  93. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode.egg-info/requires.txt +0 -0
  94. {gemcode-0.3.55 → gemcode-0.3.57}/src/gemcode.egg-info/top_level.txt +0 -0
  95. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_agent_instruction.py +0 -0
  96. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_autocompact.py +0 -0
  97. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_capability_routing.py +0 -0
  98. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_claude_web_adapter_sse.py +0 -0
  99. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_cli_init.py +0 -0
  100. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_computer_use_permissions.py +0 -0
  101. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_context_budget.py +0 -0
  102. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_context_warning.py +0 -0
  103. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_credentials.py +0 -0
  104. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_interactive_permission_ask.py +0 -0
  105. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_kairos_scheduler.py +0 -0
  106. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_modality_tools.py +0 -0
  107. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_model_error_retry.py +0 -0
  108. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_model_errors.py +0 -0
  109. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_model_routing.py +0 -0
  110. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_paths.py +0 -0
  111. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_permissions.py +0 -0
  112. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_prompt_suggestions.py +0 -0
  113. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_repl_commands.py +0 -0
  114. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_repl_slash.py +0 -0
  115. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_slash_commands.py +0 -0
  116. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_thinking_config.py +0 -0
  117. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_token_budget.py +0 -0
  118. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_tool_context_circulation.py +0 -0
  119. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_tools.py +0 -0
  120. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_tools_inspector.py +0 -0
  121. {gemcode-0.3.55 → gemcode-0.3.57}/tests/test_workspace_hints.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.55
3
+ Version: 0.3.57
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gemcode"
7
- version = "0.3.55"
7
+ version = "0.3.57"
8
8
  description = "Local-first coding agent on Google Gemini + ADK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -94,6 +94,10 @@ def apply_capability_routing(
94
94
  cfg.enable_embeddings = True
95
95
 
96
96
  def enable_computer() -> None:
97
+ # Respect session-level unavailability (e.g. Playwright not installed).
98
+ # When computer-use is known-broken, auto-routing must not re-enable it.
99
+ if getattr(cfg, "_computer_use_available", True) is False:
100
+ return
97
101
  cfg.enable_computer_use = True
98
102
 
99
103
  def enable_audio() -> None:
@@ -696,6 +696,15 @@ async def process_repl_slash(
696
696
  return ReplSlashResult(skip_model_turn=True)
697
697
 
698
698
  if args_s == "on":
699
+ # If the session has already determined computer-use is unavailable
700
+ # (Playwright missing), do not allow re-enabling without installing it
701
+ # and restarting the process.
702
+ if getattr(cfg, "_computer_use_available", True) is False:
703
+ out("computer_use: unavailable — Playwright browsers are not installed")
704
+ out("Run: python3 -m playwright install chromium")
705
+ out("Then restart GemCode and run: /computer on")
706
+ out()
707
+ return ReplSlashResult(skip_model_turn=True)
699
708
  cfg.enable_computer_use = True
700
709
  out("computer_use: on — Playwright Chromium browser automation enabled")
701
710
  out(" Runner will rebuild on the next turn to inject browser tools.")
@@ -911,6 +920,12 @@ async def process_repl_slash(
911
920
  out()
912
921
  return ReplSlashResult(skip_model_turn=True, force_rebuild_runner=True)
913
922
  if args_s in ("computer", "browser"):
923
+ if getattr(cfg, "_computer_use_available", True) is False:
924
+ out("enable_computer_use: unavailable — Playwright browsers are not installed")
925
+ out("Run: python3 -m playwright install chromium")
926
+ out("Then restart GemCode and re-enable computer-use.")
927
+ out()
928
+ return ReplSlashResult(skip_model_turn=True)
914
929
  cfg.enable_computer_use = True
915
930
  out("enable_computer_use: on (runner rebuilding…)")
916
931
  out("Tip: set GEMCODE_COMPUTER_HEADLESS=0 before starting gemcode to see the browser window.")
@@ -47,14 +47,37 @@ def _playwright_available() -> bool:
47
47
  This is called before building the runner so we can disable computer-use
48
48
  early and prevent model routing from switching to gemini-2.5-computer-use-*.
49
49
  """
50
+ # 1) Preferred: ask Playwright for the resolved executable path.
51
+ # This can fail in some environment-mismatch cases (package installed but driver
52
+ # cannot start), so we also do a cache-based probe below.
50
53
  try:
51
54
  from playwright.sync_api import sync_playwright
52
55
  with sync_playwright() as p:
53
- exe = p.chromium.executable_path
54
- return bool(exe) and Path(exe).exists()
56
+ exe = getattr(p.chromium, "executable_path", None)
57
+ if exe and Path(str(exe)).exists():
58
+ return True
55
59
  except Exception:
56
60
  pass
57
- # playwright not installed at all
61
+
62
+ # 2) Fallback: check the default browser cache directly.
63
+ # This avoids false negatives when Playwright import/driver resolution is flaky,
64
+ # but browsers are present (common on macOS with mixed --user/system installs).
65
+ try:
66
+ cache_root = Path.home() / "Library" / "Caches" / "ms-playwright"
67
+ if not cache_root.exists():
68
+ return False
69
+ # macOS paths (Chromium.app or "Google Chrome for Testing.app")
70
+ mac_bins = list(cache_root.glob("chromium-*/*/Chromium.app/Contents/MacOS/Chromium"))
71
+ mac_bins += list(
72
+ cache_root.glob(
73
+ "chromium-*/*/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing"
74
+ )
75
+ )
76
+ if any(p.exists() for p in mac_bins):
77
+ return True
78
+ except Exception:
79
+ pass
80
+
58
81
  return False
59
82
 
60
83
 
@@ -228,6 +251,14 @@ def create_runner(cfg: GemCodeConfig, extra_tools: list | None = None) -> Runner
228
251
  # Disable so model_routing stays on the normal model (not computer-use preview).
229
252
  cfg.enable_computer_use = False
230
253
  cfg._computer_use_available = False # type: ignore[attr-defined]
254
+ # If the TUI already routed the model to the computer-use preview model for
255
+ # this turn, reset back to the normal model so the next agent construction
256
+ # doesn't keep using a model that requires the missing tool.
257
+ try:
258
+ if not getattr(cfg, "model_overridden", False) and cfg.model == cfg.model_computer_use:
259
+ cfg.model = os.environ.get("GEMCODE_MODEL", "gemini-3.1-pro-preview")
260
+ except Exception:
261
+ pass
231
262
  else:
232
263
  cfg._computer_use_available = True # type: ignore[attr-defined]
233
264
  headless_env = os.environ.get("GEMCODE_COMPUTER_HEADLESS", "1").lower()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.55
3
+ Version: 0.3.57
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
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