krishnadhulipalla commited on
Commit
8da73c0
Β·
1 Parent(s): 7e89912

added logs

Browse files
Files changed (4) hide show
  1. backend/agent.py +36 -42
  2. backend/api.py +48 -4
  3. backend/g_cal.py +7 -10
  4. ui/src/useChat.tsx +8 -0
backend/agent.py CHANGED
@@ -27,6 +27,9 @@ from langgraph.graph import StateGraph, START, END
27
  from langgraph.prebuilt import ToolNode
28
  from langgraph.checkpoint.memory import MemorySaver
29
 
 
 
 
30
  # from google.oauth2.credentials import Credentials
31
  # from google_auth_oauthlib.flow import InstalledAppFlow
32
  # from googleapiclient.discovery import build
@@ -264,21 +267,6 @@ def memory_flush():
264
  memory_dirty = False
265
  memory_write_count = 0
266
 
267
- # def _get_gcal_service():
268
- # creds = None
269
- # if TOKEN_FILE.exists():
270
- # creds = Credentials.from_authorized_user_file(str(TOKEN_FILE), GOOGLE_SCOPES)
271
- # if not creds or not creds.valid:
272
- # if creds and creds.expired and creds.refresh_token:
273
- # creds.refresh(Request()) # type: ignore
274
- # else:
275
- # flow = InstalledAppFlow.from_client_secrets_file(str(CLIENT_SECRET_FILE), GOOGLE_SCOPES)
276
- # # This opens a local browser once per server instance to authorize
277
- # creds = flow.run_local_server(port=8765, prompt="consent")
278
- # with open(TOKEN_FILE, "w") as f:
279
- # f.write(creds.to_json())
280
- # return build("calendar", "v3", credentials=creds)
281
-
282
  class Attendee(TypedDict):
283
  email: str
284
  optional: Optional[bool]
@@ -298,36 +286,42 @@ def schedule_meeting(
298
  Create a Google Calendar event (and optional Google Meet link).
299
  Returns a human-readable confirmation.
300
  """
301
- svc = get_gcal_service()
302
-
303
- body = {
304
- "summary": title,
305
- "description": description or "",
306
- "location": location or "",
307
- "start": {"dateTime": start_rfc3339},
308
- "end": {"dateTime": end_rfc3339},
309
- "attendees": [{"email": a["email"], "optional": a.get("optional", False)} for a in (attendees or [])],
310
- }
311
-
312
- params = {}
313
- if make_meet_link:
314
- body["conferenceData"] = {
315
- "createRequest": {"requestId": str(uuid4())}
316
  }
317
- params["conferenceDataVersion"] = 1
318
 
319
- event = svc.events().insert(calendarId=calendar_id, body=body, **params).execute()
320
- meet = (
321
- (event.get("conferenceData") or {})
322
- .get("entryPoints", [{}])[0]
323
- .get("uri")
324
- if make_meet_link
325
- else None
326
- )
 
 
 
 
 
 
 
 
327
 
328
- attendee_str = ", ".join([a["email"] for a in (attendees or [])]) or "no attendees"
329
- when = f'{event["start"]["dateTime"]} β†’ {event["end"]["dateTime"]}'
330
- return f"βœ… Scheduled: {title}\nπŸ“… When: {when}\nπŸ‘₯ With: {attendee_str}\nπŸ”— Meet: {meet or 'β€”'}\nπŸ—‚οΈ Calendar: {calendar_id}\nπŸ†” Event ID: {event.get('id','')}"
 
 
 
331
 
332
  @tool("update_meeting")
333
  def update_meeting(
 
27
  from langgraph.prebuilt import ToolNode
28
  from langgraph.checkpoint.memory import MemorySaver
29
 
30
+ import logging
31
+ tool_log = logging.getLogger("tools")
32
+
33
  # from google.oauth2.credentials import Credentials
34
  # from google_auth_oauthlib.flow import InstalledAppFlow
35
  # from googleapiclient.discovery import build
 
267
  memory_dirty = False
268
  memory_write_count = 0
269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  class Attendee(TypedDict):
271
  email: str
272
  optional: Optional[bool]
 
286
  Create a Google Calendar event (and optional Google Meet link).
287
  Returns a human-readable confirmation.
288
  """
289
+ try:
290
+ tool_log.info(f"schedule_meeting args title={title} start={start_rfc3339} end={end_rfc3339} attendees={[a.get('email') for a in (attendees or [])]}")
291
+ svc = get_gcal_service()
292
+
293
+ body = {
294
+ "summary": title,
295
+ "description": description or "",
296
+ "location": location or "",
297
+ "start": {"dateTime": start_rfc3339},
298
+ "end": {"dateTime": end_rfc3339},
299
+ "attendees": [{"email": a["email"], "optional": a.get("optional", False)} for a in (attendees or [])],
 
 
 
 
300
  }
 
301
 
302
+ params = {}
303
+ if make_meet_link:
304
+ body["conferenceData"] = {
305
+ "createRequest": {"requestId": str(uuid4())}
306
+ }
307
+ params["conferenceDataVersion"] = 1
308
+
309
+ event = svc.events().insert(calendarId=calendar_id, body=body, **params).execute()
310
+ tool_log.info(f"βœ… created event id={event.get('id')} html={event.get('htmlLink')}")
311
+ meet = (
312
+ (event.get("conferenceData") or {})
313
+ .get("entryPoints", [{}])[0]
314
+ .get("uri")
315
+ if make_meet_link
316
+ else None
317
+ )
318
 
319
+ attendee_str = ", ".join([a["email"] for a in (attendees or [])]) or "no attendees"
320
+ when = f'{event["start"]["dateTime"]} β†’ {event["end"]["dateTime"]}'
321
+ return f"βœ… Scheduled: {title}\nπŸ“… When: {when}\nπŸ‘₯ With: {attendee_str}\nπŸ”— Meet: {meet or 'β€”'}\nπŸ—‚οΈ Calendar: {calendar_id}\nπŸ†” Event ID: {event.get('id','')}"
322
+ except Exception as e:
323
+ tool_log.exception("❌ schedule_meeting failed")
324
+ return f"Calendar error: {e}"
325
 
326
  @tool("update_meeting")
327
  def update_meeting(
backend/api.py CHANGED
@@ -12,6 +12,16 @@ from uuid import uuid4
12
  from pathlib import Path
13
  import json, secrets, urllib.parse, os
14
  from google_auth_oauthlib.flow import Flow
 
 
 
 
 
 
 
 
 
 
15
 
16
  from .agent import app as lg_app
17
 
@@ -33,6 +43,14 @@ api.add_middleware(
33
  allow_credentials=True,
34
  )
35
 
 
 
 
 
 
 
 
 
36
  from .g_cal import SCOPES, TOKEN_FILE
37
 
38
  CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
@@ -78,7 +96,21 @@ def oauth_callback(request: Request):
78
 
79
  @api.get("/api/health")
80
  def health():
81
- return {"ok": True}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  # --- GET route for EventSource (matches the React UI I gave you) ---
84
  # GET
@@ -136,16 +168,28 @@ UI_DIST = REPO_ROOT / "ui" / "dist"
136
 
137
  RESUME_PATH = REPO_ROOT / "backend" / "assets" / "KrishnaVamsiDhulipalla.pdf"
138
 
139
- @api.get("/resume/download")
140
  def resume_download():
 
141
  if not RESUME_PATH.is_file():
142
- return PlainTextResponse("Resume not found", status_code=404)
143
- # Same-origin download; content-disposition prompts save/open dialog
144
  return FileResponse(
145
  path=str(RESUME_PATH),
146
  media_type="application/pdf",
147
  filename="Krishna_Vamsi_Dhulipalla_Resume.pdf",
148
  )
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
  if UI_DIST.is_dir():
151
  api.mount("/", StaticFiles(directory=str(UI_DIST), html=True), name="ui")
 
12
  from pathlib import Path
13
  import json, secrets, urllib.parse, os
14
  from google_auth_oauthlib.flow import Flow
15
+ from .g_cal import get_gcal_service
16
+
17
+
18
+ # logging + helpers
19
+ import logging, os, time
20
+ from datetime import datetime, timezone
21
+ from fastapi.responses import JSONResponse, FileResponse, RedirectResponse
22
+
23
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s :: %(message)s")
24
+ log = logging.getLogger("api")
25
 
26
  from .agent import app as lg_app
27
 
 
43
  allow_credentials=True,
44
  )
45
 
46
+ # logging + helpers
47
+ import logging, os, time
48
+ from datetime import datetime, timezone
49
+ from fastapi.responses import JSONResponse, FileResponse, RedirectResponse
50
+
51
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s :: %(message)s")
52
+ log = logging.getLogger("api")
53
+
54
  from .g_cal import SCOPES, TOKEN_FILE
55
 
56
  CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
 
96
 
97
  @api.get("/api/health")
98
  def health():
99
+ return {"ok": True, "ts": datetime.now(timezone.utc).isoformat()}
100
+
101
+ @api.get("/api/debug/routes")
102
+ def list_routes():
103
+ return {"routes": sorted([getattr(r, "path", str(r)) for r in api.router.routes])}
104
+
105
+ @api.get("/api/debug/env")
106
+ def debug_env():
107
+ return {
108
+ "public_base_url": os.getenv("PUBLIC_BASE_URL"),
109
+ "has_google_client_id": bool(os.getenv("GOOGLE_CLIENT_ID")),
110
+ "has_google_client_secret": bool(os.getenv("GOOGLE_CLIENT_SECRET")),
111
+ "ui_dist_exists": UI_DIST.is_dir(),
112
+ "resume_exists": RESUME_PATH.is_file(),
113
+ }
114
 
115
  # --- GET route for EventSource (matches the React UI I gave you) ---
116
  # GET
 
168
 
169
  RESUME_PATH = REPO_ROOT / "backend" / "assets" / "KrishnaVamsiDhulipalla.pdf"
170
 
171
+ @api.get("/api/resume/download")
172
  def resume_download():
173
+ log.info(f"πŸ“„ resume download hit; exists={RESUME_PATH.is_file()} path={RESUME_PATH}")
174
  if not RESUME_PATH.is_file():
175
+ return JSONResponse({"ok": False, "error": "Resume not found"}, status_code=404)
 
176
  return FileResponse(
177
  path=str(RESUME_PATH),
178
  media_type="application/pdf",
179
  filename="Krishna_Vamsi_Dhulipalla_Resume.pdf",
180
  )
181
+
182
+ @api.get("/api/health/google")
183
+ def google_health():
184
+ try:
185
+ svc = get_gcal_service()
186
+ data = svc.calendarList().list(maxResults=1).execute()
187
+ names = [item.get("summary") for item in data.get("items", [])]
188
+ log.info(f"🟒 Google token OK; calendars={names}")
189
+ return {"ok": True, "calendars": names}
190
+ except Exception as e:
191
+ log.exception("πŸ”΄ Google Calendar health failed")
192
+ return JSONResponse({"ok": False, "error": str(e)}, status_code=500)
193
 
194
  if UI_DIST.is_dir():
195
  api.mount("/", StaticFiles(directory=str(UI_DIST), html=True), name="ui")
backend/g_cal.py CHANGED
@@ -1,21 +1,18 @@
1
- # backend/gcal.py
2
- import os
3
  from pathlib import Path
4
  from google.oauth2.credentials import Credentials
5
  from googleapiclient.discovery import build
6
 
7
- # Same scope you used everywhere
8
- SCOPES = ["https://www.googleapis.com/auth/calendar.events"]
9
 
10
- # HF Spaces persistent disk path (Settings β†’ Persistent storage)
11
  TOKEN_FILE = Path(os.getenv("GCAL_TOKEN_PATH", "/data/google_token.json"))
12
 
13
  def get_gcal_service():
14
- """
15
- Load saved Google OAuth credentials and return a Calendar API client.
16
- Raise a clear error if not connected yet.
17
- """
18
  if not TOKEN_FILE.exists():
19
  raise RuntimeError("Google Calendar not connected. Visit /oauth/google/start to connect.")
20
  creds = Credentials.from_authorized_user_file(str(TOKEN_FILE), SCOPES)
21
- return build("calendar", "v3", credentials=creds)
 
 
 
1
+ import os, logging
 
2
  from pathlib import Path
3
  from google.oauth2.credentials import Credentials
4
  from googleapiclient.discovery import build
5
 
6
+ log = logging.getLogger("g_cal")
 
7
 
8
+ SCOPES = ["https://www.googleapis.com/auth/calendar.events"]
9
  TOKEN_FILE = Path(os.getenv("GCAL_TOKEN_PATH", "/data/google_token.json"))
10
 
11
  def get_gcal_service():
12
+ log.info(f"πŸ” get_gcal_service token_path={TOKEN_FILE} exists={TOKEN_FILE.exists()}")
 
 
 
13
  if not TOKEN_FILE.exists():
14
  raise RuntimeError("Google Calendar not connected. Visit /oauth/google/start to connect.")
15
  creds = Credentials.from_authorized_user_file(str(TOKEN_FILE), SCOPES)
16
+ svc = build("calendar", "v3", credentials=creds)
17
+ log.info("βœ… built calendar service client")
18
+ return svc
ui/src/useChat.tsx CHANGED
@@ -186,6 +186,14 @@ export function useChat() {
186
  url.searchParams.set("thread_id", thread_id);
187
 
188
  const es = new EventSource(url.toString());
 
 
 
 
 
 
 
 
189
  esRef.current = es;
190
  setIsStreaming(true);
191
  setHasFirstToken(false);
 
186
  url.searchParams.set("thread_id", thread_id);
187
 
188
  const es = new EventSource(url.toString());
189
+ es.addEventListener("tool", (ev: MessageEvent) => {
190
+ try {
191
+ const data = JSON.parse((ev as MessageEvent<string>).data || "{}");
192
+ console.log("[TOOL]", data.phase, data.name);
193
+ } catch {
194
+ console.log("[TOOL]", (ev as MessageEvent<string>).data);
195
+ }
196
+ });
197
  esRef.current = es;
198
  setIsStreaming(true);
199
  setHasFirstToken(false);