147 lines
3.9 KiB
JavaScript
Raw Normal View History

2026-01-25 10:50:20 +01:00
#!/usr/local/bin/wren
import "pathlib" for Path
import "http" for Http
import "json" for Json
import "env" for Environment
import "argparse" for ArgumentParser
import "os" for Process
class SourceCodeGenerator {
static VERSION { "1.0" }
static DEFAULT_MODEL { "anthropic/claude-haiku-4.5" }
static API_ENDPOINT { "https://openrouter.ai/api/v1/chat/completions" }
static TUTORIAL_PATH { "apps/minitut.md" }
static DEFAULT_PROMPT {
"A small but useful application that combines several modules / libraries that is plug and play to use! Small description on top commenten what the application is and what it does and where it can be used for."
}
static run() {
System.print("// wren source code generator v%(this.VERSION)")
var startTime = System.clock
var args = parseArguments()
var apiKey = getApiKey()
var tutorial = loadTutorial()
var messages = buildMessages(tutorial, args["prompt"])
var sourceCode = generateCode(apiKey, messages)
printResults(startTime, sourceCode)
saveOutput(args["output"], sourceCode)
}
static parseArguments() {
var parser = ArgumentParser.new()
parser.addArgument("prompt", {"default": this.DEFAULT_PROMPT})
parser.addArgument("-o", {"long": "--output", "default": ""})
return parser.parseArgs()
}
static getApiKey() {
var apiKey = Environment.get("OPENROUTER_API_KEY")
if (apiKey == null || apiKey.count == 0) {
System.print("Error: OPENROUTER_API_KEY environment variable not set")
Fiber.abort("Missing API key")
}
return apiKey
}
static loadTutorial() {
return Path.new(this.TUTORIAL_PATH).readText()
}
static buildMessages(tutorial, userPrompt) {
var messages = []
messages.add({
"role": "system",
"content": "You are an application generator that will produce wren source code exclusively as described below:\n" + tutorial
})
messages.add({
"role": "user",
"content": "Please generate source code based on everything what i say from now on."
})
messages.add({
"role": "assistant",
"content": "I will respond in literally valid JSON only in this format: {\"source_code\":\"<the source code>\"} without any markup or markdown formatting."
})
messages.add({
"role": "user",
"content": userPrompt
})
return messages
}
static generateCode(apiKey, messages) {
var requestBody = {
"model": "%(this.DEFAULT_MODEL)",
"messages": messages
}
var headers = {
"Authorization": "Bearer " + apiKey,
"Content-Type": "application/json"
}
var response = Http.post(this.API_ENDPOINT, requestBody, headers)
if (!response.ok) {
System.print("Error: %(response.body)")
return ""
}
return extractSourceCode(response.body)
}
static extractSourceCode(responseBody) {
var data = Json.parse(responseBody)
if (data == null || data["choices"] == null || data["choices"].count == 0) {
return ""
}
var message = data["choices"][0]["message"]
if (message == null || message["content"] == null) {
return ""
}
var text = message["content"]
text = stripMarkdownWrapper(text)
text = extractFromJson(text)
return text
}
static stripMarkdownWrapper(text) {
if (text.startsWith("```")) {
return text[7..-4].trim()
}
return text
}
static extractFromJson(text) {
if (text.startsWith("{")) {
return Json.parse(text)["source_code"]
}
return text
}
static printResults(startTime, output) {
var elapsedTime = System.clock - startTime
System.print("// Generation time: %(elapsedTime)")
System.print("")
System.print(output)
}
static saveOutput(outputPath, content) {
if (!outputPath.isEmpty) {
Path.new(outputPath).writeText(content)
}
}
}
System.print(SourceCodeGenerator.DEFAULT_MODEL)
SourceCodeGenerator.run()