gemcode 0.3.67__tar.gz → 0.3.68__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 (127) hide show
  1. {gemcode-0.3.67/src/gemcode.egg-info → gemcode-0.3.68}/PKG-INFO +1 -1
  2. {gemcode-0.3.67 → gemcode-0.3.68}/pyproject.toml +1 -1
  3. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/callbacks.py +19 -0
  4. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/config.py +10 -0
  5. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/dynamic_policy.py +50 -24
  6. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/invoke.py +26 -0
  7. {gemcode-0.3.67 → gemcode-0.3.68/src/gemcode.egg-info}/PKG-INFO +1 -1
  8. {gemcode-0.3.67 → gemcode-0.3.68}/LICENSE +0 -0
  9. {gemcode-0.3.67 → gemcode-0.3.68}/MANIFEST.in +0 -0
  10. {gemcode-0.3.67 → gemcode-0.3.68}/README.md +0 -0
  11. {gemcode-0.3.67 → gemcode-0.3.68}/setup.cfg +0 -0
  12. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/__init__.py +0 -0
  13. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/__main__.py +0 -0
  14. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/agent.py +0 -0
  15. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/audit.py +0 -0
  16. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/autocompact.py +0 -0
  17. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/capability_routing.py +0 -0
  18. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/cli.py +0 -0
  19. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/compaction.py +0 -0
  20. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/computer_use/__init__.py +0 -0
  21. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/computer_use/browser_computer.py +0 -0
  22. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/context_budget.py +0 -0
  23. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/context_warning.py +0 -0
  24. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/credentials.py +0 -0
  25. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/hitl_session.py +0 -0
  26. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/hooks.py +0 -0
  27. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/intent_classifier.py +0 -0
  28. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/interactions.py +0 -0
  29. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/kairos_daemon.py +0 -0
  30. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/limits.py +0 -0
  31. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/live_audio_engine.py +0 -0
  32. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/logging_config.py +0 -0
  33. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/mcp_loader.py +0 -0
  34. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/memory/__init__.py +0 -0
  35. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/memory/embedding_memory_service.py +0 -0
  36. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/memory/file_memory_service.py +0 -0
  37. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/modality_tools.py +0 -0
  38. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/model_errors.py +0 -0
  39. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/model_routing.py +0 -0
  40. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/openapi_loader.py +0 -0
  41. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/paths.py +0 -0
  42. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/permissions.py +0 -0
  43. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/plugins/__init__.py +0 -0
  44. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
  45. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
  46. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/pricing.py +0 -0
  47. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/prompt_suggestions.py +0 -0
  48. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/query/__init__.py +0 -0
  49. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/query/config.py +0 -0
  50. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/query/deps.py +0 -0
  51. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/query/engine.py +0 -0
  52. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/query/stop_hooks.py +0 -0
  53. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/query/token_budget.py +0 -0
  54. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/query/transitions.py +0 -0
  55. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/refine.py +0 -0
  56. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/repl_commands.py +0 -0
  57. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/repl_slash.py +0 -0
  58. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/review_agent.py +0 -0
  59. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/session_runtime.py +0 -0
  60. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/session_store.py +0 -0
  61. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/slash_commands.py +0 -0
  62. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/thinking.py +0 -0
  63. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tool_prompt_manifest.py +0 -0
  64. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tool_registry.py +0 -0
  65. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tool_result_store.py +0 -0
  66. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/__init__.py +0 -0
  67. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/bash.py +0 -0
  68. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/browser.py +0 -0
  69. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/edit.py +0 -0
  70. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/filesystem.py +0 -0
  71. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/notebook.py +0 -0
  72. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/notes.py +0 -0
  73. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/repo_map.py +0 -0
  74. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/search.py +0 -0
  75. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/shell.py +0 -0
  76. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/shell_gate.py +0 -0
  77. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/subtask.py +0 -0
  78. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/tasks.py +0 -0
  79. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/think.py +0 -0
  80. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/todo.py +0 -0
  81. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/web.py +0 -0
  82. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools/web_search.py +0 -0
  83. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tools_inspector.py +0 -0
  84. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/trust.py +0 -0
  85. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tui/input_handler.py +0 -0
  86. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tui/scrollback.py +0 -0
  87. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tui/spinner.py +0 -0
  88. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tui/welcome_banner.py +0 -0
  89. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/tui/welcome_rich.py +0 -0
  90. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/version.py +0 -0
  91. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/vertex.py +0 -0
  92. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/web/__init__.py +0 -0
  93. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/web/claude_sse_adapter.py +0 -0
  94. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/web/terminal_repl.py +0 -0
  95. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode/workspace_hints.py +0 -0
  96. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode.egg-info/SOURCES.txt +0 -0
  97. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode.egg-info/dependency_links.txt +0 -0
  98. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode.egg-info/entry_points.txt +0 -0
  99. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode.egg-info/requires.txt +0 -0
  100. {gemcode-0.3.67 → gemcode-0.3.68}/src/gemcode.egg-info/top_level.txt +0 -0
  101. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_agent_instruction.py +0 -0
  102. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_autocompact.py +0 -0
  103. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_capability_routing.py +0 -0
  104. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_claude_web_adapter_sse.py +0 -0
  105. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_cli_init.py +0 -0
  106. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_computer_use_permissions.py +0 -0
  107. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_context_budget.py +0 -0
  108. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_context_warning.py +0 -0
  109. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_credentials.py +0 -0
  110. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_interactive_permission_ask.py +0 -0
  111. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_kairos_scheduler.py +0 -0
  112. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_modality_tools.py +0 -0
  113. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_model_error_retry.py +0 -0
  114. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_model_errors.py +0 -0
  115. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_model_routing.py +0 -0
  116. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_paths.py +0 -0
  117. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_permissions.py +0 -0
  118. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_prompt_suggestions.py +0 -0
  119. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_repl_commands.py +0 -0
  120. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_repl_slash.py +0 -0
  121. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_slash_commands.py +0 -0
  122. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_thinking_config.py +0 -0
  123. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_token_budget.py +0 -0
  124. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_tool_context_circulation.py +0 -0
  125. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_tools.py +0 -0
  126. {gemcode-0.3.67 → gemcode-0.3.68}/tests/test_tools_inspector.py +0 -0
  127. {gemcode-0.3.67 → gemcode-0.3.68}/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.67
3
+ Version: 0.3.68
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.67"
7
+ version = "0.3.68"
8
8
  description = "Local-first coding agent on Google Gemini + ADK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -384,6 +384,25 @@ def make_after_tool_callback(cfg: GemCodeConfig):
384
384
  st[_STATE_FAILURE_KEY] = 0
385
385
  else:
386
386
  st[_STATE_FAILURE_KEY] = 0
387
+
388
+ # Risk feedback: if tools are failing or commands return non-zero, treat the
389
+ # task as higher-risk and allow more evidence in subsequent tool outputs.
390
+ try:
391
+ cur = float(getattr(cfg, "_risk_score", 0.0) or 0.0)
392
+ bump = 0.0
393
+ if err:
394
+ bump += 0.15
395
+ if isinstance(tool_response, dict) and isinstance(tool_response.get("exit_code"), int):
396
+ if int(tool_response["exit_code"]) != 0:
397
+ bump += 0.10
398
+ # decay slowly when things are healthy
399
+ if bump == 0.0:
400
+ cur = max(0.0, cur * 0.90)
401
+ else:
402
+ cur = min(1.0, cur + bump)
403
+ object.__setattr__(cfg, "_risk_score", cur)
404
+ except Exception:
405
+ pass
387
406
  # ── Shell hooks: post_tool_use ────────────────────────────────────────
388
407
  try:
389
408
  from gemcode.hooks import run_post_tool_use_hook
@@ -143,6 +143,16 @@ class GemCodeConfig:
143
143
  dynamic_token_policy: bool = field(
144
144
  default_factory=lambda: _truthy_env("GEMCODE_DYNAMIC_TOKEN_POLICY", default=True)
145
145
  )
146
+
147
+ # Dynamic risk policy: boosts caps when the current task appears risky/complex.
148
+ dynamic_risk_policy: bool = field(
149
+ default_factory=lambda: _truthy_env("GEMCODE_DYNAMIC_RISK_POLICY", default=True)
150
+ )
151
+
152
+ # How much the risk score can expand caps (0.0-1.5 reasonable).
153
+ dynamic_risk_boost: float = field(
154
+ default_factory=lambda: float(os.environ.get("GEMCODE_DYNAMIC_RISK_BOOST", "0.6"))
155
+ )
146
156
  # Trim oldest text in llm_request.contents when over budget (see context_budget.py).
147
157
  context_shrink_enabled: bool = field(
148
158
  default_factory=lambda: _truthy_env("GEMCODE_CONTEXT_SHRINK", default=True)
@@ -32,6 +32,20 @@ def _pct_left(cfg) -> int | None:
32
32
  return None
33
33
 
34
34
 
35
+ def _risk(cfg) -> float:
36
+ try:
37
+ v = getattr(cfg, "_risk_score", None)
38
+ if isinstance(v, (int, float)):
39
+ return float(v)
40
+ except Exception:
41
+ return 0.0
42
+ return 0.0
43
+
44
+
45
+ def _clamp(x: float, lo: float, hi: float) -> float:
46
+ return lo if x < lo else hi if x > hi else x
47
+
48
+
35
49
  @dataclass(frozen=True)
36
50
  class DynamicCaps:
37
51
  tool_inline_chars: int
@@ -52,6 +66,8 @@ def get_dynamic_caps(cfg) -> DynamicCaps:
52
66
  - Healthy (>=45% left): generous caps (better evidence, less re-asking).
53
67
  - Warning (20-44%): moderate caps.
54
68
  - Tight (<20%): strict caps + prefer offload.
69
+
70
+ Then apply a risk-based boost (if enabled) so complex tasks stay evidence-rich.
55
71
  """
56
72
  # cfg can be None in some tool contexts; treat as enabled with defaults.
57
73
  enabled = _truthy(getattr(cfg, "dynamic_token_policy", True) if cfg is not None else True, default=True)
@@ -76,42 +92,52 @@ def get_dynamic_caps(cfg) -> DynamicCaps:
76
92
  base_tool = int(getattr(cfg, "tool_result_max_chars", 12000) or 12000) if cfg is not None else 12000
77
93
  base_tool = max(1000, base_tool)
78
94
 
95
+ # Risk boost: scale caps upward for risky tasks, but keep bounded.
96
+ risk_enabled = _truthy(getattr(cfg, "dynamic_risk_policy", True) if cfg is not None else True, default=True)
97
+ risk_boost = float(getattr(cfg, "dynamic_risk_boost", 0.6) if cfg is not None else 0.6)
98
+ risk_score = _risk(cfg) if (cfg is not None and risk_enabled) else 0.0
99
+ risk_score = _clamp(risk_score, 0.0, 1.0)
100
+ boost = 1.0 + (_clamp(risk_boost, 0.0, 1.5) * risk_score)
101
+
102
+ def _scale(n: int, *, cap: int) -> int:
103
+ return min(cap, max(1000, int(n * boost)))
104
+
79
105
  if pct >= 45:
80
106
  mult = 1.4
81
107
  return DynamicCaps(
82
- tool_inline_chars=min(24_000, int(base_tool * mult)),
83
- read_file_max_bytes=140_000,
84
- web_fetch_max_chars=30_000,
85
- bash_stdout_chars=30_000,
86
- bash_stderr_chars=15_000,
87
- run_stdout_chars=30_000,
88
- run_stderr_chars=30_000,
89
- grep_max_matches=60,
108
+ tool_inline_chars=_scale(min(24_000, int(base_tool * mult)), cap=30_000),
109
+ read_file_max_bytes=min(200_000, int(140_000 * boost)),
110
+ web_fetch_max_chars=min(60_000, int(30_000 * boost)),
111
+ bash_stdout_chars=min(80_000, int(30_000 * boost)),
112
+ bash_stderr_chars=min(40_000, int(15_000 * boost)),
113
+ run_stdout_chars=min(80_000, int(30_000 * boost)),
114
+ run_stderr_chars=min(80_000, int(30_000 * boost)),
115
+ grep_max_matches=min(200, int(60 * boost)),
90
116
  )
91
117
 
92
118
  if pct >= 20:
93
119
  mult = 1.0
94
120
  return DynamicCaps(
95
- tool_inline_chars=min(18_000, int(base_tool * mult)),
96
- read_file_max_bytes=80_000,
97
- web_fetch_max_chars=20_000,
98
- bash_stdout_chars=20_000,
99
- bash_stderr_chars=10_000,
100
- run_stdout_chars=20_000,
101
- run_stderr_chars=20_000,
102
- grep_max_matches=40,
121
+ tool_inline_chars=_scale(min(18_000, int(base_tool * mult)), cap=24_000),
122
+ read_file_max_bytes=min(160_000, int(80_000 * boost)),
123
+ web_fetch_max_chars=min(40_000, int(20_000 * boost)),
124
+ bash_stdout_chars=min(50_000, int(20_000 * boost)),
125
+ bash_stderr_chars=min(30_000, int(10_000 * boost)),
126
+ run_stdout_chars=min(50_000, int(20_000 * boost)),
127
+ run_stderr_chars=min(50_000, int(20_000 * boost)),
128
+ grep_max_matches=min(120, int(40 * boost)),
103
129
  )
104
130
 
105
131
  # Tight
106
132
  mult = 0.6
107
133
  return DynamicCaps(
108
- tool_inline_chars=max(2000, int(base_tool * mult)),
109
- read_file_max_bytes=35_000,
110
- web_fetch_max_chars=10_000,
111
- bash_stdout_chars=10_000,
112
- bash_stderr_chars=8_000,
113
- run_stdout_chars=10_000,
114
- run_stderr_chars=10_000,
115
- grep_max_matches=20,
134
+ tool_inline_chars=max(2000, min(12_000, int(base_tool * mult * boost))),
135
+ read_file_max_bytes=min(90_000, int(35_000 * boost)),
136
+ web_fetch_max_chars=min(20_000, int(10_000 * boost)),
137
+ bash_stdout_chars=min(25_000, int(10_000 * boost)),
138
+ bash_stderr_chars=min(20_000, int(8_000 * boost)),
139
+ run_stdout_chars=min(25_000, int(10_000 * boost)),
140
+ run_stderr_chars=min(25_000, int(10_000 * boost)),
141
+ grep_max_matches=min(80, int(20 * boost)),
116
142
  )
117
143
 
@@ -68,6 +68,32 @@ async def run_turn(
68
68
  cfg: "GemCodeConfig | None" = None,
69
69
  ) -> list:
70
70
  """Execute one user message; collect all Events (caller aggregates text)."""
71
+ # Dynamic risk score: updated each user message; later refined by tool outcomes.
72
+ # This is intentionally heuristic but configurable via env knobs.
73
+ if cfg is not None:
74
+ try:
75
+ import re
76
+ p = (prompt or "")[:20_000]
77
+ risk = 0.0
78
+ # Complexity signals
79
+ if len(p) > 600:
80
+ risk += 0.15
81
+ if len(p) > 2000:
82
+ risk += 0.15
83
+ if re.search(r"\\b(refactor|migrate|rewrite|optimi[sz]e|architecture)\\b", p, re.I):
84
+ risk += 0.2
85
+ if re.search(r"\\b(bug|fix|regression|error|traceback|failing)\\b", p, re.I):
86
+ risk += 0.2
87
+ if re.search(r"\\b(test|pytest|ci|build|deploy|release)\\b", p, re.I):
88
+ risk += 0.1
89
+ # Multi-file hints
90
+ if p.count(\"/\") >= 6 or p.count(\".py\") + p.count(\".ts\") + p.count(\".tsx\") >= 3:
91
+ risk += 0.1
92
+ # Clamp 0..1
93
+ risk = max(0.0, min(1.0, float(risk)))
94
+ object.__setattr__(cfg, \"_risk_score\", risk)
95
+ except Exception:
96
+ pass
71
97
  run_config = (
72
98
  RunConfig(max_llm_calls=max_llm_calls) if max_llm_calls is not None else None
73
99
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.67
3
+ Version: 0.3.68
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