gptdiff 0.1.0__py3-none-any.whl → 0.1.2__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.
gptdiff/gptdiff.py CHANGED
@@ -160,9 +160,9 @@ def call_gpt4_api(system_prompt, user_prompt, files_content, model, temperature=
160
160
  print(user_prompt, "+", len(files_content), "characters of file content")
161
161
 
162
162
  if api_key is None:
163
- api_key = os.getenv('NANOGPT_API_KEY')
163
+ api_key = os.getenv('GPTDIFF_LLM_API_KEY')
164
164
  if base_url is None:
165
- base_url = os.getenv('NANOGPT_BASE_URL', "https://nano-gpt.com/api/v1/")
165
+ base_url = os.getenv('GPTDIFF_LLM_BASE_URL', "https://nano-gpt.com/api/v1/")
166
166
  client = OpenAI(api_key=api_key, base_url=base_url)
167
167
  response = client.chat.completions.create(model=model,
168
168
  messages=messages,
@@ -198,15 +198,17 @@ def build_environment(files_dict):
198
198
  env.append(content)
199
199
  return '\n'.join(env)
200
200
 
201
- def generate_diff(environment, goal, model='deepseek-reasoner', temperature=0.7, max_tokens=32000, api_key=None, base_url=None, prepend=None):
201
+ def generate_diff(environment, goal, model=None, temperature=0.7, max_tokens=32000, api_key=None, base_url=None, prepend=None):
202
202
  """API: Generate diff from environment and goal"""
203
+ if model is None:
204
+ model = os.getenv('GPTDIFF_MODEL', 'deepseek-reasoner')
203
205
  if prepend:
204
206
  prepend = load_prepend_file(args.prepend)
205
207
  print("Including prepend",len(enc.encode(json.dumps(prepend))), "tokens")
206
208
  else:
207
209
  prepend = ""
208
210
 
209
- system_prompt = f"Output a git diff into a <diff> block."
211
+ system_prompt = prepend+f"Output a git diff into a <diff> block."
210
212
  _, diff_text, _, _, _, _ = call_gpt4_api(
211
213
  system_prompt,
212
214
  goal,
@@ -219,7 +221,7 @@ def generate_diff(environment, goal, model='deepseek-reasoner', temperature=0.7,
219
221
  )
220
222
  return diff_text
221
223
 
222
- def smartapply(diff_text, files, model='deepseek-reasoner', api_key=None, base_url=None):
224
+ def smartapply(diff_text, files, model=None, api_key=None, base_url=None):
223
225
  """Applies unified diffs to file contents with AI-powered conflict resolution.
224
226
 
225
227
  Key features:
@@ -254,6 +256,8 @@ def smartapply(diff_text, files, model='deepseek-reasoner', api_key=None, base_u
254
256
  def new():
255
257
  pass
256
258
  """
259
+ if model is None:
260
+ model = os.getenv('GPTDIFF_MODEL', 'deepseek-reasoner')
257
261
  parsed_diffs = parse_diff_per_file(diff_text)
258
262
  print("SMARTAPPLY", diff_text)
259
263
 
@@ -278,7 +282,6 @@ def apply_diff(project_dir, diff_text):
278
282
  with open(diff_file, 'w') as f:
279
283
  f.write(diff_text)
280
284
 
281
- return False
282
285
  result = subprocess.run(["patch", "-p1", "--remove-empty-files", "--input", str(diff_file)], cwd=project_dir, capture_output=True, text=True)
283
286
  if result.returncode != 0:
284
287
  return False
@@ -297,7 +300,7 @@ def parse_arguments():
297
300
  help='Call the GPT-4 API. Writes the full prompt to prompt.txt if not specified.')
298
301
  parser.add_argument('files', nargs='*', default=[], help='Specify additional files or directories to include.')
299
302
  parser.add_argument('--temperature', type=float, default=0.7, help='Temperature parameter for model creativity (0.0 to 2.0)')
300
- parser.add_argument('--model', type=str, default='deepseek-reasoner', help='Model to use for the API call.')
303
+ parser.add_argument('--model', type=str, default=None, help='Model to use for the API call.')
301
304
 
302
305
  parser.add_argument('--nowarn', action='store_true', help='Disable large token warning')
303
306
 
@@ -420,9 +423,9 @@ Diff to apply:
420
423
  ]
421
424
 
422
425
  if api_key is None:
423
- api_key = os.getenv('NANOGPT_API_KEY')
426
+ api_key = os.getenv('GPTDIFF_LLM_API_KEY')
424
427
  if base_url is None:
425
- base_url = os.getenv('NANOGPT_BASE_URL', "https://nano-gpt.com/api/v1/")
428
+ base_url = os.getenv('GPTDIFF_LLM_BASE_URL', "https://nano-gpt.com/api/v1/")
426
429
  client = OpenAI(api_key=api_key, base_url=base_url)
427
430
  response = client.chat.completions.create(model=model,
428
431
  messages=messages,
@@ -496,6 +499,8 @@ def main():
496
499
 
497
500
  full_prompt = f"{system_prompt}\n\n{user_prompt}\n\n{files_content}"
498
501
  token_count = len(enc.encode(full_prompt))
502
+ if args.model is None:
503
+ args.model = os.getenv('GPTDIFF_MODEL', 'deepseek-reasoner')
499
504
 
500
505
  if not args.call and not args.apply:
501
506
  with open('prompt.txt', 'w') as f:
@@ -507,23 +512,23 @@ def main():
507
512
  exit(0)
508
513
  else:
509
514
  # Validate API key presence before any API operations
510
- if not os.getenv('NANOGPT_API_KEY'):
511
- print("\033[1;31mError: NANOGPT_API_KEY environment variable required\033[0m")
512
- print("Set it with: export NANOGPT_API_KEY='your-key'")
515
+ if not os.getenv('GPTDIFF_LLM_API_KEY'):
516
+ print("\033[1;31mError: GPTDIFF_LLM_API_KEY environment variable required\033[0m")
517
+ print("Set it with: export GPTDIFF_LLM_API_KEY='your-key'")
513
518
  sys.exit(1)
514
519
 
515
520
  # Confirm large requests without specified files
516
521
  if (not args.nowarn) and (not args.files) and token_count > 10000 and (args.call or args.apply):
517
- print(f"\033[1;33mThis is a larger request ({token_count} tokens). Are you sure you want to send it? [y/N]\033[0m")
522
+ print(f"\033[1;33mThis is a larger request ({token_count} tokens). Disable this warning with --nowarn. Are you sure you want to send it? [y/N]\033[0m")
518
523
  confirmation = input().strip().lower()
519
524
  if confirmation != 'y':
520
525
  print("Request canceled")
521
526
  sys.exit(0)
522
527
  full_text, diff_text, prompt_tokens, completion_tokens, total_tokens, cost = call_gpt4_api(system_prompt, user_prompt, files_content, args.model,
523
528
  temperature=args.temperature,
524
- api_key=os.getenv('NANOGPT_API_KEY'),
525
- base_url=os.getenv('NANOGPT_BASE_URL', "https://nano-gpt.com/api/v1/")
526
- )
529
+ api_key=os.getenv('GPTDIFF_LLM_API_KEY'),
530
+ base_url=os.getenv('GPTDIFF_LLM_BASE_URL', "https://nano-gpt.com/api/v1/")
531
+ )
527
532
 
528
533
  if(diff_text.strip() == ""):
529
534
  print(f"\033[1;33mThere was no data in this diff. The LLM may have returned something invalid.\033[0m")
@@ -0,0 +1,10 @@
1
+ # We help companies adapt to the AI age through product development and consulting. 255labs.xyz
2
+ This is free and unencumbered software released into the public domain.
3
+
4
+ Copyright 2025 255labs.xyz
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
+
8
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
+
10
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,8 +1,12 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: gptdiff
3
- Version: 0.1.0
4
- Summary: A tool to generate git diffs using GPT-4
3
+ Version: 0.1.2
4
+ Summary: A tool to generate and apply git diffs using LLMs
5
5
  Author: 255labs
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ License-File: LICENSE.txt
6
10
  Requires-Dist: openai>=1.0.0
7
11
  Requires-Dist: tiktoken>=0.5.0
8
12
  Requires-Dist: ai_agent_toolbox>=0.1.0
@@ -13,6 +17,7 @@ Provides-Extra: docs
13
17
  Requires-Dist: mkdocs; extra == "docs"
14
18
  Requires-Dist: mkdocs-material; extra == "docs"
15
19
  Dynamic: author
20
+ Dynamic: classifier
16
21
  Dynamic: provides-extra
17
22
  Dynamic: requires-dist
18
23
  Dynamic: summary
@@ -0,0 +1,8 @@
1
+ gptdiff/__init__.py,sha256=yGjgwv7tNvH1ZLPsQyoo1CxpTOl1iCAwwDBp-_17ksQ,89
2
+ gptdiff/gptdiff.py,sha256=40LKJt8GfGpk6J0mhQgM88DA6w5QdWmEUXtys1keatk,23253
3
+ gptdiff-0.1.2.dist-info/LICENSE.txt,sha256=zCJk7yUYpMjFvlipi1dKtaljF8WdZ2NASndBYYbU8BY,1228
4
+ gptdiff-0.1.2.dist-info/METADATA,sha256=KwzE5yYyc3XAIY09YWxDezGVLLlBLPNQTMgl6lQ3Ttk,709
5
+ gptdiff-0.1.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
6
+ gptdiff-0.1.2.dist-info/entry_points.txt,sha256=0yvXYEVAZFI-p32kQ4-h3qKVWS0a86jsM9FAwF89t9w,49
7
+ gptdiff-0.1.2.dist-info/top_level.txt,sha256=XNkQkQGINaDndEwRxg8qToOrJ9coyfAb-EHrSUXzdCE,8
8
+ gptdiff-0.1.2.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- gptdiff/__init__.py,sha256=yGjgwv7tNvH1ZLPsQyoo1CxpTOl1iCAwwDBp-_17ksQ,89
2
- gptdiff/gptdiff.py,sha256=MBSZgt43Qq3SRqGzlKwBawwIv1Uewm2NaA_DBx_IPB8,22965
3
- gptdiff-0.1.0.dist-info/METADATA,sha256=pf6BzIRLbLCeqVX3u_dwAG91WmPXKmVReTkwUWagPyk,508
4
- gptdiff-0.1.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
5
- gptdiff-0.1.0.dist-info/entry_points.txt,sha256=0yvXYEVAZFI-p32kQ4-h3qKVWS0a86jsM9FAwF89t9w,49
6
- gptdiff-0.1.0.dist-info/top_level.txt,sha256=XNkQkQGINaDndEwRxg8qToOrJ9coyfAb-EHrSUXzdCE,8
7
- gptdiff-0.1.0.dist-info/RECORD,,