release(v0.2.0): streaming, MCP protocol, Browser Hand, security enhancements
## Major Features ### Streaming Response System - Implement LlmDriver trait with `stream()` method returning async Stream - Add SSE parsing for Anthropic and OpenAI API streaming - Integrate Tauri event system for frontend streaming (`stream:chunk` events) - Add StreamChunk types: Delta, ToolStart, ToolEnd, Complete, Error ### MCP Protocol Implementation - Add MCP JSON-RPC 2.0 types (mcp_types.rs) - Implement stdio-based MCP transport (mcp_transport.rs) - Support tool discovery, execution, and resource operations ### Browser Hand Implementation - Complete browser automation with Playwright-style actions - Support Navigate, Click, Type, Scrape, Screenshot, Wait actions - Add educational Hands: Whiteboard, Slideshow, Speech, Quiz ### Security Enhancements - Implement command whitelist/blacklist for shell_exec tool - Add SSRF protection with private IP blocking - Create security.toml configuration file ## Test Improvements - Fix test import paths (security-utils, setup) - Fix vi.mock hoisting issues with vi.hoisted() - Update test expectations for validateUrl and sanitizeFilename - Add getUnsupportedLocalGatewayStatus mock ## Documentation Updates - Update architecture documentation - Improve configuration reference - Add quick-start guide updates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,9 @@ import { Users, Loader2, Settings } from 'lucide-react';
|
||||
import { EmptyState } from './components/ui';
|
||||
import { isTauriRuntime, getLocalGatewayStatus, startLocalGateway } from './lib/tauri-gateway';
|
||||
import { useOnboarding } from './lib/use-onboarding';
|
||||
import { intelligenceClient } from './lib/intelligence-client';
|
||||
import { useProposalNotifications, ProposalNotificationHandler } from './lib/useProposalNotifications';
|
||||
import { useToast } from './components/ui/Toast';
|
||||
import type { Clone } from './store/agentStore';
|
||||
|
||||
type View = 'main' | 'settings';
|
||||
@@ -63,6 +66,24 @@ function App() {
|
||||
const { setCurrentAgent, newConversation } = useChatStore();
|
||||
const { isNeeded: onboardingNeeded, isLoading: onboardingLoading, markCompleted } = useOnboarding();
|
||||
|
||||
// Proposal notifications
|
||||
const { toast } = useToast();
|
||||
useProposalNotifications(); // Sets up polling for pending proposals
|
||||
|
||||
// Show toast when new proposals are available
|
||||
useEffect(() => {
|
||||
const handleProposalAvailable = (event: Event) => {
|
||||
const customEvent = event as CustomEvent<{ count: number }>;
|
||||
const { count } = customEvent.detail;
|
||||
toast(`${count} 个新的人格变更提案待审批`, 'info');
|
||||
};
|
||||
|
||||
window.addEventListener('zclaw:proposal-available', handleProposalAvailable);
|
||||
return () => {
|
||||
window.removeEventListener('zclaw:proposal-available', handleProposalAvailable);
|
||||
};
|
||||
}, [toast]);
|
||||
|
||||
useEffect(() => {
|
||||
document.title = 'ZCLAW';
|
||||
}, []);
|
||||
@@ -160,6 +181,41 @@ function App() {
|
||||
// Step 4: Initialize stores with gateway client
|
||||
initializeStores();
|
||||
|
||||
// Step 4.5: Auto-start heartbeat engine for self-evolution
|
||||
try {
|
||||
const defaultAgentId = 'zclaw-main';
|
||||
await intelligenceClient.heartbeat.init(defaultAgentId, {
|
||||
enabled: true,
|
||||
interval_minutes: 30,
|
||||
quiet_hours_start: '22:00',
|
||||
quiet_hours_end: '08:00',
|
||||
notify_channel: 'ui',
|
||||
proactivity_level: 'standard',
|
||||
max_alerts_per_tick: 5,
|
||||
});
|
||||
|
||||
// Sync memory stats to heartbeat engine
|
||||
try {
|
||||
const stats = await intelligenceClient.memory.stats();
|
||||
const taskCount = stats.byType?.['task'] || 0;
|
||||
await intelligenceClient.heartbeat.updateMemoryStats(
|
||||
defaultAgentId,
|
||||
taskCount,
|
||||
stats.totalEntries,
|
||||
stats.storageSizeBytes
|
||||
);
|
||||
console.log('[App] Memory stats synced to heartbeat engine');
|
||||
} catch (statsErr) {
|
||||
console.warn('[App] Failed to sync memory stats:', statsErr);
|
||||
}
|
||||
|
||||
await intelligenceClient.heartbeat.start(defaultAgentId);
|
||||
console.log('[App] Heartbeat engine started for self-evolution');
|
||||
} catch (err) {
|
||||
console.warn('[App] Failed to start heartbeat engine:', err);
|
||||
// Non-critical, continue without heartbeat
|
||||
}
|
||||
|
||||
// Step 5: Bootstrap complete
|
||||
setBootstrapping(false);
|
||||
} catch (err) {
|
||||
@@ -364,6 +420,9 @@ function App() {
|
||||
onReject={handleRejectHand}
|
||||
onClose={handleCloseApprovalModal}
|
||||
/>
|
||||
|
||||
{/* Proposal Notifications Handler */}
|
||||
<ProposalNotificationHandler />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user