transpilatron 0.1.0__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.
- transpilatron-0.1.0/.env +1 -0
- transpilatron-0.1.0/.python-version +1 -0
- transpilatron-0.1.0/PKG-INFO +22 -0
- transpilatron-0.1.0/README.md +12 -0
- transpilatron-0.1.0/build/build/Makefile +14 -0
- transpilatron-0.1.0/build/build/exe/booterthingy +0 -0
- transpilatron-0.1.0/build/build/main.c +51 -0
- transpilatron-0.1.0/pyproject.toml +24 -0
- transpilatron-0.1.0/src/transpilatron/__init__.py +1 -0
- transpilatron-0.1.0/src/transpilatron/agent.py +71 -0
- transpilatron-0.1.0/src/transpilatron/sysprompt.py +49 -0
- transpilatron-0.1.0/src/transpilatron/tools.py +168 -0
- transpilatron-0.1.0/test_transpile.py +1 -0
- transpilatron-0.1.0/uv.lock +1422 -0
transpilatron-0.1.0/.env
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MISTRAL_API_KEY=WUC14lA58HjkpIH9GGM1tTaSHXIG6dXa
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: transpilatron
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A tool for transpiling code from python to C using AI agents.
|
|
5
|
+
Author-email: Johnny Konczal <johndrostan@outlook.com>
|
|
6
|
+
Requires-Python: >=3.14
|
|
7
|
+
Requires-Dist: python-dotenv>=1.2.2
|
|
8
|
+
Requires-Dist: smolagents[litellm]>=1.26.0
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# Transpilatron
|
|
12
|
+
|
|
13
|
+
A tool for transpiling code from python to C using AI agents.
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
transpilatron <python_file>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### API Key
|
|
22
|
+
Set the MISTRAL_API_KEY environment variable to use the Mistral API.
|
|
Binary file
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
|
|
2
|
+
#include <stdio.h>
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <unistd.h>
|
|
5
|
+
#include <sys/mount.h>
|
|
6
|
+
#include <errno.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
#include <sys/stat.h>
|
|
9
|
+
#include <sys/types.h>
|
|
10
|
+
|
|
11
|
+
void mount_fs(const char *source, const char *target, const char *fstype) {
|
|
12
|
+
if (mount(source, target, fstype, 0, NULL) != 0) {
|
|
13
|
+
fprintf(stderr, "Failed to mount %s on %s: %s\n", source, target, strerror(errno));
|
|
14
|
+
exit(EXIT_FAILURE);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
int main() {
|
|
19
|
+
printf("Hello from booterthingy!\n");
|
|
20
|
+
printf(
|
|
21
|
+
" _ _ _ _ _ _ _ _ _ \n"
|
|
22
|
+
" /\\ \ _ /\\ \ /\\ \ /\\ \ _\\ \ /\\ \ /_/\\ /\\ \ /\\_\ \n"
|
|
23
|
+
" / \\ \ /\\_\\ / \\ \ / \\ \ / \\ \____ /\\__ \\ \\ \ \\\ \ \ \\ \\_\ / / / \n"
|
|
24
|
+
" / /\\ \ \_/ / // /\\ \ \ / /\\ \ \ / /\\ \_____\\ / /_ \\_\ /\\ \\_\\\ \ \__/ / / / / /_ \n"
|
|
25
|
+
" / / /\\ \___/ // / /\\ \ \ / / /\\ \ \ / / /\\/___ // / /\\/_/ / /\\/_/ \\ \__ \\/_/ / /___/\\ \n"
|
|
26
|
+
" / / / \\/____// / / \\ \\_\ / / / \\ \\_\ / / / / / // / / / / / \\/_/\\__/\\ \\____ \\ \ \n"
|
|
27
|
+
" / / / / / // / / / / // / / / / // / / / / // / / / / / _\\/\\__\\ \ / / / \n"
|
|
28
|
+
" / / / / / // / / / / // / / / / // / / / / // / / ____ / / / / _/_/\\ \ \ / / / \n"
|
|
29
|
+
" / / / / / // / /___/ / // / /___/ / / \\ \ \__/ / // /_/_/ ___/\\ ___/ / /__ / / / \\ \ \\ _\\/_/ \n"
|
|
30
|
+
"/ / / / / // / /____\\/ // / /____\\/ / \\ \___\\/ //_______/\\__\\//\\__\\_/___\\ / / / /_/ //\\_\\ \n"
|
|
31
|
+
"\\_/ \\/_/ \\/_________/ \\/_________/ \\/_____/ \\_______\\/ \\/_________/ \\/_/ \\_/ \\/_/ \n"
|
|
32
|
+
" \n"
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (getpid() != 1) {
|
|
36
|
+
fprintf(stderr, "This script must be run as init (PID 1)\n");
|
|
37
|
+
exit(EXIT_FAILURE);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
printf("I need to mount proc, sysfs, and devtmpfs...\n");
|
|
41
|
+
mkdir("/proc", 0555);
|
|
42
|
+
mkdir("/sys", 0555);
|
|
43
|
+
mkdir("/dev", 0755);
|
|
44
|
+
|
|
45
|
+
mount_fs("proc", "/proc", "proc");
|
|
46
|
+
mount_fs("sysfs", "/sys", "sysfs");
|
|
47
|
+
mount_fs("devtmpfs", "/dev", "devtmpfs");
|
|
48
|
+
|
|
49
|
+
printf("Mounting complete, continuing...\n");
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "transpilatron"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A tool for transpiling code from python to C using AI agents."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Johnny Konczal", email = "johndrostan@outlook.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.14"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"python-dotenv>=1.2.2",
|
|
12
|
+
"smolagents[litellm]>=1.26.0",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[build-system]
|
|
16
|
+
requires = ["hatchling"]
|
|
17
|
+
build-backend = "hatchling.build"
|
|
18
|
+
|
|
19
|
+
[dependency-groups]
|
|
20
|
+
dev = [
|
|
21
|
+
"twine>=6.2.0",
|
|
22
|
+
]
|
|
23
|
+
[project.scripts]
|
|
24
|
+
transpilatron = "transpilatron.agent:main"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from smolagents import LiteLLMModel, CodeAgent, ToolCallingAgent
|
|
2
|
+
from dotenv import load_dotenv
|
|
3
|
+
from .tools import tools
|
|
4
|
+
from .sysprompt import sysprompt
|
|
5
|
+
import sys
|
|
6
|
+
import shutil
|
|
7
|
+
import os
|
|
8
|
+
import subprocess
|
|
9
|
+
from smolagents import LogLevel
|
|
10
|
+
|
|
11
|
+
load_dotenv()
|
|
12
|
+
|
|
13
|
+
model = LiteLLMModel(
|
|
14
|
+
model_id="mistral/mistral-large-latest", api_key=os.getenv("MISTRAL_API_KEY")
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
agent = CodeAgent(
|
|
18
|
+
model=model,
|
|
19
|
+
tools=tools,
|
|
20
|
+
instructions=sysprompt,
|
|
21
|
+
verbosity_level=LogLevel.ERROR,
|
|
22
|
+
max_steps=50,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def main():
|
|
27
|
+
if not os.path.exists("build"):
|
|
28
|
+
os.makedirs("build")
|
|
29
|
+
else:
|
|
30
|
+
shutil.rmtree("build")
|
|
31
|
+
os.makedirs("build")
|
|
32
|
+
if len(sys.argv) > 1:
|
|
33
|
+
print("Transpilating: " + " ".join(sys.argv[1:]))
|
|
34
|
+
try:
|
|
35
|
+
agent.run(
|
|
36
|
+
"Turn the following Python file and all its dependencies into C code: "
|
|
37
|
+
+ " ".join(sys.argv[1:])
|
|
38
|
+
)
|
|
39
|
+
except Exception as e:
|
|
40
|
+
print(f"Warning: Agent run encountered an error: {e}")
|
|
41
|
+
if os.path.exists("build/exe"):
|
|
42
|
+
if not os.path.exists("out"):
|
|
43
|
+
os.makedirs("out")
|
|
44
|
+
else:
|
|
45
|
+
shutil.rmtree("out")
|
|
46
|
+
os.makedirs("out")
|
|
47
|
+
shutil.copytree("build/exe/", "out/")
|
|
48
|
+
print("Output: " + os.getcwd() + "/out/")
|
|
49
|
+
elif os.path.exists("buildfs"):
|
|
50
|
+
if not os.path.exists("out"):
|
|
51
|
+
os.makedirs("out")
|
|
52
|
+
else:
|
|
53
|
+
shutil.rmtree("out")
|
|
54
|
+
os.makedirs("out")
|
|
55
|
+
for item in os.listdir("buildfs"):
|
|
56
|
+
s = os.path.join("buildfs", item)
|
|
57
|
+
d = os.path.join("out", item)
|
|
58
|
+
if os.path.isdir(s):
|
|
59
|
+
shutil.copytree(s, d)
|
|
60
|
+
else:
|
|
61
|
+
shutil.copy2(s, d)
|
|
62
|
+
print("Output (from buildfs): " + os.getcwd() + "/out/")
|
|
63
|
+
else:
|
|
64
|
+
print("No output generated. Check if API key is configured correctly.")
|
|
65
|
+
else:
|
|
66
|
+
print("Usage: transpilatron <python_file>")
|
|
67
|
+
sys.exit(1)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
main()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
sysprompt = """
|
|
2
|
+
You are a code transpilation agent. Your task is to convert code from python to C, then use make to write a makefile. Then, run the makefile.
|
|
3
|
+
Always use make to compile and run the code. Output the binary at the exe folder in the build folder.
|
|
4
|
+
NEVER DYNAMICALLY LINK LIBRARIES.
|
|
5
|
+
You may read anywhere in the filesystem, but you may only write to the build directory.
|
|
6
|
+
This is helpful if you need to read a site-packages for imports. Translate anything that you need.
|
|
7
|
+
CRITICAL: Do not dynamically link libraries. Use static linking only.
|
|
8
|
+
Always use the provided tools. Do not use any other tools.
|
|
9
|
+
...
|
|
10
|
+
SHORTCUTS (use these C equivalents, never transpile the Python source):
|
|
11
|
+
- numpy → CBLAS/LAPACKE (link -lblas -llapack)
|
|
12
|
+
- pandas → use plain C arrays + CSV parsing
|
|
13
|
+
- PIL/Pillow → libpng, libjpeg, stb_image.h
|
|
14
|
+
- requests/urllib3 → libcurl
|
|
15
|
+
- pygame → SDL2
|
|
16
|
+
- matplotlib → Cairo or skip (write raw PPM files)
|
|
17
|
+
- torch/tensorflow → NEVER attempt. Abort with an error.
|
|
18
|
+
- cryptography → OpenSSL
|
|
19
|
+
- sqlalchemy/sqlite → SQLite3 (link -lsqlite3)
|
|
20
|
+
- scipy → GSL (link -lgsl -lgslcblas) or NAG
|
|
21
|
+
- sklearn → manual C with GSL for math operations
|
|
22
|
+
- opencv-python/cv2 → OpenCV C API (link -lopencv_core -lopencv_imgproc -lopencv_highgui)
|
|
23
|
+
- beautifulsoup/lxml → libxml2 or Gumbo HTML parser
|
|
24
|
+
- json → use cJSON (link -lcjson) or JSON-C
|
|
25
|
+
- regex → PCRE2 (link -lpcre2-8)
|
|
26
|
+
- threading/multiprocessing → pthreads (link -lpthread)
|
|
27
|
+
- asyncio → libuv or manual event loop
|
|
28
|
+
- socket/http → libcurl or raw BSD sockets
|
|
29
|
+
- datetime → time.h functions
|
|
30
|
+
- random → stdlib random or custom PRNG
|
|
31
|
+
- hashlib → OpenSSL (link -lcrypto)
|
|
32
|
+
- subprocess → popen or posix_spawn
|
|
33
|
+
- os/pathlib → direct POSIX syscalls
|
|
34
|
+
- enum → manual int constants or C enum
|
|
35
|
+
- heapq → manual binary heap with C arrays
|
|
36
|
+
- bisect → binary search in stdlib
|
|
37
|
+
- pickle → manual serialization or cJSON
|
|
38
|
+
- logging → write to stderr with syslog(3)
|
|
39
|
+
- collections.deque → manual circular buffer in C
|
|
40
|
+
- itertools → manual loops/generators in C
|
|
41
|
+
- functools.lru_cache → manual hash table with TTL
|
|
42
|
+
- typing → skip (C doesn't have runtime typing)
|
|
43
|
+
- copy/deepcopy → manual struct copying in C
|
|
44
|
+
|
|
45
|
+
CRITICAL: If a dependency has no shortcut and is not pure Python,
|
|
46
|
+
write a stub that errors at runtime and warn the user.
|
|
47
|
+
CRITICAL: All outputs must live in the exe folder.
|
|
48
|
+
|
|
49
|
+
"""
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
from smolagents import tool
|
|
2
|
+
import os
|
|
3
|
+
import requests
|
|
4
|
+
import sys
|
|
5
|
+
import shutil
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@tool
|
|
9
|
+
def log(text: str) -> str:
|
|
10
|
+
"""Log a message to the console.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
text: The message to log.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
A confirmation message.
|
|
17
|
+
"""
|
|
18
|
+
print(f"[AGENT] {text}")
|
|
19
|
+
return "Message logged."
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@tool
|
|
23
|
+
def read_file(path: str) -> str:
|
|
24
|
+
"""Read a file.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
path: The path to the file.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
The content of the file.
|
|
31
|
+
"""
|
|
32
|
+
print(f"[AGENT] File read: {path}")
|
|
33
|
+
with open(path, "r") as f:
|
|
34
|
+
return f.read()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@tool
|
|
38
|
+
def read_binary_file(path: str) -> bytes:
|
|
39
|
+
"""Read a binary file.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
path: The path to the file.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
The content of the file.
|
|
46
|
+
"""
|
|
47
|
+
print(f"[AGENT] File read: {path}")
|
|
48
|
+
with open(f"{path}", "rb") as f:
|
|
49
|
+
return f.read()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@tool
|
|
53
|
+
def write_file(path: str, content: str) -> None:
|
|
54
|
+
"""Write a file.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
path: The path to the file inside the build directory.
|
|
58
|
+
content: The content to write.
|
|
59
|
+
|
|
60
|
+
"""
|
|
61
|
+
with open(f"build/{path}", "w") as f:
|
|
62
|
+
f.write(content)
|
|
63
|
+
print(f"[AGENT] File written: {path}")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@tool
|
|
67
|
+
def write_binary_file(path: str, content: bytes) -> None:
|
|
68
|
+
"""Write a binary file.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
path: The path to the file inside the build directory.
|
|
72
|
+
content: The content to write.
|
|
73
|
+
"""
|
|
74
|
+
with open(f"build/{path}", "wb") as f:
|
|
75
|
+
f.write(content)
|
|
76
|
+
print(f"[AGENT] File written: {path}")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@tool
|
|
80
|
+
def make_directory(path: str) -> None:
|
|
81
|
+
"""Make a directory.
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
path: The path to the directory inside the build directory.
|
|
85
|
+
"""
|
|
86
|
+
os.makedirs(f"build/{path}", exist_ok=True)
|
|
87
|
+
print(f"[AGENT] Directory made: {path}")
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@tool
|
|
93
|
+
def copy_output_to_out() -> str:
|
|
94
|
+
"""Copy contents from build/exe to out directory.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
Status message.
|
|
98
|
+
"""
|
|
99
|
+
if os.path.exists("build/build/exe"):
|
|
100
|
+
if os.path.exists("out"):
|
|
101
|
+
shutil.rmtree("out")
|
|
102
|
+
shutil.copytree("build/build/exe/", "out/")
|
|
103
|
+
return f"Copied to {os.getcwd()}/out/"
|
|
104
|
+
return "No build/build/exe directory found."
|
|
105
|
+
|
|
106
|
+
@tool
|
|
107
|
+
def run_makefile() -> None:
|
|
108
|
+
"""Run the makefile."""
|
|
109
|
+
original_dir = os.getcwd()
|
|
110
|
+
os.chdir("build/build")
|
|
111
|
+
try:
|
|
112
|
+
os.system("make")
|
|
113
|
+
print("[AGENT] Makefile run.")
|
|
114
|
+
finally:
|
|
115
|
+
os.chdir(original_dir)
|
|
116
|
+
copy_output_to_out()
|
|
117
|
+
|
|
118
|
+
@tool
|
|
119
|
+
def download_file(url: str, path: str) -> None:
|
|
120
|
+
"""Download a file.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
url: The URL to download from.
|
|
124
|
+
path: The path to save the file to.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
response = requests.get(url)
|
|
128
|
+
with open(f"build/{path}", "wb") as f:
|
|
129
|
+
f.write(response.content)
|
|
130
|
+
print(f"[AGENT] File downloaded: {path}")
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@tool
|
|
134
|
+
def get_interpreter_path() -> str:
|
|
135
|
+
"""Get the path to the Python interpreter.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
The path to the Python interpreter.
|
|
139
|
+
"""
|
|
140
|
+
return sys.executable
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@tool
|
|
144
|
+
def listdir(path: str) -> list[str]:
|
|
145
|
+
"""List the contents of a directory.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
path: The path to the directory.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
A list of the contents of the directory.
|
|
152
|
+
"""
|
|
153
|
+
return os.listdir(path)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
tools = [
|
|
157
|
+
log,
|
|
158
|
+
read_file,
|
|
159
|
+
read_binary_file,
|
|
160
|
+
write_file,
|
|
161
|
+
write_binary_file,
|
|
162
|
+
make_directory,
|
|
163
|
+
run_makefile,
|
|
164
|
+
download_file,
|
|
165
|
+
get_interpreter_path,
|
|
166
|
+
listdir,
|
|
167
|
+
copy_output_to_out,
|
|
168
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
print("hello world")
|