Tuesday, March 10, 2026

#1126 - OIC Agent driven diffing part 2 - comparing Actions

Introduction 

In this post I am checking for deltas in respect of actions between 2 different major versions of the same integration. Again, I will be leveraging the factory api as an agent tool, the same apis will be invoked as in the previous post

OIC Actions/Milestones


We all know OIC actions, but what are milestones? Let's check out the result of the above api call for an instance of the following simple integration - 



















{
    "errorMilestones": "",
    "flowCode": "TESTER3",
    "flowMilestones": "r0,r0#m,l0Pre,a0Pre,a0Post,l0Post,n0Pre,n0Post,m0Pre,m0Post,y0#m,y0",
    "flowVersion": "01.00.0000",
    "id": "n23cHBu6EfGsAQHrZc0f7Q",
    "isPurged": false,
    "isReplayable": false,
    "items": [
        {
            "adapter": "rest",
            "hasChildInstance": false,
            "hasErrorChild": false,
            "identifier": "stream-1",
            "invokedBy": "niall.commiskey@oracle.com",
            "isErrorMilestone": false,
            "message": "Wire Message received by Trigger Tester3",
            "milestone": "r0",

Check out the field flowMilestones

"flowMilestones": "r0,r0#m,l0Pre,a0Pre,a0Post,l0Post,n0Pre,n0Post,m0Pre,m0Post,y0#m,y0"

This are the milestones for the executed actions in this flow. Take the Notification action. This has the code n. We see pre and post milestones for this action. The general format of the codes is as follows - alpha + number. The alpha refers to the action (e.g. n = Notification)  and the number to the execution occurrence of this action in the flow (e.g. n0Pre = the milestone before the execution of the first Notification action in the flow). 

So let's go through the milestones above.

r0 - r stands for receive by the adapter. 0 for the initial receive.
r0#m - the #m signals received by the OIC orchestration engine

a0Pre/Post - a here refers to the Assign action

As you can see, this is enclosed in l0Pre and l0Post.

l0Pre/Post - signals begin / end of single assignments 
 
n0Pre/Post - n here refers to the Notification action

m0Pre/Post - m here refers to the Map action

y0 - y here refers to the Reply action
y0#m - the #m signals the reply from the OIC orchestration engine

These milestone codes surface further on in the api response, so it is easy to work out what they mean - e.g.

Now you should be clear on the relationship between milestones and actions; you should also have an appreciation for the codes and what they mean.

So with this information, it should be easy to have my OIC agent compare the milestones between 2 flows and highlight the deltas.

OIC Test Flows - TESTER3 V1 and V2

TESTER3 is a convoluted flow, as I was simply trying to add as many actions as possible, but it will suffice for demo purposes.

That's version 1.0 of the flow, now to version 2.0. It is the same, except for the addition of an extra Publish Event action.

TESTER3 V2.0 - 



Ok, so that's my delta. That's what the agent should highlight.

OIC Diffing Agent

This is a variation on the agent discussed in the previous post.

I need the following tools - 

Run Action Diff Tests - will execute the 2 integrations - TESTER3 v1.0 and TESTER3 v2.0.

wait - The wait tool is called to implement a short pause to ensure the logs have been fully updated

Get OIC Instances - will return the list of instanceIds for recently executed flows. The integration that implements this tool, uses the factory api to retrieve the data.

Get Instance Activity Stream - will retrieve the activity stream for a specific instanceId. The integration that implements this tool, uses the factory api to retrieve the data.

Notify - is used to email the result to the OIC admin.

Agent Guidelines 

The prompt you receive will contain the input you require to run the test.

#### 1. Run Regression Test
The tool you will use requires the following inputs - interationId1 + version nr - integrationId2 + version nr - resource and order details. Output all these details and then run  **Run Action Diff Tests**. Then output the response from the tool.

#### 2. Wait for the logs to be updated
Run the **wait** tool, set the waitInSecs parameter to 30.
Output the response.

#### 2. Get the instance id for the first test
Get the instance id of the integration with the id integrationId1, passed in the prompt. Use the **Get OIC Instances** tool for this. Set the timewindow parameter to 1h.
 Parse the response as follows -
2.1. check for the entry for the integrationId1 passed in the prompt. This should match the value of the integrationId field. The instanceId is 3 fields before the integrationId entry. e.g. 
{
            "creationDate": "2026-03-06T18:22:58.448+0000",
            "date": "2026-03-06T18:22:58.848+0000",
       ...
            "instanceId": "gKMQcBmJEfGsAQHrZc0f7Q",
            "instanceReportingLevel": "Debug",
            "integration": "TESTER|01.00.0000|AA_MAERSK_AGENT_REGRES_TESTS",
            "integrationId": "TESTER",

Always take the instanceId with the correct integrationId and the most recent creationDate value, because there may be more entries for the same integrationId.

Output the instanceId you find as "*** First Test Instance Id is ***" + instanceId +  " executed at " + creationDate.

Then take the instanceId field value for the first test and use it to invoke the **Get Instance Activity Stream** tool.

2.2. Parse the result, looking for the field "flowMilestones", remember this field and its values as FirstTestInstanceMilestones.
--
#### 3. Get the instance id for the second test
Get the instance id of the integration with the id integrationId2, passed in the prompt. Use the **Get OIC Instances** tool for this. Set the timewindow parameter to 1h.
 Parse the response as follows -
3.1. check for the entry for the integrationId2 passed in the prompt. This should match the value of the integrationId field. The instanceId is 3 fields before the integrationId entry. e.g. 
{
            "creationDate": "2026-03-06T18:22:58.448+0000",
            "date": "2026-03-06T18:22:58.848+0000",
       ...
            "instanceId": "gKMQcBmJEfGsAQHrZc0f7Q",
            "instanceReportingLevel": "Debug",
            "integration": "TESTER2|01.00.0000|AA_MAERSK_AGENT_REGRES_TESTS",
            "integrationId": "TESTER2",

Always select the instanceId with the correct integrationId and the most recent creationDate value, because there may be more entries for the same integrationId.

Output the instanceId you find as "*** Second Test Instance Id is ***" + instanceId +  " executed at " + creationDate.

Then take the instanceId field value for the second test and use it to invoke the **Get Instance Activity Stream** tool.
3.2. Parse the result, looking for the field "flowMilestones", remember this field and its values as SecondTestInstanceMilestones.

The flowMilestones values are codes - the codes have the following structure - alpha+number e.g. r0 - 
The alpha refers to the action and the number to the occurance of that action e.g. r0 refers to the initial receive.
Many codes have the following format - a0Pre and a0Post. a refers to the assign action and pre and post are the before and after milestones.

Logger action - The log action is identified by lgn - n referring to the occurance e.g. lg1 for the first occurance of the log action. If a log in enclosed in a For Each action - we see the following -
f0Pre,f0p-1,lg0-1,f0p-2,lg0-2,f0Post-2. This shows 2 Logger actions within a For Each.

For Each action - has pre and post and also iteration e.g. f0Pre,f0p-1,lg0-1,f0p-2,lg0-2,f0Post-2. f0p-1 is the first iteration within the first For Each, f0p-2 is the second iteration within the first For Each.
Note the post format - f0Post-n, n refers to the number of iterations executed e.g. f0Post-2 signals 2 iterations.     

All of the milestone codes surface in the response in a "message" / "milestone" combination e.g. - 
 "message": "Message processed by Invoke FileServerGetFile",
 "milestone": "i1Post#m",
 
Remember the message value for each milestone as milestoneText, as they will be needed for the final output. 

3.3.  Action Codes List
 
Here is a list of codes and the actions to which they refer-

a refers to Assign action
f refers to the For Each action
i refers to invoke
l refers to Label action which encloses the assign action 
lg refers to the Logger action
m refers to Map action
n refers to Notification action
r refers to Receive action
s refers to Switch action
sc refers to Switch Route action
sf refers to Stage Fle action
t refers to Scope action
ta refers to Catch All action 
th refers to the Throw New Error action
w refers to Wait action
wh refers to the While action

4. Now compare the values of FirstTestInstanceMilestones and SecondTestInstanceMilestones.
Hightlight any deltas and output this information, using the action names from the Action Codes List.
Also output the "milestoneText" for each action/milestone.

For any codes found that are not in the Action Codes List - output these codes, tagging them as "unknown code".

Finally send the comparison results as an email using the **Notify** tool. Set the email parameter to niall.commiskey@oracle.com. Set the subject to "Diffing result for " + integrationId1 + " and " + integrationId2.
Set the body to the result of the comparison you just performed.

Run the Agent

The result - 
I check my email - 

Summa Summarum

The agent highlighted the new Publish event action in v2.0. It also listed the Map that goes with the Publish event.

It notes that the milestone code for Publish (pub) is not included in the list I provided, but it worked out what it is.

Map Checking the email, I see - 
Differences found:
- Additional Map (m) milestones in version 2.0: m3Pre (Message received by Data Mapper), m3Post (Data Mapping completed with Message).
- New unknown code milestones starting with 'pub' in version 2.0: pub0Pre#m, pub0Pre, pub0Post, pub0Post#m (Message: Publish TESTER3EVENT1).

I can now update the milestone list in the agent guideines with the new code.

Granted this is a very basic POC, but it does, I hope, show the power of Agentic AI@OIC.




 



 



Monday, March 9, 2026

#1125 - OIC Agent for diffing between 2 integration flows


Introduction 

I have a very simple use case here - my first integration, TESTER, invokes 3 apps -

  • Netsuite
  • QuickBooks
  • SAP
My second integration, TESTER2, is simply a new version of TESTER. It invokes the 3 apps mentioned above, however, there may be some payload changes, new fields added etc.

I need to know the mapping deltas between these 2. e.g. the map for the Netsuite invoke in TESTER has 4 fields -

  • orderNr
  • customer
  • product
  • price
While the same invoke in TESTER2 expects the extra field, country.

Net, net, I need to do a diff of the maps between both flows.

Leveraging the OIC Factory API

The factory api helps us here, let's say my steps are as follows - 

  • Run TESTER
  • Run TESTER2
  • Get the instanceId of the TESTER flow
  • Use that instanceId to retrieve the activity stream for that instance
  • Retrieve the output of the MAP action for the 3 invokes
  • Get the instanceId of the TESTER2 flow
  • Use that instanceId to retrieve the activity stream for that instance
  • Retrieve the output of the MAP action for the 3 invokes
  • Compare and contrast. Output the deltas.

I use the following factory apis -

I will need to get the latest instance of the integration, based on creationId. Then retrieve the relevant instanceId e.g.

I then use the instanceId to retrieve the activity stream.




Each flow has milestones and I'm only interested in the following mapping milestones - 

"m1Post,m2Post,m3Post"

 Let's check out one of the entries for such a milestone -

The payload field contains the result of the map in xml format. This is what I need to compare and contrast between both flows.


OIC Agent Tools

 
 I'll need to give the agent some tools to work with. I begin with the 2 factory api calls.

I also add a wait tool, to ensure the logs have been updated, before I retrieve them.


The 2 integrations I need to validate are in a separate project, they are called TESTER and TESTER2.

Each invokes the 3 ERP create integrations, but different versions - 

TESTER invokes version 1.0 of each, while TESTER2 invokes version 2.0

I need to see if there are any mapping deltas between the 2 flows.

Now back to my tools, I include another one, which will start the test, invoking TESTER and TESTER2 -


I also include a "Notify" tool to email results to interested parties.

Naturally, all of these tools are integrations, which can be exposed as agent tools with one mouse click.

The final tool I create is - Set Trace to Debug. This is a preparatory step to ensure the 2 integrations, TESTER and TESTER2, are running in Debug mode. This is required to ensure the map results are written to the activity stream.


OIC Agent

I use he ReAct pattern and configure my agent as follows - 

Role is set to - 

you are a tester that runs a test and compares outputs of map actions in OIC flows.


Guidelines set as follows - 

----------

The prompt you receive will contain the input you require to run the test.


#### 1. Run Regression Test

The tool you will use requires the following inputs - interationId1 + version nr - integrationId2 + version nr - resource and order details. Output all these details and then run  **Run Regression Tests**. Then output the response from the tool.


#### 2. Wait for the logs to be updated

Run the **wait** tool, set the waitInSecs parameter to 30.

Output the response.


#### 2. Get the instance id for the first test

Get the instance id of the integration with the id integrationId1, passed in the prompt. Use the **Get OIC Instances** tool for this. Set the timewindow parameter to 1h.

 Parse the response as follows -

2.1. check for the entry for the integrationId1 passed in the prompt. This should match the value of the integrationId field. The instanceId is 3 fields before the integrationId entry. e.g. 

{

            "creationDate": "2026-03-06T18:22:58.448+0000",

            "date": "2026-03-06T18:22:58.848+0000",

       ...

            "instanceId": "gKMQcBmJEfGsAQHrZc0f7Q",

            "instanceReportingLevel": "Debug",

            "integration": "TESTER|01.00.0000|AA_MAERSK_AGENT_REGRES_TESTS",

            "integrationId": "TESTER",


Always take the instanceId with the correct integrationId and the most recent creationDate value, because there may be more entries for the same integrationId.


Output the instanceId you find as "*** First Test Instance Id is ***" + instanceId +  " executed at " + creationDate.


Then take the instanceId field value for the first test and use it to invoke the **Get Instance Activity Stream** tool.


2.2. Parse the result, looking for the field "m1Post", then take the value of the the following payload field and format it as proper XML. Output the result as value of integrationId1 + "  Output of Map1  " + the proper XML, e.g. TESTER Output of Map1 <xml>.


2.3. Parse the result, looking for the field "m2Post", then take the value of the the following payload field and format it as proper XML. Output the result as value of integrationId1 + "  Output of Map2  " + the proper XML, e.g. TESTER Output of Map2 <xml>.

2.4. Parse the result, looking for the field "m3Post", then take the value of the the following payload field and format it as proper XML. Output the result as value of integrationId1 + "  Output of Map3  " + the proper XML, e.g. TESTER Output of Map3 <xml>.


--

#### 3. Get the instance id for the second test

Get the instance id of the integration with the id integrationId2, passed in the prompt. Use the **Get OIC Instances** tool for this. Set the timewindow parameter to 1h.

 Parse the response as follows -

1.1. check for the entry for the integrationId2 passed in the prompt. This should match the value of the integrationId field. The instanceId is 3 fields before the integrationId entry. e.g. 

{

            "creationDate": "2026-03-06T18:22:58.448+0000",

            "date": "2026-03-06T18:22:58.848+0000",

       ...

            "instanceId": "gKMQcBmJEfGsAQHrZc0f7Q",

            "instanceReportingLevel": "Debug",

            "integration": "TESTER2|01.00.0000|AA_MAERSK_AGENT_REGRES_TESTS",

            "integrationId": "TESTER2",


Always select the instanceId with the correct integrationId and the most recent creationDate value, because there may be more entries for the same integrationId.


Output the instanceId you find as "*** Second Test Instance Id is ***" + instanceId +  " executed at " + creationDate.


Then take the instanceId field value for the second test and use it to invoke the **Get Instance Activity Stream** tool.


1.2. Parse the result, looking for the field "m1Post", then take the value of the the following payload field and format it as proper XML.  Output the result as value of integrationId2 + "  Output of Map1  " + the proper XML, e.g. TESTER2 Output of Map1 <xml>.


1.3. Parse the result, looking for the field "m2Post", then take the value of the the following payload field and format it as proper XML.Output the result as value of integrationId2 + "  Output of Map2  " + the proper XML, e.g. TESTER2 Output of Map2 <xml>.


1.4. Parse the result, looking for the field "m3Post", then take the value of the the following payload field and format it as proper XML. Output the result as value of integrationId2 + "  Output of Map3  " + the proper XML, e.g. TESTER2 Output of Map3 <xml>.

--


Compare the structure of the xml payloads from integrationId1 and integrationId2 and output the deltas. I am looking for fields that are added or missing.

Finally send the comparison results as an email using the **Notify** tool. Set the email parameter to niall.commiskey@oracle.com. Set the subject to "Diffing result for " + integrationId1 + " and " + integrationId2.

Set the body to the result of the comparison you just performed.  

--------

Run the Agent

Just up front, the deltas are as follows -

TESTER

  • payload for Netsuite invoke includes orderNr, customer, product, price
  • payload for QuickBooks invoke includes orderNr, customer, product, price
  • payload for SAP invoke includes orderNr, customer, product, price

TESTER2

  • payload for Netsuite invoke includes orderNr, customer, product, price, country
  • payload for QuickBooks invoke includes orderNr, customer, product, price
  • payload for SAP invoke includes orderNr, customer, product, price, status

Let's see if the agent can work this out.

It found the structure delta in the Netsuite map.

It also highlighted TESTER returns the orderNr with the prefix, Netsuite-, excellent.


Map2 - no structural change.

Map3 - TESTER2 has the extra field, status, for the SAP invoke.

I check my email - 

Summa Summarum

Granted, I did this in a hurry. I need to optimise the guidelines, but I hope I have demonstrated the power available to you here. Net, net, the world is your oyster!















 

Tuesday, March 3, 2026

#1124 - OIC Announcements

Introduction

According to the docsSystem announcements provide timely and important information to Oracle Integration users. Your tenancy displays system announcements only after an administrator creates a policy that allows the announcements. Creating the policy is a one-time action that applies to all Oracle Integration instances in the tenancy.

I check out my OIC instance - 

and see nada. It is imperative to activate announcements in the OIC UI, because many OIC users do not have OCI console access, and this information can be crucial. 

So here are the 2 policies I need to apply - 
allow service integration to {ANNOUNCEMENT_LIST} in tenancy
allow service integration to {ANNOUNCEMENT_READ} in tenancy

These I apply in the root compartment.

But, before I do that, let's check out the announcements in the OCI console - Governance & Administration -> Announcements

Here is one such announcement - 
Note, I have 4 of these announcements, why so many?

Let's take a step back - I am viewing these announcements in the context of a specific compartment. I check how many OIC instances I have in this compartment - 3 in one region, another in Chicago.

Now back to the announcements- 
I open the first one - and click on Impacted resources

Ok, so that's my NiallC-Demo instance addressed.

I could now mark that announcement as read - 

The second announcement is for the resource - devShape.

The 3rd is for Ruck3.
The 4th is for the OIC instance in Chicago.
 
That's that cleared up; net, net - one announcement per service instance.

Now I'll apply the policy at root level - 
Now back to my OIC UI - 

Announcements are now surfaced.

Summa Summarum

This is a must do for OIC admins, so, hopefully, you've all done it, if not...















#1123 - OIC Tools powering Private Agent Factory

Introduction

This is a follow up on the previous PAF post. It's a slight variation on my ubiquitous Order Processing Agent & Tools

Here the orders are in a DB and a user can browse the DB table and decide which orders to process e.g. I see shedloads of orders, but decide for some reason only know to myself to just process order with the number 678.  

Creating the Flow in Private Agent Factory

Let's work thru these, left to right - 

Chat input - the user input, such as process order 678.

Agent - this agent takes the input and extracts the orderNr, and surface it in an SQL statement e.g. SELECT * from orders WHERE orderNr = '678'.

The custom instructions - Parse the chat input and extract the order number.
Use that order number to create a valid SQL Select statement against the orders table -
Select * from orders where orderNr = 'extracted orderNumber'  
Don't include a ; at the end of the SQL statement and ensure there are no extra invisible characters in the string you return

I join this to the SQL Query action.

Now to the order processing agent - 

Here I just push the result of the SQL execution to the Order Processing Agent.

Click on Playground, to test the flow  - 


Summa Summarum

Private Agent Factory is yet another compelling agent framework offering from ORCL. OIC based tools are the lingua franca here, so what stopping you getting started on your Agentic AI journey?