indent 0.1.11__py3-none-any.whl → 0.1.13__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.
- exponent/__init__.py +2 -2
- exponent/commands/cloud_commands.py +582 -0
- exponent/commands/common.py +4 -9
- exponent/commands/run_commands.py +20 -9
- exponent/commands/workflow_commands.py +1 -1
- exponent/core/graphql/client.py +5 -3
- exponent/core/graphql/mutations.py +114 -0
- exponent/core/graphql/queries.py +23 -0
- exponent/core/remote_execution/cli_rpc_types.py +17 -0
- exponent/core/remote_execution/client.py +108 -19
- exponent/core/remote_execution/file_write.py +0 -375
- exponent/core/remote_execution/types.py +1 -7
- exponent/core/types/generated/strategy_info.py +0 -12
- {indent-0.1.11.dist-info → indent-0.1.13.dist-info}/METADATA +3 -3
- {indent-0.1.11.dist-info → indent-0.1.13.dist-info}/RECORD +17 -17
- {indent-0.1.11.dist-info → indent-0.1.13.dist-info}/WHEEL +0 -0
- {indent-0.1.11.dist-info → indent-0.1.13.dist-info}/entry_points.txt +0 -0
|
@@ -1,85 +1,13 @@
|
|
|
1
|
-
import logging
|
|
2
1
|
import os
|
|
3
|
-
import re
|
|
4
|
-
import subprocess
|
|
5
|
-
from collections.abc import Callable
|
|
6
|
-
from textwrap import dedent, indent
|
|
7
2
|
|
|
8
3
|
from anyio import Path as AsyncPath
|
|
9
|
-
from diff_match_patch import diff_match_patch
|
|
10
|
-
from pydantic import BaseModel
|
|
11
4
|
|
|
12
5
|
from exponent.core.remote_execution.types import (
|
|
13
6
|
FilePath,
|
|
14
|
-
FileWriteRequest,
|
|
15
|
-
FileWriteResponse,
|
|
16
7
|
)
|
|
17
8
|
from exponent.core.remote_execution.utils import (
|
|
18
|
-
assert_unreachable,
|
|
19
|
-
safe_read_file,
|
|
20
9
|
safe_write_file,
|
|
21
10
|
)
|
|
22
|
-
from exponent.core.types.command_data import (
|
|
23
|
-
WRITE_STRATEGY_FULL_FILE_REWRITE,
|
|
24
|
-
WRITE_STRATEGY_NATURAL_EDIT,
|
|
25
|
-
WRITE_STRATEGY_SEARCH_REPLACE,
|
|
26
|
-
WRITE_STRATEGY_UDIFF,
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
logger = logging.getLogger(__name__)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class FileEditResult(BaseModel):
|
|
33
|
-
content: str | None
|
|
34
|
-
failed_edits: list[tuple[str, str]]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
async def execute_file_write(
|
|
38
|
-
event: FileWriteRequest, working_directory: str
|
|
39
|
-
) -> FileWriteResponse:
|
|
40
|
-
write_strategy = event.write_strategy
|
|
41
|
-
content = event.content
|
|
42
|
-
|
|
43
|
-
if write_strategy == WRITE_STRATEGY_FULL_FILE_REWRITE:
|
|
44
|
-
result = await execute_full_file_rewrite(
|
|
45
|
-
event.file_path, content, working_directory
|
|
46
|
-
)
|
|
47
|
-
elif write_strategy == WRITE_STRATEGY_UDIFF:
|
|
48
|
-
result = await execute_udiff_edit(event.file_path, content, working_directory)
|
|
49
|
-
elif write_strategy == WRITE_STRATEGY_SEARCH_REPLACE:
|
|
50
|
-
result = await execute_search_replace_edit(
|
|
51
|
-
event.file_path, content, working_directory
|
|
52
|
-
)
|
|
53
|
-
elif write_strategy == WRITE_STRATEGY_NATURAL_EDIT:
|
|
54
|
-
result = await execute_full_file_rewrite(
|
|
55
|
-
event.file_path, content, working_directory
|
|
56
|
-
)
|
|
57
|
-
else:
|
|
58
|
-
assert_unreachable(write_strategy)
|
|
59
|
-
return FileWriteResponse(
|
|
60
|
-
content=result,
|
|
61
|
-
correlation_id=event.correlation_id,
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def lint_file(file_path: str, working_directory: str) -> str:
|
|
66
|
-
try:
|
|
67
|
-
# Construct the absolute path
|
|
68
|
-
full_file_path = os.path.join(working_directory, file_path)
|
|
69
|
-
|
|
70
|
-
# Run ruff check --fix on the file
|
|
71
|
-
result = subprocess.run(
|
|
72
|
-
["ruff", "check", "--fix", full_file_path],
|
|
73
|
-
capture_output=True,
|
|
74
|
-
text=True,
|
|
75
|
-
check=True,
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
# If the subprocess ran successfully, return a success message
|
|
79
|
-
return f"Lint results:\n\n{result.stdout}\n\n{result.stderr}"
|
|
80
|
-
except Exception as e:
|
|
81
|
-
# For any other errors, return a generic error message
|
|
82
|
-
return f"An error occurred while linting: {e!s}"
|
|
83
11
|
|
|
84
12
|
|
|
85
13
|
async def execute_full_file_rewrite(
|
|
@@ -105,306 +33,3 @@ async def execute_full_file_rewrite(
|
|
|
105
33
|
|
|
106
34
|
except Exception as e:
|
|
107
35
|
return f"An error occurred: {e!s}"
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
async def execute_udiff_edit(
|
|
111
|
-
file_path: str, content: str, working_directory: str
|
|
112
|
-
) -> str:
|
|
113
|
-
return await execute_partial_edit(
|
|
114
|
-
file_path, content, working_directory, apply_udiff
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
async def execute_search_replace_edit(
|
|
119
|
-
file_path: str, content: str, working_directory: str
|
|
120
|
-
) -> str:
|
|
121
|
-
return await execute_partial_edit(
|
|
122
|
-
file_path, content, working_directory, apply_all_search_replace
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
async def execute_partial_edit(
|
|
127
|
-
file_path: str,
|
|
128
|
-
edit_content: str,
|
|
129
|
-
working_directory: str,
|
|
130
|
-
edit_function: Callable[[str, str], FileEditResult],
|
|
131
|
-
) -> str:
|
|
132
|
-
try:
|
|
133
|
-
# Construct the absolute path
|
|
134
|
-
full_file_path = AsyncPath(os.path.join(working_directory, file_path))
|
|
135
|
-
|
|
136
|
-
# Check if the directory exists, if not, create it
|
|
137
|
-
await full_file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
138
|
-
|
|
139
|
-
# Determine if the file exists and write the new content
|
|
140
|
-
file_content, created = await read_or_init_file(full_file_path)
|
|
141
|
-
|
|
142
|
-
success = await open_file_and_apply_edit(
|
|
143
|
-
file_path=full_file_path,
|
|
144
|
-
file_content=file_content,
|
|
145
|
-
edit_content=edit_content,
|
|
146
|
-
edit_function=edit_function,
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
if success:
|
|
150
|
-
verb = "Created" if created else "Modified"
|
|
151
|
-
return f"{verb} file {file_path}"
|
|
152
|
-
else:
|
|
153
|
-
verb = "create" if created else "modify"
|
|
154
|
-
return f"Failed to {verb} file {file_path}"
|
|
155
|
-
|
|
156
|
-
except Exception as e:
|
|
157
|
-
raise e
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
async def read_or_init_file(file_path: FilePath) -> tuple[str, bool]:
|
|
161
|
-
path = AsyncPath(file_path)
|
|
162
|
-
|
|
163
|
-
if not (await path.exists()):
|
|
164
|
-
await path.touch()
|
|
165
|
-
return "", True
|
|
166
|
-
|
|
167
|
-
content = await safe_read_file(path)
|
|
168
|
-
return content, False
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
async def open_file_and_apply_edit(
|
|
172
|
-
file_path: FilePath,
|
|
173
|
-
file_content: str,
|
|
174
|
-
edit_content: str,
|
|
175
|
-
edit_function: Callable[[str, str], FileEditResult],
|
|
176
|
-
) -> bool:
|
|
177
|
-
result = edit_function(file_content, edit_content)
|
|
178
|
-
|
|
179
|
-
if not result.content:
|
|
180
|
-
return False
|
|
181
|
-
|
|
182
|
-
await safe_write_file(file_path, result.content)
|
|
183
|
-
|
|
184
|
-
return True
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def find_leading_whitespace(existing_content: str, search: str) -> str | None:
|
|
188
|
-
existing_lines = existing_content.splitlines()
|
|
189
|
-
|
|
190
|
-
search_line_count = len(search.splitlines())
|
|
191
|
-
dedented_search = dedent(search)
|
|
192
|
-
|
|
193
|
-
for i in range(len(existing_lines)):
|
|
194
|
-
existing_window_content = "\n".join(existing_lines[i : i + search_line_count])
|
|
195
|
-
dedented_existing_window = dedent(existing_window_content)
|
|
196
|
-
|
|
197
|
-
leading_ws_len = len(existing_window_content) - len(
|
|
198
|
-
existing_window_content.lstrip()
|
|
199
|
-
)
|
|
200
|
-
leading_ws = existing_window_content[:leading_ws_len]
|
|
201
|
-
|
|
202
|
-
if dedented_existing_window == dedented_search:
|
|
203
|
-
return leading_ws
|
|
204
|
-
|
|
205
|
-
return None
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
def try_fix_whitespace(
|
|
209
|
-
existing_content: str, search: str, replace: str
|
|
210
|
-
) -> tuple[str, str] | None:
|
|
211
|
-
# Try to fix the whitespace of the search and replace
|
|
212
|
-
# to make the edit more likely to apply
|
|
213
|
-
leading_ws = find_leading_whitespace(existing_content, search)
|
|
214
|
-
if leading_ws is None:
|
|
215
|
-
return None
|
|
216
|
-
|
|
217
|
-
dedented_search = dedent(search)
|
|
218
|
-
dedented_replace = dedent(replace)
|
|
219
|
-
|
|
220
|
-
return indent(dedented_search, leading_ws), indent(dedented_replace, leading_ws)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
def try_search_replace(existing_content: str, search: str, replace: str) -> str | None:
|
|
224
|
-
# Try simple search and replace first
|
|
225
|
-
new_content = simple_search_and_replace(existing_content, search, replace)
|
|
226
|
-
if new_content:
|
|
227
|
-
return new_content
|
|
228
|
-
|
|
229
|
-
fixed_ws = try_fix_whitespace(existing_content, search, replace)
|
|
230
|
-
if not fixed_ws:
|
|
231
|
-
return None
|
|
232
|
-
|
|
233
|
-
search, replace = fixed_ws
|
|
234
|
-
|
|
235
|
-
new_content = simple_search_and_replace(existing_content, search, replace)
|
|
236
|
-
if new_content:
|
|
237
|
-
return new_content
|
|
238
|
-
|
|
239
|
-
return None
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
def try_diff_patch(existing_content: str, search: str, replace: str) -> str | None:
|
|
243
|
-
new_content = diff_patch_search_and_replace(existing_content, search, replace)
|
|
244
|
-
if new_content:
|
|
245
|
-
print("Applied diff patch search and replace")
|
|
246
|
-
return new_content
|
|
247
|
-
|
|
248
|
-
return None
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
def apply_udiff(existing_content: str, diff_content: str) -> FileEditResult:
|
|
252
|
-
hunks = get_raw_udiff_hunks(diff_content)
|
|
253
|
-
|
|
254
|
-
for hunk in hunks:
|
|
255
|
-
if not hunk:
|
|
256
|
-
continue
|
|
257
|
-
|
|
258
|
-
search, replace = split_hunk_for_search_and_replace(hunk)
|
|
259
|
-
|
|
260
|
-
# Exact match
|
|
261
|
-
new_content = try_search_replace(existing_content, search, replace)
|
|
262
|
-
if new_content is not None:
|
|
263
|
-
print("Applied successfully!")
|
|
264
|
-
return FileEditResult(content=new_content, failed_edits=[])
|
|
265
|
-
|
|
266
|
-
# Fuzzy match
|
|
267
|
-
new_content = try_diff_patch(existing_content, search, replace)
|
|
268
|
-
if new_content is not None:
|
|
269
|
-
print("Applied successfully!")
|
|
270
|
-
return FileEditResult(content=new_content, failed_edits=[])
|
|
271
|
-
|
|
272
|
-
print("Failed to apply hunk, exiting!")
|
|
273
|
-
return FileEditResult(content=None, failed_edits=[(search, replace)])
|
|
274
|
-
|
|
275
|
-
return FileEditResult(content=existing_content, failed_edits=[])
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
def get_raw_udiff_hunks(content: str) -> list[list[str]]:
|
|
279
|
-
lines = content.splitlines(keepends=True)
|
|
280
|
-
hunks: list[list[str]] = []
|
|
281
|
-
current_hunk: list[str] = []
|
|
282
|
-
for line in lines:
|
|
283
|
-
if line.startswith("@@"):
|
|
284
|
-
if current_hunk:
|
|
285
|
-
hunks.append(current_hunk)
|
|
286
|
-
current_hunk = []
|
|
287
|
-
else:
|
|
288
|
-
current_hunk.append(line)
|
|
289
|
-
if current_hunk:
|
|
290
|
-
hunks.append(current_hunk)
|
|
291
|
-
return hunks
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
def split_hunk_for_search_and_replace(hunk: list[str]) -> tuple[str, str]:
|
|
295
|
-
search_lines = []
|
|
296
|
-
replace_lines = []
|
|
297
|
-
|
|
298
|
-
search_prefixes = ["-", " "]
|
|
299
|
-
replace_prefixes = ["+", " "]
|
|
300
|
-
for line in hunk:
|
|
301
|
-
if not line:
|
|
302
|
-
continue
|
|
303
|
-
prefix, content = line[0], line[1:]
|
|
304
|
-
if not content:
|
|
305
|
-
continue
|
|
306
|
-
if prefix in search_prefixes:
|
|
307
|
-
search_lines.append(content)
|
|
308
|
-
if prefix in replace_prefixes:
|
|
309
|
-
replace_lines.append(content)
|
|
310
|
-
return "".join(search_lines), "".join(replace_lines)
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
def simple_search_and_replace(content: str, search: str, replace: str) -> str | None:
|
|
314
|
-
if content.count(search) >= 1:
|
|
315
|
-
return content.replace(search, replace)
|
|
316
|
-
return None
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
def diff_patch_search_and_replace(
|
|
320
|
-
content: str, search: str, replace: str
|
|
321
|
-
) -> str | None:
|
|
322
|
-
patcher = diff_match_patch()
|
|
323
|
-
# 3 second tieout for computing diffs
|
|
324
|
-
patcher.Diff_Timeout = 3
|
|
325
|
-
patcher.Match_Threshold = 0.95
|
|
326
|
-
patcher.Match_Distance = 500
|
|
327
|
-
patcher.Match_MaxBits = 128
|
|
328
|
-
patcher.Patch_Margin = 32
|
|
329
|
-
search_vs_replace_diff = patcher.diff_main(search, replace, False)
|
|
330
|
-
|
|
331
|
-
# Simplify the diff as much as possible
|
|
332
|
-
patcher.diff_cleanupEfficiency(search_vs_replace_diff)
|
|
333
|
-
patcher.diff_cleanupSemantic(search_vs_replace_diff)
|
|
334
|
-
|
|
335
|
-
original_vs_search_diff = patcher.diff_main(search, content)
|
|
336
|
-
new_diffs = patcher.patch_make(search, search_vs_replace_diff)
|
|
337
|
-
# Offset the search vs. replace diffs with the offset
|
|
338
|
-
# of the search diff within the original content.
|
|
339
|
-
for new_diff in new_diffs:
|
|
340
|
-
new_diff.start1 = patcher.diff_xIndex(original_vs_search_diff, new_diff.start1)
|
|
341
|
-
new_diff.start2 = patcher.diff_xIndex(original_vs_search_diff, new_diff.start2)
|
|
342
|
-
|
|
343
|
-
new_content, successes = patcher.patch_apply(new_diffs, content)
|
|
344
|
-
if not all(successes):
|
|
345
|
-
return None
|
|
346
|
-
|
|
347
|
-
return str(new_content)
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
SEARCH_REPLACE_RE = re.compile(
|
|
351
|
-
r"[^<>]*<<<+\s*SEARCH\n((?P<search>.*?)\n)??===+\n((?P<replace>.*?)\n)??>>>+\s*?REPLACE\s*?[^<>]*",
|
|
352
|
-
re.DOTALL,
|
|
353
|
-
)
|
|
354
|
-
|
|
355
|
-
TAGGED_SEARCH_REPLACE_RE = re.compile(
|
|
356
|
-
r"<search>(?P<search>.*?)??</search>\s*?<replace>(?P<replace>.*?)??</replace>",
|
|
357
|
-
re.DOTALL,
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
def apply_search_replace(result: str, search: str, replace: str) -> str | None:
|
|
362
|
-
if not search and not replace:
|
|
363
|
-
# Nonsense
|
|
364
|
-
return None
|
|
365
|
-
|
|
366
|
-
if not search and not result:
|
|
367
|
-
# New file, just return replace
|
|
368
|
-
return replace
|
|
369
|
-
|
|
370
|
-
if not search.strip():
|
|
371
|
-
# Search on just whitespace,
|
|
372
|
-
# too dangerous to apply
|
|
373
|
-
return None
|
|
374
|
-
|
|
375
|
-
return try_search_replace(result, search, replace)
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
def apply_all_search_replace(
|
|
379
|
-
existing_content: str,
|
|
380
|
-
sr_content: str,
|
|
381
|
-
match_re: re.Pattern[str] = SEARCH_REPLACE_RE,
|
|
382
|
-
) -> FileEditResult:
|
|
383
|
-
# Same as apply_search_replace, but applies all search and replace pairs
|
|
384
|
-
# in the sr_content to the existing_content
|
|
385
|
-
|
|
386
|
-
result = existing_content
|
|
387
|
-
failed_edits: list[tuple[str, str]] = []
|
|
388
|
-
|
|
389
|
-
for match in match_re.finditer(sr_content):
|
|
390
|
-
match_dict = match.groupdict()
|
|
391
|
-
search, replace = match_dict.get("search"), match_dict.get("replace")
|
|
392
|
-
search = search or ""
|
|
393
|
-
replace = replace or ""
|
|
394
|
-
|
|
395
|
-
new_result = apply_search_replace(result, search, replace)
|
|
396
|
-
if new_result is None:
|
|
397
|
-
failed_edits.append((search, replace))
|
|
398
|
-
continue
|
|
399
|
-
|
|
400
|
-
result = new_result
|
|
401
|
-
|
|
402
|
-
return FileEditResult(content=result, failed_edits=failed_edits)
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
def apply_all_tagged_search_replace(
|
|
406
|
-
existing_content: str, sr_content: str
|
|
407
|
-
) -> FileEditResult:
|
|
408
|
-
return apply_all_search_replace(
|
|
409
|
-
existing_content, sr_content, TAGGED_SEARCH_REPLACE_RE
|
|
410
|
-
)
|
|
@@ -98,6 +98,7 @@ class HeartbeatInfo(BaseModel):
|
|
|
98
98
|
default_factory=lambda: datetime.datetime.now(datetime.UTC)
|
|
99
99
|
)
|
|
100
100
|
timestamp_received: datetime.datetime | None = None
|
|
101
|
+
cli_uuid: str | None = None
|
|
101
102
|
|
|
102
103
|
|
|
103
104
|
class RemoteFile(BaseModel):
|
|
@@ -505,17 +506,10 @@ class ChatMode(str, Enum):
|
|
|
505
506
|
CLI = "CLI"
|
|
506
507
|
CLOUD = "CLOUD" # chat with cloud devbox
|
|
507
508
|
CODEBASE = "CODEBASE" # chat with codebase
|
|
508
|
-
PYTHON_INTERPRETER = "PYTHON_INTERPRETER"
|
|
509
509
|
DATABASE = "DATABASE" # chat with database connection
|
|
510
510
|
WORKFLOW = "WORKFLOW"
|
|
511
511
|
|
|
512
512
|
|
|
513
|
-
DEVBOX_CHAT_MODES = [
|
|
514
|
-
ChatMode.CLOUD,
|
|
515
|
-
ChatMode.CODEBASE,
|
|
516
|
-
]
|
|
517
|
-
|
|
518
|
-
|
|
519
513
|
class ChatSource(str, Enum):
|
|
520
514
|
CLI_SHELL = "CLI_SHELL"
|
|
521
515
|
CLI_RUN = "CLI_RUN"
|
|
@@ -4,8 +4,6 @@ import enum
|
|
|
4
4
|
|
|
5
5
|
from pydantic import BaseModel
|
|
6
6
|
|
|
7
|
-
from exponent.core.remote_execution.types import ChatMode
|
|
8
|
-
|
|
9
7
|
|
|
10
8
|
class StrategyName(str, enum.Enum):
|
|
11
9
|
NATURAL_EDIT_CLAUDE_3_7_XML = "NATURAL_EDIT_CLAUDE_3_7_XML"
|
|
@@ -39,16 +37,6 @@ class StrategyInfo(BaseModel):
|
|
|
39
37
|
is_agentic: bool
|
|
40
38
|
|
|
41
39
|
|
|
42
|
-
CHAT_MODE_DEFAULTS: dict[ChatMode, StrategyName] = {
|
|
43
|
-
ChatMode.DEFAULT: StrategyName.RAW_GPT,
|
|
44
|
-
ChatMode.CLI: StrategyName.NATURAL_EDIT_CLAUDE_3_7_XML,
|
|
45
|
-
ChatMode.CLOUD: StrategyName.NATURAL_EDIT_CLAUDE_3_7_XML,
|
|
46
|
-
ChatMode.DATABASE: StrategyName.DATABASE,
|
|
47
|
-
ChatMode.PYTHON_INTERPRETER: StrategyName.NATURAL_EDIT_CLAUDE_3_7_XML,
|
|
48
|
-
ChatMode.WORKFLOW: StrategyName.NATURAL_EDIT_CLAUDE_3_7_XML,
|
|
49
|
-
ChatMode.CODEBASE: StrategyName.READ_ONLY,
|
|
50
|
-
}
|
|
51
|
-
|
|
52
40
|
STRATEGY_INFO_LIST: list[StrategyInfo] = [
|
|
53
41
|
StrategyInfo(
|
|
54
42
|
strategy_name=StrategyName.NATURAL_EDIT_CLAUDE_3_7_XML,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: indent
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.13
|
|
4
4
|
Summary: Indent is an AI Pair Programmer
|
|
5
5
|
Author-email: Sashank Thupukari <sashank@exponent.run>
|
|
6
6
|
Requires-Python: <3.13,>=3.10
|
|
@@ -14,7 +14,7 @@ Requires-Dist: diff-match-patch<20230431,>=20230430
|
|
|
14
14
|
Requires-Dist: eval-type-backport<0.3,>=0.2.0
|
|
15
15
|
Requires-Dist: git-python>=1.0.3
|
|
16
16
|
Requires-Dist: gitignore-parser<0.2,>=0.1.11
|
|
17
|
-
Requires-Dist: gql[httpx,websockets]
|
|
17
|
+
Requires-Dist: gql[httpx,websockets]~=4.0
|
|
18
18
|
Requires-Dist: httpx>=0.28.1
|
|
19
19
|
Requires-Dist: ipykernel<7,>=6.29.4
|
|
20
20
|
Requires-Dist: jupyter-client<9,>=8.6.1
|
|
@@ -32,4 +32,4 @@ Requires-Dist: rapidfuzz<4,>=3.9.0
|
|
|
32
32
|
Requires-Dist: rich<14,>=13.7.1
|
|
33
33
|
Requires-Dist: sentry-sdk<3,>=2.1.1
|
|
34
34
|
Requires-Dist: toml<0.11,>=0.10.2
|
|
35
|
-
Requires-Dist: websockets~=
|
|
35
|
+
Requires-Dist: websockets~=15.0
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
exponent/__init__.py,sha256=
|
|
1
|
+
exponent/__init__.py,sha256=Xz5RLbyPcCHHXte393JYfUy4Dt7uaeWyrGVw9SmJ0eg,706
|
|
2
2
|
exponent/cli.py,sha256=u3hhZnn5uqVXyNz6wU8j4U5vLJ--pbA-PweHhpvRzY4,3444
|
|
3
3
|
exponent/py.typed,sha256=9XZl5avs8yHp89XP_1Fjtbeg_2rjYorCC9I0k_j-h2c,334
|
|
4
|
-
exponent/commands/cloud_commands.py,sha256=
|
|
5
|
-
exponent/commands/common.py,sha256=
|
|
4
|
+
exponent/commands/cloud_commands.py,sha256=TNSbKnc7VBo7VALj44CqV5tdCACJejEGmtYvc5wjza4,19080
|
|
5
|
+
exponent/commands/common.py,sha256=6Xww3tdK2IGdlPvHZ6T_fJirO3PwZi3XCzVGSOhUWIw,13493
|
|
6
6
|
exponent/commands/config_commands.py,sha256=iVIX7LuoO5QshzZNSrfvw5yPIiLlce8GQSMBEp7-nzw,11415
|
|
7
|
-
exponent/commands/run_commands.py,sha256=
|
|
7
|
+
exponent/commands/run_commands.py,sha256=kowWiBtp4ZLQHBMG31fSotQ35ruGD3OfbPsMcbbnHU8,6240
|
|
8
8
|
exponent/commands/settings.py,sha256=UwwwoCgCY5hzAFD9slOBbA9Gr1hNfoyJ2blsFDC6V8w,1559
|
|
9
9
|
exponent/commands/types.py,sha256=iDJL3hdwhO1PrhsJTJBioNYSKo0CWV8Nv-ONcDaWIRs,3670
|
|
10
10
|
exponent/commands/upgrade.py,sha256=JZr0sNazziuLByQHdT8GZb-lDbRG1YpHW8VB94q-r8w,803
|
|
11
11
|
exponent/commands/utils.py,sha256=Z3eu3mvYwBh7J_hq17lyt7_MwMG8KcsP7AnsCgOnTNc,4638
|
|
12
|
-
exponent/commands/workflow_commands.py,sha256=
|
|
12
|
+
exponent/commands/workflow_commands.py,sha256=eQufFbKrKCZtewyDpuVe_0QcndbxuaIKHfHpHF8-XzI,3602
|
|
13
13
|
exponent/core/config.py,sha256=TNFLUgLnfSocRMVSav_7E4VcaNHXZ_3Mg5Lp1smP46U,5731
|
|
14
14
|
exponent/core/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
exponent/core/graphql/client.py,sha256=
|
|
15
|
+
exponent/core/graphql/client.py,sha256=SRagD3YPyoYZSO1RtfO-OXD7b5dm1NvgoL6CTbN380o,2009
|
|
16
16
|
exponent/core/graphql/get_chats_query.py,sha256=9-2N1VfapXUZB3IFIKw5U_gKdmfyviJp5JSUntB_Yyk,1177
|
|
17
17
|
exponent/core/graphql/github_config_queries.py,sha256=zKRDxF38q73apQcVaEAA_A20FVr3U0ADc5-8Y6Ns5Dw,1260
|
|
18
|
-
exponent/core/graphql/mutations.py,sha256=
|
|
19
|
-
exponent/core/graphql/queries.py,sha256=
|
|
18
|
+
exponent/core/graphql/mutations.py,sha256=cAAiSefyamBgy1zJEZ7LNk0rbjwawTPxMyj8eU6yRRI,3502
|
|
19
|
+
exponent/core/graphql/queries.py,sha256=RYsk8bub0esspqgakilhzX07yJf2652Ey9tBZK1l_lY,3297
|
|
20
20
|
exponent/core/graphql/subscriptions.py,sha256=SQngv_nYVNJjiZ_P2k0UcLIu1pzc4vi7q7lhH89NCZM,393
|
|
21
21
|
exponent/core/remote_execution/checkpoints.py,sha256=3QGYMLa8vT7XmxMYTRcGrW8kNGHwRC0AkUfULribJWg,6354
|
|
22
|
-
exponent/core/remote_execution/cli_rpc_types.py,sha256=
|
|
23
|
-
exponent/core/remote_execution/client.py,sha256=
|
|
22
|
+
exponent/core/remote_execution/cli_rpc_types.py,sha256=bmpfZASzzsD_NDIF2Mnym79km2fem8Oc0tSlSC-0EoY,7478
|
|
23
|
+
exponent/core/remote_execution/client.py,sha256=PzYG5bIHLxlGxVsIzzg2SX1X6G50hJ3XXV0Cai5tS7A,28911
|
|
24
24
|
exponent/core/remote_execution/code_execution.py,sha256=jYPB_7dJzS9BTPLX9fKQpsFPatwjbXuaFFSxT9tDTfI,2388
|
|
25
25
|
exponent/core/remote_execution/error_info.py,sha256=Rd7OA3ps06qYejPVcOaMBB9AtftP3wqQoOfiILFASnc,1378
|
|
26
26
|
exponent/core/remote_execution/exceptions.py,sha256=eT57lBnBhvh-KJ5lsKWcfgGA5-WisAxhjZx-Z6OupZY,135
|
|
27
|
-
exponent/core/remote_execution/file_write.py,sha256=
|
|
27
|
+
exponent/core/remote_execution/file_write.py,sha256=8Sa70ANIDHGxIAq4_Uy2Qoo55K7-cSzU3282zyu7hG8,978
|
|
28
28
|
exponent/core/remote_execution/files.py,sha256=mIVjhStaEKETW6y3pCVeV8eJKNaPtroWGP_kBK1x8uA,8776
|
|
29
29
|
exponent/core/remote_execution/git.py,sha256=dGjBpeoKJZsYgRwctSq29GmbsNIN9tbSA3VwBnRD0IQ,7810
|
|
30
30
|
exponent/core/remote_execution/http_fetch.py,sha256=aFEyXd0S-MRfisSMuIFiEyc1AEAj9nUZ9Rj_P_YRows,2827
|
|
@@ -32,7 +32,7 @@ exponent/core/remote_execution/session.py,sha256=jlQIdeUj0f7uOk3BgzlJtBJ_GyTIjCc
|
|
|
32
32
|
exponent/core/remote_execution/system_context.py,sha256=QY1zY8_fWj3sh-fmLYtewvgxh7uTX4ITIJqlUTDkj6c,648
|
|
33
33
|
exponent/core/remote_execution/tool_execution.py,sha256=ZBDC2RN_l8oCFO8Fc8dkKoLY_0rn-5h394PvWeXqTnI,12972
|
|
34
34
|
exponent/core/remote_execution/truncation.py,sha256=noB6c4eaebqq5ghTlYJkXbe2XY8Bz_GBeh9DazJUrrU,9644
|
|
35
|
-
exponent/core/remote_execution/types.py,sha256=
|
|
35
|
+
exponent/core/remote_execution/types.py,sha256=123sT6Uz2dE0X_Amw5nxyQd8haFblrikDC5jbDh1Pjg,14847
|
|
36
36
|
exponent/core/remote_execution/utils.py,sha256=6PlBqYJ3OQwZ0dgXiIu3br04a-d-glDeDZpD0XGGPAE,14793
|
|
37
37
|
exponent/core/remote_execution/languages/python_execution.py,sha256=nsX_LsXcUcHhiEHpSTjOTVNd7CxM146al0kw_iQX5OU,7724
|
|
38
38
|
exponent/core/remote_execution/languages/shell_streaming.py,sha256=eEhngdLhiMiDM0KUfLUtj6BdU3ay3G1zJy6dlR2V6nw,7389
|
|
@@ -41,12 +41,12 @@ exponent/core/types/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
41
41
|
exponent/core/types/command_data.py,sha256=_HqQsnamRZeVoVaTpeO3ecVUzNBdG62WXlFy6Q7rtUM,5294
|
|
42
42
|
exponent/core/types/event_types.py,sha256=Hi9OMlLwB8f0TwPsKMThkXLFVzvOyJfMWk2urjPD1Uo,2468
|
|
43
43
|
exponent/core/types/generated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
|
-
exponent/core/types/generated/strategy_info.py,sha256=
|
|
44
|
+
exponent/core/types/generated/strategy_info.py,sha256=LN6_ykFMszb21Qc3yw77xEKUtd7m4e-zzhPS1HZjvzE,6641
|
|
45
45
|
exponent/migration-docs/login.md,sha256=KIeXy3m2nzSUgw-4PW1XzXfHael1D4Zu93CplLMb3hI,4252
|
|
46
46
|
exponent/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
47
|
exponent/utils/colors.py,sha256=HBkqe_ZmhJ9YiL2Fpulqek4KvLS5mwBTY4LQSM5N8SM,2762
|
|
48
48
|
exponent/utils/version.py,sha256=dmSFUzspaGjehLr9y_PkGTAQe298M0TwK9PF8fv3EKA,8819
|
|
49
|
-
indent-0.1.
|
|
50
|
-
indent-0.1.
|
|
51
|
-
indent-0.1.
|
|
52
|
-
indent-0.1.
|
|
49
|
+
indent-0.1.13.dist-info/METADATA,sha256=awgxeJ-xbpUWcdHfr-2BzxOJiCJc6iHuF_myMRQhYq0,1273
|
|
50
|
+
indent-0.1.13.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
51
|
+
indent-0.1.13.dist-info/entry_points.txt,sha256=q8q1t1sbl4NULGOR0OV5RmSG4KEjkpEQRU_RUXEGzcs,44
|
|
52
|
+
indent-0.1.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|