Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3599513128 | |||
| 7dd8f53f2f | |||
| 90bb7251e3 | |||
| e57bef95e5 |
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { X } from '@lucide/vue'
|
||||
import { X, ExternalLink } from '@lucide/vue'
|
||||
import type { AgentNodeData } from '../../composables/useDashboardData'
|
||||
|
||||
defineProps<{
|
||||
@@ -27,6 +27,9 @@ defineEmits<{
|
||||
<span class="modal-role">{{ agent.role }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<a :href="`/agents/${agent.id}`" class="agent-link-btn" title="Open agent config">
|
||||
<ExternalLink :size="14" />
|
||||
</a>
|
||||
<button class="modal-close-btn" @click="$emit('close')" aria-label="Close">
|
||||
<X :size="16" />
|
||||
</button>
|
||||
@@ -75,10 +78,6 @@ defineEmits<{
|
||||
<section class="modal-section">
|
||||
<h3 class="section-label">Live Thinking</h3>
|
||||
<div class="thinking-panel">
|
||||
<div class="thinking-orbiter">
|
||||
<span class="orbiter-dot dot-blue"></span>
|
||||
<span class="orbiter-dot dot-violet"></span>
|
||||
</div>
|
||||
<div class="thinking-stream" ref="thinkingStreamRef">
|
||||
<div
|
||||
v-for="(msg, idx) in agent.thinkingStream"
|
||||
@@ -88,6 +87,10 @@ defineEmits<{
|
||||
>
|
||||
<span class="entry-time">{{ msg.time }}</span>
|
||||
<span class="entry-text">{{ msg.text }}</span>
|
||||
<span class="thinking-dots" v-if="idx === agent.thinkingStream.length - 1">
|
||||
<span class="thinking-dot blue"></span>
|
||||
<span class="thinking-dot violet"></span>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="!agent.thinkingStream?.length" class="thinking-placeholder">
|
||||
Waiting for thought stream...
|
||||
@@ -193,6 +196,25 @@ defineEmits<{
|
||||
color: #6b7385;
|
||||
font-weight: 500;
|
||||
}
|
||||
.agent-link-btn {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 8px;
|
||||
background: transparent;
|
||||
color: #6b7385;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
flex-shrink: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
.agent-link-btn:hover {
|
||||
border-color: var(--agent-color);
|
||||
color: var(--agent-color);
|
||||
}
|
||||
|
||||
.modal-close-btn {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
@@ -277,41 +299,27 @@ defineEmits<{
|
||||
animation: panel-pulse 2.5s ease-in-out infinite;
|
||||
}
|
||||
@keyframes panel-pulse {
|
||||
0%, 100% { border-color: rgba(139, 124, 246, 0.2); box-shadow: 0 0 8px rgba(139,124,246,0.05); }
|
||||
50% { border-color: rgba(139, 124, 246, 0.35); box-shadow: 0 0 16px rgba(139,124,246,0.1); }
|
||||
0%, 100% { border-color: rgba(139, 124, 246, 0.25); box-shadow: 0 0 12px rgba(139,124,246,0.08); }
|
||||
50% { border-color: rgba(139, 124, 246, 0.5); box-shadow: 0 0 24px rgba(139,124,246,0.18), 0 0 40px rgba(139,124,246,0.06); }
|
||||
}
|
||||
|
||||
.thinking-orbiter {
|
||||
position: absolute;
|
||||
inset: -8px;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
animation: spin-orbiter 4s linear infinite;
|
||||
.thinking-dots {
|
||||
display: inline-flex;
|
||||
gap: 6px;
|
||||
margin-left: 8px;
|
||||
flex-shrink: 0;
|
||||
animation: spin-dots 2s linear infinite;
|
||||
}
|
||||
@keyframes spin-orbiter {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
.orbiter-dot {
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
.thinking-dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
filter: blur(1px);
|
||||
}
|
||||
.dot-blue {
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: #3b82f6;
|
||||
box-shadow: 0 0 10px #3b82f6, 0 0 20px rgba(59,130,246,0.5);
|
||||
}
|
||||
.dot-violet {
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 50%);
|
||||
background: #8b7cf6;
|
||||
box-shadow: 0 0 10px #8b7cf6, 0 0 20px rgba(139,124,246,0.5);
|
||||
.thinking-dot.blue { background: #3b82f6; box-shadow: 0 0 8px #3b82f6; }
|
||||
.thinking-dot.violet { background: #8b7cf6; box-shadow: 0 0 8px #8b7cf6; }
|
||||
@keyframes spin-dots {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.thinking-stream {
|
||||
|
||||
@@ -118,7 +118,7 @@ const connectionPaths = computed<Record<string, ConnectionPath | null>>(() => {
|
||||
|
||||
// Spread start points across Iris bottom edge (30%-70% range)
|
||||
const t = total > 1 ? idx / (total - 1) : 0.5
|
||||
const startX = iris.left + iris.width * (0.30 + t * 0.40)
|
||||
const startX = iris.left + iris.width * (0.38 + t * 0.24)
|
||||
const startY = iris.bottom - 1
|
||||
|
||||
// Determine column: left or right of Iris center
|
||||
@@ -130,8 +130,8 @@ const connectionPaths = computed<Record<string, ConnectionPath | null>>(() => {
|
||||
|
||||
// Bézier control points
|
||||
const cp1x = startX
|
||||
const cp1y = startY + 40
|
||||
const cp2x = endX + (isLeftColumn ? 50 : -50)
|
||||
const cp1y = startY + 70
|
||||
const cp2x = endX + (isLeftColumn ? 35 : -35)
|
||||
const cp2y = endY - 10
|
||||
|
||||
const d = `M ${startX} ${startY} C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${endX} ${endY}`
|
||||
@@ -445,7 +445,7 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 32px;
|
||||
gap: 64px;
|
||||
}
|
||||
|
||||
.hero-slot {
|
||||
|
||||
Reference in New Issue
Block a user