gemcode 0.3.71__tar.gz → 0.3.73__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 (128) hide show
  1. {gemcode-0.3.71/src/gemcode.egg-info → gemcode-0.3.73}/PKG-INFO +6 -1
  2. {gemcode-0.3.71 → gemcode-0.3.73}/README.md +5 -0
  3. {gemcode-0.3.71 → gemcode-0.3.73}/pyproject.toml +1 -1
  4. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/agent.py +39 -1
  5. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/config.py +25 -0
  6. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/invoke.py +2 -2
  7. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/repl_slash.py +8 -0
  8. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/session_runtime.py +28 -0
  9. {gemcode-0.3.71 → gemcode-0.3.73/src/gemcode.egg-info}/PKG-INFO +6 -1
  10. {gemcode-0.3.71 → gemcode-0.3.73}/LICENSE +0 -0
  11. {gemcode-0.3.71 → gemcode-0.3.73}/MANIFEST.in +0 -0
  12. {gemcode-0.3.71 → gemcode-0.3.73}/setup.cfg +0 -0
  13. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/__init__.py +0 -0
  14. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/__main__.py +0 -0
  15. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/audit.py +0 -0
  16. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/autocompact.py +0 -0
  17. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/callbacks.py +0 -0
  18. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/capability_routing.py +0 -0
  19. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/cli.py +0 -0
  20. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/compaction.py +0 -0
  21. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/computer_use/__init__.py +0 -0
  22. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/computer_use/browser_computer.py +0 -0
  23. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/context_budget.py +0 -0
  24. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/context_warning.py +0 -0
  25. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/credentials.py +0 -0
  26. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/dynamic_policy.py +0 -0
  27. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/hitl_session.py +0 -0
  28. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/hooks.py +0 -0
  29. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/intent_classifier.py +0 -0
  30. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/interactions.py +0 -0
  31. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/kairos_daemon.py +0 -0
  32. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/limits.py +0 -0
  33. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/live_audio_engine.py +0 -0
  34. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/logging_config.py +0 -0
  35. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/mcp_loader.py +0 -0
  36. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/memory/__init__.py +0 -0
  37. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/memory/embedding_memory_service.py +0 -0
  38. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/memory/file_memory_service.py +0 -0
  39. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/modality_tools.py +0 -0
  40. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/model_errors.py +0 -0
  41. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/model_routing.py +0 -0
  42. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/openapi_loader.py +0 -0
  43. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/paths.py +0 -0
  44. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/permissions.py +0 -0
  45. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/plugins/__init__.py +0 -0
  46. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
  47. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
  48. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/policy_profile.py +0 -0
  49. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/pricing.py +0 -0
  50. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/prompt_suggestions.py +0 -0
  51. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/query/__init__.py +0 -0
  52. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/query/config.py +0 -0
  53. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/query/deps.py +0 -0
  54. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/query/engine.py +0 -0
  55. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/query/stop_hooks.py +0 -0
  56. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/query/token_budget.py +0 -0
  57. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/query/transitions.py +0 -0
  58. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/refine.py +0 -0
  59. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/repl_commands.py +0 -0
  60. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/review_agent.py +0 -0
  61. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/session_store.py +0 -0
  62. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/slash_commands.py +0 -0
  63. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/thinking.py +0 -0
  64. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tool_prompt_manifest.py +0 -0
  65. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tool_registry.py +0 -0
  66. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tool_result_store.py +0 -0
  67. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/__init__.py +0 -0
  68. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/bash.py +0 -0
  69. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/browser.py +0 -0
  70. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/edit.py +0 -0
  71. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/filesystem.py +0 -0
  72. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/notebook.py +0 -0
  73. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/notes.py +0 -0
  74. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/repo_map.py +0 -0
  75. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/search.py +0 -0
  76. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/shell.py +0 -0
  77. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/shell_gate.py +0 -0
  78. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/subtask.py +0 -0
  79. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/tasks.py +0 -0
  80. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/think.py +0 -0
  81. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/todo.py +0 -0
  82. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/web.py +0 -0
  83. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools/web_search.py +0 -0
  84. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tools_inspector.py +0 -0
  85. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/trust.py +0 -0
  86. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tui/input_handler.py +0 -0
  87. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tui/scrollback.py +0 -0
  88. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tui/spinner.py +0 -0
  89. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tui/welcome_banner.py +0 -0
  90. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/tui/welcome_rich.py +0 -0
  91. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/version.py +0 -0
  92. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/vertex.py +0 -0
  93. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/web/__init__.py +0 -0
  94. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/web/claude_sse_adapter.py +0 -0
  95. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/web/terminal_repl.py +0 -0
  96. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode/workspace_hints.py +0 -0
  97. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode.egg-info/SOURCES.txt +0 -0
  98. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode.egg-info/dependency_links.txt +0 -0
  99. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode.egg-info/entry_points.txt +0 -0
  100. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode.egg-info/requires.txt +0 -0
  101. {gemcode-0.3.71 → gemcode-0.3.73}/src/gemcode.egg-info/top_level.txt +0 -0
  102. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_agent_instruction.py +0 -0
  103. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_autocompact.py +0 -0
  104. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_capability_routing.py +0 -0
  105. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_claude_web_adapter_sse.py +0 -0
  106. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_cli_init.py +0 -0
  107. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_computer_use_permissions.py +0 -0
  108. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_context_budget.py +0 -0
  109. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_context_warning.py +0 -0
  110. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_credentials.py +0 -0
  111. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_interactive_permission_ask.py +0 -0
  112. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_kairos_scheduler.py +0 -0
  113. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_modality_tools.py +0 -0
  114. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_model_error_retry.py +0 -0
  115. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_model_errors.py +0 -0
  116. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_model_routing.py +0 -0
  117. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_paths.py +0 -0
  118. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_permissions.py +0 -0
  119. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_prompt_suggestions.py +0 -0
  120. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_repl_commands.py +0 -0
  121. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_repl_slash.py +0 -0
  122. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_slash_commands.py +0 -0
  123. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_thinking_config.py +0 -0
  124. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_token_budget.py +0 -0
  125. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_tool_context_circulation.py +0 -0
  126. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_tools.py +0 -0
  127. {gemcode-0.3.71 → gemcode-0.3.73}/tests/test_tools_inspector.py +0 -0
  128. {gemcode-0.3.71 → gemcode-0.3.73}/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.71
3
+ Version: 0.3.73
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
@@ -246,6 +246,11 @@ GemCode keeps project-local state under `.gemcode/`:
246
246
  - `gemcode tools smoke` fails non-zero if any tool’s declaration compilation fails
247
247
  - Optional inspection flags: `--deep-research`, `--maps-grounding`, `--embeddings`, `--memory`
248
248
  - **Optional compaction**: set `GEMCODE_ENABLE_COMPACT=1` to trim old `Content` entries before each model call (MVP sliding window; can break complex tool chains if too aggressive—tune `GEMCODE_MAX_CONTENT_ITEMS`).
249
+ - **ADK multi-agent transfer (recommended)**: enabled by default; GemCode builds an ADK sub-agent tree (Explorer/Verifier) and allows the model to transfer with `transfer_to_agent` when specialization helps.
250
+ - Disable: `GEMCODE_ADK_AGENT_TRANSFER=0`
251
+ - **ADK event compaction (new)**: optional ADK-native summarization of older events to keep long sessions coherent without exploding context.
252
+ - Enable: `GEMCODE_ADK_EVENTS_COMPACTION=1`
253
+ - Tune: `GEMCODE_ADK_COMPACTION_INTERVAL`, `GEMCODE_ADK_COMPACTION_OVERLAP`, `GEMCODE_ADK_COMPACTION_MODEL`
249
254
  - **Session token ceiling**: set `GEMCODE_MAX_SESSION_TOKENS` to stop the next LLM call when cumulative `usage_metadata.total_token_count` exceeds the limit.
250
255
  - **Token budget tracking**: set `GEMCODE_TOKEN_BUDGET` to enforce continuation/stop decisions per user turn (token-budget audit in `.gemcode/audit.log`).
251
256
  - **Stop-the-loop hooks**: set `GEMCODE_POST_TURN_HOOK=/path/to/hook.sh` (or place an executable at `.gemcode/hooks/post_turn`) to run after each user message.
@@ -57,6 +57,11 @@ GemCode keeps project-local state under `.gemcode/`:
57
57
  - `gemcode tools smoke` fails non-zero if any tool’s declaration compilation fails
58
58
  - Optional inspection flags: `--deep-research`, `--maps-grounding`, `--embeddings`, `--memory`
59
59
  - **Optional compaction**: set `GEMCODE_ENABLE_COMPACT=1` to trim old `Content` entries before each model call (MVP sliding window; can break complex tool chains if too aggressive—tune `GEMCODE_MAX_CONTENT_ITEMS`).
60
+ - **ADK multi-agent transfer (recommended)**: enabled by default; GemCode builds an ADK sub-agent tree (Explorer/Verifier) and allows the model to transfer with `transfer_to_agent` when specialization helps.
61
+ - Disable: `GEMCODE_ADK_AGENT_TRANSFER=0`
62
+ - **ADK event compaction (new)**: optional ADK-native summarization of older events to keep long sessions coherent without exploding context.
63
+ - Enable: `GEMCODE_ADK_EVENTS_COMPACTION=1`
64
+ - Tune: `GEMCODE_ADK_COMPACTION_INTERVAL`, `GEMCODE_ADK_COMPACTION_OVERLAP`, `GEMCODE_ADK_COMPACTION_MODEL`
60
65
  - **Session token ceiling**: set `GEMCODE_MAX_SESSION_TOKENS` to stop the next LLM call when cumulative `usage_metadata.total_token_count` exceeds the limit.
61
66
  - **Token budget tracking**: set `GEMCODE_TOKEN_BUDGET` to enforce continuation/stop decisions per user turn (token-budget audit in `.gemcode/audit.log`).
62
67
  - **Stop-the-loop hooks**: set `GEMCODE_POST_TURN_HOOK=/path/to/hook.sh` (or place an executable at `.gemcode/hooks/post_turn`) to run after each user message.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gemcode"
7
- version = "0.3.71"
7
+ version = "0.3.73"
8
8
  description = "Local-first coding agent on Google Gemini + ADK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -887,7 +887,6 @@ def build_root_agent(
887
887
  pre-built list that excludes run_subtask itself, preventing recursion).
888
888
  When set, build_function_tools() is NOT called.
889
889
  """
890
- return (base + tool_guide).strip() + "\n"
891
890
  if _tools is not None:
892
891
  tools = list(_tools)
893
892
  else:
@@ -966,12 +965,51 @@ def build_root_agent(
966
965
  tool_config=tool_cfg,
967
966
  )
968
967
 
968
+ # ── ADK multi-agent tree (LLM-controlled transfer) ───────────────────────
969
+ sub_agents = []
970
+ if getattr(cfg, "enable_adk_agent_transfer", True) and _tools is None:
971
+ try:
972
+ # Explorer: read-only, fast, low-risk. Keep instruction short.
973
+ explorer_tools = build_function_tools(cfg, include_subtask=False)
974
+ explorer_tools = [t for t in explorer_tools if getattr(t, "__name__", "") not in ("write_file", "search_replace", "delete_file", "move_file", "bash", "run_command")]
975
+ explorer = LlmAgent(
976
+ name="explorer",
977
+ model=getattr(cfg, "model_alt", None) or cfg.model,
978
+ instruction=(
979
+ "You are Explorer. Your job is to quickly map the codebase and answer: "
980
+ "what files/symbols matter and where to look next. Use read-only tools only. "
981
+ "Return concise findings with file paths and symbol names."
982
+ ),
983
+ tools=explorer_tools,
984
+ generate_content_config=gen_cfg,
985
+ **cb_kwargs,
986
+ )
987
+ # Verifier: focuses on checking, tests, and consistency.
988
+ verifier_tools = build_function_tools(cfg, include_subtask=False)
989
+ verifier_tools = [t for t in verifier_tools if getattr(t, "__name__", "") not in ("write_file", "search_replace", "delete_file", "move_file")]
990
+ verifier = LlmAgent(
991
+ name="verifier",
992
+ model=getattr(cfg, "model_alt", None) or cfg.model,
993
+ instruction=(
994
+ "You are Verifier. Your job is to verify changes: run checks/tests when needed, "
995
+ "spot inconsistencies, and report PASS/FAIL with concrete evidence. "
996
+ "Prefer minimal commands and short outputs."
997
+ ),
998
+ tools=verifier_tools,
999
+ generate_content_config=gen_cfg,
1000
+ **cb_kwargs,
1001
+ )
1002
+ sub_agents = [explorer, verifier]
1003
+ except Exception:
1004
+ sub_agents = []
1005
+
969
1006
  agent_kwargs: dict = dict(
970
1007
  model=cfg.model,
971
1008
  name="gemcode",
972
1009
  instruction=build_instruction(cfg),
973
1010
  tools=tools,
974
1011
  generate_content_config=gen_cfg,
1012
+ sub_agents=sub_agents or None,
975
1013
  **cb_kwargs,
976
1014
  )
977
1015
 
@@ -141,6 +141,31 @@ class GemCodeConfig:
141
141
  default_factory=lambda: int(os.environ.get("GEMCODE_TOOL_RESULT_GROUP_BUDGET_CHARS", "60000"))
142
142
  )
143
143
 
144
+ # ADK App-level event compaction (sliding-window summarization).
145
+ enable_adk_events_compaction: bool = field(
146
+ default_factory=lambda: _truthy_env("GEMCODE_ADK_EVENTS_COMPACTION", default=False)
147
+ )
148
+ adk_compaction_interval: int = field(
149
+ default_factory=lambda: int(os.environ.get("GEMCODE_ADK_COMPACTION_INTERVAL", "6"))
150
+ )
151
+ adk_compaction_overlap: int = field(
152
+ default_factory=lambda: int(os.environ.get("GEMCODE_ADK_COMPACTION_OVERLAP", "1"))
153
+ )
154
+ adk_compaction_token_threshold: int | None = field(
155
+ default_factory=lambda: _opt_positive_int("GEMCODE_ADK_COMPACTION_TOKEN_THRESHOLD")
156
+ )
157
+ adk_compaction_event_retention_size: int | None = field(
158
+ default_factory=lambda: _opt_positive_int("GEMCODE_ADK_COMPACTION_EVENT_RETENTION")
159
+ )
160
+ adk_compaction_summarizer_model: str = field(
161
+ default_factory=lambda: os.environ.get("GEMCODE_ADK_COMPACTION_MODEL", "gemini-2.5-flash")
162
+ )
163
+
164
+ # ADK multi-agent transfer (Explorer/Implementer/Verifier sub-agents).
165
+ enable_adk_agent_transfer: bool = field(
166
+ default_factory=lambda: _truthy_env("GEMCODE_ADK_AGENT_TRANSFER", default=True)
167
+ )
168
+
144
169
  # When enabled, oversized tool outputs are offloaded to disk under
145
170
  # .gemcode/tool-results/ and replaced in history with stable refs + previews.
146
171
  # This reduces context bloat and improves prompt-cache stability.
@@ -87,11 +87,11 @@ async def run_turn(
87
87
  if re.search(r"\\b(test|pytest|ci|build|deploy|release)\\b", p, re.I):
88
88
  risk += 0.1
89
89
  # Multi-file hints
90
- if p.count(\"/\") >= 6 or p.count(\".py\") + p.count(\".ts\") + p.count(\".tsx\") >= 3:
90
+ if p.count("/") >= 6 or p.count(".py") + p.count(".ts") + p.count(".tsx") >= 3:
91
91
  risk += 0.1
92
92
  # Clamp 0..1
93
93
  risk = max(0.0, min(1.0, float(risk)))
94
- object.__setattr__(cfg, \"_risk_score\", risk)
94
+ object.__setattr__(cfg, "_risk_score", risk)
95
95
  except Exception:
96
96
  pass
97
97
  run_config = (
@@ -400,6 +400,14 @@ async def process_repl_slash(
400
400
  out(f" dynamic_token_policy: {getattr(cfg, 'dynamic_token_policy', True)}")
401
401
  out(f" dynamic_risk_policy: {getattr(cfg, 'dynamic_risk_policy', True)}")
402
402
  out(f" dynamic_risk_boost: {getattr(cfg, 'dynamic_risk_boost', 0.6)}")
403
+ out()
404
+ out(" ADK advanced:")
405
+ out(f" adk_agent_transfer: {getattr(cfg, 'enable_adk_agent_transfer', True)}")
406
+ out(f" adk_events_compaction: {getattr(cfg, 'enable_adk_events_compaction', False)}")
407
+ if getattr(cfg, "enable_adk_events_compaction", False):
408
+ out(f" compaction_interval: {getattr(cfg, 'adk_compaction_interval', 6)}")
409
+ out(f" compaction_overlap: {getattr(cfg, 'adk_compaction_overlap', 1)}")
410
+ out(f" compaction_model: {getattr(cfg, 'adk_compaction_summarizer_model', 'gemini-2.5-flash')}")
403
411
  out(f" risk_score: {risk:.2f}")
404
412
  if isinstance(pct, int):
405
413
  out(f" context_percent_left: {pct}%")
@@ -66,11 +66,39 @@ def _build_app(agent, plugins, cfg: GemCodeConfig):
66
66
  """
67
67
  try:
68
68
  from google.adk.apps.app import App
69
+ events_compaction_config = None
70
+ if getattr(cfg, "enable_adk_events_compaction", False):
71
+ try:
72
+ from google.adk.apps.app import EventsCompactionConfig
73
+ summarizer = None
74
+ try:
75
+ from google.adk.apps.llm_event_summarizer import LlmEventSummarizer
76
+ from google.adk.models import Gemini
77
+ summarizer_llm = Gemini(model=getattr(cfg, "adk_compaction_summarizer_model", "gemini-2.5-flash"))
78
+ summarizer = LlmEventSummarizer(llm=summarizer_llm)
79
+ except Exception:
80
+ summarizer = None
81
+
82
+ kw = dict(
83
+ compaction_interval=max(2, int(getattr(cfg, "adk_compaction_interval", 6) or 6)),
84
+ overlap_size=max(0, int(getattr(cfg, "adk_compaction_overlap", 1) or 1)),
85
+ )
86
+ tt = getattr(cfg, "adk_compaction_token_threshold", None)
87
+ rs = getattr(cfg, "adk_compaction_event_retention_size", None)
88
+ if tt is not None and rs is not None:
89
+ kw["token_threshold"] = int(tt)
90
+ kw["event_retention_size"] = int(rs)
91
+ if summarizer is not None:
92
+ kw["summarizer"] = summarizer
93
+ events_compaction_config = EventsCompactionConfig(**kw)
94
+ except Exception:
95
+ events_compaction_config = None
69
96
  return App(
70
97
  name="gemcode",
71
98
  root_agent=agent,
72
99
  plugins=plugins,
73
100
  context_cache_config=_build_context_cache_config(),
101
+ events_compaction_config=events_compaction_config,
74
102
  )
75
103
  except Exception:
76
104
  # Fall back silently — Runner still accepts the legacy kwargs.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemcode
3
- Version: 0.3.71
3
+ Version: 0.3.73
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
@@ -246,6 +246,11 @@ GemCode keeps project-local state under `.gemcode/`:
246
246
  - `gemcode tools smoke` fails non-zero if any tool’s declaration compilation fails
247
247
  - Optional inspection flags: `--deep-research`, `--maps-grounding`, `--embeddings`, `--memory`
248
248
  - **Optional compaction**: set `GEMCODE_ENABLE_COMPACT=1` to trim old `Content` entries before each model call (MVP sliding window; can break complex tool chains if too aggressive—tune `GEMCODE_MAX_CONTENT_ITEMS`).
249
+ - **ADK multi-agent transfer (recommended)**: enabled by default; GemCode builds an ADK sub-agent tree (Explorer/Verifier) and allows the model to transfer with `transfer_to_agent` when specialization helps.
250
+ - Disable: `GEMCODE_ADK_AGENT_TRANSFER=0`
251
+ - **ADK event compaction (new)**: optional ADK-native summarization of older events to keep long sessions coherent without exploding context.
252
+ - Enable: `GEMCODE_ADK_EVENTS_COMPACTION=1`
253
+ - Tune: `GEMCODE_ADK_COMPACTION_INTERVAL`, `GEMCODE_ADK_COMPACTION_OVERLAP`, `GEMCODE_ADK_COMPACTION_MODEL`
249
254
  - **Session token ceiling**: set `GEMCODE_MAX_SESSION_TOKENS` to stop the next LLM call when cumulative `usage_metadata.total_token_count` exceeds the limit.
250
255
  - **Token budget tracking**: set `GEMCODE_TOKEN_BUDGET` to enforce continuation/stop decisions per user turn (token-budget audit in `.gemcode/audit.log`).
251
256
  - **Stop-the-loop hooks**: set `GEMCODE_POST_TURN_HOOK=/path/to/hook.sh` (or place an executable at `.gemcode/hooks/post_turn`) to run after each user message.
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