File size: 8,284 Bytes
ec74f30
 
df25732
3a5dbe6
df25732
3667c7a
 
 
 
 
 
ab840dc
3667c7a
 
 
 
1b279d5
70bf9cc
fdae8f6
2d989a9
 
70bf9cc
15f2bc2
00be385
72abfd9
6ba2996
2d989a9
 
6ba2996
2d989a9
e98b248
 
 
4518e15
ac13632
 
6ba2996
d6cd6c2
 
2d989a9
 
 
 
 
 
 
ab840dc
2d989a9
 
 
eef0040
 
 
 
 
 
 
 
 
 
ab840dc
2d989a9
 
 
8138173
6ba2996
1b279d5
df25732
 
 
a10bc68
 
1b279d5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c57cd9a
a10bc68
891f3b9
a10bc68
c57cd9a
df25732
 
1b279d5
70bf9cc
fb73ff7
3a5dbe6
a10bc68
df25732
87ae702
1b279d5
3a5dbe6
 
 
 
 
 
 
 
 
1b279d5
87ae702
3a5dbe6
 
 
df25732
 
 
70bf9cc
e227c00
e71ef7a
 
1b279d5
e227c00
1f19f64
e227c00
eef0040
e227c00
3667c7a
72abfd9
8d3b67a
a10bc68
e227c00
8d3b67a
e227c00
eef0040
 
f6e34f2
c57cd9a
1b279d5
 
 
 
eef0040
 
 
e227c00
e71ef7a
 
c8e8be4
ab840dc
3667c7a
82598a2
78654a1
3a5dbe6
eef0040
e227c00
3a5dbe6
 
 
87ae702
 
3a5dbe6
 
 
 
 
 
 
eef0040
3a5dbe6
 
eef0040
3a5dbe6
 
1b279d5
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
176
177
178
179
180
import os

import gradio as gr
import numpy as np

from api.audio import STTManager, TTSManager
from api.llm import LLMManager
from config import config
from docs.instruction import instruction
from resources.data import fixed_messages, topics_list
from resources.prompts import prompts
from utils.ui import add_candidate_message, add_interviewer_message, get_status_color

llm = LLMManager(config, prompts)
tts = TTSManager(config)
stt = STTManager(config)

# Interface
with gr.Blocks(title="AI Interviewer") as demo:
    if os.getenv("IS_DEMO"):
        gr.Markdown(instruction["demo"])

    started_coding = gr.State(False)
    audio_output = gr.Audio(label="Play audio", autoplay=True, visible=os.environ.get("DEBUG", False), streaming=tts.streaming)
    with gr.Tab("Instruction") as instruction_tab:
        with gr.Row():
            with gr.Column(scale=2):
                gr.Markdown(instruction["introduction"])
            with gr.Column(scale=1):
                space = " " * 10

                tts_status = get_status_color(tts)
                gr.Markdown(f"TTS status: {tts_status}{space}{config.tts.name}")

                stt_status = get_status_color(stt)
                gr.Markdown(f"STT status: {stt_status}{space}{config.stt.name}")

                llm_status = get_status_color(llm)
                gr.Markdown(f"LLM status: {llm_status}{space}{config.llm.name}")

        gr.Markdown(instruction["quick_start"])
        with gr.Row():
            with gr.Column(scale=2):
                gr.Markdown(instruction["interface"])
            with gr.Column(scale=1):
                gr.Markdown("Bot interaction area will look like this. Use Record button to record your answer.")
                gr.Markdown("Click 'Send' to send you answer and get a reply.")
                chat_example = gr.Chatbot(
                    label="Chat", show_label=False, show_share_button=False, value=[["Candidate message", "Interviewer message"]]
                )
                default_audio_params = {
                    "label": "Record answer",
                    "sources": ["microphone"],
                    "type": "numpy",
                    "waveform_options": {"show_controls": False},
                    "editable": False,
                    "container": False,
                    "show_share_button": False,
                    "streaming": stt.streaming,
                }
                send_btn_example = gr.Button("Send", interactive=False)
                audio_input_example = gr.Audio(interactive=True, **default_audio_params)
        gr.Markdown(instruction["models"])
        gr.Markdown(instruction["acknowledgements"])
        gr.Markdown(instruction["legal"])

    with gr.Tab("Coding") as coding_tab:
        chat_history = gr.State([])
        previous_code = gr.State("")
        with gr.Accordion("Settings") as init_acc:
            with gr.Row():
                with gr.Column():
                    gr.Markdown("##### Problem settings")
                    with gr.Row():
                        gr.Markdown("Difficulty")
                        difficulty_select = gr.Dropdown(
                            label="Select difficulty",
                            choices=["Easy", "Medium", "Hard"],
                            value="Medium",
                            container=False,
                            allow_custom_value=True,
                        )
                    with gr.Row():
                        gr.Markdown("Topic (can type custom value)")
                        topic_select = gr.Dropdown(
                            label="Select topic", choices=topics_list, value="Arrays", container=False, allow_custom_value=True
                        )
                with gr.Column(scale=2):
                    requirements = gr.Textbox(label="Requirements", placeholder="Specify additional requirements", lines=5)
                    start_btn = gr.Button("Generate a problem")

        with gr.Accordion("Problem statement", open=True) as problem_acc:
            description = gr.Markdown()
        with gr.Accordion("Solution", open=False) as solution_acc:
            with gr.Row() as content:
                with gr.Column(scale=2):
                    code = gr.Code(
                        label="Please write your code here. You can use any language, but only Python syntax highlighting is available.",
                        language="python",
                        lines=46,
                    )
                with gr.Column(scale=1):
                    end_btn = gr.Button("Finish the interview", interactive=False)
                    chat = gr.Chatbot(label="Chat", show_label=False, show_share_button=False)
                    message = gr.Textbox(
                        label="Message",
                        placeholder="Your message will appear here",
                        show_label=False,
                        lines=3,
                        max_lines=3,
                        interactive=False,
                    )
                    send_btn = gr.Button("Send", interactive=False)
                    audio_input = gr.Audio(interactive=False, **default_audio_params)

                    audio_buffer = gr.State(np.array([], dtype=np.int16))
                    transcript = gr.State({"words": [], "not_confirmed": 0, "last_cutoff": 0, "text": ""})

        with gr.Accordion("Feedback", open=True) as feedback_acc:
            feedback = gr.Markdown()

    # Events
    coding_tab.select(fn=add_interviewer_message(fixed_messages["intro"]), inputs=[chat, started_coding], outputs=[chat]).success(
        fn=tts.read_last_message, inputs=[chat], outputs=[audio_output]
    )

    start_btn.click(fn=add_interviewer_message(fixed_messages["start"]), inputs=[chat], outputs=[chat]).success(
        fn=lambda: True, outputs=[started_coding]
    ).success(fn=tts.read_last_message, inputs=[chat], outputs=[audio_output]).success(
        fn=lambda: (gr.update(open=False), gr.update(interactive=False)), outputs=[init_acc, start_btn]
    ).success(
        fn=llm.get_problem,
        inputs=[requirements, difficulty_select, topic_select],
        outputs=[description],
        scroll_to_output=True,
    ).success(
        fn=llm.init_bot, inputs=[description], outputs=[chat_history]
    ).success(
        fn=lambda: (gr.update(open=True), gr.update(interactive=True), gr.update(interactive=True)),
        outputs=[solution_acc, end_btn, audio_input],
    )

    end_btn.click(
        fn=add_interviewer_message(fixed_messages["end"]),
        inputs=[chat],
        outputs=[chat],
    ).success(fn=tts.read_last_message, inputs=[chat], outputs=[audio_output]).success(
        fn=lambda: (gr.update(open=False), gr.update(interactive=False), gr.update(open=False), gr.update(interactive=False)),
        outputs=[solution_acc, end_btn, problem_acc, audio_input],
    ).success(
        fn=llm.end_interview, inputs=[description, chat_history], outputs=[feedback]
    )

    send_btn.click(fn=add_candidate_message, inputs=[message, chat], outputs=[chat]).success(fn=lambda: None, outputs=[message]).success(
        fn=llm.send_request,
        inputs=[code, previous_code, chat_history, chat],
        outputs=[chat_history, chat, previous_code],
    ).success(fn=tts.read_last_message, inputs=[chat], outputs=[audio_output]).success(
        fn=lambda: gr.update(interactive=False), outputs=[send_btn]
    ).success(
        fn=lambda: np.array([], dtype=np.int16), outputs=[audio_buffer]
    ).success(
        fn=lambda: {"words": [], "not_confirmed": 0, "last_cutoff": 0, "text": ""}, outputs=[transcript]
    )

    if stt.streaming:
        audio_input.stream(
            stt.process_audio_chunk,
            inputs=[audio_input, audio_buffer, transcript],
            outputs=[transcript, audio_buffer, message],
            show_progress="hidden",
        )
        audio_input.stop_recording(fn=lambda: gr.update(interactive=True), outputs=[send_btn])
    else:
        audio_input.stop_recording(fn=stt.speech_to_text_full, inputs=[audio_input], outputs=[message]).success(
            fn=lambda: gr.update(interactive=True), outputs=[send_btn]
        ).success(fn=lambda: None, outputs=[audio_input])

demo.launch(show_api=False)