We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Cannot have multi-turn conversation with agent via interactive_web.py script
Cannot have multi-turn conversation with agent via interactive_web.py script

**Reproduction steps**
Run interacive_web.py with some model file 
```
python3 ../ParlAI/parlai/scripts/interactive_web.py -mf ~/models/model_file 
```
communicate with the agent, send any two consecutive messages as shown below.
```
curl -XPOST "http://localhost:8080/interact" "Content-Type: text" -d "Hello"
```
**Expected behavior**
No exception should be thrown, agent should be available for multi-turn conversation.

The second message produces the following stacktrace
```
Exception happened during processing of request from ('127.0.0.1', 55372)
Traceback (most recent call last):
  File "/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/socketserver.py", line 320, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/socketserver.py", line 351, in process_request
    self.finish_request(request, client_address)
  File "/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/socketserver.py", line 364, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/socketserver.py", line 724, in __init__
    self.handle()
  File "/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/http/server.py", line 418, in handle
    self.handle_one_request()
  File "/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/http/server.py", line 406, in handle_one_request
    method()
  File "/Users/johnsmith/ParlAI/parlai/scripts/interactive_web.py", line 155, in do_POST
    SHARED.get('opt'), body.decode('utf-8')
  File "/Users/johnsmith/ParlAI/parlai/scripts/interactive_web.py", line 139, in interactive_running
    SHARED['agent'].observe(reply)
  File "/Users/johnsmith/ParlAI/parlai/core/torch_agent.py", line 1545, in observe
    reply = self.last_reply(use_reply=self.opt.get('use_reply', 'label'))
  File "/Users/johnsmith/ParlAI/parlai/core/torch_agent.py", line 1515, in last_reply
    or self.observation['episode_done']
KeyError: 'episode_done'
--------------------------

After second message.
```

### Suggestion
The following edit could be made to prevent this issue.
```
self.observation['episode_done'] --> 'episode_done' in self.observation
```
### Extra
Making the change above allows multi-turn conversation, but now there is the question of some functionality terminating the conversation from the client-side i.e.
```
curl -XPOST "http://localhost:8080/interact" "Content-Type: text" -d "[DONE]"
```
such that user application or human has some option to terminate multi-turn conversations. 
If this should be moved to functionality, just let me know!

Thank you 🙏 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `parlai/scripts/interactive_web.py`
Content:
```
1 #!/usr/bin/env python3
2 
3 # Copyright (c) Facebook, Inc. and its affiliates.
4 # This source code is licensed under the MIT license found in the
5 # LICENSE file in the root directory of this source tree.
6 """ Talk with a model using a web UI. """
7 
8 
9 from http.server import BaseHTTPRequestHandler, HTTPServer
10 from parlai.scripts.interactive import setup_args
11 from parlai.core.agents import create_agent
12 from parlai.core.worlds import create_task
13 
14 import json
15 
16 HOST_NAME = 'localhost'
17 PORT = 8080
18 SHARED = {}
19 STYLE_SHEET = "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.css"
20 FONT_AWESOME = "https://use.fontawesome.com/releases/v5.3.1/js/all.js"
21 WEB_HTML = """
22 <html>
23     <link rel="stylesheet" href={} />
24     <script defer src={}></script>
25     <head><title> Interactive Run </title></head>
26     <body>
27         <div class="columns">
28             <div class="column is-three-fifths is-offset-one-fifth">
29               <section class="hero is-info is-large has-background-light has-text-grey-dark">
30                 <div id="parent" class="hero-body">
31                     <article class="media">
32                       <figure class="media-left">
33                         <span class="icon is-large">
34                           <i class="fas fa-robot fas fa-2x"></i>
35                         </span>
36                       </figure>
37                       <div class="media-content">
38                         <div class="content">
39                           <p>
40                             <strong>Model</strong>
41                             <br>
42                             Enter a message, and the model will respond interactively.
43                           </p>
44                         </div>
45                       </div>
46                     </article>
47                 </div>
48                 <div class="hero-foot column is-three-fifths is-offset-one-fifth">
49                   <form id = "interact">
50                       <div class="field is-grouped">
51                         <p class="control is-expanded">
52                           <input class="input" type="text" id="userIn" placeholder="Type in a message">
53                         </p>
54                         <p class="control">
55                           <button id="respond" type="submit" class="button has-text-white-ter has-background-grey-dark">
56                             Submit
57                           </button>
58                         </p>
59                       </div>
60                   </form>
61                 </div>
62               </section>
63             </div>
64         </div>
65 
66         <script>
67             function createChatRow(agent, text) {{
68                 var article = document.createElement("article");
69                 article.className = "media"
70 
71                 var figure = document.createElement("figure");
72                 figure.className = "media-left";
73 
74                 var span = document.createElement("span");
75                 span.className = "icon is-large";
76 
77                 var icon = document.createElement("i");
78                 icon.className = "fas fas fa-2x" + (agent === "You" ? " fa-user " : agent === "Model" ? " fa-robot" : "");
79 
80                 var media = document.createElement("div");
81                 media.className = "media-content";
82 
83                 var content = document.createElement("div");
84                 content.className = "content";
85 
86                 var para = document.createElement("p");
87                 var paraText = document.createTextNode(text);
88 
89                 var strong = document.createElement("strong");
90                 strong.innerHTML = agent;
91                 var br = document.createElement("br");
92 
93                 para.appendChild(strong);
94                 para.appendChild(br);
95                 para.appendChild(paraText);
96                 content.appendChild(para);
97                 media.appendChild(content);
98 
99                 span.appendChild(icon);
100                 figure.appendChild(span);
101 
102                 article.appendChild(figure);
103                 article.appendChild(media);
104 
105                 return article;
106             }}
107             document.getElementById("interact").addEventListener("submit", function(event){{
108                 event.preventDefault()
109                 var text = document.getElementById("userIn").value;
110                 document.getElementById('userIn').value = "";
111 
112                 fetch('/interact', {{
113                     headers: {{
114                         'Content-Type': 'application/json'
115                     }},
116                     method: 'POST',
117                     body: text
118                 }}).then(response=>response.json()).then(data=>{{
119                     var parDiv = document.getElementById("parent");
120 
121                     parDiv.append(createChatRow("You", text));
122 
123                     // Change info for Model response
124                     parDiv.append(createChatRow("Model", data.text));
125                     window.scrollTo(0,document.body.scrollHeight);
126                 }})
127             }});
128         </script>
129 
130     </body>
131 </html>
132 """  # noqa: E501
133 
134 
135 class MyHandler(BaseHTTPRequestHandler):
136     def interactive_running(self, opt, reply_text):
137         reply = {}
138         reply['text'] = reply_text
139         SHARED['agent'].observe(reply)
140         model_res = SHARED['agent'].act()
141         return model_res
142 
143     def do_HEAD(self):
144         self.send_response(200)
145         self.send_header('Content-type', 'text/html')
146         self.end_headers()
147 
148     def do_POST(self):
149         if self.path != '/interact':
150             return self.respond({'status': 500})
151 
152         content_length = int(self.headers['Content-Length'])
153         body = self.rfile.read(content_length)
154         model_response = self.interactive_running(
155             SHARED.get('opt'), body.decode('utf-8')
156         )
157 
158         self.send_response(200)
159         self.send_header('Content-type', 'application/json')
160         self.end_headers()
161         json_str = json.dumps(model_response)
162         self.wfile.write(bytes(json_str, 'utf-8'))
163 
164     def do_GET(self):
165         paths = {
166             '/': {'status': 200},
167             '/favicon.ico': {'status': 202},  # Need for chrome
168         }
169         if self.path in paths:
170             self.respond(paths[self.path])
171         else:
172             self.respond({'status': 500})
173 
174     def handle_http(self, status_code, path, text=None):
175         self.send_response(status_code)
176         self.send_header('Content-type', 'text/html')
177         self.end_headers()
178         content = WEB_HTML.format(STYLE_SHEET, FONT_AWESOME)
179         return bytes(content, 'UTF-8')
180 
181     def respond(self, opts):
182         response = self.handle_http(opts['status'], self.path)
183         self.wfile.write(response)
184 
185 
186 def setup_interactive(shared):
187     parser = setup_args()
188     SHARED['opt'] = parser.parse_args(print_args=True)
189 
190     SHARED['opt']['task'] = 'parlai.agents.local_human.local_human:LocalHumanAgent'
191 
192     # Create model and assign it to the specified task
193     SHARED['agent'] = create_agent(SHARED.get('opt'), requireModelExists=True)
194     SHARED['world'] = create_task(SHARED.get('opt'), SHARED['agent'])
195 
196 
197 if __name__ == '__main__':
198     setup_interactive(SHARED)
199     server_class = HTTPServer
200     Handler = MyHandler
201     Handler.protocol_version = 'HTTP/1.0'
202     httpd = server_class((HOST_NAME, PORT), Handler)
203     print('http://{}:{}/'.format(HOST_NAME, PORT))
204 
205     try:
206         httpd.serve_forever()
207     except KeyboardInterrupt:
208         pass
209     httpd.server_close()
210
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/parlai/scripts/interactive_web.py b/parlai/scripts/interactive_web.py
--- a/parlai/scripts/interactive_web.py
+++ b/parlai/scripts/interactive_web.py
@@ -134,8 +134,7 @@
 
 class MyHandler(BaseHTTPRequestHandler):
     def interactive_running(self, opt, reply_text):
-        reply = {}
-        reply['text'] = reply_text
+        reply = {'episode_done': False, 'text': reply_text}
         SHARED['agent'].observe(reply)
         model_res = SHARED['agent'].act()
         return model_res

{"golden_diff": "diff --git a/parlai/scripts/interactive_web.py b/parlai/scripts/interactive_web.py\n--- a/parlai/scripts/interactive_web.py\n+++ b/parlai/scripts/interactive_web.py\n@@ -134,8 +134,7 @@\n \n class MyHandler(BaseHTTPRequestHandler):\n     def interactive_running(self, opt, reply_text):\n-        reply = {}\n-        reply['text'] = reply_text\n+        reply = {'episode_done': False, 'text': reply_text}\n         SHARED['agent'].observe(reply)\n         model_res = SHARED['agent'].act()\n         return model_res\n", "issue": "Cannot have multi-turn conversation with agent via interactive_web.py script\nCannot have multi-turn conversation with agent via interactive_web.py script\r\n\r\n**Reproduction steps**\r\nRun interacive_web.py with some model file \r\n```\r\npython3 ../ParlAI/parlai/scripts/interactive_web.py -mf ~/models/model_file \r\n```\r\ncommunicate with the agent, send any two consecutive messages as shown below.\r\n```\r\ncurl -XPOST \"http://localhost:8080/interact\" \"Content-Type: text\" -d \"Hello\"\r\n```\r\n**Expected behavior**\r\nNo exception should be thrown, agent should be available for multi-turn conversation.\r\n\r\nThe second message produces the following stacktrace\r\n```\r\nException happened during processing of request from ('127.0.0.1', 55372)\r\nTraceback (most recent call last):\r\n  File \"/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/socketserver.py\", line 320, in _handle_request_noblock\r\n    self.process_request(request, client_address)\r\n  File \"/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/socketserver.py\", line 351, in process_request\r\n    self.finish_request(request, client_address)\r\n  File \"/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/socketserver.py\", line 364, in finish_request\r\n    self.RequestHandlerClass(request, client_address, self)\r\n  File \"/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/socketserver.py\", line 724, in __init__\r\n    self.handle()\r\n  File \"/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/http/server.py\", line 418, in handle\r\n    self.handle_one_request()\r\n  File \"/Users/johnsmith/miniconda3/envs/rasa-env/lib/python3.6/http/server.py\", line 406, in handle_one_request\r\n    method()\r\n  File \"/Users/johnsmith/ParlAI/parlai/scripts/interactive_web.py\", line 155, in do_POST\r\n    SHARED.get('opt'), body.decode('utf-8')\r\n  File \"/Users/johnsmith/ParlAI/parlai/scripts/interactive_web.py\", line 139, in interactive_running\r\n    SHARED['agent'].observe(reply)\r\n  File \"/Users/johnsmith/ParlAI/parlai/core/torch_agent.py\", line 1545, in observe\r\n    reply = self.last_reply(use_reply=self.opt.get('use_reply', 'label'))\r\n  File \"/Users/johnsmith/ParlAI/parlai/core/torch_agent.py\", line 1515, in last_reply\r\n    or self.observation['episode_done']\r\nKeyError: 'episode_done'\r\n--------------------------\r\n\r\nAfter second message.\r\n```\r\n\r\n### Suggestion\r\nThe following edit could be made to prevent this issue.\r\n```\r\nself.observation['episode_done'] --> 'episode_done' in self.observation\r\n```\r\n### Extra\r\nMaking the change above allows multi-turn conversation, but now there is the question of some functionality terminating the conversation from the client-side i.e.\r\n```\r\ncurl -XPOST \"http://localhost:8080/interact\" \"Content-Type: text\" -d \"[DONE]\"\r\n```\r\nsuch that user application or human has some option to terminate multi-turn conversations. \r\nIf this should be moved to functionality, just let me know!\r\n\r\nThank you \ud83d\ude4f \n", "before_files": [{"content": "#!/usr/bin/env python3\n\n# Copyright (c) Facebook, Inc. and its affiliates.\n# This source code is licensed under the MIT license found in the\n# LICENSE file in the root directory of this source tree.\n\"\"\" Talk with a model using a web UI. \"\"\"\n\n\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\nfrom parlai.scripts.interactive import setup_args\nfrom parlai.core.agents import create_agent\nfrom parlai.core.worlds import create_task\n\nimport json\n\nHOST_NAME = 'localhost'\nPORT = 8080\nSHARED = {}\nSTYLE_SHEET = \"https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.css\"\nFONT_AWESOME = \"https://use.fontawesome.com/releases/v5.3.1/js/all.js\"\nWEB_HTML = \"\"\"\n<html>\n    <link rel=\"stylesheet\" href={} />\n    <script defer src={}></script>\n    <head><title> Interactive Run </title></head>\n    <body>\n        <div class=\"columns\">\n            <div class=\"column is-three-fifths is-offset-one-fifth\">\n              <section class=\"hero is-info is-large has-background-light has-text-grey-dark\">\n                <div id=\"parent\" class=\"hero-body\">\n                    <article class=\"media\">\n                      <figure class=\"media-left\">\n                        <span class=\"icon is-large\">\n                          <i class=\"fas fa-robot fas fa-2x\"></i>\n                        </span>\n                      </figure>\n                      <div class=\"media-content\">\n                        <div class=\"content\">\n                          <p>\n                            <strong>Model</strong>\n                            <br>\n                            Enter a message, and the model will respond interactively.\n                          </p>\n                        </div>\n                      </div>\n                    </article>\n                </div>\n                <div class=\"hero-foot column is-three-fifths is-offset-one-fifth\">\n                  <form id = \"interact\">\n                      <div class=\"field is-grouped\">\n                        <p class=\"control is-expanded\">\n                          <input class=\"input\" type=\"text\" id=\"userIn\" placeholder=\"Type in a message\">\n                        </p>\n                        <p class=\"control\">\n                          <button id=\"respond\" type=\"submit\" class=\"button has-text-white-ter has-background-grey-dark\">\n                            Submit\n                          </button>\n                        </p>\n                      </div>\n                  </form>\n                </div>\n              </section>\n            </div>\n        </div>\n\n        <script>\n            function createChatRow(agent, text) {{\n                var article = document.createElement(\"article\");\n                article.className = \"media\"\n\n                var figure = document.createElement(\"figure\");\n                figure.className = \"media-left\";\n\n                var span = document.createElement(\"span\");\n                span.className = \"icon is-large\";\n\n                var icon = document.createElement(\"i\");\n                icon.className = \"fas fas fa-2x\" + (agent === \"You\" ? \" fa-user \" : agent === \"Model\" ? \" fa-robot\" : \"\");\n\n                var media = document.createElement(\"div\");\n                media.className = \"media-content\";\n\n                var content = document.createElement(\"div\");\n                content.className = \"content\";\n\n                var para = document.createElement(\"p\");\n                var paraText = document.createTextNode(text);\n\n                var strong = document.createElement(\"strong\");\n                strong.innerHTML = agent;\n                var br = document.createElement(\"br\");\n\n                para.appendChild(strong);\n                para.appendChild(br);\n                para.appendChild(paraText);\n                content.appendChild(para);\n                media.appendChild(content);\n\n                span.appendChild(icon);\n                figure.appendChild(span);\n\n                article.appendChild(figure);\n                article.appendChild(media);\n\n                return article;\n            }}\n            document.getElementById(\"interact\").addEventListener(\"submit\", function(event){{\n                event.preventDefault()\n                var text = document.getElementById(\"userIn\").value;\n                document.getElementById('userIn').value = \"\";\n\n                fetch('/interact', {{\n                    headers: {{\n                        'Content-Type': 'application/json'\n                    }},\n                    method: 'POST',\n                    body: text\n                }}).then(response=>response.json()).then(data=>{{\n                    var parDiv = document.getElementById(\"parent\");\n\n                    parDiv.append(createChatRow(\"You\", text));\n\n                    // Change info for Model response\n                    parDiv.append(createChatRow(\"Model\", data.text));\n                    window.scrollTo(0,document.body.scrollHeight);\n                }})\n            }});\n        </script>\n\n    </body>\n</html>\n\"\"\"  # noqa: E501\n\n\nclass MyHandler(BaseHTTPRequestHandler):\n    def interactive_running(self, opt, reply_text):\n        reply = {}\n        reply['text'] = reply_text\n        SHARED['agent'].observe(reply)\n        model_res = SHARED['agent'].act()\n        return model_res\n\n    def do_HEAD(self):\n        self.send_response(200)\n        self.send_header('Content-type', 'text/html')\n        self.end_headers()\n\n    def do_POST(self):\n        if self.path != '/interact':\n            return self.respond({'status': 500})\n\n        content_length = int(self.headers['Content-Length'])\n        body = self.rfile.read(content_length)\n        model_response = self.interactive_running(\n            SHARED.get('opt'), body.decode('utf-8')\n        )\n\n        self.send_response(200)\n        self.send_header('Content-type', 'application/json')\n        self.end_headers()\n        json_str = json.dumps(model_response)\n        self.wfile.write(bytes(json_str, 'utf-8'))\n\n    def do_GET(self):\n        paths = {\n            '/': {'status': 200},\n            '/favicon.ico': {'status': 202},  # Need for chrome\n        }\n        if self.path in paths:\n            self.respond(paths[self.path])\n        else:\n            self.respond({'status': 500})\n\n    def handle_http(self, status_code, path, text=None):\n        self.send_response(status_code)\n        self.send_header('Content-type', 'text/html')\n        self.end_headers()\n        content = WEB_HTML.format(STYLE_SHEET, FONT_AWESOME)\n        return bytes(content, 'UTF-8')\n\n    def respond(self, opts):\n        response = self.handle_http(opts['status'], self.path)\n        self.wfile.write(response)\n\n\ndef setup_interactive(shared):\n    parser = setup_args()\n    SHARED['opt'] = parser.parse_args(print_args=True)\n\n    SHARED['opt']['task'] = 'parlai.agents.local_human.local_human:LocalHumanAgent'\n\n    # Create model and assign it to the specified task\n    SHARED['agent'] = create_agent(SHARED.get('opt'), requireModelExists=True)\n    SHARED['world'] = create_task(SHARED.get('opt'), SHARED['agent'])\n\n\nif __name__ == '__main__':\n    setup_interactive(SHARED)\n    server_class = HTTPServer\n    Handler = MyHandler\n    Handler.protocol_version = 'HTTP/1.0'\n    httpd = server_class((HOST_NAME, PORT), Handler)\n    print('http://{}:{}/'.format(HOST_NAME, PORT))\n\n    try:\n        httpd.serve_forever()\n    except KeyboardInterrupt:\n        pass\n    httpd.server_close()\n", "path": "parlai/scripts/interactive_web.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n\n# Copyright (c) Facebook, Inc. and its affiliates.\n# This source code is licensed under the MIT license found in the\n# LICENSE file in the root directory of this source tree.\n\"\"\" Talk with a model using a web UI. \"\"\"\n\n\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\nfrom parlai.scripts.interactive import setup_args\nfrom parlai.core.agents import create_agent\nfrom parlai.core.worlds import create_task\n\nimport json\n\nHOST_NAME = 'localhost'\nPORT = 8080\nSHARED = {}\nSTYLE_SHEET = \"https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.css\"\nFONT_AWESOME = \"https://use.fontawesome.com/releases/v5.3.1/js/all.js\"\nWEB_HTML = \"\"\"\n<html>\n    <link rel=\"stylesheet\" href={} />\n    <script defer src={}></script>\n    <head><title> Interactive Run </title></head>\n    <body>\n        <div class=\"columns\">\n            <div class=\"column is-three-fifths is-offset-one-fifth\">\n              <section class=\"hero is-info is-large has-background-light has-text-grey-dark\">\n                <div id=\"parent\" class=\"hero-body\">\n                    <article class=\"media\">\n                      <figure class=\"media-left\">\n                        <span class=\"icon is-large\">\n                          <i class=\"fas fa-robot fas fa-2x\"></i>\n                        </span>\n                      </figure>\n                      <div class=\"media-content\">\n                        <div class=\"content\">\n                          <p>\n                            <strong>Model</strong>\n                            <br>\n                            Enter a message, and the model will respond interactively.\n                          </p>\n                        </div>\n                      </div>\n                    </article>\n                </div>\n                <div class=\"hero-foot column is-three-fifths is-offset-one-fifth\">\n                  <form id = \"interact\">\n                      <div class=\"field is-grouped\">\n                        <p class=\"control is-expanded\">\n                          <input class=\"input\" type=\"text\" id=\"userIn\" placeholder=\"Type in a message\">\n                        </p>\n                        <p class=\"control\">\n                          <button id=\"respond\" type=\"submit\" class=\"button has-text-white-ter has-background-grey-dark\">\n                            Submit\n                          </button>\n                        </p>\n                      </div>\n                  </form>\n                </div>\n              </section>\n            </div>\n        </div>\n\n        <script>\n            function createChatRow(agent, text) {{\n                var article = document.createElement(\"article\");\n                article.className = \"media\"\n\n                var figure = document.createElement(\"figure\");\n                figure.className = \"media-left\";\n\n                var span = document.createElement(\"span\");\n                span.className = \"icon is-large\";\n\n                var icon = document.createElement(\"i\");\n                icon.className = \"fas fas fa-2x\" + (agent === \"You\" ? \" fa-user \" : agent === \"Model\" ? \" fa-robot\" : \"\");\n\n                var media = document.createElement(\"div\");\n                media.className = \"media-content\";\n\n                var content = document.createElement(\"div\");\n                content.className = \"content\";\n\n                var para = document.createElement(\"p\");\n                var paraText = document.createTextNode(text);\n\n                var strong = document.createElement(\"strong\");\n                strong.innerHTML = agent;\n                var br = document.createElement(\"br\");\n\n                para.appendChild(strong);\n                para.appendChild(br);\n                para.appendChild(paraText);\n                content.appendChild(para);\n                media.appendChild(content);\n\n                span.appendChild(icon);\n                figure.appendChild(span);\n\n                article.appendChild(figure);\n                article.appendChild(media);\n\n                return article;\n            }}\n            document.getElementById(\"interact\").addEventListener(\"submit\", function(event){{\n                event.preventDefault()\n                var text = document.getElementById(\"userIn\").value;\n                document.getElementById('userIn').value = \"\";\n\n                fetch('/interact', {{\n                    headers: {{\n                        'Content-Type': 'application/json'\n                    }},\n                    method: 'POST',\n                    body: text\n                }}).then(response=>response.json()).then(data=>{{\n                    var parDiv = document.getElementById(\"parent\");\n\n                    parDiv.append(createChatRow(\"You\", text));\n\n                    // Change info for Model response\n                    parDiv.append(createChatRow(\"Model\", data.text));\n                    window.scrollTo(0,document.body.scrollHeight);\n                }})\n            }});\n        </script>\n\n    </body>\n</html>\n\"\"\"  # noqa: E501\n\n\nclass MyHandler(BaseHTTPRequestHandler):\n    def interactive_running(self, opt, reply_text):\n        reply = {'episode_done': False, 'text': reply_text}\n        SHARED['agent'].observe(reply)\n        model_res = SHARED['agent'].act()\n        return model_res\n\n    def do_HEAD(self):\n        self.send_response(200)\n        self.send_header('Content-type', 'text/html')\n        self.end_headers()\n\n    def do_POST(self):\n        if self.path != '/interact':\n            return self.respond({'status': 500})\n\n        content_length = int(self.headers['Content-Length'])\n        body = self.rfile.read(content_length)\n        model_response = self.interactive_running(\n            SHARED.get('opt'), body.decode('utf-8')\n        )\n\n        self.send_response(200)\n        self.send_header('Content-type', 'application/json')\n        self.end_headers()\n        json_str = json.dumps(model_response)\n        self.wfile.write(bytes(json_str, 'utf-8'))\n\n    def do_GET(self):\n        paths = {\n            '/': {'status': 200},\n            '/favicon.ico': {'status': 202},  # Need for chrome\n        }\n        if self.path in paths:\n            self.respond(paths[self.path])\n        else:\n            self.respond({'status': 500})\n\n    def handle_http(self, status_code, path, text=None):\n        self.send_response(status_code)\n        self.send_header('Content-type', 'text/html')\n        self.end_headers()\n        content = WEB_HTML.format(STYLE_SHEET, FONT_AWESOME)\n        return bytes(content, 'UTF-8')\n\n    def respond(self, opts):\n        response = self.handle_http(opts['status'], self.path)\n        self.wfile.write(response)\n\n\ndef setup_interactive(shared):\n    parser = setup_args()\n    SHARED['opt'] = parser.parse_args(print_args=True)\n\n    SHARED['opt']['task'] = 'parlai.agents.local_human.local_human:LocalHumanAgent'\n\n    # Create model and assign it to the specified task\n    SHARED['agent'] = create_agent(SHARED.get('opt'), requireModelExists=True)\n    SHARED['world'] = create_task(SHARED.get('opt'), SHARED['agent'])\n\n\nif __name__ == '__main__':\n    setup_interactive(SHARED)\n    server_class = HTTPServer\n    Handler = MyHandler\n    Handler.protocol_version = 'HTTP/1.0'\n    httpd = server_class((HOST_NAME, PORT), Handler)\n    print('http://{}:{}/'.format(HOST_NAME, PORT))\n\n    try:\n        httpd.serve_forever()\n    except KeyboardInterrupt:\n        pass\n    httpd.server_close()\n", "path": "parlai/scripts/interactive_web.py"}]}