FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
codeless/start.py at main · josephbruce/codeless · GitHub
josephbruce
codeless
Repository navigation
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
codeless
/
start.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
172 lines (145 loc) · 6.37 KB
Breadcrumbs
codeless
/
start.py
Copy path
File metadata and controls
172 lines (145 loc) · 6.37 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# Create project dir, then watch it for changes
# If new interface file: enter test iteration loop.
# If test changes and compiles, enter impl iteration loop.
#
# Test iteration loop
# 1. Run test gen w/compile loop
# 2. When compiles, pause and ask user to nudge when ready.
# 3. Start impl iteration loop
#
# Impl iteration loop
# 1. Impl generation/test loop.
# 2. Notify user when done, or when giving up.
from
agents
import
impl_generator
from
agents
import
test_generator
from
dotenv
import
load_dotenv
from
enum
import
Enum
from
watchdog
.
events
import
FileSystemEventHandler
from
watchdog
.
observers
import
Observer
import
logfire
import
os
import
py_compile
import
sys
import
time
import
unittest
def
run_tests
(
start_dir
:
str
)
->
tuple
[
bool
,
str
]:
test_suite
=
unittest
.
defaultTestLoader
.
discover
(
start_dir
=
start_dir
,
pattern
=
'*_test.py'
)
runner
=
unittest
.
TextTestRunner
(
verbosity
=
2
)
result
:
unittest
.
TextTestResult
=
runner
.
run
(
test_suite
)
if
result
.
wasSuccessful
():
return
True
,
''
else
:
output
=
[]
if
result
.
errors
:
output
.
append
(
"
\n
Errors:"
)
for
test
,
err
in
result
.
errors
:
output
.
append
(
f" Test:
{
test
}
"
)
output
.
append
(
f" Error:
{
err
}
"
)
if
result
.
failures
:
output
.
append
(
"
\n
Failures:"
)
for
test
,
fail
in
result
.
failures
:
output
.
append
(
f" Test:
{
test
}
"
)
output
.
append
(
f" Failure:
{
fail
}
"
)
return
False
,
'
\n
'
.
join
(
output
)
def
try_compile_file
(
code_file
:
str
)
->
str
:
try
:
py_compile
.
compile
(
code_file
,
doraise
=
True
)
return
''
except
py_compile
.
PyCompileError
as
e
:
return
str
(
e
)
class
FileKind
(
Enum
):
IFACE
=
1
TEST
=
2
IMPL
=
3
def
guess_file_kind
(
filename
:
str
)
->
FileKind
:
if
'_impl'
in
filename
:
return
FileKind
.
IMPL
if
'_test'
in
filename
:
return
FileKind
.
TEST
return
FileKind
.
IFACE
class
ProjectEventHandler
(
FileSystemEventHandler
):
def
__init__
(
self
,
working_dir
:
str
,
test_gen
:
test_generator
.
TestGenerator
,
impl_gen
:
impl_generator
.
ImplGenerator
):
self
.
_test_gen
=
test_gen
self
.
_impl_gen
=
impl_gen
self
.
_working_dir
=
working_dir
def
test_iteration_loop
(
self
,
iface_path
:
str
)
->
None
:
"""Iterates on test creation, returning the finished file."""
with
open
(
iface_path
,
'r'
)
as
iface_file
:
iface_str
=
iface_file
.
read
()
test_path
=
iface_path
.
replace
(
'.py'
,
'_test.py'
)
request
=
test_generator
.
TestGenerationRequest
(
interface_str
=
iface_str
)
test_str
=
self
.
_test_gen
.
str_to_file
(
request
,
test_path
)
if
compilation_error
:=
try_compile_file
(
test_path
):
attempt
=
test_generator
.
GenerationAttempt
(
code
=
test_str
,
errors
=
compilation_error
)
request
=
test_generator
.
TestGenerationRequest
(
interface_str
=
iface_str
,
prior_attempts
=
[
attempt
])
test_str
=
self
.
_test_gen
.
str_to_file
(
request
,
test_path
)
def
impl_iteration_loop
(
self
,
iface_path
:
str
,
test_path
:
str
)
->
None
:
"""Iterates on impl creation, returning the finished file."""
with
open
(
iface_path
,
'r'
)
as
iface_file
:
iface_str
=
iface_file
.
read
()
with
open
(
test_path
,
'r'
)
as
test_file
:
test_str
=
test_file
.
read
()
impl_path
=
iface_path
.
replace
(
'.py'
,
'_impl.py'
)
request
=
impl_generator
.
ImplGenerationRequest
(
iface_str
,
test_str
)
impl_str
=
self
.
_impl_gen
.
str_to_file
(
request
,
impl_path
)
tests_pass
,
test_output
=
run_tests
(
self
.
_working_dir
)
attempts
=
[]
while
not
tests_pass
:
attempts
.
append
(
impl_generator
.
GenerationAttempt
(
code
=
impl_str
,
errors
=
test_output
))
request
=
impl_generator
.
ImplGenerationRequest
(
iface_str
,
test_str
,
attempts
)
impl_str
=
self
.
_impl_gen
.
str_to_file
(
request
,
impl_path
)
tests_pass
,
test_output
=
run_tests
(
self
.
_working_dir
)
def
on_created
(
self
,
event
):
if
not
event
.
is_directory
:
print
(
f'File created:
{
event
.
src_path
}
'
)
kind
=
guess_file_kind
(
event
.
src_path
)
if
kind
==
FileKind
.
IFACE
:
input
(
f"Interface file
{
event
.
src_path
}
detected. Press Enter to continue generating tests."
)
if
compilation_errors
:=
try_compile_file
(
event
.
src_path
):
print
(
f'Your interface file has errors:
{
compilation_errors
}
'
)
else
:
self
.
test_iteration_loop
(
event
.
src_path
)
def
on_modified
(
self
,
event
):
if
not
event
.
is_directory
:
print
(
f'File modified:
{
event
.
src_path
}
'
)
kind
=
guess_file_kind
(
event
.
src_path
)
if
kind
==
FileKind
.
IFACE
:
if
compilation_errors
:=
try_compile_file
(
event
.
src_path
):
print
(
f'Your interface file has errors:
{
compilation_errors
}
'
)
else
:
input
(
f"Interface file
{
event
.
src_path
}
change detected. Press Enter to continue generating tests."
)
self
.
test_iteration_loop
(
event
.
src_path
)
if
kind
==
FileKind
.
TEST
:
if
compilation_error
:=
try_compile_file
(
event
.
src_path
):
print
(
f'Test file
{
event
.
src_path
}
has errors:
{
compilation_error
}
'
)
else
:
input
(
f"Test file
{
event
.
src_path
}
change detected. Press Enter to continue implementing the interface."
)
iface_path
=
event
.
src_path
.
replace
(
'_impl.py'
,
'.py'
)
self
.
impl_iteration_loop
(
iface_path
,
event
.
src_path
)
def
on_deleted
(
self
,
event
):
pass
def
on_moved
(
self
,
event
):
pass
def
main
(
project_id
:
str
):
load_dotenv
()
logfire
.
configure
(
send_to_logfire
=
'if-token-present'
)
project_dir
=
os
.
path
.
join
(
'output'
,
project_id
)
os
.
makedirs
(
project_dir
,
exist_ok
=
True
)
model
=
'claude-3-5-sonnet-latest'
test_gen
=
test_generator
.
TestGenerator
(
model_str
=
model
)
impl_gen
=
impl_generator
.
ImplGenerator
(
model_str
=
model
)
event_handler
=
ProjectEventHandler
(
project_dir
,
test_gen
,
impl_gen
)
observer
=
Observer
()
observer
.
schedule
(
event_handler
,
project_dir
,
recursive
=
False
)
observer
.
start
()
try
:
while
True
:
time
.
sleep
(
1
)
except
KeyboardInterrupt
:
observer
.
stop
()
observer
.
join
()
if
__name__
==
"__main__"
:
if
len
(
sys
.
argv
)
<
2
:
print
(
'Usage: cli <unique project ID>'
)
else
:
main
(
sys
.
argv
[
1
])
Back
|
FazBrowse Home
|
New Git URL