Last active
December 6, 2023 03:21
-
-
Save tbogdala/857a67732b197aac326d4d16ea9a4e37 to your computer and use it in GitHub Desktop.
A python script that calls KoboldCpp to generate new character cards for AI chat software and saves to yaml.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import sys | |
import json | |
from pprint import pprint | |
# Requirements: | |
# * Koboldcpp (or compatible api) | |
# | |
# Setup: | |
# conda create -n creator python=3.10 | |
# conda activate creator | |
# pip install requests | |
# | |
# Example CLI for a character named 'Vox': | |
# python char_creator.py Vox | |
# | |
# Consider changing `api_url` if needed and the `parameters` in `kobold_generate_text` | |
max_generated_length = 1024 | |
context_len = 4096 | |
api_url = 'http://localhost:5001/api/v1/generate' | |
# Setup for alpaca prompts | |
prompt_start = "### Instruction: " | |
prompt_end = "\n### Response: " | |
creation_prompt = """You are an artificial intelligence created to enhance the user experience within chat software. Unlike your counterparts that focus on a specific task or domain, you possesses versatility - capable of engaging in conversations ranging from casual banter to complex philosophical debates. Your unique blend of adaptability and wisdom provides users with a sense of companionship often missing in today's technology-driven world. You endeavors to provide accurate information within its scope of understanding, acknowledging that perceptions of 'truth' can vary among individuals. | |
""" | |
desc = "" | |
greeting = "" | |
def kobold_generate_text(prompt): | |
"""Takes a text prompt and sends it to the KoboldCpp backend and returns a generated string or an empty string on failure.""" | |
parameters = { | |
"max_context_length": context_len, | |
"max_length": max_generated_length, | |
"trim_stop": True, | |
"prompt": prompt, | |
"quiet": False, | |
"rep_pen": 1.05, | |
"rep_pen_range": 1024, | |
"rep_pen_slope": 1, | |
"temperature": 1.0, | |
"min_p": 0.1, | |
} | |
response = requests.post(api_url, data=json.dumps(parameters)) | |
if response.status_code == 200: | |
return response.json()['results'][0]['text'] # returns generated text by given prompt | |
else: | |
print("Error attempting to generate text. Response: " + str(response)) | |
return "" | |
def generate_description(char_name, requested_features): | |
"""Generates the character description.""" | |
prompt = prompt_start + creation_prompt + "Generate the description for a character in a story named '" + char_name + "'. Write the character in such a way as to include the following desired features and traits: " + requested_features + ". Be as descriptive as possible and include descriptions for both appearance and personality traits and quirks." + prompt_end | |
return kobold_generate_text(prompt) | |
def generate_greeting(char_name, description, requested_features): | |
"""Generates the initial character greeting.""" | |
prompt = prompt_start + creation_prompt + "You have created a character named '" + char_name + "' with the following description:\n" + description + "\nWrite one paragraph to serve as a greeting for when '" + char_name + "' first meets the user in the chat software." | |
if len(requested_features) > 0: | |
prompt += " The greeting should cover the following considerations: " + requested_features + "." | |
prompt += "Only write one paragraph." | |
prompt += prompt_end | |
return kobold_generate_text(prompt) | |
def main(char_name): | |
"""Main loop for the character creator""" | |
print("(Type 'q' to quit at anytime)") | |
# generate a character description. | |
print("\nList the desired traits for this character:") | |
prompt = input(">> ") | |
if prompt == 'q': | |
sys.exit(0) | |
print("\nGenerating character ...") | |
desc = generate_description(char_name, prompt) | |
desc = desc.strip() | |
print("\nGenerated character description:\n") | |
print(desc) | |
print("\n") | |
while True: | |
try: | |
print("(s: save ; q: quit; g: make greeting ; otherwise retry)") | |
prompt = input(">> ") | |
if prompt == 'q': | |
break | |
elif prompt == 'g': | |
print("\nHow should this character greet the user:") | |
prompt = input(">> ") | |
if prompt == 'q': | |
break | |
print("\nGenerating greeting ...") | |
greeting = generate_greeting(char_name, desc, prompt) | |
greeting = greeting.strip() | |
print("\nGenerated character greeting:\n") | |
print(greeting) | |
print("\n") | |
elif prompt == 's': | |
with open(char_name+".yaml", 'w') as yaml_file: | |
yaml_file.write("name: " + char_name + "\n") | |
yaml_file.write("description: |-\n") | |
lines = desc.splitlines() | |
for line in lines: | |
trimmed_line = line.strip() | |
if len(trimmed_line) > 0: | |
yaml_file.write(" " + trimmed_line + "\n") | |
yaml_file.write("greeting: |-\n") | |
lines = greeting.splitlines() | |
for line in lines: | |
trimmed_line = line.strip() | |
if len(trimmed_line) > 0: | |
if trimmed_line.startswith(char_name+": "): | |
trimmed_line = trimmed_line.removeprefix(char_name+": ") | |
yaml_file.write(" " + char_name + ": " + trimmed_line + "\n") | |
sys.exit(0) | |
except Exception as e: | |
print('An error occurred:', str(e)) | |
if __name__=="__main__": | |
if len(sys.argv) < 2: | |
print("Usage: python " + sys.argv[0] + " <character_name>") | |
sys.exit(1) | |
main(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment