o
    i                     @   s>  d dl Z d dlmZ d dlmZ d dlZd dlZd dlZd dlm	Z	 d dl
mZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZmZmZm Z  d dl!m"Z"m#Z# d dl$m%Z%m&Z& d dl'm(Z( d dl)m*Z* d dl+m,Z, d dl-m.Z. ej/ddddZ0dde1e2e3B  de2de4fddZ5de2de4fd d!Z6d"e2de4fd#d$Z7e0j8d%d&d'ej9eej:dd(d)d*d+ej:dd,d-d.d+fd/e4d0ee. fd1d%Z1e0j8d2d3d'ej9eej;d4d+ej:dd(d)d5d+fd6e4d/e4fd7d2Z<e0j8d8d9d'ej9ee#ej:ddd:ej;dd;d<d=ej:dd>d?d@d+ej:dd(d)dAd+fd6e4dBe4d/e4fdCd8Z=e0j8dDdEd'ej9edFdD Z>G dGdH dHe4eZ?G dIdJ dJe4eZ@G dKdL dLe4eZAe0j8dMdNd'ej9eej:dd(d)d5d+ej:ddOdPdQd+ej:e?jBdRdSdTd+ej:dUdVdWdXd+ej:ddYdZd[d+ej:dd\d]d^d+fd6e4d/e4d_e@d`e?dae2dbe4dBe4fdcdMZCe0j8ddded'ej9eej:dd(d)dfd+ej:d<dgdSdhd+fd6e4d/e4dieDfdjddZEe0j8dkdld'ej9eej:dd(d)dmd+fd6e4d/e4fdndkZFe0j8dodpd'ej9ee#ej:ddd:ej;ddqd+ej:d<dgdSdhdrdsej:ddtdudvdrdsej:ddwdZdxdrdsej:d<dydzd{drdsej:dd|d}d~drdsej:dd(d)dd+fd6e4dieDde4de4deDde4d/e4fddoZGe0j8ddd'ej9ee#ej:ddd:ej;ddd+ej:dd\d]dd+ej:dd(d)dd+ej:d<dgdSdhd+fd6e4dBe4d/e4dieDfddZHdS )    N)Enum)Optional)logger)box)Columns)Group)Live)Panel)Table)Text)synchronizer)requires_login)calculate_percentilesconsoleformat_durationformat_timestamp)DeployConfigParamswith_deploy_config)get_region_codesvalidate_region)PIPECAT_CLI_NAME)API)config)RegionagentzAgent managementT)namehelpno_args_is_help2   values	max_widthreturnc           	         s   | sdS t | |kr>t | | }g }t|D ]%}t|| }t|d | }| || }||r8t|t | nd q|} d t| t| }|krU d t |  S | d d fdd| D S )	z?Generate Unicode sparkline from values, downsampling if needed.    r   u   ▁▂▃▄▅▆▇█      c                 3   s*    | ]} t d t|   V  qdS )r%   N)minint).0vblocksloscale S/home/ubuntu/.local/lib/python3.10/site-packages/pipecatcloud/cli/commands/agent.py	<genexpr>>   s   ( zsparkline.<locals>.<genexpr>)lenranger'   appendsumr&   maxjoin)	r   r    bucket_sizedownsampledistartendbuckethir.   r*   r/   	sparkline)   s"    r>   bc                 C   sR   | dkr| d ddS | dkr| d ddS | dkr$| d ddS |  d	S )
z&Format bytes as human-readable string.i   @.1fGBi   z.0fMBi   KBBr.   )r?   r.   r.   r/   format_bytesA   s   
rE   
millicoresc                 C   s   | d ddS )z/Format CPU millicores as human-readable string.i  z.2fz coresr.   )rF   r.   r.   r/   
format_cpuL   s   rG   listzList agents in an organization.)r   r   z--organizationz-ozOrganization to list agents for)r   z--regionz-rzFilter by regionorganizationregionc                    s  | pt d}|r+t|I d H s+t I d H }td| dd| d tdS tj	d| dd	d
 t
j||dI d H \}}|rPt W  d    S |rXt|dkrptd| dt d tdW  d    S tdddtjd}|d |d |d |d |d |d |D ]}|d|d  d|d |d |d |d |d   qtj|d!| t| d"d# W d    d S 1 sw   Y  d S )$Norgz[red]Invalid region 'z'. Valid regions are: z, [/red]r#   z.[dim]Fetching agents for organization: [bold]''[/bold][/dim]dotsspinner)rK   rJ   r   z3[red]No agents found for namespace / organization 'zB'[/red]

[dim]Please deploy an agent first using[/dim] [bold cyan]z deploy[/bold cyan]Tdimshow_header
show_linesborder_styler   Namer   zAgent IDzActive Deployment ID
Created At
Updated Atz[bold]r   [/bold]rJ   idactiveDeploymentId	createdAt	updatedAtzAgents for organization: z results)titletitle_extra)r   getr   r   r   printr6   typerExitstatusr   agentsr1   errorr   r
   r   SIMPLE
add_columnadd_rowsuccess)rI   rJ   rK   valid_regionsdatarf   tableservicer.   r.   r/   rH   T   sV   






	"rd   zGet status of agent deploymentz2Name of the agent to get status of e.g. 'my-agent'z'Organization to get status of agent for
agent_namec                    s  |pt d}ttjd|  ddd}tj| ||dI d H \}}td|  |	  |r=t
 W  d    S |sStd|  d	 t
 W  d    S td
d
tjd}|d |d |dt|dd |dt|di di di dd |d}|r|dt| |dt|dd |dt|dd |dt|dd |di di di di }t|tr|dd
}	nt|}	|d |	rd!nd" |d#}
d"}|
rt|
tr|
d$}|rd%| d&}|d'| |d(d }|r9td)|d*d+ d,d-td.|d/d+ d,d-g}tt|d0d1d2d3}d }|d4g }|rt|d+krtd
d
tjd}|d5 |d6 |D ]}|d7|d8  d9d:|d;d pw|d<d= d> q_t|d?d1d@d3}|dA rdBndC}|dA rdDt dE|  dFndGt dH|  dF}ttt||r|ndItdJ| dK|dA rdLndM dN|dA rdOndPd
dQ|r|ndIdR|  dSd1d1|dT W d    d S 1 sw   Y  d S )UNrK   z [dim]Looking up agent with name [/dim]rN   rO   ro   rK   livezAgent status: z.No deployment data found for agent with name ''F)rS   rT   r   KeyValuez"[bold]Active Session Count:[/bold]activeSessionCountN/Az[bold]Image:[/bold]
deploymentmanifestspecimageagentProfilez[bold]Agent Profile:[/bold]z"[bold]Active Deployment ID:[/bold]r[   z[bold]Created At:[/bold]r\   z[bold]Updated At:[/bold]r]   integratedKeysProxyenabledz[bold]Managed Keys:[/bold]z[green]Enabled[/green]z[dim]Disabled[/dim]	krispVivaaudioFilterz[green]Enabled (z	)[/green]z[bold]Krisp VIVA:[/bold]autoScalingz[bold]Minimum Agents[/bold]
minReplicasr   Texpandz[bold]Maximum Agents[/bold]
maxReplicasz#[bold]Scaling configuration:[/bold]leftrQ   r^   title_alignrU   errorsCodeMessagez
[bold red]codez[/bold red]z[red]messagerf   zUnknown errorrL   z"[bold red]Agent errors:[/bold red]redreadyz
bold greenzbold yellowz6[dim]Start a new active session with[/dim] [bold cyan]z agent start [/bold cyan]z;[dim]For more information check logs with[/dim] [bold cyan]z agent logs r"   [z	]Health: ReadyStopped[/]greenyellow)rU   r   zStatus for agent [bold]rY   )r^   r   subtitle_alignsubtitle)r   r`   r   r   rd   r   r   r   debugstoprb   rc   rf   r
   r   rg   rh   ri   str
isinstancedictboolr	   r   r1   r   ra   r   )ro   rI   rK   rr   rl   rf   deployment_tableagent_profileintegrated_keysintegrated_keys_enabled
krisp_vivakrisp_viva_statusaudio_filterautoscaling_datascaling_renderablesscaling_panelerror_panelr   error_tablecolorr   r.   r.   r/   rd      s   	

&








 

 $sessionsz!List active sessions for an agent)hiddenz6Name of the agent to list sessions for e.g. 'my-agent'F)r   show_defaultz--idz-izSession ID to filter byz!Organization to list sessions for
session_idc           +         s4  |pt d}|s| r| jr| j}n
td tdS |rttjd| dddm}t	j
||||dI d H \}}|  |rNt W  d    S |sdtd	| d
 t W  d    S t|d|dppd}|dd}	|dr|	dkrdnd}
nd}
d|d  d|
 |	r|	dkrd|	 dnd d| dt|d d|drt|dnd |dd urd|d dnd d!|d"rd#nd$ g}|d%}|r~|d&g }|d'd(}t|d)kr|d* d+d(|d( d+d( }| d}nd}|d |d,| d-| d. d/d0 |D }|r,t|nd}|d1d(}|d2d(}|d3| d4t| d5t|  d6d0 |D }|rZt|nd}t|d7d(}t|d8d(}|d9| d4t| d5t|  ttd:|d;| d<| d=d>d? 	 W d    d S 1 sw   Y  ttjd@| ddd}t	j|||dAI d H \}}|  |rt W  d    S |stdB| dC t W  d    S |dDg }t|}dEd0 |D }g }|D ]7}z*d(dFlm} ||d dGdH}||d dGdH} | |  }!||! W q ty5   Y qw dId0 |D }"t|"}#t|}$tdJdK |D }%g }&|$r|#r|d(kr|%| dL }'tdM| dNdOdPtdQ|$d( dRdS|$d dRdT|$d) dRdUdOdPtdV|#d( dRdS|#d dRdT|#d) dRdUdOdPtdW|% dX| dY|'dRdZdOdPg}&tdOdOd[t j!d\}(|("d] |("d^ |("d_ |("d` |("da |("db |("dc |dDg D ]}|r|d |krqt|d |d pd}|dd}	|d r|	dkrd}
nd}
nd}
|d" dOu })|)rddnd |d t|d |d r0t|d nd||
|d d urA|d  dnd|d" dOu rKd#n
|d" deu rTd$ndg}*|)rc fdfd0|*D }*|(j#|*  qtjt$|&ry|syt%|&dOdgnd|(dh| di| d=dj W d    d S 1 sw   Y  d S )kNrK   No target agent name providedr#   z[dim]Looking up session 'z'[/dim]rN   rO   )ro   r   rK   rr   	Session 'z' not foundr\   endedAtrw   completionStatusr"   500z[red]Error (500)[/red]Completez[yellow]Active[/yellow]z[bold]Session ID:[/bold] 	sessionIdz[bold]Status:[/bold] z ()z[bold]Duration:[/bold] z[bold]Created:[/bold] z[bold]Ended:[/bold] z[dim]N/A[/dim]botStartSecondsz[bold]Bot Start:[/bold] sz&[bold]Bot Start:[/bold] [dim]N/A[/dim]z[bold]Cold Start:[/bold] 	coldStartz[red]Yes[/red]NoresourceMetrics
timeseriessampleCountr      tz[bold]Resource Metrics[/bold] (z samples over z):c                 S      g | ]}| d dqS )cr   r`   r(   r   r.   r.   r/   
<listcomp>      zsessions.<locals>.<listcomp>cpuMillicoresP50cpuMillicoresP99z
  CPU:    z  p50: z  p99: c                 S   r   )mr   r   r   r.   r.   r/   r     r   memoryBytesP50memoryBytesP99z
  Memory: 
z Session details for agent [bold]z[/bold] [dim](z)[/dim]r   r^   r   z![dim]Looking up agent with name 'rq   z+No session data found for agent with name 'rs   r   c                 S   s   g | ]	}| d r|qS )r   r   r   r.   r.   r/   r     s    )datetimeZz+00:00c                 S   s"   g | ]}| d dur|d  qS )r   Nr   r   r.   r.   r/   r     s    c                 s   s"    | ]}| d du rdV  qdS )r   Tr#   Nr   r   r.   r.   r/   r0     s     zsessions.<locals>.<genexpr>d   z[bold]Total Sessions:[/bold]
z
 Tr   z[bold]Average Duration:[/bold]
r@   zs
[dim](p5: zs, p95: zs)[/dim]z[bold]Bot Start Time:[/bold]
z[bold]Cold Starts:[/bold]
/z
[dim](z%)[/dim]rQ   rR   z
Session IDrW   zEnded AtDurationStatuszBot Start Timez
Cold Startzon redFc                    s   g | ]}d   d| dqS )r   ]r   r.   )r(   cell	row_styler.   r/   r     s    )equalzSession data for agent z [dim]()r^   )&r   r`   ro   r   rf   rb   rc   r   rd   r   agent_sessionr   r   r   r1   r3   r>   rG   r'   rE   rj   r	   r6   agent_sessionsr   fromisoformatreplacetotal_secondsBaseExceptionr   r4   r
   r   rg   rh   ri   r   r   )+deploy_configro   r   rI   rK   rr   rl   rf   session_durationrd   status_display
info_linesmetricsr   sample_countts_durationts_duration_str
cpu_values	cpu_sparkcpu_p50cpu_p99
mem_values	mem_sparkmem_p50mem_p99sessions_listtotal_sessionscompleted_sessions	durationssessionr   
created_atended_atduration_secondsbot_start_timesbot_start_metricsduration_metricscold_starts_countmetric_renderablescold_start_percentrm   is_cold_startrow_datar.   r   r/   r   2  sd  



 
 
"R

((









$r-   z"Modify agent runtime configurationc                      s   t d d S )NzNot implemented)r   rf   r.   r.   r.   r/   r-      s   c                   @   s   e Zd ZdZdZdS )	LogFormatTEXTJSONN)__name__
__module____qualname__r  r  r.   r.   r.   r/   r   '  s    r   c                   @       e Zd ZdZdZdZdZdZdS )LogLevelDEBUGINFOWARNINGERRORCRITICALNr  r  r  r  r	  r
  r  r  r.   r.   r.   r/   r  ,      r  c                   @   r  )LogLevelColorsbluer   r   r   zbold redNr  r.   r.   r.   r/   r  4  r  r  logszGet logs for the given agent.z--levelz-lzLevel of logs to getz--formatz-fzLogs formatr   z--limitz-nzNumber of logs to getz--deploymentz-dzFilter logs by deployment IDz--session-idz-szFilter logs by session IDlevelformatlimitdeployment_idc                    s  |pt d}d}|rd| d}|rd| d}tjd| d|  d|r(|jnd	 d
dd/ tj| ||||dI d H \}	}
|	rG|	dsXtd t	dW  d    S W d    n1 sbw   Y  |	d D ]h}|dd}|rt
|dd}tj}tD ]}|j| v r|} nq|r|j|jkrqk|tjkrtt|tjj}tjt|dddd tt||d qk|tjkr||d}tttj|dddd qkd S )NrK   r   zdeployment (r   z	session (z[dim]Fetching logs for z	: [bold]'z#'[/bold] with severity: [bold cyan]ALLz[/bold cyan][/dim]rN   rO   )ro   rK   r  r  r   r  z"[dim]No logs found for agent[/dim]r#   logr"   	timestampzbold dim)style )r;   )r  r  F)ensure_asciigray)r   r`   r   rd   valuer   
agent_logsra   rb   rc   r   r  r	  upperr   r  getattrr  r  r   r  jsondumps)ro   rI   r  r  r  r  r   rK   status_textrl   rf   r  log_datar  severitylog_severityr   liner.   r.   r/   r  <  sZ    



deletezDelete an agent.z!Organization to delete agent fromz--forcezBypass prompt for confirmationforcec                    s   |pt d}|std I d H std tdS tj	d|  dddF t
j| |d	I d H \}}|rDtdW  d    S |s^td
|  d| d tdW  d    S td
|  d W d    d S 1 srw   Y  d S )NrK   zAre you sure you want to delete this agent? Note: active sessions will not be interrupted and will continue to run until completion.z$[bold]Aborting delete request[/bold]r#   z[dim]Deleting agent: [bold]'rM   rN   rO   )ro   rK   Agent 'z)' not found in namespace / organization 'rs   z' deleted successfully)r   r`   questionaryconfirm	ask_asyncr   ra   rb   rc   rd   r   agent_deleterf   rj   )ro   rI   r)  rK   rl   rf   r.   r.   r/   r(  z  s*   


"deploymentszGet deployments for an agent.z#Organization to get deployments forc                    s  t d}|pt d}d }ztjd|  ddd t 4 I d H #}|jtdj|| d d	d
| idI d H }W d   I d H  n1 I d H sMw   Y  |jdkr`t	|j}|
  | I d H }tdddtjd}|d |d |d |d |d |d D ])}	|	di di }
||	dd|
dd|
dd|	dd|	dd qtt|d|  dd d! W d    W d S 1 sw   Y  W d S  ty } zt| t|d"|   W Y d }~d S d }~ww )#NtokenrK   z,[dim]Fetching deployments for agent: [bold]'rM   rN   rO   services_deployments_path)rK   rn   AuthorizationzBearer )headers   TrQ   rR   IDz	Node TypeImagerW   rX   r/  ry   rz   rZ   rw   dailyNodeTyper{   r\   r]   z[bold]Deployments for agent: rY   r   r   zUnable to get deployments for )r   r`   r   rd   aiohttpClientSessionr   construct_api_urlr  r   raise_for_statusr!  r
   r   rg   rh   ri   ra   r	   	Exceptionr   r   	api_error)ro   rI   r0  rK   
error_coder   responserl   rm   rx   rz   er.   r.   r/   r/    sh   

(












&,
 r:   zStart an agent instancez*Name of the agent to start e.g. 'my-agent'zStart Configuration)r   rich_help_panelz	--api-keyz-kz(Public API key to use for starting agentz--dataz,Data to pass to the agent (stringified JSON)z--use-dailyz-Dz+Create a Daily WebRTC session for the agentz--daily-propertiesz-pz(Daily room properties (stringified JSON)z'Organization which the agent belongs toapi_keyrl   	use_dailydaily_propertiesc                    s^  |pt d}|pt d}	|rdnt d}
| pt }|s0|j}|s.td tdS |}|	sItt	dt
 dt
 d	d
ddd tdS |r|rzt| W n+ tjy } ztd|  tdt| d tdW  Y d }~S d }~ww |s|pd}|rt|dkr|d d d }tt	d| d|
 d|	 d| d| d| d| dddd td I d H std tdS ttjdd d!d"d#}tj|||d$I d H \}}|r|d% s
|  td&| d't
 d(| d) tdW  d    S |tjd*| d+d d! tj||	||||d,I d H \}}|r;|  tdW  d    S |  td&| d- |rvt|trv|d.}|d/}|rv| d0| }td1 td2| d3| d4 t|tr|d5}|rtd6|  W d    d S W d    d S W d    d S 1 sw   Y  d S )7NrK   default_public_keyzCLI provideddefault_public_key_namer   r#   zwNo public API key provided. Please provide a public API key using the --api-key flag or set a default using [bold cyan]zx organizations keys use[/bold cyan].

If you have not yet created a public API key, you can do so by running [bold cyan]z' organizations keys create[/bold cyan].zPublic API Key Requiredr   r   r   z/Invalid JSON format for Daily room properties: z[dim]JSON error: rp   NoneP   M   z...Agent Name: z
Public API Key: z [dim]z[/dim]
Use Daily: z
Daily Properties: z
Data: z[bold]Start Request for agent: rY   z@Are you sure you want to start an active session for this agent?z#[bold]Aborting start request[/bold]z#[dim]Checking agent health...[/dim]rN   rO   r$   )refresh_per_secondrq   r   r*  z]' does not exist or is not in a healthy state. Please check the agent status with [bold cyan]z agent status r   z[dim]Agent 'z,' is healthy, sending start request...[/dim])ro   rB  rC  rl   rD  rr   z' started successfully	dailyRoom
dailyTokenz?t=z.
Join your session by visiting the link below:z[link=r   z[/link]r   
Session ID: )r   r`   r   ro   r   rf   rb   rc   ra   r	   r   r!  loadsJSONDecodeErrorr   r1   r+  r,  r-  r   rd   r   r   r   updatestart_agentrj   r   r   )r   ro   r)  rB  rl   rC  rD  rI   rK   default_public_api_keydefault_public_api_key_namepartial_configdefault_agent_namer@  daily_props_displayrr   health_datarf   
daily_roomdaily_tokenurlr   r.   r.   r/   r:     s   1








	 



,.$r   zStop an active agent sessionz!Name of the agent e.g. 'my-agent'.zID of the session to stopc           	         s  |pt d}| pt }|s"|r|jr|j}n
td tdS |sItt	d| d| dddd	 t
d
 I d H sItd tdS tjd| d| ddd- tj|||dI d H \}}|rstdW  d    S td| d W d    d S 1 sw   Y  d S )NrK   r   r#   rJ  rN  z[bold]Stop Session[/bold]r   r   r   z+Are you sure you want to stop this session?z"[bold]Aborting stop request[/bold]z[dim]Stopping session [bold]'z'[/bold] for agent [bold]'rM   rN   rO   )ro   r   rK   r   z' stopped successfully)r   r`   r   ro   r   rf   rb   rc   ra   r	   r+  r,  r-  rd   r   agent_session_terminaterj   )	r   ro   r   rI   r)  rK   rU  rl   rf   r.   r.   r/   r     s@   





")r   )Ir!  enumr   typingr   r8  r+  rb   logurur   richr   rich.columnsr   rich.consoler   	rich.liver   
rich.panelr	   
rich.tabler
   	rich.textr   pipecatcloud._utils.async_utilsr   pipecatcloud._utils.auth_utilsr   !pipecatcloud._utils.console_utilsr   r   r   r    pipecatcloud._utils.deploy_utilsr   r   pipecatcloud._utils.regionsr   r   pipecatcloud.clir   pipecatcloud.cli.apir   pipecatcloud.cli.configr   pipecatcloud.constantsr   Typer	agent_clirH   r'   floatr   r>   rE   rG   commandcreate_blockingOptionArgumentrd   r   r-   r   r  r  r  r  r   r(  r/  r:   r   r.   r.   r.   r/   <module>   s   <
  k;%@
& #	