diff --git a/frontend/index.html b/frontend/index.html index 4a60860..5be239e 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -63,41 +63,55 @@
-

Recent Activity

-

Track latest agent executions across all directives.

+

Perspective

+

Overview of recent agent directives and live communication.

+ +
+ + +
+
-
- - - - - - - - - - - -
DirectiveStatusDate
+
+
+
+

Neural Link

+ +
+
+ +
+

Establish connection with the neural assistant.

+
+
+
+ + +
+
-
-
-

Quick Chat

- +
+
+ + + + + + + + + + + +
DirectiveStatusDate
-
- -
-

Start a conversation with the assistant.

-
-
-
- - -
diff --git a/frontend/src/main.js b/frontend/src/main.js index a3569ae..e7ac424 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -17,7 +17,8 @@ const state = { currentView: 'dashboard', // 'dashboard' or 'task' isEditing: false, isAuthenticated: false, - chatMessages: [] + chatMessages: [], + activeDashboardTab: 'chat' // 'chat' or 'activity' }; // DOM elements const loginOverlay = document.getElementById('login-overlay'); @@ -271,6 +272,28 @@ function showDashboard() { renderTaskList(); fetchRecentRuns(); + renderDashboardTabs(); +} + +function renderDashboardTabs() { + const tabs = document.querySelectorAll('.tab-btn'); + const panels = document.querySelectorAll('.tab-panel'); + + tabs.forEach(tab => { + if (tab.dataset.tab === state.activeDashboardTab) { + tab.classList.add('active'); + } else { + tab.classList.remove('active'); + } + }); + + panels.forEach(panel => { + if (panel.id === `${state.activeDashboardTab}-tab-panel`) { + panel.classList.add('active'); + } else { + panel.classList.remove('active'); + } + }); } function renderDashboard(recentRuns) { @@ -723,6 +746,13 @@ logoutBtn.addEventListener('click', () => { logout(); }); +document.querySelectorAll('.tab-btn').forEach(btn => { + btn.addEventListener('click', () => { + state.activeDashboardTab = btn.dataset.tab; + renderDashboardTabs(); + }); +}); + async function initializeApp() { const hasSession = await checkSession(); diff --git a/frontend/src/style.css b/frontend/src/style.css index 4552f6f..f34da31 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -88,9 +88,15 @@ body { .dashboard-content { flex: 1; overflow-y: auto; - border-radius: 12px; + border-radius: 16px; display: flex; flex-direction: column; + width: 100%; + max-width: 900px; + background: rgba(255, 255, 255, 0.02); + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); + border: 1px solid var(--glass-border); + min-height: 0; } .activity-table { @@ -125,19 +131,73 @@ body { } .dashboard-content-grid { - display: grid; - grid-template-columns: 1fr 350px; - gap: 24px; + display: flex; + flex-direction: column; + align-items: center; + gap: 32px; flex: 1; min-height: 0; + width: 100%; +} + +.dashboard-tabs { + display: flex; + gap: 12px; + margin-top: 24px; +} + +.tab-btn { + background: rgba(255, 255, 255, 0.03); + border: 1px solid var(--glass-border); + color: var(--text-dim); + padding: 10px 20px; + border-radius: 100px; + font-size: 14px; + font-weight: 600; + cursor: pointer; + transition: var(--transition); + display: flex; + align-items: center; + gap: 8px; +} + +.tab-btn:hover { + background: rgba(255, 255, 255, 0.08); + color: var(--text-main); +} + +.tab-btn.active { + background: var(--primary); + color: white; + border-color: var(--primary); + box-shadow: 0 4px 15px var(--primary-glow); +} + +.tab-panel { + display: none; + width: 100%; + flex-direction: column; + align-items: center; + flex: 1; + min-height: 0; +} + +.tab-panel.active { + display: flex; } .chat-container { display: flex; flex-direction: column; - border-radius: 12px; + border-radius: 16px; overflow: hidden; background: rgba(255, 255, 255, 0.02); + width: 100%; + max-width: 900px; + flex: 1; + min-height: 0; + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); + border: 1px solid var(--glass-border); } .chat-header { @@ -176,11 +236,11 @@ body { } .chat-message { - max-width: 85%; - padding: 10px 14px; - border-radius: 12px; - font-size: 14px; - line-height: 1.4; + max-width: 80%; + padding: 12px 18px; + border-radius: 16px; + font-size: 15px; + line-height: 1.5; word-wrap: break-word; } @@ -210,10 +270,10 @@ body { flex: 1; background: rgba(0, 0, 0, 0.2); border: 1px solid var(--glass-border); - border-radius: 6px; - padding: 8px 12px; + border-radius: 12px; + padding: 12px 20px; color: var(--text-main); - font-size: 14px; + font-size: 15px; outline: none; transition: var(--transition); } @@ -894,9 +954,9 @@ textarea:focus { } .btn-sm { - padding: 6px 12px; + padding: 6px 16px; font-size: 12px; - width: 100%; + width: auto; justify-content: center; } diff --git a/src/domain/agent/tools.rs b/src/domain/agent/tools.rs index bbdff4c..17251d3 100644 --- a/src/domain/agent/tools.rs +++ b/src/domain/agent/tools.rs @@ -96,6 +96,17 @@ pub fn get_tools() -> Vec { }), }, }, + Tool { + tool_type: "function".to_string(), + function: FunctionDefinition { + name: "get_current_time".to_string(), + description: "Get the current date and time in ISO 8601 format".to_string(), + parameters: serde_json::json!({ + "type": "object", + "properties": {}, + }), + }, + }, ] } @@ -198,6 +209,8 @@ pub async fn handle_tool_call( )); } (out, false) + } else if name == "get_current_time" { + (chrono::Utc::now().to_rfc3339(), false) } else { (format!("Error: Unknown tool {}", name), false) };