|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"/> |
|
<meta name="viewport" contents="width=device-width, initial-scale=1.0" /> |
|
<title>StarCoder Editor</title> |
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> |
|
<script src="https://cdn.jsdelivr.net/npm/js-base64@3.7.2/base64.min.js"></script> |
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/ace.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-plain_text.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-c_cpp.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-csharp.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-clojure.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-coffee.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-golang.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-haskell.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-python.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-java.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-javascript.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-lua.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-objectivec.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-perl.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-php.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-python.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-ruby.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-rust.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-scala.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-sh.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-swift.min.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/mode-typescript.min.js"></script> |
|
<link rel="stylesheet" href="static/style.css"> |
|
</head> |
|
<style type="text/css"> |
|
|
|
|
|
|
|
|
|
|
|
main { |
|
max-width: 80rem; |
|
} |
|
.rightside { |
|
width: 30em; |
|
} |
|
.submit-holder { |
|
margin-top: 2em; |
|
} |
|
.submit input { |
|
font-size: 16pt; |
|
} |
|
.slider { |
|
width: 20em; |
|
} |
|
#faq { |
|
max-width: 60em; |
|
} |
|
#result { |
|
font-family: monospace; |
|
white-space: pre-wrap; |
|
word-wrap: break-word; |
|
font-size: 12pt; |
|
clear: both; |
|
margin-top: 1em; |
|
border: 1px solid black; |
|
padding: 1em; |
|
width: 60em; |
|
min-height: 12em; |
|
} |
|
#prompt { |
|
font-weight: bold; |
|
} |
|
.loader { |
|
border: 4px solid #f3f3f3; |
|
border-radius: 50%; |
|
border-top: 4px solid #3498db; |
|
width: 30px; |
|
height: 30px; |
|
animation: spin 2s linear infinite; |
|
margin-right: 1em; |
|
} |
|
@keyframes spin { |
|
0% { transform: rotate(0deg); } |
|
100% { transform: rotate(360deg); } |
|
} |
|
#loader_holder { |
|
visibility: hidden; |
|
display: flex; |
|
align-items: center; |
|
} |
|
|
|
label { |
|
margin-top: 1em; |
|
display: inline-elock; |
|
width: 10em; |
|
text-align: right; |
|
font-size: 80%; |
|
} |
|
#loader_holder_super { |
|
} |
|
#error { |
|
color: red; |
|
width: 100%; |
|
} |
|
#warning { |
|
color: darkorange; |
|
width: 100%; |
|
} |
|
#examples span { |
|
margin-right: 1em; |
|
} |
|
#editor { |
|
position: relative; |
|
width: 100%; |
|
height: 400px; |
|
} |
|
#editor-holder { |
|
position: relative; |
|
width: 100%; |
|
height: 400px; |
|
} |
|
.ace_infill { |
|
color: red; |
|
} |
|
</style> |
|
<body> |
|
<main> |
|
<div class="card" id="about"> |
|
<div class="header"> <h1>StarCoder Editor</h1> </div> |
|
<p>This is a demo to interactively generate code with <a href=https://huggingface.co/bigcode/starcoderbase target="_blank" rel="noopener noreferrer">StarCoderBase</a>, a 15B parameter model for code generation in 86 programming languages.</p> |
|
<p>Select one of the examples below, or input your own code into the editor. You can type <infill> to mark a location you want the model to insert code at.</p> |
|
<p>Click "Extend" to append text at the end of the editor. Click "Infill" to replace all <infill> masks. (Click "Add <infill> mask" to add a mask at the cursor or replace the current selection.) </p> |
|
</div> |
|
<div class="card" id="examples"> |
|
<div id="examples-extend"> |
|
<span class="softspan">Extend Examples:</span> |
|
<br> |
|
<span class="softspan"><a href='javascript:select_example("logistic-regression");'>Logistic Regression (Python)</a></span> |
|
<span class="softspan"><a href='javascript:select_example("array");'>Arrays (JS)</a></span> |
|
<span class="softspan"><a href='javascript:select_example("metadata");'>Metadata-Conditioning (JS)</a></span> |
|
</div> |
|
<div id="examples-infill"> |
|
<span class="softspan">Infill Examples:</span> |
|
<br> |
|
<span class="softspan"><a href='javascript:select_example("type-pred");'>Type Prediction</a></span> |
|
<span class="softspan"><a href='javascript:select_example("docstring");'>Docstring Generation</a></span> |
|
</div> |
|
</div> |
|
<div class="card" id="controls"> |
|
<div> |
|
<label>Num Tokens:</label> |
|
<input type="range" value="64" min="16" max="256" step="16" class="slider" |
|
oninput="this.nextElementSibling.value = this.value" name="length" id='length_slider'> |
|
<output class='a' id="length_slider_output">64</output> |
|
</div> |
|
<div> |
|
<label>Temperature:</label> |
|
<input type="range" value="0.6" min="0.1" max="1.0" step="0.10" class="slider" |
|
oninput="this.nextElementSibling.value = this.value" name="temp" id='temp_slider'> |
|
<output class='a' id="temp_slider_output">0.6</output> |
|
</div> |
|
<div id="buttons"> |
|
<br> |
|
<input type="button" value="Extend" id="extend-form-button" /> |
|
<input type="button" value="Infill" id="infill-form-button" /> |
|
<br> |
|
<br> |
|
<input type="button" value="Add <infill> mask" id="insert-mask-button" title="add the infill marker at cursor or selection" /> |
|
</div> |
|
</div> |
|
<div id="edit-container" class="card"> |
|
<div id="syntax"> |
|
<span class="softspan">Syntax:</span> |
|
<select name="mode" id="mode"> |
|
<option value="text">Text</option> |
|
<option value="c_cpp">C/C++</option> |
|
<option value="csharp">C#</option> |
|
<option value="clojure">Clojure</option> |
|
<option value="coffee">CoffeeScript</option> |
|
<option value="golang">Go</option> |
|
<option value="haskell">Haskell</option> |
|
<option value="java">Java</option> |
|
<option value="javascript">JavaScript</option> |
|
<option value="lua">Lua</option> |
|
<option value="objectivec">Objective C</option> |
|
<option value="perl">Perl</option> |
|
<option value="php">PHP</option> |
|
<option value="python">Python</option> |
|
<option value="ruby">Ruby</option> |
|
<option value="rust">Rust</option> |
|
<option value="scala">Scala</option> |
|
<option value="sh">Shell</option> |
|
<option value="swift">Swift</option> |
|
<option value="typescript">Typescript</option> |
|
</select> |
|
</div> |
|
<div id="editor"></div> |
|
</div> |
|
<div id="loader_holder_super" class="card"> |
|
<h1>Messages</h1> |
|
<div id="error"></div> |
|
<div id="warning"></div> |
|
<div id="loader_holder"> |
|
<div class="loader"></div> |
|
<div> |
|
Generation queued, please wait... |
|
</div> |
|
</div> |
|
</div> |
|
<div id="info" class="card"> |
|
<h1 id="debug-info">More Info</h1> |
|
<p>See our <a href="https://huggingface.co/bigcode" target="_blank" rel="noopener noreferrer">organization card</a> for links to the technical report, models, VSCode extension, training dataset, and more.</p> |
|
<p>Credits: BigCode team. This demo is based upon the <a href="https://huggingface.co/spaces/facebook/incoder-demo" target="_blank" rel="noopener noreferrer">InCoder demo<a> by Facebook AI Research.</p> |
|
</div> |
|
</main> |
|
<script type="text/javascript"> |
|
|
|
var OVERHEAD = 3; |
|
var PER_TOKEN = 0.12; |
|
var SPLIT_TOKEN = "<infill>" |
|
|
|
var Range = require("ace/range").Range; |
|
|
|
|
|
var EXAMPLES = { |
|
"type-pred": { |
|
"prompt": `def count_words(filename: str) -> <infill> |
|
"""Count the number of occurrences of each word in the file.""" |
|
with open(filename, 'r') as f: |
|
word_counts = {} |
|
for line in f: |
|
for word in line.split(): |
|
if word in word_counts: |
|
word_counts[word] = 1 |
|
else: |
|
word_counts[word] = 1 |
|
return word_counts |
|
`, |
|
"length": 4, |
|
"temperature": 0.2, |
|
"mode": "python" |
|
}, |
|
"docstring": { |
|
"prompt": `def _minimize_in_graph(build_loss_fn, num_steps=200, optimizer=None): |
|
""" |
|
<infill> |
|
""" |
|
optimizer = tf.compat.v1.train.AdamOptimizer( |
|
0.1) if optimizer is None else optimizer |
|
|
|
def train_loop_body(step): |
|
train_op = optimizer.minimize( |
|
build_loss_fn if tf.executing_eagerly() else build_loss_fn()) |
|
return tf.tuple(tensors=[tf.add(step, 1)], control_inputs=[train_op]) |
|
|
|
minimize_op = tf.compat.v1.while_loop( |
|
cond=lambda step: step < num_steps, |
|
body=train_loop_body, |
|
loop_vars=[tf.constant(0)], |
|
return_same_structure=True)[0] |
|
return minimize_op`, |
|
"length": 128, |
|
"temperature": 0.2, |
|
"mode": "python", |
|
}, |
|
|
|
"logistic-regression": { |
|
"prompt": `X_train, y_train, X_test, y_test = train_test_split(X, y, test_size=0.1) |
|
|
|
# Train a logistic regression model, predict the labels on the test set and compute the accuracy score`, |
|
"length": 64, |
|
"temperature": 0.6, |
|
"mode": "python" |
|
}, |
|
"array": { |
|
"prompt": |
|
`// Returns every other value in the array as a new array. |
|
function everyOther(arr) {`, |
|
"temperature": 0.6, |
|
"length": 64, |
|
"mode": "javascript" |
|
}, |
|
"metadata": { |
|
"prompt": `<filename>start_server.js<gh_stars>100-1000 |
|
`, |
|
"temperature": 0.6, |
|
"length": 128, |
|
"mode": "javascript" |
|
}, |
|
}; |
|
|
|
var editor = ace.edit("editor"); |
|
editor.setOption("wrap", true); |
|
|
|
|
|
function set_editor_mode(mode) { |
|
session = editor.session |
|
session.setMode("ace/mode/" + mode, function() { |
|
var rules = session.$mode.$highlightRules.getRules(); |
|
for (var stateName in rules) { |
|
if (Object.prototype.hasOwnProperty.call(rules, stateName)) { |
|
rules[stateName].unshift({ |
|
token: 'infill', |
|
regex: SPLIT_TOKEN |
|
}); |
|
} |
|
} |
|
|
|
session.$mode.$tokenizer = null; |
|
session.bgTokenizer.setTokenizer(session.$mode.getTokenizer()); |
|
|
|
session.bgTokenizer.start(0); |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function set_text(text) { |
|
editor.getSession().setValue(text); |
|
|
|
} |
|
|
|
function set_selection(data) { |
|
var lines = editor.getSession().doc.$lines; |
|
var lines_flat = join_lines(lines); |
|
if (data['type'] == 'generate') { |
|
doc_length = lines_flat.length; |
|
var start = convert_string_index_to_location(data['prompt'].length, lines); |
|
var end = convert_string_index_to_location(doc_length, lines); |
|
|
|
editor.selection.setRange(new Range(end.row, end.column, start.row, start.column)); |
|
} else if (data['type'] == 'infill') { |
|
var length_so_far = 0; |
|
for (var i = 0; i < data['infills'].length; i++) { |
|
var prefix = data['parts'][i]; |
|
var suffix = data['parts'][i+1]; |
|
var infilled = data['infills'][i]; |
|
var start = convert_string_index_to_location(length_so_far + prefix.length, lines); |
|
var end = convert_string_index_to_location(length_so_far + (prefix + infilled).length, lines); |
|
var range = null; |
|
if (data['infills'].length == 1) { |
|
range = new Range(end.row, end.column, start.row, start.column) |
|
} else { |
|
range = new Range(start.row, start.column, end.row, end.column) |
|
} |
|
if (i == 0) { |
|
editor.selection.setRange(range); |
|
} else { |
|
editor.selection.addRange(range); |
|
} |
|
length_so_far += (prefix + infilled).length; |
|
} |
|
} |
|
editor.focus(); |
|
} |
|
|
|
function select_example(name) { |
|
$("#length_slider").val(EXAMPLES[name]["length"]); |
|
$("#length_slider_output").text(EXAMPLES[name]["length"]); |
|
$("#temp_slider").val(EXAMPLES[name]["temperature"]); |
|
$("#temp_slider_output").text(EXAMPLES[name]["temperature"]); |
|
set_text(EXAMPLES[name]["prompt"]) |
|
var mode = EXAMPLES[name]["mode"]; |
|
|
|
set_editor_mode(mode); |
|
$("#mode").val(mode).change(); |
|
} |
|
|
|
function newline_character() { |
|
return editor.getSession().doc.getNewLineCharacter(); |
|
} |
|
|
|
function join_lines(lines) { |
|
return lines.join(newline_character()); |
|
} |
|
|
|
function get_prefix(location, lines) { |
|
if (!(location.hasOwnProperty('row') && location.hasOwnProperty('column'))) { |
|
console.error("invalid location " + location); |
|
} |
|
if (location.row == 0) { |
|
return lines[location.row].substring(0, location.column); |
|
} else { |
|
return join_lines(lines.slice(0, location.row)) + newline_character() + lines[location.row].substring(0, location.column); |
|
} |
|
} |
|
|
|
function convert_location_to_string_index(location, lines) { |
|
return get_prefix(location, lines).length; |
|
} |
|
|
|
function convert_string_index_to_location(string_index, lines) { |
|
var column = 0; |
|
var row = 0; |
|
var char_count = 0; |
|
var line_sep_length = editor.getSession().doc.getNewLineCharacter().length; |
|
for (var i = 0; i < lines.length; i++) { |
|
var line = lines[i]; |
|
var new_char_count = char_count + line.length + line_sep_length; |
|
if (string_index < new_char_count) { |
|
return { |
|
'row': i, |
|
'column': string_index - char_count, |
|
} |
|
} |
|
char_count = new_char_count; |
|
} |
|
console.error("did not find index " + string_index + " in lines " + lines); |
|
return null; |
|
} |
|
|
|
function get_infill_parts(warn_on_single) { |
|
var lines = editor.getSession().doc.$lines; |
|
var lines_flat = join_lines(lines); |
|
parts = lines_flat.split(SPLIT_TOKEN) |
|
if (warn_on_single && parts.length == 1) { |
|
window.alert('There are no infill masks, add some <infill> masks before requesting an infill') |
|
} |
|
return parts |
|
} |
|
|
|
function insert_mask() { |
|
if (editor.selection.ranges.length > 1) { |
|
for (var i = 0; i < editor.selection.ranges.length; i++) { |
|
console.log('range is', editor.selection.ranges[i]) |
|
editor.session.replace(editor.selection.ranges[i], SPLIT_TOKEN) |
|
} |
|
} else { |
|
editor.session.replace(editor.selection.getRange(), SPLIT_TOKEN) |
|
} |
|
} |
|
|
|
|
|
function make_generate_listener(url) { |
|
return async function(event) { |
|
var length = $("#length_slider").val(); |
|
var eta = PER_TOKEN * length + OVERHEAD; |
|
|
|
|
|
|
|
|
|
var send_data = { |
|
length: $("#length_slider").val(), |
|
temperature: $("#temp_slider").val(), |
|
extra_sentinel: $('#extra_sentinel_checkbox').is(":checked"), |
|
max_retries: $('#max_retries_slider').val(), |
|
parts: get_infill_parts(url == "infill"), |
|
prompt: editor.getSession().getValue(), |
|
} |
|
console.log("send_data:"); |
|
console.log(send_data); |
|
|
|
$("#loader_holder").css("visibility", "visible"); |
|
$("#extend-form-button").prop("disabled", true); |
|
$("#infill-form-button").prop("disabled", true); |
|
$("#error").text(""); |
|
|
|
function complete() { |
|
$("#loader_holder").css("visibility", "hidden"); |
|
$("#extend-form-button").prop("disabled", false); |
|
$("#infill-form-button").prop("disabled", false); |
|
} |
|
|
|
function success(receive_data) { |
|
console.log("Response:"); |
|
console.log(receive_data); |
|
if (receive_data["result"] == "success") { |
|
console.log("success"); |
|
|
|
|
|
set_text(receive_data["text"]); |
|
set_selection(receive_data); |
|
$("#error").text(""); |
|
if (receive_data["message"] != "") { |
|
$("#warning").text(receive_data["message"]); |
|
} else { |
|
$("#warning").text(""); |
|
} |
|
} else { |
|
console.log("error"); |
|
console.log("data:"); |
|
console.log(receive_data); |
|
set_text(receive_data["text"]) |
|
$("#error").text(receive_data["message"]); |
|
} |
|
} |
|
|
|
function error(err) { |
|
console.log(err); |
|
$("#error").text(err); |
|
} |
|
|
|
try { |
|
var stringified = JSON.stringify(send_data); |
|
|
|
var encoded_data = Base64.encodeURI(stringified); |
|
|
|
const response = await fetch(`${url}?info=${encoded_data}`); |
|
|
|
|
|
|
|
|
|
if (response.status >= 400) { |
|
error(response.statusText); |
|
console.log("here"); |
|
console.log(response.status); |
|
} else { |
|
response.json().then(success).catch(error).finally(complete); |
|
} |
|
} catch (e) { |
|
error(e); |
|
} finally { |
|
complete(); |
|
} |
|
} |
|
} |
|
|
|
|
|
$(document).ready(function() { |
|
$("#insert-mask-button").click(insert_mask); |
|
$("#extend-form-button").click(make_generate_listener("generate")); |
|
$("#infill-form-button").click(make_generate_listener("infill")); |
|
$("#mode").change(function (e) { |
|
var mode = $("#mode").val(); |
|
set_editor_mode(mode); |
|
}); |
|
select_example("python") |
|
|
|
}); |
|
</script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.2/iframeResizer.contentWindow.min.js"></script> |
|
</body> |
|
</html> |
|
|