gptdiff 0.1.20__tar.gz → 0.1.21__tar.gz
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-0.1.20 → gptdiff-0.1.21}/PKG-INFO +2 -2
- {gptdiff-0.1.20 → gptdiff-0.1.21}/gptdiff/gptdiff.py +10 -4
- {gptdiff-0.1.20 → gptdiff-0.1.21}/gptdiff.egg-info/PKG-INFO +2 -2
- {gptdiff-0.1.20 → gptdiff-0.1.21}/gptdiff.egg-info/requires.txt +1 -1
- {gptdiff-0.1.20 → gptdiff-0.1.21}/setup.py +2 -2
- gptdiff-0.1.21/tests/test_swallow_reasoning.py +156 -0
- gptdiff-0.1.20/tests/test_swallow_reasoning.py +0 -51
- {gptdiff-0.1.20 → gptdiff-0.1.21}/LICENSE.txt +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/README.md +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/gptdiff/__init__.py +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/gptdiff/gptpatch.py +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/gptdiff.egg-info/SOURCES.txt +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/gptdiff.egg-info/dependency_links.txt +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/gptdiff.egg-info/entry_points.txt +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/gptdiff.egg-info/top_level.txt +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/setup.cfg +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/tests/test_applydiff.py +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/tests/test_applydiff_edgecases.py +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/tests/test_diff_parse.py +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/tests/test_failing_case.py +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/tests/test_parse_diff_per_file.py +0 -0
- {gptdiff-0.1.20 → gptdiff-0.1.21}/tests/test_smartapply.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: gptdiff
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.21
|
4
4
|
Summary: A tool to generate and apply git diffs using LLMs
|
5
5
|
Author: 255labs
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -10,7 +10,7 @@ Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE.txt
|
11
11
|
Requires-Dist: openai>=1.0.0
|
12
12
|
Requires-Dist: tiktoken>=0.5.0
|
13
|
-
Requires-Dist:
|
13
|
+
Requires-Dist: ai-agent-toolbox>=0.1.15
|
14
14
|
Provides-Extra: test
|
15
15
|
Requires-Dist: pytest; extra == "test"
|
16
16
|
Requires-Dist: pytest-mock; extra == "test"
|
@@ -985,17 +985,23 @@ def swallow_reasoning(full_response: str) -> (str, str):
|
|
985
985
|
- reasoning: The extracted reasoning block, or an empty string if not found.
|
986
986
|
"""
|
987
987
|
pattern = re.compile(
|
988
|
-
r"(?P<reasoning>>\s*Reasoning.*?Reasoned
|
988
|
+
r"(?P<reasoning>>\s*Reasoning.*?Reasoned.*?seconds)",
|
989
989
|
re.DOTALL
|
990
990
|
)
|
991
991
|
match = pattern.search(full_response)
|
992
992
|
if match:
|
993
|
-
|
994
|
-
|
993
|
+
raw_reasoning = match.group("reasoning")
|
994
|
+
# Remove any leading '+' characters and extra whitespace from each line
|
995
|
+
reasoning_lines = [line.lstrip('+').strip() for line in raw_reasoning.splitlines()]
|
996
|
+
reasoning = "\n".join(reasoning_lines).strip()
|
997
|
+
|
998
|
+
# Remove the reasoning block from the response using its exact span
|
999
|
+
final_content = full_response[:match.start()] + full_response[match.end():]
|
1000
|
+
final_content = final_content.strip()
|
995
1001
|
else:
|
996
1002
|
reasoning = ""
|
997
1003
|
final_content = full_response.strip()
|
998
1004
|
return final_content, reasoning
|
999
1005
|
|
1000
1006
|
if __name__ == "__main__":
|
1001
|
-
main()
|
1007
|
+
main()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: gptdiff
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.21
|
4
4
|
Summary: A tool to generate and apply git diffs using LLMs
|
5
5
|
Author: 255labs
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
@@ -10,7 +10,7 @@ Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE.txt
|
11
11
|
Requires-Dist: openai>=1.0.0
|
12
12
|
Requires-Dist: tiktoken>=0.5.0
|
13
|
-
Requires-Dist:
|
13
|
+
Requires-Dist: ai-agent-toolbox>=0.1.15
|
14
14
|
Provides-Extra: test
|
15
15
|
Requires-Dist: pytest; extra == "test"
|
16
16
|
Requires-Dist: pytest-mock; extra == "test"
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
2
2
|
|
3
3
|
setup(
|
4
4
|
name='gptdiff',
|
5
|
-
version='0.1.
|
5
|
+
version='0.1.21',
|
6
6
|
description='A tool to generate and apply git diffs using LLMs',
|
7
7
|
author='255labs',
|
8
8
|
packages=find_packages(), # Use find_packages() to automatically discover packages
|
@@ -12,7 +12,7 @@ setup(
|
|
12
12
|
install_requires=[
|
13
13
|
'openai>=1.0.0',
|
14
14
|
'tiktoken>=0.5.0',
|
15
|
-
'
|
15
|
+
'ai-agent-toolbox>=0.1.15'
|
16
16
|
],
|
17
17
|
extras_require={
|
18
18
|
'test': ['pytest', 'pytest-mock'],
|
@@ -0,0 +1,156 @@
|
|
1
|
+
import pytest
|
2
|
+
|
3
|
+
from gptdiff.gptdiff import swallow_reasoning
|
4
|
+
|
5
|
+
def test_swallow_reasoning_extraction():
|
6
|
+
llm_response = (
|
7
|
+
"+> Reasoning\n"
|
8
|
+
"+None\n"
|
9
|
+
"+Reasoned about summary drawer button 변경 for 15 seconds\n"
|
10
|
+
"+def new():\n"
|
11
|
+
"```"
|
12
|
+
)
|
13
|
+
final_content, reasoning = swallow_reasoning(llm_response)
|
14
|
+
expected_reasoning = (
|
15
|
+
"> Reasoning\n"
|
16
|
+
"**Applying the diff**\n"
|
17
|
+
"I'm piecing together how to efficiently apply a diff to a file...\n"
|
18
|
+
"**Returning the result**\n"
|
19
|
+
"I'm finalizing the method to apply the diff updates...\n"
|
20
|
+
"Reasoned for 6 seconds"
|
21
|
+
)
|
22
|
+
assert reasoning == expected_reasoning
|
23
|
+
# The final content should no longer contain the reasoning block.
|
24
|
+
assert expected_reasoning not in final_content
|
25
|
+
# And it should contain the diff block.
|
26
|
+
assert "```diff" in final_content
|
27
|
+
|
28
|
+
|
29
|
+
def test_swallow_reasoning_with_untested_response():
|
30
|
+
llm_response = (
|
31
|
+
"> Reasoning\n"
|
32
|
+
"**Considering the request**\n"
|
33
|
+
"I’m noting that the user wants me to apply a diff to a file and return the result in a block, ensuring the entire file is included.\n"
|
34
|
+
"**Ensuring comprehensive inclusion**\n"
|
35
|
+
"I'm making sure the entire file is included when presenting the result in a block, following the user's request carefully.\n"
|
36
|
+
"**Ensuring clarity**\n"
|
37
|
+
"I’m integrating the diff into the file and ensuring the entire file is returned as requested. This approach maintains precision and clarity in the response.\n"
|
38
|
+
"**Refining the response**\n"
|
39
|
+
"I’m focusing on how to structure the response by carefully integrating the diff and ensuring the entire file is included in a clear block format.\n"
|
40
|
+
"**Connecting the pieces**\n"
|
41
|
+
"I'm mapping out how to apply the diff to the file carefully and ensure the entire file is incorporated into the final block.\n"
|
42
|
+
"Reasoned for a few seconds\n"
|
43
|
+
"\n"
|
44
|
+
"```diff\n"
|
45
|
+
"--- a/file.py\n"
|
46
|
+
"+++ b/file.py\n"
|
47
|
+
"@@ -1,2 +1,2 @@\n"
|
48
|
+
"-def old():\n"
|
49
|
+
"+def new():\n"
|
50
|
+
"```"
|
51
|
+
)
|
52
|
+
final_content, reasoning = swallow_reasoning(llm_response)
|
53
|
+
|
54
|
+
expected_reasoning = (
|
55
|
+
"> Reasoning\n"
|
56
|
+
"**Considering the request**\n"
|
57
|
+
"I’m noting that the user wants me to apply a diff to a file and return the result in a block, ensuring the entire file is included.\n"
|
58
|
+
"**Ensuring comprehensive inclusion**\n"
|
59
|
+
"I'm making sure the entire file is included when presenting the result in a block, following the user's request carefully.\n"
|
60
|
+
"**Ensuring clarity**\n"
|
61
|
+
"I’m integrating the diff into the file and ensuring the entire file is returned as requested. This approach maintains precision and clarity in the response.\n"
|
62
|
+
"**Refining the response**\n"
|
63
|
+
"I’m focusing on how to structure the response by carefully integrating the diff and ensuring the entire file is included in a clear block format.\n"
|
64
|
+
"**Connecting the pieces**\n"
|
65
|
+
"I'm mapping out how to apply the diff to the file carefully and ensure the entire file is incorporated into the final block.\n"
|
66
|
+
"Reasoned for a few seconds"
|
67
|
+
)
|
68
|
+
|
69
|
+
assert reasoning == expected_reasoning
|
70
|
+
# The final content should no longer contain the reasoning block.
|
71
|
+
assert expected_reasoning not in final_content
|
72
|
+
# And it should contain the diff block.
|
73
|
+
assert "```diff" in final_content
|
74
|
+
|
75
|
+
def test_swallow_reasoning_extraction():
|
76
|
+
llm_response = (
|
77
|
+
"> Reasoning\n"
|
78
|
+
"**Applying the diff**\n"
|
79
|
+
"I'm piecing together how to efficiently apply a diff to a file...\n"
|
80
|
+
"**Returning the result**\n"
|
81
|
+
"I'm finalizing the method to apply the diff updates...\n"
|
82
|
+
"Reasoned for 6 seconds\n"
|
83
|
+
"\n"
|
84
|
+
"```diff\n"
|
85
|
+
"--- a/file.py\n"
|
86
|
+
"+++ b/file.py\n"
|
87
|
+
"@@ -1,2 +1,2 @@\n"
|
88
|
+
"-def old():\n"
|
89
|
+
"+def new():\n"
|
90
|
+
"```"
|
91
|
+
)
|
92
|
+
final_content, reasoning = swallow_reasoning(llm_response)
|
93
|
+
expected_reasoning = (
|
94
|
+
"> Reasoning\n"
|
95
|
+
"**Applying the diff**\n"
|
96
|
+
"I'm piecing together how to efficiently apply a diff to a file...\n"
|
97
|
+
"**Returning the result**\n"
|
98
|
+
"I'm finalizing the method to apply the diff updates...\n"
|
99
|
+
"Reasoned for 6 seconds"
|
100
|
+
)
|
101
|
+
assert reasoning == expected_reasoning
|
102
|
+
# The final content should no longer contain the reasoning block.
|
103
|
+
assert expected_reasoning not in final_content
|
104
|
+
# And it should contain the diff block.
|
105
|
+
assert "```diff" in final_content
|
106
|
+
|
107
|
+
|
108
|
+
def test_swallow_reasoning_no_reasoning():
|
109
|
+
llm_response = (
|
110
|
+
"```diff\n"
|
111
|
+
"--- a/file.py\n"
|
112
|
+
"+++ b/file.py\n"
|
113
|
+
"@@ -1,2 +1,2 @@\n"
|
114
|
+
"-def old():\n"
|
115
|
+
"+def new():\n"
|
116
|
+
"```"
|
117
|
+
)
|
118
|
+
final_content, reasoning = swallow_reasoning(llm_response)
|
119
|
+
assert reasoning == ""
|
120
|
+
assert final_content == llm_response.strip()
|
121
|
+
|
122
|
+
def test_swallow_reasoning_inline_newlines():
|
123
|
+
llm_response = (
|
124
|
+
"Prefix text before reasoning and some inline content "
|
125
|
+
"> Reasoning\n"
|
126
|
+
"Inline line 1\n"
|
127
|
+
"Inline line 2\n"
|
128
|
+
"Reasoned for 2 seconds "
|
129
|
+
"and then suffix text.\n"
|
130
|
+
"```diff\n"
|
131
|
+
"--- a/inline.py\n"
|
132
|
+
"+++ b/inline.py\n"
|
133
|
+
"@@ -1,2 +1,2 @@\n"
|
134
|
+
"-print('Old')\n"
|
135
|
+
"+print('New')\n"
|
136
|
+
"```"
|
137
|
+
)
|
138
|
+
final_content, reasoning = swallow_reasoning(llm_response)
|
139
|
+
expected_reasoning = (
|
140
|
+
"> Reasoning\n"
|
141
|
+
"Inline line 1\n"
|
142
|
+
"Inline line 2\n"
|
143
|
+
"Reasoned for 2 seconds"
|
144
|
+
)
|
145
|
+
# Count the newlines in the extracted reasoning block.
|
146
|
+
newline_count = reasoning.count('\n')
|
147
|
+
# There should be 3 newline characters: after "> Reasoning", after "Inline line 1", and after "Inline line 2"
|
148
|
+
assert newline_count == 3, f"Expected 3 newlines, got {newline_count}"
|
149
|
+
assert reasoning == expected_reasoning
|
150
|
+
# Ensure the reasoning block is removed from the final content.
|
151
|
+
assert expected_reasoning not in final_content
|
152
|
+
# Verify that surrounding content remains.
|
153
|
+
assert "Prefix text before reasoning" in final_content
|
154
|
+
assert "and then suffix text." in final_content
|
155
|
+
# Verify that the diff block is still present.
|
156
|
+
assert "```diff" in final_content
|
@@ -1,51 +0,0 @@
|
|
1
|
-
import pytest
|
2
|
-
|
3
|
-
from gptdiff.gptdiff import swallow_reasoning
|
4
|
-
|
5
|
-
|
6
|
-
def test_swallow_reasoning_extraction():
|
7
|
-
llm_response = (
|
8
|
-
"> Reasoning\n"
|
9
|
-
"**Applying the diff**\n"
|
10
|
-
"I'm piecing together how to efficiently apply a diff to a file...\n"
|
11
|
-
"**Returning the result**\n"
|
12
|
-
"I'm finalizing the method to apply the diff updates...\n"
|
13
|
-
"Reasoned for 6 seconds\n"
|
14
|
-
"\n"
|
15
|
-
"```diff\n"
|
16
|
-
"--- a/file.py\n"
|
17
|
-
"+++ b/file.py\n"
|
18
|
-
"@@ -1,2 +1,2 @@\n"
|
19
|
-
"-def old():\n"
|
20
|
-
"+def new():\n"
|
21
|
-
"```"
|
22
|
-
)
|
23
|
-
final_content, reasoning = swallow_reasoning(llm_response)
|
24
|
-
expected_reasoning = (
|
25
|
-
"> Reasoning\n"
|
26
|
-
"**Applying the diff**\n"
|
27
|
-
"I'm piecing together how to efficiently apply a diff to a file...\n"
|
28
|
-
"**Returning the result**\n"
|
29
|
-
"I'm finalizing the method to apply the diff updates...\n"
|
30
|
-
"Reasoned for 6 seconds"
|
31
|
-
)
|
32
|
-
assert reasoning == expected_reasoning
|
33
|
-
# The final content should no longer contain the reasoning block.
|
34
|
-
assert expected_reasoning not in final_content
|
35
|
-
# And it should contain the diff block.
|
36
|
-
assert "```diff" in final_content
|
37
|
-
|
38
|
-
|
39
|
-
def test_swallow_reasoning_no_reasoning():
|
40
|
-
llm_response = (
|
41
|
-
"```diff\n"
|
42
|
-
"--- a/file.py\n"
|
43
|
-
"+++ b/file.py\n"
|
44
|
-
"@@ -1,2 +1,2 @@\n"
|
45
|
-
"-def old():\n"
|
46
|
-
"+def new():\n"
|
47
|
-
"```"
|
48
|
-
)
|
49
|
-
final_content, reasoning = swallow_reasoning(llm_response)
|
50
|
-
assert reasoning == ""
|
51
|
-
assert final_content == llm_response.strip()
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|