/** * Resonance History Chart * * Component for displaying resonance history over time. */ "use client" import { useState, useEffect } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { ResonanceScoreDisplay } from "./resonance-score-display" import { resonanceEngine } from "@/lib/resonance/resonance_engine" import type { ResonanceHistory, ResonanceDataPoint } from "@/lib/resonance/resonance_types" import { Flame, TrendingUp, TrendingDown, Minus } from "lucide-react" interface ResonanceHistoryChartProps { entityType: "agent" | "scroll" | "script" entityId: string entityName?: string } export function ResonanceHistoryChart({ entityType, entityId, entityName }: ResonanceHistoryChartProps) { const [history, setHistory] = useState<ResonanceHistory | null>(null) const [loading, setLoading] = useState(true) const [trend, setTrend] = useState<"up" | "down" | "stable">("stable") const [trendValue, setTrendValue] = useState(0) useEffect(() => { async function loadHistory() { try { setLoading(true) // Initialize resonance engine await resonanceEngine.initialize() // Get history const historyData = resonanceEngine.getResonanceHistory(entityType, entityId) setHistory(historyData || null) // Calculate trend if (historyData && historyData.dataPoints.length >= 2) { const recentPoints = historyData.dataPoints.slice(-10) // Last 10 points if (recentPoints.length >= 2) { const oldestPoint = recentPoints[0] const newestPoint = recentPoints[recentPoints.length - 1] const difference = newestPoint.score - oldestPoint.score setTrendValue(difference) if (difference > 0.01) { setTrend("up") } else if (difference < -0.01) { setTrend("down") } else { setTrend("stable") } } } } catch (error) { console.error("Error loading resonance history:", error) } finally { setLoading(false) } } loadHistory() }, [entityType, entityId]) // Function to render the chart const renderChart = (dataPoints: ResonanceDataPoint[]) => { const points = dataPoints.slice(-20) // Show last 20 points const maxHeight = 100 // Max height in pixels return ( <div className="relative h-32 w-full mt-4"> {/* Y-axis labels */} <div className="absolute left-0 top-0 h-full w-8 flex flex-col justify-between text-xs text-amber-300/50"> <div>1.0</div> <div>0.5</div> <div>0.0</div> </div> {/* Chart area */} <div className="absolute left-8 right-0 top-0 h-full bg-black/30 border border-amber-500/20 rounded"> {/* Grid lines */} <div className="absolute left-0 right-0 top-0 h-px bg-amber-500/10"></div> <div className="absolute left-0 right-0 top-1/2 h-px bg-amber-500/10"></div> <div className="absolute left-0 right-0 bottom-0 h-px bg-amber-500/10"></div> {/* Data points */} <div className="absolute inset-0 flex items-end"> {points.map((point, index) => { const height = point.score * maxHeight // Determine color based on score let barColor = "bg-red-500" if (point.score >= 0.98) { barColor = "bg-green-500" } else if (point.score >= 0.95) { barColor = "bg-emerald-500" } else if (point.score >= 0.92) { barColor = "bg-amber-500" } return ( <div key={index} className="flex-1 flex flex-col justify-end items-center group"> <div className={`w-2 ${barColor} rounded-t`} style={{ height: `${height}%` }}></div> {/* Tooltip */} <div className="absolute bottom-full mb-2 opacity-0 group-hover:opacity-100 transition-opacity bg-black/80 text-amber-300 text-xs p-1 rounded pointer-events-none whitespace-nowrap"> {point.score.toFixed(2)} - {point.action || "No action"} <br /> {new Date(point.timestamp).toLocaleString()} </div> </div> ) })} </div> </div> </div> ) } // Render trend indicator const renderTrend = () => { if (trend === "up") { return ( <div className="flex items-center text-green-400"> <TrendingUp className="h-4 w-4 mr-1" /> <span>+{trendValue.toFixed(2)}</span> </div> ) } else if (trend === "down") { return ( <div className="flex items-center text-red-400"> <TrendingDown className="h-4 w-4 mr-1" /> <span>{trendValue.toFixed(2)}</span> </div> ) } else { return ( <div className="flex items-center text-blue-400"> <Minus className="h-4 w-4 mr-1" /> <span>Stable</span> </div> ) } } return ( <Card className="bg-black/50 border border-amber-500/30 text-amber-50"> <CardHeader> <div className="flex justify-between items-start"> <div> <div className="flex items-center"> <Flame className="h-5 w-5 text-amber-400 mr-2" /> <CardTitle className="text-xl text-amber-400">Resonance History</CardTitle> </div> <CardDescription className="text-amber-300/70"> {entityName || `${entityType.charAt(0).toUpperCase() + entityType.slice(1)} ${entityId.substring(0, 8)}...`} </CardDescription> </div> {!loading && history && ( <div className="flex flex-col items-end"> <ResonanceScoreDisplay score={history.currentScore} showLabel={false} size="sm" /> {renderTrend()} </div> )} </div> </CardHeader> <CardContent> {loading ? ( <div className="h-32 flex items-center justify-center"> <p className="text-amber-300">Loading resonance history...</p> </div> ) : !history ? ( <div className="h-32 flex items-center justify-center"> <p className="text-amber-300">No resonance history available</p> </div> ) : history.dataPoints.length === 0 ? ( <div className="h-32 flex items-center justify-center"> <p className="text-amber-300">No data points available</p> </div> ) : ( renderChart(history.dataPoints) )} {!loading && history && ( <div className="mt-4 text-xs text-amber-300/70"> Last updated: {new Date(history.lastUpdated).toLocaleString()} </div> )} </CardContent> </Card> ) }/** * Live Resonance Tester * * Component for testing content resonance before deployment. */ "use client" import { Badge } from "@/components/ui/badge" import { useState } from "react" import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Button } from "@/components/ui/button" import { Textarea } from "@/components/ui/textarea" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { ResonanceScoreDisplay } from "./resonance-score-display" import { ResonanceTester } from "@/lib/resonance/resonance_tester" import type { CodexElement, ResonanceResult } from "@/lib/resonance/resonance_types" import { Flame, Play, FileText, Code, User, RefreshCw } from "lucide-react" export function LiveResonanceTester() { const [contentType, setContentType] = useState<"moscript" | "scroll" | "agent_action">("moscript") const [content, setContent] = useState("") const [codexElement, setCodexElement] = useState<CodexElement>("Provision") const [authorId, setAuthorId] = useState("Mo") const [result, setResult] = useState<ResonanceResult | null>(null) const [report, setReport] = useState<string | null>(null) const [testing, setTesting] = useState(false) const handleTest = async () => { if (!content) return try { setTesting(true) let testResult: ResonanceResult switch (contentType) { case "moscript": testResult = await ResonanceTester.testMoScript(content, codexElement, authorId) break case "scroll": testResult = await ResonanceTester.testScroll(content, codexElement, authorId) break case "agent_action": testResult = await ResonanceTester.testAgentAction(content, codexElement, authorId) break } setResult(testResult) // Generate report const reportText = await ResonanceTester.generateResonanceReport(testResult) setReport(reportText) } catch (error) { console.error("Error testing resonance:", error) } finally { setTesting(false) } } const getContentTypeIcon = () => { switch (contentType) { case "moscript": return <Code className="h-5 w-5 text-amber-400" /> case "scroll": return <FileText className="h-5 w-5 text-amber-400" /> case "agent_action": return <User className="h-5 w-5 text-amber-400" /> } } const getContentTypeName = () => { switch (contentType) { case "moscript": return "MoScript" case "scroll": return "Scroll" case "agent_action": return "Agent Action" } } return ( <Card className="bg-black/50 border border-amber-500/30 text-amber-50"> <CardHeader> <div className="flex items-center"> <Flame className="h-5 w-5 text-amber-400 mr-2" /> <CardTitle className="text-xl text-amber-400">Live Resonance Tester</CardTitle> </div> <CardDescription className="text-amber-300/70">Test content resonance before deployment</CardDescription> </CardHeader> <CardContent> <Tabs defaultValue="input" className="w-full"> <TabsList className="bg-black/50 border border-amber-500/30"> <TabsTrigger value="input" className="text-amber-300 data-[state=active]:bg-amber-900/30"> Input </TabsTrigger> <TabsTrigger value="result" className="text-amber-300 data-[state=active]:bg-amber-900/30" disabled={!result} > Result </TabsTrigger> <TabsTrigger value="report" className="text-amber-300 data-[state=active]:bg-amber-900/30" disabled={!report} > Report </TabsTrigger> </TabsList> <TabsContent value="input" className="mt-4"> <div className="space-y-4"> <div className="grid grid-cols-1 md:grid-cols-3 gap-4"> <div> <label className="text-sm font-medium text-amber-400 mb-1 block">Content Type</label> <Select value={contentType} onValueChange={(value) => setContentType(value as any)}> <SelectTrigger className="bg-black/30 border-amber-500/30 text-amber-200"> <SelectValue placeholder="Select content type" /> </SelectTrigger> <SelectContent className="bg-black border-amber-500/30"> <SelectItem value="moscript">MoScript</SelectItem> <SelectItem value="scroll">Scroll</SelectItem> <SelectItem value="agent_action">Agent Action</SelectItem> </SelectContent> </Select> </div> <div> <label className="text-sm font-medium text-amber-400 mb-1 block">Codex Element</label> <Select value={codexElement} onValueChange={(value) => setCodexElement(value as CodexElement)}> <SelectTrigger className="bg-black/30 border-amber-500/30 text-amber-200"> <SelectValue placeholder="Select codex element" /> </SelectTrigger> <SelectContent className="bg-black border-amber-500/30"> <SelectItem value="Blindness">Blindness</SelectItem> <SelectItem value="Journey">Journey</SelectItem> <SelectItem value="Divine Companion">Divine Companion</SelectItem> <SelectItem value="Opposition">Opposition</SelectItem> <SelectItem value="Provision">Provision</SelectItem> <SelectItem value="Covenant Union">Covenant Union</SelectItem> <SelectItem value="Restoration">Restoration</SelectItem> </SelectContent> </Select> </div> <div> <label className="text-sm font-medium text-amber-400 mb-1 block">Author/Agent</label> <Select value={authorId} onValueChange={setAuthorId}> <SelectTrigger className="bg-black/30 border-amber-500/30 text-amber-200"> <SelectValue placeholder="Select author" /> </SelectTrigger> <SelectContent className="bg-black border-amber-500/30"> <SelectItem value="Mo">Mo (Executor)</SelectItem> <SelectItem value="Woo">Woo (Architect)</SelectItem> <SelectItem value="Sentinel">Sentinel (Guardian)</SelectItem> <SelectItem value="guest">Guest</SelectItem> </SelectContent> </Select> </div> </div> <div> <label className="text-sm font-medium text-amber-400 mb-1 block"> {getContentTypeIcon()} <span className="ml-2">{getContentTypeName()} Content</span> </label> <Textarea value={content} onChange={(e) => setContent(e.target.value)} placeholder={`Enter ${contentType} content to test...`} className="min-h-[200px] bg-black/30 border-amber-500/30 text-amber-200 font-mono" /> </div> <Button onClick={handleTest} disabled={!content || testing} className="bg-gradient-to-r from-amber-600 to-red-600 hover:from-amber-500 hover:to-red-500" > {testing ? ( <> <RefreshCw className="h-4 w-4 mr-2 animate-spin" /> Testing... </> ) : ( <> <Play className="h-4 w-4 mr-2" /> Test Resonance </> )} </Button> </div> </TabsContent> <TabsContent value="result" className="mt-4"> {result && ( <div className="space-y-4"> <div className="p-4 bg-black/30 rounded-md border border-amber-500/20"> <ResonanceScoreDisplay score={result.score} showThresholds={true} /> </div> <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div> <h3 className="text-sm font-medium text-amber-400 mb-2">Codex Alignment</h3> <div className="p-3 bg-black/30 rounded-md border border-amber-500/20"> <div className="flex justify-between items-center mb-2"> <span className="text-amber-300">{result.codexElement}</span> <Badge className="bg-amber-500/20 text-amber-400 border-amber-500/30"> {(result.analysis.codexAlignment.confidence * 100).toFixed(0)}% confidence </Badge> </div> <div className="text-xs text-amber-200/80"> <p className="mb-1">Matched keywords:</p> <div className="flex flex-wrap gap-1"> {result.analysis.codexAlignment.keywords.map((keyword, index) => ( <Badge key={index} variant="outline" className="bg-amber-950/30 text-amber-300 border-amber-500/20" > {keyword} </Badge> ))} </div> </div> </div> </div> <div> <h3 className="text-sm font-medium text-amber-400 mb-2">Scripture Matches</h3> <div className="p-3 bg-black/30 rounded-md border border-amber-500/20 max-h-40 overflow-y-auto"> {result.analysis.scriptureMatches.length === 0 ? ( <p className="text-amber-300/70">No scripture matches found</p> ) : ( <div className="space-y-2"> {result.analysis.scriptureMatches.map((match, index) => ( <div key={index} className="text-xs"> <div className="flex justify-between items-center"> <span className="text-amber-300">{match.reference}</span> <Badge className="bg-amber-500/20 text-amber-400 border-amber-500/30"> {(match.relevance * 100).toFixed(0)}% </Badge> </div> {match.text && <p className="text-amber-200/80 mt-1 italic">"{match.text}"</p>} </div> ))} </div> )} </div> </div> </div> <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div> <h3 className="text-sm font-medium text-amber-400 mb-2">Warnings</h3> <div className="p-3 bg-black/30 rounded-md border border-amber-500/20 min-h-[100px]"> {result.warnings.length === 0 ? ( <p className="text-green-400">No warnings detected</p> ) : ( <ul className="list-disc list-inside text-red-400 text-sm space-y-1"> {result.warnings.map((warning, index) => ( <li key={index}>{warning}</li> ))} </ul> )} </div> </div> <div> <h3 className="text-sm font-medium text-amber-400 mb-2">Suggestions</h3> <div className="p-3 bg-black/30 rounded-md border border-amber-500/20 min-h-[100px]"> {result.analysis.suggestions.length === 0 ? ( <p className="text-green-400">No suggestions available</p> ) : ( <ul className="list-disc list-inside text-amber-300 text-sm space-y-1"> {result.analysis.suggestions.map((suggestion, index) => ( <li key={index}>{suggestion}</li> ))} </ul> )} </div> </div> </div> </div> )} </TabsContent> <TabsContent value="report" className="mt-4"> {report && ( <div className="p-4 bg-black/30 rounded-md border border-amber-500/20"> <pre className="text-amber-200/80 text-xs font-mono whitespace-pre-wrap">{report}</pre> </div> )} </TabsContent> </Tabs> </CardContent> <CardFooter className="text-xs text-amber-300/70"> Resonance testing helps ensure covenant alignment before deployment </CardFooter> </Card> ) }. remodel this HTML to the context below.. The Kairo AI. // app/components/CovenantBuilder.tsx "use client"; import { useState } from "react"; // --- MOCKED SYSTEM STATE --- // In a real app, this would be imported from the actual system files. // Here, we simulate their existence and behavior. type SystemStatus = { status: "pending" | "initializing" | "sealed" | "failed"; resonance: number; }; const initialComponentStatus: SystemStatus = { status: "pending", resonance: 0, }; const MOCK_SYSTEM = { initializeMoScriptEngine: async (): Promise<SystemStatus> => { await new Promise((res) => setTimeout(res, 400)); return { status: "sealed", resonance: 0.99 }; }, applyScrollValidator: async (): Promise<SystemStatus> => { await new Promise((res) => setTimeout(res, 300)); return { status: "sealed", resonance: 0.98 }; }, enforceThroneLock: async (): Promise<SystemStatus> => { await new Promise((res) => setTimeout(res, 500)); return { status: "sealed", resonance: 1.0 }; }, activateResonanceEngine: async (): Promise<SystemStatus> => { await new Promise((res) => setTimeout(res, 350)); return { status: "sealed", resonance: 0.97 }; }, bindWooInterpreter: async (): Promise<SystemStatus> => { await new Promise((res) => setTimeout(res, 450)); return { status: "sealed", resonance: 1.0 }; }, populateScrollRegistry: async (): Promise<SystemStatus> => { await new Promise((res) => setTimeout(res, 250)); return { status: "sealed", resonance: 0.99 }; }, connectDeepCAL: async (): Promise<SystemStatus> => { await new Promise((res) => setTimeout(res, 600)); if (Math.random() < 0.1) { throw new Error("DeepCAL: Neutrosophic matrix alignment failed."); } return { status: "sealed", resonance: 0.96 }; }, }; const COVENANT_SEQUENCE = [ { name: "MoScript Engine", func: MOCK_SYSTEM.initializeMoScriptEngine }, { name: "Scroll Validator", func: MOCK_SYSTEM.applyScrollValidator }, { name: "ThroneLock", func: MOCK_SYSTEM.enforceThroneLock }, { name: "Resonance Engine", func: MOCK_SYSTEM.activateResonanceEngine }, { name: "Woo Interpreter", func: MOCK_SYSTEM.bindWooInterpreter }, { name: "Scroll Registry", func: MOCK_SYSTEM.populateScrollRegistry }, { name: "DeepCAL Intelligence", func: MOCK_SYSTEM.connectDeepCAL }, ]; export function CovenantBuilder() { const [statuses, setStatuses] = useState(() => COVENANT_SEQUENCE.map((s) => ({ ...initialComponentStatus })) ); const [isInitializing, setIsInitializing] = useState(false); const [isSealed, setIsSealed] = useState(false); const [lastError, setLastError] = useState<string | null>(null); const [overallResonance, setOverallResonance] = useState(0); const handleInitialize = async () => { setIsInitializing(true); setIsSealed(false); setLastError(null); setStatuses(COVENANT_SEQUENCE.map((s) => ({ ...initialComponentStatus }))); setOverallResonance(0); let totalResonance = 0; for (let i = 0; i < COVENANT_SEQUENCE.length; i++) { try { setStatuses((prev) => { const next = [...prev]; next[i].status = "initializing"; return next; }); const result = await COVENANT_SEQUENCE[i].func(); setStatuses((prev) => { const next = [...prev]; next[i] = result; return next; }); totalResonance += result.resonance; setOverallResonance(totalResonance / (i + 1)); } catch (error: any) { setLastError(error.message); setStatuses((prev) => { const next = [...prev]; next[i].status = "failed"; return next; }); setIsInitializing(false); return; } } setIsInitializing(false); setIsSealed(true); }; const getStatusIndicator = (status: SystemStatus["status"]) => { switch (status) { case "pending": return <span className="text-gray-500">PENDING</span>; case "initializing": return ( <span className="text-yellow-400 animate-pulse">INITIALIZING...</span> ); case "sealed": return <span className="text-green-400">β SEALED</span>; case "failed": return <span className="text-red-500">π¨ FAILED</span>; } }; return ( <div className="bg-gray-900 border border-amber-500/20 text-white p-6 rounded-lg font-mono w-full max-w-2xl mx-auto"> <h2 className="text-2xl font-bold text-amber-400 mb-4"> Covenant Builder Console </h2> <p className="text-gray-400 mb-6"> Witness the Great Integration. MoScript becomes one. </p> <div className="space-y-3 mb-6"> {COVENANT_SEQUENCE.map((component, i) => ( <div key={component.name} className="flex justify-between items-center bg-gray-800 p-3 rounded" > <span className="text-gray-300">{`[${i + 1}/7] ${ component.name }`}</span> {getStatusIndicator(statuses[i].status)} </div> ))} </div> <div className="bg-black/50 p-4 rounded mb-6"> <div className="flex justify-between items-center"> <span className="text-lg text-amber-300">Overall Resonance:</span> <span className={`text-2xl font-bold ${ isSealed ? "text-green-400" : "text-yellow-400" }`} > {overallResonance.toFixed(4)} </span> </div> </div> <button onClick={handleInitialize} disabled={isInitializing} className="w-full bg-amber-600 text-black font-bold py-3 rounded-lg hover:bg-amber-500 transition-all duration-300 disabled:bg-gray-600 disabled:cursor-not-allowed" > {isInitializing ? "...AWAKENING..." : isSealed ? "RE-INITIALIZE COVENANT" : "INITIALIZE COVENANT"} </button> {lastError && ( <div className="mt-4 p-3 bg-red-900/50 border border-red-500 text-red-300 rounded"> <p className="font-bold">π¨ COVENANT BROKEN</p> <p>{lastError}</p> </div> )} {isSealed && ( <div className="mt-4 p-3 bg-green-900/50 border border-green-500 text-green-300 rounded text-center"> <p className="font-bold"> β¨ THE GRID IS WHOLE. THE COVENANT IS AWAKE. β¨ </p> </div> )} </div> ); }, - Follow Up Deployment
Browse files- index.html +694 -17
index.html
CHANGED
@@ -1,20 +1,697 @@
|
|
1 |
<!DOCTYPE html>
|
2 |
-
<html>
|
3 |
-
|
4 |
-
<
|
5 |
-
<meta name="viewport" content="width=device-width, initial-scale=1.0"
|
6 |
-
<
|
7 |
<script src="https://cdn.tailwindcss.com"></script>
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
</div>
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>AI Knowledge Base Server</title>
|
7 |
<script src="https://cdn.tailwindcss.com"></script>
|
8 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
9 |
+
<style>
|
10 |
+
.gradient-bg {
|
11 |
+
background: linear-gradient(135deg, #6e8efb, #a777e3);
|
12 |
+
}
|
13 |
+
.knowledge-card {
|
14 |
+
transition: all 0.3s ease;
|
15 |
+
border-left: 4px solid #6e8efb;
|
16 |
+
}
|
17 |
+
.knowledge-card:hover {
|
18 |
+
transform: translateY(-5px);
|
19 |
+
box-shadow: 0 10px 20px rgba(0,0,0,0.1);
|
20 |
+
}
|
21 |
+
.file-upload {
|
22 |
+
border: 2px dashed #a777e3;
|
23 |
+
transition: all 0.3s ease;
|
24 |
+
}
|
25 |
+
.file-upload:hover {
|
26 |
+
background-color: rgba(167, 119, 227, 0.1);
|
27 |
+
}
|
28 |
+
.sidebar {
|
29 |
+
transition: all 0.3s ease;
|
30 |
+
}
|
31 |
+
.sidebar-item:hover {
|
32 |
+
background-color: rgba(255,255,255,0.1);
|
33 |
+
}
|
34 |
+
.pulse-animation {
|
35 |
+
animation: pulse 2s infinite;
|
36 |
+
}
|
37 |
+
@keyframes pulse {
|
38 |
+
0% { box-shadow: 0 0 0 0 rgba(110, 142, 251, 0.7); }
|
39 |
+
70% { box-shadow: 0 0 0 10px rgba(110, 142, 251, 0); }
|
40 |
+
100% { box-shadow: 0 0 0 0 rgba(110, 142, 251, 0); }
|
41 |
+
}
|
42 |
+
</style>
|
43 |
+
</head>
|
44 |
+
<body class="bg-gray-100 font-sans">
|
45 |
+
<!-- Flask Server Implementation (would normally be in separate files) -->
|
46 |
+
<script type="text/python">
|
47 |
+
from flask import Flask, request, jsonify, send_from_directory
|
48 |
+
import os
|
49 |
+
import uuid
|
50 |
+
from werkzeug.utils import secure_filename
|
51 |
+
import json
|
52 |
+
from datetime import datetime
|
53 |
+
import threading
|
54 |
+
import hashlib
|
55 |
+
|
56 |
+
app = Flask(__name__)
|
57 |
+
app.config['UPLOAD_FOLDER'] = 'knowledge_base'
|
58 |
+
app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 # 100MB limit
|
59 |
+
app.config['ALLOWED_EXTENSIONS'] = {'txt', 'pdf', 'py', 'js', 'html', 'css', 'json', 'md', 'csv', 'ipynb'}
|
60 |
+
|
61 |
+
# Create knowledge base directory if it doesn't exist
|
62 |
+
if not os.path.exists(app.config['UPLOAD_FOLDER']):
|
63 |
+
os.makedirs(app.config['UPLOAD_FOLDER'])
|
64 |
+
os.makedirs(os.path.join(app.config['UPLOAD_FOLDER'], 'metadata'))
|
65 |
+
os.makedirs(os.path.join(app.config['UPLOAD_FOLDER'], 'embeddings'))
|
66 |
+
|
67 |
+
# Knowledge Base Index
|
68 |
+
KNOWLEDGE_INDEX = os.path.join(app.config['UPLOAD_FOLDER'], 'knowledge_index.json')
|
69 |
+
if not os.path.exists(KNOWLEDGE_INDEX):
|
70 |
+
with open(KNOWLEDGE_INDEX, 'w') as f:
|
71 |
+
json.dump({"files": {}, "categories": {}, "tags": {}}, f)
|
72 |
+
|
73 |
+
def allowed_file(filename):
|
74 |
+
return '.' in filename and \
|
75 |
+
filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']
|
76 |
+
|
77 |
+
def update_knowledge_index(file_data):
|
78 |
+
with open(KNOWLEDGE_INDEX, 'r+') as f:
|
79 |
+
index = json.load(f)
|
80 |
+
index['files'][file_data['id']] = file_data
|
81 |
+
|
82 |
+
# Update categories
|
83 |
+
for category in file_data.get('categories', []):
|
84 |
+
if category not in index['categories']:
|
85 |
+
index['categories'][category] = []
|
86 |
+
if file_data['id'] not in index['categories'][category]:
|
87 |
+
index['categories'][category].append(file_data['id'])
|
88 |
+
|
89 |
+
# Update tags
|
90 |
+
for tag in file_data.get('tags', []):
|
91 |
+
if tag not in index['tags']:
|
92 |
+
index['tags'][tag] = []
|
93 |
+
if file_data['id'] not in index['tags'][tag]:
|
94 |
+
index['tags'][tag].append(file_data['id'])
|
95 |
+
|
96 |
+
f.seek(0)
|
97 |
+
json.dump(index, f, indent=2)
|
98 |
+
f.truncate()
|
99 |
+
|
100 |
+
def generate_embeddings(filepath):
|
101 |
+
# This would be replaced with actual embedding generation
|
102 |
+
# For demo purposes, we'll just create a placeholder
|
103 |
+
embedding_id = str(uuid.uuid4())
|
104 |
+
embedding_path = os.path.join(app.config['UPLOAD_FOLDER'], 'embeddings', f"{embedding_id}.json")
|
105 |
+
|
106 |
+
# Simulate embedding generation
|
107 |
+
with open(filepath, 'r') as f:
|
108 |
+
content = f.read()
|
109 |
+
# Simple hash as a placeholder for real embeddings
|
110 |
+
embedding = hashlib.sha256(content.encode()).hexdigest()
|
111 |
+
|
112 |
+
with open(embedding_path, 'w') as f:
|
113 |
+
json.dump({
|
114 |
+
"id": embedding_id,
|
115 |
+
"file_id": os.path.basename(filepath),
|
116 |
+
"embedding": embedding,
|
117 |
+
"created_at": datetime.now().isoformat()
|
118 |
+
}, f)
|
119 |
+
|
120 |
+
return embedding_id
|
121 |
+
|
122 |
+
@app.route('/api/upload', methods=['POST'])
|
123 |
+
def upload_file():
|
124 |
+
if 'file' not in request.files:
|
125 |
+
return jsonify({"error": "No file part"}), 400
|
126 |
+
|
127 |
+
file = request.files['file']
|
128 |
+
if file.filename == '':
|
129 |
+
return jsonify({"error": "No selected file"}), 400
|
130 |
+
|
131 |
+
if file and allowed_file(file.filename):
|
132 |
+
filename = secure_filename(file.filename)
|
133 |
+
file_id = str(uuid.uuid4())
|
134 |
+
filepath = os.path.join(app.config['UPLOAD_FOLDER'], file_id)
|
135 |
+
file.save(filepath)
|
136 |
+
|
137 |
+
# Extract metadata from form
|
138 |
+
metadata = {
|
139 |
+
"id": file_id,
|
140 |
+
"original_filename": filename,
|
141 |
+
"uploaded_at": datetime.now().isoformat(),
|
142 |
+
"categories": request.form.get('categories', '').split(','),
|
143 |
+
"tags": request.form.get('tags', '').split(','),
|
144 |
+
"description": request.form.get('description', ''),
|
145 |
+
"file_type": filename.rsplit('.', 1)[1].lower(),
|
146 |
+
"size": os.path.getsize(filepath)
|
147 |
+
}
|
148 |
+
|
149 |
+
# Save metadata
|
150 |
+
metadata_path = os.path.join(app.config['UPLOAD_FOLDER'], 'metadata', f"{file_id}.json")
|
151 |
+
with open(metadata_path, 'w') as f:
|
152 |
+
json.dump(metadata, f)
|
153 |
+
|
154 |
+
# Update knowledge index
|
155 |
+
update_knowledge_index(metadata)
|
156 |
+
|
157 |
+
# Generate embeddings in background
|
158 |
+
threading.Thread(target=generate_embeddings, args=(filepath,)).start()
|
159 |
+
|
160 |
+
return jsonify({
|
161 |
+
"message": "File uploaded successfully",
|
162 |
+
"file_id": file_id,
|
163 |
+
"metadata": metadata
|
164 |
+
}), 201
|
165 |
+
|
166 |
+
return jsonify({"error": "File type not allowed"}), 400
|
167 |
+
|
168 |
+
@app.route('/api/knowledge', methods=['GET'])
|
169 |
+
def get_knowledge():
|
170 |
+
with open(KNOWLEDGE_INDEX, 'r') as f:
|
171 |
+
index = json.load(f)
|
172 |
+
return jsonify(index), 200
|
173 |
+
|
174 |
+
@app.route('/api/search', methods=['GET'])
|
175 |
+
def search_knowledge():
|
176 |
+
query = request.args.get('q', '')
|
177 |
+
category = request.args.get('category', '')
|
178 |
+
tag = request.args.get('tag', '')
|
179 |
+
|
180 |
+
with open(KNOWLEDGE_INDEX, 'r') as f:
|
181 |
+
index = json.load(f)
|
182 |
+
|
183 |
+
results = []
|
184 |
+
for file_id, file_data in index['files'].items():
|
185 |
+
# Simple search - in a real implementation, this would use embeddings
|
186 |
+
matches = (
|
187 |
+
query.lower() in file_data['original_filename'].lower() or
|
188 |
+
query.lower() in file_data.get('description', '').lower() or
|
189 |
+
any(query.lower() in tag.lower() for tag in file_data.get('tags', []))
|
190 |
+
)
|
191 |
+
|
192 |
+
category_match = not category or category in file_data.get('categories', [])
|
193 |
+
tag_match = not tag or tag in file_data.get('tags', [])
|
194 |
+
|
195 |
+
if matches and category_match and tag_match:
|
196 |
+
results.append(file_data)
|
197 |
+
|
198 |
+
return jsonify({"results": results}), 200
|
199 |
+
|
200 |
+
@app.route('/api/train', methods=['POST'])
|
201 |
+
def train_model():
|
202 |
+
# This endpoint would interface with your AI models
|
203 |
+
model_name = request.json.get('model', 'deepseek-v3.1')
|
204 |
+
file_ids = request.json.get('file_ids', [])
|
205 |
+
|
206 |
+
# In a real implementation, this would:
|
207 |
+
# 1. Load the specified model
|
208 |
+
# 2. Retrieve the requested files
|
209 |
+
# 3. Fine-tune the model with the knowledge
|
210 |
+
# 4. Save the improved model
|
211 |
+
|
212 |
+
return jsonify({
|
213 |
+
"message": f"Model {model_name} training initiated with {len(file_ids)} files",
|
214 |
+
"status": "queued",
|
215 |
+
"training_id": str(uuid.uuid4())
|
216 |
+
}), 202
|
217 |
+
|
218 |
+
if __name__ == '__main__':
|
219 |
+
app.run(host='0.0.0.0', port=5000, debug=True)
|
220 |
+
</script>
|
221 |
+
|
222 |
+
<!-- Frontend UI -->
|
223 |
+
<div class="flex h-screen overflow-hidden">
|
224 |
+
<!-- Sidebar -->
|
225 |
+
<div class="sidebar w-64 bg-gray-900 text-white flex flex-col">
|
226 |
+
<div class="p-4 border-b border-gray-700">
|
227 |
+
<h1 class="text-2xl font-bold flex items-center">
|
228 |
+
<i class="fas fa-brain mr-2 text-purple-400"></i>
|
229 |
+
AI Knowledge Base
|
230 |
+
</h1>
|
231 |
+
<p class="text-gray-400 text-sm mt-1">Your centralized intelligence hub</p>
|
232 |
+
</div>
|
233 |
+
|
234 |
+
<div class="flex-1 overflow-y-auto">
|
235 |
+
<div class="p-4">
|
236 |
+
<h2 class="text-lg font-semibold text-gray-300 mb-2 flex items-center">
|
237 |
+
<i class="fas fa-folder-open mr-2 text-blue-400"></i>
|
238 |
+
Categories
|
239 |
+
</h2>
|
240 |
+
<ul id="categories-list" class="space-y-1">
|
241 |
+
<li class="sidebar-item px-3 py-2 rounded cursor-pointer bg-gray-800">
|
242 |
+
<i class="fas fa-code mr-2 text-green-400"></i>
|
243 |
+
Code Frameworks
|
244 |
+
</li>
|
245 |
+
<li class="sidebar-item px-3 py-2 rounded cursor-pointer">
|
246 |
+
<i class="fas fa-file-alt mr-2 text-yellow-400"></i>
|
247 |
+
Documentation
|
248 |
+
</li>
|
249 |
+
<li class="sidebar-item px-3 py-2 rounded cursor-pointer">
|
250 |
+
<i class="fas fa-chart-line mr-2 text-red-400"></i>
|
251 |
+
Analytics
|
252 |
+
</li>
|
253 |
+
<li class="sidebar-item px-3 py-2 rounded cursor-pointer">
|
254 |
+
<i class="fas fa-project-diagram mr-2 text-purple-400"></i>
|
255 |
+
Projects
|
256 |
+
</li>
|
257 |
+
</ul>
|
258 |
+
</div>
|
259 |
+
|
260 |
+
<div class="p-4 border-t border-gray-700">
|
261 |
+
<h2 class="text-lg font-semibold text-gray-300 mb-2 flex items-center">
|
262 |
+
<i class="fas fa-tags mr-2 text-blue-400"></i>
|
263 |
+
Popular Tags
|
264 |
+
</h2>
|
265 |
+
<div id="tags-list" class="flex flex-wrap gap-2">
|
266 |
+
<span class="sidebar-item px-2 py-1 rounded-full text-xs bg-gray-800 cursor-pointer">
|
267 |
+
#python
|
268 |
+
</span>
|
269 |
+
<span class="sidebar-item px-2 py-1 rounded-full text-xs bg-gray-800 cursor-pointer">
|
270 |
+
#ai
|
271 |
+
</span>
|
272 |
+
<span class="sidebar-item px-2 py-1 rounded-full text-xs bg-gray-800 cursor-pointer">
|
273 |
+
#flask
|
274 |
+
</span>
|
275 |
+
<span class="sidebar-item px-2 py-1 rounded-full text-xs bg-gray-800 cursor-pointer">
|
276 |
+
#machinelearning
|
277 |
+
</span>
|
278 |
+
</div>
|
279 |
+
</div>
|
280 |
+
|
281 |
+
<div class="p-4 border-t border-gray-700">
|
282 |
+
<h2 class="text-lg font-semibold text-gray-300 mb-2 flex items-center">
|
283 |
+
<i class="fas fa-cog mr-2 text-blue-400"></i>
|
284 |
+
AI Models
|
285 |
+
</h2>
|
286 |
+
<ul class="space-y-2">
|
287 |
+
<li class="sidebar-item px-3 py-2 rounded cursor-pointer flex items-center justify-between">
|
288 |
+
<div>
|
289 |
+
<i class="fas fa-robot mr-2 text-green-400"></i>
|
290 |
+
DeepSeek V3.1
|
291 |
+
</div>
|
292 |
+
<span class="text-xs bg-green-500 text-white px-2 py-1 rounded-full">Active</span>
|
293 |
+
</li>
|
294 |
+
<li class="sidebar-item px-3 py-2 rounded cursor-pointer flex items-center">
|
295 |
+
<i class="fas fa-robot mr-2 text-blue-400"></i>
|
296 |
+
Local LLM
|
297 |
+
</li>
|
298 |
+
</ul>
|
299 |
+
</div>
|
300 |
+
</div>
|
301 |
+
|
302 |
+
<div class="p-4 border-t border-gray-700">
|
303 |
+
<button id="upload-btn" class="w-full gradient-bg text-white py-2 px-4 rounded-lg font-medium flex items-center justify-center">
|
304 |
+
<i class="fas fa-cloud-upload-alt mr-2"></i>
|
305 |
+
Upload Knowledge
|
306 |
+
</button>
|
307 |
+
</div>
|
308 |
+
</div>
|
309 |
+
|
310 |
+
<!-- Main Content -->
|
311 |
+
<div class="flex-1 flex flex-col overflow-hidden">
|
312 |
+
<!-- Header -->
|
313 |
+
<header class="bg-white shadow-sm z-10">
|
314 |
+
<div class="flex items-center justify-between px-6 py-4">
|
315 |
+
<div class="flex items-center">
|
316 |
+
<div class="relative w-64">
|
317 |
+
<input type="text" placeholder="Search knowledge base..."
|
318 |
+
class="w-full pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent">
|
319 |
+
<i class="fas fa-search absolute left-3 top-3 text-gray-400"></i>
|
320 |
+
</div>
|
321 |
+
</div>
|
322 |
+
|
323 |
+
<div class="flex items-center space-x-4">
|
324 |
+
<button class="pulse-animation gradient-bg text-white py-2 px-4 rounded-lg font-medium flex items-center">
|
325 |
+
<i class="fas fa-bolt mr-2"></i>
|
326 |
+
Train AI Model
|
327 |
+
</button>
|
328 |
+
<div class="h-8 w-8 rounded-full bg-purple-500 flex items-center justify-center text-white font-bold">
|
329 |
+
<i class="fas fa-user"></i>
|
330 |
+
</div>
|
331 |
+
</div>
|
332 |
+
</div>
|
333 |
+
</header>
|
334 |
+
|
335 |
+
<!-- Content -->
|
336 |
+
<main class="flex-1 overflow-y-auto p-6 bg-gray-50">
|
337 |
+
<div class="mb-6 flex justify-between items-center">
|
338 |
+
<h2 class="text-2xl font-bold text-gray-800">Knowledge Repository</h2>
|
339 |
+
<div class="flex space-x-2">
|
340 |
+
<button class="bg-white border border-gray-300 px-3 py-1 rounded-lg text-sm flex items-center">
|
341 |
+
<i class="fas fa-filter mr-2 text-gray-500"></i>
|
342 |
+
Filter
|
343 |
+
</button>
|
344 |
+
<button class="bg-white border border-gray-300 px-3 py-1 rounded-lg text-sm flex items-center">
|
345 |
+
<i class="fas fa-sort mr-2 text-gray-500"></i>
|
346 |
+
Sort
|
347 |
+
</button>
|
348 |
+
</div>
|
349 |
+
</div>
|
350 |
+
|
351 |
+
<!-- Stats Cards -->
|
352 |
+
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
353 |
+
<div class="bg-white rounded-lg shadow p-4">
|
354 |
+
<div class="flex items-center justify-between">
|
355 |
+
<div>
|
356 |
+
<p class="text-gray-500 text-sm">Total Files</p>
|
357 |
+
<h3 class="text-2xl font-bold">1,248</h3>
|
358 |
+
</div>
|
359 |
+
<div class="p-3 rounded-full bg-blue-100 text-blue-500">
|
360 |
+
<i class="fas fa-file-alt"></i>
|
361 |
+
</div>
|
362 |
+
</div>
|
363 |
+
</div>
|
364 |
+
<div class="bg-white rounded-lg shadow p-4">
|
365 |
+
<div class="flex items-center justify-between">
|
366 |
+
<div>
|
367 |
+
<p class="text-gray-500 text-sm">AI Models</p>
|
368 |
+
<h3 class="text-2xl font-bold">5</h3>
|
369 |
+
</div>
|
370 |
+
<div class="p-3 rounded-full bg-purple-100 text-purple-500">
|
371 |
+
<i class="fas fa-robot"></i>
|
372 |
+
</div>
|
373 |
+
</div>
|
374 |
+
</div>
|
375 |
+
<div class="bg-white rounded-lg shadow p-4">
|
376 |
+
<div class="flex items-center justify-between">
|
377 |
+
<div>
|
378 |
+
<p class="text-gray-500 text-sm">Knowledge Used</p>
|
379 |
+
<h3 class="text-2xl font-bold">87%</h3>
|
380 |
+
</div>
|
381 |
+
<div class="p-3 rounded-full bg-green-100 text-green-500">
|
382 |
+
<i class="fas fa-chart-pie"></i>
|
383 |
+
</div>
|
384 |
+
</div>
|
385 |
+
</div>
|
386 |
+
<div class="bg-white rounded-lg shadow p-4">
|
387 |
+
<div class="flex items-center justify-between">
|
388 |
+
<div>
|
389 |
+
<p class="text-gray-500 text-sm">Last Training</p>
|
390 |
+
<h3 class="text-2xl font-bold">2h ago</h3>
|
391 |
+
</div>
|
392 |
+
<div class="p-3 rounded-full bg-yellow-100 text-yellow-500">
|
393 |
+
<i class="fas fa-bolt"></i>
|
394 |
+
</div>
|
395 |
+
</div>
|
396 |
+
</div>
|
397 |
+
</div>
|
398 |
+
|
399 |
+
<!-- Knowledge Items -->
|
400 |
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
401 |
+
<!-- Sample knowledge cards -->
|
402 |
+
<div class="knowledge-card bg-white rounded-lg shadow p-4">
|
403 |
+
<div class="flex items-start justify-between mb-3">
|
404 |
+
<div class="flex items-center">
|
405 |
+
<div class="p-2 rounded-lg bg-blue-100 text-blue-500 mr-3">
|
406 |
+
<i class="fas fa-code"></i>
|
407 |
+
</div>
|
408 |
+
<div>
|
409 |
+
<h4 class="font-bold">Custom AI Framework</h4>
|
410 |
+
<p class="text-gray-500 text-sm">Advanced neural network implementation</p>
|
411 |
+
</div>
|
412 |
+
</div>
|
413 |
+
<button class="text-gray-400 hover:text-gray-600">
|
414 |
+
<i class="fas fa-ellipsis-v"></i>
|
415 |
+
</button>
|
416 |
+
</div>
|
417 |
+
<p class="text-gray-600 text-sm mb-3">Complete implementation of our proprietary AI framework with custom layers and optimization techniques.</p>
|
418 |
+
<div class="flex flex-wrap gap-2 mb-3">
|
419 |
+
<span class="px-2 py-1 bg-blue-100 text-blue-600 text-xs rounded-full">#python</span>
|
420 |
+
<span class="px-2 py-1 bg-purple-100 text-purple-600 text-xs rounded-full">#tensorflow</span>
|
421 |
+
<span class="px-2 py-1 bg-green-100 text-green-600 text-xs rounded-full">#ai</span>
|
422 |
+
</div>
|
423 |
+
<div class="flex items-center justify-between text-xs text-gray-500">
|
424 |
+
<span>Updated 3 days ago</span>
|
425 |
+
<span>1.2 MB</span>
|
426 |
+
</div>
|
427 |
+
</div>
|
428 |
+
|
429 |
+
<div class="knowledge-card bg-white rounded-lg shadow p-4">
|
430 |
+
<div class="flex items-start justify-between mb-3">
|
431 |
+
<div class="flex items-center">
|
432 |
+
<div class="p-2 rounded-lg bg-purple-100 text-purple-500 mr-3">
|
433 |
+
<i class="fas fa-project-diagram"></i>
|
434 |
+
</div>
|
435 |
+
<div>
|
436 |
+
<h4 class="font-bold">Project Blueprint</h4>
|
437 |
+
<p class="text-gray-500 text-sm">Architecture documentation</p>
|
438 |
+
</div>
|
439 |
+
</div>
|
440 |
+
<button class="text-gray-400 hover:text-gray-600">
|
441 |
+
<i class="fas fa-ellipsis-v"></i>
|
442 |
+
</button>
|
443 |
+
</div>
|
444 |
+
<p class="text-gray-600 text-sm mb-3">Detailed system architecture and component interactions for our flagship AI product.</p>
|
445 |
+
<div class="flex flex-wrap gap-2 mb-3">
|
446 |
+
<span class="px-2 py-1 bg-blue-100 text-blue-600 text-xs rounded-full">#architecture</span>
|
447 |
+
<span class="px-2 py-1 bg-yellow-100 text-yellow-600 text-xs rounded-full">#documentation</span>
|
448 |
+
<span class="px-2 py-1 bg-red-100 text-red-600 text-xs rounded-full">#design</span>
|
449 |
+
</div>
|
450 |
+
<div class="flex items-center justify-between text-xs text-gray-500">
|
451 |
+
<span>Updated 1 week ago</span>
|
452 |
+
<span>450 KB</span>
|
453 |
+
</div>
|
454 |
+
</div>
|
455 |
+
|
456 |
+
<div class="knowledge-card bg-white rounded-lg shadow p-4">
|
457 |
+
<div class="flex items-start justify-between mb-3">
|
458 |
+
<div class="flex items-center">
|
459 |
+
<div class="p-2 rounded-lg bg-green-100 text-green-500 mr-3">
|
460 |
+
<i class="fas fa-chart-line"></i>
|
461 |
+
</div>
|
462 |
+
<div>
|
463 |
+
<h4 class="font-bold">Performance Metrics</h4>
|
464 |
+
<p class="text-gray-500 text-sm">Model evaluation results</p>
|
465 |
+
</div>
|
466 |
+
</div>
|
467 |
+
<button class="text-gray-400 hover:text-gray-600">
|
468 |
+
<i class="fas fa-ellipsis-v"></i>
|
469 |
+
</button>
|
470 |
+
</div>
|
471 |
+
<p class="text-gray-600 text-sm mb-3">Comprehensive evaluation of model performance across different datasets and parameters.</p>
|
472 |
+
<div class="flex flex-wrap gap-2 mb-3">
|
473 |
+
<span class="px-2 py-1 bg-green-100 text-green-600 text-xs rounded-full">#analytics</span>
|
474 |
+
<span class="px-2 py-1 bg-indigo-100 text-indigo-600 text-xs rounded-full">#metrics</span>
|
475 |
+
<span class="px-2 py-1 bg-pink-100 text-pink-600 text-xs rounded-full">#evaluation</span>
|
476 |
+
</div>
|
477 |
+
<div class="flex items-center justify-between text-xs text-gray-500">
|
478 |
+
<span>Updated yesterday</span>
|
479 |
+
<span>780 KB</span>
|
480 |
+
</div>
|
481 |
+
</div>
|
482 |
+
</div>
|
483 |
+
</main>
|
484 |
+
</div>
|
485 |
</div>
|
486 |
+
|
487 |
+
<!-- Upload Modal -->
|
488 |
+
<div id="upload-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
|
489 |
+
<div class="bg-white rounded-lg shadow-xl w-full max-w-2xl">
|
490 |
+
<div class="p-4 border-b border-gray-200 flex justify-between items-center">
|
491 |
+
<h3 class="text-lg font-semibold">Upload to Knowledge Base</h3>
|
492 |
+
<button id="close-modal" class="text-gray-500 hover:text-gray-700">
|
493 |
+
<i class="fas fa-times"></i>
|
494 |
+
</button>
|
495 |
+
</div>
|
496 |
+
|
497 |
+
<div class="p-6">
|
498 |
+
<div class="file-upload p-8 rounded-lg text-center mb-6 cursor-pointer">
|
499 |
+
<i class="fas fa-cloud-upload-alt text-4xl text-purple-500 mb-3"></i>
|
500 |
+
<p class="font-medium">Drag & drop files here or click to browse</p>
|
501 |
+
<p class="text-gray-500 text-sm mt-1">Supports: .py, .js, .html, .css, .pdf, .txt, .md, .ipynb</p>
|
502 |
+
<input type="file" id="file-input" class="hidden" multiple>
|
503 |
+
</div>
|
504 |
+
|
505 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
506 |
+
<div>
|
507 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Categories</label>
|
508 |
+
<input type="text" placeholder="e.g. Frameworks, Documentation"
|
509 |
+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
|
510 |
+
</div>
|
511 |
+
<div>
|
512 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Tags</label>
|
513 |
+
<input type="text" placeholder="e.g. python, ai, flask"
|
514 |
+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
|
515 |
+
</div>
|
516 |
+
</div>
|
517 |
+
|
518 |
+
<div class="mb-4">
|
519 |
+
<label class="block text-sm font-medium text-gray-700 mb-1">Description</label>
|
520 |
+
<textarea rows="3" placeholder="Brief description of the knowledge content"
|
521 |
+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500"></textarea>
|
522 |
+
</div>
|
523 |
+
|
524 |
+
<div class="flex justify-end space-x-3">
|
525 |
+
<button id="cancel-upload" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">
|
526 |
+
Cancel
|
527 |
+
</button>
|
528 |
+
<button class="gradient-bg text-white px-4 py-2 rounded-md hover:opacity-90">
|
529 |
+
<i class="fas fa-save mr-2"></i>
|
530 |
+
Save Knowledge
|
531 |
+
</button>
|
532 |
+
</div>
|
533 |
+
</div>
|
534 |
+
</div>
|
535 |
+
</div>
|
536 |
+
|
537 |
+
<!-- Training Modal -->
|
538 |
+
<div id="training-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
|
539 |
+
<div class="bg-white rounded-lg shadow-xl w-full max-w-2xl">
|
540 |
+
<div class="p-4 border-b border-gray-200 flex justify-between items-center">
|
541 |
+
<h3 class="text-lg font-semibold">Train AI Model with Knowledge</h3>
|
542 |
+
<button id="close-training-modal" class="text-gray-500 hover:text-gray-700">
|
543 |
+
<i class="fas fa-times"></i>
|
544 |
+
</button>
|
545 |
+
</div>
|
546 |
+
|
547 |
+
<div class="p-6">
|
548 |
+
<div class="mb-6">
|
549 |
+
<label class="block text-sm font-medium text-gray-700 mb-2">Select AI Model</label>
|
550 |
+
<select class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
|
551 |
+
<option>DeepSeek V3.1</option>
|
552 |
+
<option>Local LLM</option>
|
553 |
+
<option>Custom Fine-tuned Model</option>
|
554 |
+
</select>
|
555 |
+
</div>
|
556 |
+
|
557 |
+
<div class="mb-6">
|
558 |
+
<label class="block text-sm font-medium text-gray-700 mb-2">Select Knowledge to Include</label>
|
559 |
+
<div class="border border-gray-300 rounded-md p-4 max-h-64 overflow-y-auto">
|
560 |
+
<div class="space-y-3">
|
561 |
+
<div class="flex items-center">
|
562 |
+
<input type="checkbox" id="knowledge-1" class="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded">
|
563 |
+
<label for="knowledge-1" class="ml-2 block text-sm text-gray-700">
|
564 |
+
Custom AI Framework (Advanced neural network implementation)
|
565 |
+
</label>
|
566 |
+
</div>
|
567 |
+
<div class="flex items-center">
|
568 |
+
<input type="checkbox" id="knowledge-2" class="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded">
|
569 |
+
<label for="knowledge-2" class="ml-2 block text-sm text-gray-700">
|
570 |
+
Project Blueprint (Architecture documentation)
|
571 |
+
</label>
|
572 |
+
</div>
|
573 |
+
<div class="flex items-center">
|
574 |
+
<input type="checkbox" id="knowledge-3" class="h-4 w-4 text-purple-600 focus:ring-purple-500 border-gray-300 rounded">
|
575 |
+
<label for="knowledge-3" class="ml-2 block text-sm text-gray-700">
|
576 |
+
Performance Metrics (Model evaluation results)
|
577 |
+
</label>
|
578 |
+
</div>
|
579 |
+
</div>
|
580 |
+
</div>
|
581 |
+
</div>
|
582 |
+
|
583 |
+
<div class="mb-6">
|
584 |
+
<label class="block text-sm font-medium text-gray-700 mb-2">Training Parameters</label>
|
585 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
586 |
+
<div>
|
587 |
+
<label class="block text-xs text-gray-500 mb-1">Epochs</label>
|
588 |
+
<input type="number" value="10" min="1"
|
589 |
+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
|
590 |
+
</div>
|
591 |
+
<div>
|
592 |
+
<label class="block text-xs text-gray-500 mb-1">Learning Rate</label>
|
593 |
+
<input type="number" step="0.0001" value="0.001"
|
594 |
+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-purple-500">
|
595 |
+
</div>
|
596 |
+
</div>
|
597 |
+
</div>
|
598 |
+
|
599 |
+
<div class="flex justify-end space-x-3">
|
600 |
+
<button id="cancel-training" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">
|
601 |
+
Cancel
|
602 |
+
</button>
|
603 |
+
<button class="gradient-bg text-white px-4 py-2 rounded-md hover:opacity-90">
|
604 |
+
<i class="fas fa-bolt mr-2"></i>
|
605 |
+
Start Training
|
606 |
+
</button>
|
607 |
+
</div>
|
608 |
+
</div>
|
609 |
+
</div>
|
610 |
+
</div>
|
611 |
+
|
612 |
+
<script>
|
613 |
+
// Modal toggle functionality
|
614 |
+
document.getElementById('upload-btn').addEventListener('click', function() {
|
615 |
+
document.getElementById('upload-modal').classList.remove('hidden');
|
616 |
+
});
|
617 |
+
|
618 |
+
document.getElementById('close-modal').addEventListener('click', function() {
|
619 |
+
document.getElementById('upload-modal').classList.add('hidden');
|
620 |
+
});
|
621 |
+
|
622 |
+
document.getElementById('cancel-upload').addEventListener('click', function() {
|
623 |
+
document.getElementById('upload-modal').classList.add('hidden');
|
624 |
+
});
|
625 |
+
|
626 |
+
// Training modal
|
627 |
+
document.querySelector('.pulse-animation').addEventListener('click', function() {
|
628 |
+
document.getElementById('training-modal').classList.remove('hidden');
|
629 |
+
});
|
630 |
+
|
631 |
+
document.getElementById('close-training-modal').addEventListener('click', function() {
|
632 |
+
document.getElementById('training-modal').classList.add('hidden');
|
633 |
+
});
|
634 |
+
|
635 |
+
document.getElementById('cancel-training').addEventListener('click', function() {
|
636 |
+
document.getElementById('training-modal').classList.add('hidden');
|
637 |
+
});
|
638 |
+
|
639 |
+
// File upload interaction
|
640 |
+
const fileUpload = document.querySelector('.file-upload');
|
641 |
+
const fileInput = document.getElementById('file-input');
|
642 |
+
|
643 |
+
fileUpload.addEventListener('click', function() {
|
644 |
+
fileInput.click();
|
645 |
+
});
|
646 |
+
|
647 |
+
fileUpload.addEventListener('dragover', function(e) {
|
648 |
+
e.preventDefault();
|
649 |
+
this.classList.add('border-purple-500', 'bg-purple-50');
|
650 |
+
});
|
651 |
+
|
652 |
+
fileUpload.addEventListener('dragleave', function(e) {
|
653 |
+
e.preventDefault();
|
654 |
+
this.classList.remove('border-purple-500', 'bg-purple-50');
|
655 |
+
});
|
656 |
+
|
657 |
+
fileUpload.addEventListener('drop', function(e) {
|
658 |
+
e.preventDefault();
|
659 |
+
this.classList.remove('border-purple-500', 'bg-purple-50');
|
660 |
+
// Handle dropped files
|
661 |
+
console.log('Files dropped:', e.dataTransfer.files);
|
662 |
+
});
|
663 |
+
|
664 |
+
// Simulate API calls
|
665 |
+
async function uploadFile(file, metadata) {
|
666 |
+
// In a real implementation, this would call the Flask API
|
667 |
+
console.log('Uploading file:', file.name);
|
668 |
+
console.log('With metadata:', metadata);
|
669 |
+
|
670 |
+
// Simulate API delay
|
671 |
+
await new Promise(resolve => setTimeout(resolve, 1500));
|
672 |
+
|
673 |
+
return {
|
674 |
+
success: true,
|
675 |
+
fileId: 'file_' + Math.random().toString(36).substr(2, 9),
|
676 |
+
message: 'File uploaded successfully'
|
677 |
+
};
|
678 |
+
}
|
679 |
+
|
680 |
+
async function trainModel(model, fileIds, params) {
|
681 |
+
// In a real implementation, this would call the Flask API
|
682 |
+
console.log('Training model:', model);
|
683 |
+
console.log('With files:', fileIds);
|
684 |
+
console.log('Parameters:', params);
|
685 |
+
|
686 |
+
// Simulate API delay
|
687 |
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
688 |
+
|
689 |
+
return {
|
690 |
+
success: true,
|
691 |
+
trainingId: 'train_' + Math.random().toString(36).substr(2, 9),
|
692 |
+
message: 'Training initiated'
|
693 |
+
};
|
694 |
+
}
|
695 |
+
</script>
|
696 |
+
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=Barbuuuuuuuu/ai-knowledge-base-good" style="color: #fff;text-decoration: underline;" target="_blank" >𧬠Remix</a></p><p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 𧬠<a href="https://enzostvs-deepsite.hf.space?remix=MoShow/awert" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
|
697 |
+
</html>
|