nyxora 26.6.19 → 26.6.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/core/src/agent/reasoning.js +1 -1
- package/dist/packages/core/src/gateway/server.js +17 -0
- package/dist/packages/core/src/web3/skills/getPrice.js +11 -6
- package/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/packages/core/src/agent/reasoning.ts +1 -1
- package/packages/core/src/gateway/server.ts +17 -0
- package/packages/core/src/web3/skills/getPrice.ts +11 -6
- package/packages/dashboard/dist/assets/{index-DnQrbB4c.css → index-CQNHWZtN.css} +1 -1
- package/packages/dashboard/dist/assets/{index-BAXifdMN.js → index-O2m42q4p.js} +3 -3
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package.json +1 -1
- package/packages/mcp-server/package.json +1 -1
- package/packages/policy/package.json +1 -1
- package/packages/signer/package.json +1 -1
|
@@ -327,7 +327,7 @@ async function processUserInput(input, role = 'user', onProgress, sessionId) {
|
|
|
327
327
|
break;
|
|
328
328
|
}
|
|
329
329
|
case 'get_price': {
|
|
330
|
-
result = await (0, getPrice_1.getPrice)(args.coinId);
|
|
330
|
+
result = await (0, getPrice_1.getPrice)(args.coinId, args.currency);
|
|
331
331
|
break;
|
|
332
332
|
}
|
|
333
333
|
case 'swap_token': {
|
|
@@ -563,6 +563,7 @@ app.post('/api/transactions/:id/reject', async (req, res) => {
|
|
|
563
563
|
let cachedTrending = null;
|
|
564
564
|
let lastTrendingFetch = 0;
|
|
565
565
|
let cachedPrices = {};
|
|
566
|
+
let cachedPriceChanges = {};
|
|
566
567
|
let lastPricesFetch = 0;
|
|
567
568
|
app.get('/api/trending', async (req, res) => {
|
|
568
569
|
const now = Date.now();
|
|
@@ -591,6 +592,15 @@ app.get('/api/trending', async (req, res) => {
|
|
|
591
592
|
res.status(500).json({ error: err.message });
|
|
592
593
|
}
|
|
593
594
|
});
|
|
595
|
+
app.get('/api/wallet', async (req, res) => {
|
|
596
|
+
try {
|
|
597
|
+
const userAddress = await (0, config_1.getAddress)();
|
|
598
|
+
res.json({ address: userAddress });
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
res.status(500).json({ error: error.message });
|
|
602
|
+
}
|
|
603
|
+
});
|
|
594
604
|
app.get('/api/portfolio', async (req, res) => {
|
|
595
605
|
try {
|
|
596
606
|
const userAddress = await (0, config_1.getAddress)();
|
|
@@ -681,9 +691,11 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
681
691
|
const uniqueAddrs = Array.from(addressesToFetch);
|
|
682
692
|
const now = Date.now();
|
|
683
693
|
let priceMap = cachedPrices;
|
|
694
|
+
let changeMap = cachedPriceChanges;
|
|
684
695
|
if (uniqueAddrs.length > 0 && now - lastPricesFetch > 2 * 60 * 1000) {
|
|
685
696
|
try {
|
|
686
697
|
const newPrices = {};
|
|
698
|
+
const newChanges = {};
|
|
687
699
|
await Promise.all(uniqueAddrs.map(async (addr) => {
|
|
688
700
|
try {
|
|
689
701
|
const res = await (0, httpClient_1.safeFetch)(`https://api.dexscreener.com/latest/dex/tokens/${addr}`);
|
|
@@ -706,9 +718,11 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
706
718
|
const quoteAddr = bestPair.quoteToken?.address?.toLowerCase();
|
|
707
719
|
if (baseAddr === addr) {
|
|
708
720
|
newPrices[addr] = parseFloat(bestPair.priceUsd);
|
|
721
|
+
newChanges[addr] = bestPair.priceChange?.h24 || 0;
|
|
709
722
|
}
|
|
710
723
|
else if (quoteAddr === addr && bestPair.priceNative && parseFloat(bestPair.priceNative) > 0) {
|
|
711
724
|
newPrices[addr] = parseFloat(bestPair.priceUsd) / parseFloat(bestPair.priceNative);
|
|
725
|
+
newChanges[addr] = bestPair.priceChange?.h24 || 0;
|
|
712
726
|
}
|
|
713
727
|
}
|
|
714
728
|
}
|
|
@@ -720,7 +734,9 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
720
734
|
}));
|
|
721
735
|
console.log('DexScreener Fetched Prices:', newPrices);
|
|
722
736
|
cachedPrices = { ...cachedPrices, ...newPrices };
|
|
737
|
+
cachedPriceChanges = { ...cachedPriceChanges, ...newChanges };
|
|
723
738
|
priceMap = cachedPrices;
|
|
739
|
+
changeMap = cachedPriceChanges;
|
|
724
740
|
lastPricesFetch = now;
|
|
725
741
|
}
|
|
726
742
|
catch (e) {
|
|
@@ -735,6 +751,7 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
735
751
|
lookupAddr = ((tokens_1.TOKEN_MAP[chain]?.[wToken]) || '').toLowerCase();
|
|
736
752
|
}
|
|
737
753
|
t.priceUsd = priceMap[lookupAddr] || 0;
|
|
754
|
+
t.priceChange24h = changeMap[lookupAddr] || 0;
|
|
738
755
|
}
|
|
739
756
|
}
|
|
740
757
|
res.json(portfolio);
|
|
@@ -14,27 +14,32 @@ exports.getPriceToolDefinition = {
|
|
|
14
14
|
coinId: {
|
|
15
15
|
type: "string",
|
|
16
16
|
description: "The CoinGecko ID of the coin (e.g., 'ethereum', 'bitcoin', 'solana')."
|
|
17
|
+
},
|
|
18
|
+
currency: {
|
|
19
|
+
type: "string",
|
|
20
|
+
description: "The fiat currency to convert to (e.g., 'usd', 'idr', 'eur', 'jpy'). Defaults to 'usd'."
|
|
17
21
|
}
|
|
18
22
|
},
|
|
19
23
|
required: ["coinId"]
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
};
|
|
23
|
-
async function getPrice(coinId) {
|
|
27
|
+
async function getPrice(coinId, currency = 'usd') {
|
|
24
28
|
try {
|
|
25
|
-
const
|
|
29
|
+
const cur = currency.toLowerCase();
|
|
30
|
+
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${coinId}&vs_currencies=${cur}&include_24hr_change=true`;
|
|
26
31
|
const data = await (0, httpClient_1.safeFetchJson)(url);
|
|
27
32
|
if (!data[coinId]) {
|
|
28
33
|
return `❌ Could not find price data for **${coinId.toUpperCase()}**. Please verify the coin name.`;
|
|
29
34
|
}
|
|
30
|
-
const price = data[coinId]
|
|
31
|
-
const change24h = data[coinId]
|
|
35
|
+
const price = data[coinId][cur];
|
|
36
|
+
const change24h = data[coinId][`${cur}_24h_change`];
|
|
32
37
|
const isPositive = change24h >= 0;
|
|
33
38
|
const arrow = isPositive ? '📈 🟩 +' : '📉 🟥 ';
|
|
34
|
-
const priceFormatted = new Intl.NumberFormat('en-US', { style: 'currency', currency:
|
|
39
|
+
const priceFormatted = new Intl.NumberFormat(cur === 'idr' ? 'id-ID' : 'en-US', { style: 'currency', currency: cur.toUpperCase() }).format(price);
|
|
35
40
|
const changeFormatted = change24h ? change24h.toFixed(2) : '0.00';
|
|
36
41
|
return `💰 **Price Update for ${coinId.toUpperCase()}**\n\n` +
|
|
37
|
-
`- **Price (
|
|
42
|
+
`- **Price (${cur.toUpperCase()})**: \`${priceFormatted}\`\n` +
|
|
38
43
|
`- **24h Change**: ${arrow}${changeFormatted}%`;
|
|
39
44
|
}
|
|
40
45
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -382,7 +382,7 @@ export async function processUserInput(input: string, role: 'user' | 'system' =
|
|
|
382
382
|
break;
|
|
383
383
|
}
|
|
384
384
|
case 'get_price': {
|
|
385
|
-
result = await getPrice(args.coinId);
|
|
385
|
+
result = await getPrice(args.coinId, args.currency);
|
|
386
386
|
break;
|
|
387
387
|
}
|
|
388
388
|
case 'swap_token': {
|
|
@@ -603,6 +603,7 @@ let cachedTrending: string[] | null = null;
|
|
|
603
603
|
let lastTrendingFetch = 0;
|
|
604
604
|
|
|
605
605
|
let cachedPrices: Record<string, number> = {};
|
|
606
|
+
let cachedPriceChanges: Record<string, number> = {};
|
|
606
607
|
let lastPricesFetch = 0;
|
|
607
608
|
|
|
608
609
|
app.get('/api/trending', async (req, res) => {
|
|
@@ -629,6 +630,15 @@ app.get('/api/trending', async (req, res) => {
|
|
|
629
630
|
}
|
|
630
631
|
});
|
|
631
632
|
|
|
633
|
+
app.get('/api/wallet', async (req, res) => {
|
|
634
|
+
try {
|
|
635
|
+
const userAddress = await getAddress();
|
|
636
|
+
res.json({ address: userAddress });
|
|
637
|
+
} catch (error: any) {
|
|
638
|
+
res.status(500).json({ error: error.message });
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
|
|
632
642
|
app.get('/api/portfolio', async (req, res) => {
|
|
633
643
|
try {
|
|
634
644
|
const userAddress = await getAddress();
|
|
@@ -722,10 +732,12 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
722
732
|
const uniqueAddrs = Array.from(addressesToFetch);
|
|
723
733
|
const now = Date.now();
|
|
724
734
|
let priceMap = cachedPrices;
|
|
735
|
+
let changeMap = cachedPriceChanges;
|
|
725
736
|
|
|
726
737
|
if (uniqueAddrs.length > 0 && now - lastPricesFetch > 2 * 60 * 1000) {
|
|
727
738
|
try {
|
|
728
739
|
const newPrices: Record<string, number> = {};
|
|
740
|
+
const newChanges: Record<string, number> = {};
|
|
729
741
|
|
|
730
742
|
await Promise.all(uniqueAddrs.map(async (addr) => {
|
|
731
743
|
try {
|
|
@@ -751,8 +763,10 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
751
763
|
|
|
752
764
|
if (baseAddr === addr) {
|
|
753
765
|
newPrices[addr] = parseFloat(bestPair.priceUsd);
|
|
766
|
+
newChanges[addr] = bestPair.priceChange?.h24 || 0;
|
|
754
767
|
} else if (quoteAddr === addr && bestPair.priceNative && parseFloat(bestPair.priceNative) > 0) {
|
|
755
768
|
newPrices[addr] = parseFloat(bestPair.priceUsd) / parseFloat(bestPair.priceNative);
|
|
769
|
+
newChanges[addr] = bestPair.priceChange?.h24 || 0;
|
|
756
770
|
}
|
|
757
771
|
}
|
|
758
772
|
}
|
|
@@ -765,7 +779,9 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
765
779
|
console.log('DexScreener Fetched Prices:', newPrices);
|
|
766
780
|
|
|
767
781
|
cachedPrices = { ...cachedPrices, ...newPrices };
|
|
782
|
+
cachedPriceChanges = { ...cachedPriceChanges, ...newChanges };
|
|
768
783
|
priceMap = cachedPrices;
|
|
784
|
+
changeMap = cachedPriceChanges;
|
|
769
785
|
lastPricesFetch = now;
|
|
770
786
|
} catch (e) {
|
|
771
787
|
console.error('DexScreener fetch error:', e);
|
|
@@ -780,6 +796,7 @@ app.get('/api/portfolio', async (req, res) => {
|
|
|
780
796
|
lookupAddr = (((TOKEN_MAP as any)[chain]?.[wToken]) || '').toLowerCase();
|
|
781
797
|
}
|
|
782
798
|
t.priceUsd = priceMap[lookupAddr] || 0;
|
|
799
|
+
t.priceChange24h = changeMap[lookupAddr] || 0;
|
|
783
800
|
}
|
|
784
801
|
}
|
|
785
802
|
|
|
@@ -11,6 +11,10 @@ export const getPriceToolDefinition = {
|
|
|
11
11
|
coinId: {
|
|
12
12
|
type: "string",
|
|
13
13
|
description: "The CoinGecko ID of the coin (e.g., 'ethereum', 'bitcoin', 'solana')."
|
|
14
|
+
},
|
|
15
|
+
currency: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "The fiat currency to convert to (e.g., 'usd', 'idr', 'eur', 'jpy'). Defaults to 'usd'."
|
|
14
18
|
}
|
|
15
19
|
},
|
|
16
20
|
required: ["coinId"]
|
|
@@ -18,25 +22,26 @@ export const getPriceToolDefinition = {
|
|
|
18
22
|
}
|
|
19
23
|
};
|
|
20
24
|
|
|
21
|
-
export async function getPrice(coinId: string): Promise<string> {
|
|
25
|
+
export async function getPrice(coinId: string, currency: string = 'usd'): Promise<string> {
|
|
22
26
|
try {
|
|
23
|
-
const
|
|
27
|
+
const cur = currency.toLowerCase();
|
|
28
|
+
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${coinId}&vs_currencies=${cur}&include_24hr_change=true`;
|
|
24
29
|
const data = await safeFetchJson<any>(url);
|
|
25
30
|
|
|
26
31
|
if (!data[coinId]) {
|
|
27
32
|
return `❌ Could not find price data for **${coinId.toUpperCase()}**. Please verify the coin name.`;
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
const price = data[coinId]
|
|
31
|
-
const change24h = data[coinId]
|
|
35
|
+
const price = data[coinId][cur];
|
|
36
|
+
const change24h = data[coinId][`${cur}_24h_change`];
|
|
32
37
|
|
|
33
38
|
const isPositive = change24h >= 0;
|
|
34
39
|
const arrow = isPositive ? '📈 🟩 +' : '📉 🟥 ';
|
|
35
|
-
const priceFormatted = new Intl.NumberFormat('en-US', { style: 'currency', currency:
|
|
40
|
+
const priceFormatted = new Intl.NumberFormat(cur === 'idr' ? 'id-ID' : 'en-US', { style: 'currency', currency: cur.toUpperCase() }).format(price);
|
|
36
41
|
const changeFormatted = change24h ? change24h.toFixed(2) : '0.00';
|
|
37
42
|
|
|
38
43
|
return `💰 **Price Update for ${coinId.toUpperCase()}**\n\n` +
|
|
39
|
-
`- **Price (
|
|
44
|
+
`- **Price (${cur.toUpperCase()})**: \`${priceFormatted}\`\n` +
|
|
40
45
|
`- **24h Change**: ${arrow}${changeFormatted}%`;
|
|
41
46
|
} catch (error: any) {
|
|
42
47
|
return `❌ **Failed to fetch price:** ${error.message}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--bg-color:#3b4252;--bg-secondary:#434c5e;--bg-sidebar:#2e3440;--text-primary:#eceff4;--text-secondary:#d8dee9;--accent:#88c0d0;--accent-hover:#81a1c1;--glass-bg:#2e3440b3;--glass-border:#d8dee91a;--chat-user:#88c0d0;--chat-user-text:#2e3440;--chat-agent:#2e3440;--tool-bg:#4c566a;--success:#a3be8c;--danger:#bf616a}*{box-sizing:border-box;margin:0;padding:0}body{background-color:var(--bg-color);color:var(--text-primary);height:100vh;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;overflow:hidden}#root{width:100vw;height:100vh;display:flex}.sidebar{background-color:var(--bg-sidebar);border-right:1px solid var(--glass-border);z-index:100;flex-direction:column;width:280px;display:flex;box-shadow:10px 0 30px -10px #00000080}.agent-identity-card{background:linear-gradient(#3b82f60d 0%,#0000 100%);border-bottom:1px solid #ffffff0d;align-items:center;gap:16px;margin-bottom:8px;padding:24px;display:flex}.agent-avatar{justify-content:center;align-items:center;display:flex}.agent-info{flex-direction:column;gap:4px;display:flex}.agent-name{color:#fff;letter-spacing:-.025em;font-size:1.1rem;font-weight:700}.agent-status{color:#4ade80;letter-spacing:.05em;align-items:center;gap:6px;font-size:.75rem;font-weight:600;display:flex}.status-dot{background-color:#4ade80;border-radius:50%;width:8px;height:8px;animation:2s infinite pulse-green;box-shadow:0 0 8px #4ade80}@keyframes pulse-green{0%{transform:scale(.95);box-shadow:0 0 #4ade80b3}70%{transform:scale(1);box-shadow:0 0 0 6px #4ade8000}to{transform:scale(.95);box-shadow:0 0 #4ade8000}}.sidebar-scroll-area{flex:1;padding-bottom:24px;overflow-y:auto}.sidebar-scroll-area::-webkit-scrollbar{width:4px}.sidebar-scroll-area::-webkit-scrollbar-thumb{background:#ffffff0d}.sidebar-section{color:#8b9bb4;padding:24px 24px 8px;font-size:.75rem;font-weight:500}.sidebar-nav{flex-direction:column;gap:4px;padding:0 16px;display:flex}.nav-item{color:#94a3b8;cursor:pointer;border:1px solid #0000;border-radius:8px;align-items:center;gap:10px;padding:8px 12px;font-size:.8rem;font-weight:500;transition:all .25s cubic-bezier(.4,0,.2,1);display:flex}.nav-icon{transition:transform .25s cubic-bezier(.4,0,.2,1)}.nav-item:hover{color:#fff;background-color:#ffffff08;transform:translate(4px)}.nav-item:hover .nav-icon{color:#fff;transform:scale(1.1)}.sessions-list{flex:none!important;justify-content:flex-start!important;gap:0!important;height:max-content!important}.session-item{justify-content:space-between;flex:none!important;height:max-content!important;min-height:28px!important;margin-top:0!important;margin-bottom:2px!important;padding:4px 10px!important}.delete-session-btn{color:#bf616a;cursor:pointer;opacity:0;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:4px;transition:opacity .2s,transform .2s;display:flex}.delete-session-btn:hover{background:#bf616a33;transform:scale(1.1)}.session-item:hover .delete-session-btn{opacity:1}.nav-item.active{color:#fff;border-left:3px solid var(--accent);background:linear-gradient(90deg,#3b82f626 0%,#0000 100%);border-radius:4px 12px 12px 4px;font-weight:600}.nav-item.active .nav-icon{color:var(--accent)}.main-content{background-image:radial-gradient(at 0 0,#3b82f61a 0,#0000 50%),radial-gradient(at 100% 100%,#8b5cf61a 0,#0000 50%);flex-direction:column;flex:1;display:flex}.topbar{border-bottom:1px solid var(--glass-border);background:var(--bg-color);justify-content:space-between;align-items:center;height:64px;padding:0 24px;display:flex}.topbar-left{color:var(--text-secondary);align-items:center;gap:16px;font-size:.95rem;font-weight:500;display:flex}.topbar-right{align-items:center;gap:12px;display:flex}.custom-network-selector{position:relative}.network-selector-pill{color:#000;cursor:pointer;background:#88c0d0;border:none;border-radius:9999px;outline:none;align-items:center;gap:8px;padding:8px 16px;font-family:inherit;font-size:.85rem;font-weight:600;transition:all .2s;display:flex}.network-selector-pill:hover{opacity:.9;box-shadow:0 0 10px #88c0d066}.network-selector-pill:focus-visible{box-shadow:0 0 0 2px #88c0d080}.network-icon{flex-shrink:0}.network-chevron{opacity:.7;margin-left:4px}.network-dropdown-menu{background:var(--bg-secondary);border:1px solid var(--glass-border);z-index:100;border-radius:12px;min-width:180px;margin:0;padding:6px;list-style:none;animation:.2s ease-out dropdownSlideIn;position:absolute;top:calc(100% + 8px);right:0;box-shadow:0 8px 24px #0006}@keyframes dropdownSlideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.network-dropdown-item{cursor:pointer;color:#e5e7eb;border-radius:8px;padding:10px 14px;font-size:.85rem;transition:background .1s}.network-dropdown-item:hover{background:#ffffff0d}.network-dropdown-item.active{color:#88c0d0;background:#88c0d01a;font-weight:600}.workspace-container{width:100%;height:calc(100vh - 64px);display:flex}.chat-wrapper{flex-direction:column;height:100%;padding:24px 0;display:flex}.resizer{background:var(--glass-border);cursor:col-resize;z-index:10;width:6px;transition:background .2s}.resizer:hover,.resizer:active{background:var(--accent)}.canvas-panel{background:var(--bg-sidebar);background-image:radial-gradient(#3b82f60d 0,#0000 80%);flex-direction:column;flex:1;padding:32px;display:flex;position:relative;overflow-y:auto}.canvas-header{border-bottom:1px solid #ffffff0d;justify-content:space-between;align-items:center;margin-bottom:32px;padding-bottom:16px;display:flex}.canvas-title{color:#94a3b8;text-transform:uppercase;letter-spacing:.05em;align-items:center;gap:8px;font-family:monospace;font-size:.85rem;display:flex}.canvas-empty{color:#475569;flex-direction:column;justify-content:center;align-items:center;gap:16px;height:100%;display:flex}.chat-container{flex-direction:column;flex:1;gap:20px;padding:0 24px;display:flex;overflow-y:auto}.chat-container::-webkit-scrollbar{width:6px}.chat-container::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}.message-wrapper{flex-direction:column;max-width:85%;animation:.3s ease-out forwards fadeIn;display:flex}.message-wrapper.agent{flex-direction:row;align-self:flex-start;align-items:flex-end;gap:8px}.message-wrapper.user{flex-direction:row-reverse;align-self:flex-end;align-items:flex-end;gap:8px}.copy-btn{color:var(--text-secondary);cursor:pointer;opacity:0;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:6px;transition:opacity .2s,background .2s;display:flex}.copy-btn:hover{background:var(--bg-secondary);color:var(--text-primary)}.message-wrapper:hover .copy-btn{opacity:1}.message-bubble{white-space:pre-wrap;border-radius:18px;padding:14px 18px;font-size:.95rem;line-height:1.6;box-shadow:0 4px 6px -1px #0000001a}.user .message-bubble{background-color:var(--chat-user);color:var(--chat-user-text);border-bottom-right-radius:4px}.agent .message-bubble{background-color:var(--chat-agent);border:1px solid var(--glass-border);color:var(--text-primary);border-bottom-left-radius:4px}.tool-call{color:var(--text-secondary);background:var(--tool-bg);border:1px solid var(--glass-border);border-radius:12px;align-items:center;gap:8px;margin-top:10px;padding:10px 14px;font-size:.85rem;display:flex}.tool-call code{color:var(--accent);font-family:monospace}.input-area{padding:20px 24px 0}.input-form{background:var(--bg-secondary);border:1px solid var(--glass-border);border-radius:16px;gap:12px;padding:8px;transition:all .2s;display:flex}.input-form:focus-within{border-color:var(--accent);box-shadow:0 0 0 2px #3b82f633}.chat-input{color:#fff;background:0 0;border:none;outline:none;flex:1;padding:12px 16px;font-family:inherit;font-size:.95rem}.send-button{background:var(--accent);color:#fff;cursor:pointer;border:none;border-radius:12px;justify-content:center;align-items:center;width:44px;height:44px;transition:all .2s;display:flex}.voice-button{background:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--glass-border);cursor:pointer;border-radius:12px;justify-content:center;align-items:center;width:44px;height:44px;transition:all .2s;display:flex}.voice-button:hover{color:#fff;border-color:#ef4444}.voice-button.listening{color:#ef4444;background:#ef444433;border-color:#ef4444;animation:1.5s infinite pulse-red}.voice-button.active-mode{color:#3b82f6;border-color:#3b82f6}.voice-button.speaking{color:#3b82f6;background:#3b82f633;border-color:#3b82f6;animation:1.5s infinite pulse-blue}@keyframes pulse-red{0%{box-shadow:0 0 #ef444466}70%{box-shadow:0 0 0 10px #ef444400}to{box-shadow:0 0 #ef444400}}@keyframes pulse-blue{0%{box-shadow:0 0 #3b82f666}70%{box-shadow:0 0 0 10px #3b82f600}to{box-shadow:0 0 #3b82f600}}.send-button:hover:not(:disabled){background:var(--accent-hover);transform:scale(1.05)}.send-button:disabled{opacity:.5;cursor:not-allowed}.typing-indicator{background-color:var(--chat-agent);border:1px solid var(--glass-border);border-radius:18px 18px 18px 4px;align-self:flex-start;gap:4px;width:fit-content;padding:14px 18px;display:flex}.dot{background:var(--text-secondary);border-radius:50%;width:6px;height:6px;animation:1.4s ease-in-out infinite both bounce}.dot:first-child{animation-delay:-.32s}.dot:nth-child(2){animation-delay:-.16s}@keyframes bounce{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.prompt-suggestions{gap:12px;margin-bottom:12px;display:flex;overflow-x:auto}.prompt-suggestions button{background:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--glass-border);cursor:pointer;white-space:nowrap;border-radius:20px;padding:8px 16px;font-size:.85rem;transition:all .2s}.prompt-suggestions button:hover{border-color:var(--accent);color:var(--text-primary)}.trending-tokens{color:var(--text-secondary);align-items:center;gap:12px;margin-top:12px;font-size:.8rem;display:flex}.token-tag{background:var(--accent);color:var(--bg-color);cursor:pointer;border-radius:12px;padding:4px 10px;font-weight:600;transition:transform .2s,filter .2s}.token-tag:hover{filter:brightness(1.2);transform:translateY(-2px)}.nord-label{color:#81a1c1;text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px;font-size:.75rem;font-weight:700;display:block}.nord-pill-input{color:#88c0d0;background-color:#2e3440b3;border:1px solid #d8dee91a;border-radius:9999px;outline:none;width:100%;padding:10px 20px;font-size:.9rem;font-weight:600;transition:all .2s}.nord-pill-input:focus{border-color:#88c0d0;box-shadow:0 0 10px #88c0d033}.nord-pill-input::placeholder{color:#4c566a}.nord-input{color:#eceff4;background-color:#2e3440;border:1px solid #434c5e;border-radius:6px;outline:none;width:100%;padding:10px 14px;font-size:.9rem;transition:all .2s}.nord-input:focus{border-color:#88c0d0;box-shadow:0 0 0 2px #88c0d033}.nord-input::placeholder{color:#4c566a}.nord-slider{appearance:none;background:#4c566a;border-radius:3px;outline:none;width:100%;height:6px;margin-top:10px}.nord-slider::-webkit-slider-thumb{appearance:none;cursor:pointer;background:#eceff4;border:2px solid #88c0d0;border-radius:50%;width:18px;height:18px;transition:all .2s}.nord-slider::-webkit-slider-thumb:hover{background:#fff;transform:scale(1.1)}.nord-slider::-moz-range-thumb{cursor:pointer;background:#eceff4;border:2px solid #88c0d0;border-radius:50%;width:18px;height:18px;transition:all .2s}.nord-btn-primary{color:#2e3440;cursor:pointer;background-color:#81a1c1;border:none;border-radius:6px;justify-content:center;align-items:center;padding:10px 20px;font-size:.9rem;font-weight:600;transition:background-color .2s;display:flex}.nord-btn-primary:hover{background-color:#88c0d0}.nord-btn-primary:disabled{color:#8fbcbb;cursor:not-allowed;background-color:#4c566a}.nord-panel-header{border-bottom:1px solid #d8dee90d;align-items:center;gap:10px;margin-bottom:20px;padding-bottom:12px;display:flex}.nord-panel-header h3{color:#eceff4;margin:0;font-size:1.1rem;font-weight:600}.overview-container{color:#fff;max-width:1200px;height:calc(100vh - 64px);margin:0 auto;padding:24px;font-family:Inter,sans-serif;overflow-y:auto}.overview-container::-webkit-scrollbar{width:6px}.overview-container::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}.overview-header h1{margin-bottom:4px;font-size:1.5rem;font-weight:600}.overview-header p{color:var(--text-secondary);margin-bottom:24px;font-size:.9rem}.panel{background:#14182099;border:1px solid #ffffff0d;border-radius:12px;margin-bottom:24px;padding:20px}.panel-header h3{margin-bottom:4px;font-size:1.1rem;font-weight:600}.panel-header p{color:var(--text-secondary);margin-bottom:16px;font-size:.85rem}.form-group{margin-bottom:16px}.form-row{gap:16px;display:flex}.flex-1{flex:1}label{text-transform:uppercase;color:var(--text-secondary);letter-spacing:.05em;margin-bottom:8px;font-size:.75rem;display:block}input,select{color:#fff;background:#0000004d;border:1px solid #ffffff1a;border-radius:8px;width:100%;padding:10px 12px;font-family:monospace;font-size:.9rem}input:read-only{color:var(--text-secondary)}.input-with-icon{align-items:center;display:flex;position:relative}.input-with-icon svg{color:var(--text-secondary);cursor:pointer;position:absolute;right:12px}.form-actions{align-items:center;gap:12px;margin-top:20px;display:flex}.btn-primary{color:#fff;cursor:pointer;background:#3b82f6;border:none;border-radius:6px;padding:8px 16px;font-size:.9rem}.btn-secondary{color:#fff;cursor:pointer;background:0 0;border:1px solid #fff3;border-radius:6px;padding:8px 16px;font-size:.9rem}.action-hint{color:var(--text-secondary);margin-left:8px;font-size:.85rem}.snapshot-grid{grid-template-columns:repeat(4,1fr);gap:20px;display:grid}.stat-val{margin-bottom:4px;font-size:1.5rem;font-weight:700}.text-green{color:#22c55e}.stat-block p{color:var(--text-secondary);margin-top:8px;font-size:.8rem;line-height:1.4}.metrics-grid{grid-template-columns:repeat(5,1fr);gap:16px;margin-bottom:32px;display:grid}.metric-card{background:#14182099;border:1px solid #ffffff0d;border-radius:12px;padding:16px}.metric-val{margin-bottom:4px;font-size:1.5rem;font-weight:700}.metric-sub{color:var(--text-secondary);font-size:.75rem}.section-title{text-transform:uppercase;color:var(--text-secondary);letter-spacing:.05em;margin-bottom:12px;font-size:.75rem}.session-item{justify-content:space-between;margin-bottom:24px;padding:16px 20px;display:flex}.text-secondary{color:var(--text-secondary)}.attention-panel{background:#eab3081a;border:1px solid #eab30833;border-radius:12px;flex-direction:column;margin-bottom:24px;padding:16px 20px;display:flex}.attention-header{color:#eab308;align-items:center;gap:8px;margin-bottom:8px;display:flex}.attention-header h4{font-size:1rem;font-weight:600}.attention-content p{margin-bottom:4px;font-size:.95rem}.attention-content span{font-size:.85rem}.logs-grid{grid-template-columns:1fr 1fr;gap:16px;display:grid}.log-panel{background:#0a0c10cc;border:1px solid #ffffff0d;border-radius:12px;flex-direction:column;height:300px;display:flex;overflow:hidden}.log-header{background:#ffffff0d;border-bottom:1px solid #ffffff0d;padding:12px 16px;font-size:.85rem;font-weight:600}.badge{background:#ffffff1a;border-radius:10px;margin-left:8px;padding:2px 6px;font-size:.7rem}.log-content{flex-direction:column;gap:4px;padding:12px 16px;display:flex;overflow:auto}.log-content::-webkit-scrollbar{width:6px;height:6px}.log-content::-webkit-scrollbar-thumb{background:#434c5e;border-radius:4px}.log-content::-webkit-scrollbar-thumb:hover{background:#4c566a}.log-content::-webkit-scrollbar-corner{background:0 0}.memory-log-container::-webkit-scrollbar{width:6px;height:6px}.memory-log-container::-webkit-scrollbar-thumb{background:#434c5e;border-radius:4px}.memory-log-container::-webkit-scrollbar-thumb:hover{background:#4c566a}.memory-log-container::-webkit-scrollbar-corner{background:0 0}.log-content code,.log-json{color:#a3a3a3;word-break:break-all;font-family:Consolas,Monaco,monospace;font-size:.75rem;line-height:1.4}.log-row{gap:12px;margin-bottom:4px;font-family:Consolas,Monaco,monospace;font-size:.75rem;display:flex}.log-time{color:#fb923c;min-width:60px}.log-msg{color:#d1d5db}.log-meta{color:#6b7280}.gateway-row{margin-bottom:2px}
|
|
1
|
+
:root{--bg-color:#3b4252;--bg-secondary:#434c5e;--bg-sidebar:#2e3440;--text-primary:#eceff4;--text-secondary:#d8dee9;--accent:#88c0d0;--accent-hover:#81a1c1;--glass-bg:#2e3440b3;--glass-border:#d8dee91a;--chat-user:#88c0d0;--chat-user-text:#2e3440;--chat-agent:#2e3440;--tool-bg:#4c566a;--success:#a3be8c;--danger:#bf616a}*{box-sizing:border-box;margin:0;padding:0}body{background-color:var(--bg-color);color:var(--text-primary);height:100vh;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,sans-serif;overflow:hidden}#root{width:100vw;height:100vh;display:flex}.sidebar{background-color:var(--bg-sidebar);border-right:1px solid var(--glass-border);z-index:100;flex-direction:column;width:280px;display:flex;box-shadow:10px 0 30px -10px #00000080}.agent-identity-card{background:linear-gradient(#3b82f60d 0%,#0000 100%);border-bottom:1px solid #ffffff0d;align-items:center;gap:16px;margin-bottom:8px;padding:24px;display:flex}.agent-avatar{justify-content:center;align-items:center;display:flex}.agent-info{flex-direction:column;gap:4px;display:flex}.agent-name{color:#fff;letter-spacing:-.025em;font-size:1.1rem;font-weight:700}.agent-status{color:#4ade80;letter-spacing:.05em;align-items:center;gap:6px;font-size:.75rem;font-weight:600;display:flex}.status-dot{background-color:#4ade80;border-radius:50%;width:8px;height:8px;animation:2s infinite pulse-green;box-shadow:0 0 8px #4ade80}@keyframes pulse-green{0%{transform:scale(.95);box-shadow:0 0 #4ade80b3}70%{transform:scale(1);box-shadow:0 0 0 6px #4ade8000}to{transform:scale(.95);box-shadow:0 0 #4ade8000}}.sidebar-scroll-area{flex:1;padding-bottom:24px;overflow-y:auto}.sidebar-scroll-area::-webkit-scrollbar{width:4px}.sidebar-scroll-area::-webkit-scrollbar-thumb{background:#ffffff0d}.sidebar-section{color:#8b9bb4;padding:24px 24px 8px;font-size:.75rem;font-weight:500}.sidebar-nav{flex-direction:column;gap:4px;padding:0 16px;display:flex}.nav-item{color:#94a3b8;cursor:pointer;border:1px solid #0000;border-radius:8px;align-items:center;gap:10px;padding:8px 12px;font-size:.8rem;font-weight:500;transition:all .25s cubic-bezier(.4,0,.2,1);display:flex}.nav-icon{transition:transform .25s cubic-bezier(.4,0,.2,1)}.nav-item:hover{color:#fff;background-color:#ffffff08;transform:translate(4px)}.nav-item:hover .nav-icon{color:#fff;transform:scale(1.1)}.sessions-list{flex:none!important;justify-content:flex-start!important;gap:0!important;height:max-content!important}.session-item{justify-content:space-between;flex:none!important;height:max-content!important;min-height:28px!important;margin-top:0!important;margin-bottom:2px!important;padding:4px 10px!important}.delete-session-btn{color:#bf616a;cursor:pointer;opacity:0;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:4px;transition:opacity .2s,transform .2s;display:flex}.delete-session-btn:hover{background:#bf616a33;transform:scale(1.1)}.session-item:hover .delete-session-btn{opacity:1}.nav-item.active{color:#fff;border-left:3px solid var(--accent);background:linear-gradient(90deg,#3b82f626 0%,#0000 100%);border-radius:4px 12px 12px 4px;font-weight:600}.nav-item.active .nav-icon{color:var(--accent)}.main-content{background-image:radial-gradient(at 0 0,#3b82f61a 0,#0000 50%),radial-gradient(at 100% 100%,#8b5cf61a 0,#0000 50%);flex-direction:column;flex:1;display:flex}.topbar{border-bottom:1px solid var(--glass-border);background:var(--bg-color);justify-content:space-between;align-items:center;height:64px;padding:0 24px;display:flex}.topbar-left{color:var(--text-secondary);align-items:center;gap:16px;font-size:.95rem;font-weight:500;display:flex}.topbar-right{align-items:center;gap:12px;display:flex}.custom-network-selector{position:relative}.network-selector-pill{color:#000;cursor:pointer;background:#88c0d0;border:none;border-radius:9999px;outline:none;align-items:center;gap:8px;padding:8px 16px;font-family:inherit;font-size:.85rem;font-weight:600;transition:all .2s;display:flex}.network-selector-pill:hover{opacity:.9;box-shadow:0 0 10px #88c0d066}.network-selector-pill:focus-visible{box-shadow:0 0 0 2px #88c0d080}.network-icon{flex-shrink:0}.network-chevron{opacity:.7;margin-left:4px}.network-dropdown-menu{background:var(--bg-secondary);border:1px solid var(--glass-border);z-index:100;border-radius:12px;min-width:180px;margin:0;padding:6px;list-style:none;animation:.2s ease-out dropdownSlideIn;position:absolute;top:calc(100% + 8px);right:0;box-shadow:0 8px 24px #0006}@keyframes dropdownSlideIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.network-dropdown-item{cursor:pointer;color:#e5e7eb;border-radius:8px;padding:10px 14px;font-size:.85rem;transition:background .1s}.network-dropdown-item:hover{background:#ffffff0d}.network-dropdown-item.active{color:#88c0d0;background:#88c0d01a;font-weight:600}.workspace-container{width:100%;height:calc(100vh - 64px);display:flex}.chat-wrapper{flex-direction:column;height:100%;padding:24px 0;display:flex}.resizer{background:var(--glass-border);cursor:col-resize;z-index:10;width:6px;transition:background .2s}.resizer:hover,.resizer:active{background:var(--accent)}.canvas-panel{background:var(--bg-sidebar);background-image:radial-gradient(#3b82f60d 0,#0000 80%);flex-direction:column;flex:1;padding:32px;display:flex;position:relative;overflow-y:auto}.canvas-header{border-bottom:1px solid #ffffff0d;justify-content:space-between;align-items:center;margin-bottom:32px;padding-bottom:16px;display:flex}.canvas-title{color:#94a3b8;text-transform:uppercase;letter-spacing:.05em;align-items:center;gap:8px;font-family:monospace;font-size:.85rem;display:flex}.canvas-empty{color:#475569;flex-direction:column;justify-content:center;align-items:center;gap:16px;height:100%;display:flex}.chat-container{flex-direction:column;flex:1;gap:20px;padding:0 24px;display:flex;overflow-y:auto}.chat-container::-webkit-scrollbar{width:6px}.chat-container::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}.message-wrapper{flex-direction:column;max-width:85%;animation:.3s ease-out forwards fadeIn;display:flex}.message-wrapper.agent{flex-direction:row;align-self:flex-start;align-items:flex-end;gap:8px}.message-wrapper.user{flex-direction:row-reverse;align-self:flex-end;align-items:flex-end;gap:8px}.copy-btn{color:var(--text-secondary);cursor:pointer;opacity:0;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:6px;transition:opacity .2s,background .2s;display:flex}.copy-btn:hover{background:var(--bg-secondary);color:var(--text-primary)}.message-wrapper:hover .copy-btn{opacity:1}.message-bubble{white-space:pre-wrap;border-radius:18px;padding:14px 18px;font-size:.95rem;line-height:1.6;box-shadow:0 4px 6px -1px #0000001a}.user .message-bubble{background-color:var(--chat-user);color:var(--chat-user-text);border-bottom-right-radius:4px}.agent .message-bubble{background-color:var(--chat-agent);border:1px solid var(--glass-border);color:var(--text-primary);border-bottom-left-radius:4px}.tool-call{color:var(--text-secondary);background:var(--tool-bg);border:1px solid var(--glass-border);border-radius:12px;align-items:center;gap:8px;margin-top:10px;padding:10px 14px;font-size:.85rem;display:flex}.tool-call code{color:var(--accent);font-family:monospace}.input-area{padding:20px 24px 0}.input-form{background:var(--bg-secondary);border:1px solid var(--glass-border);border-radius:16px;gap:12px;padding:8px;transition:all .2s;display:flex}.input-form:focus-within{border-color:var(--accent);box-shadow:0 0 0 2px #3b82f633}.chat-input{color:#fff;background:0 0;border:none;outline:none;flex:1;padding:12px 16px;font-family:inherit;font-size:.95rem}.send-button{background:var(--accent);color:#fff;cursor:pointer;border:none;border-radius:12px;justify-content:center;align-items:center;width:44px;height:44px;transition:all .2s;display:flex}.voice-button{background:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--glass-border);cursor:pointer;border-radius:12px;justify-content:center;align-items:center;width:44px;height:44px;transition:all .2s;display:flex}.voice-button:hover{color:#fff;border-color:#ef4444}.voice-button.listening{color:#ef4444;background:#ef444433;border-color:#ef4444;animation:1.5s infinite pulse-red}.voice-button.active-mode{color:#3b82f6;border-color:#3b82f6}.voice-button.speaking{color:#3b82f6;background:#3b82f633;border-color:#3b82f6;animation:1.5s infinite pulse-blue}@keyframes pulse-red{0%{box-shadow:0 0 #ef444466}70%{box-shadow:0 0 0 10px #ef444400}to{box-shadow:0 0 #ef444400}}@keyframes pulse-blue{0%{box-shadow:0 0 #3b82f666}70%{box-shadow:0 0 0 10px #3b82f600}to{box-shadow:0 0 #3b82f600}}.send-button:hover:not(:disabled){background:var(--accent-hover);transform:scale(1.05)}.send-button:disabled{opacity:.5;cursor:not-allowed}.typing-indicator{background-color:var(--chat-agent);border:1px solid var(--glass-border);border-radius:18px 18px 18px 4px;align-self:flex-start;gap:4px;width:fit-content;padding:14px 18px;display:flex}.dot{background:var(--text-secondary);border-radius:50%;width:6px;height:6px;animation:1.4s ease-in-out infinite both bounce}.dot:first-child{animation-delay:-.32s}.dot:nth-child(2){animation-delay:-.16s}@keyframes bounce{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.prompt-suggestions{gap:12px;margin-bottom:12px;display:flex;overflow-x:auto}.prompt-suggestions button{background:var(--bg-secondary);color:var(--text-secondary);border:1px solid var(--glass-border);cursor:pointer;white-space:nowrap;border-radius:20px;padding:8px 16px;font-size:.85rem;transition:all .2s}.prompt-suggestions button:hover{border-color:var(--accent);color:var(--text-primary)}.trending-tokens{color:var(--text-secondary);align-items:center;gap:12px;margin-top:12px;font-size:.8rem;display:flex}.token-tag{background:var(--accent);color:var(--bg-color);cursor:pointer;border-radius:12px;padding:4px 10px;font-weight:600;transition:transform .2s,filter .2s}.token-tag:hover{filter:brightness(1.2);transform:translateY(-2px)}.nord-label{color:#81a1c1;text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px;font-size:.75rem;font-weight:700;display:block}.nord-pill-input{color:#88c0d0;background-color:#2e3440b3;border:1px solid #d8dee91a;border-radius:9999px;outline:none;width:100%;padding:10px 20px;font-size:.9rem;font-weight:600;transition:all .2s}.nord-pill-input:focus{border-color:#88c0d0;box-shadow:0 0 10px #88c0d033}.nord-pill-input::placeholder{color:#4c566a}.nord-input{color:#eceff4;background-color:#2e3440;border:1px solid #434c5e;border-radius:6px;outline:none;width:100%;padding:10px 14px;font-size:.9rem;transition:all .2s}.nord-input:focus{border-color:#88c0d0;box-shadow:0 0 0 2px #88c0d033}.nord-input::placeholder{color:#4c566a}.nord-slider{appearance:none;background:#4c566a;border-radius:3px;outline:none;width:100%;height:6px;margin-top:10px}.nord-slider::-webkit-slider-thumb{appearance:none;cursor:pointer;background:#eceff4;border:2px solid #88c0d0;border-radius:50%;width:18px;height:18px;transition:all .2s}.nord-slider::-webkit-slider-thumb:hover{background:#fff;transform:scale(1.1)}.nord-slider::-moz-range-thumb{cursor:pointer;background:#eceff4;border:2px solid #88c0d0;border-radius:50%;width:18px;height:18px;transition:all .2s}.nord-btn-primary{color:#2e3440;cursor:pointer;background-color:#81a1c1;border:none;border-radius:6px;justify-content:center;align-items:center;padding:10px 20px;font-size:.9rem;font-weight:600;transition:background-color .2s;display:flex}.nord-btn-primary:hover{background-color:#88c0d0}.nord-btn-primary:disabled{color:#8fbcbb;cursor:not-allowed;background-color:#4c566a}.nord-panel-header{border-bottom:1px solid #d8dee90d;align-items:center;gap:10px;margin-bottom:20px;padding-bottom:12px;display:flex}.nord-panel-header h3{color:#eceff4;margin:0;font-size:1.1rem;font-weight:600}.overview-container{color:#fff;height:calc(100vh - 64px);padding:24px;font-family:Inter,sans-serif;overflow-y:auto}.overview-container::-webkit-scrollbar{width:6px}.overview-container::-webkit-scrollbar-thumb{background:#ffffff1a;border-radius:4px}.overview-header h1{margin-bottom:4px;font-size:1.5rem;font-weight:600}.overview-header p{color:var(--text-secondary);margin-bottom:24px;font-size:.9rem}.panel{background:#14182099;border:1px solid #ffffff0d;border-radius:12px;margin-bottom:24px;padding:20px}.panel-header h3{margin-bottom:4px;font-size:1.1rem;font-weight:600}.panel-header p{color:var(--text-secondary);margin-bottom:16px;font-size:.85rem}.form-group{margin-bottom:16px}.form-row{gap:16px;display:flex}.flex-1{flex:1}label{text-transform:uppercase;color:var(--text-secondary);letter-spacing:.05em;margin-bottom:8px;font-size:.75rem;display:block}input,select{color:#fff;background:#0000004d;border:1px solid #ffffff1a;border-radius:8px;width:100%;padding:10px 12px;font-family:monospace;font-size:.9rem}input:read-only{color:var(--text-secondary)}.input-with-icon{align-items:center;display:flex;position:relative}.input-with-icon svg{color:var(--text-secondary);cursor:pointer;position:absolute;right:12px}.form-actions{align-items:center;gap:12px;margin-top:20px;display:flex}.btn-primary{color:#fff;cursor:pointer;background:#3b82f6;border:none;border-radius:6px;padding:8px 16px;font-size:.9rem}.btn-secondary{color:#fff;cursor:pointer;background:0 0;border:1px solid #fff3;border-radius:6px;padding:8px 16px;font-size:.9rem}.action-hint{color:var(--text-secondary);margin-left:8px;font-size:.85rem}.snapshot-grid{grid-template-columns:repeat(4,1fr);gap:20px;display:grid}.stat-val{margin-bottom:4px;font-size:1.5rem;font-weight:700}.text-green{color:#22c55e}.stat-block p{color:var(--text-secondary);margin-top:8px;font-size:.8rem;line-height:1.4}.metrics-grid{grid-template-columns:repeat(5,1fr);gap:16px;margin-bottom:32px;display:grid}.metric-card{background:#14182099;border:1px solid #ffffff0d;border-radius:12px;padding:16px}.metric-val{margin-bottom:4px;font-size:1.5rem;font-weight:700}.metric-sub{color:var(--text-secondary);font-size:.75rem}.section-title{text-transform:uppercase;color:var(--text-secondary);letter-spacing:.05em;margin-bottom:12px;font-size:.75rem}.session-item{justify-content:space-between;margin-bottom:24px;padding:16px 20px;display:flex}.text-secondary{color:var(--text-secondary)}.attention-panel{background:#eab3081a;border:1px solid #eab30833;border-radius:12px;flex-direction:column;margin-bottom:24px;padding:16px 20px;display:flex}.attention-header{color:#eab308;align-items:center;gap:8px;margin-bottom:8px;display:flex}.attention-header h4{font-size:1rem;font-weight:600}.attention-content p{margin-bottom:4px;font-size:.95rem}.attention-content span{font-size:.85rem}.logs-grid{grid-template-columns:1fr 1fr;gap:16px;display:grid}.log-panel{background:#0a0c10cc;border:1px solid #ffffff0d;border-radius:12px;flex-direction:column;height:300px;display:flex;overflow:hidden}.log-header{background:#ffffff0d;border-bottom:1px solid #ffffff0d;padding:12px 16px;font-size:.85rem;font-weight:600}.badge{background:#ffffff1a;border-radius:10px;margin-left:8px;padding:2px 6px;font-size:.7rem}.log-content{flex-direction:column;gap:4px;padding:12px 16px;display:flex;overflow:auto}.log-content::-webkit-scrollbar{width:6px;height:6px}.log-content::-webkit-scrollbar-thumb{background:#434c5e;border-radius:4px}.log-content::-webkit-scrollbar-thumb:hover{background:#4c566a}.log-content::-webkit-scrollbar-corner{background:0 0}.memory-log-container::-webkit-scrollbar{width:6px;height:6px}.memory-log-container::-webkit-scrollbar-thumb{background:#434c5e;border-radius:4px}.memory-log-container::-webkit-scrollbar-thumb:hover{background:#4c566a}.memory-log-container::-webkit-scrollbar-corner{background:0 0}.log-content code,.log-json{color:#a3a3a3;word-break:break-all;font-family:Consolas,Monaco,monospace;font-size:.75rem;line-height:1.4}.log-row{gap:12px;margin-bottom:4px;font-family:Consolas,Monaco,monospace;font-size:.75rem;display:flex}.log-time{color:#fb923c;min-width:60px}.log-msg{color:#d1d5db}.log-meta{color:#6b7280}.gateway-row{margin-bottom:2px}
|