mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
## Summary - **Fix stuck sessions**: Root cause was `_stream_listener` infinite xread loop when Redis session metadata TTL expired — `hget` returned `None` which bypassed the `status != "running"` break condition. Fixed by treating `None` status as non-running. - **Fix stop button reliability**: Cancel endpoint now force-completes via `mark_session_completed` when executor doesn't respond within 5s. Returns `cancelled=True` for already-expired sessions. - **Single-owner StreamFinish**: All `yield StreamFinish()` removed from service layers (sdk/service.py, service.py, dummy.py). `mark_session_completed` is now the single atomic source of truth for publishing StreamFinish via Lua CAS script. - **Rename task → session/turn**: Consistent terminology across stream_registry and processor. - **Frontend session refetch**: Added `refetchOnMount: true` so page refresh re-fetches session state. - **Test fixes**: Updated e2e, service, and run_agent tests for StreamFinish removal; fixed async fixture decorators. ## Test plan - [x] E2E dummy streaming tests pass (13 passed, 1 xfailed) - [x] run_agent_test.py passes (async fixture decorator fix) - [x] service_test.py passes (StreamFinish assertions removed) - [ ] Manual: verify stuck sessions recover on page refresh - [ ] Manual: verify stop button works for active and expired sessions - [ ] Manual: verify no duplicate StreamFinish events in SSE stream
60 lines
1.6 KiB
Python
60 lines
1.6 KiB
Python
import logging
|
|
from typing import TYPE_CHECKING
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
|
|
if TYPE_CHECKING:
|
|
from backend.util.process import AppProcess
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def run_processes(*processes: "AppProcess", **kwargs):
|
|
"""
|
|
Execute all processes in the app. The last process is run in the foreground.
|
|
Includes enhanced error handling and process lifecycle management.
|
|
"""
|
|
try:
|
|
# Run all processes except the last one in the background.
|
|
for process in processes[:-1]:
|
|
process.start(background=True, **kwargs)
|
|
|
|
# Run the last process in the foreground.
|
|
processes[-1].start(background=False, **kwargs)
|
|
finally:
|
|
for process in reversed(processes):
|
|
try:
|
|
process.stop()
|
|
except Exception as e:
|
|
logger.exception(f"[{process.service_name}] unable to stop: {e}")
|
|
|
|
|
|
def main(**kwargs):
|
|
"""
|
|
Run all the processes required for the AutoGPT-server (REST and WebSocket APIs).
|
|
"""
|
|
|
|
from backend.api.rest_api import AgentServer
|
|
from backend.api.ws_api import WebsocketServer
|
|
from backend.copilot.executor.manager import CoPilotExecutor
|
|
from backend.data.db_manager import DatabaseManager
|
|
from backend.executor import ExecutionManager, Scheduler
|
|
from backend.notifications import NotificationManager
|
|
|
|
run_processes(
|
|
DatabaseManager().set_log_level("warning"),
|
|
Scheduler(),
|
|
NotificationManager(),
|
|
WebsocketServer(),
|
|
AgentServer(),
|
|
ExecutionManager(),
|
|
CoPilotExecutor(),
|
|
**kwargs,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|