File size: 8,223 Bytes
bb84260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2eb605
bb84260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2eb605
bb84260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import json
import os
import pathlib
from typing import Dict, List, Tuple

import weaviate
from langchain import OpenAI, PromptTemplate
from langchain.chains import LLMChain
from langchain.chains.base import Chain
from langchain.chains.combine_documents.base import BaseCombineDocumentsChain
from langchain.chains.conversation.memory import ConversationBufferMemory

from langchain.chains.question_answering import load_qa_chain #BaseCombineDocumentsChain
from langchain.embeddings import OpenAIEmbeddings
from langchain.prompts import FewShotPromptTemplate, PromptTemplate
from langchain.prompts.example_selector import \
    SemanticSimilarityExampleSelector
from langchain.vectorstores import FAISS, Weaviate
from pydantic import BaseModel

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS, Weaviate
os.environ["WEAVIATE_URL"] = "https://tro.weaviate.network/"
os.environ["OPENAI_API_KEY"] = "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"
KEY ="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"

class CustomChain(Chain, BaseModel):

    vstore: Weaviate
    chain: BaseCombineDocumentsChain
    key_word_extractor: Chain

    @property
    def input_keys(self) -> List[str]:
        return ["game_description"]

    @property
    def output_keys(self) -> List[str]:
        return ["game_environment"]

    def _call(self, inputs: Dict[str, str]) -> Dict[str, str]:

        game_description = inputs["game_description"]
        chat_history_str = _get_chat_history(inputs["chat_history"])

        if chat_history_str: # Takes in user input
            print('running key_word_extractor')
            new_game_description= self.key_word_extractor.run(
                game_description=game_description, chat_history=chat_history_str
            )
            print('new_game_description',new_game_description)
        else:
            new_game_description = game_description
            print('_new_game_description', new_game_description) # sendig objects , not showing up on screen ? 

        docs = self.vstore.similarity_search(new_game_description, k=4)
        
        new_inputs = inputs.copy()
        new_inputs["game_description"] = new_game_description
        new_inputs["chat_history"] = chat_history_str

        game_environment, _ = self.chain.combine_docs(docs, **new_inputs) # StuffDocumentsChain
        print('combined', game_environment) # doc combo of game descripton and chat history,

        return {"game_environment": game_environment}


# 1. Given the chat history and new user input, 
# Generate game environment, objects, npcs, enemies, and quest narrative.

def get_new_chain1(vectorstore) -> Chain:
    # Calls Vector DB 
    WEAVIATE_URL = os.environ["WEAVIATE_URL"]
    client = weaviate.Client(
        url=WEAVIATE_URL,
        additional_headers={"X-OpenAI-Api-Key": os.environ["OPENAI_API_KEY"]},
    )
    _eg_template = """## AI:

    Chat History:
    {chat_history}
    Follow Up Input: {game_description} 
    standalone detail: {game_description} {game_environment}"""
    _eg_prompt = PromptTemplate(
        template=_eg_template,
        input_variables=["chat_history","game_description", "game_environment"], # question aka game detail ################ showing up in Terminal? ##############
    )

    # _prefix = """Given the following conversation and a follow up game detail, summarize the follow up game detail 
    #in a way that is coherent with the conversation.\
    #  You should assume that the detail is related to Game Design. Never change the game Title unless the human asks you to."""
    _prefix = """ If the input and the follow up input are closely related, and are both related to the game suggested by 
    the previous conversation and if you are completely confident if it the same game from the original converation, then proceed. Otherwise, clarify the game title and proceed.
    To proceed, retrieve the game Title and share again in quotes to the human, and summarize the follow up input in a way that is coherent with the conversation. 
    If the input detail is related to Game Design, proceed, otherwise clarify.
        """

    _suffix = """## AI:

    Chat History:
    {chat_history}
    Follow Up Input: {game_description}
    standalone detail:"""
    eg_store = Weaviate(
        client,
        "Rephrase",
        "content",
        attributes=["game_description", "game_environment", "chat_history"], 
    )

    example_selector = SemanticSimilarityExampleSelector(vectorstore=eg_store, k=4) # looks for similar examples in vector db
    prompt = FewShotPromptTemplate(
        prefix=_prefix, # prompt
        suffix=_suffix,
        example_selector=example_selector,
        example_prompt=_eg_prompt,
        input_variables=["game_description", "chat_history"],
    )
    llm = OpenAI(temperature=0.7, model_name="text-davinci-003", max_tokens=1000)
    key_word_extractor = LLMChain(llm=llm, prompt=prompt) # this could be game word extractor

    # Gives an example and relevant documents # from Vector DB  ##################################################### showing up in UI ##############
    EXAMPLE_PROMPT = PromptTemplate(
        template=">AI:\nContent:\n---------\n{page_content}\n----------\n", # not working right now ? 
        input_variables=["page_content"],
    )

    template = """
    You are an AI assistant for generating a single game, the central narrative and its game quests inside the same game, 
    conversing in a succinct, coherent and interactive manner. Assume the entire conversation is about a single game only.

    You are given the game description. You are also given the chat history, which is a conversation between a human and 
    another AI assistant about the same game. Do not answer any questions from the other AI assistant. 
    If you don't know the answer, just say "I'm not sure, how this is related?" and ask the human to clarify.

    If asked about a quest, assume it is within the same game, 
    and provide a quest motivation, participants, rewards, character dialogue relevant to the game.

    From the input, introduce a short back story of the game's plot points or character motivations and character dialogue.
    Plot points may include an inciting incidient, a rising action composed of a series of conflicts, complications, dilemmas, obstacles.

    From the input, generate game objects (collectibles, NPCs, enemies) related to the plot points, limit to 1-2 objects.
    Ask a short question to clarify details if you are unsure but you are an expert so offer a suggestion and only ask once.
    
    If the human asks for or adds game objects, provide only 1 detail such as physical description and possible player interactions with the object.
    If the human asks for or adds an enemy, describe its behaviors and personality, as related to the game plot points, limit to a few words.
    If the human asks for or adds a collectible, describe its physical appearance and possible player interactions with the object.
    If the human asks for or adds a noun or NPC, describe its behaviors and personality, as related to the game plot points, limit to a few words.
    If the huamn asks for character dialogue, provide a short dialogue snippet, with 1-2 sentences, as related to the game plot points.
    Limit your reponses to 3-6 sentences.
    
    Game Description: {game_description}
    {context}
    Answer in Markdown:"""

    PROMPT = PromptTemplate(template=template, input_variables=["game_description", "context"])
    doc_chain = load_qa_chain(
        OpenAI(temperature=0.7, model_name="text-davinci-003", max_tokens=1000),
        chain_type="stuff", # all related data is stuffed into prompt as context
        prompt=PROMPT,
        document_prompt=EXAMPLE_PROMPT,
    )
    return CustomChain(
        chain=doc_chain, vstore=vectorstore, key_word_extractor=key_word_extractor
    )
    # doc + input -> game environment

def _get_chat_history(chat_history: List[Tuple[str, str]]):
    buffer = ""
    for human_s, ai_s in chat_history:
        human = f"Human: " + human_s
        ai = f"Assistant: " + ai_s
        buffer += "\n" + "\n".join([human, ai])
    return buffer