153 lines
4.5 KiB
Python
153 lines
4.5 KiB
Python
"""Prompt management CLI commands."""
|
|
|
|
from datetime import datetime
|
|
from typing import Optional
|
|
|
|
import click
|
|
|
|
from ..models import Prompt
|
|
from ..storage import PromptStorage
|
|
|
|
|
|
@click.group()
|
|
def prompt_cmd():
|
|
"""Manage prompts."""
|
|
pass
|
|
|
|
|
|
@prompt_cmd.command("create")
|
|
@click.argument("name")
|
|
@click.option("--template", "-t", required=True, help="Prompt template string")
|
|
@click.option("--description", "-d", default="", help="Prompt description")
|
|
@click.option("--tag", multiple=True, help="Tags to add to the prompt")
|
|
@click.option("--variable", "-v", multiple=True, help="Variables as name:description:required")
|
|
@click.option("--provider", default="", help="LLM provider (ollama, lmstudio)")
|
|
@click.option("--model", default="", help="Model name")
|
|
@click.option("--dir", "prompt_dir", default=None, help="Prompt directory")
|
|
def create_prompt(
|
|
name: str,
|
|
template: str,
|
|
description: str,
|
|
tag: tuple,
|
|
variable: tuple,
|
|
provider: str,
|
|
model: str,
|
|
prompt_dir: Optional[str]
|
|
):
|
|
"""Create a new prompt."""
|
|
storage = PromptStorage(prompt_dir)
|
|
|
|
if storage.prompt_exists(name):
|
|
click.echo(f"Error: Prompt '{name}' already exists", err=True)
|
|
return
|
|
|
|
variables = []
|
|
for v in variable:
|
|
if ":" in v:
|
|
parts = v.split(":", 2)
|
|
var_dict = {
|
|
"name": parts[0].strip(),
|
|
"description": parts[1].strip() if len(parts) > 1 else "",
|
|
"required": len(parts) < 3 or parts[2].strip().lower() != "false"
|
|
}
|
|
variables.append(var_dict)
|
|
|
|
prompt = Prompt(
|
|
name=name,
|
|
template=template,
|
|
description=description,
|
|
tags=list(tag),
|
|
variables=variables,
|
|
provider=provider,
|
|
model=model,
|
|
created_at=datetime.now().isoformat(),
|
|
updated_at=datetime.now().isoformat(),
|
|
)
|
|
|
|
storage.save_prompt(prompt)
|
|
|
|
for t in tag:
|
|
storage.add_tag_to_prompt(name, t)
|
|
|
|
click.echo(f"Created prompt: {name}")
|
|
|
|
|
|
@prompt_cmd.command("list")
|
|
@click.option("--tag", "-t", default=None, help="Filter by tag")
|
|
@click.option("--dir", "prompt_dir", default=None, help="Prompt directory")
|
|
def list_prompts(tag: Optional[str], prompt_dir: Optional[str]):
|
|
"""List all prompts."""
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
|
|
storage = PromptStorage(prompt_dir)
|
|
|
|
if tag:
|
|
prompts = storage.get_prompts_by_tag(tag)
|
|
else:
|
|
prompt_names = storage.list_prompts()
|
|
prompts = [storage.get_prompt(n) for n in prompt_names]
|
|
|
|
table = Table(title="Prompts")
|
|
table.add_column("Name", style="cyan")
|
|
table.add_column("Tags", style="magenta")
|
|
table.add_column("Description", style="green")
|
|
|
|
for prompt in prompts:
|
|
tags_str = ", ".join(prompt.tags) if prompt.tags else "-"
|
|
desc = prompt.description[:50] + "..." if len(prompt.description) > 50 else prompt.description
|
|
table.add_row(prompt.name, tags_str, desc)
|
|
|
|
console = Console()
|
|
console.print(table)
|
|
|
|
|
|
@prompt_cmd.command("show")
|
|
@click.argument("name")
|
|
@click.option("--dir", "prompt_dir", default=None, help="Prompt directory")
|
|
def show_prompt(name: str, prompt_dir: Optional[str]):
|
|
"""Show prompt details."""
|
|
from rich.console import Console
|
|
from rich.panel import Panel
|
|
|
|
storage = PromptStorage(prompt_dir)
|
|
prompt = storage.get_prompt(name)
|
|
|
|
if not prompt:
|
|
click.echo(f"Error: Prompt '{name}' not found", err=True)
|
|
return
|
|
|
|
content = f"""Name: {prompt.name}
|
|
Description: {prompt.description}
|
|
Tags: {', '.join(prompt.tags) if prompt.tags else 'None'}
|
|
Variables: {', '.join(prompt.get_required_variables()) if prompt.get_required_variables() else 'None'}
|
|
Provider: {prompt.provider or 'Default'}
|
|
Model: {prompt.model or 'Default'}
|
|
|
|
Template:
|
|
{prompt.template}
|
|
"""
|
|
|
|
console = Console()
|
|
console.print(Panel(content, title=f"Prompt: {name}"))
|
|
|
|
|
|
@prompt_cmd.command("delete")
|
|
@click.argument("name")
|
|
@click.option("--force", "-f", is_flag=True, help="Skip confirmation")
|
|
@click.option("--dir", "prompt_dir", default=None, help="Prompt directory")
|
|
def delete_prompt(name: str, force: bool, prompt_dir: Optional[str]):
|
|
"""Delete a prompt."""
|
|
storage = PromptStorage(prompt_dir)
|
|
|
|
if not storage.prompt_exists(name):
|
|
click.echo(f"Error: Prompt '{name}' not found", err=True)
|
|
return
|
|
|
|
if not force:
|
|
if not click.confirm(f"Delete prompt '{name}'?"):
|
|
return
|
|
|
|
storage.delete_prompt(name)
|
|
click.echo(f"Deleted prompt: {name}")
|