rubocop-prompt 0.1.0 → 0.1.1
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/CHANGELOG.md +5 -0
- data/README.md +14 -1
- data/lib/rubocop/cop/prompt/missing_stop.rb +57 -4
- data/lib/rubocop/prompt/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f026b256cf28252627df48e3c2a4bbe671661a6a655d7612cb7608f0f543609b
|
4
|
+
data.tar.gz: '0187b65632f0856d6b62a6e0b4d410737e8f26840c5bca9a5bc7d6692965b268'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15f9af32e189230966dba8ba5596f3d7eb1f1619edc5062d9e373fa964dbc14723507fb6c3ad4ce6ac482a36dcb992f1d3b74a112a57b2b779e88e431ad155d3
|
7
|
+
data.tar.gz: 888687654e0ce23cf280fd6262e4eb0489e9d2052f3dd006692826d95a87946beaf35df374a2e1fbd1286f66df1d9e0d1e36634fcb36796320437bf69d16239c
|
data/CHANGELOG.md
CHANGED
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [0.1.1] - 2025-06-06
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
- Enhance OpenAI Client Detection and Specification Handling
|
12
|
+
|
8
13
|
## [0.1.0] - 2025-06-06
|
9
14
|
|
10
15
|
### Added
|
data/README.md
CHANGED
@@ -215,9 +215,10 @@ This cop identifies OpenAI::Client.chat method calls and ensures they include ei
|
|
215
215
|
|
216
216
|
**Key Features:**
|
217
217
|
- Detects explicit OpenAI::Client.new.chat calls
|
218
|
+
- Detects variable-assigned client calls (e.g., client.chat)
|
218
219
|
- Checks for presence of stop: or max_tokens: parameters
|
219
220
|
- Helps prevent runaway generation and unexpected token consumption
|
220
|
-
-
|
221
|
+
- Intelligently identifies OpenAI client usage patterns
|
221
222
|
|
222
223
|
**Bad:**
|
223
224
|
```ruby
|
@@ -230,6 +231,18 @@ class ChatService
|
|
230
231
|
}
|
231
232
|
)
|
232
233
|
end
|
234
|
+
|
235
|
+
# Also bad - variable client without stop controls
|
236
|
+
def chat_completion(user_msg, context)
|
237
|
+
client = OpenAI::Client.new(access_token: ENV["OPENAI_API_KEY"])
|
238
|
+
client.chat(parameters: {
|
239
|
+
model: "gpt-4o-mini",
|
240
|
+
messages: [
|
241
|
+
{ role: "system", content: "You are an AI assistant" },
|
242
|
+
{ role: "user", content: "#{user_msg}\n\n### 参考資料\n#{context}" }
|
243
|
+
]
|
244
|
+
})
|
245
|
+
end
|
233
246
|
end
|
234
247
|
```
|
235
248
|
|
@@ -82,11 +82,17 @@ module RuboCop
|
|
82
82
|
return false unless receiver
|
83
83
|
|
84
84
|
# Case 1: OpenAI::Client.new.chat
|
85
|
-
|
85
|
+
if receiver.type == :send && receiver.method_name == :new && openai_client_const?(receiver.receiver)
|
86
|
+
return true
|
87
|
+
end
|
88
|
+
|
89
|
+
# Case 2: Variable/method call that likely contains an OpenAI::Client
|
90
|
+
# Look for patterns like:
|
91
|
+
# - client.chat (where client variable is used)
|
92
|
+
# - method_returning_client.chat
|
93
|
+
# We'll check the surrounding context for OpenAI::Client instantiation
|
94
|
+
return true if openai_client_context?(node)
|
86
95
|
|
87
|
-
# Case 2: For now, we'll be conservative and only check explicit OpenAI::Client calls
|
88
|
-
# to avoid false positives. In the future, this could be enhanced with more
|
89
|
-
# sophisticated type analysis.
|
90
96
|
false
|
91
97
|
end
|
92
98
|
|
@@ -104,6 +110,53 @@ module RuboCop
|
|
104
110
|
end
|
105
111
|
end
|
106
112
|
|
113
|
+
def openai_client_context?(node)
|
114
|
+
# Check if we're in a context that suggests OpenAI::Client usage
|
115
|
+
# Look for OpenAI::Client.new assignment in the same method or class
|
116
|
+
return true if find_openai_client_assignment(node)
|
117
|
+
|
118
|
+
# Check if the receiver variable name suggests it's an OpenAI client
|
119
|
+
receiver = node.receiver
|
120
|
+
return true if receiver&.type == :lvar && openai_client_variable_name?(receiver.children[0])
|
121
|
+
|
122
|
+
false
|
123
|
+
end
|
124
|
+
|
125
|
+
def find_openai_client_assignment(node)
|
126
|
+
# Traverse up to find the containing method or class
|
127
|
+
current = node
|
128
|
+
while current&.parent
|
129
|
+
current = current.parent
|
130
|
+
break if %i[def defs class module].include?(current.type)
|
131
|
+
end
|
132
|
+
|
133
|
+
return false unless current
|
134
|
+
|
135
|
+
# Search for OpenAI::Client.new assignments in the same scope
|
136
|
+
found_assignment = false
|
137
|
+
current.each_descendant(:lvasgn, :ivasgn, :cvasgn, :gvasgn) do |assignment_node|
|
138
|
+
next unless assignment_node.children[1]
|
139
|
+
|
140
|
+
# Check if the assignment is to OpenAI::Client.new
|
141
|
+
value_node = assignment_node.children[1]
|
142
|
+
next unless value_node.type == :send && value_node.method_name == :new &&
|
143
|
+
openai_client_const?(value_node.receiver)
|
144
|
+
|
145
|
+
found_assignment = true
|
146
|
+
break
|
147
|
+
end
|
148
|
+
|
149
|
+
found_assignment
|
150
|
+
end
|
151
|
+
|
152
|
+
def openai_client_variable_name?(var_name)
|
153
|
+
# Common variable names that suggest OpenAI client usage
|
154
|
+
client_patterns = %w[client openai_client ai_client llm_client chat_client api_client]
|
155
|
+
var_name_str = var_name.to_s.downcase
|
156
|
+
|
157
|
+
client_patterns.any? { |pattern| var_name_str.include?(pattern) }
|
158
|
+
end
|
159
|
+
|
107
160
|
def extract_parameters_hash(node)
|
108
161
|
# Look for parameters: { ... } in the method arguments
|
109
162
|
node.arguments.each do |arg|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-prompt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masumi Kawasaki
|
@@ -13,16 +13,16 @@ dependencies:
|
|
13
13
|
name: lint_roller
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
|
-
- - "
|
16
|
+
- - ">="
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: '
|
18
|
+
version: '0'
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
|
-
- - "
|
23
|
+
- - ">="
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: '
|
25
|
+
version: '0'
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: rubocop
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
@@ -111,11 +111,11 @@ homepage: https://github.com/geeknees/rubocop-prompt
|
|
111
111
|
licenses:
|
112
112
|
- MIT
|
113
113
|
metadata:
|
114
|
+
allowed_push_host: https://rubygems.org
|
114
115
|
default_lint_roller_plugin: RuboCop::Prompt::Plugin
|
115
116
|
homepage_uri: https://github.com/geeknees/rubocop-prompt
|
116
117
|
source_code_uri: https://github.com/geeknees/rubocop-prompt
|
117
118
|
changelog_uri: https://github.com/geeknees/rubocop-prompt/blob/main/CHANGELOG.md
|
118
|
-
documentation_uri: https://github.com/geeknees/rubocop-prompt/blob/main/README.md
|
119
119
|
rubygems_mfa_required: 'true'
|
120
120
|
rdoc_options: []
|
121
121
|
require_paths:
|