def from_dict(cls, raw, Scenario, scenario_db=None): if 'scenario' in raw: scenario = Scenario.from_dict(None, raw['scenario']) # Compatible with old data formats (to be removed) elif scenario_db: print('WARNING: scenario should be provided in the example') scenario = scenario_db.get(raw['scenario_uuid']) else: raise ValueError('No scenario') uuid = raw['scenario_uuid'] events = Event.gather_eval([Event.from_dict(e) for e in raw['events']]) outcome = raw['outcome'] ex_id = raw['uuid'] if 'agents' in raw: agents = {int(k): v for k, v in raw['agents'].iteritems()} else: agents = None agents_info = raw.get('agents_info', None) return Example(scenario, uuid, events, outcome, ex_id, agents, agents_info=agents_info)
def send(self): # TODO: even if cross talk is enabled, we don't want the bot to talk in a row if self.num_utterances >= 1: return None if self.received is False and (self.prev_action == 'select' or \ self.last_message_timestamp + random.uniform(1, self.PATIENCE) > time.time()): return None if len(self.queued_event) == 0: self.queued_event.append(self.session.send()) event = self.queued_event[0] if event is None: return self.queued_event.popleft() if event.action == 'message': delay = float(len(event.data)) / self.CHAR_RATE + random.uniform( 0, self.EPSILON) elif event.action == 'select': delay = self.SELECTION_DELAY + random.uniform(0, self.EPSILON) if self.prev_action == 'select': delay += self.REPEATED_SELECTION_DELAY # TODO: refactor this elif event.action in ('offer', 'accept', 'reject', 'done', 'quit'): delay = self.SELECTION_DELAY + random.uniform(0, self.EPSILON) elif event.action == 'join': delay = 0.5 else: raise ValueError('Unknown event type: %s' % event.action) if self.last_message_timestamp + delay > time.time(): # Add reading time before start typing reading_time = 0 if self.prev_action == 'join' else random.uniform( 0.5, 1) if event.action == 'message' and self.start_typing is False and \ self.last_message_timestamp + reading_time < time.time(): self.start_typing = True return Event.TypingEvent(self.agent, 'started') else: return None else: if event.action == 'message' and self.start_typing is True: self.start_typing = False return Event.TypingEvent(self.agent, 'stopped') elif event.action == 'join': event = self.queued_event.popleft() return event else: event = self.queued_event.popleft() self.prev_action = event.action self.received = False self.num_utterances += 1 self.last_message_timestamp = time.time() event.time = str(self.last_message_timestamp) return event
def leave_chat(): backend = get_backend() uid = userid() chat_info = backend.get_chat_info(uid) backend.send( uid, Event.LeaveEvent(chat_info.agent_index, uid, str(time.time()))) return jsonify(success=True)
def test_dict(cls, raw): uuid = raw['scenario_uuid'] events = Event.gather_eval([Event.from_dict(e) for e in raw['events']]) outcome = raw['outcome'] ex_id = raw['uuid'] if 'agents' in raw: agents = {int(k): v for k, v in raw['agents'].iteritems()} else: agents = None agents_info = raw.get('agents_info', None) return Example(None, uuid, events, outcome, ex_id, agents, agents_info=agents_info)
def join_chat(): """Sent by clients when they enter a room. A status message is broadcast to all people in the room.""" backend = get_backend() uid = userid() chat_info = backend.get_chat_info(uid) backend.send(uid, Event.JoinEvent(chat_info.agent_index, uid, str(time.time()))) return jsonify(message=format_message("You entered the room.", True))
def __init__(self, session): self.session = session self.last_message_timestamp = time.time() self.queued_event = deque() # JoinEvent init_event = Event.JoinEvent(self.agent) self.queued_event.append(init_event) self.prev_action = None self.received = False self.num_utterances = 0 self.start_typing = False
def send_eval(): backend = get_backend() labels = request.json['labels'] eval_data = request.json['eval_data'] uid = request.json['uid'] chat_info = backend.get_chat_info(uid) data = {'utterance': eval_data['utterance'], 'labels': labels} backend.send( uid, Event.EvalEvent(chat_info.agent_index, data, eval_data['timestamp'])) return jsonify(success=True)
def typing_event(): backend = get_backend() action = request.args.get('action') uid = userid() chat_info = backend.get_chat_info(uid) backend.send( uid, Event.TypingEvent(chat_info.agent_index, action, str(time.time()))) return jsonify(success=True)
def text(): backend = get_backend() message = unicode(request.args.get('message')) displayed_message = format_message(u"You: {}".format(message), False) uid = userid() time_taken = float(request.args.get('time_taken')) received_time = time.time() start_time = received_time - time_taken chat_info = backend.get_chat_info(uid) backend.send( uid, Event.MessageEvent(chat_info.agent_index, message, str(received_time), str(start_time))) return jsonify(message=displayed_message, timestamp=str(received_time))
def get_chat_events(cls, cursor, chat_id, include_meta=False): """Read all events in the chat specified by chat_id. Returns: [Event] """ cursor.execute('SELECT * FROM event WHERE chat_id=? ORDER BY time ASC', (chat_id, )) logged_events = cursor.fetchall() chat_events = [] agent_chat = {0: False, 1: False} for row in logged_events: # Compatible with older event structure agent, action, time, data = [ row[k] for k in ('agent', 'action', 'time', 'data') ] try: start_time = row['start_time'] except IndexError: start_time = time try: metadata = json.loads(row['metadata']) except IndexError: metadata = None if not include_meta: if action == 'join' or action == 'leave' or action == 'typing': continue if action == 'message' and len(data.strip()) == 0: continue data = cls.process_event_data(action, data) agent_chat[agent] = True time = cls.convert_time_format(time) start_time = cls.convert_time_format(start_time) event = Event(agent, time, action, data, start_time, metadata=metadata) chat_events.append(event) return chat_events
def build_event(self, result): if isinstance(result, list): if len(result) == 0: action = 'reject' data = {} else: action = 'select' data = {'book': result[0], 'hat': result[1], 'ball': result[2]} else: action = 'message' data = result return Event( agent=1 - self.agent_num, time=self.time, action=action, data=data, )
def render_chat(cls, chat, agent=None, partner_type='human', worker_ids=None): events = Event.gather_eval( [Event.from_dict(e) for e in chat["events"]]) if len(events) == 0: return False, False, None def get_worker_id(agent_id): if worker_ids is None: return 'N/A' id_ = worker_ids.get(str(agent_id), None) return id_ if id_ is not None else '' chat_html = [ '<div class=\"chatLog\">', '<div class=\"divTitle\"> Chat Log: %s <br> Agent 0: %s Agent 1: %s </div>' % (chat['uuid'], get_worker_id(0), get_worker_id(1)), '<table class=\"chat\">' ] # Used for visualizing chat during debugging agent_str = {0: '', 1: ''} if agent is not None: agent_str[agent] = 'Agent %d (you)' % agent agent_str[1 - agent] = 'Agent %d (%s)' % (1 - agent, partner_type) elif 'agents' in chat and chat['agents']: for agent in (0, 1): agent_str[agent] = 'Agent %d (%s)' % ( agent, cls.agent_labels[chat['agents'][str(agent)]]) else: for agent in (0, 1): agent_str[agent] = 'Agent %d (%s)' % (agent, 'unknown') for event in events: if not event.time: t = None else: t = datetime.datetime.fromtimestamp(float( event.time)).strftime('%Y-%m-%d %H:%M:%S') a = agent_str[event.agent] s = cls.render_event(event) if s is None: continue try: tags = ', '.join(event.tags) except AttributeError: tags = '' if event.metadata is None: response_tag = '' template = '' received_row = None else: sent_data = event.metadata['sent'] response_tag = sent_data['logical_form']['intent'] template = sent_data['template'] if isinstance(template, dict): template = template['template'] # Received event received_data = event.metadata['received'] partner_tag = received_data['logical_form']['intent'] partner_template = ' '.join(received_data['template']) received_row = '<tr class=\"agent%d\">\ <td class=\"time\">%s</td>\ <td class=\"agent\">%s</td>\ <td class=\"tags\">%s</td>\ <td class=\"act\">%s</td>\ <td class=\"template\">%s</td>\ <td class=\"message\">%s</td>\ </tr>' % (event.agent, '', '', '', partner_tag, partner_template, '') row = '<tr class=\"agent%d\">\ <td class=\"time\">%s</td>\ <td class=\"agent\">%s</td>\ <td class=\"tags\">%s</td>\ <td class=\"act\">%s</td>\ <td class=\"template\">%s</td>\ <td class=\"message\">%s</td>\ </tr>' % (event.agent, t, a, tags, response_tag, template, s) if received_row: chat_html.append(received_row) chat_html.append(row) chat_html.extend(['</table>', '</div>']) completed = False if chat["outcome"] is None or chat["outcome"][ "reward"] == 0 else True return completed, True, chat_html
def message(self, text, state=None): event = Event(agent=self.agent, time=None, action='message', data=text) event.state = state return event
def message(self, text, metadata=None): return Event.MessageEvent(self.agent, text, time=self.timestamp(), metadata=metadata)