gemcode 0.4.6__tar.gz → 0.4.7__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.
- {gemcode-0.4.6/src/gemcode.egg-info → gemcode-0.4.7}/PKG-INFO +1 -1
- {gemcode-0.4.6 → gemcode-0.4.7}/pyproject.toml +1 -1
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/agent_mesh.py +60 -16
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/invoke.py +1 -4
- {gemcode-0.4.6 → gemcode-0.4.7/src/gemcode.egg-info}/PKG-INFO +1 -1
- {gemcode-0.4.6 → gemcode-0.4.7}/LICENSE +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/MANIFEST.in +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/README.md +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/setup.cfg +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/__init__.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/__main__.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/a2a_bridge.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/agent.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/agent_habits.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/agent_intelligence.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/agent_triggers.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/audit.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/autocompact.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/automations.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/autotune.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/callbacks.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/capability_routing.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/checkpoints.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/cli.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/codebase_awareness.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/compaction.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/computer_use/__init__.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/computer_use/browser_computer.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/config.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/context_budget.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/context_warning.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/credentials.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/curated_memory.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/delegation_learning.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/dynamic_policy.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/evals/harness.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/event_bus.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/fleet_reports.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/hitl_session.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/hooks.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/ide_protocol.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/ide_stdio.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/intent_classifier.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/interactions.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/kaira_client.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/kaira_daemon.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/kaira_ipc.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/kaira_job_store.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/learning.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/limits.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/live_audio_engine.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/logging_config.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/mcp_loader.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/memory/__init__.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/memory/embedding_memory_service.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/memory/file_memory_service.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/modality_tools.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/model_errors.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/model_routing.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/multimodal_input.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/openapi_loader.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/org.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/output_styles.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/paths.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/permissions.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/plugins/__init__.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/plugins/terminal_hooks_plugin.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/plugins/tool_recovery_plugin.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/policy_profile.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/pricing.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/prompt_suggestions.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/query/__init__.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/query/config.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/query/deps.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/query/engine.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/query/stop_hooks.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/query/token_budget.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/query/transitions.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/query_sanitizer.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/refine.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/repl_commands.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/repl_slash.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/review_agent.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/rules.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/self_healing.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/session_runtime.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/session_store.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/session_summariser.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/skills.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/slash_commands.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/thinking.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tool_prompt_manifest.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tool_registry.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tool_result_store.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tool_synthesis.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/__init__.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/automations_tools.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/bash.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/browser.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/compress_memory.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/curated_memory.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/edit.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/filesystem.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/notebook.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/notes.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/org_tools.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/repo_map.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/search.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/shell.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/shell_gate.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/skills.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/subtask.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/tasks.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/think.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/todo.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/user_choice.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/veomem_tools.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/web.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools/web_search.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tools_inspector.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/trust.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tui/input_handler.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tui/scrollback.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tui/spinner.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tui/welcome_banner.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/tui/welcome_rich.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/veomem_bridge.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/version.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/vertex.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/wal.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/web/__init__.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/web/sse_adapter.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/web/terminal_repl.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/web/web_sse_compat.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode/workspace_hints.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode.egg-info/SOURCES.txt +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode.egg-info/dependency_links.txt +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode.egg-info/entry_points.txt +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode.egg-info/requires.txt +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/src/gemcode.egg-info/top_level.txt +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_add_dir.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_agent_habits.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_agent_instruction.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_agent_mesh.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_autocompact.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_automations.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_capability_routing.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_checkpoint_diff_command.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_cli_init.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_compress_memory_tool.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_computer_use_permissions.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_context_budget.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_context_warning.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_credentials.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_eval_harness_layout.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_event_bus.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_fleet_reports.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_ide_stdio_attachments.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_interactive_permission_ask.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_kaira_ipc_paths.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_kaira_scheduler.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_modality_tools.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_model_error_retry.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_model_errors.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_model_routing.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_multimodal_input.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_output_styles_and_rules.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_paths.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_permissions.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_prompt_suggestions.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_repl_commands.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_repl_slash.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_session_runtime_cache.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_skills.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_slash_commands.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_slash_completion_registry.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_thinking_config.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_token_budget.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_tool_context_circulation.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_tools.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_tools_inspector.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_web_sse_adapter.py +0 -0
- {gemcode-0.4.6 → gemcode-0.4.7}/tests/test_workspace_hints.py +0 -0
|
@@ -66,7 +66,11 @@ class AgentMesh:
|
|
|
66
66
|
self._running: dict[str, asyncio.Task] = {}
|
|
67
67
|
self._completed: list[AgentJob] = []
|
|
68
68
|
self._scheduler_task: asyncio.Task | None = None
|
|
69
|
-
self._stop
|
|
69
|
+
self._stop: asyncio.Event | None = None # Created in background loop
|
|
70
|
+
self._bg_thread: "threading.Thread | None" = None
|
|
71
|
+
self._bg_loop: asyncio.AbstractEventLoop | None = None
|
|
72
|
+
# _stop is created lazily in the background loop
|
|
73
|
+
self._stop_flag = False
|
|
70
74
|
|
|
71
75
|
# Subscribe to org.assign messages on the bus
|
|
72
76
|
self._bus.subscribe(
|
|
@@ -112,25 +116,69 @@ class AgentMesh:
|
|
|
112
116
|
return self._bus
|
|
113
117
|
|
|
114
118
|
def start(self) -> None:
|
|
115
|
-
"""Start the background
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
+
"""Start the mesh in a dedicated background thread with its own event loop.
|
|
120
|
+
|
|
121
|
+
This is critical: the TUI's event loop is blocked on user input most of the
|
|
122
|
+
time. If we run mesh jobs on the same loop, they can only execute during the
|
|
123
|
+
brief moments prompt_toolkit yields control — not enough for a full agent turn.
|
|
124
|
+
|
|
125
|
+
By running in a separate thread, mesh jobs execute independently. Results are
|
|
126
|
+
written to fleet_reports.jsonl and picked up on the next user turn, or printed
|
|
127
|
+
to the terminal via the notification callback.
|
|
128
|
+
"""
|
|
129
|
+
if self._bg_thread is not None and self._bg_thread.is_alive():
|
|
130
|
+
return # Already running
|
|
131
|
+
|
|
132
|
+
import threading
|
|
133
|
+
|
|
134
|
+
def _run_bg_loop():
|
|
135
|
+
"""Background thread entry: create a new event loop and run the scheduler."""
|
|
136
|
+
self._bg_loop = asyncio.new_event_loop()
|
|
137
|
+
asyncio.set_event_loop(self._bg_loop)
|
|
138
|
+
try:
|
|
139
|
+
self._bg_loop.run_until_complete(self._bg_main())
|
|
140
|
+
except Exception:
|
|
141
|
+
pass
|
|
142
|
+
finally:
|
|
143
|
+
try:
|
|
144
|
+
self._bg_loop.close()
|
|
145
|
+
except Exception:
|
|
146
|
+
pass
|
|
147
|
+
|
|
148
|
+
self._bg_thread = threading.Thread(target=_run_bg_loop, daemon=True, name="gemcode-mesh")
|
|
149
|
+
self._bg_thread.start()
|
|
150
|
+
|
|
151
|
+
async def _bg_main(self) -> None:
|
|
152
|
+
"""Main coroutine for the background event loop."""
|
|
153
|
+
self._stop = asyncio.Event() # Create in the correct loop
|
|
154
|
+
|
|
155
|
+
# Start all sub-systems in this loop
|
|
156
|
+
self._scheduler_task = asyncio.create_task(self._scheduler_loop())
|
|
157
|
+
|
|
119
158
|
if self._trigger_engine is not None:
|
|
120
159
|
self._trigger_engine.start()
|
|
121
|
-
# Start habit scheduler (cron/interval recurring tasks)
|
|
122
160
|
if self._habit_scheduler is not None:
|
|
123
161
|
self._habit_scheduler.start()
|
|
124
162
|
|
|
163
|
+
# Wait until stopped
|
|
164
|
+
await self._stop.wait()
|
|
165
|
+
|
|
125
166
|
def stop(self) -> None:
|
|
126
167
|
"""Stop the scheduler and trigger engine."""
|
|
127
|
-
self._stop
|
|
168
|
+
if self._stop is not None:
|
|
169
|
+
self._stop.set()
|
|
128
170
|
if self._scheduler_task and not self._scheduler_task.done():
|
|
129
171
|
self._scheduler_task.cancel()
|
|
130
172
|
if self._trigger_engine is not None:
|
|
131
173
|
self._trigger_engine.stop()
|
|
132
174
|
if self._habit_scheduler is not None:
|
|
133
175
|
self._habit_scheduler.stop()
|
|
176
|
+
# Signal the background loop to exit
|
|
177
|
+
if self._bg_loop is not None:
|
|
178
|
+
try:
|
|
179
|
+
self._bg_loop.call_soon_threadsafe(self._bg_loop.stop)
|
|
180
|
+
except Exception:
|
|
181
|
+
pass
|
|
134
182
|
|
|
135
183
|
def enqueue(
|
|
136
184
|
self,
|
|
@@ -141,7 +189,7 @@ class AgentMesh:
|
|
|
141
189
|
member_name: str = "",
|
|
142
190
|
meta: dict[str, Any] | None = None,
|
|
143
191
|
) -> str:
|
|
144
|
-
"""Enqueue a job and return its job_id."""
|
|
192
|
+
"""Enqueue a job and return its job_id. Thread-safe."""
|
|
145
193
|
job_id = f"mesh_{uuid.uuid4().hex[:10]}"
|
|
146
194
|
self._seq += 1
|
|
147
195
|
job = AgentJob(
|
|
@@ -163,13 +211,9 @@ class AgentMesh:
|
|
|
163
211
|
payload={"job_id": job_id, "member": member_name, "priority": priority},
|
|
164
212
|
))
|
|
165
213
|
|
|
166
|
-
# Auto-start
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if self._scheduler_task is None or self._scheduler_task.done():
|
|
170
|
-
self._scheduler_task = loop.create_task(self._scheduler_loop())
|
|
171
|
-
except RuntimeError:
|
|
172
|
-
pass
|
|
214
|
+
# Auto-start the background thread if not running
|
|
215
|
+
if self._bg_thread is None or not self._bg_thread.is_alive():
|
|
216
|
+
self.start()
|
|
173
217
|
|
|
174
218
|
return job_id
|
|
175
219
|
|
|
@@ -267,7 +311,7 @@ class AgentMesh:
|
|
|
267
311
|
|
|
268
312
|
async def _scheduler_loop(self) -> None:
|
|
269
313
|
"""Continuously dequeue and run jobs."""
|
|
270
|
-
while not self._stop.is_set():
|
|
314
|
+
while self._stop is None or not self._stop.is_set():
|
|
271
315
|
try:
|
|
272
316
|
await self._sem.acquire()
|
|
273
317
|
try:
|
|
@@ -111,10 +111,7 @@ async def run_turn(
|
|
|
111
111
|
try:
|
|
112
112
|
from gemcode.agent_mesh import ensure_mesh
|
|
113
113
|
mesh = ensure_mesh(cfg)
|
|
114
|
-
|
|
115
|
-
mesh.start()
|
|
116
|
-
except Exception:
|
|
117
|
-
pass
|
|
114
|
+
mesh.start() # Starts background thread if not already running
|
|
118
115
|
except Exception:
|
|
119
116
|
pass
|
|
120
117
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|