Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ jobs:
command: |
poetry install
- run:
name: Run Pylint
name: Run linter
command: |
poetry run pylint devchat tests
make check
- run:
name: Run Pytest
command: |
Expand Down
3 changes: 0 additions & 3 deletions .flake8

This file was deleted.

31 changes: 31 additions & 0 deletions .github/workflows/dev.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Dev

on:
pull_request:
branches: [main]
push:
branches: [main]

jobs:
lint-and-test:
name: Run linter and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: "3.8"
- uses: abatilo/actions-poetry@v2
- name: Install Python dependencies
run: |
poetry install

- name: Run linter
run: |
make check

- name: Run Pytest
run: |
poetry run pytest
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY_FOR_TEST }}
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "data/workflows"]
path = data/workflows
url = https://github.com/devchat-ai/workflows.git
17 changes: 0 additions & 17 deletions .pylintrc

This file was deleted.

17 changes: 17 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.PHONY: check fix

div = $(shell printf '=%.0s' {1..120})

DIR="."
check:
@echo ${div}
poetry run ruff check $(DIR)
poetry run ruff format $(DIR) --check
@echo "Done!"

fix:
@echo ${div}
poetry run ruff format $(DIR)
@echo ${div}
poetry run ruff check $(DIR) --fix
@echo "Done!"
1 change: 0 additions & 1 deletion data/workflows
Submodule workflows deleted from 32ebbc
15 changes: 8 additions & 7 deletions devchat/_cli/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import os

from .log import log
from .prompt import prompt
from .route import route
from .run import run
from .topic import topic
from .route import route

script_dir = os.path.dirname(os.path.realpath(__file__))
os.environ['TIKTOKEN_CACHE_DIR'] = os.path.join(script_dir, '..', 'tiktoken_cache')
os.environ["TIKTOKEN_CACHE_DIR"] = os.path.join(script_dir, "..", "tiktoken_cache")

__all__ = [
'log',
'prompt',
'run',
'topic',
'route',
"log",
"prompt",
"run",
"topic",
"route",
]
2 changes: 0 additions & 2 deletions devchat/_cli/errors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@


class MissContentInPromptException(Exception):
pass
33 changes: 19 additions & 14 deletions devchat/_cli/log.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# pylint: disable=import-outside-toplevel

import json
import sys
import time
from typing import Optional, List, Dict
from dataclasses import dataclass, field
from typing import Dict, List, Optional

import click


@dataclass
class PromptData:
model: str = "none"
Expand All @@ -19,28 +18,34 @@ class PromptData:
response_tokens: int = 0


@click.command(help='Process logs')
@click.option('--skip', default=0, help='Skip number prompts before showing the prompt history.')
@click.option('-n', '--max-count', default=1, help='Limit the number of commits to output.')
@click.option('-t', '--topic', 'topic_root', default=None,
help='Hash of the root prompt of the topic to select prompts from.')
@click.option('--insert', default=None, help='JSON string of the prompt to insert into the log.')
@click.option('--delete', default=None, help='Hash of the leaf prompt to delete from the log.')
@click.command(help="Process logs")
@click.option("--skip", default=0, help="Skip number prompts before showing the prompt history.")
@click.option("-n", "--max-count", default=1, help="Limit the number of commits to output.")
@click.option(
"-t",
"--topic",
"topic_root",
default=None,
help="Hash of the root prompt of the topic to select prompts from.",
)
@click.option("--insert", default=None, help="JSON string of the prompt to insert into the log.")
@click.option("--delete", default=None, help="Hash of the leaf prompt to delete from the log.")
def log(skip, max_count, topic_root, insert, delete):
"""
Manage the prompt history.
"""
from devchat._cli.utils import get_model_config, handle_errors, init_dir
from devchat.openai.openai_chat import OpenAIChat, OpenAIChatConfig, OpenAIPrompt

from devchat.store import Store
from devchat._cli.utils import handle_errors, init_dir, get_model_config
from devchat.utils import get_logger, get_user_info

logger = get_logger(__name__)

if (insert or delete) and (skip != 0 or max_count != 1 or topic_root is not None):
print("Error: The --insert or --delete option cannot be used with other options.",
file=sys.stderr)
print(
"Error: The --insert or --delete option cannot be used with other options.",
file=sys.stderr,
)
sys.exit(1)

repo_chat_dir, user_chat_dir = init_dir()
Expand Down
8 changes: 2 additions & 6 deletions devchat/_cli/main.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
"""
This module contains the main function for the DevChat CLI.
"""

import click

from devchat._cli import log, prompt, route, run, topic
from devchat.utils import get_logger
from devchat._cli import log
from devchat._cli import prompt
from devchat._cli import run
from devchat._cli import topic
from devchat._cli import route

from devchat.workflow.cli import workflow

logger = get_logger(__name__)
Expand Down
80 changes: 55 additions & 25 deletions devchat/_cli/prompt.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,61 @@
# pylint: disable=import-outside-toplevel
import sys
from typing import List, Optional

import click


@click.command(help='Interact with the large language model (LLM).')
@click.argument('content', required=False)
@click.option('-p', '--parent', help='Input the parent prompt hash to continue the conversation.')
@click.option('-r', '--reference', multiple=True,
help='Input one or more specific previous prompts to include in the current prompt.')
@click.option('-i', '--instruct', multiple=True,
help='Add one or more files to the prompt as instructions.')
@click.option('-c', '--context', multiple=True,
help='Add one or more files to the prompt as a context.')
@click.option('-m', '--model', help='Specify the model to use for the prompt.')
@click.option('--config', 'config_str',
help='Specify a JSON string to overwrite the default configuration for this prompt.')
@click.option('-f', '--functions', type=click.Path(exists=True),
help='Path to a JSON file with functions for the prompt.')
@click.option('-n', '--function-name',
help='Specify the function name when the content is the output of a function.')
@click.option('-ns', '--not-store', is_flag=True, default=False, required=False,
help='Do not save the conversation to the store.')
def prompt(content: Optional[str], parent: Optional[str], reference: Optional[List[str]],
instruct: Optional[List[str]], context: Optional[List[str]],
model: Optional[str], config_str: Optional[str] = None,
functions: Optional[str] = None, function_name: Optional[str] = None,
not_store: Optional[bool] = False):
@click.command(help="Interact with the large language model (LLM).")
@click.argument("content", required=False)
@click.option("-p", "--parent", help="Input the parent prompt hash to continue the conversation.")
@click.option(
"-r",
"--reference",
multiple=True,
help="Input one or more specific previous prompts to include in the current prompt.",
)
@click.option(
"-i", "--instruct", multiple=True, help="Add one or more files to the prompt as instructions."
)
@click.option(
"-c", "--context", multiple=True, help="Add one or more files to the prompt as a context."
)
@click.option("-m", "--model", help="Specify the model to use for the prompt.")
@click.option(
"--config",
"config_str",
help="Specify a JSON string to overwrite the default configuration for this prompt.",
)
@click.option(
"-f",
"--functions",
type=click.Path(exists=True),
help="Path to a JSON file with functions for the prompt.",
)
@click.option(
"-n",
"--function-name",
help="Specify the function name when the content is the output of a function.",
)
@click.option(
"-ns",
"--not-store",
is_flag=True,
default=False,
required=False,
help="Do not save the conversation to the store.",
)
def prompt(
content: Optional[str],
parent: Optional[str],
reference: Optional[List[str]],
instruct: Optional[List[str]],
context: Optional[List[str]],
model: Optional[str],
config_str: Optional[str] = None,
functions: Optional[str] = None,
function_name: Optional[str] = None,
not_store: Optional[bool] = False,
):
"""
This command performs interactions with the specified large language model (LLM)
by sending prompts and receiving responses.
Expand Down Expand Up @@ -62,6 +90,7 @@ def prompt(content: Optional[str], parent: Optional[str], reference: Optional[Li

"""
from devchat._cli.router import llm_prompt

llm_prompt(
content,
parent,
Expand All @@ -72,5 +101,6 @@ def prompt(content: Optional[str], parent: Optional[str], reference: Optional[Li
config_str,
functions,
function_name,
not_store)
not_store,
)
sys.exit(0)
69 changes: 40 additions & 29 deletions devchat/_cli/route.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,48 @@
# pylint: disable=import-outside-toplevel
import sys
from typing import List, Optional

import click


@click.command(help='Route a prompt to the specified LLM')
@click.argument('content', required=False)
@click.option('-p', '--parent', help='Input the parent prompt hash to continue the conversation.')
@click.option('-r', '--reference', multiple=True,
help='Input one or more specific previous prompts to include in the current prompt.')
@click.option('-i', '--instruct', multiple=True,
help='Add one or more files to the prompt as instructions.')
@click.option('-c', '--context', multiple=True,
help='Add one or more files to the prompt as a context.')
@click.option('-m', '--model', help='Specify the model to use for the prompt.')
@click.option('--config', 'config_str',
help='Specify a JSON string to overwrite the default configuration for this prompt.')
@click.option('-a', '--auto', is_flag=True, default=False, required=False,
help='Answer question by function-calling.')
def route(content: Optional[str], parent: Optional[str], reference: Optional[List[str]],
instruct: Optional[List[str]], context: Optional[List[str]],
model: Optional[str], config_str: Optional[str] = None,
auto: Optional[bool] = False):
@click.command(help="Route a prompt to the specified LLM")
@click.argument("content", required=False)
@click.option("-p", "--parent", help="Input the parent prompt hash to continue the conversation.")
@click.option(
"-r",
"--reference",
multiple=True,
help="Input one or more specific previous prompts to include in the current prompt.",
)
@click.option(
"-i", "--instruct", multiple=True, help="Add one or more files to the prompt as instructions."
)
@click.option(
"-c", "--context", multiple=True, help="Add one or more files to the prompt as a context."
)
@click.option("-m", "--model", help="Specify the model to use for the prompt.")
@click.option(
"--config",
"config_str",
help="Specify a JSON string to overwrite the default configuration for this prompt.",
)
@click.option(
"-a",
"--auto",
is_flag=True,
default=False,
required=False,
help="Answer question by function-calling.",
)
def route(
content: Optional[str],
parent: Optional[str],
reference: Optional[List[str]],
instruct: Optional[List[str]],
context: Optional[List[str]],
model: Optional[str],
config_str: Optional[str] = None,
auto: Optional[bool] = False,
):
"""
This command performs interactions with the specified large language model (LLM)
by sending prompts and receiving responses.
Expand Down Expand Up @@ -58,14 +78,5 @@ def route(content: Optional[str], parent: Optional[str], reference: Optional[Lis
"""
from devchat._cli.router import llm_route

llm_route(
content,
parent,
reference,
instruct,
context,
model,
config_str,
auto
)
llm_route(content, parent, reference, instruct, context, model, config_str, auto)
sys.exit(0)
Loading