Spaces:
Sleeping
Sleeping
deploy from github
Browse files- .github/workflows/restart-space.yml +21 -0
- frontend/src/App.jsx +54 -1
.github/workflows/restart-space.yml
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Restart Space
|
| 2 |
+
|
| 3 |
+
on:
|
| 4 |
+
push:
|
| 5 |
+
branches: [main]
|
| 6 |
+
paths-ignore:
|
| 7 |
+
- '.env'
|
| 8 |
+
- '**.md'
|
| 9 |
+
|
| 10 |
+
jobs:
|
| 11 |
+
restart-space:
|
| 12 |
+
runs-on: ubuntu-latest
|
| 13 |
+
steps:
|
| 14 |
+
- name: Restart HuggingFace Space
|
| 15 |
+
run: |
|
| 16 |
+
echo "Restarting space..."
|
| 17 |
+
# Call the restart endpoint if the space is running
|
| 18 |
+
curl -X POST "${{ secrets.HF_SPACE_URL }}/api/restart" 2>/dev/null || echo "Restart signal sent"
|
| 19 |
+
echo "Space restart requested"
|
| 20 |
+
env:
|
| 21 |
+
HF_SPACE_URL: ${{ secrets.HF_SPACE_URL }}
|
frontend/src/App.jsx
CHANGED
|
@@ -25,6 +25,7 @@ function App() {
|
|
| 25 |
const [loadingRunId, setLoadingRunId] = useState(null)
|
| 26 |
const [actionDistribution, setActionDistribution] = useState([])
|
| 27 |
const [chaosEvents, setChaosEvents] = useState([])
|
|
|
|
| 28 |
const summariesRef = useRef(null)
|
| 29 |
|
| 30 |
useEffect(() => {
|
|
@@ -46,7 +47,8 @@ function App() {
|
|
| 46 |
fetchSummaries(),
|
| 47 |
fetchAllAgentsProfits(),
|
| 48 |
fetchActionDistribution(),
|
| 49 |
-
fetchChaosEvents()
|
|
|
|
| 50 |
])
|
| 51 |
} finally {
|
| 52 |
setLoading(false)
|
|
@@ -126,6 +128,18 @@ function App() {
|
|
| 126 |
}
|
| 127 |
}
|
| 128 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
const toggleRun = async (runId) => {
|
| 130 |
if (expandedRun === runId) {
|
| 131 |
setExpandedRun(null)
|
|
@@ -354,6 +368,45 @@ function App() {
|
|
| 354 |
</ResponsiveContainer>
|
| 355 |
</div>
|
| 356 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 357 |
{/* Runs List */}
|
| 358 |
<div className="win-border-outset bg-[#c0c0c0] p-1">
|
| 359 |
<div className="bg-[#808080] text-white px-2 py-0.5 font-bold text-xs mb-1">
|
|
|
|
| 25 |
const [loadingRunId, setLoadingRunId] = useState(null)
|
| 26 |
const [actionDistribution, setActionDistribution] = useState([])
|
| 27 |
const [chaosEvents, setChaosEvents] = useState([])
|
| 28 |
+
const [wealthTrajectories, setWealthTrajectories] = useState([])
|
| 29 |
const summariesRef = useRef(null)
|
| 30 |
|
| 31 |
useEffect(() => {
|
|
|
|
| 47 |
fetchSummaries(),
|
| 48 |
fetchAllAgentsProfits(),
|
| 49 |
fetchActionDistribution(),
|
| 50 |
+
fetchChaosEvents(),
|
| 51 |
+
fetchWealthTrajectories()
|
| 52 |
])
|
| 53 |
} finally {
|
| 54 |
setLoading(false)
|
|
|
|
| 128 |
}
|
| 129 |
}
|
| 130 |
|
| 131 |
+
const fetchWealthTrajectories = async () => {
|
| 132 |
+
try {
|
| 133 |
+
const res = await fetch(`${API_BASE}/analysis/all-wealth-trajectories`)
|
| 134 |
+
if (res.ok) {
|
| 135 |
+
const data = await res.json()
|
| 136 |
+
setWealthTrajectories(data.trajectories || [])
|
| 137 |
+
}
|
| 138 |
+
} catch (e) {
|
| 139 |
+
console.error('Failed to fetch wealth trajectories:', e)
|
| 140 |
+
}
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
const toggleRun = async (runId) => {
|
| 144 |
if (expandedRun === runId) {
|
| 145 |
setExpandedRun(null)
|
|
|
|
| 368 |
</ResponsiveContainer>
|
| 369 |
</div>
|
| 370 |
|
| 371 |
+
{/* Wealth Trajectory Summary - Winners/Losers */}
|
| 372 |
+
<div className="win-border-outset bg-white p-4">
|
| 373 |
+
<h3 className="font-bold mb-3 text-xs">Wealth Trajectory - Winners & Losers</h3>
|
| 374 |
+
{wealthTrajectories.length === 0 ? (
|
| 375 |
+
<div className="text-gray-400 text-center py-4">No trajectory data available</div>
|
| 376 |
+
) : (
|
| 377 |
+
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-3">
|
| 378 |
+
{wealthTrajectories.slice(0, 10).reverse().map((traj) => (
|
| 379 |
+
<div key={traj.run_number} className="win-border-inset bg-[#f5f5f5] p-2 text-xs">
|
| 380 |
+
<div className="font-bold border-b border-gray-300 pb-1 mb-2">
|
| 381 |
+
Run #{traj.run_number}
|
| 382 |
+
</div>
|
| 383 |
+
<div className="space-y-1">
|
| 384 |
+
{Object.entries(traj.gains).map(([agent, gain]) => (
|
| 385 |
+
<div key={agent} className="flex justify-between items-center">
|
| 386 |
+
<span className="truncate max-w-[80px]" title={agent}>
|
| 387 |
+
{agent.split('_')[1] || agent}
|
| 388 |
+
</span>
|
| 389 |
+
<span className={`font-bold ${gain >= 0 ? 'text-green-700' : 'text-red-700'}`}>
|
| 390 |
+
{gain >= 0 ? '+' : ''}{gain.toFixed(1)}
|
| 391 |
+
</span>
|
| 392 |
+
</div>
|
| 393 |
+
))}
|
| 394 |
+
<div className="border-t border-gray-300 pt-1 mt-1">
|
| 395 |
+
<div className="flex justify-between font-bold">
|
| 396 |
+
<span>Winner:</span>
|
| 397 |
+
<span className="text-green-700">{traj.winner?.split('_')[1] || traj.winner}</span>
|
| 398 |
+
</div>
|
| 399 |
+
<div className="text-right text-green-700 font-bold text-lg">
|
| 400 |
+
+{traj.winner_gain?.toFixed(1)}
|
| 401 |
+
</div>
|
| 402 |
+
</div>
|
| 403 |
+
</div>
|
| 404 |
+
</div>
|
| 405 |
+
))}
|
| 406 |
+
</div>
|
| 407 |
+
)}
|
| 408 |
+
</div>
|
| 409 |
+
|
| 410 |
{/* Runs List */}
|
| 411 |
<div className="win-border-outset bg-[#c0c0c0] p-1">
|
| 412 |
<div className="bg-[#808080] text-white px-2 py-0.5 font-bold text-xs mb-1">
|