Octopus - Prompt AI

Octopus.Script exported 2024-10-03 by mcasperson belongs to ‘Octopus’ category.

Prompt the Octopus AI service with a message and store the result in a variable. See https://octopus.com/docs/administration/copilot for more information.

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

The prompt to send to the AI service

OctopusAI.Prompt = Describe deployment "#{Octopus.Release.Number}" for project "#{Octopus.Project.Name}" to environment "#{Octopus.Environment.Name}" in space "#{Octopus.Space.Name}"

null

The GitHub Token

OctopusAI.GitHub.Token =

null

The Octopus API Key

OctopusAI.Octopus.APIKey =

null

The Octopus URL

OctopusAI.Octopus.Url = #{Octopus.Web.ServerUri}

null

Script body

Steps based on this template will execute the following Python script.

import os
import re
import http.client
import json

# If this script is not being run as part of an Octopus step, return variables from environment variables.
# Periods are replaced with underscores, and the variable name is converted to uppercase
if 'get_octopusvariable' not in globals():
    def get_octopusvariable(variable):
        return os.environ.get(re.sub('\\.', '_', variable.upper()))

if 'set_octopusvariable' not in globals():
    def set_octopusvariable(variable, value):
        print(f"Setting {variable} to {value}")

# If this script is not being run as part of an Octopus step, print directly to std out.
if 'printverbose' not in globals():
    def printverbose(msg):
        print(msg)

def make_post_request(message, github_token, octopus_api_key, octopus_server):
    """
    Query the Octopus AI service with a message.
    :param message: The prompt message
    :param github_token: The GitHub token
    :param octopus_api_key: The Octopus API key
    :param octopus_server: The Octopus URL
    :return: The AI response
    """
    headers = {
        "X-GitHub-Token": github_token,
        "X-Octopus-ApiKey": octopus_api_key,
        "X-Octopus-Server": octopus_server,
        "Content-Type": "application/json"
    }
    body = json.dumps({"messages": [{"content": message}]}).encode("utf8")

    conn = http.client.HTTPSConnection("aiagent.octopus.com")
    conn.request("POST", "/api/form_handler", body, headers)
    response = conn.getresponse()
    response_data = response.read().decode("utf8")
    conn.close()

    return convert_from_sse_response(response_data)


def convert_from_sse_response(sse_response):
    """
    Converts an SSE response into a string.
    :param sse_response: The SSE response to convert.
    :return: The string representation of the SSE response.
    """

    responses = map(
        lambda line: json.loads(line.replace("data: ", "")),
        filter(lambda line: line.strip(), sse_response.split("\n")),
    )
    content_responses = filter(
        lambda response: "content" in response["choices"][0]["delta"], responses
    )
    return "\n".join(
        map(
            lambda line: line["choices"][0]["delta"]["content"].strip(),
            content_responses,
        )
    )

step_name = get_octopusvariable("Octopus.Step.Name")
message = get_octopusvariable("OctopusAI.Prompt")
github_token = get_octopusvariable("OctopusAI.GitHub.Token")
octopus_api = get_octopusvariable("OctopusAI.Octopus.APIKey")
octopus_url = get_octopusvariable("OctopusAI.Octopus.Url")

result = make_post_request(message, github_token, octopus_api, octopus_url)

set_octopusvariable("AIResult", result)

print(result)
print(f"AI result is available in the variable: Octopus.Action[{step_name}].Output.AIResult")

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "8ce3eb55-2c35-45c2-be8c-27e71ffbf032",
  "Name": "Octopus - Prompt AI",
  "Description": "Prompt the Octopus AI service with a message and store the result in a variable. See https://octopus.com/docs/administration/copilot for more information.",
  "Version": 1,
  "ExportedAt": "2024-10-03T20:35:41.372Z",
  "ActionType": "Octopus.Script",
  "Author": "mcasperson",
  "Packages": [],
  "Parameters": [
    {
      "Id": "10c6b0c8-92e0-4bce-91a7-0d1d0b275c1a",
      "Name": "OctopusAI.Prompt",
      "Label": "The prompt to send to the AI service",
      "HelpText": null,
      "DefaultValue": "Describe deployment \"#{Octopus.Release.Number}\" for project \"#{Octopus.Project.Name}\" to environment \"#{Octopus.Environment.Name}\" in space \"#{Octopus.Space.Name}\"",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    },
    {
      "Id": "831e4eda-0ad3-460a-9375-42ce580bfd7d",
      "Name": "OctopusAI.GitHub.Token",
      "Label": "The GitHub Token",
      "HelpText": null,
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "7d6a276d-fcb5-4dd9-b5a3-b7a3b48782c1",
      "Name": "OctopusAI.Octopus.APIKey",
      "Label": "The Octopus API Key",
      "HelpText": null,
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Id": "3eb54042-8169-4ae4-8910-a02b14325e71",
      "Name": "OctopusAI.Octopus.Url",
      "Label": "The Octopus URL",
      "HelpText": null,
      "DefaultValue": "#{Octopus.Web.ServerUri}",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.RunOnServer": "true",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.Syntax": "Python",
    "Octopus.Action.Script.ScriptBody": "import os\nimport re\nimport http.client\nimport json\n\n# If this script is not being run as part of an Octopus step, return variables from environment variables.\n# Periods are replaced with underscores, and the variable name is converted to uppercase\nif 'get_octopusvariable' not in globals():\n    def get_octopusvariable(variable):\n        return os.environ.get(re.sub('\\\\.', '_', variable.upper()))\n\nif 'set_octopusvariable' not in globals():\n    def set_octopusvariable(variable, value):\n        print(f\"Setting {variable} to {value}\")\n\n# If this script is not being run as part of an Octopus step, print directly to std out.\nif 'printverbose' not in globals():\n    def printverbose(msg):\n        print(msg)\n\ndef make_post_request(message, github_token, octopus_api_key, octopus_server):\n    \"\"\"\n    Query the Octopus AI service with a message.\n    :param message: The prompt message\n    :param github_token: The GitHub token\n    :param octopus_api_key: The Octopus API key\n    :param octopus_server: The Octopus URL\n    :return: The AI response\n    \"\"\"\n    headers = {\n        \"X-GitHub-Token\": github_token,\n        \"X-Octopus-ApiKey\": octopus_api_key,\n        \"X-Octopus-Server\": octopus_server,\n        \"Content-Type\": \"application/json\"\n    }\n    body = json.dumps({\"messages\": [{\"content\": message}]}).encode(\"utf8\")\n\n    conn = http.client.HTTPSConnection(\"aiagent.octopus.com\")\n    conn.request(\"POST\", \"/api/form_handler\", body, headers)\n    response = conn.getresponse()\n    response_data = response.read().decode(\"utf8\")\n    conn.close()\n\n    return convert_from_sse_response(response_data)\n\n\ndef convert_from_sse_response(sse_response):\n    \"\"\"\n    Converts an SSE response into a string.\n    :param sse_response: The SSE response to convert.\n    :return: The string representation of the SSE response.\n    \"\"\"\n\n    responses = map(\n        lambda line: json.loads(line.replace(\"data: \", \"\")),\n        filter(lambda line: line.strip(), sse_response.split(\"\\n\")),\n    )\n    content_responses = filter(\n        lambda response: \"content\" in response[\"choices\"][0][\"delta\"], responses\n    )\n    return \"\\n\".join(\n        map(\n            lambda line: line[\"choices\"][0][\"delta\"][\"content\"].strip(),\n            content_responses,\n        )\n    )\n\nstep_name = get_octopusvariable(\"Octopus.Step.Name\")\nmessage = get_octopusvariable(\"OctopusAI.Prompt\")\ngithub_token = get_octopusvariable(\"OctopusAI.GitHub.Token\")\noctopus_api = get_octopusvariable(\"OctopusAI.Octopus.APIKey\")\noctopus_url = get_octopusvariable(\"OctopusAI.Octopus.Url\")\n\nresult = make_post_request(message, github_token, octopus_api, octopus_url)\n\nset_octopusvariable(\"AIResult\", result)\n\nprint(result)\nprint(f\"AI result is available in the variable: Octopus.Action[{step_name}].Output.AIResult\")"
  },
  "Category": "Octopus",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/octopus-ai-prompt.json",
  "Website": "/step-templates/8ce3eb55-2c35-45c2-be8c-27e71ffbf032",
  "Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAC1QTFRFT6Tl////L5Pg8vj9Y67omsvwPJrisdfzfbzs5fL7y+T32Ov5isLucLXqvt31CJPHWwAABMJJREFUeNrs3deW4jAMAFDF3U75/89dlp0ZhiU4blJEjvQ8hYubLJsA00UCBCIQgQhEIAIRiEAEIhCBCEQgAhGIQAQiEIEIhD8kJm+t+QprfdKfB9HbYpx6CWfspj8HMi+gMgHL/AmQA8W3JTKH+ALFvzCeL0RbpyoCPE9IJeNOSQwh5Z3qd6yRGWQ2qi2cZQWxqj1WzQYSjeoJmJlAklOd4VlArOqPhQEkqBERToeMcfRJBkC0Uep8CfBpjz4JsHJ0zF3dkEWNje0kiB/sUC6eApndaIiCMyAa1PiwJ0AWhRGJHJJQHG2dC7h1rNbO1QOxSA7lNCkkKrQIpJCAB1GREILYIC1NAiwbpKFJgGWDNExcwGstfExcZBCHC6nOglshHtmhViLIig1RNBCN7qjtW8C0Z1UvJcC1Z9XmwMBzzvobmgAyEzgq91dtEEsBsQSQQAFZCSBAATEEEApHZbrVBIkkEIUPSVeB+KtALA0kXQUSrwKZBCIQBnk8Y4i5CsReBeKvkqLM+BCSDWJlrZFvGk9SRTHshkgjZCGAaArIxm3H3grhVzFlW2msfl1ca79UJ1bofYvsDHHlNdTZnlh5MghuPd5NdBDUNZHyCkfktIh03XzALGRPlBDPac7qgWjHZzWcmF5zmmkhidMQ6boKiDXcDTUEaylZqCGJ0Vjvu/fLJtHqhSANEvqb2OYqkOUqEHuVMbJcZdZCGiPhKhC4yjqiIjEE7XThMp8fAWII3mY3kUIQD+AMKQTzPiBhgQ63HlT/KSvgtoi0dq5mCPah1UIE0eh3sT0NhOByvKeAkFzi8PgQomumFhsyOxpIzZN4gLOj5plVwNpR0b2AuePWKBEHQu24pSsJA+LVCeHHQxZ1SiyDIdqok8IOhSSnTottHEQTdyt4ettAj4KkzA4dMikk2Dht2S5ptm1vswnPDxn0YyDZ5oDM3iToo2T5voWaYe+Q+vdjH80QyAzZhCgcDtLMI1Tmtz9w++XHgziHQHJJu/OZ3bs9Xn8gQ72NcP3dKqEfkp10F51xhoIi2I91R+LurXV/5q7pH+wx061CzO16oSQleMyr8fXvwMA0Pro8432DPD/ySx8XrHfSuDAM8n6UhnjQabaiXf5Bq/lREHvEeNtn1rJ08+C/uXkQZHeguxAPC3UvtcJYUogLzZX5hhZZvS6onG5lxXtzWGaygwb79vT/IXhdlNibwlKYOR6T8xjI7W8n+xV7T+GH4tMzWwR+lZhRkJYSsC0thpmCYqyngOz3rN2FLBZ2wZflBCggUHF0Vnp88JKienzIXLSEZCZqU7IKr/gQW9yx3pzV7Y9kvWZWTRRIqDmTtRUnU7b2lLcTYmoqHqnmiO1poER0SPkAeZMAZxaJx0Y3TCdAclsIqDz03ALcyxfTCZBsthoGXWmigGyVhWPLFJJfuuKQWycoEFdXbH4dJJoJxNR1eD/kshz6yn48cF8yW8sFoitflB1w6Q8n+/15Za7oA17/pYNmYgP5fmWm8L1NOHPWgK8kuFew1/JXtOA0yJCv7ah7X8ObUuT5kObU30+fDZm8+zqP+HTIpK0xQ796b5Kv2hSIQAQiEIEIRCACEYhABCIQgQhEIAIRiEAEIpBf8UeAAQAEjtYmlDTcCgAAAABJRU5ErkJggg==",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Thursday, October 3, 2024