When you use Rovo APIs, you must comply with the Atlassian Acceptable Use Policy, including the section titled “Artificial intelligence offerings and features.” For the protection of our customers, Atlassian performs safety screening on Agents at our sole discretion. If we identify any issues with your Agent, we may take protective actions, such as preventing the Agent from being deployed or suspending your use of Rovo APIs. Where possible we will notify you of the nature of the issue, and you must use reasonable commercial efforts to correct the issue before deploying your Agent again.
This tutorial explains how the Q&A Creator example Forge app works. If you are unfamiliar with Forge app development, you may want to visit this introduction.
The Q&A Creator app comprises an Agent and associated actions that provide custom capabilities that creates a list of questions and answers based on the Confluence content where the Agent is executing.
The source code of the app is available here. Readers are recommended to review the code as they complete this tutorial.
Before starting this tutorial, you may want to familiarise yourself with the Forge Rovo module documentation and complete the Build a Rovo Agent tutorial to ensure you are familiar with the basics of creating, installing and viewing Rovo apps.
Clone the Forge Q&A Creator app.
The app has the following structure:
1 2├── src └── backend └── action.js └── confluenceUtil.js └── qandaUtil.js └── resolver.js └── frontend └── macro.jsx └── index.js ├── manifest.yml ├── package.json
backend
: Most of the code is within the backend directory. All of the backend code runs in Forge’s functions as a service infrastructure.
frontend: The code in the frontend directory runs in the user’s browser, but it can make calls to the backend via the resolver. It comprises the implementation of a Confluence macro that provides a bespoke experience presenting a list of questions and answers.
manifest
: a significant amount of logic is contained in the app manifest, manifest.yml. The manifest is where the app declares all the Forge capabilities it utilises. It’s also where the prompt of the apps Agent is defined.
Q1: Where is the app’s AI logic?
A1: The app’s AI logic is defined by the prompt in the app’s manifest plus the actions that run in the backend of the app.
Q2: What does the resolver.js
do?
A2: The resolver defines operations in the backend that can be invoked by the macro which executes in the user’s browser.
Q3: What does the action.js
do?
Q3: This code exports functions that implement the actions indirectly referenced by the prompt.
Q4: What does the confluenceUtil.js
do?
Q4: This code implements generic Confluence related utilities needed by the app.
Q5: What does the qandaUtil.js
do?
Q5: This code implements utilities specific to the Q&A logic needed by the app. Most of these utilities relate to the storage of questions and answers.
The app manifest, manifest.yml, declares various modules:
1 2modules: macro: - key: qanda-macro title: Q&A Quiz ... rovo:agent: - key: q-and-a ... actions: - fetch-content - register-q-and-a - insert-q-and-a action: - key: fetch-content ... - key: register-q-and-a ... - key: insert-q-and-a ... function: - key: fetchContent handler: index.fetchContent - key: registerQandA handler: index.registerQandA - key: insertQandAMacro handler: index.insertQandAMacro - key: macro-resolver handler: index.macroHandler ... app: runtime: name: nodejs22.x id: ari:cloud:ecosystem::app/6452e1d8-c457-446a-82a7-d186ef150f15 permissions: scopes: - read:content.metadata:confluence - read:page:confluence - write:page:confluence resources: - key: q-and-a-macro path: src/frontend/macro.jsx - key: static-resources path: static
Some modules are wired to other modules by referencing their keys. The function modules are wired to code by referencing handlers. In this tutorial we have used 3 modules:
The app declares one agent using the rovo:agent
module and a Confluence macro using the macro
module.
The permissions
section declares the need for several scopes in order to invoke various Confluence APIs.
The resources
section declares front end components such as the macro code and the location of icons.
Q1: When do actions run?
A1: Actions are triggered by the AI when conditions outlined by the prompt are met. For example, the fetch content action retrieves the content of the current Confluence page or blogpost or the selected text at the start of the AI processing.
Q2: Which types of modules relate specifically to AI capabilities?
A2: The rovo:agent
and action
modules relate specifically to AI capabilities.
The prompt defines how the AI should behave and can be thought of as a program in its own right, but instead of the programming language being Javascript or another traditional programming language, the prompt programming language is English.
The app declares a single Agent that instructs the AI how to generate a list of questions and answers. At a high level, the prompt defines the following logic:
The app’s prompt has the following outline:
1 2Preamble Workflow Jobs Templates
Forge Rovo apps can define actions to augment the behavior of the AI. The following diagram illustrates the relationships between prompts, actions and the AI:
The Forge Q&A app’s prompt instructs the AI to delegate certain operations to three actions:
fetch-content
: The AI does not automatically operate with the current page or blog post in its context so this action is necessary to retrieve the content.register-q-and-a
: After the AI has generated the list of questions and answers, it is instructed to register each question and answer with this action. The action stores the question and answer provided in a content property.insert-q-and-a
: After presenting the generated questions and answers to the user, the AI also asks the user if they would like the Q&A Quiz macro to be inserted in order to provide a custom user experience to present the questions and answers.Q1: Do all prompts need complicated structures?
A1: No, but increasing structure helps when prompts comprise considerable amounts of logic.
Q2: Must all prompts have the concepts of a workflow, jobs and templates.
A2: No, these abstractions are used by this apps prompt, but alternate abstractions may be used by other prompts.
Q3: How should a prompt reference a job to execute or a template to use?
A3: Jobs and templates are referenced by quoting their names.
Actions are routines that prompts can delegate to. More accurately, the AI delegates work to an action whilst the prompt defines the logic defining when the AI should delegate to an action.
Actions are defined in the app manifest. The definition of an action can define any number of parameters that the AI is expected to supply when invoking the action. Action parameters are provided by the AI in response to the context of the AI and instructions in the prompt.
Actions accept a payload parameter which contains a range of contextual information, including the parameters specified by the action.
A prompt may indicate that the information returned by the action should be used by subsequent AI processing.
View the actions documentation for more details about actions.
Q1: What is an action?
A1: An action is an app function that the prompt can instruct the AI to invoke at certain stages and under certain conditions.
Q2: How many actions can an app define for a prompt.
A2: Any number. App prompts do not need any actions to be defined, but there is no limit to the number of actions allowed.
Q3: How do actions know what information to process?
A3: The definition of actions in the app manifest includes inputs that the AI invokes the action with.
The fetch content action is implemented by the fetchContent
routine within src/backend/action.js
. The action takes a single parameter;- contentId
, the ID of the content that the AI is open against. The action first checks if the user is working against a section of the content by checking of the payload’s highlightedText
field. If they are, then the highlightedText
is returned. Otherwise, the content is fetched via a utility routine, fetchPageOrBlogInfo
using the ID of the content that the AI passes in.
Q1: How does the AI know what value to provide for the contentId
input parameter?
A1: The AI executes in a context such as Confluence page or blog post. The AI is aware of the context and able to retrieve information from it.
The register Q&A action is implemented by the registerQandA
routine within src/backend/action.js
. It is invoked separately for each question and answer pair that the AI generates. The action takes three parameters:
contentId
: the ID of the content that the AI is open against;question
: the AI generated question; andanswer
: the AI generated answer.The register Q&A action demonstrates the ability to post process information returned by the AI. It assigns a score to each question and answer pair and it also stores the question and answer pair as a content property using the Confluence API. To achieve this, the routine performs the following steps:
Each question and answer pair are stored in JSON format to simplify parsing.
Q1: What is the purpose of the register Q&A action?
A1: The purpose of the register Q&A action is to post process each generated question and answer pair. It assigns a random score and stores the question and answer pair against the content which will be utilised by the Q&A Quiz macro.
The insert macro action is implemented by the insertQandAMacro
routine within src/backend/action.js
. The action takes a single contentId
parameter.
To store the macro, the routine performs the following steps:
Q1: Why does the insert quiz macro update a draft of the content rather than publishing a new version of the content.
A1: Updating the draft provides the user with an opportunity to review and further edit the applied changes before publishing them.
As you can see, the prompt contains a considerable amount of logic. As with all types of programs, the prompt needs to be iteratively developed and the behavior of the AI needs to understood as changes are made. Traditional programming typically involves the ability the set breakpoints to stop the program and inspect the state of the program. Alternatively, programs can be debugged by logging output. Whilst you can’t set breakpoints in the AI, you can use the logging technique to debug it.
Whilst the prompt has been fully developed, it still includes some logging statements to illustrate the technique. Here is an excerpt showing logging statements:
1 24. DEBUG: Inform the user of the number of characters in the content. 5. If the length of the fecthed content is less than 200 characters, return a failure message to the user and abort further processing. 6. DEBUG: Provide the user with an explanation of how you fetched the text of the Confluence content. 7. DEBUG: Return up to the first 500 characters of the text of the Confluence content to the user. 8. DEBUG: Return the URL of the Confluence content to the user.
Note the “DEBUG: “ prefix and the following instruction in the preamble:
1 2Some instructions begin with "DEBUG: ", indicating its purpose is to help debug the state. Debugging is enabled so perform these instructions.
To disable the debugging statements, change the last part of the preamble as follows:
1 2Debugging is disabled so ignore these instructions.
Q1: Is is possible to set breakpoints in the AI.
A1: No, breakpoints can’t be set in the AI, but the AI can be debugged via logging instructions in the prompt.
Q2: How can the debugging output of the prompt be disabled.
A2: The debugging output of the prompt can be disabled by modifying the preamble part of the prompt to inform the AI that it should ignore the DEBUG
instructions.
The app demonstrates the ability of a prompt to be defined which involves:
Rate this page: