feat(intelligence): add TypeScript frontend adapter for Rust commands

Provides unified API for calling Tauri intelligence commands:

- memory: store, search, get, delete, stats, export/import
- heartbeat: init, start, stop, tick, config management
- compactor: token estimation, threshold check, compact
- reflection: should_reflect, reflect, history, state
- identity: get/update files, proposals, snapshots

Usage:
```typescript
import { intelligence } from './intelligence-backend';
await intelligence.memory.store({ ... });
await intelligence.heartbeat.start('agent-1');
```

Part of Phase 4: Integration and documentation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
iven
2026-03-21 00:54:31 +08:00
parent d97c03fb28
commit 17fb1e69aa

View File

@@ -0,0 +1,445 @@
/**
* Intelligence Layer Backend Adapter
*
* Provides TypeScript API for calling Rust intelligence commands.
* This replaces the localStorage-based implementations in:
* - agent-memory.ts (Phase 1)
* - heartbeat-engine.ts (Phase 2)
* - context-compactor.ts (Phase 2)
* - reflection-engine.ts (Phase 3)
* - agent-identity.ts (Phase 3)
*
* Usage:
* ```typescript
* import { intelligence } from './intelligence-backend';
*
* // Memory
* const memoryId = await intelligence.memory.store({ ... });
* const memories = await intelligence.memory.search({ query: '...' });
*
* // Heartbeat
* await intelligence.heartbeat.init('agent-1');
* await intelligence.heartbeat.start('agent-1');
*
* // Reflection
* const result = await intelligence.reflection.reflect('agent-1', memories);
* ```
*/
import { invoke } from '@tauri-apps/api/core';
// === Types ===
export interface MemoryEntryInput {
agent_id: string;
memory_type: string;
content: string;
importance?: number;
source?: string;
tags?: string[];
conversation_id?: string;
}
export interface PersistentMemory {
id: string;
agent_id: string;
memory_type: string;
content: string;
importance: number;
source: string;
tags: string;
conversation_id: string | null;
created_at: string;
last_accessed_at: string;
access_count: number;
embedding: string | null;
}
export interface MemorySearchOptions {
agent_id?: string;
memory_type?: string;
tags?: string[];
query?: string;
min_importance?: number;
limit?: number;
offset?: number;
}
export interface MemoryStats {
total_memories: number;
by_type: Record<string, number>;
by_agent: Record<string, number>;
oldest_memory: string | null;
newest_memory: string | null;
}
// Heartbeat types
export interface HeartbeatConfig {
enabled: boolean;
interval_minutes: number;
quiet_hours_start: string | null;
quiet_hours_end: string | null;
notify_channel: 'ui' | 'desktop' | 'all';
proactivity_level: 'silent' | 'light' | 'standard' | 'autonomous';
max_alerts_per_tick: number;
}
export interface HeartbeatAlert {
title: string;
content: string;
urgency: 'low' | 'medium' | 'high';
source: string;
timestamp: string;
}
export interface HeartbeatResult {
status: 'ok' | 'alert';
alerts: HeartbeatAlert[];
checked_items: number;
timestamp: string;
}
// Compactor types
export interface CompactableMessage {
role: string;
content: string;
id?: string;
timestamp?: string;
}
export interface CompactionResult {
compacted_messages: CompactableMessage[];
summary: string;
original_count: number;
retained_count: number;
flushed_memories: number;
tokens_before_compaction: number;
tokens_after_compaction: number;
}
export interface CompactionCheck {
should_compact: boolean;
current_tokens: number;
threshold: number;
urgency: 'none' | 'soft' | 'hard';
}
// Reflection types
export interface MemoryEntryForAnalysis {
memory_type: string;
content: string;
importance: number;
access_count: number;
tags: string[];
}
export interface PatternObservation {
observation: string;
frequency: number;
sentiment: 'positive' | 'negative' | 'neutral';
evidence: string[];
}
export interface ImprovementSuggestion {
area: string;
suggestion: string;
priority: 'high' | 'medium' | 'low';
}
export interface ReflectionResult {
patterns: PatternObservation[];
improvements: ImprovementSuggestion[];
identity_proposals: IdentityChangeProposal[];
new_memories: number;
timestamp: string;
}
export interface ReflectionState {
conversations_since_reflection: number;
last_reflection_time: string | null;
last_reflection_agent_id: string | null;
}
// Identity types
export interface IdentityFiles {
soul: string;
instructions: string;
user_profile: string;
heartbeat?: string;
}
export interface IdentityChangeProposal {
id: string;
agent_id: string;
file: 'soul' | 'instructions';
reason: string;
current_content: string;
suggested_content: string;
status: 'pending' | 'approved' | 'rejected';
created_at: string;
}
export interface IdentitySnapshot {
id: string;
agent_id: string;
files: IdentityFiles;
timestamp: string;
reason: string;
}
// === Memory API ===
export const memory = {
async init(): Promise<void> {
await invoke('memory_init');
},
async store(entry: MemoryEntryInput): Promise<string> {
return invoke('memory_store', { entry });
},
async get(id: string): Promise<PersistentMemory | null> {
return invoke('memory_get', { id });
},
async search(options: MemorySearchOptions): Promise<PersistentMemory[]> {
return invoke('memory_search', { options });
},
async delete(id: string): Promise<void> {
await invoke('memory_delete', { id });
},
async deleteAll(agentId: string): Promise<number> {
return invoke('memory_delete_all', { agentId });
},
async stats(): Promise<MemoryStats> {
return invoke('memory_stats');
},
async export(): Promise<PersistentMemory[]> {
return invoke('memory_export');
},
async import(memories: PersistentMemory[]): Promise<number> {
return invoke('memory_import', { memories });
},
async dbPath(): Promise<string> {
return invoke('memory_db_path');
},
};
// === Heartbeat API ===
export const heartbeat = {
async init(agentId: string, config?: HeartbeatConfig): Promise<void> {
await invoke('heartbeat_init', { agentId, config });
},
async start(agentId: string): Promise<void> {
await invoke('heartbeat_start', { agentId });
},
async stop(agentId: string): Promise<void> {
await invoke('heartbeat_stop', { agentId });
},
async tick(agentId: string): Promise<HeartbeatResult> {
return invoke('heartbeat_tick', { agentId });
},
async getConfig(agentId: string): Promise<HeartbeatConfig> {
return invoke('heartbeat_get_config', { agentId });
},
async updateConfig(agentId: string, config: HeartbeatConfig): Promise<void> {
await invoke('heartbeat_update_config', { agentId, config });
},
async getHistory(agentId: string, limit?: number): Promise<HeartbeatResult[]> {
return invoke('heartbeat_get_history', { agentId, limit });
},
};
// === Compactor API ===
export const compactor = {
estimateTokens(text: string): Promise<number> {
return invoke('compactor_estimate_tokens', { text });
},
estimateMessagesTokens(messages: CompactableMessage[]): Promise<number> {
return invoke('compactor_estimate_messages_tokens', { messages });
},
checkThreshold(
messages: CompactableMessage[],
config?: CompactionConfig
): Promise<CompactionCheck> {
return invoke('compactor_check_threshold', { messages, config });
},
compact(
messages: CompactableMessage[],
agentId: string,
conversationId?: string,
config?: CompactionConfig
): Promise<CompactionResult> {
return invoke('compactor_compact', {
messages,
agentId,
conversationId,
config,
});
},
};
export interface CompactionConfig {
soft_threshold_tokens?: number;
hard_threshold_tokens?: number;
reserve_tokens?: number;
memory_flush_enabled?: boolean;
keep_recent_messages?: number;
summary_max_tokens?: number;
use_llm?: boolean;
llm_fallback_to_rules?: boolean;
}
// === Reflection API ===
export const reflection = {
async init(config?: ReflectionConfig): Promise<void> {
await invoke('reflection_init', { config });
},
async recordConversation(): Promise<void> {
await invoke('reflection_record_conversation');
},
async shouldReflect(): Promise<boolean> {
return invoke('reflection_should_reflect');
},
async reflect(
agentId: string,
memories: MemoryEntryForAnalysis[]
): Promise<ReflectionResult> {
return invoke('reflection_reflect', { agentId, memories });
},
async getHistory(limit?: number): Promise<ReflectionResult[]> {
return invoke('reflection_get_history', { limit });
},
async getState(): Promise<ReflectionState> {
return invoke('reflection_get_state');
},
};
export interface ReflectionConfig {
trigger_after_conversations?: number;
trigger_after_hours?: number;
allow_soul_modification?: boolean;
require_approval?: boolean;
use_llm?: boolean;
llm_fallback_to_rules?: boolean;
}
// === Identity API ===
export const identity = {
async get(agentId: string): Promise<IdentityFiles> {
return invoke('identity_get', { agentId });
},
async getFile(agentId: string, file: string): Promise<string> {
return invoke('identity_get_file', { agentId, file });
},
async buildPrompt(
agentId: string,
memoryContext?: string
): Promise<string> {
return invoke('identity_build_prompt', { agentId, memoryContext });
},
async updateUserProfile(agentId: string, content: string): Promise<void> {
await invoke('identity_update_user_profile', { agentId, content });
},
async appendUserProfile(agentId: string, addition: string): Promise<void> {
await invoke('identity_append_user_profile', { agentId, addition });
},
async proposeChange(
agentId: string,
file: 'soul' | 'instructions',
suggestedContent: string,
reason: string
): Promise<IdentityChangeProposal> {
return invoke('identity_propose_change', {
agentId,
file,
suggestedContent,
reason,
});
},
async approveProposal(proposalId: string): Promise<IdentityFiles> {
return invoke('identity_approve_proposal', { proposalId });
},
async rejectProposal(proposalId: string): Promise<void> {
await invoke('identity_reject_proposal', { proposalId });
},
async getPendingProposals(
agentId?: string
): Promise<IdentityChangeProposal[]> {
return invoke('identity_get_pending_proposals', { agentId });
},
async updateFile(
agentId: string,
file: string,
content: string
): Promise<void> {
await invoke('identity_update_file', { agentId, file, content });
},
async getSnapshots(
agentId: string,
limit?: number
): Promise<IdentitySnapshot[]> {
return invoke('identity_get_snapshots', { agentId, limit });
},
async restoreSnapshot(
agentId: string,
snapshotId: string
): Promise<void> {
await invoke('identity_restore_snapshot', { agentId, snapshotId });
},
async listAgents(): Promise<string[]> {
return invoke('identity_list_agents');
},
async deleteAgent(agentId: string): Promise<void> {
await invoke('identity_delete_agent', { agentId });
},
};
// === Unified Export ===
export const intelligence = {
memory,
heartbeat,
compactor,
reflection,
identity,
};
export default intelligence;