ServiceNow – Testing Automatic Code Entry from ChatGPT – Initial Testing

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:

FunctionNotes
extractAssistantMessageUsed to extract the response message from ChatGPT. Purely to make things a bit easier.
createScriptCreates a script on the system based on the response it receives from ChatGPT.
extractCodeBlocksNOT 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'
};

One thought on “ServiceNow – Testing Automatic Code Entry from ChatGPT – Initial Testing”

  1. I really like what you guys are up too. This kind of clever work and reporting!
    Keep up the fantastic works guys I’ve included you guys to
    my blogroll.

Comments are closed.