Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- S9: MessageSearch 新增 Session/Global 双模式,Global 调用 VikingStorage memory_search - M4b: LLM 压缩器集成到 kernel AgentLoop,支持 use_llm 配置切换 - M4c: 压缩时自动提取记忆到 VikingStorage (runtime + tauri 双路径) - H6: 新增 ChartRenderer(recharts)、Document/Slideshow 完整渲染 - 累计修复 23 项,整体完成度 ~72%,真实可用率 ~80%
464 lines
11 KiB
TypeScript
464 lines
11 KiB
TypeScript
/**
|
|
* 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_entries: number;
|
|
by_type: Record<string, number>;
|
|
by_agent: Record<string, number>;
|
|
oldest_entry: string | null;
|
|
newest_entry: string | null;
|
|
storage_size_bytes: number;
|
|
}
|
|
|
|
// 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';
|
|
}
|
|
|
|
// Reflection identity proposal (from reflection engine, not yet persisted)
|
|
export interface ReflectionIdentityProposal {
|
|
agent_id: string;
|
|
field: string;
|
|
current_value: string;
|
|
proposed_value: string;
|
|
reason: string;
|
|
}
|
|
|
|
export interface ReflectionResult {
|
|
patterns: PatternObservation[];
|
|
improvements: ImprovementSuggestion[];
|
|
identity_proposals: ReflectionIdentityProposal[];
|
|
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');
|
|
},
|
|
|
|
async buildContext(
|
|
agentId: string,
|
|
query: string,
|
|
maxTokens: number | null,
|
|
): Promise<{ systemPromptAddition: string; totalTokens: number; memoriesUsed: number }> {
|
|
return invoke('memory_build_context', { agentId, query, maxTokens });
|
|
},
|
|
};
|
|
|
|
// === 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, agentId?: string): Promise<ReflectionResult[]> {
|
|
return invoke('reflection_get_history', { limit, agentId });
|
|
},
|
|
|
|
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;
|