1212from perfkitbenchmarker import context
1313from perfkitbenchmarker import data
1414from perfkitbenchmarker import errors
15+ from perfkitbenchmarker import sample
1516from perfkitbenchmarker import vm_util
1617from perfkitbenchmarker .providers .gcp import gce_virtual_machine
1718from perfkitbenchmarker .providers .gcp import gcs
@@ -363,6 +364,8 @@ def __init__(self, client_vm, ai_agent_spec):
363364 self ._remote_agent_name = None
364365 self ._staging_bucket = self .base_dir
365366 self .spec = ai_agent_spec
367+ self ._time_to_create : float | None = None
368+ self ._time_to_ready : float | None = None
366369
367370 @override
368371 def _StageAgentCode (self ):
@@ -419,6 +422,9 @@ def _GetDeploymentConfig(self) -> dict[str, Any]:
419422 'staging_bucket' : self ._staging_bucket ,
420423 'agent_config' : self .agent_config ,
421424 })
425+ initial_prompt = self ._GetInitialPromptText ()
426+ if initial_prompt :
427+ config ['initial_prompt' ] = initial_prompt
422428 return config
423429
424430 def _Create (self ):
@@ -446,12 +452,17 @@ def _Create(self):
446452 command = ' && ' .join (command_parts )
447453 stdout , _ = self .client_vm .RemoteCommand (command )
448454
449- # 5. Parse output to get remote agent name
455+ # 5. Parse output to get remote agent name and latencies
450456 for line in stdout .split ('\n ' ):
451457 if line .startswith ('Resource name: ' ):
452458 _ , _ , agent_name = line .partition ('Resource name: ' )
453459 self ._remote_agent_name = agent_name .strip ()
454- break
460+ elif line .startswith ('Time to Create: ' ):
461+ _ , _ , time_str = line .partition ('Time to Create: ' )
462+ self ._time_to_create = float (time_str .strip ())
463+ elif line .startswith ('Time to Ready: ' ):
464+ _ , _ , time_str = line .partition ('Time to Ready: ' )
465+ self ._time_to_ready = float (time_str .strip ())
455466
456467 if not self ._remote_agent_name :
457468 raise errors .Benchmarks .PrepareException (
@@ -464,6 +475,16 @@ def _Create(self):
464475 self ._remote_agent_name ,
465476 )
466477
478+ def _PostCreate (self ):
479+ if (
480+ ai_agent_service .AI_AGENT_INITIAL_PROMPT_URL .value
481+ and not self ._time_to_ready
482+ ):
483+ raise errors .Benchmarks .PrepareException (
484+ 'Initial prompt was explictly passed, but failed to get remote ready'
485+ ' time from deploy script output.'
486+ )
487+
467488 def _Delete (self ):
468489 """Deletes the remote agent."""
469490 if not self ._remote_agent_name :
@@ -600,3 +621,38 @@ def Execute(
600621 'Agent execution finished. Raw output:\n %s' ,
601622 stdout ,
602623 )
624+
625+ @override
626+ def GetSamples (self ):
627+ samples = super ().GetSamples ()
628+ create_time_sample = [s for s in samples if s .metric == 'Time to Create' ][0 ]
629+ resource_type = create_time_sample .metadata .get ('resource_type' )
630+ resource_class = create_time_sample .metadata .get ('resource_class' )
631+ metadata = {
632+ 'resource_type' : resource_type ,
633+ 'resource_class' : resource_class ,
634+ }
635+
636+ # Remove existing samples for 'Time to Create' and 'Time to Ready' if any
637+ samples = [
638+ s
639+ for s in samples
640+ if s .metric not in ('Time to Create' , 'Time to Ready' )
641+ ]
642+
643+ if self ._time_to_create is not None :
644+ samples .append (
645+ sample .Sample (
646+ 'Time to Create' ,
647+ self ._time_to_create ,
648+ 'seconds' ,
649+ metadata = metadata ,
650+ )
651+ )
652+ if self ._time_to_ready is not None :
653+ samples .append (
654+ sample .Sample (
655+ 'Time to Ready' , self ._time_to_ready , 'seconds' , metadata = metadata
656+ )
657+ )
658+ return samples
0 commit comments