feat(intelligence): complete migration to Rust backend

- Unify all intelligence modules to use intelligenceClient
- Delete legacy TS implementations (agent-memory, reflection-engine, heartbeat-engine, context-compactor, agent-identity, memory-index)
- Update all consumers to use snake_case backend types
- Remove deprecated llm-integration.test.ts

This eliminates code duplication between frontend and backend, resolves
localStorage limitations, and enables persistent intelligence features.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-03-21 15:17:39 +08:00
parent 17fb1e69aa
commit f3ec3c8d4c
24 changed files with 1172 additions and 3095 deletions

View File

@@ -26,11 +26,23 @@ import {
RefreshCw,
} from 'lucide-react';
import {
HeartbeatEngine,
DEFAULT_HEARTBEAT_CONFIG,
intelligenceClient,
type HeartbeatConfig as HeartbeatConfigType,
type HeartbeatResult,
} from '../lib/heartbeat-engine';
type HeartbeatAlert,
} from '../lib/intelligence-client';
// === Default Config ===
const DEFAULT_HEARTBEAT_CONFIG: HeartbeatConfigType = {
enabled: false,
interval_minutes: 30,
quiet_hours_start: null,
quiet_hours_end: null,
notify_channel: 'ui',
proactivity_level: 'standard',
max_alerts_per_tick: 5,
};
// === Types ===
@@ -309,8 +321,8 @@ export function HeartbeatConfig({ className = '', onConfigChange }: HeartbeatCon
const handleTestHeartbeat = useCallback(async () => {
setIsTesting(true);
try {
const engine = new HeartbeatEngine('zclaw-main', config);
const result = await engine.tick();
await intelligenceClient.heartbeat.init('zclaw-main', config);
const result = await intelligenceClient.heartbeat.tick('zclaw-main');
setLastResult(result);
} catch (error) {
console.error('[HeartbeatConfig] Test failed:', error);
@@ -408,12 +420,12 @@ export function HeartbeatConfig({ className = '', onConfigChange }: HeartbeatCon
min="5"
max="120"
step="5"
value={config.intervalMinutes}
onChange={(e) => updateConfig({ intervalMinutes: parseInt(e.target.value) })}
value={config.interval_minutes}
onChange={(e) => updateConfig({ interval_minutes: parseInt(e.target.value) })}
className="flex-1 h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer accent-pink-500"
/>
<span className="text-sm font-medium text-gray-900 dark:text-gray-100 w-16 text-right">
{config.intervalMinutes}
{config.interval_minutes}
</span>
</div>
</div>
@@ -428,8 +440,8 @@ export function HeartbeatConfig({ className = '', onConfigChange }: HeartbeatCon
</div>
<div className="pl-6">
<ProactivityLevelSelector
value={config.proactivityLevel}
onChange={(level) => updateConfig({ proactivityLevel: level })}
value={config.proactivity_level}
onChange={(level) => updateConfig({ proactivity_level: level })}
/>
</div>
</div>
@@ -437,15 +449,15 @@ export function HeartbeatConfig({ className = '', onConfigChange }: HeartbeatCon
{/* Quiet Hours */}
<div className="space-y-2">
<QuietHoursConfig
start={config.quietHoursStart}
end={config.quietHoursEnd}
enabled={!!config.quietHoursStart}
onStartChange={(time) => updateConfig({ quietHoursStart: time })}
onEndChange={(time) => updateConfig({ quietHoursEnd: time })}
start={config.quiet_hours_start ?? undefined}
end={config.quiet_hours_end ?? undefined}
enabled={!!config.quiet_hours_start}
onStartChange={(time) => updateConfig({ quiet_hours_start: time })}
onEndChange={(time) => updateConfig({ quiet_hours_end: time })}
onToggle={(enabled) =>
updateConfig({
quietHoursStart: enabled ? '22:00' : undefined,
quietHoursEnd: enabled ? '08:00' : undefined,
quiet_hours_start: enabled ? '22:00' : null,
quiet_hours_end: enabled ? '08:00' : null,
})
}
/>
@@ -484,12 +496,12 @@ export function HeartbeatConfig({ className = '', onConfigChange }: HeartbeatCon
</span>
</div>
<div className="text-xs text-gray-500 dark:text-gray-400">
{lastResult.checkedItems}
{lastResult.checked_items}
{lastResult.alerts.length > 0 && ` · ${lastResult.alerts.length} 个提醒`}
</div>
{lastResult.alerts.length > 0 && (
<div className="mt-2 space-y-1">
{lastResult.alerts.map((alert, i) => (
{lastResult.alerts.map((alert: HeartbeatAlert, i: number) => (
<div
key={i}
className={`text-xs p-2 rounded ${