geekdict 0.1.2 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +109 -36
- data/lib/geekdict/cli.rb +58 -24
- data/lib/geekdict/config.rb +33 -0
- data/lib/geekdict/openai/gpt.rb +6 -2
- data/lib/geekdict/openrouter/api.rb +7 -3
- data/lib/geekdict/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c60ec472c37345eac7c1b4be1f60c56ea5edca02c3c5af8eb19be3cd1173470
|
4
|
+
data.tar.gz: ada5e008be1245e52e1b70827b7ef517f067ce187a3a7c755d97e45c189cb14d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06ae16f269a32062b8d825debf6e4f76df6cf9e65394365c8275dd0846d163bcaa70203d39561695c6744ae9e137364d6cd2b2ce4d2ee9bb59df492bed357022
|
7
|
+
data.tar.gz: e29388ec6089b5172b6898f805942150c8862e0b909ba0dbc37ee4e2d3835b89d190128e6824b19bef7905174dcd8b1c7654f6b3debc176d9e72536fc1be100f
|
data/README.md
CHANGED
@@ -12,57 +12,130 @@ You can install via rubygems:
|
|
12
12
|
|
13
13
|
Configure
|
14
14
|
--------
|
15
|
-
GeekDict
|
15
|
+
GeekDict requires API keys for certain providers, set as environment variables:
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
* **OpenRouter**: Set `OPENROUTER_API_KEY`.
|
18
|
+
* **OpenAI**: Set `OPENAI_API_KEY`.
|
19
|
+
* **Youdao**: Configuration for Youdao keys is typically handled within its specific module or a separate config file if needed (refer to Youdao provider specifics if used).
|
20
|
+
|
21
|
+
### Configuration File (Optional)
|
22
|
+
|
23
|
+
You can customize the default provider and model by creating a configuration file at `~/.geekdict.config`. The file should be in YAML format.
|
24
|
+
|
25
|
+
**Example `~/.geekdict.config`:**
|
26
|
+
|
27
|
+
```yaml
|
28
|
+
provider: openrouter # 'openai', 'openrouter', or 'youdao'
|
29
|
+
model: google/gemini-2.5-flash-preview # Specific model for the chosen provider
|
30
|
+
```
|
31
|
+
|
32
|
+
**Defaults:**
|
33
|
+
|
34
|
+
* If the config file is not present or a setting is missing, the tool defaults to:
|
35
|
+
* `provider: openrouter`
|
36
|
+
* `model: google/gemini-2.5-flash-preview`
|
37
|
+
|
38
|
+
**Prioritization:**
|
39
|
+
|
40
|
+
Settings are applied in the following order (highest priority first):
|
41
|
+
|
42
|
+
1. Command-line options (`--provider`, `--model`)
|
43
|
+
2. Values in `~/.geekdict.config`
|
44
|
+
3. Hardcoded defaults
|
20
45
|
|
21
46
|
|
22
47
|
Commands
|
23
48
|
--------
|
24
|
-
### Translate a word
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
49
|
+
### Translate a word (`t`)
|
50
|
+
|
51
|
+
Translates a given word between English and Chinese.
|
52
|
+
|
53
|
+
**Usage:**
|
54
|
+
|
55
|
+
```bash
|
56
|
+
geekdict t [options] <word>
|
57
|
+
```
|
58
|
+
|
59
|
+
**Options:**
|
60
|
+
|
61
|
+
* `-p, --provider PROVIDER`: Specify the translation provider (`openai`, `openrouter`, `youdao`). Overrides config file setting.
|
62
|
+
* `-m, --model MODEL`: Specify the LLM model to use (e.g., `gpt-4`, `google/gemini-pro`). Overrides config file setting.
|
63
|
+
* `-d, --debug`: Enable debug output.
|
64
|
+
* `-o, --open`: (Functionality might vary - check specific provider usage)
|
65
|
+
|
66
|
+
**Examples:**
|
67
|
+
|
68
|
+
```bash
|
69
|
+
# Use defaults (provider/model from CLI -> config -> hardcoded defaults)
|
70
|
+
$ geekdict t hello
|
71
|
+
|
72
|
+
# Specify provider (uses default/config model for that provider)
|
73
|
+
$ geekdict t hello -p openai
|
74
|
+
|
75
|
+
# Specify model (uses default/config provider)
|
76
|
+
$ geekdict t hello -m gpt-4
|
77
|
+
|
78
|
+
# Specify both provider and model
|
79
|
+
$ geekdict t hello --provider openrouter --model anthropic/claude-3-haiku
|
80
|
+
|
81
|
+
# Use Youdao provider (model option typically ignored)
|
82
|
+
$ geekdict t hello -p youdao
|
83
|
+
```
|
84
|
+
|
85
|
+
**Example Output (using an LLM provider):**
|
86
|
+
|
87
|
+
```
|
88
|
+
Translation: 你好 (nǐ hǎo)
|
89
|
+
|
90
|
+
Explanation:
|
91
|
+
"你好" (nǐ hǎo) is the standard Mandarin Chinese greeting equivalent to "hello" in English. It's a polite and common way to greet someone.
|
92
|
+
|
93
|
+
Examples:
|
94
|
+
1. 你好,请问有什么可以帮您的吗?
|
95
|
+
Hello, may I help you with anything?
|
96
|
+
2. 他笑着对我说你好。
|
97
|
+
He smiled and said hello to me.
|
98
|
+
```
|
45
99
|
|
46
100
|
Command Help
|
47
101
|
------------
|
48
|
-
Use
|
102
|
+
Use the `help` command to get detailed information about commands and options.
|
49
103
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
104
|
+
```bash
|
105
|
+
$ geekdict help
|
106
|
+
Commands:
|
107
|
+
geekdict help [COMMAND] # Describe available commands or one specific command
|
108
|
+
geekdict t <word> # Translate a word
|
109
|
+
geekdict v # Show version
|
54
110
|
|
55
|
-
|
56
|
-
|
57
|
-
|
111
|
+
$ geekdict help t
|
112
|
+
Usage:
|
113
|
+
geekdict t [options] <word>
|
58
114
|
|
59
|
-
|
115
|
+
Options:
|
60
116
|
-d, [--debug], [--no-debug]
|
61
117
|
-o, [--open], [--no-open]
|
62
|
-
-p, [--provider=PROVIDER]
|
118
|
+
-p, [--provider=PROVIDER] # Provider (overrides config: openai/openrouter/youdao)
|
119
|
+
-m, [--model=MODEL] # LLM model (overrides config)
|
120
|
+
# Default: false
|
121
|
+
|
122
|
+
Translate a word
|
123
|
+
```
|
124
|
+
|
125
|
+
### Shell Alias (Optional)
|
63
126
|
|
64
|
-
|
127
|
+
For faster access, you can create a shell alias. Add the following line to your shell configuration file (e.g., `~/.bashrc`, `~/.zshrc`):
|
65
128
|
|
129
|
+
```bash
|
130
|
+
alias t='geekdict t'
|
131
|
+
```
|
132
|
+
|
133
|
+
After adding the alias and restarting your shell or sourcing the configuration file (e.g., `source ~/.zshrc`), you can simply use `t` instead of `geekdict t`:
|
134
|
+
|
135
|
+
```bash
|
136
|
+
# Instead of: geekdict t hello
|
137
|
+
t hello
|
138
|
+
```
|
66
139
|
|
67
140
|
Development
|
68
141
|
----------
|
data/lib/geekdict/cli.rb
CHANGED
@@ -1,35 +1,69 @@
|
|
1
1
|
require "thor"
|
2
|
+
# Remove YAML require, handled in config.rb
|
2
3
|
require_relative 'local_history'
|
3
4
|
require_relative 'version'
|
5
|
+
require_relative 'config' # Add require for the new config module
|
4
6
|
require_relative 'openai/gpt.rb'
|
5
7
|
require_relative 'openrouter/api.rb'
|
8
|
+
# Assuming youdao might be added later or is handled elsewhere
|
9
|
+
# require_relative 'youdao/api.rb'
|
10
|
+
require_relative 'youdao/api.rb' # Keep youdao require
|
6
11
|
|
7
12
|
module GeekDict
|
13
|
+
class CLI < Thor
|
14
|
+
# Constants and load_config are now in GeekDict::Config
|
8
15
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
16
|
+
desc "t", "Translate a word"
|
17
|
+
option :debug, :aliases => '-d', :type => :boolean, :default => false
|
18
|
+
option :open, :aliases => '-o', :type => :boolean, :default => false
|
19
|
+
# Update enum and desc to use Config constants
|
20
|
+
option :provider, :aliases => '-p', :type => :string, :enum => GeekDict::Config::ALLOWED_PROVIDERS, :desc => "Provider (overrides config: #{GeekDict::Config::ALLOWED_PROVIDERS.join('/')})"
|
21
|
+
# Add model option
|
22
|
+
option :model, :aliases => '-m', :type => :string, :desc => "LLM model (overrides config)"
|
23
|
+
def t(word)
|
24
|
+
GeekDict.debugger options[:debug]
|
25
|
+
LocalHistory.save word
|
26
|
+
|
27
|
+
# 1. Load config file using the Config module
|
28
|
+
config = GeekDict::Config.load_config
|
29
|
+
|
30
|
+
# 2. Determine provider: CLI option > Config file > Default (use Config constants)
|
31
|
+
provider = options[:provider]&.downcase || config[:provider] || GeekDict::Config::DEFAULT_PROVIDER
|
32
|
+
|
33
|
+
# 3. Determine model: CLI option > Config file > Default (use Config constants)
|
34
|
+
model = options[:model] || config[:model] || GeekDict::Config::DEFAULT_MODEL
|
35
|
+
|
36
|
+
# 4. Validate provider (use Config constants)
|
37
|
+
unless GeekDict::Config::ALLOWED_PROVIDERS.include?(provider)
|
38
|
+
warn "Warning: Invalid provider '#{provider}' specified. Using default '#{GeekDict::Config::DEFAULT_PROVIDER}'."
|
39
|
+
provider = GeekDict::Config::DEFAULT_PROVIDER
|
40
|
+
# Reset model if provider changed to default, unless model was explicitly set via CLI
|
41
|
+
model = options[:model] || GeekDict::Config::DEFAULT_MODEL # Use default model for the default provider
|
42
|
+
end
|
43
|
+
|
44
|
+
# Optional: Output effective settings for debugging/clarity
|
45
|
+
puts "Using provider: #{provider}, model: #{model}" if options[:debug]
|
46
|
+
|
47
|
+
# 5. Call the appropriate provider with the word and model
|
48
|
+
result = case provider
|
49
|
+
when 'openai'
|
50
|
+
# TODO: Update OpenAI class to accept model
|
51
|
+
GeekDict::OpenAI.translate(word, model: model)
|
52
|
+
when 'openrouter'
|
53
|
+
# TODO: Update OpenRouter class to accept model
|
54
|
+
GeekDict::OpenRouter.translate(word, model: model)
|
55
|
+
when 'youdao'
|
56
|
+
# Youdao might not use a 'model' in the same way.
|
57
|
+
# If it needs config, adjust here. For now, pass nothing extra.
|
58
|
+
GeekDict::Youdao.translate(word)
|
59
|
+
else
|
60
|
+
# This case should technically not be reached due to validation
|
61
|
+
warn "Internal Error: Unknown provider '#{provider}'. Aborting."
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
|
65
|
+
puts result
|
66
|
+
end
|
33
67
|
|
34
68
|
desc "v", "version"
|
35
69
|
def v()
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "yaml"
|
2
|
+
|
3
|
+
module GeekDict
|
4
|
+
module Config
|
5
|
+
CONFIG_PATH = File.expand_path("~/.geekdict.config")
|
6
|
+
DEFAULT_PROVIDER = "openrouter"
|
7
|
+
DEFAULT_MODEL = "google/gemini-2.5-flash-preview"
|
8
|
+
ALLOWED_PROVIDERS = ['openai', 'openrouter', 'youdao'].freeze
|
9
|
+
|
10
|
+
module_function
|
11
|
+
|
12
|
+
# Method to load configuration from ~/.geekdict.config
|
13
|
+
def load_config
|
14
|
+
config = {}
|
15
|
+
if File.exist?(CONFIG_PATH)
|
16
|
+
begin
|
17
|
+
loaded_config = YAML.load_file(CONFIG_PATH)
|
18
|
+
config = loaded_config if loaded_config.is_a?(Hash)
|
19
|
+
rescue Psych::SyntaxError => e
|
20
|
+
warn "Warning: Error parsing config file #{CONFIG_PATH}: #{e.message}. Using defaults."
|
21
|
+
rescue => e
|
22
|
+
warn "Warning: Could not load config file #{CONFIG_PATH}: #{e.message}. Using defaults."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
# Ensure keys are symbols for easier access, handle potential nil values
|
26
|
+
config = config.transform_keys { |k| k.to_s.downcase.to_sym rescue k } # Make keys symbols & lowercase
|
27
|
+
{
|
28
|
+
provider: config[:provider],
|
29
|
+
model: config[:model]
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/geekdict/openai/gpt.rb
CHANGED
@@ -8,12 +8,16 @@ module GeekDict
|
|
8
8
|
|
9
9
|
module_function
|
10
10
|
|
11
|
-
|
11
|
+
# Update translate method to accept model
|
12
|
+
def translate(word, model: nil) # Add model keyword argument
|
12
13
|
@debugger = GeekDict.debugger
|
14
|
+
# Use the provided model, or fallback to a default if nil
|
15
|
+
effective_model = model || "gpt-3.5-turbo" # Fallback model for OpenAI
|
16
|
+
|
13
17
|
client = ::OpenAI::Client.new(access_token: ENV.fetch('OPENAI_API_KEY'))
|
14
18
|
response = client.chat(
|
15
19
|
parameters: {
|
16
|
-
model:
|
20
|
+
model: effective_model, # Use the determined model
|
17
21
|
messages: [
|
18
22
|
{ role: "system", content: system_prompt(word)},
|
19
23
|
{ role: "user", content: word}
|
@@ -5,9 +5,13 @@ module GeekDict
|
|
5
5
|
module OpenRouter
|
6
6
|
module_function
|
7
7
|
|
8
|
-
|
8
|
+
# Update translate method to accept model
|
9
|
+
def translate(word, model: nil) # Add model keyword argument
|
9
10
|
@debugger = GeekDict.debugger
|
10
11
|
|
12
|
+
# Use the provided model, or fallback to a default if nil (though CLI should provide one)
|
13
|
+
effective_model = model || 'google/gemini-2.5-flash-preview' # Fallback, though CLI provides default
|
14
|
+
|
11
15
|
client = HTTPClient.new
|
12
16
|
headers = {
|
13
17
|
'Content-Type' => 'application/json',
|
@@ -15,7 +19,7 @@ module GeekDict
|
|
15
19
|
}
|
16
20
|
|
17
21
|
body = {
|
18
|
-
model:
|
22
|
+
model: effective_model, # Use the determined model
|
19
23
|
messages: [
|
20
24
|
{ role: "system", content: system_prompt(word) },
|
21
25
|
{ role: "user", content: word }
|
@@ -60,4 +64,4 @@ module GeekDict
|
|
60
64
|
EOS
|
61
65
|
end
|
62
66
|
end
|
63
|
-
end
|
67
|
+
end
|
data/lib/geekdict/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geekdict
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wenbing Li
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- geekdict.gemspec
|
111
111
|
- lib/geekdict.rb
|
112
112
|
- lib/geekdict/cli.rb
|
113
|
+
- lib/geekdict/config.rb
|
113
114
|
- lib/geekdict/debugger.rb
|
114
115
|
- lib/geekdict/local_history.rb
|
115
116
|
- lib/geekdict/openai/gpt.rb
|
@@ -139,7 +140,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
140
|
- !ruby/object:Gem::Version
|
140
141
|
version: '0'
|
141
142
|
requirements: []
|
142
|
-
rubygems_version: 3.
|
143
|
+
rubygems_version: 3.5.22
|
143
144
|
signing_key:
|
144
145
|
specification_version: 4
|
145
146
|
summary: A command line tool for translation.
|