-
Notifications
You must be signed in to change notification settings - Fork 74
Expand file tree
/
Copy pathmain.py
More file actions
223 lines (179 loc) · 7.05 KB
/
Copy pathmain.py
File metadata and controls
223 lines (179 loc) · 7.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#!/usr/bin/env python3
from __future__ import annotations
import os
import signal
import sys
import logging
from logging.handlers import RotatingFileHandler
from typing import Any
from config.paths import ensure_data_dirs, get_logs_dir
from vibe.logging_config import APPLICATION_LOG_BACKUP_COUNT, APPLICATION_LOG_MAX_BYTES
from vibe.macos_session_diagnostics import start_macos_session_diagnostics
from vibe.runtime import (
ServiceAlreadyRunningError,
acquire_service_instance_lock,
consume_shutdown_intent,
release_service_instance_lock,
shutdown_intent_required,
)
def _build_logging_handlers(logs_dir: str) -> list[logging.Handler]:
handlers: list[logging.Handler] = [
RotatingFileHandler(
f"{logs_dir}/vibe_remote.log",
maxBytes=APPLICATION_LOG_MAX_BYTES,
backupCount=APPLICATION_LOG_BACKUP_COUNT,
)
]
if os.environ.get("VIBE_DISABLE_STDOUT_LOGGING", "").lower() not in {"1", "true", "yes"}:
handlers.insert(0, logging.StreamHandler(sys.stdout))
return handlers
def setup_logging(level: str = "INFO"):
"""Setup logging configuration with file location and line numbers"""
# Create a custom formatter with file location
log_format = '%(asctime)s - %(name)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(funcName)s() - %(message)s'
# For development, you can use this more detailed format:
# log_format = '%(asctime)s - %(name)s - %(levelname)s - [%(pathname)s:%(lineno)d] - %(funcName)s() - %(message)s'
ensure_data_dirs()
logs_dir = str(get_logs_dir())
logging.basicConfig(
level=getattr(logging, level.upper()),
format=log_format,
handlers=_build_logging_handlers(logs_dir),
)
def apply_claude_sdk_patches():
"""Apply runtime patches for third-party SDK limits."""
logger = logging.getLogger(__name__)
try:
from modules.claude_sdk_compat import CLAUDE_SDK_MAX_BUFFER_SIZE
from claude_agent_sdk._internal.transport import subprocess_cli
except Exception as exc:
logger.warning(f"Claude SDK patch skipped: {exc}")
return
patched = []
for attr in ("_DEFAULT_MAX_BUFFER_SIZE", "_MAX_BUFFER_SIZE"):
if not hasattr(subprocess_cli, attr):
continue
previous = getattr(subprocess_cli, attr)
setattr(subprocess_cli, attr, CLAUDE_SDK_MAX_BUFFER_SIZE)
if previous != CLAUDE_SDK_MAX_BUFFER_SIZE:
patched.append(f"{attr} from {previous} to {CLAUDE_SDK_MAX_BUFFER_SIZE} bytes")
if patched:
logger.info(
"Patched claude_agent_sdk buffer limits: %s",
", ".join(patched),
)
def load_config() -> Any:
from config.v2_config import V2Config
return V2Config.load()
def ensure_sqlite_state(*args, **kwargs):
from storage.importer import ensure_sqlite_state as _ensure_sqlite_state
return _ensure_sqlite_state(*args, **kwargs)
def prepare_sqlite_state(config: Any):
"""Run safe SQLite state migrations before the service starts."""
return ensure_sqlite_state(primary_platform=config.platform)
def _log_shutdown_signal(logger: logging.Logger, signum: int) -> None:
try:
logger.info(
"Received signal %s pid=%s ppid=%s pgid=%s sid=%s",
signum,
os.getpid(),
os.getppid(),
os.getpgid(0),
os.getsid(0),
)
except Exception:
logger.info("Received signal %s", signum)
def _log_shutdown_intent(logger: logging.Logger, signum: int) -> None:
if signum != signal.SIGTERM or not shutdown_intent_required():
return
intent = consume_shutdown_intent(os.getpid(), signum)
if intent is None:
logger.warning(
"No managed shutdown intent found for SIGTERM pid=%s; honoring signal",
os.getpid(),
)
return
logger.info("Accepted managed shutdown intent: %s", intent)
def _stop_macos_session_diagnostics(monitor: Any) -> None:
if monitor is None:
return
try:
monitor.stop()
except Exception:
logging.getLogger(__name__).debug("macOS session diagnostics cleanup failed")
def main():
"""Main entry point"""
lock_acquired = False
macos_session_diagnostics = None
try:
acquire_service_instance_lock()
lock_acquired = True
# Load configuration
config = load_config()
# Setup logging
setup_logging(config.runtime.log_level)
logger = logging.getLogger(__name__)
apply_claude_sdk_patches()
from vibe.sentry_integration import init_sentry
init_sentry(config, component="service")
logger.info("Starting vibe-remote service...")
logger.info(f"Working directory: {config.runtime.default_cwd}")
logger.info(
"Shutdown intent diagnostics enabled=%s env=%s",
shutdown_intent_required(),
os.environ.get("VIBE_REQUIRE_SHUTDOWN_INTENT"),
)
macos_session_diagnostics = start_macos_session_diagnostics(logger)
if sys.platform != "darwin":
from core.process_diagnostics import log_process_snapshot
log_process_snapshot(logger, "service-start")
report = prepare_sqlite_state(config)
logger.info(
"SQLite state ready: imported=%s db_path=%s backup_path=%s",
report.imported,
report.db_path,
report.backup_path,
)
# Create and run controller
from core.controller import Controller
from config.v2_compat import to_app_config
controller = Controller(to_app_config(config))
shutdown_initiated = False
def _handle_shutdown(signum, frame):
nonlocal shutdown_initiated
if shutdown_initiated:
return
shutdown_initiated = True
try:
_log_shutdown_signal(logger, signum)
_log_shutdown_intent(logger, signum)
logger.info("Shutting down after signal %s", signum)
except Exception:
pass
_stop_macos_session_diagnostics(macos_session_diagnostics)
try:
controller.cleanup_sync()
except Exception as cleanup_err:
logger.error(f"Cleanup failed: {cleanup_err}")
finally:
release_service_instance_lock()
raise SystemExit(0)
signal.signal(signal.SIGTERM, _handle_shutdown)
signal.signal(signal.SIGINT, _handle_shutdown)
try:
controller.run()
finally:
_stop_macos_session_diagnostics(macos_session_diagnostics)
release_service_instance_lock()
except ServiceAlreadyRunningError as e:
logging.error("Failed to start: %s", e)
sys.exit(2)
except Exception as e:
if lock_acquired:
release_service_instance_lock()
logging.error(f"Failed to start: {e}")
sys.exit(1)
finally:
_stop_macos_session_diagnostics(macos_session_diagnostics)
if __name__ == "__main__":
main()