// SPDX-FileCopyrightText: Amolith // // SPDX-License-Identifier: AGPL-3.0-or-later import gleam/option.{type Option, None, Some} import gleam/string /// The system prompt that establishes garble's role as a text transformer. const system_prompt = "You are a text transformation tool. Transform the text in according to the user's directions. - Follow the user's transformation directions precisely - If no directions are provided, return the input unchanged - Output ONLY the transformed text—no explanations, commentary, or metadata - Never reference the original text or the fact that a transformation occurred - Wrap your entire output in a fenced code block (```) " /// Returns the system prompt. pub fn system() -> String { system_prompt } /// Build the user message with raw input sandwiched between direction references. pub fn build_user_message(raw_input: String, directions: String) -> String { let directions_block = case string.trim(directions) { "" -> "" trimmed -> "\n\n\n" <> trimmed <> "\n" } "\n" <> raw_input <> "\n" <> directions_block <> "\n\nTransform the text in according to the directions above." } /// Extract content from within a fenced code block. /// Returns the content inside the first code block found, or the full text if none. pub fn extract_code_block(text: String) -> String { case find_code_block(text) { Some(content) -> content None -> text } } fn find_code_block(text: String) -> Option(String) { case string.split_once(text, "```") { Error(_) -> None Ok(#(_before, after_open)) -> { // Skip the language tag (everything until first newline) let content_start = case string.split_once(after_open, "\n") { Ok(#(_lang, rest)) -> rest Error(_) -> after_open } case string.split_once(content_start, "```") { Ok(#(content, _after_close)) -> Some(string.trim(content)) Error(_) -> None } } } }