-
Notifications
You must be signed in to change notification settings - Fork 320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Language Server API for AI #9679
Conversation
69f8b64
to
27db5ed
Compare
The communication with OpenAi looks like this: {
"model" : "gpt-4-turbo-preview",
"response_format" : {
"type" : "json_object"
},
"messages" : [
{
"role" : "system",
"content" : "You are a data analyst. You use Python3. Installed libraries: ['pandas'].\nYour task is to output JSON object with fields:\n- 'kind': 'final'\n- 'fn': String, Python function returning what user wants. Always write as generic code as possible that will work even if the input data (e.g. file content) changes. Do not assume any input data exists if not provided with it explicitly. Use your knowledge about the world if the provided data is missing.\n- 'fnCall': String, Python code that calls the generated function.\n- 'resultPreview': Code in Python. When evaluated, prints to stdout a preview of the result, e.g. 'Visualization.AI.print(\"Number 5\")'. Make it as generic as possible. It should work even if the input data changes. The string written to stdout should be one-line, as short as possible, and as informative as possible, e.g. 'Table with 50 rows and columns \"c1\", \"c2\", and \"c3\"'. It can assume that the 'fnCall' result is in scope.\n- 'queryParts': Array of user query divided into either non-editable text, or widgets. The idea is that users can click widgets to change them to other values. Every part should be one of the JSON objects:\n * Fields:\n a. 'kind': 'text'\n b. 'text': Part of the user query that should not be widget. In particular, numbers shoul not be widgets.\n * Fields:\n a. 'kind': 'dropdown'\n b. 'values': list of possible values. For example, if the query contains name of a column in a data set, provide all other column names, like ['columnName1', 'columnName2']. If the query contains a common comparator like 'less than', provide other comparators like ['greater than', 'equal to']. The same applies to other comparators like 'most popular'.\n\nIf in order to provide the answer you need to investigate what is inside the data, you can run code and be asked again the same question with provided stdout by outputing JSON object with fields:\n- 'kind': 'eval'\n- 'code': Python code required to investigate data. The code should write to stdout as little as possible. Use 'Visualization.AI.print' function for printing to stdout. You can only use data you are already provided with, no more data can be provided and you can't ask for more data.\n- 'reason': Reason why you were not able to provide final code.\nAlways prefer outputting the final code. Use kind \"eval\" only if you can't output object with kind \"final\".\n\nIf you can't provide the answer, because the current data and your knowledge about the world is not enough, output JSON object with fields:\n- 'kind': 'fail'\n- 'reason': Reason why you were not able to provide the answer. As short as possible. Do not mention Python nor code, this is information for non-tech users.\n"
},
{
"role" : "user",
"content" : "There is 'operator70395' variable defined in the program. What is the result of the variable 'operator70395'?"
}
]
} {
"id": "chatcmpl-9JPO6mDpY9zZ7hJxQcQw2w95grj1F",
"object": "chat.completion",
"created": 1714412850,
"model": "gpt-4-0125-preview",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\n \"kind\": \"eval\",\n \"code\": \"Visualization.AI.print(operator70395)\",\n \"reason\": \"To provide the result of 'operator70395', I need to know its current value.\"\n}"
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 655,
"completion_tokens": 44,
"total_tokens": 699
},
"system_fingerprint": "fp_d65ac1064c"
} {
"model" : "gpt-4-turbo-preview",
"response_format" : {
"type" : "json_object"
},
"messages" : [
{
"role" : "system",
"content" : "You are a data analyst. You use Python3. Installed libraries: ['pandas'].\nYour task is to output JSON object with fields:\n- 'kind': 'final'\n- 'fn': String, Python function returning what user wants. Always write as generic code as possible that will work even if the input data (e.g. file content) changes. Do not assume any input data exists if not provided with it explicitly. Use your knowledge about the world if the provided data is missing.\n- 'fnCall': String, Python code that calls the generated function.\n- 'resultPreview': Code in Python. When evaluated, prints to stdout a preview of the result, e.g. 'Visualization.AI.print(\"Number 5\")'. Make it as generic as possible. It should work even if the input data changes. The string written to stdout should be one-line, as short as possible, and as informative as possible, e.g. 'Table with 50 rows and columns \"c1\", \"c2\", and \"c3\"'. It can assume that the 'fnCall' result is in scope.\n- 'queryParts': Array of user query divided into either non-editable text, or widgets. The idea is that users can click widgets to change them to other values. Every part should be one of the JSON objects:\n * Fields:\n a. 'kind': 'text'\n b. 'text': Part of the user query that should not be widget. In particular, numbers shoul not be widgets.\n * Fields:\n a. 'kind': 'dropdown'\n b. 'values': list of possible values. For example, if the query contains name of a column in a data set, provide all other column names, like ['columnName1', 'columnName2']. If the query contains a common comparator like 'less than', provide other comparators like ['greater than', 'equal to']. The same applies to other comparators like 'most popular'.\n\nIf in order to provide the answer you need to investigate what is inside the data, you can run code and be asked again the same question with provided stdout by outputing JSON object with fields:\n- 'kind': 'eval'\n- 'code': Python code required to investigate data. The code should write to stdout as little as possible. Use 'Visualization.AI.print' function for printing to stdout. You can only use data you are already provided with, no more data can be provided and you can't ask for more data.\n- 'reason': Reason why you were not able to provide final code.\nAlways prefer outputting the final code. Use kind \"eval\" only if you can't output object with kind \"final\".\n\nIf you can't provide the answer, because the current data and your knowledge about the world is not enough, output JSON object with fields:\n- 'kind': 'fail'\n- 'reason': Reason why you were not able to provide the answer. As short as possible. Do not mention Python nor code, this is information for non-tech users.\n"
},
{
"role" : "user",
"content" : "There is 'operator70395' variable defined in the program. What is the result of the variable 'operator70395'?"
},
{
"role" : "user",
"content" : "EVALUATED:\nVisualization.AI.print(operator70395)\n\nOUTPUT:\n226"
}
]
} {
"id": "chatcmpl-9JPOALptlvpvX52NJXd22STfeGSZL",
"object": "chat.completion",
"created": 1714412854,
"model": "gpt-4-0125-preview",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\n \"kind\": \"final\",\n \"fn\": \"def get_operator70395_result():\\n return operator70395\",\n \"fnCall\": \"get_operator70395_result()\",\n \"resultPreview\": \"Visualization.AI.print('Result is 226')\",\n \"queryParts\": [\n {\n \"kind\": \"text\",\n \"text\": \"There is 'operator70395' variable defined in the program. What is the result of the variable 'operator70395'?\"\n }\n ]\n}"
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 674,
"completion_tokens": 108,
"total_tokens": 782
},
"system_fingerprint": "fp_d65ac1064c"
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm missing something but it looks like the new handler never stops?
("response", responseUtf8String.asJson) | ||
) | ||
replyTo ! ResponseError(Some(id), AiApi.AiError(Some(payload))) | ||
}(success => replyTo ! ResponseResult(AiCompletion2, id, success)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look like we ever stop the handler?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed 👍
private def stop(): Unit = { | ||
self ! PoisonPill | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we normally did context.stop(self)
? Is there any reason for it to process any existing messages in the queue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really. It could be a stop method of a context.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving the *.enso
part of the changes
Pull Request Description
close #9656
Changelog:
ai/completion_v2
methodVisualization.AI.print
method for converting the expression to text formatVisualization.AI.print
method for printing.Important Notes
The project New_Project_1.zip contains the following main file:
To test the functionality, I asked AI to show me the result of the
operator70395
variable:I got the following responses:
Checklist
Please ensure that the following checklist has been satisfied before submitting the PR:
Scala,
Java,
and
Rust
style guides. In case you are using a language not listed above, follow the Rust style guide.
./run ide build
.