Skip to content

Commit

Permalink
feat(cli): Add tools app
Browse files Browse the repository at this point in the history
  • Loading branch information
HamadaSalhab committed Jan 30, 2025
1 parent 833f651 commit 37c8f53
Showing 1 changed file with 132 additions and 27 deletions.
159 changes: 132 additions & 27 deletions cli/julep_cli/tools.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import json
from pathlib import Path
from typing import Annotated

import typer
import yaml

from .app import tools_app
from .utils import get_julep_client

from .app import tools_app, console, error_console

from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.text import Text
from rich.table import Table
from rich.box import HEAVY_HEAD


@tools_app.command()
Expand All @@ -29,12 +38,35 @@ def create(
Requires either a definition file or direct parameters. If both are provided,
command-line options override values from the definition file.
"""
# TODO: Implement actual API call
typer.echo(f"Created tool '{name}' for agent '{agent_id}'")

client = get_julep_client()

tool_yaml_contents = yaml.safe_load(Path(definition).read_text())

if name:
tool_yaml_contents["name"] = name

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient=True,
) as progress:
try:
create_tool_task = progress.add_task(description="Creating tool", total=None)
progress.start_task(create_tool_task)
tool = client.agents.tools.create(agent_id=agent_id, **tool_yaml_contents)
except Exception as e:
error_console.print(f"Error creating tool: {e}")
raise typer.Exit(1)

console.print(Text(f"Tool created successfully. Tool ID: {tool.id}", style="bold green"))


@tools_app.command()
def update(
agent_id: Annotated[
str, typer.Option("--agent-id", "-a", help="ID of the agent the tool is associated with")
],
tool_id: Annotated[str, typer.Option("--id", help="ID of the tool to update")],
definition: Annotated[
str | None,
Expand All @@ -51,12 +83,44 @@ def update(
Updates can be made using either a definition file or direct parameters.
If both are provided, command-line options override values from the definition file.
"""
# TODO: Implement actual API call
typer.echo(f"Updated tool '{tool_id}'")

client = get_julep_client()


if definition:
tool_yaml_contents = yaml.safe_load(Path(definition).read_text())
else:
tool_yaml_contents = {}

if name:
tool_yaml_contents["name"] = name

if not tool_yaml_contents:
error_console.print("Error: No tool name or definition provided", style="bold red")
raise typer.Exit(1)

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient=True,
console=console
) as progress:
try:
update_tool_task = progress.add_task("Updating tool...", start=False)
progress.start_task(update_tool_task)

client.agents.tools.update(agent_id=agent_id, tool_id=tool_id, **tool_yaml_contents)
except Exception as e:
error_console.print(f"Error updating tool: {e}", style="bold red")
raise typer.Exit(1)

console.print(Text(f"Tool updated successfully.", style="bold green"))

@tools_app.command()
def delete(
agent_id: Annotated[
str, typer.Option("--agent-id", "-a", help="ID of the agent the tool is associated with")
],
tool_id: Annotated[str, typer.Option("--id", help="ID of the tool to delete")],
force: Annotated[
bool,
Expand All @@ -69,24 +133,39 @@ def delete(
By default, prompts for confirmation unless --force is specified.
"""

if not force:
confirm = typer.confirm(f"Are you sure you want to delete tool '{tool_id}'?")
if not confirm:
typer.echo("Operation cancelled")
return
confirm = typer.confirm(
f"Are you sure you want to delete tool '{tool_id}'?")
if not confirm:
typer.echo("Operation cancelled")
return

client = get_julep_client()

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
transient=True,
console=console
) as progress:
try:
delete_tool_task = progress.add_task("Deleting tool...", start=False)
progress.start_task(delete_tool_task)

# TODO: Implement actual API call
typer.echo(f"Deleted tool '{tool_id}'")
client.agents.tools.delete(agent_id=agent_id, tool_id=tool_id)
except Exception as e:
error_console.print(f"Error deleting tool: {e}", style="bold red")
raise typer.Exit(1)

console.print(Text(f"Tool deleted successfully.", style="bold green"))


@tools_app.command()
def list(
agent_id: Annotated[
str | None, typer.Option("--agent-id", "-a", help="Filter tools by associated agent ID")
] = None,
task_id: Annotated[
str | None, typer.Option("--task-id", "-t", help="Filter tools by associated task ID")
] = None,
json_output: Annotated[
bool, typer.Option("--json", help="Output the list in JSON format")
] = False,
Expand All @@ -95,24 +174,50 @@ def list(
Either --agent-id or --task-id must be provided to filter the tools list.
"""
if not agent_id and not task_id:
typer.echo("Error: Either --agent-id or --task-id must be provided", err=True)
if not agent_id:
typer.echo("Error: --agent-id must be provided", err=True)
raise typer.Exit(1)

# TODO: Implement actual API call
# Mock data for demonstration
tools = [
{"id": "tool1", "name": "Web Search", "agent_id": "agent1"},
{"id": "tool2", "name": "API Call", "agent_id": "agent2"},
]
client = get_julep_client()

with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
console=console
) as progress:
try:
list_tools_task = progress.add_task("Listing tools...", start=False)
progress.start_task(list_tools_task)

tools = client.agents.tools.list(agent_id=agent_id)
except Exception as e:
error_console.print(f"Error listing tools: {e}", style="bold red")
raise typer.Exit(1)

if json_output:
typer.echo(json.dumps(tools, indent=2))
return

# Table format output
typer.echo("Available tools:")
typer.echo("ID\tName\tAgent ID")
typer.echo("-" * 40)
tools_table = Table(
title=Text("Available Tools:", style="bold underline magenta"),
box=HEAVY_HEAD, # border between cells
show_lines=True, # Adds lines between rows
show_header=True,
header_style="bold magenta",
width=130
)

tools_table.add_column("ID", style="green")
tools_table.add_column("Name", style="cyan")
tools_table.add_column("Type", style="yellow")
tools_table.add_column("Description", style="yellow")

for tool in tools:
typer.echo(f"{tool['id']}\t{tool['name']}\t{tool['agent_id']}")
tools_table.add_row(
tool.id,
tool.name,
tool.type,
tool.description
)

console.print(tools_table)

0 comments on commit 37c8f53

Please sign in to comment.