gemcode 0.3.120__tar.gz → 0.4.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 (178) hide show
  1. {gemcode-0.3.120/src/gemcode.egg-info → gemcode-0.4.0}/PKG-INFO +40 -31
  2. {gemcode-0.3.120 → gemcode-0.4.0}/README.md +38 -29
  3. {gemcode-0.3.120 → gemcode-0.4.0}/pyproject.toml +2 -2
  4. gemcode-0.4.0/src/gemcode/a2a_bridge.py +258 -0
  5. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/agent.py +6 -1
  6. gemcode-0.4.0/src/gemcode/agent_intelligence.py +259 -0
  7. gemcode-0.4.0/src/gemcode/agent_mesh.py +536 -0
  8. gemcode-0.4.0/src/gemcode/agent_triggers.py +332 -0
  9. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/checkpoints.py +18 -0
  10. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/cli.py +38 -2
  11. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/config.py +3 -0
  12. gemcode-0.4.0/src/gemcode/delegation_learning.py +245 -0
  13. gemcode-0.4.0/src/gemcode/event_bus.py +201 -0
  14. gemcode-0.4.0/src/gemcode/fleet_reports.py +350 -0
  15. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/invoke.py +43 -220
  16. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/kaira_client.py +4 -2
  17. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/kaira_daemon.py +70 -7
  18. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/kaira_ipc.py +67 -0
  19. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/repl_slash.py +94 -38
  20. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/__init__.py +52 -0
  21. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/automations_tools.py +3 -3
  22. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/org_tools.py +123 -106
  23. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/subtask.py +29 -10
  24. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tui/scrollback.py +47 -4
  25. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tui/welcome_banner.py +1 -1
  26. {gemcode-0.3.120 → gemcode-0.4.0/src/gemcode.egg-info}/PKG-INFO +40 -31
  27. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode.egg-info/SOURCES.txt +11 -0
  28. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode.egg-info/requires.txt +1 -1
  29. gemcode-0.4.0/tests/test_agent_mesh.py +96 -0
  30. gemcode-0.4.0/tests/test_event_bus.py +151 -0
  31. gemcode-0.4.0/tests/test_fleet_reports.py +100 -0
  32. gemcode-0.4.0/tests/test_kaira_ipc_paths.py +39 -0
  33. {gemcode-0.3.120 → gemcode-0.4.0}/LICENSE +0 -0
  34. {gemcode-0.3.120 → gemcode-0.4.0}/MANIFEST.in +0 -0
  35. {gemcode-0.3.120 → gemcode-0.4.0}/setup.cfg +0 -0
  36. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/__init__.py +0 -0
  37. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/__main__.py +0 -0
  38. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/audit.py +0 -0
  39. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/autocompact.py +0 -0
  40. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/automations.py +0 -0
  41. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/autotune.py +0 -0
  42. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/callbacks.py +0 -0
  43. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/capability_routing.py +0 -0
  44. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/compaction.py +0 -0
  45. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/computer_use/__init__.py +0 -0
  46. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/computer_use/browser_computer.py +0 -0
  47. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/context_budget.py +0 -0
  48. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/context_warning.py +0 -0
  49. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/credentials.py +0 -0
  50. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/curated_memory.py +0 -0
  51. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/dynamic_policy.py +0 -0
  52. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/evals/harness.py +0 -0
  53. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/hitl_session.py +0 -0
  54. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/hooks.py +0 -0
  55. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/ide_protocol.py +0 -0
  56. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/ide_stdio.py +0 -0
  57. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/intent_classifier.py +0 -0
  58. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/interactions.py +0 -0
  59. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/kaira_job_store.py +0 -0
  60. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/learning.py +0 -0
  61. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/limits.py +0 -0
  62. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/live_audio_engine.py +0 -0
  63. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/logging_config.py +0 -0
  64. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/mcp_loader.py +0 -0
  65. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/memory/__init__.py +0 -0
  66. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/memory/embedding_memory_service.py +0 -0
  67. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/memory/file_memory_service.py +0 -0
  68. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/modality_tools.py +0 -0
  69. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/model_errors.py +0 -0
  70. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/model_routing.py +0 -0
  71. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/multimodal_input.py +0 -0
  72. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/openapi_loader.py +0 -0
  73. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/org.py +0 -0
  74. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/output_styles.py +0 -0
  75. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/paths.py +0 -0
  76. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/permissions.py +0 -0
  77. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/plugins/__init__.py +0 -0
  78. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
  79. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
  80. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/policy_profile.py +0 -0
  81. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/pricing.py +0 -0
  82. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/prompt_suggestions.py +0 -0
  83. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/query/__init__.py +0 -0
  84. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/query/config.py +0 -0
  85. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/query/deps.py +0 -0
  86. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/query/engine.py +0 -0
  87. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/query/stop_hooks.py +0 -0
  88. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/query/token_budget.py +0 -0
  89. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/query/transitions.py +0 -0
  90. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/query_sanitizer.py +0 -0
  91. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/refine.py +0 -0
  92. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/repl_commands.py +0 -0
  93. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/review_agent.py +0 -0
  94. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/rules.py +0 -0
  95. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/session_runtime.py +0 -0
  96. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/session_store.py +0 -0
  97. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/session_summariser.py +0 -0
  98. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/skills.py +0 -0
  99. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/slash_commands.py +0 -0
  100. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/thinking.py +0 -0
  101. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tool_prompt_manifest.py +0 -0
  102. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tool_registry.py +0 -0
  103. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tool_result_store.py +0 -0
  104. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/bash.py +0 -0
  105. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/browser.py +0 -0
  106. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/compress_memory.py +0 -0
  107. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/curated_memory.py +0 -0
  108. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/edit.py +0 -0
  109. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/filesystem.py +0 -0
  110. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/notebook.py +0 -0
  111. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/notes.py +0 -0
  112. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/repo_map.py +0 -0
  113. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/search.py +0 -0
  114. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/shell.py +0 -0
  115. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/shell_gate.py +0 -0
  116. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/skills.py +0 -0
  117. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/tasks.py +0 -0
  118. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/think.py +0 -0
  119. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/todo.py +0 -0
  120. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/user_choice.py +0 -0
  121. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/veomem_tools.py +0 -0
  122. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/web.py +0 -0
  123. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools/web_search.py +0 -0
  124. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tools_inspector.py +0 -0
  125. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/trust.py +0 -0
  126. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tui/input_handler.py +0 -0
  127. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tui/spinner.py +0 -0
  128. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/tui/welcome_rich.py +0 -0
  129. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/veomem_bridge.py +0 -0
  130. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/version.py +0 -0
  131. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/vertex.py +0 -0
  132. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/wal.py +0 -0
  133. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/web/__init__.py +0 -0
  134. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/web/sse_adapter.py +0 -0
  135. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/web/terminal_repl.py +0 -0
  136. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/web/web_sse_compat.py +0 -0
  137. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode/workspace_hints.py +0 -0
  138. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode.egg-info/dependency_links.txt +0 -0
  139. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode.egg-info/entry_points.txt +0 -0
  140. {gemcode-0.3.120 → gemcode-0.4.0}/src/gemcode.egg-info/top_level.txt +0 -0
  141. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_add_dir.py +0 -0
  142. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_agent_instruction.py +0 -0
  143. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_autocompact.py +0 -0
  144. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_automations.py +0 -0
  145. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_capability_routing.py +0 -0
  146. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_checkpoint_diff_command.py +0 -0
  147. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_cli_init.py +0 -0
  148. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_compress_memory_tool.py +0 -0
  149. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_computer_use_permissions.py +0 -0
  150. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_context_budget.py +0 -0
  151. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_context_warning.py +0 -0
  152. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_credentials.py +0 -0
  153. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_eval_harness_layout.py +0 -0
  154. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_ide_stdio_attachments.py +0 -0
  155. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_interactive_permission_ask.py +0 -0
  156. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_kaira_scheduler.py +0 -0
  157. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_modality_tools.py +0 -0
  158. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_model_error_retry.py +0 -0
  159. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_model_errors.py +0 -0
  160. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_model_routing.py +0 -0
  161. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_multimodal_input.py +0 -0
  162. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_output_styles_and_rules.py +0 -0
  163. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_paths.py +0 -0
  164. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_permissions.py +0 -0
  165. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_prompt_suggestions.py +0 -0
  166. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_repl_commands.py +0 -0
  167. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_repl_slash.py +0 -0
  168. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_session_runtime_cache.py +0 -0
  169. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_skills.py +0 -0
  170. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_slash_commands.py +0 -0
  171. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_slash_completion_registry.py +0 -0
  172. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_thinking_config.py +0 -0
  173. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_token_budget.py +0 -0
  174. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_tool_context_circulation.py +0 -0
  175. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_tools.py +0 -0
  176. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_tools_inspector.py +0 -0
  177. {gemcode-0.3.120 → gemcode-0.4.0}/tests/test_web_sse_adapter.py +0 -0
  178. {gemcode-0.3.120 → gemcode-0.4.0}/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.120
3
+ Version: 0.4.0
4
4
  Summary: Local-first coding agent on Google Gemini + ADK
5
5
  Author: GemCode Contributors
6
6
  License: Apache License
@@ -175,7 +175,7 @@ Classifier: Topic :: Terminals
175
175
  Requires-Python: >=3.11
176
176
  Description-Content-Type: text/markdown
177
177
  License-File: LICENSE
178
- Requires-Dist: google-adk>=1.0.0
178
+ Requires-Dist: google-adk[a2a]>=1.0.0
179
179
  Requires-Dist: google-genai>=1.0.0
180
180
  Requires-Dist: python-dotenv>=1.0.0
181
181
  Requires-Dist: rich>=13.0.0
@@ -210,10 +210,12 @@ GemCode is designed for repository-native work rather than copy-paste chat workf
210
210
  |---|---|
211
211
  | One-shot CLI | Single prompt/response runs |
212
212
  | REPL | Stateful terminal interaction |
213
- | TUI | Scrollback terminal UI over the REPL runtime |
213
+ | TUI | GemCode terminal UI (scrollback-style; `tui/scrollback.py`) |
214
214
  | IDE stdio | Editor integration over JSONL stdin/stdout |
215
- | Kaira | Priority-queue scheduler for background jobs |
216
- | Live audio (future scope) | Planned: microphone-driven Gemini Live sessions (currently experimental/unreliable) |
215
+ | Agent Mesh | In-process multi-agent orchestration (automatic) |
216
+ | Kaira daemon | Optional always-on background scheduler |
217
+ | A2A server | Cross-machine agent communication via Google A2A protocol |
218
+ | Live audio (experimental) | Microphone-driven Gemini Live sessions |
217
219
 
218
220
  ## Recommended reading order
219
221
 
@@ -360,32 +362,25 @@ gemcode -C . --attach ./report.pdf "Summarize this"
360
362
  gemcode kaira -C .
361
363
  ```
362
364
 
363
- ### Orchestration (Kaira + org delegation)
365
+ ### Orchestration (Agent Mesh + Multi-Agent)
364
366
 
365
- Docs:
366
- - `../docs/orchestration.md`
367
-
368
- In one terminal:
367
+ GemCode includes a built-in multi-agent orchestration system that works automatically — no separate daemon required.
369
368
 
370
- ```bash
371
- gemcode kaira -C .
372
- ```
373
-
374
- In another terminal:
375
-
376
- ```bash
377
- gemcode -C .
378
- ```
379
-
380
- Then in the REPL/TUI:
369
+ **Key features:**
370
+ - **Agent Mesh** — in-process concurrent agent execution with full tool access
371
+ - **Event Bus** — agents communicate via pub/sub (no Unix sockets needed)
372
+ - **Self-Triggering Agents** — agents auto-activate on events (e.g., verifier reviews completed work)
373
+ - **Delegation Learning** — remembers which agents succeed at which tasks
374
+ - **A2A Bridge** — expose/consume agents across machines via Google's A2A protocol
381
375
 
376
+ Quick example in the REPL:
382
377
  ```text
383
- /org tree
384
- /org hire verifier "QA / test planner" subagent gemcode "Find risks, propose tests, review plans."
385
- /org assign verifier "Review the plan and propose tests"
386
- /kaira jobs
387
- /kaira follow <job_id_prefix>
378
+ > Analyze the auth module. Delegate security review to the verifier.
388
379
  ```
380
+ The agent calls `org_delegate("verifier", ...)` → mesh runs a full-power verifier agent → result flows back automatically.
381
+
382
+ Docs:
383
+ - [`../docs/orchestration.md`](../docs/orchestration.md)
389
384
 
390
385
  ### Start the IDE bridge
391
386
  ```bash
@@ -418,11 +413,21 @@ Status note:
418
413
  | `/rules` | Inspect active rules |
419
414
  | `/diff` | Show current diff/checkpoint diff |
420
415
  | `/rewind` | Restore checkpoints |
421
- | `/review` | Run a review workflow |
416
+ | `/review` | Run a parallel code review pipeline |
422
417
  | `/eval` | Run evaluation gates |
423
418
  | `/kaira` | Show scheduler usage help |
424
419
  | `/super` | Super mode: auto-approve tools, no GemCode HITL · `/super off` |
425
420
 
421
+ ## Orchestration commands
422
+
423
+ | Command | Purpose |
424
+ |---|---|
425
+ | `/agent list` | Show all org members |
426
+ | `/agent tree` | Show org hierarchy |
427
+ | `/agent create` | Create a new agent member |
428
+ | `/agent assign <member> <task>` | Delegate work to a member |
429
+ | `/agent improve <member> <lessons>` | Improve a member's skill |
430
+
426
431
  Detailed behavior:
427
432
  - [`../docs/cli-and-repl.md`](../docs/cli-and-repl.md)
428
433
 
@@ -430,11 +435,15 @@ Detailed behavior:
430
435
 
431
436
  | Capability | What it adds |
432
437
  |---|---|
433
- | Deep research | research-focused tool routing and optional dedicated model path |
434
- | Embeddings | semantic search and optional embedding-backed memory |
435
- | Memory | retrieval-oriented persistent memory |
438
+ | Agent Mesh | In-process multi-agent orchestration (automatic, no daemon needed) |
439
+ | A2A Bridge | Cross-machine agent communication via Google A2A protocol |
440
+ | Self-Triggers | Agents auto-activate on events (verification, failure recovery) |
441
+ | Delegation Learning | Remembers successful patterns, suggests optimal routing |
442
+ | Deep research | Research-focused tool routing and optional dedicated model path |
443
+ | Embeddings | Semantic search and optional embedding-backed memory |
444
+ | Memory | Retrieval-oriented persistent memory |
436
445
  | Browser/computer use | Playwright-backed browser automation and inspection |
437
- | Live audio | Gemini Live microphone sessions |
446
+ | Live audio | Gemini Live microphone sessions (experimental) |
438
447
 
439
448
  Detailed behavior:
440
449
  - [`../docs/capabilities.md`](../docs/capabilities.md)
@@ -18,10 +18,12 @@ GemCode is designed for repository-native work rather than copy-paste chat workf
18
18
  |---|---|
19
19
  | One-shot CLI | Single prompt/response runs |
20
20
  | REPL | Stateful terminal interaction |
21
- | TUI | Scrollback terminal UI over the REPL runtime |
21
+ | TUI | GemCode terminal UI (scrollback-style; `tui/scrollback.py`) |
22
22
  | IDE stdio | Editor integration over JSONL stdin/stdout |
23
- | Kaira | Priority-queue scheduler for background jobs |
24
- | Live audio (future scope) | Planned: microphone-driven Gemini Live sessions (currently experimental/unreliable) |
23
+ | Agent Mesh | In-process multi-agent orchestration (automatic) |
24
+ | Kaira daemon | Optional always-on background scheduler |
25
+ | A2A server | Cross-machine agent communication via Google A2A protocol |
26
+ | Live audio (experimental) | Microphone-driven Gemini Live sessions |
25
27
 
26
28
  ## Recommended reading order
27
29
 
@@ -168,32 +170,25 @@ gemcode -C . --attach ./report.pdf "Summarize this"
168
170
  gemcode kaira -C .
169
171
  ```
170
172
 
171
- ### Orchestration (Kaira + org delegation)
173
+ ### Orchestration (Agent Mesh + Multi-Agent)
172
174
 
173
- Docs:
174
- - `../docs/orchestration.md`
175
-
176
- In one terminal:
175
+ GemCode includes a built-in multi-agent orchestration system that works automatically — no separate daemon required.
177
176
 
178
- ```bash
179
- gemcode kaira -C .
180
- ```
181
-
182
- In another terminal:
183
-
184
- ```bash
185
- gemcode -C .
186
- ```
187
-
188
- Then in the REPL/TUI:
177
+ **Key features:**
178
+ - **Agent Mesh** — in-process concurrent agent execution with full tool access
179
+ - **Event Bus** — agents communicate via pub/sub (no Unix sockets needed)
180
+ - **Self-Triggering Agents** — agents auto-activate on events (e.g., verifier reviews completed work)
181
+ - **Delegation Learning** — remembers which agents succeed at which tasks
182
+ - **A2A Bridge** — expose/consume agents across machines via Google's A2A protocol
189
183
 
184
+ Quick example in the REPL:
190
185
  ```text
191
- /org tree
192
- /org hire verifier "QA / test planner" subagent gemcode "Find risks, propose tests, review plans."
193
- /org assign verifier "Review the plan and propose tests"
194
- /kaira jobs
195
- /kaira follow <job_id_prefix>
186
+ > Analyze the auth module. Delegate security review to the verifier.
196
187
  ```
188
+ The agent calls `org_delegate("verifier", ...)` → mesh runs a full-power verifier agent → result flows back automatically.
189
+
190
+ Docs:
191
+ - [`../docs/orchestration.md`](../docs/orchestration.md)
197
192
 
198
193
  ### Start the IDE bridge
199
194
  ```bash
@@ -226,11 +221,21 @@ Status note:
226
221
  | `/rules` | Inspect active rules |
227
222
  | `/diff` | Show current diff/checkpoint diff |
228
223
  | `/rewind` | Restore checkpoints |
229
- | `/review` | Run a review workflow |
224
+ | `/review` | Run a parallel code review pipeline |
230
225
  | `/eval` | Run evaluation gates |
231
226
  | `/kaira` | Show scheduler usage help |
232
227
  | `/super` | Super mode: auto-approve tools, no GemCode HITL · `/super off` |
233
228
 
229
+ ## Orchestration commands
230
+
231
+ | Command | Purpose |
232
+ |---|---|
233
+ | `/agent list` | Show all org members |
234
+ | `/agent tree` | Show org hierarchy |
235
+ | `/agent create` | Create a new agent member |
236
+ | `/agent assign <member> <task>` | Delegate work to a member |
237
+ | `/agent improve <member> <lessons>` | Improve a member's skill |
238
+
234
239
  Detailed behavior:
235
240
  - [`../docs/cli-and-repl.md`](../docs/cli-and-repl.md)
236
241
 
@@ -238,11 +243,15 @@ Detailed behavior:
238
243
 
239
244
  | Capability | What it adds |
240
245
  |---|---|
241
- | Deep research | research-focused tool routing and optional dedicated model path |
242
- | Embeddings | semantic search and optional embedding-backed memory |
243
- | Memory | retrieval-oriented persistent memory |
246
+ | Agent Mesh | In-process multi-agent orchestration (automatic, no daemon needed) |
247
+ | A2A Bridge | Cross-machine agent communication via Google A2A protocol |
248
+ | Self-Triggers | Agents auto-activate on events (verification, failure recovery) |
249
+ | Delegation Learning | Remembers successful patterns, suggests optimal routing |
250
+ | Deep research | Research-focused tool routing and optional dedicated model path |
251
+ | Embeddings | Semantic search and optional embedding-backed memory |
252
+ | Memory | Retrieval-oriented persistent memory |
244
253
  | Browser/computer use | Playwright-backed browser automation and inspection |
245
- | Live audio | Gemini Live microphone sessions |
254
+ | Live audio | Gemini Live microphone sessions (experimental) |
246
255
 
247
256
  Detailed behavior:
248
257
  - [`../docs/capabilities.md`](../docs/capabilities.md)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gemcode"
7
- version = "0.3.120"
7
+ version = "0.4.0"
8
8
  description = "Local-first coding agent on Google Gemini + ADK"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -27,7 +27,7 @@ classifiers = [
27
27
  "Topic :: Terminals",
28
28
  ]
29
29
  dependencies = [
30
- "google-adk>=1.0.0",
30
+ "google-adk[a2a]>=1.0.0",
31
31
  "google-genai>=1.0.0",
32
32
  "python-dotenv>=1.0.0",
33
33
  "rich>=13.0.0",
@@ -0,0 +1,258 @@
1
+ """
2
+ A2A Bridge — Expose and consume GemCode agents via Google's Agent2Agent protocol.
3
+
4
+ This module bridges the org system with ADK's native A2A support:
5
+ - `expose_agent()` — Turn an org member into a network-accessible A2A server
6
+ - `connect_remote_agent()` — Consume a remote A2A agent as an org member
7
+ - Auto-generate agent cards from org.json metadata
8
+
9
+ Requires: google-adk[a2a] (pip install google-adk[a2a])
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import os
15
+ from pathlib import Path
16
+ from typing import Any
17
+
18
+ from gemcode.config import GemCodeConfig
19
+ from gemcode.org import OrgMember, find_member, resolve_fleet_root
20
+
21
+
22
+ def a2a_available() -> bool:
23
+ """Check if A2A support is installed."""
24
+ try:
25
+ from google.adk.a2a.utils.agent_to_a2a import to_a2a # noqa: F401
26
+ from google.adk.agents.remote_a2a_agent import RemoteA2aAgent # noqa: F401
27
+ return True
28
+ except ImportError:
29
+ # Try auto-installing the a2a-sdk dependency
30
+ try:
31
+ import subprocess
32
+ import sys
33
+ subprocess.check_call(
34
+ [sys.executable, "-m", "pip", "install", "a2a-sdk>=0.3.4,<0.4.0", "--quiet"],
35
+ stdout=subprocess.DEVNULL,
36
+ stderr=subprocess.DEVNULL,
37
+ )
38
+ # Retry import after install
39
+ from google.adk.a2a.utils.agent_to_a2a import to_a2a # noqa: F401
40
+ from google.adk.agents.remote_a2a_agent import RemoteA2aAgent # noqa: F401
41
+ return True
42
+ except Exception:
43
+ return False
44
+
45
+
46
+ def build_agent_card_dict(member: OrgMember, *, base_url: str = "") -> dict[str, Any]:
47
+ """
48
+ Build an A2A agent card dictionary from an org member.
49
+
50
+ This is the metadata that describes what an agent can do,
51
+ following the A2A protocol specification.
52
+ """
53
+ skills = []
54
+
55
+ # Primary skill based on the member's role
56
+ skills.append({
57
+ "id": f"{member.name}_primary",
58
+ "name": member.title,
59
+ "description": member.description or f"Agent: {member.name} ({member.title})",
60
+ "tags": [member.kind, "gemcode"],
61
+ })
62
+
63
+ url = base_url or f"http://localhost:0/a2a/{member.name}"
64
+
65
+ return {
66
+ "name": member.name,
67
+ "description": member.description or f"{member.name} — {member.title}",
68
+ "version": "1.0.0",
69
+ "url": url,
70
+ "capabilities": {
71
+ "streaming": True,
72
+ "pushNotifications": False,
73
+ },
74
+ "defaultInputModes": ["text/plain"],
75
+ "defaultOutputModes": ["text/plain", "application/json"],
76
+ "skills": skills,
77
+ "supportsAuthenticatedExtendedCard": False,
78
+ }
79
+
80
+
81
+ def expose_member_as_a2a(
82
+ cfg: GemCodeConfig,
83
+ member_name: str,
84
+ *,
85
+ port: int = 0,
86
+ host: str = "localhost",
87
+ ) -> Any | None:
88
+ """
89
+ Expose an org member as an A2A server using ADK's to_a2a().
90
+
91
+ Returns the Starlette app (can be served with uvicorn) or None if A2A unavailable.
92
+ """
93
+ if not a2a_available():
94
+ return None
95
+
96
+ from google.adk.a2a.utils.agent_to_a2a import to_a2a
97
+
98
+ fleet_root = resolve_fleet_root(cfg.project_root)
99
+ m = find_member(fleet_root, member_name)
100
+ if m is None:
101
+ return None
102
+
103
+ # Build a real ADK agent for this member
104
+ from gemcode.agent import build_root_agent
105
+ from gemcode.tools import build_function_tools
106
+
107
+ import copy
108
+ agent_cfg = copy.deepcopy(cfg)
109
+ tools = build_function_tools(agent_cfg, include_subtask=False)
110
+ agent = build_root_agent(agent_cfg, _tools=tools)
111
+
112
+ # Generate agent card
113
+ base_url = f"http://{host}:{port}" if port else f"http://{host}"
114
+ card_dict = build_agent_card_dict(m, base_url=base_url)
115
+
116
+ # Create A2A app
117
+ try:
118
+ a2a_app = to_a2a(agent, port=port or 8001, agent_card=card_dict)
119
+ return a2a_app
120
+ except Exception:
121
+ # Fallback: try without custom card
122
+ try:
123
+ a2a_app = to_a2a(agent, port=port or 8001)
124
+ return a2a_app
125
+ except Exception:
126
+ return None
127
+
128
+
129
+ def create_remote_a2a_member(
130
+ *,
131
+ name: str,
132
+ description: str,
133
+ agent_card_url: str,
134
+ use_legacy: bool = False,
135
+ ) -> Any | None:
136
+ """
137
+ Create a RemoteA2aAgent that can be used as a sub-agent.
138
+
139
+ This lets GemCode consume external A2A agents as if they were local org members.
140
+ """
141
+ if not a2a_available():
142
+ return None
143
+
144
+ try:
145
+ from google.adk.agents.remote_a2a_agent import RemoteA2aAgent
146
+
147
+ remote_agent = RemoteA2aAgent(
148
+ name=name,
149
+ description=description,
150
+ agent_card=agent_card_url,
151
+ use_legacy=use_legacy,
152
+ )
153
+ return remote_agent
154
+ except Exception:
155
+ return None
156
+
157
+
158
+ def list_exposed_agents(cfg: GemCodeConfig) -> list[dict[str, Any]]:
159
+ """List all org members that could be exposed via A2A."""
160
+ from gemcode.org import list_members
161
+
162
+ fleet_root = resolve_fleet_root(cfg.project_root)
163
+ members = list_members(fleet_root)
164
+ return [
165
+ {
166
+ "name": m.name,
167
+ "title": m.title,
168
+ "kind": m.kind,
169
+ "description": m.description,
170
+ "a2a_available": a2a_available(),
171
+ "card": build_agent_card_dict(m),
172
+ }
173
+ for m in members
174
+ ]
175
+
176
+
177
+ def make_a2a_tools(cfg: GemCodeConfig) -> list:
178
+ """Build A2A-related tools for the agent."""
179
+
180
+ def a2a_expose(member: str, port: int = 8001, host: str = "localhost") -> dict:
181
+ """
182
+ Expose an org member as an A2A server (network-accessible agent).
183
+
184
+ Other GemCode instances or any A2A-compatible agent can then communicate
185
+ with this member over HTTP.
186
+
187
+ Args:
188
+ member: Name or ID of the org member to expose.
189
+ port: Port to serve on (default 8001).
190
+ host: Host to bind to (default localhost).
191
+ """
192
+ if not a2a_available():
193
+ return {"ok": False, "error": "A2A auto-install failed. Try: pip install a2a-sdk"}
194
+
195
+ app = expose_member_as_a2a(cfg, member, port=port, host=host)
196
+ if app is None:
197
+ return {"ok": False, "error": f"Failed to expose member '{member}'. Check org_list() for available members."}
198
+
199
+ return {
200
+ "ok": True,
201
+ "member": member,
202
+ "url": f"http://{host}:{port}",
203
+ "agent_card_url": f"http://{host}:{port}/.well-known/agent-card.json",
204
+ "note": f"Start with: uvicorn ... --host {host} --port {port}",
205
+ }
206
+
207
+ def a2a_connect(name: str, description: str, agent_card_url: str) -> dict:
208
+ """
209
+ Connect to a remote A2A agent and register it as an org member.
210
+
211
+ This lets you delegate tasks to agents running on other machines or
212
+ in other frameworks (LangGraph, CrewAI, etc.) via the A2A protocol.
213
+
214
+ Args:
215
+ name: Local name for this remote agent.
216
+ description: What this agent does.
217
+ agent_card_url: URL to the agent's card (e.g., http://host:port/.well-known/agent-card.json)
218
+ """
219
+ if not a2a_available():
220
+ return {"ok": False, "error": "A2A auto-install failed. Try: pip install a2a-sdk"}
221
+
222
+ remote = create_remote_a2a_member(
223
+ name=name,
224
+ description=description,
225
+ agent_card_url=agent_card_url,
226
+ )
227
+ if remote is None:
228
+ return {"ok": False, "error": f"Failed to connect to remote agent at {agent_card_url}"}
229
+
230
+ # Register in org
231
+ from gemcode.org import hire_member
232
+ fleet_root = resolve_fleet_root(cfg.project_root)
233
+ m = hire_member(
234
+ fleet_root,
235
+ name=name,
236
+ title=f"Remote A2A Agent",
237
+ kind="subagent",
238
+ description=f"[A2A] {description} (card: {agent_card_url})",
239
+ reports_to="manager",
240
+ )
241
+
242
+ return {
243
+ "ok": True,
244
+ "member": m.to_dict() if hasattr(m, "to_dict") else {"name": name},
245
+ "agent_card_url": agent_card_url,
246
+ "note": "Use org_delegate to send tasks to this remote agent.",
247
+ }
248
+
249
+ def a2a_list() -> dict:
250
+ """List all agents that can be exposed or are connected via A2A."""
251
+ agents = list_exposed_agents(cfg)
252
+ return {"ok": True, "agents": agents, "a2a_installed": a2a_available()}
253
+
254
+ a2a_expose.__name__ = "a2a_expose"
255
+ a2a_connect.__name__ = "a2a_connect"
256
+ a2a_list.__name__ = "a2a_list"
257
+
258
+ return [a2a_expose, a2a_connect, a2a_list]
@@ -372,7 +372,12 @@ def _build_runtime_facts(cfg: GemCodeConfig) -> str:
372
372
  "(up to N concurrently). Each job gets `kaira_sleep_ms(ms)` and "
373
373
  "`kaira_enqueue_prompt(prompt, priority, session_id)` tools so GemCode can "
374
374
  "schedule and trigger follow-up work itself. Useful for: tests/builds, bulk file processing, "
375
- "periodic automations, and parallelising large independent tasks."
375
+ "periodic automations, and parallelising large independent tasks. "
376
+ "Completed `org.report` / `job.report` / `agent.report` outcomes are also appended to "
377
+ "`.gemcode/fleet_reports.jsonl` and prepended to the next turn (GemCode TUI when `GEMCODE_TUI=1`, and any path using `run_turn`; disable with "
378
+ "`GEMCODE_FLEET_REPORTS_INJECT=0`). Optional hands-off follow-up: "
379
+ "`GEMCODE_FLEET_REPORTS_AUTO_CONTINUE=1` with `GEMCODE_FLEET_REPORTS_AUTO_CONTINUE_MODE=tui|enqueue|both` "
380
+ "(cap via `GEMCODE_FLEET_REPORTS_AUTO_CONTINUE_MAX`, debounce `GEMCODE_FLEET_REPORTS_ENQUEUE_DEBOUNCE_S`)."
376
381
  )
377
382
 
378
383
  # ── Git context ───────────────────────────────────────────────────────────