|
// retoor <retoor@molodetz.nl>
|
|
|
|
import "http" for Http
|
|
import "json" for Json
|
|
import "env" for Environment
|
|
import "io" for Stdin, Stdout
|
|
|
|
class Chat {
|
|
construct new(model) {
|
|
_model = model
|
|
_messages = []
|
|
_apiKey = Environment.get("OPENROUTER_API_KEY")
|
|
if (_apiKey == null || _apiKey.count == 0) {
|
|
Fiber.abort("OPENROUTER_API_KEY environment variable not set")
|
|
}
|
|
}
|
|
|
|
addSystem(content) {
|
|
_messages.add({"role": "system", "content": content})
|
|
}
|
|
|
|
send(content) {
|
|
_messages.add({"role": "user", "content": content})
|
|
|
|
var requestBody = {
|
|
"model": _model,
|
|
"messages": _messages,
|
|
"stream": false
|
|
}
|
|
|
|
var headers = {
|
|
"Authorization": "Bearer " + _apiKey,
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
var response = Http.post("https://openrouter.ai/api/v1/chat/completions", requestBody, headers)
|
|
|
|
if (!response.ok) {
|
|
var error = "API error: %(response.statusCode)"
|
|
if (response.body.count > 0) {
|
|
var data = Json.parse(response.body)
|
|
if (data["error"] != null && data["error"]["message"] != null) {
|
|
error = data["error"]["message"]
|
|
}
|
|
}
|
|
return {"error": error}
|
|
}
|
|
|
|
var data = Json.parse(response.body)
|
|
if (data["choices"] != null && data["choices"].count > 0) {
|
|
var message = data["choices"][0]["message"]
|
|
if (message != null) {
|
|
_messages.add(message)
|
|
return {
|
|
"content": message["content"],
|
|
"model": data["model"],
|
|
"usage": data["usage"]
|
|
}
|
|
}
|
|
}
|
|
|
|
return {"error": "Invalid response format"}
|
|
}
|
|
|
|
clear() {
|
|
var system = _messages.count > 0 && _messages[0]["role"] == "system" ? _messages[0] : null
|
|
_messages = []
|
|
if (system != null) _messages.add(system)
|
|
}
|
|
|
|
model { _model }
|
|
model=(value) { _model = value }
|
|
messageCount { _messages.count }
|
|
}
|
|
|
|
var model = "x-ai/grok-code-fast-1"
|
|
var chat = Chat.new(model)
|
|
|
|
chat.addSystem("You are a helpful assistant. Be concise in your responses.")
|
|
|
|
System.print("OpenRouter Chat")
|
|
System.print("Model: %(model)")
|
|
System.print("Commands: /quit, /clear, /model <name>, /history")
|
|
System.print("-" * 50)
|
|
|
|
while (true) {
|
|
System.write("\nYou: ")
|
|
Stdout.flush()
|
|
var input = Stdin.readLine()
|
|
|
|
if (input == null || input.trim() == "/quit" || input.trim() == "/exit") {
|
|
System.print("Goodbye!")
|
|
break
|
|
}
|
|
|
|
input = input.trim()
|
|
if (input.count == 0) continue
|
|
|
|
if (input == "/clear") {
|
|
chat.clear()
|
|
System.print("[Conversation cleared]")
|
|
continue
|
|
}
|
|
|
|
if (input == "/history") {
|
|
System.print("[%(chat.messageCount) messages in history]")
|
|
continue
|
|
}
|
|
|
|
if (input.startsWith("/model ")) {
|
|
var newModel = input[7..-1].trim()
|
|
if (newModel.count > 0) {
|
|
chat.model = newModel
|
|
System.print("[Model changed to: %(newModel)]")
|
|
}
|
|
continue
|
|
}
|
|
|
|
if (input.startsWith("/")) {
|
|
System.print("[Unknown command: %(input)]")
|
|
continue
|
|
}
|
|
|
|
System.write("\nAssistant: ")
|
|
Stdout.flush()
|
|
|
|
var result = chat.send(input)
|
|
|
|
if (result["error"] != null) {
|
|
System.print("[Error: %(result["error"])]")
|
|
} else {
|
|
System.print(result["content"])
|
|
if (result["usage"] != null) {
|
|
var usage = result["usage"]
|
|
System.print("\n[tokens: %(usage["prompt_tokens"]) prompt, %(usage["completion_tokens"]) completion]")
|
|
}
|
|
}
|
|
}
|