Thursday, April 23, 2026

#1141 - OIC Agent for error resubmission

Introduction 

This is a simple demo on leveraging OIC Agents to monitor and resubmit errors. The setup is as follows - 

The entry point is the ASYNC_MAIN integration, which invokes 2 sync integrations, SYNC1 and SYNC2.

I need to monitor errors in ASYNC_MAIN, I also need the ability to resubmit failed instances.






Note the WAIT action after the invoke of SYNC1. This will ensure flow state dehydration. Our use case will involve generating an error in SYNC2. By resubmit, we do not want SYNC1 to be invoked a second time. 

The error will be generated, when I process an invalid product, iCar. The map action for the SYNC2 invoke will take the product value from an OIC lookup - 



The next component is a DB table on ATP - 

Sample DDL -

CREATE TABLE "NIALLC"."ERRORED_FLOWS"   ( "INSTANCEID" VARCHAR2(30 BYTE) COLLATE "USING_NLS_COMP", "PROJECTNAME" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP", "INTEGRATIONNAME" VARCHAR2(50 BYTE) COLLATE "USING_NLS_COMP"   )  DEFAULT COLLATION "USING_NLS_COMP" ;

ALTER TABLE "NIALLC"."ERRORED_FLOWS" MODIFY ("INSTANCEID" NOT NULL ENABLE);

ALTER TABLE "NIALLC"."ERRORED_FLOWS" MODIFY ("PROJECTNAME" NOT NULL ENABLE);

ALTER TABLE "NIALLC"."ERRORED_FLOWS" MODIFY ("INTEGRATIONNAME" NOT NULL ENABLE); 

On error, a row will be written to this table - 


The flow, with instance id, 2HVm-j8dEfG8Ab8Y-P4nAQ, errors out. 


Let's run a second flow, with the same invalid product, iCar.


The flow, with instance id, O6f-Sj8eEfGQlVci_IGJCQ, errors out.

The result - 2 rows in my errors table -

Using the OIC Factory API to monitor errors 

Here is the api call to monitor errors in this integration - 

https://design.integration.yourRegion.ocp.oraclecloud.com/ic/api/integration/v1/monitoring/errors?integrationInstance=yourOICInstance&q={timewindow: '1h', projectCode: 'AA_RESUBMIT_AGENT',code: 'ASYNC_MAIN'}

Here is an excerpt from the response -

{
    "dataFetchTime": "2026-04-23T14:13:26.594+0000",
    "items": [
        {
            "creationDate": "2026-04-23T14:10:50.525+0000",
            "currentTraceLevel": "Debug",
            "errorCode": "500",
            "errorDetails": "<fault xmlns=\"http://xmlns.oracle.com/cloud/oic/gen3fault\"><traceId>05c9604058916bdfd251f9e87336055a</traceId><requestId>CVYW6UTM6SM9AV7EWAENG1KU1TUPPP6Z/29IPDW8CZUZS6R4C7GHTARVNN35NZBXB/IDJUBT7YVZ59ZT2ZN2DF384ODTFMPFU3</requestId><errorId>Td54bD8eEfGv9004aPKSdQ</errorId><flowId>O6f-Sj8eEfGQlVci_IGJCQ</flowId><errorType>CalledExternalServiceInternalError</errorType><origin>tech-adapters-5b6f967c4-hz976</origin><errorCode>500</errorCode><faultName>ns0:APIInvocationError</faultName><retriable>false</retriable><reason>&lt;![CDATA[{\n  \"type\" : \"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1\",\n  \"title\" : \"ERR-001\",\n  \"detail\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n  \"errorCode\" : \"500\",\n  \"errorDetails\" : [ {\n    \"type\" : \"UnMappedFault:\",\n    \"instance\" : \"NA\",\n    \"title\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n    \"errorPath\" : \"&lt;![CDATA[&lt;location xmlns=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">mcube&lt;/location>\\n]]&gt;\",\n    \"errorCode\" : \"ERR-001\"\n  } ]\n}.The 500 Internal Server Error is a very general HTTP status code that means something has gone wrong on the server side, but the target service could not be more specific on what the exact problem is. Try invoking the target service using cURL. If the problem persists, contact the target service admin.]]&gt;</reason><details><ns0:APIInvocationError xmlns:ns0=\"http://xmlns.oracle.com/cloud/generic/rest/fault/collocatedics/invokeSync2\"><ns0:type/><ns0:title/><ns0:detail/><ns0:errorCode/><ns0:errorDetails><ns0:type>http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1</ns0:type><ns0:title>Internal Server Error</ns0:title><ns0:errorCode>500</ns0:errorCode><ns0:errorPath>&lt;![CDATA[InboundJaxrsResponse{context=ClientResponse{method=POST, uri=http://rest-adapter:8080/ic/api/integration/v2/flows/rest/project/AA_RESUBMIT_AGENT/SYNC_2/1.0/sync2, status=500, reason=Internal Server Error}}]]&gt;</ns0:errorPath><ns0:instance>&lt;![CDATA[{\n  \"type\" : \"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1\",\n  \"title\" : \"ERR-001\",\n  \"detail\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n  \"errorCode\" : \"500\",\n  \"errorDetails\" : [ {\n    \"type\" : \"UnMappedFault:\",\n    \"instance\" : \"NA\",\n    \"title\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n    \"errorPath\" : \"&lt;![CDATA[&lt;location xmlns=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">mcube&lt;/location>\\n]]&gt;\",\n    \"errorCode\" : \"ERR-001\"\n  } ]\n}.The 500 Internal Server Error is a very general HTTP status code that means something has gone wrong on the server side, but the target service could not be more specific on what the exact problem is. Try invoking the target service using cURL. If the problem persists, contact the target service admin.]]&gt;</ns0:instance></ns0:errorDetails></ns0:APIInvocationError></details></fault>",
            "errorItems": [
                {
                    "detailErrorMessage": "<fault xmlns=\"http://xmlns.oracle.com/cloud/oic/gen3fault\"><traceId>05c9604058916bdfd251f9e87336055a</traceId><requestId>CVYW6UTM6SM9AV7EWAENG1KU1TUPPP6Z/29IPDW8CZUZS6R4C7GHTARVNN35NZBXB/IDJUBT7YVZ59ZT2ZN2DF384ODTFMPFU3</requestId><errorId>Td54bD8eEfGv9004aPKSdQ</errorId><flowId>O6f-Sj8eEfGQlVci_IGJCQ</flowId><errorType>CalledExternalServiceInternalError</errorType><origin>tech-adapters-5b6f967c4-hz976</origin><errorCode>500</errorCode><faultName>ns0:APIInvocationError</faultName><retriable>false</retriable><reason>&lt;![CDATA[{\n  \"type\" : \"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1\",\n  \"title\" : \"ERR-001\",\n  \"detail\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n  \"errorCode\" : \"500\",\n  \"errorDetails\" : [ {\n    \"type\" : \"UnMappedFault:\",\n    \"instance\" : \"NA\",\n    \"title\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n    \"errorPath\" : \"&lt;![CDATA[&lt;location xmlns=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">mcube&lt;/location>\\n]]&gt;\",\n    \"errorCode\" : \"ERR-001\"\n  } ]\n}.The 500 Internal Server Error is a very general HTTP status code that means something has gone wrong on the server side, but the target service could not be more specific on what the exact problem is. Try invoking the target service using cURL. If the problem persists, contact the target service admin.]]&gt;</reason><details><ns0:APIInvocationError xmlns:ns0=\"http://xmlns.oracle.com/cloud/generic/rest/fault/collocatedics/invokeSync2\"><ns0:type/><ns0:title/><ns0:detail/><ns0:errorCode/><ns0:errorDetails><ns0:type>http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1</ns0:type><ns0:title>Internal Server Error</ns0:title><ns0:errorCode>500</ns0:errorCode><ns0:errorPath>&lt;![CDATA[InboundJaxrsResponse{context=ClientResponse{method=POST, uri=http://rest-adapter:8080/ic/api/integration/v2/flows/rest/project/AA_RESUBMIT_AGENT/SYNC_2/1.0/sync2, status=500, reason=Internal Server Error}}]]&gt;</ns0:errorPath><ns0:instance>&lt;![CDATA[{\n  \"type\" : \"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1\",\n  \"title\" : \"ERR-001\",\n  \"detail\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n  \"errorCode\" : \"500\",\n  \"errorDetails\" : [ {\n    \"type\" : \"UnMappedFault:\",\n    \"instance\" : \"NA\",\n    \"title\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n    \"errorPath\" : \"&lt;![CDATA[&lt;location xmlns=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">mcube&lt;/location>\\n]]&gt;\",\n    \"errorCode\" : \"ERR-001\"\n  } ]\n}.The 500 Internal Server Error is a very general HTTP status code that means something has gone wrong on the server side, but the target service could not be more specific on what the exact problem is. Try invoking the target service using cURL. If the problem persists, contact the target service admin.]]&gt;</ns0:instance></ns0:errorDetails></ns0:APIInvocationError></details></fault>",
                    "errorCode": "500",
                    "errorLocation": "Re-throw Fault",
                    "errorMessage": "<![CDATA[{\n  \"type\" : \"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1\",\n  \"title\" : \"ERR-001\",\n  \"detail\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n  \"errorCode\" : \"500\",\n  \"errorDetails\" : [ {\n    \"type\" : \"UnMappedFault:\",\n    \"instance\" : \"NA\",\n    \"title\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n    \"errorPath\" : \"<![CDATA[<location xmlns=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">mcube</location>\\n]]>\",\n    \"errorCode\" : \"ERR-001\"\n  } ]\n}.The 500 Internal Server Error is a very general HTTP status code that means something has gone wrong on the server side, but the target service could not be more specific on what the exact problem is. Try invoking the target service using cURL. If the problem persists, contact the target service admin.]]>",
                    "faultId": "TfJ0sj8eEfGmnJ2vua-GOA",
                    "milestone": "eh0",
                    "recoverable": true,
                    "retryCount": 0,
                    "state": "MCUBE_ACTIVITY_RECOVERY_REQUIRED",
                    "status": "FAILED"
                }
            ],
            "errorLocation": "Re-throw Fault",
            "errorMessage": "<![CDATA[{\n  \"type\" : \"http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.1\",\n  \"title\" : \"ERR-001\",\n  \"detail\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n  \"errorCode\" : \"500\",\n  \"errorDetails\" : [ {\n    \"type\" : \"UnMappedFault:\",\n    \"instance\" : \"NA\",\n    \"title\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n    \"errorPath\" : \"<![CDATA[<location xmlns=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">mcube</location>\\n]]>\",\n    \"errorCode\" : \"ERR-001\"\n  } ]\n}.The 500 Internal Server Error is a very general HTTP status code that means something has gone wrong on the server side, but the target service could not be more specific on what the exact problem is. Try invoking the target service using cURL. If the problem persists, contact the target service admin.]]>",
            "faultId": "TfJ0sj8eEfGmnJ2vua-GOA",
            "id": "O6f-Sj8eEfGQlVci_IGJCQ",
            "instanceId": "O6f-Sj8eEfGQlVci_IGJCQ",
            "instanceReportingLevel": "Debug",
            "integrationDeleted": false,
            "invokedBy": "niall.commiskey@oracle.com",
            "isDataAccurate": true,
      ... 
             "primaryName": "orderNr",
            "primaryValue": "2113",
            "projectCode": "AA_RESUBMIT_AGENT",
            "projectName": "AA-Resubmit-Agent",
            "recoverable": true,
            "replayable": false,
            "replayed": false,
            "retryCount": 0
        },
        {
            "creationDate": "2026-04-23T14:08:04.154+0000",
            "currentTraceLevel": "Debug",
            "errorCode": "500",
            "errorDetails": "...
16-sec10.html#sec10.5.1\",\n  \"title\" : \"ERR-001\",\n  \"detail\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n  \"errorCode\" : \"500\",\n  \"errorDetails\" : [ {\n    \"type\" : \"UnMappedFault:\",\n    \"instance\" : \"NA\",\n    \"title\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n    \"errorPath\" : \"&lt;![CDATA[&lt;location xmlns=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">mcube&lt;/location>\\n]]&gt;\",\n    \"errorCode\" : \"ERR-001\"\n  } ]\n}
...
            "errorItems": [
                {
                    "detailErrorMessage": "
... \"ERR-001\",\n  \"detail\" : \"faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n  \"errorCode\" : \"500\",\n  \"errorDetails\" : [ {\n    \"type\" : \"UnMappedFault:\",\n    \"instance\" : \"NA\",\n    \"title\" : \"faultName: 
... 
{{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n    \"errorPath\" : \"<![CDATA[<location xmlns=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">mcube</location>\\n]]>\",\n    \"errorCode\" : \"ERR-001\"\n  } ]\n}.The 500 Internal Server Error is a very general HTTP status code
...

                    "recoverable": true,
                    "retryCount": 0,
                    "state": "MCUBE_ACTIVITY_RECOVERY_REQUIRED",
                    "status": "FAILED"
                }
            ],
     ...
faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}\",\n    \"errorPath\" : \"<![CDATA[<location xmlns=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">mcube</location>\\n]]>\",\n    \"errorCode\" : \"ERR-001\"\n  } ]\n}.
...
            "faultId": "6tIF0D8dEfGez3_SZkbBOA",
            "id": "2HVm-j8dEfG8Ab8Y-P4nAQ",
            "instanceId": "2HVm-j8dEfG8Ab8Y-P4nAQ",
           ...
          "primaryName": "orderNr",
            "primaryValue": "2112",
            "projectCode": "AA_RESUBMIT_AGENT",
            "projectName": "AA-Resubmit-Agent",
        ...
        }
    ],
   ...
    "timeWindow": "1",
    "totalRecordsCount": 2,
    "totalResults": 2
}

Interesting fields in red. 

Using the OIC Factory API to resubmit errors 

Here is the api call I use - 

Now to my integrations, which will leverage the factory api - 






I expose these as tools to my agent - 

Let's try out the agent -

In the last hour, there were 2 errors for the integration ASYNC_MAIN in the project AA_RESUBMIT_AGENT.

What caused these errors? 

The errors were caused by an internal server error with HTTP status code 500. Specifically, the faultName is "ns0:APIInvocationError," and the reason provided is related to an internal server problem with the message: "faultName: {{http://schemas.oracle.com/bpel/extension}remoteFault} cause: {Invalid Product: iCar}."


This indicates that the underlying issue causing the errors was invoking an external service that encountered an internal error related to an invalid product identified as "iCar."


Was order number 2112 affected?

Yes, the order number 2112 was affected. It is associated with one of the errored instances in the last hour for the integration ASYNC_MAIN in the project AA_RESUBMIT_AGENT.


"The best revenge is to be unlike him who performed the injury." - Marcus Aurelius

Let's resubmit, but, before we do so, let's set the lookup value to iBike.

I resubmit via the agent - 

The database table no longer has any rows; the delete being done in the RESUBMIT integration -

I validate in OIC Observability

Naturally, we could have a scheduled integration that uses the new OIC AI Agent native action to ensure these resubmits are done on a regular basis.

Summa Summarum


This is a simple use case for an agent, but it does save lots of time and manual effort.
Please ping me, if you want the project export.














Tuesday, April 21, 2026

#1140 - Fusion AI Agent Studio - leveraging OIC Tools

Introduction 

Here is my ubiquitous order processing agent, running on Fusion AI Agent Studio.

So what did I need to do here? Thanks to my esteemed colleague, Gianni C. for steering me on the right path. 

First step is to create a connection to my OIC MCP Server. 


I click on Tools

Access the OIC Tools

The tool configuration includes the MCP Server URL, from my OIC project.


When defining the tool, the data, required to connect to OIC, is provided as a json structure - 


{"grant_type": "client_credentials","client_id": "yourClientId","client_secret":"yourSecret","scope":"https://yourOICscope.ocp.oraclecloud.com:443urn:opc:resource:consumer::all"}

Now to the Agent, that will leverage the tool -


Create the Agent

Here I've added the Tools, just created -

Create the Agent Team

I created this with type=Supervisor - 

Now to testing...

Test Fusion AI Studio Agent 

process the following order - order nr 2525, customer is Renate Commiskey, product is iBike, price is 4567, country is Ireland, email address is niall.commiskey@oracle.com

I validate in OIC Observability - 











Sunday, April 19, 2026

#1139 - AI Database Private Agent Factory


I am revisiting Private Agent Factory, after a couple of months, and notice lots of new features.

As to be expected, my focus is on how easy it is for this AI Agent framework to leverage OIC tools; so that is where I'll begin.


As you can see, It's simple to create a connection to my OIC based MCP Server - 

The OIC MCP Server allows access to my order processing agentic tools, which execute tasks, such as create order in Netsuite, create order in SAP etc. 

The MCP Server configuration requires client id, secret etc. For this, I created a new integrated application (confidential app) in IDCS.

I added the usual OIC instance scopes -


The MCP Server configuration in PAF - 

then add the usual OIC scopes - 

Then save and authorize - 

Let's go through some more Settings -

I'm using the OCI GenAI based grok model.


Enable SSO - in my case, this allows me to grant transparent access to the users in my IDCS domain. This greatly simplifies use management -  

Define Data Sources -



 


Now let's create an Agent

I use the following Custom instructions


### Order Processing Steps

the processing steps are as follows -

1. check for duplicates - use the get order tool for this

2. validate the order - use the validate order tool for this

3. check inventory to ensure product ordered is in stock - use the check inventory tool for this

4. create order in ERP system - for Irish orders use Netsuite, for German orders use SAP

5. email confirmation to customer - use the notify customer tool for this

6. finally, detail exactly what you did and end with a quote from the great stoic, Marcus Aurelius

Test in Playground -

I test with the following input - 

create order with the order number 310138 for Ireland customer Niall Mac Cumascaigh, for the product, iBike, price is 4567. Customer email is niall.commiskey@oracle.com



OIC Tools are invoked - 

No output is shown, so let's add chat output



I run again - 











I check my email - 

Now lets process new orders from our Orders DB - 


The workflow design is as follows - 

Note the use of the SQL Query component - this will execute the SQL to retrieve new orders - 

SELECT   orderNr,  customer,  email,
  country,  orderDate,  status,  product,
  price
FROM orders
WHERE status = 'NEW'
  AND NVL(processed_flag,'N') = 'N'
ORDER BY orderDate

The Agent Custom instructions have been updated as follows - 

### Order Processing Steps
Process the orders provided in the input from the SQL Query step using the Order Processing Steps.
The processing steps are as follows -

1. check for duplicates - use the get order tool for this

2. validate the order - use the validate order tool for this

3. check inventory to ensure product ordered is in stock - use the check inventory tool for this

4. create order in ERP system - for Irish orders use Netsuite, for German orders use SAP

5. email confirmation to customer - use the notify customer tool for this

6. finally, detail exactly what you did and end with a quote from the great stoic, Marcus Aurelius


Let's test this in Playground

Tool execution starts and the 3 orders are created in Netsuite -


..and so on.

All well and good, you may say; another variation on a theme. So why consider using this specific agent framework?

Why choose Private Agent Framework?

While Oracle offers several agentic frameworks, Private Agent Factory is uniquely designed for organizations that want to build AI where their data already lives. If your goal is to create high-performance, data-centric agents—specifically for structured data analysis or knowledge-based RAG—PAF is the definitive choice.

Why it stands out:

Deep Database Synergy: Unlike generic frameworks, PAF treats Oracle AI Database features as first-class citizens. You get immediate, native access to new database-level AI innovations as soon as they drop.
OOTB Intelligence: It ships with pre-built, "ready-to-work" agents designed for the most common enterprise needs, such as deep knowledge search and complex data analytics.

Fortified Data Privacy: Security isn't an afterthought. PAF runs on a compute node within your own tenancy, ensuring sensitive business data never leaves the OCI perimeter. It inherits the robust, multi-layered security protocols of the Oracle AI Database.

Democratized AI (No-Code): You don't need a team of developers to get started. Its intuitive no-code interface allows "citizen developers" and business analysts to build and deploy sophisticated agents alongside technical teams.

Uncompromising Flexibility: You get the best of both worlds: the high-speed performance of a native Oracle stack and the freedom to choose your preferred LLM—whether it's OCI Generative AI or a local model.

Niall's Verdict: If you need to turn your private enterprise data into an actionable AI workforce without the overhead of moving data or writing complex glue code, Private Agent Factory is your go-to framework.

Summa Summarum

Private Agent Factory is Oracle’s premier framework for building secure, data-centric AI agents directly within the enterprise data perimeter. It bridges the gap between raw business data and actionable AI by integrating agentic logic directly into the Oracle AI Database stack.

These agents can easily leverage OIC based tools, for integrating with enterprise apps and technologies; this is our sweet spot, with our 130+ adapters.