mirror of
https://github.com/varunshenoy/GraphGPT.git
synced 2023-05-24 23:39:42 +03:00
fix typo
This commit is contained in:
@@ -9,8 +9,12 @@ Successive queries can update the existing state of the graph or create an entir
|
|||||||
|
|
||||||
The current few-shot prompt guides GPT-3 in accurately understanding the JSON formatting GraphGPT requires for proper rendering. You can see the entire prompt in `public/prompts/main.prompt`. A major issue at the moment is latency. Due to the nature of OpenAI API calls, it takes up to 20 seconds to receive a response.
|
The current few-shot prompt guides GPT-3 in accurately understanding the JSON formatting GraphGPT requires for proper rendering. You can see the entire prompt in `public/prompts/main.prompt`. A major issue at the moment is latency. Due to the nature of OpenAI API calls, it takes up to 20 seconds to receive a response.
|
||||||
|
|
||||||
|
## Prompting Magic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
1. Run `npm install` to download required dependencies (currently just [react-graph-vis](https://github.com/crubier/react-graph-vis)).
|
1. Run `npm install` to download required dependencies (currently just [react-graph-vis](https://github.com/crubier/react-graph-vis)).
|
||||||
2. Enter your OPENAI_API_KEY in `src/App.js`.
|
2. Make sure you have an [OpenAI API key](https://openai.com/api/). You will enter this into the web app when running queries.
|
||||||
3. Run `npm run start`. GraphGPT should open up in a new browser tab.
|
3. Run `npm run start`. GraphGPT should open up in a new browser tab.
|
||||||
@@ -2,12 +2,12 @@ Given the current state of a graph and a prompt, extrapolate as many relationshi
|
|||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
current state:
|
current state:
|
||||||
{ "counter": 1, "graph": { "nodes": [ { "id": 1, "label": "Bob", "color": "#ffffff" } ], "edges": [] } }
|
{ "nodes": [ { "id": 1, "label": "Bob", "color": "#ffffff" } ], "edges": [] }
|
||||||
|
|
||||||
prompt: Alice is Bob's roommate. Make her node green.
|
prompt: Alice is Bob's roommate. Make her node green.
|
||||||
|
|
||||||
new state:
|
new state:
|
||||||
{ "counter": 2, "graph": { "nodes": [ { "id": 1, "label": "Bob", "color": "#ffffff" }, { "id": 2, "label": "Alice", "color": "#ff7675" } ], "edges": [ { "from": 1, "to": 2, "label": "roommate" }, ] } }
|
{ "nodes": [ { "id": 1, "label": "Bob", "color": "#ffffff" }, { "id": 2, "label": "Alice", "color": "#ff7675" } ], "edges": [ { "from": 1, "to": 2, "label": "roommate" } ] }
|
||||||
|
|
||||||
current state:
|
current state:
|
||||||
$state
|
$state
|
||||||
190
src/App.js
190
src/App.js
@@ -11,6 +11,8 @@ const DEFAULT_PARAMS = {
|
|||||||
"presence_penalty": 0
|
"presence_penalty": 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SELECTED_PROMPT = "STATELESS"
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
layout: {
|
layout: {
|
||||||
hierarchical: false
|
hierarchical: false
|
||||||
@@ -21,31 +23,157 @@ const options = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [state, setState] = useState(
|
|
||||||
|
const [graphState, setGraphState] = useState(
|
||||||
{
|
{
|
||||||
counter: 0,
|
nodes: [],
|
||||||
graph: {
|
edges: []
|
||||||
nodes: [],
|
}
|
||||||
edges: []
|
);
|
||||||
}
|
|
||||||
})
|
|
||||||
const { graph } = state;
|
|
||||||
|
|
||||||
const clearState = () => {
|
const clearState = () => {
|
||||||
setState({
|
setGraphState({
|
||||||
counter: 0,
|
nodes: [],
|
||||||
graph: {
|
edges: []
|
||||||
nodes: [],
|
|
||||||
edges: []
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
};
|
||||||
|
|
||||||
const queryPrompt = (prompt, apiKey) => {
|
const updateGraph = (updates) => {
|
||||||
fetch('prompts/main.prompt')
|
// updates will be provided as a list of lists
|
||||||
|
// each list will be of the form [ENTITY1, RELATION, ENTITY2] or [ENTITY1, COLOR]
|
||||||
|
|
||||||
|
var current_graph = JSON.parse(JSON.stringify(graphState));
|
||||||
|
|
||||||
|
if (updates.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check type of first element in updates
|
||||||
|
if (typeof updates[0] === "string") {
|
||||||
|
// updates is a list of strings
|
||||||
|
updates = [updates]
|
||||||
|
}
|
||||||
|
|
||||||
|
updates.forEach(update => {
|
||||||
|
if (update.length === 3) {
|
||||||
|
// update the current graph with a new relation
|
||||||
|
const [entity1, relation, entity2] = update;
|
||||||
|
|
||||||
|
// check if the nodes already exist
|
||||||
|
var node1 = current_graph.nodes.find(node => node.id === entity1);
|
||||||
|
var node2 = current_graph.nodes.find(node => node.id === entity2);
|
||||||
|
|
||||||
|
if (node1 === undefined) {
|
||||||
|
current_graph.nodes.push({ id: entity1, label: entity1, color: "#ffffff" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node2 === undefined) {
|
||||||
|
current_graph.nodes.push({ id: entity2, label: entity2, color: "#ffffff" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if an edge between the two nodes already exists and if so, update the label
|
||||||
|
var edge = current_graph.edges.find(edge => edge.from === entity1 && edge.to === entity2);
|
||||||
|
if (edge !== undefined) {
|
||||||
|
edge.label = relation;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_graph.edges.push({ from: entity1, to: entity2, label: relation });
|
||||||
|
|
||||||
|
} else if (update.length === 2 && update[1].startsWith("#")) {
|
||||||
|
// update the current graph with a new color
|
||||||
|
const [entity, color] = update;
|
||||||
|
|
||||||
|
// check if the node already exists
|
||||||
|
var node = current_graph.nodes.find(node => node.id === entity);
|
||||||
|
|
||||||
|
if (node === undefined) {
|
||||||
|
current_graph.nodes.push({ id: entity, label: entity, color: color });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the color of the node
|
||||||
|
node.color = color;
|
||||||
|
|
||||||
|
} else if (update.length === 2 && update[0] == "DELETE") {
|
||||||
|
// delete the node at the given index
|
||||||
|
const [_, index] = update;
|
||||||
|
|
||||||
|
// check if the node already exists
|
||||||
|
var node = current_graph.nodes.find(node => node.id === index);
|
||||||
|
|
||||||
|
console.log("HIII");
|
||||||
|
|
||||||
|
if (node === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete the node
|
||||||
|
current_graph.nodes = current_graph.nodes.filter(node => node.id !== index);
|
||||||
|
|
||||||
|
// delete all edges that contain the node
|
||||||
|
current_graph.edges = current_graph.edges.filter(edge => edge.from !== index && edge.to !== index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setGraphState(current_graph);
|
||||||
|
};
|
||||||
|
|
||||||
|
const queryStatelessPrompt = (prompt, apiKey) => {
|
||||||
|
fetch('prompts/stateless.prompt')
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(text => text.replace("$prompt", prompt))
|
.then(text => text.replace("$prompt", prompt))
|
||||||
.then(text => text.replace("$state", JSON.stringify(state)))
|
.then(prompt => {
|
||||||
|
console.log(prompt)
|
||||||
|
|
||||||
|
const params = { ...DEFAULT_PARAMS, prompt: prompt, stop: "\n" };
|
||||||
|
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': 'Bearer ' + String(apiKey)
|
||||||
|
},
|
||||||
|
body: JSON.stringify(params)
|
||||||
|
};
|
||||||
|
fetch('https://api.openai.com/v1/completions', requestOptions)
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
switch (response.status) {
|
||||||
|
case 401: // 401: Unauthorized: API key is wrong
|
||||||
|
throw new Error('Please double-check your API key.');
|
||||||
|
case 429: // 429: Too Many Requests: Need to pay
|
||||||
|
throw new Error('You exceeded your current quota, please check your plan and billing details.');
|
||||||
|
default:
|
||||||
|
throw new Error('Something went wrong with the request, please check the Network log');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
const { choices } = response;
|
||||||
|
const text = choices[0].text;
|
||||||
|
console.log(text);
|
||||||
|
|
||||||
|
const updates = JSON.parse(text);
|
||||||
|
console.log(updates);
|
||||||
|
|
||||||
|
updateGraph(updates);
|
||||||
|
|
||||||
|
document.getElementsByClassName("searchBar")[0].value = "";
|
||||||
|
document.body.style.cursor = 'default';
|
||||||
|
document.getElementsByClassName("generateButton")[0].disabled = false;
|
||||||
|
}).catch((error) => {
|
||||||
|
console.log(error);
|
||||||
|
alert(error);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
const queryStatefulPrompt = (prompt, apiKey) => {
|
||||||
|
fetch('prompts/stateful.prompt')
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(text => text.replace("$prompt", prompt))
|
||||||
|
.then(text => text.replace("$state", JSON.stringify(graphState)))
|
||||||
.then(prompt => {
|
.then(prompt => {
|
||||||
console.log(prompt)
|
console.log(prompt)
|
||||||
|
|
||||||
@@ -77,21 +205,31 @@ function App() {
|
|||||||
const { choices } = response;
|
const { choices } = response;
|
||||||
const text = choices[0].text;
|
const text = choices[0].text;
|
||||||
console.log(text);
|
console.log(text);
|
||||||
|
|
||||||
const new_graph = JSON.parse(text);
|
const new_graph = JSON.parse(text);
|
||||||
console.log(new_graph);
|
|
||||||
setState(new_graph, () => {
|
setGraphState(new_graph);
|
||||||
console.log(state);
|
|
||||||
});
|
document.getElementsByClassName("searchBar")[0].value = "";
|
||||||
document.body.style.cursor = 'default';
|
document.body.style.cursor = 'default';
|
||||||
document.getElementsByClassName("generateButton")[0].disabled = false;
|
document.getElementsByClassName("generateButton")[0].disabled = false;
|
||||||
document.getElementsByClassName("searchBar")[0].value = "";
|
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
alert(error);
|
alert(error);
|
||||||
document.body.style.cursor = 'default';
|
|
||||||
document.getElementsByClassName("generateButton")[0].disabled = false;
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
const queryPrompt = (prompt, apiKey) => {
|
||||||
|
if (SELECTED_PROMPT === "STATELESS") {
|
||||||
|
queryStatelessPrompt(prompt, apiKey);
|
||||||
|
} else if (SELECTED_PROMPT === "STATEFUL") {
|
||||||
|
queryStatefulPrompt(prompt, apiKey);
|
||||||
|
} else {
|
||||||
|
alert("Please select a prompt");
|
||||||
|
document.body.style.cursor = 'default';
|
||||||
|
document.getElementsByClassName("generateButton")[0].disabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -119,7 +257,7 @@ function App() {
|
|||||||
</div>
|
</div>
|
||||||
</center>
|
</center>
|
||||||
<div className='graphContainer'>
|
<div className='graphContainer'>
|
||||||
<Graph graph={graph} options={options} style={{ height: "640px" }} />
|
<Graph graph={graphState} options={options} style={{ height: "640px" }} />
|
||||||
</div>
|
</div>
|
||||||
<p className='footer'>Pro tip: don't take a screenshot! You can right-click and save the graph as a .png 📸</p>
|
<p className='footer'>Pro tip: don't take a screenshot! You can right-click and save the graph as a .png 📸</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user