gemcode 0.3.121__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.121/src/gemcode.egg-info → gemcode-0.4.0}/PKG-INFO +39 -32
  2. {gemcode-0.3.121 → gemcode-0.4.0}/README.md +37 -30
  3. {gemcode-0.3.121 → gemcode-0.4.0}/pyproject.toml +2 -2
  4. gemcode-0.4.0/src/gemcode/a2a_bridge.py +258 -0
  5. gemcode-0.4.0/src/gemcode/agent_intelligence.py +259 -0
  6. gemcode-0.4.0/src/gemcode/agent_mesh.py +536 -0
  7. gemcode-0.4.0/src/gemcode/agent_triggers.py +332 -0
  8. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/checkpoints.py +18 -0
  9. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/cli.py +1 -1
  10. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/config.py +3 -0
  11. gemcode-0.4.0/src/gemcode/delegation_learning.py +245 -0
  12. gemcode-0.4.0/src/gemcode/event_bus.py +201 -0
  13. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/fleet_reports.py +3 -1
  14. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/invoke.py +33 -220
  15. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/kaira_client.py +4 -2
  16. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/kaira_daemon.py +21 -7
  17. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/kaira_ipc.py +67 -0
  18. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/repl_slash.py +36 -13
  19. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/__init__.py +52 -0
  20. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/automations_tools.py +3 -3
  21. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/org_tools.py +113 -104
  22. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/subtask.py +21 -10
  23. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tui/scrollback.py +6 -3
  24. {gemcode-0.3.121 → gemcode-0.4.0/src/gemcode.egg-info}/PKG-INFO +39 -32
  25. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode.egg-info/SOURCES.txt +9 -0
  26. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode.egg-info/requires.txt +1 -1
  27. gemcode-0.4.0/tests/test_agent_mesh.py +96 -0
  28. gemcode-0.4.0/tests/test_event_bus.py +151 -0
  29. gemcode-0.4.0/tests/test_kaira_ipc_paths.py +39 -0
  30. {gemcode-0.3.121 → gemcode-0.4.0}/LICENSE +0 -0
  31. {gemcode-0.3.121 → gemcode-0.4.0}/MANIFEST.in +0 -0
  32. {gemcode-0.3.121 → gemcode-0.4.0}/setup.cfg +0 -0
  33. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/__init__.py +0 -0
  34. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/__main__.py +0 -0
  35. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/agent.py +0 -0
  36. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/audit.py +0 -0
  37. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/autocompact.py +0 -0
  38. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/automations.py +0 -0
  39. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/autotune.py +0 -0
  40. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/callbacks.py +0 -0
  41. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/capability_routing.py +0 -0
  42. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/compaction.py +0 -0
  43. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/computer_use/__init__.py +0 -0
  44. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/computer_use/browser_computer.py +0 -0
  45. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/context_budget.py +0 -0
  46. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/context_warning.py +0 -0
  47. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/credentials.py +0 -0
  48. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/curated_memory.py +0 -0
  49. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/dynamic_policy.py +0 -0
  50. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/evals/harness.py +0 -0
  51. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/hitl_session.py +0 -0
  52. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/hooks.py +0 -0
  53. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/ide_protocol.py +0 -0
  54. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/ide_stdio.py +0 -0
  55. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/intent_classifier.py +0 -0
  56. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/interactions.py +0 -0
  57. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/kaira_job_store.py +0 -0
  58. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/learning.py +0 -0
  59. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/limits.py +0 -0
  60. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/live_audio_engine.py +0 -0
  61. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/logging_config.py +0 -0
  62. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/mcp_loader.py +0 -0
  63. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/memory/__init__.py +0 -0
  64. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/memory/embedding_memory_service.py +0 -0
  65. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/memory/file_memory_service.py +0 -0
  66. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/modality_tools.py +0 -0
  67. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/model_errors.py +0 -0
  68. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/model_routing.py +0 -0
  69. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/multimodal_input.py +0 -0
  70. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/openapi_loader.py +0 -0
  71. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/org.py +0 -0
  72. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/output_styles.py +0 -0
  73. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/paths.py +0 -0
  74. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/permissions.py +0 -0
  75. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/plugins/__init__.py +0 -0
  76. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
  77. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
  78. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/policy_profile.py +0 -0
  79. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/pricing.py +0 -0
  80. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/prompt_suggestions.py +0 -0
  81. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/query/__init__.py +0 -0
  82. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/query/config.py +0 -0
  83. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/query/deps.py +0 -0
  84. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/query/engine.py +0 -0
  85. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/query/stop_hooks.py +0 -0
  86. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/query/token_budget.py +0 -0
  87. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/query/transitions.py +0 -0
  88. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/query_sanitizer.py +0 -0
  89. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/refine.py +0 -0
  90. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/repl_commands.py +0 -0
  91. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/review_agent.py +0 -0
  92. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/rules.py +0 -0
  93. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/session_runtime.py +0 -0
  94. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/session_store.py +0 -0
  95. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/session_summariser.py +0 -0
  96. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/skills.py +0 -0
  97. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/slash_commands.py +0 -0
  98. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/thinking.py +0 -0
  99. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tool_prompt_manifest.py +0 -0
  100. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tool_registry.py +0 -0
  101. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tool_result_store.py +0 -0
  102. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/bash.py +0 -0
  103. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/browser.py +0 -0
  104. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/compress_memory.py +0 -0
  105. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/curated_memory.py +0 -0
  106. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/edit.py +0 -0
  107. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/filesystem.py +0 -0
  108. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/notebook.py +0 -0
  109. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/notes.py +0 -0
  110. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/repo_map.py +0 -0
  111. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/search.py +0 -0
  112. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/shell.py +0 -0
  113. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/shell_gate.py +0 -0
  114. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/skills.py +0 -0
  115. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/tasks.py +0 -0
  116. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/think.py +0 -0
  117. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/todo.py +0 -0
  118. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/user_choice.py +0 -0
  119. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/veomem_tools.py +0 -0
  120. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/web.py +0 -0
  121. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools/web_search.py +0 -0
  122. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tools_inspector.py +0 -0
  123. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/trust.py +0 -0
  124. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tui/input_handler.py +0 -0
  125. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tui/spinner.py +0 -0
  126. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tui/welcome_banner.py +0 -0
  127. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/tui/welcome_rich.py +0 -0
  128. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/veomem_bridge.py +0 -0
  129. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/version.py +0 -0
  130. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/vertex.py +0 -0
  131. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/wal.py +0 -0
  132. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/web/__init__.py +0 -0
  133. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/web/sse_adapter.py +0 -0
  134. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/web/terminal_repl.py +0 -0
  135. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/web/web_sse_compat.py +0 -0
  136. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode/workspace_hints.py +0 -0
  137. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode.egg-info/dependency_links.txt +0 -0
  138. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode.egg-info/entry_points.txt +0 -0
  139. {gemcode-0.3.121 → gemcode-0.4.0}/src/gemcode.egg-info/top_level.txt +0 -0
  140. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_add_dir.py +0 -0
  141. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_agent_instruction.py +0 -0
  142. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_autocompact.py +0 -0
  143. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_automations.py +0 -0
  144. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_capability_routing.py +0 -0
  145. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_checkpoint_diff_command.py +0 -0
  146. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_cli_init.py +0 -0
  147. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_compress_memory_tool.py +0 -0
  148. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_computer_use_permissions.py +0 -0
  149. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_context_budget.py +0 -0
  150. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_context_warning.py +0 -0
  151. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_credentials.py +0 -0
  152. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_eval_harness_layout.py +0 -0
  153. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_fleet_reports.py +0 -0
  154. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_ide_stdio_attachments.py +0 -0
  155. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_interactive_permission_ask.py +0 -0
  156. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_kaira_scheduler.py +0 -0
  157. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_modality_tools.py +0 -0
  158. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_model_error_retry.py +0 -0
  159. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_model_errors.py +0 -0
  160. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_model_routing.py +0 -0
  161. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_multimodal_input.py +0 -0
  162. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_output_styles_and_rules.py +0 -0
  163. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_paths.py +0 -0
  164. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_permissions.py +0 -0
  165. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_prompt_suggestions.py +0 -0
  166. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_repl_commands.py +0 -0
  167. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_repl_slash.py +0 -0
  168. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_session_runtime_cache.py +0 -0
  169. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_skills.py +0 -0
  170. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_slash_commands.py +0 -0
  171. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_slash_completion_registry.py +0 -0
  172. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_thinking_config.py +0 -0
  173. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_token_budget.py +0 -0
  174. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_tool_context_circulation.py +0 -0
  175. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_tools.py +0 -0
  176. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_tools_inspector.py +0 -0
  177. {gemcode-0.3.121 → gemcode-0.4.0}/tests/test_web_sse_adapter.py +0 -0
  178. {gemcode-0.3.121 → 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.121
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
@@ -212,8 +212,10 @@ GemCode is designed for repository-native work rather than copy-paste chat workf
212
212
  | REPL | Stateful terminal interaction |
213
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,34 +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
- Background completions are visible on the runtime **bus** and also accumulated in **`.gemcode/fleet_reports.jsonl`** for the next manager turn (optional auto-continue). See `../docs/orchestration.md`.
367
+ GemCode includes a built-in multi-agent orchestration system that works automatically no separate daemon required.
366
368
 
367
- Docs:
368
- - `../docs/orchestration.md`
369
-
370
- In one terminal:
371
-
372
- ```bash
373
- gemcode kaira -C .
374
- ```
375
-
376
- In another terminal:
377
-
378
- ```bash
379
- gemcode -C .
380
- ```
381
-
382
- 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
383
375
 
376
+ Quick example in the REPL:
384
377
  ```text
385
- /org tree
386
- /org hire verifier "QA / test planner" subagent gemcode "Find risks, propose tests, review plans."
387
- /org assign verifier "Review the plan and propose tests"
388
- /kaira jobs
389
- /kaira follow <job_id_prefix>
378
+ > Analyze the auth module. Delegate security review to the verifier.
390
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)
391
384
 
392
385
  ### Start the IDE bridge
393
386
  ```bash
@@ -420,11 +413,21 @@ Status note:
420
413
  | `/rules` | Inspect active rules |
421
414
  | `/diff` | Show current diff/checkpoint diff |
422
415
  | `/rewind` | Restore checkpoints |
423
- | `/review` | Run a review workflow |
416
+ | `/review` | Run a parallel code review pipeline |
424
417
  | `/eval` | Run evaluation gates |
425
418
  | `/kaira` | Show scheduler usage help |
426
419
  | `/super` | Super mode: auto-approve tools, no GemCode HITL · `/super off` |
427
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
+
428
431
  Detailed behavior:
429
432
  - [`../docs/cli-and-repl.md`](../docs/cli-and-repl.md)
430
433
 
@@ -432,11 +435,15 @@ Detailed behavior:
432
435
 
433
436
  | Capability | What it adds |
434
437
  |---|---|
435
- | Deep research | research-focused tool routing and optional dedicated model path |
436
- | Embeddings | semantic search and optional embedding-backed memory |
437
- | 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 |
438
445
  | Browser/computer use | Playwright-backed browser automation and inspection |
439
- | Live audio | Gemini Live microphone sessions |
446
+ | Live audio | Gemini Live microphone sessions (experimental) |
440
447
 
441
448
  Detailed behavior:
442
449
  - [`../docs/capabilities.md`](../docs/capabilities.md)
@@ -20,8 +20,10 @@ GemCode is designed for repository-native work rather than copy-paste chat workf
20
20
  | REPL | Stateful terminal interaction |
21
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,34 +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
- Background completions are visible on the runtime **bus** and also accumulated in **`.gemcode/fleet_reports.jsonl`** for the next manager turn (optional auto-continue). See `../docs/orchestration.md`.
175
+ GemCode includes a built-in multi-agent orchestration system that works automatically no separate daemon required.
174
176
 
175
- Docs:
176
- - `../docs/orchestration.md`
177
-
178
- In one terminal:
179
-
180
- ```bash
181
- gemcode kaira -C .
182
- ```
183
-
184
- In another terminal:
185
-
186
- ```bash
187
- gemcode -C .
188
- ```
189
-
190
- 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
191
183
 
184
+ Quick example in the REPL:
192
185
  ```text
193
- /org tree
194
- /org hire verifier "QA / test planner" subagent gemcode "Find risks, propose tests, review plans."
195
- /org assign verifier "Review the plan and propose tests"
196
- /kaira jobs
197
- /kaira follow <job_id_prefix>
186
+ > Analyze the auth module. Delegate security review to the verifier.
198
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)
199
192
 
200
193
  ### Start the IDE bridge
201
194
  ```bash
@@ -228,11 +221,21 @@ Status note:
228
221
  | `/rules` | Inspect active rules |
229
222
  | `/diff` | Show current diff/checkpoint diff |
230
223
  | `/rewind` | Restore checkpoints |
231
- | `/review` | Run a review workflow |
224
+ | `/review` | Run a parallel code review pipeline |
232
225
  | `/eval` | Run evaluation gates |
233
226
  | `/kaira` | Show scheduler usage help |
234
227
  | `/super` | Super mode: auto-approve tools, no GemCode HITL · `/super off` |
235
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
+
236
239
  Detailed behavior:
237
240
  - [`../docs/cli-and-repl.md`](../docs/cli-and-repl.md)
238
241
 
@@ -240,11 +243,15 @@ Detailed behavior:
240
243
 
241
244
  | Capability | What it adds |
242
245
  |---|---|
243
- | Deep research | research-focused tool routing and optional dedicated model path |
244
- | Embeddings | semantic search and optional embedding-backed memory |
245
- | 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 |
246
253
  | Browser/computer use | Playwright-backed browser automation and inspection |
247
- | Live audio | Gemini Live microphone sessions |
254
+ | Live audio | Gemini Live microphone sessions (experimental) |
248
255
 
249
256
  Detailed behavior:
250
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.121"
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]