@@ -15,6 +15,10 @@ use crate::platform::api::{PlatformApiClient, PlatformApiError};
1515pub struct GetDeploymentStatusArgs {
1616 /// The task ID to check status for
1717 pub task_id : String ,
18+ /// Optional project ID to check actual deployment status (for public_url)
19+ pub project_id : Option < String > ,
20+ /// Optional service name to find the specific deployment
21+ pub service_name : Option < String > ,
1822}
1923
2024/// Error type for get deployment status operations
@@ -46,22 +50,28 @@ impl Tool for GetDeploymentStatusTool {
4650 async fn definition ( & self , _prompt : String ) -> ToolDefinition {
4751 ToolDefinition {
4852 name : Self :: NAME . to_string ( ) ,
49- description : r#"Get the status of a deployment task.
53+ description : r#"Get the status of a deployment task and optionally check the actual service status .
5054
5155Returns the current status of a deployment, including progress percentage,
52- current step, and overall status.
56+ current step, overall status, and optionally the public URL if the service is ready.
57+
58+ **IMPORTANT for Cloud Runner:**
59+ The task may show "completed" when infrastructure is provisioned, but the actual
60+ service build and deployment takes longer. Pass project_id and service_name to
61+ also check if the service has a public URL (meaning it's actually ready).
5362
5463**Status Values:**
5564- Task status: "processing", "completed", "failed"
5665- Overall status: "generating", "building", "deploying", "healthy", "failed"
66+ - Service ready: Only when public_url is available
5767
5868**Prerequisites:**
5969- User must be authenticated via `sync-ctl auth login`
6070- A deployment must have been triggered (use trigger_deployment first)
6171
6272**Use Cases:**
6373- Monitor deployment progress after triggering
64- - Check if a deployment has completed
74+ - Check if a deployment has completed AND is actually serving traffic
6575- Get error details if deployment failed"#
6676 . to_string ( ) ,
6777 parameters : json ! ( {
@@ -70,6 +80,14 @@ current step, and overall status.
7080 "task_id" : {
7181 "type" : "string" ,
7282 "description" : "The deployment task ID (from trigger_deployment response)"
83+ } ,
84+ "project_id" : {
85+ "type" : "string" ,
86+ "description" : "Optional: Project ID to check actual service status and public URL"
87+ } ,
88+ "service_name" : {
89+ "type" : "string" ,
90+ "description" : "Optional: Service name to find the specific deployment"
7391 }
7492 } ,
7593 "required" : [ "task_id" ]
@@ -99,46 +117,92 @@ current step, and overall status.
99117 }
100118 } ;
101119
102- // Get the deployment status
120+ // Get the deployment status (Backstage task)
103121 match client. get_deployment_status ( & args. task_id ) . await {
104122 Ok ( status) => {
105- let is_complete = status. status == "completed" ;
123+ let task_complete = status. status == "completed" ;
106124 let is_failed = status. status == "failed" || status. overall_status == "failed" ;
107125 let is_healthy = status. overall_status == "healthy" ;
108126
127+ // Also check actual deployment if project_id and service_name provided
128+ // This is crucial for Cloud Runner where task completes but service takes longer
129+ let ( service_status, public_url, service_ready) = if let ( Some ( project_id) , Some ( service_name) ) = ( & args. project_id , & args. service_name ) {
130+ match client. list_deployments ( project_id, Some ( 10 ) ) . await {
131+ Ok ( paginated) => {
132+ // Find the deployment for this service
133+ let deployment = paginated. data . iter ( )
134+ . find ( |d| d. service_name . eq_ignore_ascii_case ( service_name) ) ;
135+
136+ match deployment {
137+ Some ( d) => (
138+ Some ( d. status . clone ( ) ) ,
139+ d. public_url . clone ( ) ,
140+ d. public_url . is_some ( ) && d. status == "running"
141+ ) ,
142+ None => ( None , None , false )
143+ }
144+ }
145+ Err ( _) => ( None , None , false )
146+ }
147+ } else {
148+ ( None , None , false )
149+ } ;
150+
151+ // True completion = task done AND (service has URL or no service check requested)
152+ let truly_ready = if args. project_id . is_some ( ) {
153+ service_ready
154+ } else {
155+ is_healthy
156+ } ;
157+
109158 let mut result = json ! ( {
110159 "success" : true ,
111160 "task_id" : args. task_id,
112- "status " : status. status,
113- "progress " : status. progress,
161+ "task_status " : status. status,
162+ "task_progress " : status. progress,
114163 "current_step" : status. current_step,
115164 "overall_status" : status. overall_status,
116165 "overall_message" : status. overall_message,
117- "is_complete " : is_complete ,
166+ "task_complete " : task_complete ,
118167 "is_failed" : is_failed,
119- "is_healthy " : is_healthy
168+ "service_ready " : truly_ready
120169 } ) ;
121170
171+ // Add service-specific info if we checked
172+ if let Some ( svc_status) = service_status {
173+ result[ "service_status" ] = json ! ( svc_status) ;
174+ }
175+ if let Some ( url) = & public_url {
176+ result[ "public_url" ] = json ! ( url) ;
177+ }
178+
122179 // Add error details if failed
123180 if let Some ( error) = & status. error {
124181 result[ "error" ] = json ! ( error) ;
125182 }
126183
127- // Add next steps based on status
184+ // Add next steps based on actual status
128185 if is_failed {
129186 result[ "next_steps" ] = json ! ( [
130187 "Review the error message for details" ,
131188 "Check the deployment configuration" ,
132189 "Verify the code builds successfully locally" ,
133190 "Try triggering a new deployment after fixing the issue"
134191 ] ) ;
135- } else if is_healthy {
192+ } else if truly_ready && public_url. is_some ( ) {
193+ result[ "next_steps" ] = json ! ( [
194+ format!( "Service is live at: {}" , public_url. as_ref( ) . unwrap( ) ) ,
195+ "Deployment completed successfully!" ,
196+ "Use get_service_logs to view container logs"
197+ ] ) ;
198+ } else if task_complete && !truly_ready {
136199 result[ "next_steps" ] = json ! ( [
137- "Deployment completed successfully " ,
138- "Use list_deployments to see the deployed service details " ,
139- "Check the public_url to access the deployed service "
200+ "Infrastructure task completed, but service is still deploying " ,
201+ "Cloud Runner is building and deploying your container " ,
202+ "Call get_deployment_status again in 30-60 seconds to check for public_url "
140203 ] ) ;
141- } else if !is_complete {
204+ result[ "note" ] = json ! ( "Task shows 100% but service is still being built/deployed. This is normal for Cloud Runner." ) ;
205+ } else if !task_complete {
142206 result[ "next_steps" ] = json ! ( [
143207 format!( "Deployment is {} ({}% complete)" , status. overall_status, status. progress) ,
144208 "Call get_deployment_status again to check progress"
0 commit comments