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 +21 -16
- gptdiff-0.1.2.dist-info/LICENSE.txt +10 -0
- {gptdiff-0.1.0.dist-info → gptdiff-0.1.2.dist-info}/METADATA +7 -2
- gptdiff-0.1.2.dist-info/RECORD +8 -0
- gptdiff-0.1.0.dist-info/RECORD +0 -7
- {gptdiff-0.1.0.dist-info → gptdiff-0.1.2.dist-info}/WHEEL +0 -0
- {gptdiff-0.1.0.dist-info → gptdiff-0.1.2.dist-info}/entry_points.txt +0 -0
- {gptdiff-0.1.0.dist-info → gptdiff-0.1.2.dist-info}/top_level.txt +0 -0
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('
|
163
|
+
api_key = os.getenv('GPTDIFF_LLM_API_KEY')
|
164
164
|
if base_url is None:
|
165
|
-
base_url = os.getenv('
|
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=
|
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=
|
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=
|
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('
|
426
|
+
api_key = os.getenv('GPTDIFF_LLM_API_KEY')
|
424
427
|
if base_url is None:
|
425
|
-
base_url = os.getenv('
|
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('
|
511
|
-
print("\033[1;31mError:
|
512
|
-
print("Set it with: export
|
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('
|
525
|
-
base_url=os.getenv('
|
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.
|
4
|
-
Summary: A tool to generate git diffs using
|
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,,
|
gptdiff-0.1.0.dist-info/RECORD
DELETED
@@ -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,,
|
File without changes
|
File without changes
|
File without changes
|