feat(domains): add Intelligence Domain with Valtio store and caching
- Create types.ts with frontend-friendly types - Create cache.ts with LRU cache + TTL support - Create store.ts wrapping intelligence-client with reactive state - Create hooks.ts for React component integration - Re-export backend types for compatibility Intelligence Domain provides: - Memory: store, search, delete with caching - Heartbeat: init, start, stop, tick operations - Compaction: threshold check and compact - Reflection: conversation tracking and reflection - Identity: load, build prompt, propose changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
212
desktop/src/domains/intelligence/cache.ts
Normal file
212
desktop/src/domains/intelligence/cache.ts
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
/**
|
||||||
|
* Intelligence Domain Cache
|
||||||
|
*
|
||||||
|
* LRU cache with TTL support for intelligence operations.
|
||||||
|
* Reduces redundant API calls and improves responsiveness.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { CacheEntry, CacheStats } from './types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple LRU cache with TTL support
|
||||||
|
*/
|
||||||
|
export class IntelligenceCache {
|
||||||
|
private cache = new Map<string, CacheEntry<unknown>>();
|
||||||
|
private accessOrder: string[] = [];
|
||||||
|
private maxSize: number;
|
||||||
|
private defaultTTL: number;
|
||||||
|
|
||||||
|
// Stats tracking
|
||||||
|
private hits = 0;
|
||||||
|
private misses = 0;
|
||||||
|
|
||||||
|
constructor(options?: { maxSize?: number; defaultTTL?: number }) {
|
||||||
|
this.maxSize = options?.maxSize ?? 100;
|
||||||
|
this.defaultTTL = options?.defaultTTL ?? 5 * 60 * 1000; // 5 minutes default
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value from cache
|
||||||
|
*/
|
||||||
|
get<T>(key: string): T | null {
|
||||||
|
const entry = this.cache.get(key) as CacheEntry<T> | undefined;
|
||||||
|
|
||||||
|
if (!entry) {
|
||||||
|
this.misses++;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check TTL
|
||||||
|
if (Date.now() > entry.timestamp + entry.ttl) {
|
||||||
|
this.cache.delete(key);
|
||||||
|
this.accessOrder = this.accessOrder.filter(k => k !== key);
|
||||||
|
this.misses++;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update access order (move to end = most recently used)
|
||||||
|
this.accessOrder = this.accessOrder.filter(k => k !== key);
|
||||||
|
this.accessOrder.push(key);
|
||||||
|
|
||||||
|
this.hits++;
|
||||||
|
return entry.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a value in cache
|
||||||
|
*/
|
||||||
|
set<T>(key: string, data: T, ttl?: number): void {
|
||||||
|
// Remove if exists (to update access order)
|
||||||
|
if (this.cache.has(key)) {
|
||||||
|
this.accessOrder = this.accessOrder.filter(k => k !== key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evict oldest if at capacity
|
||||||
|
while (this.cache.size >= this.maxSize && this.accessOrder.length > 0) {
|
||||||
|
const oldestKey = this.accessOrder.shift();
|
||||||
|
if (oldestKey) {
|
||||||
|
this.cache.delete(oldestKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cache.set(key, {
|
||||||
|
data,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
ttl: ttl ?? this.defaultTTL,
|
||||||
|
});
|
||||||
|
this.accessOrder.push(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if key exists and is not expired
|
||||||
|
*/
|
||||||
|
has(key: string): boolean {
|
||||||
|
const entry = this.cache.get(key);
|
||||||
|
if (!entry) return false;
|
||||||
|
|
||||||
|
if (Date.now() > entry.timestamp + entry.ttl) {
|
||||||
|
this.cache.delete(key);
|
||||||
|
this.accessOrder = this.accessOrder.filter(k => k !== key);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a specific key
|
||||||
|
*/
|
||||||
|
delete(key: string): boolean {
|
||||||
|
if (this.cache.has(key)) {
|
||||||
|
this.cache.delete(key);
|
||||||
|
this.accessOrder = this.accessOrder.filter(k => k !== key);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all cache entries
|
||||||
|
*/
|
||||||
|
clear(): void {
|
||||||
|
this.cache.clear();
|
||||||
|
this.accessOrder = [];
|
||||||
|
// Don't reset hits/misses to maintain historical stats
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache statistics
|
||||||
|
*/
|
||||||
|
getStats(): CacheStats {
|
||||||
|
const total = this.hits + this.misses;
|
||||||
|
return {
|
||||||
|
entries: this.cache.size,
|
||||||
|
hits: this.hits,
|
||||||
|
misses: this.misses,
|
||||||
|
hitRate: total > 0 ? this.hits / total : 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset statistics
|
||||||
|
*/
|
||||||
|
resetStats(): void {
|
||||||
|
this.hits = 0;
|
||||||
|
this.misses = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all keys (for debugging)
|
||||||
|
*/
|
||||||
|
keys(): string[] {
|
||||||
|
return Array.from(this.cache.keys());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cache size
|
||||||
|
*/
|
||||||
|
get size(): number {
|
||||||
|
return this.cache.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Cache Key Generators ===
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate cache key for memory search
|
||||||
|
*/
|
||||||
|
export function memorySearchKey(options: Record<string, unknown>): string {
|
||||||
|
const sorted = Object.entries(options)
|
||||||
|
.filter(([, v]) => v !== undefined)
|
||||||
|
.sort(([a], [b]) => a.localeCompare(b))
|
||||||
|
.map(([k, v]) => `${k}=${JSON.stringify(v)}`)
|
||||||
|
.join('&');
|
||||||
|
return `memory:search:${sorted}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate cache key for identity
|
||||||
|
*/
|
||||||
|
export function identityKey(agentId: string): string {
|
||||||
|
return `identity:${agentId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate cache key for heartbeat config
|
||||||
|
*/
|
||||||
|
export function heartbeatConfigKey(agentId: string): string {
|
||||||
|
return `heartbeat:config:${agentId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate cache key for reflection state
|
||||||
|
*/
|
||||||
|
export function reflectionStateKey(): string {
|
||||||
|
return 'reflection:state';
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Singleton Instance ===
|
||||||
|
|
||||||
|
let cacheInstance: IntelligenceCache | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the global cache instance
|
||||||
|
*/
|
||||||
|
export function getIntelligenceCache(): IntelligenceCache {
|
||||||
|
if (!cacheInstance) {
|
||||||
|
cacheInstance = new IntelligenceCache({
|
||||||
|
maxSize: 200,
|
||||||
|
defaultTTL: 5 * 60 * 1000, // 5 minutes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return cacheInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the global cache instance
|
||||||
|
*/
|
||||||
|
export function clearIntelligenceCache(): void {
|
||||||
|
if (cacheInstance) {
|
||||||
|
cacheInstance.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
253
desktop/src/domains/intelligence/hooks.ts
Normal file
253
desktop/src/domains/intelligence/hooks.ts
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
/**
|
||||||
|
* Intelligence Domain Hooks
|
||||||
|
*
|
||||||
|
* React hooks for accessing intelligence state with Valtio.
|
||||||
|
* Provides reactive access to memory, heartbeat, reflection, and identity.
|
||||||
|
*/
|
||||||
|
import { useSnapshot } from 'valtio';
|
||||||
|
import { intelligenceStore } from './store';
|
||||||
|
import type { MemoryEntry, CacheStats } from './types';
|
||||||
|
|
||||||
|
// === Memory Hooks ===
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access memories list
|
||||||
|
*/
|
||||||
|
export function useMemories() {
|
||||||
|
const { memories } = useSnapshot(intelligenceStore);
|
||||||
|
return memories as readonly MemoryEntry[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access memory stats
|
||||||
|
*/
|
||||||
|
export function useMemoryStats() {
|
||||||
|
const { memoryStats } = useSnapshot(intelligenceStore);
|
||||||
|
return memoryStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to check if memories are loading
|
||||||
|
*/
|
||||||
|
export function useMemoryLoading(): boolean {
|
||||||
|
const { isMemoryLoading } = useSnapshot(intelligenceStore);
|
||||||
|
return isMemoryLoading;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Heartbeat Hooks ===
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access heartbeat config
|
||||||
|
*/
|
||||||
|
export function useHeartbeatConfig() {
|
||||||
|
const { heartbeatConfig } = useSnapshot(intelligenceStore);
|
||||||
|
return heartbeatConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access heartbeat history
|
||||||
|
*/
|
||||||
|
export function useHeartbeatHistory() {
|
||||||
|
const { heartbeatHistory } = useSnapshot(intelligenceStore);
|
||||||
|
return heartbeatHistory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to check if heartbeat is running
|
||||||
|
*/
|
||||||
|
export function useHeartbeatRunning(): boolean {
|
||||||
|
const { isHeartbeatRunning } = useSnapshot(intelligenceStore);
|
||||||
|
return isHeartbeatRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Compaction Hooks ===
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access last compaction result
|
||||||
|
*/
|
||||||
|
export function useLastCompaction() {
|
||||||
|
const { lastCompaction } = useSnapshot(intelligenceStore);
|
||||||
|
return lastCompaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access compaction check
|
||||||
|
*/
|
||||||
|
export function useCompactionCheck() {
|
||||||
|
const { compactionCheck } = useSnapshot(intelligenceStore);
|
||||||
|
return compactionCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Reflection Hooks ===
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access reflection state
|
||||||
|
*/
|
||||||
|
export function useReflectionState() {
|
||||||
|
const { reflectionState } = useSnapshot(intelligenceStore);
|
||||||
|
return reflectionState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access last reflection result
|
||||||
|
*/
|
||||||
|
export function useLastReflection() {
|
||||||
|
const { lastReflection } = useSnapshot(intelligenceStore);
|
||||||
|
return lastReflection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Identity Hooks ===
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access current identity
|
||||||
|
*/
|
||||||
|
export function useIdentity() {
|
||||||
|
const { currentIdentity } = useSnapshot(intelligenceStore);
|
||||||
|
return currentIdentity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access pending identity proposals
|
||||||
|
*/
|
||||||
|
export function usePendingProposals() {
|
||||||
|
const { pendingProposals } = useSnapshot(intelligenceStore);
|
||||||
|
return pendingProposals;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Cache Hooks ===
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access cache stats
|
||||||
|
*/
|
||||||
|
export function useCacheStats(): CacheStats {
|
||||||
|
const { cacheStats } = useSnapshot(intelligenceStore);
|
||||||
|
return cacheStats;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === General Hooks ===
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to check if any intelligence operation is loading
|
||||||
|
*/
|
||||||
|
export function useIntelligenceLoading(): boolean {
|
||||||
|
const { isLoading, isMemoryLoading } = useSnapshot(intelligenceStore);
|
||||||
|
return isLoading || isMemoryLoading;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access intelligence error
|
||||||
|
*/
|
||||||
|
export function useIntelligenceError(): string | null {
|
||||||
|
const { error } = useSnapshot(intelligenceStore);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access the full intelligence state snapshot
|
||||||
|
*/
|
||||||
|
export function useIntelligenceState() {
|
||||||
|
return useSnapshot(intelligenceStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to access intelligence actions
|
||||||
|
* Returns the store directly for calling actions.
|
||||||
|
* Does not cause re-renders.
|
||||||
|
*/
|
||||||
|
export function useIntelligenceActions() {
|
||||||
|
return intelligenceStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Convenience Hooks ===
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for memory operations with loading state
|
||||||
|
*/
|
||||||
|
export function useMemoryOperations() {
|
||||||
|
const memories = useMemories();
|
||||||
|
const isLoading = useMemoryLoading();
|
||||||
|
const stats = useMemoryStats();
|
||||||
|
const actions = useIntelligenceActions();
|
||||||
|
|
||||||
|
return {
|
||||||
|
memories,
|
||||||
|
isLoading,
|
||||||
|
stats,
|
||||||
|
loadMemories: actions.loadMemories,
|
||||||
|
storeMemory: actions.storeMemory,
|
||||||
|
deleteMemory: actions.deleteMemory,
|
||||||
|
loadStats: actions.loadMemoryStats,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for heartbeat operations
|
||||||
|
*/
|
||||||
|
export function useHeartbeatOperations() {
|
||||||
|
const config = useHeartbeatConfig();
|
||||||
|
const isRunning = useHeartbeatRunning();
|
||||||
|
const history = useHeartbeatHistory();
|
||||||
|
const actions = useIntelligenceActions();
|
||||||
|
|
||||||
|
return {
|
||||||
|
config,
|
||||||
|
isRunning,
|
||||||
|
history,
|
||||||
|
init: actions.initHeartbeat,
|
||||||
|
start: actions.startHeartbeat,
|
||||||
|
stop: actions.stopHeartbeat,
|
||||||
|
tick: actions.tickHeartbeat,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for compaction operations
|
||||||
|
*/
|
||||||
|
export function useCompactionOperations() {
|
||||||
|
const lastCompaction = useLastCompaction();
|
||||||
|
const check = useCompactionCheck();
|
||||||
|
const actions = useIntelligenceActions();
|
||||||
|
|
||||||
|
return {
|
||||||
|
lastCompaction,
|
||||||
|
check,
|
||||||
|
checkThreshold: actions.checkCompaction,
|
||||||
|
compact: actions.compact,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for reflection operations
|
||||||
|
*/
|
||||||
|
export function useReflectionOperations() {
|
||||||
|
const state = useReflectionState();
|
||||||
|
const lastReflection = useLastReflection();
|
||||||
|
const actions = useIntelligenceActions();
|
||||||
|
|
||||||
|
return {
|
||||||
|
state,
|
||||||
|
lastReflection,
|
||||||
|
recordConversation: actions.recordConversation,
|
||||||
|
shouldReflect: actions.shouldReflect,
|
||||||
|
reflect: actions.reflect,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for identity operations
|
||||||
|
*/
|
||||||
|
export function useIdentityOperations() {
|
||||||
|
const identity = useIdentity();
|
||||||
|
const pendingProposals = usePendingProposals();
|
||||||
|
const actions = useIntelligenceActions();
|
||||||
|
|
||||||
|
return {
|
||||||
|
identity,
|
||||||
|
pendingProposals,
|
||||||
|
loadIdentity: actions.loadIdentity,
|
||||||
|
buildPrompt: actions.buildPrompt,
|
||||||
|
proposeChange: actions.proposeIdentityChange,
|
||||||
|
approveProposal: actions.approveProposal,
|
||||||
|
rejectProposal: actions.rejectProposal,
|
||||||
|
};
|
||||||
|
}
|
||||||
118
desktop/src/domains/intelligence/index.ts
Normal file
118
desktop/src/domains/intelligence/index.ts
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
/**
|
||||||
|
* Intelligence Domain
|
||||||
|
*
|
||||||
|
* Unified intelligence layer for memory, heartbeat, compaction,
|
||||||
|
* reflection, and identity management.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // Using hooks
|
||||||
|
* import { useMemoryOperations, useIdentityOperations } from '@/domains/intelligence';
|
||||||
|
*
|
||||||
|
* function IntelligenceComponent() {
|
||||||
|
* const { memories, loadMemories, storeMemory } = useMemoryOperations();
|
||||||
|
* const { identity, loadIdentity } = useIdentityOperations();
|
||||||
|
*
|
||||||
|
* useEffect(() => {
|
||||||
|
* loadMemories({ agentId: 'agent-1', limit: 10 });
|
||||||
|
* loadIdentity('agent-1');
|
||||||
|
* }, []);
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // Using store directly (outside React)
|
||||||
|
* import { intelligenceStore } from '@/domains/intelligence';
|
||||||
|
*
|
||||||
|
* async function storeMemory(content: string) {
|
||||||
|
* await intelligenceStore.storeMemory({
|
||||||
|
* agentId: 'agent-1',
|
||||||
|
* type: 'fact',
|
||||||
|
* content,
|
||||||
|
* importance: 5,
|
||||||
|
* source: 'user',
|
||||||
|
* tags: [],
|
||||||
|
* });
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Types - Domain-specific
|
||||||
|
export type {
|
||||||
|
MemoryEntry,
|
||||||
|
MemoryType,
|
||||||
|
MemorySource,
|
||||||
|
MemorySearchOptions,
|
||||||
|
MemoryStats,
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
CacheEntry,
|
||||||
|
CacheStats,
|
||||||
|
|
||||||
|
// Store
|
||||||
|
IntelligenceState,
|
||||||
|
IntelligenceStore,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
// Types - Re-exported from backend
|
||||||
|
export type {
|
||||||
|
HeartbeatConfig,
|
||||||
|
HeartbeatAlert,
|
||||||
|
HeartbeatResult,
|
||||||
|
CompactableMessage,
|
||||||
|
CompactionConfig,
|
||||||
|
CompactionCheck,
|
||||||
|
CompactionResult,
|
||||||
|
PatternObservation,
|
||||||
|
ImprovementSuggestion,
|
||||||
|
ReflectionResult,
|
||||||
|
ReflectionState,
|
||||||
|
ReflectionConfig,
|
||||||
|
MemoryEntryForAnalysis,
|
||||||
|
IdentityFiles,
|
||||||
|
IdentityChangeProposal,
|
||||||
|
IdentitySnapshot,
|
||||||
|
} from '../../lib/intelligence-backend';
|
||||||
|
|
||||||
|
// Store
|
||||||
|
export { intelligenceStore } from './store';
|
||||||
|
|
||||||
|
// Cache utilities
|
||||||
|
export {
|
||||||
|
IntelligenceCache,
|
||||||
|
getIntelligenceCache,
|
||||||
|
clearIntelligenceCache,
|
||||||
|
memorySearchKey,
|
||||||
|
identityKey,
|
||||||
|
heartbeatConfigKey,
|
||||||
|
reflectionStateKey,
|
||||||
|
} from './cache';
|
||||||
|
|
||||||
|
// Hooks - State accessors
|
||||||
|
export {
|
||||||
|
useMemories,
|
||||||
|
useMemoryStats,
|
||||||
|
useMemoryLoading,
|
||||||
|
useHeartbeatConfig,
|
||||||
|
useHeartbeatHistory,
|
||||||
|
useHeartbeatRunning,
|
||||||
|
useLastCompaction,
|
||||||
|
useCompactionCheck,
|
||||||
|
useReflectionState,
|
||||||
|
useLastReflection,
|
||||||
|
useIdentity,
|
||||||
|
usePendingProposals,
|
||||||
|
useCacheStats,
|
||||||
|
useIntelligenceLoading,
|
||||||
|
useIntelligenceError,
|
||||||
|
useIntelligenceState,
|
||||||
|
useIntelligenceActions,
|
||||||
|
} from './hooks';
|
||||||
|
|
||||||
|
// Hooks - Operation bundles
|
||||||
|
export {
|
||||||
|
useMemoryOperations,
|
||||||
|
useHeartbeatOperations,
|
||||||
|
useCompactionOperations,
|
||||||
|
useReflectionOperations,
|
||||||
|
useIdentityOperations,
|
||||||
|
} from './hooks';
|
||||||
415
desktop/src/domains/intelligence/store.ts
Normal file
415
desktop/src/domains/intelligence/store.ts
Normal file
@@ -0,0 +1,415 @@
|
|||||||
|
/**
|
||||||
|
* Intelligence Domain Store
|
||||||
|
*
|
||||||
|
* Valtio-based state management for intelligence operations.
|
||||||
|
* Wraps intelligence-client with caching and reactive state.
|
||||||
|
*/
|
||||||
|
import { proxy } from 'valtio';
|
||||||
|
import { intelligenceClient } from '../../lib/intelligence-client';
|
||||||
|
import {
|
||||||
|
getIntelligenceCache,
|
||||||
|
memorySearchKey,
|
||||||
|
identityKey,
|
||||||
|
} from './cache';
|
||||||
|
import type {
|
||||||
|
IntelligenceStore,
|
||||||
|
IntelligenceState,
|
||||||
|
MemoryEntry,
|
||||||
|
MemoryType,
|
||||||
|
MemorySource,
|
||||||
|
MemorySearchOptions,
|
||||||
|
MemoryStats,
|
||||||
|
CacheStats,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
|
// === Initial State ===
|
||||||
|
|
||||||
|
const initialState: IntelligenceState = {
|
||||||
|
// Memory
|
||||||
|
memories: [],
|
||||||
|
memoryStats: null,
|
||||||
|
isMemoryLoading: false,
|
||||||
|
|
||||||
|
// Heartbeat
|
||||||
|
heartbeatConfig: null,
|
||||||
|
heartbeatHistory: [],
|
||||||
|
isHeartbeatRunning: false,
|
||||||
|
|
||||||
|
// Compaction
|
||||||
|
lastCompaction: null,
|
||||||
|
compactionCheck: null,
|
||||||
|
|
||||||
|
// Reflection
|
||||||
|
reflectionState: null,
|
||||||
|
lastReflection: null,
|
||||||
|
|
||||||
|
// Identity
|
||||||
|
currentIdentity: null,
|
||||||
|
pendingProposals: [],
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
cacheStats: {
|
||||||
|
entries: 0,
|
||||||
|
hits: 0,
|
||||||
|
misses: 0,
|
||||||
|
hitRate: 0,
|
||||||
|
},
|
||||||
|
|
||||||
|
// General
|
||||||
|
isLoading: false,
|
||||||
|
error: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
// === Store Implementation ===
|
||||||
|
|
||||||
|
export const intelligenceStore = proxy<IntelligenceStore>({
|
||||||
|
...initialState,
|
||||||
|
|
||||||
|
// === Memory Actions ===
|
||||||
|
|
||||||
|
loadMemories: async (options: MemorySearchOptions): Promise<void> => {
|
||||||
|
const cache = getIntelligenceCache();
|
||||||
|
const key = memorySearchKey(options as Record<string, unknown>);
|
||||||
|
|
||||||
|
// Check cache first
|
||||||
|
const cached = cache.get<MemoryEntry[]>(key);
|
||||||
|
if (cached) {
|
||||||
|
intelligenceStore.memories = cached;
|
||||||
|
intelligenceStore.cacheStats = cache.getStats();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
intelligenceStore.isMemoryLoading = true;
|
||||||
|
intelligenceStore.error = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const rawMemories = await intelligenceClient.memory.search({
|
||||||
|
agentId: options.agentId,
|
||||||
|
type: options.type,
|
||||||
|
tags: options.tags,
|
||||||
|
query: options.query,
|
||||||
|
limit: options.limit,
|
||||||
|
minImportance: options.minImportance,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert to frontend format
|
||||||
|
const memories: MemoryEntry[] = rawMemories.map(m => ({
|
||||||
|
id: m.id,
|
||||||
|
agentId: m.agentId,
|
||||||
|
content: m.content,
|
||||||
|
type: m.type as MemoryType,
|
||||||
|
importance: m.importance,
|
||||||
|
source: m.source as MemorySource,
|
||||||
|
tags: m.tags,
|
||||||
|
createdAt: m.createdAt,
|
||||||
|
lastAccessedAt: m.lastAccessedAt,
|
||||||
|
accessCount: m.accessCount,
|
||||||
|
conversationId: m.conversationId,
|
||||||
|
}));
|
||||||
|
|
||||||
|
cache.set(key, memories);
|
||||||
|
intelligenceStore.memories = memories;
|
||||||
|
intelligenceStore.cacheStats = cache.getStats();
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to load memories';
|
||||||
|
} finally {
|
||||||
|
intelligenceStore.isMemoryLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
storeMemory: async (entry): Promise<string> => {
|
||||||
|
const cache = getIntelligenceCache();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const id = await intelligenceClient.memory.store({
|
||||||
|
agent_id: entry.agentId,
|
||||||
|
memory_type: entry.type,
|
||||||
|
content: entry.content,
|
||||||
|
importance: entry.importance,
|
||||||
|
source: entry.source,
|
||||||
|
tags: entry.tags,
|
||||||
|
conversation_id: entry.conversationId,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Invalidate relevant cache entries
|
||||||
|
cache.delete(memorySearchKey({ agentId: entry.agentId }));
|
||||||
|
|
||||||
|
return id;
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to store memory';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
deleteMemory: async (id: string): Promise<void> => {
|
||||||
|
const cache = getIntelligenceCache();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await intelligenceClient.memory.delete(id);
|
||||||
|
// Clear all memory search caches
|
||||||
|
cache.clear();
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to delete memory';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
loadMemoryStats: async (): Promise<void> => {
|
||||||
|
try {
|
||||||
|
const rawStats = await intelligenceClient.memory.stats();
|
||||||
|
const stats: MemoryStats = {
|
||||||
|
totalEntries: rawStats.totalEntries,
|
||||||
|
byType: rawStats.byType,
|
||||||
|
byAgent: rawStats.byAgent,
|
||||||
|
oldestEntry: rawStats.oldestEntry,
|
||||||
|
newestEntry: rawStats.newestEntry,
|
||||||
|
};
|
||||||
|
intelligenceStore.memoryStats = stats;
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to load memory stats';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// === Heartbeat Actions ===
|
||||||
|
|
||||||
|
initHeartbeat: async (agentId: string, config?: import('../../lib/intelligence-backend').HeartbeatConfig): Promise<void> => {
|
||||||
|
try {
|
||||||
|
await intelligenceClient.heartbeat.init(agentId, config);
|
||||||
|
if (config) {
|
||||||
|
intelligenceStore.heartbeatConfig = config;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to init heartbeat';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
startHeartbeat: async (agentId: string): Promise<void> => {
|
||||||
|
try {
|
||||||
|
await intelligenceClient.heartbeat.start(agentId);
|
||||||
|
intelligenceStore.isHeartbeatRunning = true;
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to start heartbeat';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
stopHeartbeat: async (agentId: string): Promise<void> => {
|
||||||
|
try {
|
||||||
|
await intelligenceClient.heartbeat.stop(agentId);
|
||||||
|
intelligenceStore.isHeartbeatRunning = false;
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to stop heartbeat';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
tickHeartbeat: async (agentId: string): Promise<import('../../lib/intelligence-backend').HeartbeatResult> => {
|
||||||
|
try {
|
||||||
|
const result = await intelligenceClient.heartbeat.tick(agentId);
|
||||||
|
intelligenceStore.heartbeatHistory = [
|
||||||
|
result,
|
||||||
|
...intelligenceStore.heartbeatHistory.slice(0, 99),
|
||||||
|
];
|
||||||
|
return result;
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Heartbeat tick failed';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// === Compaction Actions ===
|
||||||
|
|
||||||
|
checkCompaction: async (messages: Array<{ id?: string; role: string; content: string; timestamp?: string }>): Promise<import('../../lib/intelligence-backend').CompactionCheck> => {
|
||||||
|
try {
|
||||||
|
const compactableMessages = messages.map(m => ({
|
||||||
|
id: m.id || `msg_${Date.now()}`,
|
||||||
|
role: m.role,
|
||||||
|
content: m.content,
|
||||||
|
timestamp: m.timestamp,
|
||||||
|
}));
|
||||||
|
const check = await intelligenceClient.compactor.checkThreshold(compactableMessages);
|
||||||
|
intelligenceStore.compactionCheck = check;
|
||||||
|
return check;
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Compaction check failed';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
compact: async (
|
||||||
|
messages: Array<{ id?: string; role: string; content: string; timestamp?: string }>,
|
||||||
|
agentId: string,
|
||||||
|
conversationId?: string
|
||||||
|
): Promise<import('../../lib/intelligence-backend').CompactionResult> => {
|
||||||
|
try {
|
||||||
|
const compactableMessages = messages.map(m => ({
|
||||||
|
id: m.id || `msg_${Date.now()}`,
|
||||||
|
role: m.role,
|
||||||
|
content: m.content,
|
||||||
|
timestamp: m.timestamp,
|
||||||
|
}));
|
||||||
|
const result = await intelligenceClient.compactor.compact(
|
||||||
|
compactableMessages,
|
||||||
|
agentId,
|
||||||
|
conversationId
|
||||||
|
);
|
||||||
|
intelligenceStore.lastCompaction = result;
|
||||||
|
return result;
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Compaction failed';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// === Reflection Actions ===
|
||||||
|
|
||||||
|
recordConversation: async (): Promise<void> => {
|
||||||
|
try {
|
||||||
|
await intelligenceClient.reflection.recordConversation();
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('[IntelligenceStore] Failed to record conversation:', err);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
shouldReflect: async (): Promise<boolean> => {
|
||||||
|
try {
|
||||||
|
return intelligenceClient.reflection.shouldReflect();
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
reflect: async (agentId: string): Promise<import('../../lib/intelligence-backend').ReflectionResult> => {
|
||||||
|
try {
|
||||||
|
// Get memories for reflection
|
||||||
|
const memories = await intelligenceClient.memory.search({
|
||||||
|
agentId,
|
||||||
|
limit: 50,
|
||||||
|
minImportance: 3,
|
||||||
|
});
|
||||||
|
|
||||||
|
const analysisMemories = memories.map(m => ({
|
||||||
|
id: m.id,
|
||||||
|
memory_type: m.type,
|
||||||
|
content: m.content,
|
||||||
|
importance: m.importance,
|
||||||
|
created_at: m.createdAt,
|
||||||
|
access_count: m.accessCount,
|
||||||
|
tags: m.tags,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const result = await intelligenceClient.reflection.reflect(agentId, analysisMemories);
|
||||||
|
intelligenceStore.lastReflection = result;
|
||||||
|
|
||||||
|
// Invalidate caches
|
||||||
|
getIntelligenceCache().clear();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Reflection failed';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// === Identity Actions ===
|
||||||
|
|
||||||
|
loadIdentity: async (agentId: string): Promise<void> => {
|
||||||
|
const cache = getIntelligenceCache();
|
||||||
|
const key = identityKey(agentId);
|
||||||
|
|
||||||
|
// Check cache
|
||||||
|
const cached = cache.get<import('../../lib/intelligence-backend').IdentityFiles>(key);
|
||||||
|
if (cached) {
|
||||||
|
intelligenceStore.currentIdentity = cached;
|
||||||
|
intelligenceStore.cacheStats = cache.getStats();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const identity = await intelligenceClient.identity.get(agentId);
|
||||||
|
cache.set(key, identity, 10 * 60 * 1000); // 10 minute TTL
|
||||||
|
intelligenceStore.currentIdentity = identity;
|
||||||
|
intelligenceStore.cacheStats = cache.getStats();
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to load identity';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
buildPrompt: async (agentId: string, memoryContext?: string): Promise<string> => {
|
||||||
|
try {
|
||||||
|
return intelligenceClient.identity.buildPrompt(agentId, memoryContext);
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to build prompt';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
proposeIdentityChange: async (
|
||||||
|
agentId: string,
|
||||||
|
file: 'soul' | 'instructions',
|
||||||
|
content: string,
|
||||||
|
reason: string
|
||||||
|
): Promise<import('../../lib/intelligence-backend').IdentityChangeProposal> => {
|
||||||
|
try {
|
||||||
|
const proposal = await intelligenceClient.identity.proposeChange(
|
||||||
|
agentId,
|
||||||
|
file,
|
||||||
|
content,
|
||||||
|
reason
|
||||||
|
);
|
||||||
|
intelligenceStore.pendingProposals.push(proposal);
|
||||||
|
return proposal;
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to propose change';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
approveProposal: async (proposalId: string): Promise<void> => {
|
||||||
|
try {
|
||||||
|
const identity = await intelligenceClient.identity.approveProposal(proposalId);
|
||||||
|
intelligenceStore.pendingProposals = intelligenceStore.pendingProposals.filter(
|
||||||
|
p => p.id !== proposalId
|
||||||
|
);
|
||||||
|
intelligenceStore.currentIdentity = identity;
|
||||||
|
getIntelligenceCache().clear();
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to approve proposal';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
rejectProposal: async (proposalId: string): Promise<void> => {
|
||||||
|
try {
|
||||||
|
await intelligenceClient.identity.rejectProposal(proposalId);
|
||||||
|
intelligenceStore.pendingProposals = intelligenceStore.pendingProposals.filter(
|
||||||
|
p => p.id !== proposalId
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
intelligenceStore.error = err instanceof Error ? err.message : 'Failed to reject proposal';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// === Cache Actions ===
|
||||||
|
|
||||||
|
clearCache: (): void => {
|
||||||
|
getIntelligenceCache().clear();
|
||||||
|
intelligenceStore.cacheStats = getIntelligenceCache().getStats();
|
||||||
|
},
|
||||||
|
|
||||||
|
getCacheStats: (): CacheStats => {
|
||||||
|
return getIntelligenceCache().getStats();
|
||||||
|
},
|
||||||
|
|
||||||
|
// === General Actions ===
|
||||||
|
|
||||||
|
clearError: (): void => {
|
||||||
|
intelligenceStore.error = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: (): void => {
|
||||||
|
Object.assign(intelligenceStore, initialState);
|
||||||
|
getIntelligenceCache().clear();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export type { IntelligenceStore };
|
||||||
183
desktop/src/domains/intelligence/types.ts
Normal file
183
desktop/src/domains/intelligence/types.ts
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/**
|
||||||
|
* Intelligence Domain Types
|
||||||
|
*
|
||||||
|
* Re-exports types from intelligence-backend for consistency.
|
||||||
|
* Domain-specific extensions are added here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// === Re-export Backend Types ===
|
||||||
|
|
||||||
|
export type {
|
||||||
|
MemoryEntryInput,
|
||||||
|
PersistentMemory,
|
||||||
|
MemorySearchOptions as BackendMemorySearchOptions,
|
||||||
|
MemoryStats as BackendMemoryStats,
|
||||||
|
HeartbeatConfig,
|
||||||
|
HeartbeatAlert,
|
||||||
|
HeartbeatResult,
|
||||||
|
CompactableMessage,
|
||||||
|
CompactionResult,
|
||||||
|
CompactionCheck,
|
||||||
|
CompactionConfig,
|
||||||
|
PatternObservation,
|
||||||
|
ImprovementSuggestion,
|
||||||
|
ReflectionResult,
|
||||||
|
ReflectionState,
|
||||||
|
ReflectionConfig,
|
||||||
|
MemoryEntryForAnalysis,
|
||||||
|
IdentityFiles,
|
||||||
|
IdentityChangeProposal,
|
||||||
|
IdentitySnapshot,
|
||||||
|
} from '../../lib/intelligence-backend';
|
||||||
|
|
||||||
|
// === Frontend-Specific Types ===
|
||||||
|
|
||||||
|
export type MemoryType = 'fact' | 'preference' | 'lesson' | 'context' | 'task';
|
||||||
|
export type MemorySource = 'auto' | 'user' | 'reflection' | 'llm-reflection';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frontend-friendly memory entry
|
||||||
|
*/
|
||||||
|
export interface MemoryEntry {
|
||||||
|
id: string;
|
||||||
|
agentId: string;
|
||||||
|
content: string;
|
||||||
|
type: MemoryType;
|
||||||
|
importance: number;
|
||||||
|
source: MemorySource;
|
||||||
|
tags: string[];
|
||||||
|
createdAt: string;
|
||||||
|
lastAccessedAt: string;
|
||||||
|
accessCount: number;
|
||||||
|
conversationId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frontend memory search options
|
||||||
|
*/
|
||||||
|
export interface MemorySearchOptions {
|
||||||
|
agentId?: string;
|
||||||
|
type?: MemoryType;
|
||||||
|
types?: MemoryType[];
|
||||||
|
tags?: string[];
|
||||||
|
query?: string;
|
||||||
|
limit?: number;
|
||||||
|
minImportance?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frontend memory stats
|
||||||
|
*/
|
||||||
|
export interface MemoryStats {
|
||||||
|
totalEntries: number;
|
||||||
|
byType: Record<string, number>;
|
||||||
|
byAgent: Record<string, number>;
|
||||||
|
oldestEntry: string | null;
|
||||||
|
newestEntry: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Cache Types ===
|
||||||
|
|
||||||
|
export interface CacheEntry<T> {
|
||||||
|
data: T;
|
||||||
|
timestamp: number;
|
||||||
|
ttl: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CacheStats {
|
||||||
|
entries: number;
|
||||||
|
hits: number;
|
||||||
|
misses: number;
|
||||||
|
hitRate: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === Store Types ===
|
||||||
|
|
||||||
|
export interface IntelligenceState {
|
||||||
|
// Memory
|
||||||
|
memories: MemoryEntry[];
|
||||||
|
memoryStats: MemoryStats | null;
|
||||||
|
isMemoryLoading: boolean;
|
||||||
|
|
||||||
|
// Heartbeat
|
||||||
|
heartbeatConfig: HeartbeatConfig | null;
|
||||||
|
heartbeatHistory: HeartbeatResult[];
|
||||||
|
isHeartbeatRunning: boolean;
|
||||||
|
|
||||||
|
// Compaction
|
||||||
|
lastCompaction: CompactionResult | null;
|
||||||
|
compactionCheck: CompactionCheck | null;
|
||||||
|
|
||||||
|
// Reflection
|
||||||
|
reflectionState: ReflectionState | null;
|
||||||
|
lastReflection: ReflectionResult | null;
|
||||||
|
|
||||||
|
// Identity
|
||||||
|
currentIdentity: IdentityFiles | null;
|
||||||
|
pendingProposals: IdentityChangeProposal[];
|
||||||
|
|
||||||
|
// Cache
|
||||||
|
cacheStats: CacheStats;
|
||||||
|
|
||||||
|
// General
|
||||||
|
isLoading: boolean;
|
||||||
|
error: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import types that need to be used in store interface
|
||||||
|
import type {
|
||||||
|
HeartbeatConfig,
|
||||||
|
HeartbeatResult,
|
||||||
|
CompactionResult,
|
||||||
|
CompactionCheck,
|
||||||
|
ReflectionState,
|
||||||
|
ReflectionResult,
|
||||||
|
IdentityFiles,
|
||||||
|
IdentityChangeProposal,
|
||||||
|
} from '../../lib/intelligence-backend';
|
||||||
|
|
||||||
|
export interface IntelligenceStore extends IntelligenceState {
|
||||||
|
// Memory Actions
|
||||||
|
loadMemories: (options: MemorySearchOptions) => Promise<void>;
|
||||||
|
storeMemory: (entry: {
|
||||||
|
agentId: string;
|
||||||
|
type: MemoryType;
|
||||||
|
content: string;
|
||||||
|
importance: number;
|
||||||
|
source: MemorySource;
|
||||||
|
tags: string[];
|
||||||
|
conversationId?: string;
|
||||||
|
}) => Promise<string>;
|
||||||
|
deleteMemory: (id: string) => Promise<void>;
|
||||||
|
loadMemoryStats: () => Promise<void>;
|
||||||
|
|
||||||
|
// Heartbeat Actions
|
||||||
|
initHeartbeat: (agentId: string, config?: HeartbeatConfig) => Promise<void>;
|
||||||
|
startHeartbeat: (agentId: string) => Promise<void>;
|
||||||
|
stopHeartbeat: (agentId: string) => Promise<void>;
|
||||||
|
tickHeartbeat: (agentId: string) => Promise<HeartbeatResult>;
|
||||||
|
|
||||||
|
// Compaction Actions
|
||||||
|
checkCompaction: (messages: Array<{ id?: string; role: string; content: string; timestamp?: string }>) => Promise<CompactionCheck>;
|
||||||
|
compact: (messages: Array<{ id?: string; role: string; content: string; timestamp?: string }>, agentId: string, conversationId?: string) => Promise<CompactionResult>;
|
||||||
|
|
||||||
|
// Reflection Actions
|
||||||
|
recordConversation: () => Promise<void>;
|
||||||
|
shouldReflect: () => Promise<boolean>;
|
||||||
|
reflect: (agentId: string) => Promise<ReflectionResult>;
|
||||||
|
|
||||||
|
// Identity Actions
|
||||||
|
loadIdentity: (agentId: string) => Promise<void>;
|
||||||
|
buildPrompt: (agentId: string, memoryContext?: string) => Promise<string>;
|
||||||
|
proposeIdentityChange: (agentId: string, file: 'soul' | 'instructions', content: string, reason: string) => Promise<IdentityChangeProposal>;
|
||||||
|
approveProposal: (proposalId: string) => Promise<void>;
|
||||||
|
rejectProposal: (proposalId: string) => Promise<void>;
|
||||||
|
|
||||||
|
// Cache Actions
|
||||||
|
clearCache: () => void;
|
||||||
|
getCacheStats: () => CacheStats;
|
||||||
|
|
||||||
|
// General
|
||||||
|
clearError: () => void;
|
||||||
|
reset: () => void;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user