summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Buttke <nate-web@riseup.net>2023-07-27 17:29:36 -0700
committerNate Buttke <nate-web@riseup.net>2023-07-27 17:29:36 -0700
commitdb824e067d17eba3469a49dffb04566aed3449b2 (patch)
tree3cedc59cf4824f1774e2f9b9148857cedea1ab68
parentad9ebbe7c78c2cf7c717d7898534371d59f325d9 (diff)
add frontend components with my fixes. still messy.
-rw-r--r--frontend/index.html132
-rw-r--r--frontend/jsmain.js0
-rw-r--r--frontend/style.css138
-rw-r--r--server.py135
4 files changed, 405 insertions, 0 deletions
diff --git a/frontend/index.html b/frontend/index.html
new file mode 100644
index 0000000..47060ab
--- /dev/null
+++ b/frontend/index.html
@@ -0,0 +1,132 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="preconnect" href="https://fonts.googleapis.com">
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@100;400;900&display=swap" rel="stylesheet">
+
+ <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.0/dist/semantic.min.css">
+ <script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.0/dist/semantic.min.js"></script>
+
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flexboxgrid@6.3.1/dist/flexboxgrid.min.css">
+ <!-- <link rel="icon" type="image/x-icon" href="./assets/logo.ico"> -->
+ <link rel="stylesheet"
+ href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark-reasonable.min.css">
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
+
+ <link href="./style.css" rel="stylesheet">
+ <title>talktoANYcode</title>
+ </head>
+ <body>
+ <div id="main-content" class="row center-xs">
+ <div id="spinny">
+ <div class="ui active inverted dimmer">
+ <div class="ui large text loader" id="loader">Querying...</div>
+ </div>
+ <p></p>
+ <p></p>
+ <p></p>
+ </div>
+ <div class="col-xs-12 col-md-12 center-xs">
+ <a href="/" style="text-decoration: none;">
+ <h1 id="jumbo-title">talkto<span style="color:tomato">ANY</span>code</h1>
+ </a>
+ </div>
+ <div class="row center-xs col-xs-12" id="qa">
+ <div class="ui action input col-xs-8" >
+ <input type="text" placeholder="Talk to Code!" id="talk-text" style="font-size: 20px;">
+ <button class="ui red button" id="talk-button">Search</button>
+ <button class="ui red button" id="talk-button-2">Explain</button>
+ </div>
+ </div>
+ <div id="main-title"></div>
+ <div class="row center-xs col-xs-12" id="main">
+
+ </div>
+ <div class="col-xs-12 center-xs footie">
+ <p>
+ <a class="col-xs-12 ui white label" href="https://git.nategb.xyz/talk-to-any-code.git/" target="_blank">
+ <i class="key icon"></i>
+ git.nategb.xyz/talk-to-any-code.git/
+ </a>
+ <span style="color:white">forked from</span>
+ <a class="col-xs-12 ui white label" href="https://github.com/nuwandavek/talktocode" target="_blank">
+ <i class="github icon"></i>
+ nuwandavek/talktocode
+ </a>
+ </p>
+ </div>
+ </div>
+ <script>
+ res = {{payload|tojson}};
+
+ console.log(res);
+ text = ""
+ if (res['loctype'] == "folder"){
+ text+="<div class='code'>"
+ res['text'].forEach((a)=>{
+ text += "<div><a href='/?path="+a[0]+"'>"+a[0]+"</a><div>"
+ })
+ text+="<div>"
+
+ }
+ else if(res['loctype'] == "file"){
+ leftClass = "language-go"
+ res['text'].forEach((a, i)=>{
+ text += '<div class="col-xs-5 code" id="code-'+i+'"><pre><code class="language-go">'+a[0]+'</code></pre></div>'
+ text += '<div class="col-xs-5 summary" id="summary-"'+i+'><p>'+a[1]+'</p></div>'
+ })
+ }
+ else{
+ text = "";
+ }
+ $("#main").html(text);
+ $("#main-title").html(res['parents'] + "/" + res['current']);
+ hljs.highlightAll();
+
+ $("#talk-button").click(()=>{
+ query = $("#talk-text").val()
+ console.log(query);
+ $("#spinny").show();
+
+ fetch('/answer?q='+query, {method: "GET"})
+ .then((response) => response.json())
+ .then((data) => {
+ console.log(data);
+ $("#spinny").hide();
+ text = ""
+ data.forEach((a, i)=>{
+ text += '<div class="col-xs-5 code" id="code-'+i+'"><pre><code class="language-go">'+a['blob']+'</code></pre></div>'
+ text += '<div class="col-xs-5 summary" id="summary-"'+i+'><p>'+a['summary']+'</p></div>'
+ })
+ $("#main").html(text);
+ $("#main-title").html("");
+ hljs.highlightAll();
+
+ });
+ })
+
+ $("#talk-button-2").click(()=>{
+ query = $("#talk-text").val()
+ console.log(query);
+ $("#spinny").show();
+
+ fetch('/explain?q='+query, {method: "GET"})
+ .then((response) => response.json())
+ .then((data) => {
+ console.log(data);
+ $("#spinny").hide();
+ $("#main").html('<div class="col-xs-5 code"><pre><code class="language-plaintext">'+data+'</code></pre></div>');
+ $("#main-title").html("");
+ hljs.highlightAll();
+
+ });
+ })
+
+ </script>
+ <script src="./jsmain.js"></script>
+ </body>
+</html>
diff --git a/frontend/jsmain.js b/frontend/jsmain.js
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/frontend/jsmain.js
diff --git a/frontend/style.css b/frontend/style.css
new file mode 100644
index 0000000..8417106
--- /dev/null
+++ b/frontend/style.css
@@ -0,0 +1,138 @@
+html {
+ font-size: 16px;
+}
+
+#main-content {
+ text-align: center;
+ min-height: 100vh;
+}
+
+
+#jumbo-title {
+ font-weight: 900;
+ font-size: 10rem;
+ font-family: 'Inter' !important;
+ color: #2d3436;
+}
+
+#top-bar {
+ padding: 1rem 2rem 1rem 2rem;
+ border-bottom: #eee 1px solid;
+ margin-bottom: 2rem;
+}
+
+.top-xs {
+ align-content: start !important;
+}
+
+
+.normal-font {
+ font-size: 1rem !important;
+ color: #fff !important;
+ font-family: 'Inter' !important;
+}
+
+.normal-font-light {
+ font-size: 1rem !important;
+ color: #2d3436 !important;
+ font-family: 'Inter' !important;
+}
+
+.fat-font {
+ font-weight: 900;
+}
+
+code {
+ background-color: #2a3b4d;
+ border-radius: 2px;
+ padding: 1px;
+}
+
+.ui.button {
+ /* padding: 0.5rem !important; */
+ font-size: 1rem !important;
+ margin-left: 0.5rem !important;
+}
+
+.footie{
+ border-radius: 5px;
+ background: #2d3436;
+ padding: 2rem;
+}
+
+#transcription-result{
+ border-radius: 5px;
+ border: 1px solid #ddd;
+ min-height: 10rem;
+ margin: 1rem 0.5rem 1rem 0.5rem;
+ padding: 1rem;
+ text-align: left;
+}
+
+#spinny {
+ position: absolute;
+ z-index: 10;
+ width: 100%;
+ height: 100%;
+ display: none;
+}
+
+#transcription-title {
+ text-align: center;
+ text-transform: uppercase;
+ letter-spacing: 1rem;
+ font-weight: 900;
+}
+
+.divider{
+ color: #fff !important;
+}
+
+#all-inputs{
+ padding: 1rem;
+ border: 1px solid #2d3436;;
+ border-radius: 5px;
+ background: #2d3436;;
+}
+
+audio{
+ border: 1px solid #424e51;
+ border-radius: 5px;
+}
+
+#blinker {
+ color: #db2828;
+ margin: 1rem;
+ display: none;
+}
+
+.blink {
+ animation: blinker 1s infinite alternate;
+}
+
+.code, .summary{
+ text-align: left;
+ min-height: 500px;
+ width: 100%;
+ display: inline-block;
+ background: #282c34;
+ padding: 20px;
+ color: #fff;
+ margin: 5px;
+ border-radius: 5px;
+ font-size: 16px;;
+}
+
+#main-title{
+ background-color: #eee;
+ color: red;
+ font-size: 25px !important;
+ padding: 10px;
+ margin: 10px;
+ border-radius: 5px;;
+}
+
+@keyframes blinker {
+from { opacity: 1; }
+to { opacity: 0; }
+} \ No newline at end of file
diff --git a/server.py b/server.py
new file mode 100644
index 0000000..05e726f
--- /dev/null
+++ b/server.py
@@ -0,0 +1,135 @@
+from flask import Flask, request, Response, jsonify, render_template
+import pandas as pd
+from collections import defaultdict
+import os
+import openai
+from openai.embeddings_utils import get_embedding, cosine_similarity
+openai.api_key = os.getenv('OPENAI_KEY')
+import numpy as np
+
+app = Flask(__name__, template_folder="./frontend", static_folder="./frontend", static_url_path="")
+
+
+
+def search_code(df, query, n=4):
+ query_embedding = get_embedding(
+ query,
+ engine="text-embedding-ada-002"
+ )
+ #df["similarity"] = df.summary_embeddings.apply(lambda x: cosine_similarity(x, query_embedding))
+ df["similarity"] = df.embedding_summary.apply(lambda x: cosine_similarity(x, query_embedding))
+ # df["similarity"] = df.embeddings.apply(lambda x: cosine_similarity(x, query_embedding))
+ results = (
+ df.sort_values("similarity", ascending=False)
+ )
+ return results.head(n)
+
+
+def generate_answer(question):
+ results = search_code(df, question, n=4)
+ prompt = ''
+ for i in range(3):
+ prompt += results.iloc[i]["summary"] + "\n" + results.iloc[i]["blob"] + "\n"
+ prompt += "\n" + "Answer the following question using the code context given above, and show an example with 'Example'\nQ: " + question + "\nA: "
+ response = openai.Completion.create(
+ model="text-davinci-003",
+ # model="code-davinci-002",
+ prompt=prompt,
+ temperature=0.7,
+ max_tokens=1000,
+ top_p=1.0,
+ frequency_penalty=0.0,
+ presence_penalty=0.0,
+ stop=["\"\"\""]
+ )
+ return response["choices"][0]["text"]
+
+# The above two functions should already work with the Go version.
+
+def get_code_structure(df):
+ kids_structure = defaultdict(list)
+ parents_structure = {}
+ for path in list(df['file_path'].unique()):
+ t = path.split("/")
+ for e in range(len(t)):
+ # if we know it's a dir name, record the next path component as a
+ # child of the current dir.
+ if e < len(t) - 1:
+ kids_structure[t[e]].append(t[e+1])
+ else:
+ kids_structure[t[e]] = ["file"]
+ if e == 0:
+ parents_structure[t[e]] = "./"
+ else:
+ parents_structure[t[e]] = "/".join(t[:e])
+
+ for k, v in kids_structure.items():
+ kids_structure[k] = list(set(v))
+ return dict(kids_structure), parents_structure
+
+
+# Nate: these are from the original project. My own csv is below
+#df = pd.read_csv("./frontend/data/embedded_summarized.csv")
+#df = pd.read_csv("./frontend/data/withsummary2.csv")
+
+# My line
+df=pd.read_csv("./frontend/data/test_with_summary_and_embeddings.csv", converters={'embedding_summary': pd.eval})
+
+# need to do funny stuff to read in the data frame correctly from csv. that's
+# why the eval() is below. and pd.eval is above.
+
+#df['summary_embeddings'] = df['summary_embeddings'].apply(lambda x: eval(x))
+#df['embeddings'] = df['embeddings'].apply(lambda x: eval(x))
+
+filetypes = ['go']
+
+
+# messed this area up for debugging
+@app.route('/')
+def home():
+ stub = request.args.get('path', 'dirserver').strip()
+ kids_structure, parents_structure = get_code_structure(df)
+ print('kids_structure', kids_structure)
+ print('parents_structure', parents_structure)
+ print('stub', stub)
+ if stub not in kids_structure:
+ loctype = "nan"
+ text = [["Path not available!"], [""]]
+ elif any([stub.endswith(x) for x in filetypes]):
+ loctype = "file"
+ fullpath = f"{parents_structure[stub]}/{stub}"
+ print(fullpath)
+ text = [[x, y] for x, y in zip(
+ list(df[df['file_path'] == fullpath]['source']),
+ list(df[df['file_path'] == fullpath]['summary'])
+ )]
+ else:
+ loctype = "folder"
+ text = [[x, ""] for x in kids_structure[stub]]
+ res = {
+ 'parents': parents_structure[stub],
+ 'loctype': loctype,
+ 'text': text,
+ 'current': stub
+ }
+ return render_template('index.html', payload=res)
+
+
+@app.route('/answer')
+def answer():
+ q = request.args.get('q', '').strip()
+ a = search_code(df, q)
+ res = [{'blob': x['blob'], 'summary': x['summary']} for x in a.to_dict('records')]
+
+ return jsonify(res)
+
+@app.route('/explain')
+def explain():
+ q = request.args.get('q', '').strip()
+ a = generate_answer(q)
+ return jsonify(a)
+
+
+if __name__ == '__main__':
+ app.run(port=5001, debug=True)
+ #app.run(host="0.0.0.0", port=5001, debug=True)