akhaliq HF Staff commited on
Commit
deb8b94
Β·
1 Parent(s): 3aef00d
backend_api.py CHANGED
@@ -915,7 +915,19 @@ async def deploy(
915
  # PRIORITY 1: Check history for deployed/imported spaces (like Gradio version does)
916
  # This is more reliable than session tracking since history persists in frontend
917
  if request.history and auth.username:
918
- print(f"[Deploy] Checking history for deployed spaces ({len(request.history)} messages)...")
 
 
 
 
 
 
 
 
 
 
 
 
919
  for msg in request.history:
920
  role = msg.get('role', '')
921
  content = msg.get('content', '')
@@ -923,13 +935,18 @@ async def deploy(
923
  # Check for deployment confirmations
924
  if role == 'assistant' and ('βœ… Deployed!' in content or 'βœ… Updated!' in content):
925
  import re
 
 
926
  match = re.search(r'huggingface\.co/spaces/([^/\s\)]+/[^/\s\)]+)', content)
927
  if match:
928
  history_space_id = match.group(1)
929
- print(f"[Deploy] βœ… Found deployed space in history: {history_space_id}")
930
  if not existing_repo_id:
931
  existing_repo_id = history_space_id
 
932
  break
 
 
933
 
934
  # Check for imports
935
  elif role == 'user' and 'import' in content.lower():
@@ -943,6 +960,11 @@ async def deploy(
943
  if not existing_repo_id:
944
  existing_repo_id = imported_space
945
  break
 
 
 
 
 
946
 
947
  # PRIORITY 2: Check session for previously deployed spaces (fallback)
948
  # This helps when history isn't passed from frontend
 
915
  # PRIORITY 1: Check history for deployed/imported spaces (like Gradio version does)
916
  # This is more reliable than session tracking since history persists in frontend
917
  if request.history and auth.username:
918
+ print(f"[Deploy] ========== CHECKING HISTORY ==========")
919
+ print(f"[Deploy] History length: {len(request.history)} messages")
920
+ print(f"[Deploy] Username: {auth.username}")
921
+
922
+ # Log each message in history for debugging
923
+ for i, msg in enumerate(request.history):
924
+ role = msg.get('role', 'unknown')
925
+ content = msg.get('content', '')
926
+ content_preview = content[:100] if content else ''
927
+ print(f"[Deploy] Message {i+1}: role={role}, content_preview='{content_preview}...'")
928
+
929
+ print(f"[Deploy] ==========================================")
930
+
931
  for msg in request.history:
932
  role = msg.get('role', '')
933
  content = msg.get('content', '')
 
935
  # Check for deployment confirmations
936
  if role == 'assistant' and ('βœ… Deployed!' in content or 'βœ… Updated!' in content):
937
  import re
938
+ print(f"[Deploy] πŸ” Found deployment message in history!")
939
+ print(f"[Deploy] Content: {content[:200]}")
940
  match = re.search(r'huggingface\.co/spaces/([^/\s\)]+/[^/\s\)]+)', content)
941
  if match:
942
  history_space_id = match.group(1)
943
+ print(f"[Deploy] βœ… EXTRACTED space ID from history: {history_space_id}")
944
  if not existing_repo_id:
945
  existing_repo_id = history_space_id
946
+ print(f"[Deploy] βœ… WILL UPDATE EXISTING SPACE: {existing_repo_id}")
947
  break
948
+ else:
949
+ print(f"[Deploy] ⚠️ Deployment message found but couldn't extract space ID")
950
 
951
  # Check for imports
952
  elif role == 'user' and 'import' in content.lower():
 
960
  if not existing_repo_id:
961
  existing_repo_id = imported_space
962
  break
963
+ else:
964
+ if not request.history:
965
+ print(f"[Deploy] ⚠️ No history provided in request")
966
+ if not auth.username:
967
+ print(f"[Deploy] ⚠️ No username available")
968
 
969
  # PRIORITY 2: Check session for previously deployed spaces (fallback)
970
  # This helps when history isn't passed from frontend
frontend/src/app/page.tsx CHANGED
@@ -433,13 +433,20 @@ export default function Home() {
433
  console.log('[Deploy] Username:', currentUsername);
434
  console.log('[Deploy] Existing space from history:', existingSpace);
435
  console.log('[Deploy] Will create new space?', !existingSpace);
 
 
 
 
 
 
 
436
  console.log('[Deploy] =================================================================');
437
 
438
  // Build deploy request, omitting undefined fields
439
  const deployRequest: any = {
440
  code: generatedCode,
441
  language: selectedLanguage,
442
- history: messages.map(msg => ({ role: msg.role, content: msg.content })) // Pass full chat history
443
  };
444
 
445
  // Only include optional fields if they have values
@@ -478,12 +485,12 @@ export default function Home() {
478
  }
479
  }
480
 
481
- // Add deployment message to chat (EXACT Gradio format with markdown link)
482
  const deployMessage: Message = {
483
  role: 'assistant',
484
  content: existingSpace
485
- ? `Updated! [Open your app here](${response.space_url})`
486
- : `Deployed! [Open your app here](${response.space_url})`,
487
  timestamp: new Date().toISOString(),
488
  };
489
  setMessages((prev) => [...prev, deployMessage]);
 
433
  console.log('[Deploy] Username:', currentUsername);
434
  console.log('[Deploy] Existing space from history:', existingSpace);
435
  console.log('[Deploy] Will create new space?', !existingSpace);
436
+ console.log('[Deploy] Messages count:', messages.length);
437
+ console.log('[Deploy] Messages (first 3):', messages.slice(0, 3).map(m => ({ role: m.role, content: m.content.substring(0, 100) })));
438
+
439
+ // CRITICAL DEBUG: Check what we're actually sending
440
+ const historyToSend = messages.map(msg => ({ role: msg.role, content: msg.content }));
441
+ console.log('[Deploy] History to send (length):', historyToSend.length);
442
+ console.log('[Deploy] History to send (first 2):', historyToSend.slice(0, 2));
443
  console.log('[Deploy] =================================================================');
444
 
445
  // Build deploy request, omitting undefined fields
446
  const deployRequest: any = {
447
  code: generatedCode,
448
  language: selectedLanguage,
449
+ history: historyToSend // Use the variable we just logged
450
  };
451
 
452
  // Only include optional fields if they have values
 
485
  }
486
  }
487
 
488
+ // Add deployment message to chat (EXACT format backend expects)
489
  const deployMessage: Message = {
490
  role: 'assistant',
491
  content: existingSpace
492
+ ? `βœ… Updated! View your space at: ${response.space_url}`
493
+ : `βœ… Deployed! View your space at: ${response.space_url}`,
494
  timestamp: new Date().toISOString(),
495
  };
496
  setMessages((prev) => [...prev, deployMessage]);
frontend/src/lib/api.ts CHANGED
@@ -1,6 +1,7 @@
1
  // API client for AnyCoder backend
2
 
3
  import axios, { AxiosInstance } from 'axios';
 
4
  import type {
5
  Model,
6
  AuthStatus,
@@ -54,7 +55,12 @@ class ApiClient {
54
 
55
  // Add auth token to requests if available
56
  this.client.interceptors.request.use((config) => {
57
- if (this.token) {
 
 
 
 
 
58
  config.headers.Authorization = `Bearer ${this.token}`;
59
  }
60
  return config;
@@ -274,7 +280,8 @@ class ApiClient {
274
  method: 'POST',
275
  headers: {
276
  'Content-Type': 'application/json',
277
- ...(this.token ? { 'Authorization': `Bearer ${this.token}` } : {}),
 
278
  },
279
  body: JSON.stringify(request),
280
  signal: abortController.signal,
 
1
  // API client for AnyCoder backend
2
 
3
  import axios, { AxiosInstance } from 'axios';
4
+ import { getStoredSessionToken } from './auth'; // NEW: Import session token
5
  import type {
6
  Model,
7
  AuthStatus,
 
55
 
56
  // Add auth token to requests if available
57
  this.client.interceptors.request.use((config) => {
58
+ // Use session token instead of OAuth token for session tracking
59
+ const sessionToken = getStoredSessionToken();
60
+ if (sessionToken) {
61
+ config.headers.Authorization = `Bearer ${sessionToken}`;
62
+ } else if (this.token) {
63
+ // Fallback to OAuth token if no session token
64
  config.headers.Authorization = `Bearer ${this.token}`;
65
  }
66
  return config;
 
280
  method: 'POST',
281
  headers: {
282
  'Content-Type': 'application/json',
283
+ ...(getStoredSessionToken() ? { 'Authorization': `Bearer ${getStoredSessionToken()}` } :
284
+ this.token ? { 'Authorization': `Bearer ${this.token}` } : {}),
285
  },
286
  body: JSON.stringify(request),
287
  signal: abortController.signal,
frontend/src/lib/auth.ts CHANGED
@@ -1,6 +1,7 @@
1
  // HuggingFace OAuth authentication utilities (Server-side flow for Docker Spaces)
2
 
3
  const STORAGE_KEY = 'hf_oauth_token';
 
4
  const USER_INFO_KEY = 'hf_user_info';
5
  const DEV_MODE_KEY = 'hf_dev_mode';
6
  const API_BASE = '/api';
@@ -71,8 +72,9 @@ export async function initializeOAuth(): Promise<OAuthResult | null> {
71
  userInfo,
72
  };
73
 
74
- // Store the OAuth result
75
  storeOAuthData(oauthResult);
 
76
 
77
  // Clean up URL
78
  window.history.replaceState({}, document.title, window.location.pathname);
@@ -129,6 +131,7 @@ export async function loginWithHuggingFace(): Promise<void> {
129
  export function logout(): void {
130
  if (typeof window !== 'undefined') {
131
  localStorage.removeItem(STORAGE_KEY);
 
132
  localStorage.removeItem(USER_INFO_KEY);
133
  localStorage.removeItem(DEV_MODE_KEY);
134
  }
@@ -144,6 +147,25 @@ function storeOAuthData(result: OAuthResult): void {
144
  }
145
  }
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  /**
148
  * Get stored access token
149
  */
 
1
  // HuggingFace OAuth authentication utilities (Server-side flow for Docker Spaces)
2
 
3
  const STORAGE_KEY = 'hf_oauth_token';
4
+ const SESSION_KEY = 'hf_session_token'; // NEW: Store session UUID
5
  const USER_INFO_KEY = 'hf_user_info';
6
  const DEV_MODE_KEY = 'hf_dev_mode';
7
  const API_BASE = '/api';
 
72
  userInfo,
73
  };
74
 
75
+ // Store the OAuth result AND session token
76
  storeOAuthData(oauthResult);
77
+ storeSessionToken(sessionToken); // NEW: Store session UUID
78
 
79
  // Clean up URL
80
  window.history.replaceState({}, document.title, window.location.pathname);
 
131
  export function logout(): void {
132
  if (typeof window !== 'undefined') {
133
  localStorage.removeItem(STORAGE_KEY);
134
+ localStorage.removeItem(SESSION_KEY); // NEW: Clear session token
135
  localStorage.removeItem(USER_INFO_KEY);
136
  localStorage.removeItem(DEV_MODE_KEY);
137
  }
 
147
  }
148
  }
149
 
150
+ /**
151
+ * Store session token in localStorage
152
+ */
153
+ function storeSessionToken(sessionToken: string): void {
154
+ if (typeof window !== 'undefined') {
155
+ localStorage.setItem(SESSION_KEY, sessionToken);
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Get stored session token
161
+ */
162
+ export function getStoredSessionToken(): string | null {
163
+ if (typeof window !== 'undefined') {
164
+ return localStorage.getItem(SESSION_KEY);
165
+ }
166
+ return null;
167
+ }
168
+
169
  /**
170
  * Get stored access token
171
  */