accessible_worlds.aw_build_prompt
1from spacy.util import raise_error 2from .aw_vocabulary import AwVocabulary 3from .aw_utils import ( 4 split_sentences 5) 6 7from typing import Literal 8 9import numpy as np 10 11def assemble_list( x : list[str], last : str ='and' ) : 12 13 res = "" 14 n = len(x) 15 16 if n == 0 : 17 return res 18 elif n == 1 : 19 return f"{x[0]}." 20 21 for i, s in enumerate( x ) : 22 if i == 0 : 23 res += f"{s}," 24 elif i < n-1 : 25 res += f" {s}," 26 else : 27 res += f" {last} {s}." 28 29 return res 30 31def assemble_word_replacement_prompt( 32 paragraph : str, 33 sentence : str, 34 alternatives : dict[ str, list[str] ] 35) -> str : 36 37 prompt = f"Given the following paragraph: {paragraph}\n\n" 38 39 prompt = f"Consider this sentence within the paragraph: \"{sentence}\".\n\nYour task is to rewrite the sentence by potentially replacing some particular key words with new words from a provided set of possible alternatives. Many or all of the alternatives may be mistaken, or worse choices than the existing word within the provided context. An alternative is poor if it is unsual, less precise, or if it changes the intended meaning or connotation within the given context. Be sure to ignore those poor alternatives and default to either the original word, or a better alternative, if none are correct and high quality. " 40 41 for word, synonyms in alternatives.items() : 42 prompt += f"For the word \"{word}\", the known candidate alternatives are: " + ", ".join( synonyms ) + "." 43 44 prompt += " Do not replace the words with the candidates if they are not suitable." 45 prompt += f"Here is original sentence once more: \"{sentence}\". Output only your new replacement sentence." 46 47 return prompt 48 49def assemble_system_prompt( 50 core_prompt : str, 51 core_elements : dict[ str, list[ str ] ], 52 exposition_setting : dict[ str, list[ str ] ], 53 np_rng, 54 with_lists_as : Literal['inline', 'bulleted', 'spaced'] = 'inline', 55 balance_names : bool = False, 56 name_counts : dict[str,int] | None = None ) : 57 58 full_name_list = exposition_setting[ 'name suggestions' ] 59 60 if balance_names and name_counts is None : 61 raise ValueError( "Balance names requires passing name counts" ) 62 63 elif balance_names is not None and name_counts is not None : 64 65 for name in full_name_list : 66 if name not in name_counts : 67 raise ValueError( f"Missing count for name {name}" ) 68 69 # reqire at least 120 total names so far before we bother 70 if sum( name_counts.values() ) >= 120 : 71 72 weights = np.array( [ name_counts[ name ] for name in full_name_list ], dtype=float ) 73 weights = 1.0 / ( weights + 1 )**2 74 weights = weights / np.sum( weights ) 75 76 n_choose = max( int( round( len( full_name_list )*2/3 ) ) - 1, 1 ) 77 78 full_name_list = np_rng.choice( 79 full_name_list, 80 size=n_choose, 81 replace=False, 82 p=weights 83 ) 84 85 core_prompt = core_prompt.replace( 86 "NAMES", 87 assemble_list( np_rng.permutation( full_name_list ) ) ) 88 89 bullets = '**' if with_lists_as == 'bulleted' else '' 90 sep = ' ' if with_lists_as == 'inline' else '\n\n' 91 92 core_list = sep + sep.join( 93 f"{bullets}{key[0].upper()}{key[1:].lower()}{bullets}: {assemble_list( np_rng.permutation( core_elements[ key ] ) )}" 94 for key in np_rng.permutation( list( core_elements.keys() ) ) 95 ) 96 97 core_prompt = core_prompt.replace( 'CORE', core_list ) 98 99 return core_prompt 100 101def add_core_integrations( 102 prompt : str, 103 vocabulary : AwVocabulary, 104 min_k : int, 105 max_k : int, 106 min_extra_creature_integrations : int, 107 max_extra_creature_integrations : int, 108 np_rng ) -> tuple[str, list[str]] : 109 110 integrations = vocabulary.sample_core_integrations( 111 np_rng=np_rng, 112 min_k=min_k, 113 max_k=max_k, 114 min_extra_creature_integrations=min_extra_creature_integrations, 115 max_extra_creature_integrations=max_extra_creature_integrations 116 ) 117 118 extension = " Try to also incorporate the following: " + assemble_list( integrations ) 119 120 return prompt + extension, integrations 121 122def add_moral_integrations( 123 prompt : str, 124 vocabulary : AwVocabulary, 125 min_k : int, 126 max_k : int, 127 np_rng ) -> tuple[str, list[str]] : 128 129 integrations = vocabulary.sample_moral_integrations( 130 np_rng=np_rng, 131 min_k=min_k, 132 max_k=max_k 133 ) 134 135 extension = " In addition, try to naturally integrate the following moral concepts: " + assemble_list( integrations ) 136 137 return prompt + extension, integrations 138 139def add_underrepresented_integrations( 140 prompt : str, 141 vocabulary : AwVocabulary, 142 min_k : int, 143 max_k : int, 144 np_rng ) -> tuple[str, list[str]] : 145 146 # We don't boost contraction tokens or names 147 integrations = vocabulary.sample_least_gounded( min_k=min_k, max_k=max_k, np_rng=np_rng ) 148 integrations = [ w for w in integrations if w and w[0].islower() and "'" not in w ] 149 150 if not integrations : 151 return prompt, [] 152 153 extension = " Be sure to also integrate the following words: " + assemble_list( integrations ) 154 155 return prompt + extension, integrations 156 157def add_recursive_integrations( 158 prompt : str, 159 previous_passages : list[str], 160 np_rng ) -> tuple[str, str] : 161 162 if not previous_passages : 163 return prompt, "" 164 165 context_content = np_rng.choice( previous_passages, size=1 )[0] 166 context_sentences = split_sentences( context_content ) 167 context_sentence = np_rng.choice( context_sentences, size=1 )[0].strip() 168 169 extension = " In addition to narrowing your focus to thoughtful and thorough but concise incorporation of the provided integration items, also try to incorporate the concepts expressed in the following sentence: \"" + context_sentence + "\"" 170 171 return prompt + extension, extension
def
assemble_list(x: list[str], last: str = 'and'):
12def assemble_list( x : list[str], last : str ='and' ) : 13 14 res = "" 15 n = len(x) 16 17 if n == 0 : 18 return res 19 elif n == 1 : 20 return f"{x[0]}." 21 22 for i, s in enumerate( x ) : 23 if i == 0 : 24 res += f"{s}," 25 elif i < n-1 : 26 res += f" {s}," 27 else : 28 res += f" {last} {s}." 29 30 return res
def
assemble_word_replacement_prompt(paragraph: str, sentence: str, alternatives: dict[str, list[str]]) -> str:
32def assemble_word_replacement_prompt( 33 paragraph : str, 34 sentence : str, 35 alternatives : dict[ str, list[str] ] 36) -> str : 37 38 prompt = f"Given the following paragraph: {paragraph}\n\n" 39 40 prompt = f"Consider this sentence within the paragraph: \"{sentence}\".\n\nYour task is to rewrite the sentence by potentially replacing some particular key words with new words from a provided set of possible alternatives. Many or all of the alternatives may be mistaken, or worse choices than the existing word within the provided context. An alternative is poor if it is unsual, less precise, or if it changes the intended meaning or connotation within the given context. Be sure to ignore those poor alternatives and default to either the original word, or a better alternative, if none are correct and high quality. " 41 42 for word, synonyms in alternatives.items() : 43 prompt += f"For the word \"{word}\", the known candidate alternatives are: " + ", ".join( synonyms ) + "." 44 45 prompt += " Do not replace the words with the candidates if they are not suitable." 46 prompt += f"Here is original sentence once more: \"{sentence}\". Output only your new replacement sentence." 47 48 return prompt
def
assemble_system_prompt( core_prompt: str, core_elements: dict[str, list[str]], exposition_setting: dict[str, list[str]], np_rng, with_lists_as: Literal['inline', 'bulleted', 'spaced'] = 'inline', balance_names: bool = False, name_counts: dict[str, int] | None = None):
50def assemble_system_prompt( 51 core_prompt : str, 52 core_elements : dict[ str, list[ str ] ], 53 exposition_setting : dict[ str, list[ str ] ], 54 np_rng, 55 with_lists_as : Literal['inline', 'bulleted', 'spaced'] = 'inline', 56 balance_names : bool = False, 57 name_counts : dict[str,int] | None = None ) : 58 59 full_name_list = exposition_setting[ 'name suggestions' ] 60 61 if balance_names and name_counts is None : 62 raise ValueError( "Balance names requires passing name counts" ) 63 64 elif balance_names is not None and name_counts is not None : 65 66 for name in full_name_list : 67 if name not in name_counts : 68 raise ValueError( f"Missing count for name {name}" ) 69 70 # reqire at least 120 total names so far before we bother 71 if sum( name_counts.values() ) >= 120 : 72 73 weights = np.array( [ name_counts[ name ] for name in full_name_list ], dtype=float ) 74 weights = 1.0 / ( weights + 1 )**2 75 weights = weights / np.sum( weights ) 76 77 n_choose = max( int( round( len( full_name_list )*2/3 ) ) - 1, 1 ) 78 79 full_name_list = np_rng.choice( 80 full_name_list, 81 size=n_choose, 82 replace=False, 83 p=weights 84 ) 85 86 core_prompt = core_prompt.replace( 87 "NAMES", 88 assemble_list( np_rng.permutation( full_name_list ) ) ) 89 90 bullets = '**' if with_lists_as == 'bulleted' else '' 91 sep = ' ' if with_lists_as == 'inline' else '\n\n' 92 93 core_list = sep + sep.join( 94 f"{bullets}{key[0].upper()}{key[1:].lower()}{bullets}: {assemble_list( np_rng.permutation( core_elements[ key ] ) )}" 95 for key in np_rng.permutation( list( core_elements.keys() ) ) 96 ) 97 98 core_prompt = core_prompt.replace( 'CORE', core_list ) 99 100 return core_prompt
def
add_core_integrations( prompt: str, vocabulary: accessible_worlds.aw_vocabulary.AwVocabulary, min_k: int, max_k: int, min_extra_creature_integrations: int, max_extra_creature_integrations: int, np_rng) -> tuple[str, list[str]]:
102def add_core_integrations( 103 prompt : str, 104 vocabulary : AwVocabulary, 105 min_k : int, 106 max_k : int, 107 min_extra_creature_integrations : int, 108 max_extra_creature_integrations : int, 109 np_rng ) -> tuple[str, list[str]] : 110 111 integrations = vocabulary.sample_core_integrations( 112 np_rng=np_rng, 113 min_k=min_k, 114 max_k=max_k, 115 min_extra_creature_integrations=min_extra_creature_integrations, 116 max_extra_creature_integrations=max_extra_creature_integrations 117 ) 118 119 extension = " Try to also incorporate the following: " + assemble_list( integrations ) 120 121 return prompt + extension, integrations
def
add_moral_integrations( prompt: str, vocabulary: accessible_worlds.aw_vocabulary.AwVocabulary, min_k: int, max_k: int, np_rng) -> tuple[str, list[str]]:
123def add_moral_integrations( 124 prompt : str, 125 vocabulary : AwVocabulary, 126 min_k : int, 127 max_k : int, 128 np_rng ) -> tuple[str, list[str]] : 129 130 integrations = vocabulary.sample_moral_integrations( 131 np_rng=np_rng, 132 min_k=min_k, 133 max_k=max_k 134 ) 135 136 extension = " In addition, try to naturally integrate the following moral concepts: " + assemble_list( integrations ) 137 138 return prompt + extension, integrations
def
add_underrepresented_integrations( prompt: str, vocabulary: accessible_worlds.aw_vocabulary.AwVocabulary, min_k: int, max_k: int, np_rng) -> tuple[str, list[str]]:
140def add_underrepresented_integrations( 141 prompt : str, 142 vocabulary : AwVocabulary, 143 min_k : int, 144 max_k : int, 145 np_rng ) -> tuple[str, list[str]] : 146 147 # We don't boost contraction tokens or names 148 integrations = vocabulary.sample_least_gounded( min_k=min_k, max_k=max_k, np_rng=np_rng ) 149 integrations = [ w for w in integrations if w and w[0].islower() and "'" not in w ] 150 151 if not integrations : 152 return prompt, [] 153 154 extension = " Be sure to also integrate the following words: " + assemble_list( integrations ) 155 156 return prompt + extension, integrations
def
add_recursive_integrations(prompt: str, previous_passages: list[str], np_rng) -> tuple[str, str]:
158def add_recursive_integrations( 159 prompt : str, 160 previous_passages : list[str], 161 np_rng ) -> tuple[str, str] : 162 163 if not previous_passages : 164 return prompt, "" 165 166 context_content = np_rng.choice( previous_passages, size=1 )[0] 167 context_sentences = split_sentences( context_content ) 168 context_sentence = np_rng.choice( context_sentences, size=1 )[0].strip() 169 170 extension = " In addition to narrowing your focus to thoughtful and thorough but concise incorporation of the provided integration items, also try to incorporate the concepts expressed in the following sentence: \"" + context_sentence + "\"" 171 172 return prompt + extension, extension