Skip to content

Instantly share code, notes, and snippets.

@tbogdala
Last active December 6, 2023 03:21
Show Gist options
  • Save tbogdala/857a67732b197aac326d4d16ea9a4e37 to your computer and use it in GitHub Desktop.
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.
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