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