File size: 3,379 Bytes
0efb0d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42ab226
0efb0d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
'use client'

import { useState } from 'react'
import { useRouter } from 'next/navigation'

export default function IngestModelsButton() {
  const router = useRouter()
  const [isIngesting, setIsIngesting] = useState(false)
  const [status, setStatus] = useState<string | null>(null)
  const [results, setResults] = useState<any>(null)

  const handleIngest = async () => {
    setIsIngesting(true)
    setStatus('Starting model ingestion... This may take several minutes.')
    setResults(null)

    try {
      // Use a longer timeout for the fetch request
      const controller = new AbortController()
      const timeoutId = setTimeout(() => controller.abort(), 600000) // 10 minutes

      // Try direct ingestion first (no Python required)
      let response = await fetch('/api/models/ingest-direct', {
        method: 'POST',
        signal: controller.signal,
      })

      // If direct ingestion fails, try Python pipeline
      if (!response.ok) {
        response = await fetch('/api/models/ingest', {
          method: 'POST',
          signal: controller.signal,
        })
      }

      clearTimeout(timeoutId)

      const data = await response.json()

      if (data.success) {
        setStatus('Model ingestion complete!')
        setResults(data)
        // Refresh the page to show new models
        setTimeout(() => {
          router.refresh()
        }, 2000)
      } else {
        setStatus(`Error: ${data.error || 'Unknown error'}`)
        setResults(data)
      }
    } catch (error: any) {
      if (error.name === 'AbortError') {
        setStatus('Ingestion is taking longer than expected. It may still be running in the background.')
        setResults({ 
          error: 'Request timeout',
          message: 'The ingestion process may still be running. Check back in a few minutes or check server logs.',
        })
      } else {
        setStatus(`Error: ${error.message}`)
        setResults({ error: error.message })
      }
    } finally {
      setIsIngesting(false)
    }
  }

  return (
    <div className="relative">
      <button
        onClick={handleIngest}
        disabled={isIngesting}
        className={`btn-secondary text-sm ${
          isIngesting ? 'opacity-50 cursor-not-allowed' : ''
        }`}
        title="Ingest priority models from Epoch AI and HuggingFace"
      >
        {isIngesting ? 'Ingesting... (this may take a few minutes)' : 'Ingest Models'}
      </button>
      
      {status && (
        <div className="absolute top-full right-0 mt-2 z-50 bg-surface border border-border rounded-none shadow-lg p-3 min-w-[300px]">
          <div className="text-xs font-semibold mb-2 text-text">{status}</div>
          {results && (
            <div className="text-xs text-text-muted space-y-1">
              {(results.models_ingested !== undefined || results.created !== undefined) && (
                <div className="text-accent">
                  Models ingested: {results.models_ingested || results.created || results.total || 0}
                </div>
              )}
              {results.error && (
                <div className="text-red-500 mt-2">{results.error}</div>
              )}
              {results.message && (
                <div className="text-text-muted mt-2">{results.message}</div>
              )}
            </div>
          )}
        </div>
      )}
    </div>
  )
}