This is purely a test at the moment and still needs some work. As mentioned in my previous post, I am looking to create a ChatGPT integration that will allow for ChatGPT to enter code directly into the environment.
To do this, I added several functions into the ChatGPT script include I created in the last post. The updated script include is included at the bottom of this post.
I’m thinking to use this I might create a table to store the ChatGPT requests.
The new functions are as follows:
Function | Notes |
extractAssistantMessage | Used to extract the response message from ChatGPT. Purely to make things a bit easier. |
createScript | Creates a script on the system based on the response it receives from ChatGPT. |
NOT YET USED: This script extracts the code blocks that ChatGPT returns. Not used at present but might update if there are multiple code blocks. |
To test the process, I created a fix script. This fix script asks ChatGPT to create a ServiceNow fix script to query for active users with a first name of Jon.
var chatGPT = new global.ChatGPT(); try { var premise = chatGPT.setPremise("You are writing a code block for use in ServiceNow. I understand you cannot write it into ServiceNow directly. You should respond as a JSON string with no additional text. The response should have the following keys: name (used as a simple name for the script), table (the script table name, E.G. fix script is sys_script_fix), code (the code you are providing), notes (any notes you have about the code)."); var message1 = chatGPT.createMessage("user", "Can you write me a ServiceNow fix script to query for active users with a first name of Jon."); var result = chatGPT.submitChat([premise, message1]); chatGPT.logDebug("RESULT IS: " + result); var extract = chatGPT.extractAssistantMessage(result); chatGPT.logDebug("ASSISTANT MESSAGE IS: " + extract); var scriptId = chatGPT.createScript(extract); if (scriptId) { chatGPT.logDebug("Script was created successfully with id: " + scriptId); } else { chatGPT.logDebug("Script creation failed."); } } catch (e) { gs.error("Error during execution: " + e.message, "ChatGPT"); }
When you run the fix script, you get the following responses. For the result:
RESULT IS: { "id": "chatcmpl-XXXXXXXXXXXXXXXXX", "object": "chat.completion", "created": 1690730521, "model": "gpt-3.5-turbo-0613", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "{\n \"name\": \"ActiveUsersWithFirstNameJon\",\n \"table\": \"sys_script_fix\",\n \"code\": \"var grUsers = new GlideRecord('sys_user');\\n\\\ngrUsers.addQuery('active', true);\\n\\\ngrUsers.addQuery('first_name', 'Jon');\\n\\\ngrUsers.query();\\n\\\n\\n\\\nwhile (grUsers.next()) {\\n\\\n gs.info('User: ' + grUsers.name);\\n\\\n}\",\n \"notes\": \"This fix script queries the sys_user table for active users with a first name of 'Jon' and logs their names using the gs.info method.\"\n}" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 121, "completion_tokens": 133, "total_tokens": 254 } }
For the assistant message:
ASSISTANT MESSAGE IS: { "name": "Query Active Users with First Name Jon", "table": "sys_script_fix", "code": "var gr = new GlideRecord('sys_user');\n\ngr.addQuery('active', true);\ngr.addQuery('first_name', 'Jon');\ngr.query();", "notes": "This fix script queries the sys_user table for active users with a first name of Jon." }
If all is well, you should get some messages saying the script has been created.
ChatGPT: Creating script with name: Query Active Users with First Name Jon ChatGPT: Script created with sys_id: 02b1a8ae475831100dbe0bdbd36d43f0 ChatGPT: Script was created successfully with id: 02b1a8ae475831100dbe0bdbd36d43f0
I have seen a few issues with the response from ChatGPT having unescaped characters that the code doesn’t like. Trying to find a way around that.
Below is the updated ChatGPT script include with the new functions and some additional logging. Hope it helps.
var ChatGPT = Class.create(); ChatGPT.prototype = { debug: true, // Set to true to enable logging initialize: function() { this.model = "gpt-3.5-turbo"; this.logDebug("ChatGPT instance created with model: " + this.model); }, setPremise: function(premise) { try { this.logDebug("Setting premise: " + premise); return this.createMessage("system", premise); } catch (ex) { var exception_message = ex.getMessage(); gs.error(exception_message, "ChatGPT"); } }, createMessage: function(role, content) { try { this.logDebug("Creating message with role: " + role + " and content: " + content); return { "role": role, "content": content }; } catch (ex) { var exception_message = ex.getMessage(); gs.error(exception_message, "ChatGPT"); } }, submitChat: function(messages) { try { this.logDebug("Submitting chat messages: " + JSON.stringify(messages)); var request = new sn_ws.RESTMessageV2("ChatGPT", "POST"); request.setHttpMethod('POST'); var payload = { "model": this.model, "messages": messages, "temperature": 0.7 }; this.logDebug("Payload: " + JSON.stringify(payload)); request.setRequestBody(JSON.stringify(payload)); var response = request.execute(); var httpResponseStatus = response.getStatusCode(); var httpResponseContentType = response.getHeader('Content-Type'); if (httpResponseStatus === 200 && httpResponseContentType === 'application/json') { this.logDebug("ChatGPT API call was successful"); this.logDebug("ChatGPT Response was: " + response.getBody()); return response.getBody(); } else { gs.error('Error calling the ChatGPT API. HTTP Status: ' + httpResponseStatus, "ChatGPT"); } } catch (ex) { var exception_message = ex.getMessage(); gs.error(exception_message, "ChatGPT"); } }, extractAssistantMessage: function(apiResponse) { try { var apiResponseObject = JSON.parse(apiResponse); if (apiResponseObject.choices && apiResponseObject.choices[0] && apiResponseObject.choices[0].message && apiResponseObject.choices[0].message.content) { this.logDebug("Extracted assistant message: " + apiResponseObject.choices[0].message.content); return apiResponseObject.choices[0].message.content; } else { gs.error("No message found in the API response.", "ChatGPT"); return null; } } catch (ex) { var exception_message = ex.getMessage(); gs.error(exception_message, "ChatGPT"); } }, extractCodeBlocks: function(assistantMessage) { try { if (!assistantMessage) { gs.error("Assistant message is null or undefined", "ChatGPT"); return null; } if (typeof(assistantMessage) == "string") assistantMessage = JSON.parse(assistantMessage); var code = assistantMessage.code; if (!code) { gs.error("No code found in the assistant message.", "ChatGPT"); return null; } return code; } catch (ex) { var exception_message = ex.getMessage(); gs.error(exception_message, "ChatGPT"); } }, createScript: function(scriptJson) { try { if (typeof(scriptJson) == "string") scriptJson = JSON.parse(scriptJson); if (!scriptJson.name || !scriptJson.code || !scriptJson.notes || !scriptJson.table) { gs.error("JSON is missing required properties", "ChatGPT"); return null; } this.logDebug("Creating script with name: " + scriptJson.name); var gr = new GlideRecord(scriptJson.table); gr.initialize(); gr.setValue('name', scriptJson.name); gr.setValue('script', scriptJson.code); gr.setValue('description', scriptJson.notes); var sys_id = gr.insert(); if (sys_id) { this.logDebug("Script created with sys_id: " + sys_id); return sys_id; } else { gs.error("Failed to create script", "ChatGPT"); return null; } } catch (e) { gs.error("Failed to parse script JSON: " + e.message, "ChatGPT"); return null; } }, logDebug: function(log_message) { if (this.debug) { gs.log(log_message, "ChatGPT"); } }, type: 'ChatGPT' };