// Written by retoor@molodetz.nl // This source code initializes a command-line application that uses OpenAI for chat interactions, handles user inputs, and can start a simple HTTP server with CGI support. The code allows command execution, markdown parsing, and OpenAI chat integration. // External imports used in this code: // - openai.h // - markdown.h // - plugin.h // - line.h // MIT License // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #include "openai.h" #include "markdown.h" #include "plugin.h" #include "line.h" #include #include #include #include #include char *get_prompt_from_args(int c, char **argv) { char *prompt = malloc(1024 * 1024 + 1); prompt[0] = 0; for (int i = 1; i < c; i++) { if (argv[i][0] == '-') break; strncat(prompt, argv[i], 1024 * 1024); if (i < c - 1) { strncat(prompt, " ", 1024 * 1024); } else { strncat(prompt, ".", 1024 * 1024); } } if (!*prompt) { free(prompt); return NULL; } return prompt; } bool try_prompt(int argc, char *argv[]) { char *prompt = get_prompt_from_args(argc, argv); if (prompt != NULL) { char *response = openai_chat("user", prompt); parse_markdown_to_ansi(response); printf("\n"); free(response); free(prompt); return true; } return false; } void help(); void render(char *); void serve() { render("Starting server. *Put executables in a dir named cgi-bin and they will behave as web pages.*"); int res = system("python3 -m http.server --cgi"); (void)res; } void render(char *content) { parse_markdown_to_ansi(content); printf("\n\n"); } void repl() { line_init(); setbuf(stdout, NULL); char *line; char *previous_line = NULL; while ((line = line_read("> "))) { if (!line || !*line) { line = previous_line; } if (!line || !*line) continue; previous_line = line; if (line[0] == '!') { plugin_run(line + 1); continue; } if (!strncmp(line, "exit", 4)) { exit(0); } if (!strncmp(line, "help", 4)) { help(); continue; } if (!strncmp(line, "serve", 5)) { serve(); } if (!strncmp(line, "spar ", 5)) { char *response = line + 5; while (true) { render(response); sleep(2); response = openai_chat("user", response); } } if (!strncmp(line, "ls", 2) || !strncmp(line, "list", 4)) { int offset = 2; if (!strncmp(line, "list", 4)) { offset = 4; } char *command = (char *)malloc(strlen(line) + 42); command[0] = 0; strcpy(command, "ls "); strcat(command, line + offset); int res = system(command); (void)res; free(command); continue; } line_add_history(line); char *response = openai_chat("user", line); render(response); free(response); } } void help() { char help_text[1024 * 1024] = {0}; char *template = "# Help\n" "Written by retoor@molodetz.nl.\n\n" "## Features\n" " - navigate through history using `arrows`.\n" " - navigate through history with **recursive search** using `ctrl+r`.\n" " - **inception with python** for *incoming* and *outgoing* content.\n" " - markdown and **syntax highlighting**.\n" " - **execute python commands** with prefix `!`\n" " - list files of the current work directory using `ls`.\n" " - type `serve` to start a web server with directory listing. Easy for network transfers.\n\n" "## Configuration\n" " - model temperature is %f.\n" " - model name is %s.\n" " - max tokens is %d.\n\n" "## In development\n" " - **google search** and actions with those results.\n" " - **reminders**.\n" " - predefined **templates** for **reviewing** / **refactoring** so you can personalize.\n"; sprintf(help_text, template, prompt_temperature, prompt_model, prompt_max_tokens); render(help_text); } void openai_include(char *path) { FILE *file = fopen(path, "r"); if (file == NULL) { return; } fseek(file, 0, SEEK_END); long size = ftell(file); fseek(file, 0, SEEK_SET); char *buffer = (char *)malloc(size); size_t read = fread(buffer, 1, size, file); if (read == 0) { return; } fclose(file); buffer[read] = 0; openai_system(buffer); free(buffer); } void init() { line_init(); const char *locale = setlocale(LC_ALL, NULL); char payload[4096] = {0}; sprintf(payload, "User locale is %s. User lang is %s.\n" "You are Retoor. Use a lot of markdown in response.\n" "Be confident and short in answers.\n" "You divide things by zero if you have to.", locale, locale); printf("%s", "Loading..."); openai_system(payload); openai_include("context.txt"); printf("%s", "\rLoaded! Type help for features.\n"); } int main(int argc, char *argv[]) { init(); if (try_prompt(argc, argv)) return 0; repl(); return 0; }