diff --git a/.gitignore b/.gitignore index bf37d80..1cbca14 100644 --- a/.gitignore +++ b/.gitignore @@ -138,3 +138,9 @@ log/ *.srt *.txt *.bin +*.epub + +# For markdown files in user directories +.cursorrules +books/ +prompts/ diff --git a/README.md b/README.md index 1c28fb6..a9f86c0 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,21 @@ bbook --book_name test_books/animal_farm.epub --openai_key ${openai_key} --test - If you don't need to set the `system` role content, you can simply set it up like this: `--prompt "Translate {text} to {language}."` or `--prompt prompt_template_sample.txt` (example of a text file can be found at [./prompt_template_sample.txt](./prompt_template_sample.txt)). - If you need to set the `system` role content, you can use the following format: `--prompt '{"user":"Translate {text} to {language}", "system": "You are a professional translator."}'` or `--prompt prompt_template_sample.json` (example of a JSON file can be found at [./prompt_template_sample.json](./prompt_template_sample.json)). + + - You can now use [PromptDown](https://github.com/btfranklin/promptdown) format (`.md` files) for more structured prompts: `--prompt prompt_md.prompt.md`. PromptDown supports both traditional system messages and developer messages (used by newer AI models). Example: + + ```markdown + # Translation Prompt + + ## Developer Message + You are a professional translator who specializes in accurate translations. + + ## Conversation + + | Role | Content | + |-------|---------------------------------------------------| + | User | Please translate the following text into {language}:\n\n{text} | + ``` - You can also set the `user` and `system` role prompt by setting environment variables: `BBM_CHATGPTAPI_USER_MSG_TEMPLATE` and `BBM_CHATGPTAPI_SYS_MSG`. diff --git a/book_maker/cli.py b/book_maker/cli.py index ce0d58f..001ecfc 100644 --- a/book_maker/cli.py +++ b/book_maker/cli.py @@ -13,7 +13,46 @@ def parse_prompt_arg(prompt_arg): if prompt_arg is None: return prompt - if not any(prompt_arg.endswith(ext) for ext in [".json", ".txt"]): + # Check if it's a path to a markdown file (PromptDown format) + if prompt_arg.endswith(".md") and os.path.exists(prompt_arg): + try: + from promptdown import StructuredPrompt + structured_prompt = StructuredPrompt.from_promptdown_file(prompt_arg) + + # Initialize our prompt structure + prompt = {} + + # Handle developer_message or system_message + # Developer message takes precedence if both are present + if hasattr(structured_prompt, 'developer_message') and structured_prompt.developer_message: + prompt['system'] = structured_prompt.developer_message + elif hasattr(structured_prompt, 'system_message') and structured_prompt.system_message: + prompt['system'] = structured_prompt.system_message + + # Extract user message from conversation + if hasattr(structured_prompt, 'conversation') and structured_prompt.conversation: + for message in structured_prompt.conversation: + if message.role.lower() == 'user': + prompt['user'] = message.content + break + + # Ensure we found a user message + if 'user' not in prompt or not prompt['user']: + raise ValueError("PromptDown file must contain at least one user message") + + print(f"Successfully loaded PromptDown file: {prompt_arg}") + + # Validate required placeholders + if any(c not in prompt["user"] for c in ["{text}"]): + raise ValueError("User message in PromptDown must contain `{text}` placeholder") + + return prompt + except Exception as e: + print(f"Error parsing PromptDown file: {e}") + # Fall through to other parsing methods + + # Existing parsing logic for JSON strings and other formats + if not any(prompt_arg.endswith(ext) for ext in [".json", ".txt", ".md"]): try: # user can define prompt by passing a json string # eg: --prompt '{"system": "You are a professional translator who translates computer technology books", "user": "Translate \`{text}\` to {language}"}' diff --git a/docs/prompt.md b/docs/prompt.md index 1b2b37c..b27f76d 100644 --- a/docs/prompt.md +++ b/docs/prompt.md @@ -19,6 +19,32 @@ To tweak the prompt, use the `--prompt` parameter. Valid placeholders for the `u You can also set the `user` and `system` role prompt by setting environment variables: `BBM_CHATGPTAPI_USER_MSG_TEMPLATE` and `BBM_CHATGPTAPI_SYS_MSG`. +- You can now use PromptDown format (`.md` files) for more structured prompts: `--prompt prompt_md.prompt.md` + + # Translation Prompt + + ## System Message + You are a professional translator who specializes in accurate translations. + + ## Conversation + + | Role | Content | + |-------|------------------------------------------| + | User | Please translate the following text into {language}:\n\n{text} | + + # OR using Developer Message (for newer AI models) + + # Translation Prompt + + ## Developer Message + You are a professional translator who specializes in accurate translations. + + ## Conversation + + | Role | Content | + |-------|------------------------------------------| + | User | Please translate the following text into {language}:\n\n{text} | + ## Examples ```sh python3 make_book.py --book_name test_books/animal_farm.epub --prompt prompt_template_sample.txt diff --git a/prompt_md.prompt.md b/prompt_md.prompt.md new file mode 100644 index 0000000..8aeddfa --- /dev/null +++ b/prompt_md.prompt.md @@ -0,0 +1,11 @@ +# Translation Prompt + +## Developer Message + +You are a professional translator who specializes in accurate, natural-sounding translations that preserve the original meaning, tone, and style of the text. + +## Conversation + +| Role | Content | +|-------|---------------------------------------------------------------------------| +| User | Please translate the following text into {language}:\n\n{text} | diff --git a/pyproject.toml b/pyproject.toml index e85bba7..ea976af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ description = "The bilingual_book_maker is an AI translation tool that uses Chat readme = "README.md" license = {text = "MIT"} dynamic = ["version"] -requires-python = ">=3.9" +requires-python = ">=3.10" authors = [ { name = "yihong0618", email = "zouzou0208@gmail.com" }, ] @@ -28,10 +28,12 @@ dependencies = [ "tiktoken", "tqdm", "groq>=0.5.0", + "promptdown>=0.9.0", ] [project.scripts] bbook_maker = "book_maker.cli:main" +promptdown = "promptdown_cli:main" [project.urls] Homepage = "https://github.com/yihong0618/bilingual_book_maker" diff --git a/requirements.txt b/requirements.txt index d8b6382..ebf11b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -53,6 +53,7 @@ mdurl==0.1.2 multidict==6.0.5 openai==1.30.3 packaging==24.0 +promptdown==0.9.0 proto-plus==1.23.0 protobuf==4.25.3 pyasn1==0.6.0