diff --git a/src/babylonian-programming-editor/babylonian-programming-editor.js b/src/babylonian-programming-editor/babylonian-programming-editor.js
index 66049b323..9f9b0e1db 100644
--- a/src/babylonian-programming-editor/babylonian-programming-editor.js
+++ b/src/babylonian-programming-editor/babylonian-programming-editor.js
@@ -120,7 +120,9 @@ export default class BabylonianProgrammingEditor extends Morph {
var editorComp = this.editorComp()
console.log("Babylonian: load editor" + editorComp)
- editorComp.addEventListener("editor-loaded", () => {
+
+ // editorComp.addEventListener("editor-loaded", () => {
+ editorComp.editorLoaded().then(() => {
console.log("Babylonian: editor loaded ", this.livelyEditor())
// Patch editor to load/save comments
@@ -143,6 +145,7 @@ export default class BabylonianProgrammingEditor extends Morph {
"Tab": (cm) => { cm.replaceSelection(" ") },
})
+ debugger
// Inject styling into CodeMirror
const livelyEditorStyle =
diff --git a/src/components/tools/astro-plot.js b/src/components/tools/astro-plot.js
index 070754a34..69de3bef4 100644
--- a/src/components/tools/astro-plot.js
+++ b/src/components/tools/astro-plot.js
@@ -64,8 +64,13 @@ export default class AstroPlot extends Morph {
return str.slice(0, 100).replace('\n', '
');
}
- async displayData(features, clusters) {
- if (!clusters) clusters = Array(features.length).fill(0);
+ async updateLabels(labels) {
+ // # TODO
+ let container = this.get('#embedding_plot')
+ Plotly.restyle(container, 'marker.color', labels)
+ }
+
+ async displayData(features) {
const dataframe = {
_push(el) {
@@ -81,21 +86,23 @@ export default class AstroPlot extends Morph {
plot_title,
plot_content,
file,
- id
+ id,
+ cluster
}, i) => dataframe._push({
x: umap_embedding[0],
y: umap_embedding[1],
z: umap_embedding[2],
- color: clusters[i],
+ color: cluster,
customdata: {
- cluster: 'Cluster ' + clusters[i],
+ cluster: 'Cluster ' + cluster,
content: plot_content,
title: plot_title,
file,
contentAbbr: `${this.displayContent(plot_content)}...`
},
// text: ' ' + plot_title, // ' '+ neccessary!!
- ids: id || i
+ ids: id || i,
+ cluster
}));
const data = [
@@ -109,7 +116,7 @@ export default class AstroPlot extends Morph {
width: 0.5
},
opacity: 0.8,
- color: clusters,
+ color: dataframe.cluster,
colorscale: 'Viridis',
},
selected: {
@@ -164,6 +171,7 @@ export default class AstroPlot extends Morph {
container.on('plotly_click', (data) => {
+ debugger
let item = data.points[0];
// Update the plot with new selected points
@@ -188,10 +196,10 @@ export default class AstroPlot extends Morph {
//const getRealData = async () => await fetch("http://127.0.0.1:5000/dataset/d3-force-main/umap")
// const response = await getRealData();
- const features = await getRealData(); //await response.json()
- const clusters = await getClusters();
+ // const features = await getRealData(); //await response.json()
+ //const clusters = await getClusters();
- await this.displayData(features, clusters);
+ // await this.displayData(features);
}
/*
diff --git a/src/components/tools/astro-view-example-transformer.py b/src/components/tools/astro-view-example-transformer.py
index 1fd847252..176cd26d9 100644
--- a/src/components/tools/astro-view-example-transformer.py
+++ b/src/components/tools/astro-view-example-transformer.py
@@ -49,6 +49,14 @@ def reduce(self, df):
# multiply whole columns by respective scalar, then add them together
return \
- df['method_embedding'] * 0.8 + \
- df['class_name_embedding'] * 0.1 + \
- df['identifier_mean'] + 0.1
\ No newline at end of file
+ df['method_embedding'] * 0.5 + \
+ df['class_name_embedding'] * 0.4 + \
+ df['identifier_mean'] + 0.1
+
+ def cluster(self):
+ from sklearn.cluster import AgglomerativeClustering
+ return AgglomerativeClustering(
+ n_clusters=None,
+ distance_threshold=130,
+ linkage='ward'
+ )
\ No newline at end of file
diff --git a/src/components/tools/astro-view.html b/src/components/tools/astro-view.html
index ae67d726b..6cef4c7b5 100644
--- a/src/components/tools/astro-view.html
+++ b/src/components/tools/astro-view.html
@@ -68,6 +68,10 @@
max-height: 300px
}
+ #pool-embedding {
+ white-space: pre-wrap;
+ }
+
.token {
margin: 2px; padding: 2px; display:inline-block
}
@@ -142,6 +146,9 @@
+
@@ -154,8 +161,11 @@
+
diff --git a/src/components/tools/astro-view.js b/src/components/tools/astro-view.js
index 5ffe1e019..9a1b0fa96 100644
--- a/src/components/tools/astro-view.js
+++ b/src/components/tools/astro-view.js
@@ -61,9 +61,11 @@ export default class AstroView extends Morph {
get astInspector() { return this.get("#ast"); }
get updateButton() { return this.get("#update"); }
+ get computeEmbeddings() { return this.get("#computeEmbeddings")}
get runQueryButton() { return this.get('#runQuery'); }
get runMapButton() { return this.get('#runMap'); }
get runReduceButton() { return this.get('#runReduce'); }
+ get runClusterButton() { return this.get('#runCluster')}
get autoUpdate() { return this._autoUpdate; }
set autoUpdate(bool) {
@@ -317,10 +319,25 @@ export default class AstroView extends Morph {
}
}
+ async onComputeEmbeddings() {
+ this.status ="generating embeddings: long running task. check backend logs";
+ try {
+ let language = "typescript"; // HARDCODED CHANGE HERE
+ let response = await fetch(`${this.api}/dataset/${this.projectName}/make_context_embeddings?language=${language}`, {
+ method: 'POST',
+ })
+ response = await response.json();
+ if (response.error) throw new Error(response.error);
+ this.status = `generating embeddings: ${JSON.stringify(response.stats)}`;
+ } catch (e) {
+ this.status = "generating embeddings: " + e;
+ }
+ }
+
async onRunParse() {
this.status = "parser: running..."
try {
- let language = "typescript";
+ let language = "typescript"; // HARDCODED CHANGE HERE
let response = await fetch(`${this.api}/dataset/${this.projectName}/parse?language=${language}`, {
method: 'POST',
})
@@ -397,7 +414,25 @@ export default class AstroView extends Morph {
}
}
+ async onRunCluster() {
+ this.status = "clustering: running..."
+ let data;
+ try {
+ let response = await fetch(`${this.api}/dataset/${this.projectName}/run_cluster`, {
+ method: 'POST',
+ })
+ response = await response.json();
+ if (response.error) throw new Error(response.error);
+ let clusters = response.clusters;
+ this.status = "clustering: success. " + clusters + ' clusters found.';
+ } catch (e) {
+ this.status = "clustering: " + e;
+ return;
+ }
+ }
+
async onItemClicked(e) {
+ debugger
const item = e.detail;
let id = item.id;
@@ -414,7 +449,6 @@ export default class AstroView extends Morph {
const source = item.plot_content;
this.sourceCM.setValue(source);
- debugger
} catch (e) {
this.status = "get item: " + e;
}
diff --git a/src/components/tools/astro-view.js.l4a b/src/components/tools/astro-view.js.l4a
index 6ca6df302..a29ad79ad 100644
--- a/src/components/tools/astro-view.js.l4a
+++ b/src/components/tools/astro-view.js.l4a
@@ -1 +1 @@
-{"type":"Reference","version":"3e2e5524c855d1d6d5b2b4c8626697353c198a0e","content":"/*MD # Astro View - AST Token View spelled wrong\n\nMD*/\n\n\nimport Morph from 'src/components/widgets/lively-morph.js';\nimport SyntaxChecker from 'src/client/syntax.js'\n\nimport { uuid as generateUUID, debounce, flatmap, executeAllTestRunners, promisedEvent, loc, range } from 'utils';\n\nexport default class AstroView extends Morph {\n\n static get defaultSourceURL() { return lively4url + \"/src/components/tools/astro-view-example-source.js\"; }\n static get defaultTransformerSourceURL() { return lively4url + \"/src/components/tools/astro-view-example-transformer.py\"; }\n static get defaultWorkspaceURL() { return lively4url + \"/src/components/tools/astro-view-example-workspace.js\"; }\n \n \n\n /*MD ## UI Accessing MD*/\n get container() { return this.get(\"#content\"); }\n \n // Status Text\n get statusLine() { return this.get(\"#status\"); }\n set status(text) { this.statusLine.innerHTML = text; }\n \n // Source\n get sourceEditor() { return this.get(\"#source\"); } \n get sourceLCM() { return this.sourceEditor.livelyCodeMirror(); }\n get sourceCM() { return this.sourceEditor.currentEditor(); }\n get source() { return this.sourceCM.getValue(); }\n \n // Source Path\n get sourcePath() { return this.get(\"#sourcePath\"); }\n get sourceURL() { return this.sourcePath.value; }\n set sourceURL(urlString) { this.sourcePath.value = urlString; }\n onSourcePathEntered(urlString) { this.loadSourceFile(urlString); }\n \n // Project Name\n get projectNameInput() { return this.get('#projectName'); }\n get projectName() { return this.projectNameInput.value; }\n set projectName(text) { this.projectNameInput.value = text; }\n \n // Transformer Code\n get transformerSourceEditor() { return this.get(\"#transformerSource\"); } \n get transformerSourceLCM() { return this.transformerSourceEditor.livelyCodeMirror(); }\n get transformerSourceCM() { return this.transformerSourceEditor.currentEditor(); }\n get transformerSource() { return this.transformerSourceCM.getValue(); }\n \n // Transformer Code Path\n get transformerSourcePath() { return this.get(\"#transformerSourcePath\"); }\n get transformerSourceURL() { return this.transformerSourcePath.value; }\n set transformerSourceURL(urlString) { this.transformerSourcePath.value = urlString; }\n onTransformerSourcePathEntered(urlString) { this.loadTransformerSourceFile(urlString); }\n \n // Plot\n get astroPlot() { return this.get(\"#astro-plot\"); }\n \n get api() { return \"http://127.0.0.1:5000\"; }\n \n \n get astInspector() { return this.get(\"#ast\"); }\n \n get updateButton() { return this.get(\"#update\"); }\n get runQueryButton() { return this.get('#runQuery'); }\n get runMapButton() { return this.get('#runMap'); }\n get runReduceButton() { return this.get('#runReduce'); }\n \n get autoUpdate() { return this._autoUpdate; }\n set autoUpdate(bool) {\n this.updateButton.classList.toggle(\"on\", bool);\n this.updateButton.querySelector(\"i\").classList.toggle(\"fa-spin\", bool);\n this._autoUpdate = bool;\n }\n onUpdate(evt) {\n if (evt.button === 2) this.autoUpdate = !this.autoUpdate;\n this.update();\n }\n \n log(s) {\n console.log(s)\n }\n\n /*MD ## Initialization MD*/\n\n async loadSourceFile(urlString) {\n console.log(\"LOAD \", urlString);\n this.sourceURL = urlString;\n this.sourceEditor.setURL(lively.paths.normalizePath(urlString, \"\"));\n await this.sourceEditor.loadFile();\n await this.update(); \n }\n \n async loadTransformerSourceFile(urlString) {\n console.log(\"LOAD \", urlString);\n this.transformerSourceURL = urlString;\n this.transformerSourceEditor.setURL(lively.paths.normalizePath(urlString, \"\"));\n await this.transformerSourceEditor.loadFile();\n await this.update(); \n }\n \n async initialize() {\n this.windowTitle = \"Astro View\";\n this.registerButtons();\n\n this.getAllSubmorphs(\"button\").forEach(button => {\n button.addEventListener('contextmenu', e => {\n e.preventDefault();\n e.stopPropagation();\n e.currentTarget.dispatchEvent(new MouseEvent(\"click\", {button: 2}));\n });\n });\n \n await this.sourceEditor.awaitEditor();\n await this.transformerSourceEditor.awaitEditor();\n \n this.sourceEditor.hideToolbar();\n this.astInspector.connectEditor(this.sourceEditor);\n this.sourceLCM.doSave = async () => {\n this.save();\n };\n this.transformerSourceLCM.doSave = async () => {\n this.save();\n };\n \n this.sourceEditor.livelyCodeMirror().editor.on(\"cursorActivity\", (cm) => {\n // #TODO continue here....\n console.log(cm)\n // this.selectPath(pathKeys);\n })\n \n this.debouncedUpdate = this.update::debounce(500);\n this.sourceLCM.addEventListener(\"change\", (() =>\n SyntaxChecker.checkForSyntaxErrors(this.sourceCM))::debounce(200));\n this.sourceLCM.addEventListener(\"change\", () => {\n if (this.autoUpdate) this.debouncedUpdate()\n });\n \n this.debouncedUpdateTransformer = this.updateTransformer::debounce(500);\n this.transformerSourceLCM.addEventListener(\"change\", (() => {\n // SyntaxChecker.checkForSyntaxErrors(this.transformerSourceCM))::debounce(200) \n }));\n this.transformerSourceLCM.addEventListener(\"change\", () => {\n if (this.autoUpdate) this.debouncedUpdateTransformer()\n });\n \n this.sourcePath.addEventListener(\"keyup\", evt => {\n if (evt.code == \"Enter\") this.onSourcePathEntered(this.sourcePath.value);\n });\n this.transformerSourcePath.addEventListener(\"keyup\", evt => {\n if (evt.code == \"Enter\") this.onTransformerSourcePathEntered(this.transformerSourcePath.value);\n });\n \n this.astroPlot.addEventListener('item_click', evt => this.onItemClicked(evt));\n\n const source = this.getAttribute(\"source\");\n if (source) this.loadSourceFile(source);\n \n const transformerSource = this.getAttribute(\"transformerSource\");\n if (transformerSource) this.loadTransformerSourceFile(transformerSource);\n \n this.projectName = this.getAttribute(\"projectName\") || \"\";\n \n this.autoUpdate = true;\n\n this.dispatchEvent(new CustomEvent(\"initialize\"));\n }\n\n onEditorCursorActivity(cm) {\n var from = cm.getCursor(true)\n var to = cm.getCursor(false)\n \n this.get(\"#editorInfo\").textContent = `${cm.indexFromPos(from)}-${cm.indexFromPos(to)}`\n }\n \n async updateTokens() { \n let api = \"http://127.0.0.1:5000\";\n let dataset = \"d3-force-main\";\n \n this.status = \"source updated: fetching...\"\n \n try {\n this.tokens = null;\n \n let response = await fetch(`${api}/tokenize`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n text: this.source\n })\n })\n \n let tokens = await response.json();\n // filter new-lines\n tokens = tokens.filter(ea => !ea.value.match(/^[ \\n]+$/));\n \n this.tokens = tokens;\n } catch (e) {\n this.status = `error fetching tokens: ${e}`;\n this.log(`error fetching tokens: ${e}`);\n }\n \n try {\n let response = await fetch(`${api}/dataset/${dataset}/embedding`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n text: this.source\n }),\n })\n \n let embedding = await response.json()\n this.embedding = embedding;\n } catch (e) {\n this.log(`error fetching embedding: ${e}`);\n this.status = `error fetching embedding: ${e}`;\n }\n \n if (this.embedding) {\n let formatted = JSON.stringify(this.embedding)\n this.get('#pool_embedding').innerText = formatted\n this.get('#astro-plot').showFeature(this.embedding)\n }\n\n this.log('fetched tokens', this.tokens)\n \n if (this.tokens) {\n this.get(\"#tokens\").innerHTML = \"\"\n this.tokens.forEach((token) => {\n let tokenView = \n \n
{token.id}
\n
this.selectToken(tokenView, token)}\n pointerenter={() => this.hoverToken(tokenView, token, true)}\n pointerleave={() => this.hoverToken(tokenView, token, false)}\n >{token.value}
\n
{token.start}-{token.end}
\n
\n this.get(\"#tokens\").appendChild(tokenView)\n })\n } else {\n this.get(\"#tokens\").innerHTML = \"Error fetching tokens\"\n this.status = `error fetching tokens`;\n }\n }\n \n selectToken(view, token) {\n if (this.selectedTokenView) this.selectedTokenView.classList.remove(\"selected\")\n view.classList.add(\"selected\")\n this.selectedTokenView = view\n \n this.get(\"#embeddings\").innerHTML = \"\"\n let rows = []\n \n let tds = Array.from(token.value)\n .map(ea => ea.charCodeAt(0))\n .map(ea => {ea} | )\n \n rows.push({...tds}
)\n \n let table = \n \n this.get(\"#embeddings\").appendChild(table)\n \n }\n \n \n hoverToken(view, token, active) {\n if (active) {\n const start = loc(this.sourceCM.posFromIndex(token.start));\n const end = loc(this.sourceCM.posFromIndex(token.end));\n this.hoverMarker = this.sourceCM.markText(start.asCM(), end.asCM(), {css: \"background-color: #fe3\"});\n } else {\n this.hoverMarker.clear();\n this.hoverMarker = null;\n }\n }\n \n /*MD ## Execution MD*/\n \n async update() {\n this.lastSource = this.source\n this.log(\"source code changed, length: \" + this.source.length + \"\")\n \n try {\n var node = await this.astInspector.treeSitterParse(this.source)\n this.treeSitterRootNode = node.rootNode\n this.astInspector.inspect(this.treeSitterRootNode);\n } catch (e) {\n this.astInspector.inspect({Error: e.message});\n }\n \n this.updateTokens();\n }\n \n async updateTransformer() {\n this.status = \"transformer: sending...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/transformer`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n text: this.transformerSource\n }),\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = \"transformer: using \" + response.transformer;\n } catch (e) {\n this.status = \"transformer: \" + e;\n }\n }\n \n async onRunParse() {\n this.status = \"parser: running...\"\n try {\n let language = \"typescript\";\n let response = await fetch(`${this.api}/dataset/${this.projectName}/parse?language=${language}`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = `parser: currently ${response.ASTs} ASTs in memory. ${response.features} tokens with embeddings`;\n } catch (e) {\n this.status = \"parser: \" + e;\n }\n }\n \n async onRunQuery() {\n this.status = \"query: running...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/run_query`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = \"query: matched \" + response.matches + \" items in \" + response.files + \" files\";\n } catch (e) {\n this.status = \"query: \" + e;\n }\n }\n \n async onRunMap() {\n this.status = \"map: running...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/run_map`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = (\"map: success. Data columns: \\n\" + response.columns).replaceAll('\\n', '
');\n } catch (e) {\n this.status = \"map: \" + e;\n }\n }\n \n async onRunReduce() {\n this.status = \"reduce: running...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/run_reduce`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = \"reduce: success\";\n } catch (e) {\n this.status = \"reduce: \" + e;\n }\n }\n \n async onRunUmap() {\n this.status = \"umap: running...\"\n let data;\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/run_umap`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n data = response.umap;\n this.status = \"umap: success\";\n } catch (e) {\n this.status = \"umap: \" + e;\n return;\n }\n \n try {\n this.astroPlot.displayData(data)\n } catch (e) {\n this.status = \"plot: \" + e;\n }\n }\n \n async onItemClicked(e) {\n const item = e.detail;\n let id = item.id;\n \n this.status = \"get item: running...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/embeddings/${id}`, {\n method: 'GET',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = \"get item: success\";\n \n const item = JSON.parse(response.item);\n const source = item.plot_content;\n \n this.sourceCM.setValue(source);\n debugger\n } catch (e) {\n this.status = \"get item: \" + e;\n }\n }\n\n async save() {\n if (this.sourceURL) {\n await this.sourceEditor.saveFile();\n }\n if (this.transformerSourceURL) {\n await this.transformerSourceEditor.saveFile();\n }\n this.update();\n }\n\n /*MD ## Lively Integration MD*/\n\n livelyPrepareSave() {\n this.setAttribute('source', this.sourceURL);\n this.setAttribute('transformerSource', this.transformerSourceURL);\n this.setAttribute('projectName', this.projectName);\n \n console.log(\"PREPARE SAVE (AST Explorer)\");\n }\n \n livelyMigrate(other) {\n }\n\n async livelyExample() {\n await this.loadSourceFile(AstroView.defaultSourceURL);\n await this.loadTransformerSourceFile(AstroView.defaultTransformerSourceURL)\n }\n}"}
\ No newline at end of file
+{"type":"Reference","version":"d81cbd8e321e79fc3bf3e4e4ae9dc648ea5f3908","content":"/*MD # Astro View - AST Token View spelled wrong\n\nMD*/\n\n\nimport Morph from 'src/components/widgets/lively-morph.js';\nimport SyntaxChecker from 'src/client/syntax.js'\n\nimport { uuid as generateUUID, debounce, flatmap, executeAllTestRunners, promisedEvent, loc, range } from 'utils';\n\nexport default class AstroView extends Morph {\n\n static get defaultSourceURL() { return lively4url + \"/src/components/tools/astro-view-example-source.js\"; }\n static get defaultTransformerSourceURL() { return lively4url + \"/src/components/tools/astro-view-example-transformer.py\"; }\n static get defaultWorkspaceURL() { return lively4url + \"/src/components/tools/astro-view-example-workspace.js\"; }\n \n \n\n /*MD ## UI Accessing MD*/\n get container() { return this.get(\"#content\"); }\n \n // Status Text\n get statusLine() { return this.get(\"#status\"); }\n set status(text) { this.statusLine.innerHTML = text; }\n \n // Source\n get sourceEditor() { return this.get(\"#source\"); } \n get sourceLCM() { return this.sourceEditor.livelyCodeMirror(); }\n get sourceCM() { return this.sourceEditor.currentEditor(); }\n get source() { return this.sourceCM.getValue(); }\n \n // Source Path\n get sourcePath() { return this.get(\"#sourcePath\"); }\n get sourceURL() { return this.sourcePath.value; }\n set sourceURL(urlString) { this.sourcePath.value = urlString; }\n onSourcePathEntered(urlString) { this.loadSourceFile(urlString); }\n \n // Project Name\n get projectNameInput() { return this.get('#projectName'); }\n get projectName() { return this.projectNameInput.value; }\n set projectName(text) { this.projectNameInput.value = text; }\n \n // Transformer Code\n get transformerSourceEditor() { return this.get(\"#transformerSource\"); } \n get transformerSourceLCM() { return this.transformerSourceEditor.livelyCodeMirror(); }\n get transformerSourceCM() { return this.transformerSourceEditor.currentEditor(); }\n get transformerSource() { return this.transformerSourceCM.getValue(); }\n \n // Transformer Code Path\n get transformerSourcePath() { return this.get(\"#transformerSourcePath\"); }\n get transformerSourceURL() { return this.transformerSourcePath.value; }\n set transformerSourceURL(urlString) { this.transformerSourcePath.value = urlString; }\n onTransformerSourcePathEntered(urlString) { this.loadTransformerSourceFile(urlString); }\n \n // Plot\n get astroPlot() { return this.get(\"#astro-plot\"); }\n \n get api() { return \"http://127.0.0.1:5000\"; }\n \n \n get astInspector() { return this.get(\"#ast\"); }\n \n get updateButton() { return this.get(\"#update\"); }\n get computeEmbeddings() { return this.get(\"#computeEmbeddings\")}\n get runQueryButton() { return this.get('#runQuery'); }\n get runMapButton() { return this.get('#runMap'); }\n get runReduceButton() { return this.get('#runReduce'); }\n get runClusterButton() { return this.get('#runCluster')}\n \n get autoUpdate() { return this._autoUpdate; }\n set autoUpdate(bool) {\n this.updateButton.classList.toggle(\"on\", bool);\n this.updateButton.querySelector(\"i\").classList.toggle(\"fa-spin\", bool);\n this._autoUpdate = bool;\n }\n onUpdate(evt) {\n if (evt.button === 2) this.autoUpdate = !this.autoUpdate;\n this.update();\n }\n \n log(s) {\n console.log(s)\n }\n\n /*MD ## Initialization MD*/\n\n async loadSourceFile(urlString) {\n console.log(\"LOAD \", urlString);\n this.sourceURL = urlString;\n this.sourceEditor.setURL(lively.paths.normalizePath(urlString, \"\"));\n await this.sourceEditor.loadFile();\n await this.update(); \n }\n \n async loadTransformerSourceFile(urlString) {\n console.log(\"LOAD \", urlString);\n this.transformerSourceURL = urlString;\n this.transformerSourceEditor.setURL(lively.paths.normalizePath(urlString, \"\"));\n await this.transformerSourceEditor.loadFile();\n await this.update(); \n }\n \n async initialize() {\n this.windowTitle = \"Astro View\";\n this.registerButtons();\n\n this.getAllSubmorphs(\"button\").forEach(button => {\n button.addEventListener('contextmenu', e => {\n e.preventDefault();\n e.stopPropagation();\n e.currentTarget.dispatchEvent(new MouseEvent(\"click\", {button: 2}));\n });\n });\n \n await this.sourceEditor.awaitEditor();\n await this.transformerSourceEditor.awaitEditor();\n \n this.sourceEditor.hideToolbar();\n this.astInspector.connectEditor(this.sourceEditor);\n this.sourceLCM.doSave = async () => {\n this.save();\n };\n this.transformerSourceLCM.doSave = async () => {\n this.save();\n };\n \n this.sourceEditor.livelyCodeMirror().editor.on(\"cursorActivity\", (cm) => {\n // #TODO continue here....\n console.log(cm)\n // this.selectPath(pathKeys);\n })\n \n this.debouncedUpdate = this.update::debounce(500);\n this.sourceLCM.addEventListener(\"change\", (() =>\n SyntaxChecker.checkForSyntaxErrors(this.sourceCM))::debounce(200));\n this.sourceLCM.addEventListener(\"change\", () => {\n if (this.autoUpdate) this.debouncedUpdate()\n });\n \n this.debouncedUpdateTransformer = this.updateTransformer::debounce(500);\n this.transformerSourceLCM.addEventListener(\"change\", (() => {\n // SyntaxChecker.checkForSyntaxErrors(this.transformerSourceCM))::debounce(200) \n }));\n this.transformerSourceLCM.addEventListener(\"change\", () => {\n if (this.autoUpdate) this.debouncedUpdateTransformer()\n });\n \n this.sourcePath.addEventListener(\"keyup\", evt => {\n if (evt.code == \"Enter\") this.onSourcePathEntered(this.sourcePath.value);\n });\n this.transformerSourcePath.addEventListener(\"keyup\", evt => {\n if (evt.code == \"Enter\") this.onTransformerSourcePathEntered(this.transformerSourcePath.value);\n });\n \n this.astroPlot.addEventListener('item_click', evt => this.onItemClicked(evt));\n\n const source = this.getAttribute(\"source\");\n if (source) this.loadSourceFile(source);\n \n const transformerSource = this.getAttribute(\"transformerSource\");\n if (transformerSource) this.loadTransformerSourceFile(transformerSource);\n \n this.projectName = this.getAttribute(\"projectName\") || \"\";\n \n this.autoUpdate = true;\n\n this.dispatchEvent(new CustomEvent(\"initialize\"));\n }\n\n onEditorCursorActivity(cm) {\n var from = cm.getCursor(true)\n var to = cm.getCursor(false)\n \n this.get(\"#editorInfo\").textContent = `${cm.indexFromPos(from)}-${cm.indexFromPos(to)}`\n }\n \n async updateTokens() { \n let api = \"http://127.0.0.1:5000\";\n let dataset = \"d3-force-main\";\n \n this.status = \"source updated: fetching...\"\n \n try {\n this.tokens = null;\n \n let response = await fetch(`${api}/tokenize`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n text: this.source\n })\n })\n \n let tokens = await response.json();\n // filter new-lines\n tokens = tokens.filter(ea => !ea.value.match(/^[ \\n]+$/));\n \n this.tokens = tokens;\n } catch (e) {\n this.status = `error fetching tokens: ${e}`;\n this.log(`error fetching tokens: ${e}`);\n }\n \n try {\n let response = await fetch(`${api}/dataset/${dataset}/embedding`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n text: this.source\n }),\n })\n \n let embedding = await response.json()\n this.embedding = embedding;\n } catch (e) {\n this.log(`error fetching embedding: ${e}`);\n this.status = `error fetching embedding: ${e}`;\n }\n \n if (this.embedding) {\n let formatted = JSON.stringify(this.embedding)\n this.get('#pool_embedding').innerText = formatted\n this.get('#astro-plot').showFeature(this.embedding)\n }\n\n this.log('fetched tokens', this.tokens)\n \n if (this.tokens) {\n this.get(\"#tokens\").innerHTML = \"\"\n this.tokens.forEach((token) => {\n let tokenView = \n \n
{token.id}
\n
this.selectToken(tokenView, token)}\n pointerenter={() => this.hoverToken(tokenView, token, true)}\n pointerleave={() => this.hoverToken(tokenView, token, false)}\n >{token.value}
\n
{token.start}-{token.end}
\n
\n this.get(\"#tokens\").appendChild(tokenView)\n })\n } else {\n this.get(\"#tokens\").innerHTML = \"Error fetching tokens\"\n this.status = `error fetching tokens`;\n }\n }\n \n selectToken(view, token) {\n if (this.selectedTokenView) this.selectedTokenView.classList.remove(\"selected\")\n view.classList.add(\"selected\")\n this.selectedTokenView = view\n \n this.get(\"#embeddings\").innerHTML = \"\"\n let rows = []\n \n let tds = Array.from(token.value)\n .map(ea => ea.charCodeAt(0))\n .map(ea => {ea} | )\n \n rows.push({...tds}
)\n \n let table = \n \n this.get(\"#embeddings\").appendChild(table)\n \n }\n \n \n hoverToken(view, token, active) {\n if (active) {\n const start = loc(this.sourceCM.posFromIndex(token.start));\n const end = loc(this.sourceCM.posFromIndex(token.end));\n this.hoverMarker = this.sourceCM.markText(start.asCM(), end.asCM(), {css: \"background-color: #fe3\"});\n } else {\n this.hoverMarker.clear();\n this.hoverMarker = null;\n }\n }\n \n /*MD ## Execution MD*/\n \n async update() {\n this.lastSource = this.source\n this.log(\"source code changed, length: \" + this.source.length + \"\")\n \n try {\n var node = await this.astInspector.treeSitterParse(this.source)\n this.treeSitterRootNode = node.rootNode\n this.astInspector.inspect(this.treeSitterRootNode);\n } catch (e) {\n this.astInspector.inspect({Error: e.message});\n }\n \n this.updateTokens();\n }\n \n async updateTransformer() {\n this.status = \"transformer: sending...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/transformer`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n text: this.transformerSource\n }),\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = \"transformer: using \" + response.transformer;\n } catch (e) {\n this.status = \"transformer: \" + e;\n }\n }\n \n async onComputeEmbeddings() {\n this.status =\"generating embeddings: long running task. check backend logs\";\n try {\n let language = \"typescript\"; // HARDCODED CHANGE HERE\n let response = await fetch(`${this.api}/dataset/${this.projectName}/make_context_embeddings?language=${language}`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = `generating embeddings: ${JSON.stringify(response.stats)}`;\n } catch (e) {\n this.status = \"generating embeddings: \" + e;\n }\n }\n \n async onRunParse() {\n this.status = \"parser: running...\"\n try {\n let language = \"typescript\"; // HARDCODED CHANGE HERE\n let response = await fetch(`${this.api}/dataset/${this.projectName}/parse?language=${language}`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = `parser: currently ${response.ASTs} ASTs in memory. ${response.features} tokens with embeddings`;\n } catch (e) {\n this.status = \"parser: \" + e;\n }\n }\n \n async onRunQuery() {\n this.status = \"query: running...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/run_query`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = \"query: matched \" + response.matches + \" items in \" + response.files + \" files\";\n } catch (e) {\n this.status = \"query: \" + e;\n }\n }\n \n async onRunMap() {\n this.status = \"map: running...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/run_map`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = (\"map: success. Data columns: \\n\" + response.columns).replaceAll('\\n', '
');\n } catch (e) {\n this.status = \"map: \" + e;\n }\n }\n \n async onRunReduce() {\n this.status = \"reduce: running...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/run_reduce`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = \"reduce: success\";\n } catch (e) {\n this.status = \"reduce: \" + e;\n }\n }\n \n async onRunUmap() {\n this.status = \"umap: running...\"\n let data;\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/run_umap`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n data = response.umap;\n this.status = \"umap: success\";\n } catch (e) {\n this.status = \"umap: \" + e;\n return;\n }\n \n try {\n this.astroPlot.displayData(data)\n } catch (e) {\n this.status = \"plot: \" + e;\n }\n }\n \n async onRunCluster() {\n this.status = \"clustering: running...\"\n let data;\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/run_cluster`, {\n method: 'POST',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n let clusters = response.clusters;\n this.status = \"clustering: success. \" + clusters + ' clusters found.';\n } catch (e) {\n this.status = \"clustering: \" + e;\n return;\n }\n }\n \n async onItemClicked(e) {\n debugger\n const item = e.detail;\n let id = item.id;\n \n this.status = \"get item: running...\"\n try {\n let response = await fetch(`${this.api}/dataset/${this.projectName}/embeddings/${id}`, {\n method: 'GET',\n })\n response = await response.json();\n if (response.error) throw new Error(response.error);\n this.status = \"get item: success\";\n \n const item = JSON.parse(response.item);\n const source = item.plot_content;\n \n this.sourceCM.setValue(source);\n } catch (e) {\n this.status = \"get item: \" + e;\n }\n }\n\n async save() {\n if (this.sourceURL) {\n await this.sourceEditor.saveFile();\n }\n if (this.transformerSourceURL) {\n await this.transformerSourceEditor.saveFile();\n }\n this.update();\n }\n\n /*MD ## Lively Integration MD*/\n\n livelyPrepareSave() {\n this.setAttribute('source', this.sourceURL);\n this.setAttribute('transformerSource', this.transformerSourceURL);\n this.setAttribute('projectName', this.projectName);\n \n console.log(\"PREPARE SAVE (AST Explorer)\");\n }\n \n livelyMigrate(other) {\n }\n\n async livelyExample() {\n await this.loadSourceFile(AstroView.defaultSourceURL);\n await this.loadTransformerSourceFile(AstroView.defaultTransformerSourceURL)\n }\n}"}
\ No newline at end of file
diff --git a/src/components/tools/openai-audio-chat.js b/src/components/tools/openai-audio-chat.js
index 997379898..146220b27 100644
--- a/src/components/tools/openai-audio-chat.js
+++ b/src/components/tools/openai-audio-chat.js
@@ -140,7 +140,7 @@ export default class OpenaiAudioChat extends Morph {
//comboboxes
this.voiceBox.setOptions(["alloy", "echo", "fable", "onyx", "nova", "shimmer", "silent"])
if (!this.voiceBox.value) this.voiceBox.value="shimmer"
- this.modelBox.setOptions(["gpt-4o", "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo"])
+ this.modelBox.setOptions(["gpt-4o","gpt-4o-mini", "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo"])
if (!this.modelBox.value) this.modelBox.value="gpt-3.5-turbo"
}