I have not “locked in” the message format for agent commands yet, so consider the text below a work in progress that could potentially change at some point. (but most likely it will not since it’s used in soooo many places already)
Also, remember that this is using the message queue, so I still believe you should use work item queues for running work on agents.
All agents listen on a queue with a name that consists of the agent’s slug + “agent”.
So, if you have an agent with the slug “pythonrunner,” you send a message to “pythonrunneragent”.
Every message should contain a property called “command,” and in this case, the command is “runpackage”
Runpackage allows the following properties (arguments):
- id: _id of the package to run; this is mandatory.
- queuename: queue to stream console output and results to. This is optional.
- stream: true/false; this must be true if queuename is set, else false.
- payload: an optional payload to “feed” into the package. This must be an object or a JSON string. If this is given, it will save the payload to a randomly generated filename and set an environment variable called
payloadfile
with the full path and filename. You can update this file during the run if needed, and the content will be sent back to the queue set in queuename.
If you set queuename, you will receive multiple messages back, but you should look for one with command=runpackage and completed=true. If success=true, you can get the console output in output and the file content in payload. If success=false, you will get the console output in output and the error message in error
.
So, if you want to do this using the SDK from an agent or code you are running locally, like in VS Code, you first register a queue for receiving status commands:
const queuename = await client.RegisterQueue(
{
queuename: "" // empty string to use temp queue
},
(msg, payload, user, jwt) => {
if(payload.command == "runpackage") {
// do logic here, waiting for the result
}
});
and you trigger a package using:
const payload = {"message": "hi mom"}
await client.QueueMessage(
{
data: {
command: "runpackage",
id: packageId,
stream: true,
payload: payload,
queuename: queuename,
},
queuename: "pythonrunneragent",
},
false,
);
The agent will send multiple messages, most notably, it will send this message if the package was successfully started
{
"command": "runpackage",
"success": true,
"completed": false
}
Or, you will get this message if it failed to run the package.
{
"command": "runpackage",
"success": false,
"completed": true,
"output": output,
"error": "error message"
}
Once the package has exited, you will receive a message in the format
{
"command": "runpackage",
"success": true/false,
"completed": true,
"exitcode":number,
"output": "console output",
"payload": "payload if used"
}
You can do the same in Node-RED; use the amqp consumer
to listen on a queue (this will be a named queue and not a temp queue as in my SDK example, so you MUST update the permissions on the queue inside the MQ collection to allow the agent permission to publish to the queue after it has been registered), and you can publish a message to the agent using the amqp publish
node.