awaken_runtime/extensions/handoff/
plugin.rs1use std::collections::HashMap;
2
3use awaken_contract::StateError;
4use awaken_contract::contract::active_agent::ActiveAgentIdKey;
5use awaken_contract::model::Phase;
6use awaken_contract::registry_spec::AgentSpec;
7
8use crate::plugins::{Plugin, PluginDescriptor, PluginRegistrar};
9use crate::state::{KeyScope, MutationBatch, StateKeyOptions};
10
11use super::action::HandoffAction;
12use super::hook::HandoffSyncHook;
13use super::state::{ActiveAgentKey, HandoffState};
14use super::types::AgentOverlay;
15
16pub const HANDOFF_PLUGIN_ID: &str = "agent_handoff";
18
19pub struct HandoffPlugin {
24 overlays: HashMap<String, AgentOverlay>,
25}
26
27impl HandoffPlugin {
28 pub fn new(overlays: HashMap<String, AgentOverlay>) -> Self {
30 Self { overlays }
31 }
32
33 pub fn overlay(&self, agent: &str) -> Option<&AgentOverlay> {
35 self.overlays.get(agent)
36 }
37
38 pub fn effective_agent(state: &HandoffState) -> Option<&String> {
40 state
41 .requested_agent
42 .as_ref()
43 .or(state.active_agent.as_ref())
44 }
45}
46
47impl Plugin for HandoffPlugin {
48 fn descriptor(&self) -> PluginDescriptor {
49 PluginDescriptor {
50 name: HANDOFF_PLUGIN_ID,
51 }
52 }
53
54 fn register(&self, registrar: &mut PluginRegistrar) -> Result<(), StateError> {
55 let thread_scope = StateKeyOptions {
56 scope: KeyScope::Thread,
57 persistent: true,
58 ..StateKeyOptions::default()
59 };
60 registrar.register_key::<ActiveAgentKey>(thread_scope)?;
61 registrar.register_key::<ActiveAgentIdKey>(thread_scope)?;
62 registrar.register_phase_hook(HANDOFF_PLUGIN_ID, Phase::RunStart, HandoffSyncHook)?;
63 registrar.register_phase_hook(HANDOFF_PLUGIN_ID, Phase::StepEnd, HandoffSyncHook)?;
64 Ok(())
65 }
66
67 fn on_activate(
68 &self,
69 _agent_spec: &AgentSpec,
70 _patch: &mut MutationBatch,
71 ) -> Result<(), StateError> {
72 Ok(())
73 }
74
75 fn on_deactivate(&self, patch: &mut MutationBatch) -> Result<(), StateError> {
76 patch.update::<ActiveAgentKey>(HandoffAction::Clear);
77 patch.update::<ActiveAgentIdKey>(None);
78 Ok(())
79 }
80}