objectiveai_cli/command/agents/
wait.rs1use objectiveai_sdk::cli::command::agents::selector::AgentSelector;
22use objectiveai_sdk::cli::command::agents::wait::{Request, Response};
23
24use crate::context::Context;
25use crate::error::Error;
26
27pub async fn execute(ctx: &Context, request: Request) -> Result<Response, Error> {
28 wait(ctx, request.agent).await
29}
30
31async fn wait(ctx: &Context, agent: AgentSelector) -> Result<Response, Error> {
32 let state_dir = ctx.filesystem.state_dir();
33
34 let hierarchy = match agent {
35 AgentSelector::Instance {
36 parent_agent_instance_hierarchy,
37 agent_instance,
38 } => {
39 let parent = parent_agent_instance_hierarchy
40 .as_deref()
41 .unwrap_or(&ctx.config.agent_instance_hierarchy);
42 format!("{parent}/{agent_instance}")
43 }
44 AgentSelector::Tag { agent_tag } => {
45 match crate::db::tags::lookup(ctx.db_client().await?, &agent_tag).await? {
46 crate::db::tags::LookupState::Bound {
47 agent_instance_hierarchy,
48 } => agent_instance_hierarchy,
49 crate::db::tags::LookupState::Grouped { .. } => {
50 match wait_for_tag_upgrade(ctx, &state_dir, agent_tag).await? {
51 Some(agent_instance_hierarchy) => agent_instance_hierarchy,
52 None => return Ok(Response::Ok),
54 }
55 }
56 crate::db::tags::LookupState::Absent => {
57 return Err(Error::TagNotFound(agent_tag));
58 }
59 }
60 }
61 AgentSelector::Ref { .. } => return Err(Error::WaitRefTarget),
62 };
63
64 let (dir, key) = super::locks::agent_instance_lock(&state_dir, &hierarchy);
65 objectiveai_sdk::lockfile::wait_released(&dir, &key)
66 .await
67 .map_err(|source| Error::Lockfile { key, source })?;
68 Ok(Response::Ok)
69}
70
71async fn wait_for_tag_upgrade(
76 ctx: &Context,
77 state_dir: &std::path::Path,
78 agent_tag: String,
79) -> Result<Option<String>, Error> {
80 let (dir, key) = super::locks::agent_tag_lock(state_dir, &agent_tag);
81
82 if objectiveai_sdk::lockfile::try_held(&dir, &key).await {
83 objectiveai_sdk::lockfile::wait_released(&dir, &key)
84 .await
85 .map_err(|source| Error::Lockfile { key, source })?;
86 match crate::db::tags::lookup(ctx.db_client().await?, &agent_tag).await? {
90 crate::db::tags::LookupState::Bound {
91 agent_instance_hierarchy,
92 } => Ok(Some(agent_instance_hierarchy)),
93 crate::db::tags::LookupState::Grouped { .. } => {
94 Err(Error::TagLockDroppedWithoutUpgrade { tag: agent_tag })
95 }
96 crate::db::tags::LookupState::Absent => Err(Error::TagNotFound(agent_tag)),
97 }
98 } else {
99 match crate::db::tags::lookup(ctx.db_client().await?, &agent_tag).await? {
103 crate::db::tags::LookupState::Bound {
104 agent_instance_hierarchy,
105 } => Ok(Some(agent_instance_hierarchy)),
106 crate::db::tags::LookupState::Grouped { .. } => Ok(None),
107 crate::db::tags::LookupState::Absent => Err(Error::TagNotFound(agent_tag)),
108 }
109 }
110}
111
112pub mod request_schema {
113 use objectiveai_sdk::cli::command::agents::wait as sdk;
114 use objectiveai_sdk::cli::command::agents::wait::request_schema::{Request, Response};
115
116 use crate::context::Context;
117 use crate::error::Error;
118
119 pub async fn execute(_ctx: &Context, _request: Request) -> Result<Response, Error> {
120 Ok(objectiveai_sdk::cli::command::ResponseSchema(schemars::schema_for!(sdk::Request)))
121 }
122}
123
124pub mod response_schema {
125 use objectiveai_sdk::cli::command::agents::wait as sdk;
126 use objectiveai_sdk::cli::command::agents::wait::response_schema::{Request, Response};
127
128 use crate::context::Context;
129 use crate::error::Error;
130
131 pub async fn execute(_ctx: &Context, _request: Request) -> Result<Response, Error> {
132 Ok(objectiveai_sdk::cli::command::ResponseSchema(schemars::schema_for!(sdk::Response)))
133 }
134}