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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c56a2dd1808a3e8adf174b26793942f80b7bdf5e8e12d7272180fdd714c7e2d1
4
- data.tar.gz: 50459b65a2d22032658fb7c81d4f89b3f19ac8ee1040d6b7e807c28785e79cb2
3
+ metadata.gz: f026b256cf28252627df48e3c2a4bbe671661a6a655d7612cb7608f0f543609b
4
+ data.tar.gz: '0187b65632f0856d6b62a6e0b4d410737e8f26840c5bca9a5bc7d6692965b268'
5
5
  SHA512:
6
- metadata.gz: 2c3f7ca5e599e459c10b3b03222982132fa2022d956d1d6372d83f350ffb87889ea76f016384e1cebf527c818759f22f26631d3d3b19be289d9f7787bb7de100
7
- data.tar.gz: 4f4bf1e4a4cd476ee9696fe9a03ba1547cf9a5879b4a0a90605ad277eeb8c3b69699799096b23a4f5c4015ecfb99b474ecd5502238334a5acead52f852687c8d
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
- - Only analyzes explicit OpenAI::Client calls to avoid false positives
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
- return openai_client_const?(receiver.receiver) if receiver.type == :send && receiver.method_name == :new
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|
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module Prompt
5
- VERSION = "0.1.0"
5
+ VERSION = "0.1.1"
6
6
  end
7
7
  end
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.0
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: '1.0'
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: '1.0'
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: