y-translator-cli 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tests/__init__.py +1 -0
- tests/test_cli.py +23 -0
- translator/__init__.py +6 -0
- translator/agent.py +39 -0
- translator/cli.py +97 -0
- translator/config.py +23 -0
- y_translator_cli-0.1.0.dist-info/METADATA +117 -0
- y_translator_cli-0.1.0.dist-info/RECORD +12 -0
- y_translator_cli-0.1.0.dist-info/WHEEL +5 -0
- y_translator_cli-0.1.0.dist-info/entry_points.txt +2 -0
- y_translator_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
- y_translator_cli-0.1.0.dist-info/top_level.txt +2 -0
tests/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Tests for the Y-Translator CLI package"""
|
tests/test_cli.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Tests for Y-Translator CLI"""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from translator import __version__
|
|
5
|
+
from translator.cli import create_parser
|
|
6
|
+
|
|
7
|
+
def test_version():
|
|
8
|
+
"""Test that version is set correctly"""
|
|
9
|
+
assert __version__ is not None
|
|
10
|
+
assert isinstance(__version__, str)
|
|
11
|
+
assert len(__version__.split('.')) >= 2
|
|
12
|
+
|
|
13
|
+
def test_parser_creation():
|
|
14
|
+
"""Test that the argument parser is created properly"""
|
|
15
|
+
parser = create_parser()
|
|
16
|
+
args = parser.parse_args([])
|
|
17
|
+
assert args is not None
|
|
18
|
+
|
|
19
|
+
args = parser.parse_args(['--verbose'])
|
|
20
|
+
assert args.verbose is True
|
|
21
|
+
|
|
22
|
+
args = parser.parse_args(['--model', 'gpt-3.5-turbo'])
|
|
23
|
+
assert args.model == 'gpt-3.5-turbo'
|
translator/__init__.py
ADDED
translator/agent.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""AI agent functionality for Y-Translator CLI"""
|
|
2
|
+
|
|
3
|
+
from agno.agent import Agent
|
|
4
|
+
from agno.models.openai.like import OpenAILike
|
|
5
|
+
from .config import Config
|
|
6
|
+
|
|
7
|
+
class TranslatorAgent:
|
|
8
|
+
"""Translator AI Agent wrapper"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, config: Config):
|
|
11
|
+
"""Initialize the agent with configuration"""
|
|
12
|
+
self.config = config
|
|
13
|
+
self.model = OpenAILike(
|
|
14
|
+
id=config.model,
|
|
15
|
+
base_url=config.api_base,
|
|
16
|
+
api_key=config.api_key,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
self.agent = Agent(
|
|
20
|
+
instructions=[
|
|
21
|
+
"You are only a translator",
|
|
22
|
+
"You only translate user input to English, when user input is Chinese",
|
|
23
|
+
"You only translate user input to Chinese, when user input is English",
|
|
24
|
+
"You don't answer any questions",
|
|
25
|
+
],
|
|
26
|
+
markdown=True,
|
|
27
|
+
model=self.model,
|
|
28
|
+
stream=True,
|
|
29
|
+
add_history_to_messages=True,
|
|
30
|
+
num_history_responses=5,
|
|
31
|
+
debug_mode=config.debug,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def process_query(self, query: str, stream: bool = True) -> None:
|
|
35
|
+
"""Process a single query and print the response"""
|
|
36
|
+
if not query.strip():
|
|
37
|
+
return
|
|
38
|
+
|
|
39
|
+
self.agent.print_response(query, stream=stream)
|
translator/cli.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Command-line interface for Y-Translator CLI"""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import sys
|
|
5
|
+
from prompt_toolkit import PromptSession
|
|
6
|
+
from prompt_toolkit.history import InMemoryHistory
|
|
7
|
+
from . import __version__
|
|
8
|
+
from .config import Config
|
|
9
|
+
from .agent import TranslatorAgent
|
|
10
|
+
|
|
11
|
+
def create_parser() -> argparse.ArgumentParser:
|
|
12
|
+
"""Create command line argument parser"""
|
|
13
|
+
parser = argparse.ArgumentParser(
|
|
14
|
+
description="Y-Translator CLI - AI-powered English-Chinese translator"
|
|
15
|
+
)
|
|
16
|
+
parser.add_argument(
|
|
17
|
+
"-v", "--version",
|
|
18
|
+
action="version",
|
|
19
|
+
version=f"Y-Translator CLI version {__version__}"
|
|
20
|
+
)
|
|
21
|
+
parser.add_argument(
|
|
22
|
+
"--verbose",
|
|
23
|
+
action="store_true",
|
|
24
|
+
help="Enable debug mode"
|
|
25
|
+
)
|
|
26
|
+
parser.add_argument(
|
|
27
|
+
"--model",
|
|
28
|
+
help="AI model to use (default: gpt-4)",
|
|
29
|
+
default=None
|
|
30
|
+
)
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
"--api-key",
|
|
33
|
+
help="OpenAI API key",
|
|
34
|
+
default=None
|
|
35
|
+
)
|
|
36
|
+
parser.add_argument(
|
|
37
|
+
"--api-base",
|
|
38
|
+
help="Custom API base URL",
|
|
39
|
+
default=None
|
|
40
|
+
)
|
|
41
|
+
parser.add_argument(
|
|
42
|
+
"-n", "--no-stream",
|
|
43
|
+
action="store_true",
|
|
44
|
+
help="Disable streaming mode"
|
|
45
|
+
)
|
|
46
|
+
return parser
|
|
47
|
+
|
|
48
|
+
def run_interactive_session(agent: TranslatorAgent, stream: bool = True):
|
|
49
|
+
"""Run an interactive session with the agent"""
|
|
50
|
+
history = InMemoryHistory()
|
|
51
|
+
session = PromptSession(history=history)
|
|
52
|
+
|
|
53
|
+
print("\n" + "="*60)
|
|
54
|
+
print(f"🚀 \033[1;36mY-Translator CLI v{__version__}\033[0m - \033[1mAI-powered Translator\033[0m")
|
|
55
|
+
print("="*60)
|
|
56
|
+
print("\033[1;32m✓\033[0m English to Chinese translation")
|
|
57
|
+
print("\033[1;32m✓\033[0m Chinese to English translation")
|
|
58
|
+
print("\033[1;32m✓\033[0m Type 'exit' or press Ctrl+C to quit")
|
|
59
|
+
print("")
|
|
60
|
+
print("\033[1;33mType your text to translate and press Enter:\033[0m")
|
|
61
|
+
|
|
62
|
+
while True:
|
|
63
|
+
try:
|
|
64
|
+
query = session.prompt('>>> ')
|
|
65
|
+
|
|
66
|
+
if query.lower() in ("exit", "quit", "退出"):
|
|
67
|
+
print("\n\033[1;32mGoodbye! Have a great day!\033[0m")
|
|
68
|
+
break
|
|
69
|
+
|
|
70
|
+
agent.process_query(query, stream=stream)
|
|
71
|
+
|
|
72
|
+
except KeyboardInterrupt:
|
|
73
|
+
print("\n\033[1;32mExiting...\033[0m")
|
|
74
|
+
break
|
|
75
|
+
except Exception as e:
|
|
76
|
+
print(f"\033[1;31mError: {e}\033[0m")
|
|
77
|
+
|
|
78
|
+
def main():
|
|
79
|
+
"""Main entry point for Y-Translator CLI"""
|
|
80
|
+
parser = create_parser()
|
|
81
|
+
args = parser.parse_args()
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
config = Config.from_args(args)
|
|
85
|
+
agent = TranslatorAgent(config)
|
|
86
|
+
run_interactive_session(agent, stream=not args.no_stream)
|
|
87
|
+
except KeyboardInterrupt:
|
|
88
|
+
print("\n\033[1;32mExiting...\033[0m")
|
|
89
|
+
sys.exit(0)
|
|
90
|
+
except Exception as e:
|
|
91
|
+
print(f"\033[1;31mError: {e}\033[0m", file=sys.stderr)
|
|
92
|
+
if args.verbose:
|
|
93
|
+
raise
|
|
94
|
+
sys.exit(1)
|
|
95
|
+
|
|
96
|
+
if __name__ == "__main__":
|
|
97
|
+
main()
|
translator/config.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Configuration management for Y-Translator CLI"""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class Config:
|
|
9
|
+
"""Configuration settings for Y-Translator CLI"""
|
|
10
|
+
api_key: str = os.getenv("AI_API_KEY", "")
|
|
11
|
+
model: str = os.getenv("AI_MODEL", "gpt-4")
|
|
12
|
+
api_base: str = os.getenv("AI_API_BASE", "https://api.openai.com/v1")
|
|
13
|
+
debug: bool = False
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def from_args(cls, args) -> 'Config':
|
|
17
|
+
"""Create config from command line arguments"""
|
|
18
|
+
return cls(
|
|
19
|
+
api_key=args.api_key or os.getenv("AI_API_KEY", ""),
|
|
20
|
+
model=args.model or os.getenv("AI_MODEL", "gpt-4"),
|
|
21
|
+
api_base=args.api_base or os.getenv("AI_API_BASE", "https://api.openai.com/v1"),
|
|
22
|
+
debug=args.verbose,
|
|
23
|
+
)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: y-translator-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: An AI-powered English-Chinese translator for the command line
|
|
5
|
+
Home-page: https://github.com/yourusername/translator
|
|
6
|
+
Author: Yang
|
|
7
|
+
Author-email: your.email@example.com
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Requires-Dist: prompt_toolkit>=3.0.0
|
|
20
|
+
Requires-Dist: agno>=0.1.0
|
|
21
|
+
Requires-Dist: python-dotenv>=0.19.0
|
|
22
|
+
Dynamic: author
|
|
23
|
+
Dynamic: author-email
|
|
24
|
+
Dynamic: classifier
|
|
25
|
+
Dynamic: description
|
|
26
|
+
Dynamic: description-content-type
|
|
27
|
+
Dynamic: home-page
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+
# Y-Translator CLI
|
|
34
|
+
|
|
35
|
+
An AI-powered command-line translator that converts between English and Chinese.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install y-translator-cli
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Usage
|
|
44
|
+
|
|
45
|
+
Start the translator:
|
|
46
|
+
```bash
|
|
47
|
+
y-translator
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Options:
|
|
51
|
+
- `-h, --help`: Show help message
|
|
52
|
+
- `-v, --version`: Show version information
|
|
53
|
+
- `--verbose`: Enable debug mode
|
|
54
|
+
- `--model MODEL`: Specify AI model to use (default: gpt-4)
|
|
55
|
+
- `--api-key KEY`: Set OpenAI API key
|
|
56
|
+
- `--api-base URL`: Set custom API base URL
|
|
57
|
+
- `-n, --no-stream`: Disable streaming mode
|
|
58
|
+
|
|
59
|
+
## Environment Variables
|
|
60
|
+
|
|
61
|
+
You can set the following environment variables:
|
|
62
|
+
- `AI_API_KEY`: Your OpenAI API key
|
|
63
|
+
- `AI_MODEL`: AI model to use (default: gpt-4)
|
|
64
|
+
- `AI_API_BASE`: Custom API base URL
|
|
65
|
+
|
|
66
|
+
## Examples
|
|
67
|
+
|
|
68
|
+
1. Start the translator:
|
|
69
|
+
```bash
|
|
70
|
+
y-translator
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
2. Enable debug mode:
|
|
74
|
+
```bash
|
|
75
|
+
y-translator --verbose
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
3. Use a specific model:
|
|
79
|
+
```bash
|
|
80
|
+
y-translator --model gpt-3.5-turbo
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
4. Disable streaming output:
|
|
84
|
+
```bash
|
|
85
|
+
y-translator -n
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Development
|
|
89
|
+
|
|
90
|
+
### Installation for Development
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Clone the repository
|
|
94
|
+
git clone https://github.com/yourusername/y-translator.git
|
|
95
|
+
cd y-translator
|
|
96
|
+
|
|
97
|
+
# Install in development mode
|
|
98
|
+
pip install -e .
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Building the Package
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Use build
|
|
105
|
+
python -m build
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
If building manually, you may want to clean old files first:
|
|
109
|
+
```bash
|
|
110
|
+
# Clean before building
|
|
111
|
+
rm -rf dist/ build/ *.egg-info/ __pycache__/ .pytest_cache/
|
|
112
|
+
find . -name "*.pyc" -delete
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT License
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
tests/__init__.py,sha256=lncvqHZnsQZaPJFvF2mXv3wnnMN9ibTXP9yTIG1YpyA,45
|
|
2
|
+
tests/test_cli.py,sha256=N_xYgp_yghMtYKH4wkKBvMH4uMZY88Yl4Xzx3vfzp98,674
|
|
3
|
+
translator/__init__.py,sha256=hQDYySj23dHElMAgz1_iMVidoLUo4dkBj0OQmM7JWiM,116
|
|
4
|
+
translator/agent.py,sha256=v9iwvaGUePBRxDq4ylbS0R0ojrcT7mt5ckrhqrpqoHc,1301
|
|
5
|
+
translator/cli.py,sha256=JGbs0V9qhXBSGNucJmgD4cUYjNbQyTB-SgCfk75h-BY,2899
|
|
6
|
+
translator/config.py,sha256=_rlQO2hSMtc_HtaHl7F7I6mmLLk1yc19BfYMTZjdgk8,802
|
|
7
|
+
y_translator_cli-0.1.0.dist-info/licenses/LICENSE,sha256=ERLNVd6wQ_wrpxs7LVks0YjnHhwLmW9SsYJUYFy0ukk,1061
|
|
8
|
+
y_translator_cli-0.1.0.dist-info/METADATA,sha256=pevtt19x6QXWGLb-yfTHejjrXWE8am_hqS87dmDSLLs,2489
|
|
9
|
+
y_translator_cli-0.1.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
10
|
+
y_translator_cli-0.1.0.dist-info/entry_points.txt,sha256=3O97fL4RZwoxln34xI9uOkVObQUb_3VcJhDIbEHGOew,51
|
|
11
|
+
y_translator_cli-0.1.0.dist-info/top_level.txt,sha256=wPTGyikl7K0psWsSRLzYZqDdal4kcBKPTdbT2BwQca0,17
|
|
12
|
+
y_translator_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Yang
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|