1use super::*;
21use crate::graph::EdgeId;
22use crate::policy::Action;
23use hirn_core::types::{AgentId, Namespace};
24use std::collections::HashMap;
25
26pub struct EpisodicView<'a>(pub(super) &'a HirnDB);
32
33pub struct SemanticView<'a>(pub(super) &'a HirnDB);
35
36pub struct ProceduralView<'a>(pub(super) &'a HirnDB);
38
39pub struct WorkingView<'a>(pub(super) &'a HirnDB);
41
42pub struct GraphView<'a>(pub(super) &'a HirnDB);
44
45pub struct RecallView<'a>(pub(super) &'a HirnDB);
47
48pub struct NamespaceView<'a>(pub(super) &'a HirnDB);
50
51pub struct PolicyView<'a>(pub(super) &'a HirnDB);
53
54pub struct AdminView<'a>(pub(super) &'a HirnDB);
56
57pub struct QueryView<'a>(pub(super) &'a HirnDB);
59
60pub struct CausalView<'a>(pub(super) &'a HirnDB);
62
63impl<'a> EpisodicView<'a> {
68 #[inline]
69 pub async fn remember(&self, record: EpisodicRecord) -> HirnResult<MemoryId> {
70 self.0.remember(record).await
71 }
72
73 #[inline]
74 pub async fn remember_with_explanation(
75 &self,
76 record: EpisodicRecord,
77 ) -> Result<(MemoryId, crate::RememberExplanation), crate::RememberFailure> {
78 self.0.remember_with_explanation(record).await
79 }
80
81 #[inline]
82 pub async fn batch_remember(&self, records: Vec<EpisodicRecord>) -> Vec<HirnResult<MemoryId>> {
83 self.0.batch_remember(records).await
84 }
85
86 #[inline]
87 pub async fn get(&self, id: MemoryId) -> HirnResult<EpisodicRecord> {
88 self.0.get_episode(id).await
89 }
90
91 #[inline]
92 pub async fn list(&self, filter: &EpisodicFilter) -> HirnResult<Vec<EpisodicRecord>> {
93 self.0.list_episodes(filter).await
94 }
95
96 #[inline]
97 pub async fn delete(&self, id: MemoryId) -> HirnResult<()> {
98 self.0.delete_episode(id).await
99 }
100
101 #[inline]
102 pub async fn archive(&self, id: MemoryId) -> HirnResult<()> {
103 self.0.archive_episode(id).await
104 }
105
106 #[inline]
107 pub async fn decay(&self) -> HirnResult<usize> {
108 self.0.decay_memories().await
109 }
110
111 #[inline]
112 pub async fn purge_expired(&self) -> HirnResult<usize> {
113 self.0.purge_expired().await
114 }
115
116 #[inline]
117 pub async fn in_range(
118 &self,
119 after: Timestamp,
120 before: Timestamp,
121 ) -> HirnResult<Vec<EpisodicRecord>> {
122 self.0.episodes_in_range(after, before).await
123 }
124
125 #[inline]
126 pub async fn after(&self, after: Timestamp) -> HirnResult<Vec<EpisodicRecord>> {
127 self.0.episodes_after(after).await
128 }
129
130 #[inline]
131 pub async fn before(&self, before: Timestamp) -> HirnResult<Vec<EpisodicRecord>> {
132 self.0.episodes_before(before).await
133 }
134
135 #[inline]
136 pub async fn reverse(&self) -> HirnResult<Vec<EpisodicRecord>> {
137 self.0.episodes_reverse().await
138 }
139}
140
141impl<'a> SemanticView<'a> {
146 #[inline]
147 pub async fn store(&self, record: SemanticRecord) -> HirnResult<MemoryId> {
148 self.0.store_semantic(record).await
149 }
150
151 #[inline]
152 pub async fn get(&self, id: MemoryId) -> HirnResult<SemanticRecord> {
153 self.0.get_semantic(id).await
154 }
155
156 #[inline]
157 pub async fn get_by_concept(&self, name: &str) -> HirnResult<SemanticRecord> {
158 self.0.get_semantic_by_concept(name).await
159 }
160
161 #[inline]
162 pub async fn list(&self, filter: &SemanticFilter) -> HirnResult<Vec<SemanticRecord>> {
163 self.0.list_semantics(filter).await
164 }
165
166 #[inline]
167 pub async fn correct(
168 &self,
169 id: MemoryId,
170 update: SemanticUpdate,
171 ) -> HirnResult<SemanticRecord> {
172 self.0.correct_semantic(id, update).await
173 }
174
175 #[inline]
176 pub async fn supersede(
177 &self,
178 id: MemoryId,
179 supersession: SemanticSupersession,
180 ) -> HirnResult<SemanticRecord> {
181 self.0.supersede_semantic(id, supersession).await
182 }
183
184 #[inline]
185 pub async fn override_head(
186 &self,
187 id: MemoryId,
188 override_request: SemanticOverride,
189 ) -> HirnResult<SemanticRecord> {
190 self.0.override_semantic(id, override_request).await
191 }
192
193 #[inline]
194 pub async fn merge(
195 &self,
196 target: MemoryId,
197 merge: SemanticMerge,
198 ) -> HirnResult<SemanticMergeOutcome> {
199 self.0.merge_semantic(target, merge).await
200 }
201
202 #[inline]
203 pub async fn retract(
204 &self,
205 id: MemoryId,
206 retraction: SemanticRetraction,
207 ) -> HirnResult<SemanticRecord> {
208 self.0.retract_semantic(id, retraction).await
209 }
210
211 #[inline]
212 pub async fn purge(&self, id: MemoryId) -> HirnResult<()> {
213 self.0.purge_semantic(id).await
214 }
215
216 #[inline]
217 pub async fn history(&self, id: MemoryId) -> HirnResult<Vec<SemanticRecord>> {
218 self.0.semantic_history(id).await
219 }
220
221 #[inline]
222 pub async fn batch_store(&self, records: Vec<SemanticRecord>) -> Vec<HirnResult<MemoryId>> {
223 self.0.batch_store_semantic(records).await
224 }
225
226 #[inline]
227 pub async fn flush_access(&self) -> HirnResult<()> {
228 self.0.flush_semantic_access().await
229 }
230
231 #[inline]
232 pub async fn get_by_concept_ns(
233 &self,
234 name: &str,
235 namespace: &Namespace,
236 ) -> HirnResult<SemanticRecord> {
237 self.0.get_semantic_by_concept_ns(name, namespace).await
238 }
239}
240
241impl<'a> ProceduralView<'a> {
246 #[inline]
247 pub async fn store(&self, record: ProceduralRecord) -> HirnResult<MemoryId> {
248 self.0.store_procedural(record).await
249 }
250
251 #[inline]
252 pub async fn get(&self, id: MemoryId) -> HirnResult<ProceduralRecord> {
253 self.0.get_procedural(id).await
254 }
255
256 #[inline]
257 pub async fn execute(
258 &self,
259 id: MemoryId,
260 executor: &impl hirn_core::procedural::ToolExecutor,
261 ) -> HirnResult<hirn_core::procedural::ProcedureResult> {
262 self.0.execute_procedure(id, executor).await
263 }
264
265 #[inline]
266 pub async fn record_success(&self, id: MemoryId) -> HirnResult<()> {
267 self.0.record_procedural_success(id).await
268 }
269
270 #[inline]
271 pub async fn record_failure(&self, id: MemoryId) -> HirnResult<()> {
272 self.0.record_procedural_failure(id).await
273 }
274
275 #[inline]
283 pub async fn record_execution(
284 &self,
285 id: MemoryId,
286 success: bool,
287 _actor_id: AgentId,
288 ) -> HirnResult<()> {
289 if success {
290 self.0.record_procedural_success(id).await
291 } else {
292 self.0.record_procedural_failure(id).await
293 }
294 }
295
296 #[inline]
297 pub async fn delete(&self, id: MemoryId) -> HirnResult<()> {
298 self.0.delete_procedural(id).await
299 }
300
301 #[inline]
302 pub async fn list(&self, namespace: Option<&Namespace>) -> HirnResult<Vec<ProceduralRecord>> {
303 self.0.list_procedural(namespace).await
304 }
305}
306
307impl<'a> WorkingView<'a> {
312 #[inline]
313 pub async fn focus(&self, entry: WorkingMemoryEntry) -> HirnResult<MemoryId> {
314 self.0.focus(entry).await
315 }
316
317 #[inline]
318 pub async fn entries(&self) -> HirnResult<Vec<WorkingMemoryEntry>> {
319 self.0.working_memory().await
320 }
321
322 #[inline]
323 pub async fn entries_for_thread(&self, thread_id: &str) -> HirnResult<Vec<WorkingMemoryEntry>> {
324 self.0.working_memory_for_thread(thread_id).await
325 }
326
327 #[inline]
328 pub async fn defocus(&self, id: MemoryId) -> HirnResult<()> {
329 self.0.defocus(id).await
330 }
331}
332
333impl<'a> GraphView<'a> {
338 #[inline]
339 pub async fn connect(&self, source: MemoryId, target: MemoryId) -> HirnResult<EdgeId> {
340 self.0.connect(source, target).await
341 }
342
343 #[inline]
344 pub async fn connect_with(
345 &self,
346 source: MemoryId,
347 target: MemoryId,
348 relation: EdgeRelation,
349 weight: f32,
350 metadata: Metadata,
351 ) -> HirnResult<EdgeId> {
352 self.0
353 .connect_with(source, target, relation, weight, metadata)
354 .await
355 }
356
357 #[inline]
358 pub fn persistent_graph(&self) -> &crate::persistent_graph::PersistentGraph {
359 self.0.persistent_graph()
360 }
361
362 #[inline]
363 pub async fn flush_hebbian(&self) -> HirnResult<()> {
364 self.0.flush_hebbian().await
365 }
366}
367
368impl<'a> RecallView<'a> {
373 #[inline]
374 pub fn query(&self, query_embedding: Vec<f32>) -> RecallBuilder<'a> {
375 self.0.recall(query_embedding)
376 }
377
378 #[inline]
379 pub async fn fetch_resource(
380 &self,
381 actor_id: &AgentId,
382 resource_id: hirn_core::ResourceId,
383 hydration_mode: hirn_core::HydrationMode,
384 ) -> HirnResult<Option<hirn_storage::HydratedResource>> {
385 self.0
386 .fetch_resource(actor_id, resource_id, hydration_mode)
387 .await
388 }
389
390 #[inline]
391 pub async fn batch<'b>(
392 &self,
393 builders: Vec<RecallBuilder<'b>>,
394 ) -> Vec<HirnResult<Vec<RecallResult>>>
395 where
396 'a: 'b,
397 {
398 self.0.batch_recall(builders).await
399 }
400
401 #[inline]
402 pub fn think(&self, query_embedding: Vec<f32>) -> crate::think::ThinkBuilder<'a> {
403 self.0.think(query_embedding)
404 }
405
406 #[inline]
407 pub fn inspect(&self, id: MemoryId) -> crate::inspect::InspectBuilder<'a> {
408 self.0.inspect(id)
409 }
410
411 #[inline]
412 pub fn trace(&self, id: MemoryId) -> crate::trace::TraceBuilder<'a> {
413 self.0.trace(id)
414 }
415}
416
417impl<'a> NamespaceView<'a> {
422 #[inline]
423 pub async fn create(
424 &self,
425 name: &str,
426 kind: hirn_core::types::NamespaceKind,
427 members: Vec<AgentId>,
428 ) -> HirnResult<()> {
429 self.0.create_namespace(name, kind, members).await
430 }
431
432 #[inline]
433 pub async fn list(&self) -> HirnResult<Vec<hirn_core::namespace::NamespaceRecord>> {
434 self.0.list_namespaces().await
435 }
436
437 #[inline]
438 pub async fn get(&self, name: &str) -> HirnResult<hirn_core::namespace::NamespaceRecord> {
439 self.0.get_namespace(name).await
440 }
441
442 #[inline]
443 pub async fn delete(&self, name: &str) -> HirnResult<()> {
444 self.0.delete_namespace(name).await
445 }
446}
447
448impl<'a> PolicyView<'a> {
453 #[inline]
455 pub async fn enforce(
456 &self,
457 agent_id: &str,
458 action: Action,
459 realm: &str,
460 namespace: &str,
461 ) -> HirnResult<()> {
462 self.0.enforce(agent_id, action, realm, namespace).await
463 }
464
465 #[inline]
467 pub fn is_action_allowed(
468 &self,
469 agent_id: &str,
470 action: Action,
471 realm: &str,
472 namespace: &str,
473 ) -> bool {
474 self.0.is_action_allowed(agent_id, action, realm, namespace)
475 }
476}
477
478impl<'a> AdminView<'a> {
483 #[inline]
485 pub fn mutation_write_contracts(&self) -> &'static [MutationWriteContract] {
486 self.0.mutation_write_contracts()
487 }
488
489 #[inline]
491 pub async fn stats(&self) -> HirnResult<DbStats> {
492 self.0.stats().await
493 }
494
495 #[inline]
497 pub async fn count(&self) -> HirnResult<LayerCounts> {
498 self.0.count().await
499 }
500
501 #[inline]
503 pub fn consolidate(&self) -> crate::consolidation::ConsolidateBuilder<'a> {
504 self.0.consolidate()
505 }
506
507 #[inline]
509 pub fn lifecycle_compact(&self) -> crate::consolidation::LifecycleCompactBuilder<'a> {
510 self.0.lifecycle_compact()
511 }
512
513 #[inline]
515 pub async fn apply_resource_retention_policy(
516 &self,
517 policy: &hirn_core::ResourceRetentionPolicy,
518 ) -> HirnResult<hirn_storage::ResourceRetentionApplyResult> {
519 self.0.apply_resource_retention_policy(policy).await
520 }
521
522 #[inline]
524 pub async fn apply_configured_resource_retention(
525 &self,
526 ) -> HirnResult<hirn_storage::ResourceRetentionApplyResult> {
527 self.0.apply_configured_resource_retention().await
528 }
529
530 #[inline]
532 pub async fn audit_log(
533 &self,
534 after: Option<&Timestamp>,
535 before: Option<&Timestamp>,
536 ) -> HirnResult<Vec<hirn_core::audit::AuditEntry>> {
537 self.0.audit_log(after, before).await
538 }
539
540 #[inline]
542 pub async fn cross_agent_consolidate(
543 &self,
544 target_namespace: &Namespace,
545 auto_merge_threshold: f32,
546 ) -> HirnResult<CrossAgentConsolidationResult> {
547 self.0
548 .cross_agent_consolidate(target_namespace, auto_merge_threshold)
549 .await
550 }
551
552 #[inline]
554 pub async fn purge_agent(&self, agent_id: &AgentId) -> HirnResult<PurgeReport> {
555 self.0.purge_agent(agent_id).await
556 }
557
558 #[inline]
560 pub async fn schedule_offline_job(
561 &self,
562 job: hirn_core::CognitiveJob,
563 ) -> HirnResult<hirn_core::OfflineJobId> {
564 self.0.offline_scheduler_runtime().submit_job(job).await
565 }
566
567 #[inline]
569 pub fn offline_job_status(
570 &self,
571 job_id: hirn_core::OfflineJobId,
572 ) -> Option<hirn_core::OfflineJobStatus> {
573 self.0.offline_scheduler_runtime().job_status(job_id)
574 }
575
576 #[inline]
578 pub async fn inspect_offline_job(
579 &self,
580 job_id: hirn_core::OfflineJobId,
581 ) -> HirnResult<Option<hirn_core::OfflineJobInspection>> {
582 self.0.offline_scheduler_runtime().inspect_job(job_id).await
583 }
584
585 #[inline]
587 pub async fn retry_offline_job(
588 &self,
589 job_id: hirn_core::OfflineJobId,
590 ) -> HirnResult<hirn_core::OfflineJobId> {
591 self.0.offline_scheduler_runtime().retry_job(job_id).await
592 }
593
594 #[inline]
596 pub async fn replay_offline_job(
597 &self,
598 job_id: hirn_core::OfflineJobId,
599 ) -> HirnResult<hirn_core::OfflineJobId> {
600 self.0.offline_scheduler_runtime().replay_job(job_id).await
601 }
602
603 #[inline]
605 pub fn offline_scheduler_metrics(&self) -> hirn_core::OfflineSchedulerMetrics {
606 self.0.offline_scheduler_runtime().metrics_snapshot()
607 }
608
609 #[inline]
611 pub async fn close(&self) -> HirnResult<()> {
612 self.0.close().await
613 }
614
615 #[inline]
617 pub async fn get_memory(&self, id: MemoryId) -> HirnResult<MemoryRecord> {
618 self.0.get_memory(id).await
619 }
620
621 #[inline]
623 pub async fn get_memories_batch(
624 &self,
625 ids: &[MemoryId],
626 ) -> HirnResult<HashMap<MemoryId, MemoryRecord>> {
627 self.0.get_memories_batch(ids).await
628 }
629
630 #[inline]
632 pub async fn validate_semantic_revisions(
633 &self,
634 ) -> HirnResult<crate::integrity::SemanticRevisionIntegrityReport> {
635 crate::integrity::check_semantic_revision_integrity(self.0).await
636 }
637
638 #[inline]
640 pub async fn repair_semantic_revisions(
641 &self,
642 ) -> HirnResult<crate::integrity::SemanticRevisionRepairReport> {
643 crate::integrity::repair_semantic_revision_integrity(self.0).await
644 }
645}
646
647impl<'a> QueryView<'a> {
652 #[inline]
654 pub async fn execute(&self, query: &str) -> HirnResult<crate::ql::results::QueryResult> {
655 self.0.execute_ql(query).await
656 }
657
658 #[inline]
661 pub async fn execute_with_diagnostics(
662 &self,
663 query: &str,
664 ) -> HirnResult<(
665 crate::ql::results::QueryResult,
666 Option<crate::diagnostics::QueryDiagnostics>,
667 )> {
668 self.0.execute_ql_with_diagnostics(query).await
669 }
670
671 #[inline]
673 pub async fn execute_scoped(
674 &self,
675 query: &str,
676 allowed_namespaces: &[Namespace],
677 ) -> HirnResult<crate::ql::results::QueryResult> {
678 self.0.execute_ql_scoped(query, allowed_namespaces).await
679 }
680
681 #[inline]
683 pub fn explain(&self, query: &str) -> HirnResult<String> {
684 self.0.explain_plan(query)
685 }
686
687 #[inline]
689 pub fn prepare(&self, query: &str) -> HirnResult<crate::ql::PreparedStatement> {
690 self.0.prepare(query)
691 }
692
693 #[inline]
695 pub async fn execute_prepared(
696 &self,
697 prepared: &crate::ql::PreparedStatement,
698 params: &std::collections::HashMap<String, String>,
699 ) -> HirnResult<crate::ql::results::QueryResult> {
700 self.0.execute_prepared(prepared, params).await
701 }
702
703 #[inline]
705 pub fn builder(&self) -> crate::ql::builder::QueryBuilder<'a> {
706 self.0.query()
707 }
708
709 #[inline]
711 pub fn invalidate_cache(&self) {
712 self.0.invalidate_plan_cache();
713 }
714}
715
716impl<'a> CausalView<'a> {
721 #[inline]
723 pub async fn mark_contradiction(&self, id: MemoryId, contradicts: MemoryId) -> HirnResult<()> {
724 self.0.mark_contradiction(id, contradicts).await
725 }
726
727 #[inline]
729 pub async fn apply_aba_resolution(
730 &self,
731 winner: MemoryId,
732 loser: MemoryId,
733 loser_revised_confidence: f32,
734 reason: &str,
735 ) -> HirnResult<()> {
736 self.0
737 .apply_aba_resolution(winner, loser, loser_revised_confidence, reason)
738 .await
739 }
740
741 #[inline]
743 pub async fn review_quarantine(&self) -> HirnResult<Vec<crate::security::QuarantineEntry>> {
744 self.0.review_quarantine().await
745 }
746
747 #[inline]
749 pub async fn approve_quarantine(
750 &self,
751 id: MemoryId,
752 approved_by: AgentId,
753 ) -> HirnResult<crate::security::QuarantineApprovalOutcome> {
754 self.0.approve_quarantine(id, approved_by).await
755 }
756
757 #[inline]
759 pub async fn reject_quarantine(&self, id: MemoryId) -> HirnResult<()> {
760 self.0.reject_quarantine(id).await
761 }
762
763 #[inline]
765 pub async fn rollback_quarantine_approval(
766 &self,
767 id: MemoryId,
768 rolled_back_by: AgentId,
769 reason: String,
770 ) -> HirnResult<crate::security::QuarantineRollbackOutcome> {
771 self.0
772 .rollback_quarantine_approval(id, rolled_back_by, reason)
773 .await
774 }
775}
776
777impl HirnDB {
782 #[inline]
784 pub fn episodic(&self) -> EpisodicView<'_> {
785 EpisodicView(self)
786 }
787
788 #[inline]
790 pub fn semantic(&self) -> SemanticView<'_> {
791 SemanticView(self)
792 }
793
794 #[inline]
796 pub fn procedural(&self) -> ProceduralView<'_> {
797 ProceduralView(self)
798 }
799
800 #[inline]
802 pub fn working(&self) -> WorkingView<'_> {
803 WorkingView(self)
804 }
805
806 #[inline]
808 pub fn graph_view(&self) -> GraphView<'_> {
809 GraphView(self)
810 }
811
812 #[inline]
814 pub fn recall_view(&self) -> RecallView<'_> {
815 RecallView(self)
816 }
817
818 #[inline]
820 pub fn namespaces(&self) -> NamespaceView<'_> {
821 NamespaceView(self)
822 }
823
824 #[inline]
826 pub fn policy(&self) -> PolicyView<'_> {
827 PolicyView(self)
828 }
829
830 #[inline]
832 pub fn admin(&self) -> AdminView<'_> {
833 AdminView(self)
834 }
835
836 #[inline]
838 pub fn ql(&self) -> QueryView<'_> {
839 QueryView(self)
840 }
841
842 #[inline]
844 pub fn causal(&self) -> CausalView<'_> {
845 CausalView(self)
846 }
847}