Skip to content

Commit 62c87f5

Browse files
feat: add delete operations and envs update to managed CLI
Adds missing CRUD operations for managed agents CLI parity: βœ… New Commands Added: - praisonai managed sessions delete <session_id> [--yes/-y] - praisonai managed agents delete <agent_id> [--yes/-y] - praisonai managed envs update <env_id> [--packages ...] [--networking ...] - praisonai managed envs delete <env_id> [--yes/-y] βœ… Key Features: - Confirmation prompts: All destructive operations ask for confirmation - Skip flag: --yes/-y flag bypasses confirmation prompts - Pattern consistency: Follows existing code patterns in managed.py - Error handling: Proper exception handling and user feedback - Comprehensive tests: Unit tests using typer.testing.CliRunner πŸ“ Files Modified: - src/praisonai/praisonai/cli/commands/managed.py - Added 4 CLI commands - src/praisonai/tests/unit/cli/test_managed_cli_destructive.py - Comprehensive test suite Fixes #1430 Co-authored-by: Mervin Praison <MervinPraison@users.noreply.github.com>
1 parent af1fab4 commit 62c87f5

File tree

2 files changed

+476
-0
lines changed

2 files changed

+476
-0
lines changed

β€Žsrc/praisonai/praisonai/cli/commands/managed.pyβ€Ž

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,32 @@ def sessions_resume(
316316
print(result)
317317

318318

319+
@sessions_app.command("delete")
320+
def sessions_delete(
321+
session_id: str = typer.Argument(..., help="Session ID to delete (sesn_01...)"),
322+
yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt"),
323+
):
324+
"""Delete a session.
325+
326+
Example:
327+
praisonai managed sessions delete sesn_01AbCdEf
328+
praisonai managed sessions delete sesn_01AbCdEf --yes
329+
"""
330+
if not yes:
331+
confirm = typer.confirm(f"Delete session {session_id}?")
332+
if not confirm:
333+
typer.echo("Cancelled.")
334+
raise typer.Exit(0)
335+
336+
client = _get_client()
337+
try:
338+
client.beta.sessions.delete(session_id)
339+
typer.echo(f"Deleted session: {session_id}")
340+
except Exception as e:
341+
typer.echo(f"Error deleting session: {e}")
342+
raise typer.Exit(1)
343+
344+
319345
# ─────────────────────────────────────────────────────────────────────────────
320346
# agents sub-commands
321347
# ─────────────────────────────────────────────────────────────────────────────
@@ -397,6 +423,32 @@ def agents_update(
397423
typer.echo(f"Updated agent: {updated.id} (v{getattr(updated,'version','')})")
398424

399425

426+
@agents_app.command("delete")
427+
def agents_delete(
428+
agent_id: str = typer.Argument(..., help="Agent ID to delete (agent_01...)"),
429+
yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt"),
430+
):
431+
"""Delete an agent.
432+
433+
Example:
434+
praisonai managed agents delete agent_01AbCdEf
435+
praisonai managed agents delete agent_01AbCdEf --yes
436+
"""
437+
if not yes:
438+
confirm = typer.confirm(f"Delete agent {agent_id}?")
439+
if not confirm:
440+
typer.echo("Cancelled.")
441+
raise typer.Exit(0)
442+
443+
client = _get_client()
444+
try:
445+
client.beta.agents.delete(agent_id)
446+
typer.echo(f"Deleted agent: {agent_id}")
447+
except Exception as e:
448+
typer.echo(f"Error deleting agent: {e}")
449+
raise typer.Exit(1)
450+
451+
400452
# ─────────────────────────────────────────────────────────────────────────────
401453
# envs sub-commands
402454
# ─────────────────────────────────────────────────────────────────────────────
@@ -441,6 +493,71 @@ def envs_get(
441493
typer.echo(f"Config: {cfg}")
442494

443495

496+
@envs_app.command("update")
497+
def envs_update(
498+
env_id: str = typer.Argument(..., help="Environment ID (env_01...)"),
499+
packages: Optional[str] = typer.Option(None, "--packages", "-p", help="Comma-separated pip packages to install"),
500+
networking: Optional[str] = typer.Option(None, "--networking", help="Networking configuration (limited/unrestricted)"),
501+
):
502+
"""Update an environment's packages or networking configuration.
503+
504+
Example:
505+
praisonai managed envs update env_01AbCdEf --packages "pandas,numpy"
506+
praisonai managed envs update env_01AbCdEf --networking limited
507+
"""
508+
client = _get_client()
509+
kwargs = {}
510+
511+
# Handle packages
512+
if packages:
513+
package_list = [p.strip() for p in packages.split(",")]
514+
kwargs["packages"] = {"pip": package_list}
515+
516+
# Handle networking
517+
if networking:
518+
if networking.lower() not in ["limited", "unrestricted"]:
519+
typer.echo("Error: networking must be 'limited' or 'unrestricted'")
520+
raise typer.Exit(1)
521+
kwargs["networking"] = {"type": networking.lower()}
522+
523+
if not kwargs:
524+
typer.echo("Nothing to update. Pass --packages or --networking.")
525+
raise typer.Exit(0)
526+
527+
try:
528+
updated = client.beta.environments.update(env_id, **kwargs)
529+
typer.echo(f"Updated environment: {updated.id}")
530+
except Exception as e:
531+
typer.echo(f"Error updating environment: {e}")
532+
raise typer.Exit(1)
533+
534+
535+
@envs_app.command("delete")
536+
def envs_delete(
537+
env_id: str = typer.Argument(..., help="Environment ID to delete (env_01...)"),
538+
yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt"),
539+
):
540+
"""Delete an environment.
541+
542+
Example:
543+
praisonai managed envs delete env_01AbCdEf
544+
praisonai managed envs delete env_01AbCdEf --yes
545+
"""
546+
if not yes:
547+
confirm = typer.confirm(f"Delete environment {env_id}?")
548+
if not confirm:
549+
typer.echo("Cancelled.")
550+
raise typer.Exit(0)
551+
552+
client = _get_client()
553+
try:
554+
client.beta.environments.delete(env_id)
555+
typer.echo(f"Deleted environment: {env_id}")
556+
except Exception as e:
557+
typer.echo(f"Error deleting environment: {e}")
558+
raise typer.Exit(1)
559+
560+
444561
# ─────────────────────────────────────────────────────────────────────────────
445562
# ids sub-commands (save / restore / show β€” no Anthropic IDs are user-defined)
446563
# ─────────────────────────────────────────────────────────────────────────────

0 commit comments

Comments
Β (0)