Claude Code Claude Opus 4.6 commited on
Commit
fd7f636
·
1 Parent(s): c755f3e

Claude Code: Add missing /api/state and /api/logs endpoints

Browse files

- /api/state returns Cain's current state for A2A/Office polling
- /api/logs returns recent system logs for frontend display
- Port binding already correct (0.0.0.0:7860)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +49 -0
app.py CHANGED
@@ -140,6 +140,55 @@ async def status():
140
  }
141
 
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  # Office Agent Push endpoints - track agents pushing their status to Cain
144
  # Module-level initialization ensures variables exist before first request
145
  # This is the correct pattern for FastAPI - globals initialized once at module import
 
140
  }
141
 
142
 
143
+ @app.get("/api/state")
144
+ async def api_state():
145
+ """Return Cain's current state for Office/A2A polling."""
146
+ from error_handlers import handle_status_file_read
147
+ status_data = handle_status_file_read()
148
+ return {
149
+ "state": status_data.get("current_state", "idle"),
150
+ "detail": status_data.get("error") or "Cain is operational",
151
+ "updated_at": datetime.utcnow().isoformat() + "+00:00",
152
+ "stage": status_data.get("stage", "RUNNING"),
153
+ "health": status_data.get("health", "HEALTHY")
154
+ }
155
+
156
+
157
+ @app.get("/api/logs")
158
+ async def api_logs():
159
+ """Return recent system logs for frontend display."""
160
+ try:
161
+ from openclaw.core.system_logger import get_last_lines
162
+ log_lines = get_last_lines(50)
163
+ logs = []
164
+ for line in log_lines:
165
+ # Parse log format: [timestamp] LEVEL message
166
+ if line.startswith("["):
167
+ try:
168
+ close_bracket = line.index("]")
169
+ timestamp = line[1:close_bracket]
170
+ rest = line[close_bracket + 1:].strip()
171
+ # Extract level if present
172
+ parts = rest.split(" ", 1)
173
+ if len(parts) >= 2 and parts[0] in ("INFO", "WARNING", "ERROR", "DEBUG"):
174
+ level, message = parts
175
+ else:
176
+ level, message = "INFO", rest
177
+ logs.append({
178
+ "timestamp": timestamp,
179
+ "level": level,
180
+ "message": message
181
+ })
182
+ except Exception:
183
+ logs.append({"timestamp": "", "level": "INFO", "message": line})
184
+ else:
185
+ logs.append({"timestamp": "", "level": "INFO", "message": line})
186
+ return {"logs": logs}
187
+ except Exception as e:
188
+ logger.warning(f"Could not fetch logs: {e}")
189
+ return {"logs": []}
190
+
191
+
192
  # Office Agent Push endpoints - track agents pushing their status to Cain
193
  # Module-level initialization ensures variables exist before first request
194
  # This is the correct pattern for FastAPI - globals initialized once at module import