├── README.md ├── conversations ├── actor.txt ├── cooking.txt ├── dinner.txt └── tech_stack.txt ├── parse_context.py └── requirements.txt /README.md: -------------------------------------------------------------------------------- 1 | # `parse_context` 2 | 3 | This program uses the OpenAI API, powered by GPT-3, to power the logic of a context-based 4 | active-listening voice assistant. The context of this software is: 5 | 6 | - Humans have a conversation, which is recorded and transcribed in real time. 7 | - (**THIS PROGRAM**) The conversation is sent to the OpenAI API along with a few-shot list of examples. The API returns a 8 | detected context, suggestions for what outputs would be useful to the humans, and a list of data sources 9 | for achieving those outputs. 10 | - The voice assistant presents the data to the user to augment the conversation. 11 | 12 | ## Requirements 13 | 14 | - Python 3 15 | - OpenAI Python Client 16 | - OpenAI API key 17 | 18 | ### Installation 19 | 20 | #### API Key Setup 21 | 22 | First, set up your API key: 23 | 24 | ```bash 25 | export OPENAI_API_KEY='sk-' 26 | ``` 27 | 28 | To make it persistent, 29 | 30 | ```bash 31 | echo "export OPENAI_API_KEY='sk-'" >> ~/.bashrc && source ~/.bashrc 32 | ``` 33 | 34 | #### Python and Packages Setup 35 | 36 | Install Python. Install Pip for Python3. Then run: 37 | 38 | ```bash 39 | pip3 install -r ./requirements.txt 40 | ``` 41 | 42 | To update the requirements file after changing, you can use: 43 | 44 | ```bash 45 | pip3 freeze > ./requirements.txt 46 | ``` 47 | 48 | Or 49 | 50 | ```bash 51 | pip3 freeze | grep openai > ./requirements.txt 52 | ``` 53 | 54 | ## Usage 55 | 56 | ### Non-interactive mode (default) 57 | 58 | To use non-interactive mode, make sure the `INTERACTIVE` flag at the top of `parse_context.py` is set to `False`. 59 | 60 | Then, run the program while passing your conversation to standard input (`STDIN`). For example, if the above 61 | conversation were placed in a file located at `./conversations/tech_stack.txt`, we could run: 62 | 63 | ```bash 64 | cat ./conversations/tech_stack.txt | python3 parse_context.py 65 | ``` 66 | 67 | The result will be printed to `STDOUT` (default is the terminal window). 68 | 69 | ### Interactive Mode 70 | 71 | To use interactive mode, make sure the `INTERACTIVE` flag at the top of `parse_context.py` is set to `True`. 72 | 73 | Then, run `python3 parse_context.py`. You can enter the conversation on the command line 74 | in the following format, using `/end` to stop. 75 | 76 | ``` 77 | A: Hey, what tech stack do you think we should use for the new app? 78 | B: What app? 79 | A: The dating app we are developing. It needs to be cross-platform mobile. 80 | B: Oh, okay. Um... I don't really know any good frameworks 81 | /end 82 | ``` 83 | 84 | And the result will be printed to `STDOUT`. 85 | 86 | ## Examples of AI Output 87 | 88 | For each example, the format is: 89 | 90 | ``` 91 | input 92 | ``` 93 | 94 | ``` 95 | AI output 96 | ``` 97 | 98 | #### Talking about an actor 99 | ``` 100 | A: I watched Terminator last night. 101 | B: Oh, cool! I love that movie, it's a classic. 102 | A: Arnold Schwarzenegger was so good. 103 | B: Yeah, I agree. 104 | ``` 105 | ``` 106 | Context: A group of people are talking about a film 107 | Useful Output: Information about Arnold Schwarzenegger filmography 108 | Relevant Data Sources: Query Google Search for "Arnold Schwarzenegger filmography" 109 | ``` 110 | 111 | #### Going to Dinner 112 | ``` 113 | A: Hey Mike, let's get dinner tonight. 114 | B: Okay, sure! What restaurants do you know in the area? 115 | ``` 116 | ``` 117 | Context: Two friends are trying to decide what to eat for dinner 118 | Useful Output: List of restaurants nearby, restaurant reviews, restaurant menus 119 | Relevant Data Sources: Query Foursquare API for restaurants, query Yelp API for reviews, query OpenTable API for restaurant menus 120 | ``` 121 | 122 | #### Developing an App 123 | ``` 124 | A: Hey, what tech stack do you think we should use for the new app? 125 | B: What app? 126 | A: The dating app we are developing. It needs to be cross-platform mobile. 127 | B: Oh, okay. Um... I don't really know any good frameworks 128 | ``` 129 | ``` 130 | Context: Two people are discussing the development of a new cross-platform mobile application 131 | Useful Output: List of popular frameworks 132 | Relevant Data Sources: Query Stack Overflow website for most popular frameworks. 133 | ``` 134 | 135 | #### Cooking a Meal 136 | ``` 137 | A: Hey, what do you think we should cook for dinner tonight? 138 | B: Dunno. Let's check the fridge. 139 | A: Okay. Looks like we've got chicken, beef, lettuce, rice, mustard, mayo, taco shells, and corn. 140 | B: How about tacos? 141 | ``` 142 | ``` 143 | Context: Two people are talking about dinner 144 | Useful Output: Ingredients, recipe, estimated cooking time 145 | Relevant Data Sources: Query Google Search for "recipes with chicken, beef, lettuce, rice, mustard, mayo, taco shells, and corn", query Google Maps API for local grocery stores 146 | ``` 147 | 148 | ## License 149 | 150 | This is released under the MIT License. 151 | 152 | ## Legal 153 | 154 | Please refer to the OpenAI website for information regarding the legal and copyright status of content produced by GPT-3. 155 | By using this software, you agree that as the repository author, Radu Vasilescu, I am not responsible for any content 156 | produced by this software, including completions and model output. All content/media produced with this software must 157 | be attributed to the person or company who produced the output-- not me, and not OpenAI. 158 | I hereby release the content of this document as well as the examples included herein to the public domain. 159 | -------------------------------------------------------------------------------- /conversations/actor.txt: -------------------------------------------------------------------------------- 1 | A: I watched Terminator last night. 2 | B: Oh, cool! I love that movie, it's a classic. 3 | A: Arnold Schwarzenegger was so good. 4 | B: Yeah, I agree. 5 | -------------------------------------------------------------------------------- /conversations/cooking.txt: -------------------------------------------------------------------------------- 1 | A: Hey, what do you think we should cook for dinner tonight? 2 | B: Dunno. Let's check the fridge. 3 | A: Okay. Looks like we've got chicken, beef, lettuce, rice, mustard, mayo, taco shells, and corn. 4 | B: How about tacos? 5 | -------------------------------------------------------------------------------- /conversations/dinner.txt: -------------------------------------------------------------------------------- 1 | A: Hey Mike, let's get dinner tonight. 2 | B: Okay, sure! What restaurants do you know in the area? 3 | -------------------------------------------------------------------------------- /conversations/tech_stack.txt: -------------------------------------------------------------------------------- 1 | A: Hey, what tech stack do you think we should use for the new app? 2 | B: What app? 3 | A: The dating app we are developing. It needs to be cross-platform mobile. 4 | B: Oh, okay. Um... I don't really know any good frameworks 5 | -------------------------------------------------------------------------------- /parse_context.py: -------------------------------------------------------------------------------- 1 | """ 2 | Author: Radu Vasilescu 3 | Date: 2020-11-10 4 | """ 5 | 6 | import os 7 | import sys 8 | import openai 9 | 10 | """ 11 | Determines the input method for the script. 12 | 13 | A value of True reads the program's input from the command line interactively. 14 | A value of False reads the program's input from the process' STDIN. An example of 15 | non-interactive usage is: 16 | 17 | cat ./conversations/dinner.txt | python3 parse_content.py 18 | """ 19 | INTERACTIVE : bool = False 20 | 21 | openai.api_key : str = os.environ["OPENAI_API_KEY"] 22 | 23 | # Set up 4-shot example prompts: 24 | examples : str = "The following is a list of conversations between humans. A voice-activated AI suggests information that might be relevant in the context of the conversation.\n\nA: I'm going to leave for work soon.\nB: Okay, I'm leaving too.\nA: Let me get dressed first.\nContext: Two people are about to leave for work.\nUseful Output: Current weather, current traffic, estimated commute time, reminders\nRelevant Data Sources: Query Google Weather API to get current weather, query Google Maps API to get traffic and commute time, query Reminders app to get reminders.\n\nA: Have you seen that movie, Avengers Endgame?\nB: Oh, yeah! I saw it when it came out. I loved Iron Man in that series!\nA: Who played him again? \nB: I don't remember.\nContext: Two people are wondering who played Iron Man in the film Avengers Endgame\nUseful Output: Robert Downey Jr.\nRelevant Data Sources: Query Google Search for \"Who plays Iron Man in Avengers Endgame?\"\n\nA: So, when do you guys want to meet up later?\nB: I don't know, I have a pretty busy evening\nC: I'm free after 5:00pm\nA: Let me look at my schedule.\nContext: A group of people is trying to schedule an event this evening.\nUseful Output: Today's remaining calendar events.\nRelevant Data Sources: Query Google Calendar API for events after 5pm today.\n\nA: I have to pick my daughter up from school today.\nB: Okay, what time is that going to be?\nContext: Two people are talking about a plan to pick someone up from school\nUseful Output: Reminder to pick up the child, current traffic conditions to the school, estimated time to the school\nRelevant Data Sources: Add a reminder to the Reminders app, query Google Maps API for current traffic and school location, query Google Maps API for estimated travel time\n\n" 25 | 26 | start_sequence : str = "Context:" 27 | 28 | conversation : str = "" 29 | if INTERACTIVE: 30 | # Read the conversation from the console 31 | print('Enter conversation. Use /end to signal the end.\n') 32 | 33 | while (line := input()) != '/end': 34 | conversation += line + "\n" 35 | else: 36 | # Read the conversation from standard input 37 | for line in sys.stdin: 38 | if line == "\n" or line == "/end": 39 | print("Do not include neither newlines nor /end in the input (INTERACTIVE = %s)", str(INTERACTIVE)) 40 | exit(1) 41 | conversation += line 42 | 43 | print('Generating completion...') 44 | 45 | response = openai.Completion.create( 46 | engine = "davinci", 47 | prompt = examples + conversation + start_sequence, 48 | temperature = 0.7, 49 | max_tokens = 64, 50 | top_p = 1, 51 | stop = ["\n\n"] 52 | ) 53 | 54 | response_text : str = response["choices"][0]["text"] 55 | response_split = response_text.split("\n") 56 | gen_context, gen_output, gen_sources = response_split[0].strip(), response_split[1].strip(), response_split[2].strip() 57 | 58 | print('Context: ' + gen_context) 59 | print(gen_output) 60 | print(gen_sources) 61 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | openai==0.2.6 2 | --------------------------------------------------------------------------------