-
-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement gptme-util CLI for utilities #261
Changes from 5 commits
3a2573d
2af94f8
d73de53
cd8ef84
6cca401
ede4361
d92f291
20878dc
66ea9f8
c8e328d
d060108
1aa576a
7edb198
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
files = ["README.md", "Makefile"] | ||
files = ["README.md", "Makefile", "gptme/chat.py"] | ||
#files = ["README.md", "Makefile", "gptme/cli.py", "docs/*.rst", "docs/*.md"] | ||
ErikBjare marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
""" | ||
CLI for gptme utility commands. | ||
""" | ||
|
||
import sys | ||
import click | ||
|
||
from ..message import Message | ||
|
||
|
||
@click.group() | ||
def main(): | ||
"""Utility commands for gptme.""" | ||
pass | ||
|
||
|
||
@main.group() | ||
def chats(): | ||
"""Commands for managing chat logs.""" | ||
pass | ||
|
||
|
||
@chats.command("ls") | ||
@click.option("-n", "--limit", default=20, help="Maximum number of chats to show.") | ||
def chats_list(limit: int): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is good feedback |
||
"""List conversation logs.""" | ||
from ..logmanager import list_conversations, format_conversation | ||
|
||
conversations, found = list_conversations(limit) | ||
if not found: | ||
print("No conversations found.") | ||
return | ||
|
||
for conv in conversations: | ||
print(format_conversation(conv)) | ||
|
||
|
||
@chats.command("read") | ||
@click.argument("name") | ||
def chats_read(name: str): | ||
"""Read a specific chat log.""" | ||
from ..logmanager import LogManager | ||
from ..dirs import get_logs_dir | ||
from pathlib import Path | ||
|
||
logdir = Path(get_logs_dir()) / name | ||
if not logdir.exists(): | ||
print(f"Chat '{name}' not found") | ||
return | ||
|
||
log = LogManager.load(logdir) | ||
for msg in log.log: | ||
if isinstance(msg, Message): | ||
print(f"{msg.role}: {msg.content}") | ||
|
||
|
||
@main.group() | ||
def tokens(): | ||
"""Commands for token counting.""" | ||
pass | ||
|
||
|
||
@tokens.command("count") | ||
@click.argument("text", required=False) | ||
@click.option("-m", "--model", default="gpt-4", help="Model to use for token counting.") | ||
@click.option( | ||
"-f", "--file", type=click.Path(exists=True), help="File to count tokens in." | ||
) | ||
def tokens_count(text: str | None, model: str, file: str | None): | ||
"""Count tokens in text or file.""" | ||
import tiktoken | ||
|
||
# Get text from file if specified | ||
if file: | ||
with open(file) as f: | ||
text = f.read() | ||
elif not text and not sys.stdin.isatty(): | ||
text = sys.stdin.read() | ||
elif not text: | ||
print("Error: No text provided. Use --file or pipe text to stdin.") | ||
return | ||
|
||
# Validate model | ||
try: | ||
enc = tiktoken.encoding_for_model(model) | ||
except KeyError: | ||
print(f"Error: Model '{model}' not supported by tiktoken.") | ||
print("Supported models include: gpt-4, gpt-3.5-turbo, text-davinci-003") | ||
return 1 | ||
|
||
# Count tokens | ||
tokens = enc.encode(text) | ||
print(f"Token count ({model}): {len(tokens)}") | ||
|
||
|
||
@main.group() | ||
def context(): | ||
"""Commands for context generation.""" | ||
pass | ||
|
||
|
||
@context.command("generate") | ||
@click.argument("path", type=click.Path(exists=True)) | ||
def context_generate(path: str): | ||
"""Generate context from a directory.""" | ||
from ..context import generate_context | ||
|
||
ctx = generate_context(path) | ||
print(ctx) | ||
|
||
|
||
@main.group() | ||
def tools(): | ||
"""Tool-related utilities.""" | ||
pass | ||
|
||
|
||
@tools.command("list") | ||
@click.option( | ||
"--available/--all", default=True, help="Show only available tools or all tools" | ||
) | ||
@click.option("--langtags", is_flag=True, help="Show language tags for code execution") | ||
def tools_list(available: bool, langtags: bool): | ||
"""List available tools.""" | ||
from ..tools import loaded_tools, init_tools | ||
from ..commands import _gen_help | ||
|
||
# Initialize tools | ||
init_tools() | ||
|
||
if langtags: | ||
# Show language tags using existing help generator | ||
for line in _gen_help(incl_langtags=True): | ||
if line.startswith("Supported langtags:"): | ||
print("\nSupported language tags:") | ||
continue | ||
if line.startswith(" - "): | ||
print(line) | ||
return | ||
|
||
print("Available tools:") | ||
for tool in loaded_tools: | ||
if not available or tool.available: | ||
status = "✓" if tool.available else "✗" | ||
print(f""" | ||
{status} {tool.name} | ||
{tool.desc}""") | ||
|
||
|
||
@tools.command("info") | ||
@click.argument("tool_name") | ||
def tools_info(tool_name: str): | ||
"""Show detailed information about a tool.""" | ||
from ..tools import loaded_tools, get_tool, init_tools | ||
|
||
# Initialize tools | ||
init_tools() | ||
|
||
tool = get_tool(tool_name) | ||
if not tool: | ||
print(f"Tool '{tool_name}' not found. Available tools:") | ||
for t in loaded_tools: | ||
print(f"- {t.name}") | ||
return | ||
|
||
print(f"Tool: {tool.name}") | ||
print(f"Description: {tool.desc}") | ||
print(f"Available: {'Yes' if tool.available else 'No'}") | ||
print("\nInstructions:") | ||
print(tool.instructions) | ||
if tool.examples: | ||
print("\nExamples:") | ||
print(tool.examples) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mistakenly committed