Search This Blog

Tuesday, June 9, 2026

How I Built an Oracle AI-Driven Support Tool for Oracle Cloud Using Databricks, OCI and Claude

If you've spent any time supporting Oracle Cloud ERP, HCM, or EPM, you already know the pattern. A user submits a ticket about a payroll element not processing. You ask a series of diagnostic questions. You identify whether it's an effective date problem, a payroll cutoff issue, a security profile gap, or one of a dozen other root causes. You document the fix. Two months later, a different user hits the same issue and the whole cycle starts over.

This post walks through a tool I built to break that cycle. It is called Solution Designer, and it uses an agentic AI approach on top of Databricks to give your Oracle support team structured, consistent, context-aware troubleshooting guidance -- without requiring users to know exactly what to ask.

The Problem With Generic AI for Oracle Support

The first instinct most teams have is to point users at a general-purpose chatbot. "Just ask it your Oracle question." The problem is that Oracle Cloud is enormous and deeply configuration-dependent. A question like "why isn't my payroll processing?" has radically different answers depending on element type, entry method, effective date, pay period status, and whether payroll has already been run for the period.

A generic chat interface puts all of that burden on the user. They have to know which details matter, phrase the question precisely, and interpret an answer that wasn't tuned to their specific setup.

I took a different approach. Instead of a free-form chat interface, I built a guided intake flow that collects the right diagnostic signals before the AI ever generates a response. The model then has full context to produce a solution that actually fits the situation.

What Solution Designer Does

At its core, the tool is a Flask application deployed as a Databricks App. It connects to OCI or Claude via the Databricks Foundation Model API or the OCI LLM API. The experience works like this:

1. The user picks a scenario from a categorized library. The library currently covers 31 Oracle scenarios across ERP (Payables, Procurement, Receivables, General Ledger, Fixed Assets, Inventory, Projects), HCM (Payroll, Absence, HCM Data Loader, Fast Formula, Security, Workforce Compensation), EPM (Consolidation, Planning Data Loads, Rule Troubleshooting), and integrations (REST API, FBDI, BI Publisher, OTBI, Workflow Notifications).

2. The tool presents a structured intake form specific to that scenario. For Payroll Element Entries, for example, the user answers eight targeted questions: what type of element, how it was created, the specific symptom, how many employees are affected, the effective date, the pay period, whether payroll has already run, and the current status of the element entry. Every question has help text explaining why it matters.

3. The scenario definition includes edge cases. Each scenario JSON file encodes known Oracle gotchas as conditional logic. If the effective date falls outside the pay period, the system flags that as a high-severity edge case and incorporates it into the prompt context automatically. If payroll already ran and the entry is still unprocessed, the tool knows to surface the rollback-or-next-period decision. Users do not have to discover these traps manually.

4. OCI or Claude generates a tailored solution. With the structured inputs and edge case context loaded, OCI/Claude produces a step-by-step resolution path that is specific to what the user actually described. This is not a generic knowledge article. It is a direct answer to their exact configuration.

5. The user can refine through follow-up questions. After the initial solution, the conversation stays open. Users can ask clarifying questions and the system maintains full session context so responses stay coherent. Sessions persist in a Unity Catalog Delta table so the conversation survives page refreshes and can be resumed later.

6. After rating the solution, the user can generate a training document. Once the problem is solved and the user rates the response, a "Generate Training Doc" button appears. They specify a format (Markdown, slide outline, or quick-start guide) and a target audience, and OCI/Claude turns the solution into a shareable knowledge artifact. This is where individual troubleshooting events compound into reusable organizational knowledge.

How the Knowledge Base Works

Each scenario is a JSON file that defines intake questions, answer options, help text, edge cases, and the conditions that trigger them. Here is a simplified example from the Payroll Element Entries scenario:

```json

{

  "id": "oracle-hcm-payroll-element-entries",

  "category": "Oracle HCM",

  "title": "Payroll Element Entries Not Processing",

  "intake_questions": [

    {

      "id": "effective_date",

      "question": "What is the effective date of the entry?",

      "type": "text",

      "required": true,

      "help_text": "Enter date in format MM/DD/YYYY - must be within pay period"

    }

  ],

  "edge_cases": [

    {

      "condition": "effective_date outside of pay_period",

      "impact": "Entry will not process in expected period. Must match effective date to pay period or entry will be skipped.",

      "severity": "high"

    }

  ]

}

```

This structure means the expertise lives in the JSON, not in the prompt. Adding a new scenario or a new edge case is a file edit, not a code change. The knowledge base hot-reloads, so updates go live without a restart.

The Architecture on Databricks

Running this on Databricks was a deliberate choice. The team already uses the platform, so authentication, security, and data governance come for free. Here is the technical stack:

- Databricks Apps for hosting the Flask application

- Databricks Foundation Model API to call Claude (Sonnet 4.5 at time of writing) without managing any external API credentials or you can use the OCI LLM API and connect to it using Python from within the solution

- Unity Catalog Delta tables for two purposes: structured logging of every interaction to `ef_dv.raw_dev_metadata.solution_designer_logs`, and session persistence in `ef_dv.raw_dev_metadata.conversation_sessions`

- Serverless SQL Warehouse for querying those Delta tables from the app

- On-behalf-of (OBO) authentication so every request to Databricks runs under the identity of the actual user, not a shared service account

The logging design deserves a mention. Every time a user generates a solution, submits feedback, or asks a follow-up question, a structured record lands in the Delta table with fields for user identity, scenario ID, scenario category, satisfaction rating, time saved, duration, and the interaction text. That gives leadership a real ROI dashboard backed by queryable data rather than estimates.

How We Built This With Agentic Development

The development process itself is worth describing because it reflects a pattern that works well for Oracle-specific tooling.

We used GitHub Copilot in agent mode throughout the build. The agent did not just autocomplete code; it was given feature requirements and asked to reason through the implementation, identify edge cases in its own output, and iterate. The key discipline was keeping the agent's scope narrow. Each session had one focused objective: add session persistence, add the feedback loop, fix a specific datetime bug in Delta table reads, resolve an issue with the resume-session banner showing stale state.

This approach works well for Oracle support tooling for a specific reason: Oracle Cloud problems are well-bounded. The diagnostic questions for a 3-way match hold resolution are not the same as the diagnostic questions for an HCM Fast Formula error. That domain specificity is an asset when working with an AI coding agent because you can describe the scenario structure precisely and the agent can reason about it correctly.

The iterative cycle looked like this:

1. Identify a gap in the user experience (example: returning to a previously solved scenario still presented the rating form instead of the completed state).

2. Trace the root cause through the code. In this case, the `/feedback` endpoint stored the rating on the session's last interaction in the Delta table but intentionally left session status as `active`. The frontend never checked whether the last interaction already had feedback attached.

3. Write a targeted fix. The solution was a new `restoreFeedbackStateFromHistory()` function in the frontend that reads the persisted rating, locks the feedback buttons, skips the rating form, and surfaces the "Generate Training Doc" button directly. No backend changes needed.

4. Run the 329-test suite to verify no regressions.

5. Deploy with the PowerShell script that syncs files to the Databricks workspace and triggers a new app deployment.

6. Confirm SUCCEEDED in the Databricks Apps deployment status.

The agent accelerated every step but did not replace the domain judgment calls. Decisions like "should the session status flip to solved when feedback is submitted, or should we leave it active so users can keep the conversation going?" require understanding the Oracle support workflow. The agent implements whatever direction you give it; you still have to give the right direction.

What This Looks Like in Practice

Consider a real scenario: an Oracle Finance team is getting 3-way match holds on vendor invoices. Previously, a ticket would come in, a knowledgeable team member would spend 15 to 45 minutes asking diagnostic questions via email or a Teams chat, and then write up a resolution.

With Solution Designer, the user navigates to the "3-Way Match Hold Resolution in Payables" scenario. They answer questions about hold type (quantity vs. price variance), tolerance settings, receipt status, PO type, and approval status. The tool detects relevant edge cases -- for example, if it is a price variance hold on a blanket PO, there is a specific Oracle behavior around line-level vs. header-level tolerances that trips people up repeatedly. The solution it generates addresses exactly that combination. If the user is satisfied, they rate the response, click "Generate Training Doc," specify their audience as "Oracle Finance users," and download a formatted guide they can drop into their SharePoint or Confluence space.

The time saved compounds across every person who hits that scenario going forward.





Click on the Images to Expand Them~

What We Learned

A few things stand out after building this:

Structure beats prompting. The quality improvement from giving AI structured inputs with pre-evaluated edge cases is larger than any prompt engineering trick. When the model knows that the effective date is outside the pay period because the scenario definition explicitly flagged it, the response is categorically more useful than when the user tries to describe that situation in free text.

Persistence changes the support dynamic. When solutions survive as resumable sessions in Delta, the tool stops being a one-shot query tool and starts being a case management layer. Users come back to the same session when a problem resurfaces, add follow-up context, and build a richer record of what was tried and what worked.

Feedback closes the loop. The satisfaction ratings and time-saved estimates that land in the Delta log are not vanity metrics. They identify which scenarios are working and which ones need better edge case coverage. The scenarios with low success rates are the ones that need a knowledge base update. That is a tractable engineering task.

Domain expertise encodes well into JSON. Oracle Cloud has well-documented configuration patterns and well-known failure modes. That knowledge, once captured in the scenario JSON format, is reusable forever. An experienced Oracle consultant or admin can encode years of diagnostic heuristics in an afternoon and make them available to everyone on the team immediately.

Getting Started If You Want to Build Something Similar

The approach is not specific to this stack. The core pattern is: structured intake + knowledge-encoded edge cases + LLM synthesis + persistent sessions. You need:

- A way to call a capable LLM (Databricks Foundation Model API, OCI LLM, Azure OpenAI, or similar)

- A JSON or database structure to encode your domain knowledge

- A lightweight web framework (Flask works well; FastAPI is another good option)

- A persistence layer for sessions and logs (Delta on Databricks is convenient if you are already there; a Postgres database works just as well and of course OCI Autonomous Databases!)

If your organization runs Oracle Cloud and has people who have been troubleshooting it for years, you already have the hardest ingredient: the domain knowledge. The tool just gives you a way to make it available at scale.

The knowledge base for this project started with five scenarios based on the most frequent support tickets. It now covers 31. Each new scenario takes roughly two to four hours to build out properly, including the edge cases. That is a reasonable investment for a scenario that generates 20 support tickets a month.

If you are building something similar for your Oracle user community, the questions, edge case structures, and session management patterns described here translate directly. The specific scenarios are where your team's expertise goes -- everything else is scaffolding.

Monday, June 8, 2026

How I Connected Oracle OCI LLM Endpoints to Postman and VS Code

I recently spent some time wiring up Oracle Cloud Infrastructure Generative AI endpoints so I could call models directly with an OCI Generative AI API key, validate everything in Postman, and then take the same setup into Visual Studio Code. The process ended up being a great example of how OCI can fit into modern AI workflows without forcing teams to abandon the tools they already use every day. Oracle’s Generative AI service supports service specific API keys, OpenAI compatible endpoints, and both Chat Completions and Responses APIs, which makes it much easier to integrate enterprise hosted models into familiar developer tooling.

What stood out to me most was how practical the setup became once the moving parts were understood. OCI Generative AI API keys are not the same as standard OCI IAM API keys. They are service generated secrets created specifically for OCI Generative AI, and Oracle documents that either of the two generated secrets can be used interchangeably in the Authorization header when calling supported model endpoints in the same region where the key was created.

Step 1: Creating the OCI Generative AI API Key

The first step was creating an API key inside the OCI Generative AI area of the Oracle Cloud console. Oracle documents these as service specific credentials for model access, and that distinction matters because they are meant for LLM endpoint authentication, not for general tenancy administration. Oracle also notes that the key must be used in the same OCI region as the model endpoint, which is important when you are testing against a region specific inference URL.

Another helpful detail is that OCI gives you two interchangeable secrets per API key. That makes rotation easier because one secret can be regenerated while the other remains active. Oracle explicitly recommends using one of those secrets as the bearer token when calling a supported model endpoint.

Step 2: Adding the IAM Policy That Makes the Key Work

Creating the API key was only part of the story. The key also needed permission to call the OCI Generative AI service. Oracle’s documentation explains that a separate IAM policy is required for principals of type generativeaiapikey, and this is where a lot of integration attempts can stall if the policy step is skipped.

In my case, I created the policy in the OCI Console under *Identity & Security > Policies* and used the manual editor in the root compartment. For testing, the policy that finally unlocked the flow was:

```text

allow any-user to use generative-ai-family in tenancy where ALL {request.principal.type='generativeaiapikey'}

```

Oracle documents this pattern for broad testing access and also explains that policies can be narrowed later by compartment, model, operation type, or even a specific API key OCID. That is a good way to start wide enough to validate the integration and then tighten the scope after the path is proven.

Step 3: Calling the OCI Endpoint from Postman

Once the key and policy were in place, I moved into Postman. Oracle documents a REST endpoint pattern for Chat Completions using OCI Generative AI API keys:

```text

https://inference.generativeai.<region>.oci.oraclecloud.com/20231130/actions/v1/chat/completions

```

Oracle’s API key documentation also shows that the request should send the API key secret in the Authorization: Bearer ... header and include a valid supported model in the request body. Supported models for this API key based REST path include xAI Grok and OpenAI GPT OSS, which are the models I focused on, but there's more available models in OCI like Llama, Cohere and Gemini.

My working request in Postman ended up looking like this:

```http

POST https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/v1/chat/completions

Authorization: Bearer sk-<your-secret>

Content-Type: application/json

Accept: application/json

```

With a body like this:

```json

{

  "model": "openai.gpt-oss-20b",

  "messages": [

    {

      "role": "user",

      "content": "Say hello in one sentence."

    }

  ]

}

```

After the policy was added, that request returned a successful response. That was the turning point because it confirmed the key, the policy, the endpoint, and the region were all aligned correctly. Oracle’s documentation supports this exact pattern, including the Chat Completions endpoint and the use of a bearer token generated by OCI Generative AI.


Click the image to expand it~

What I Learned From the Postman Troubleshooting

The troubleshooting was actually a useful part of the exercise. Early failures came down to a few very specific issues. First, the bearer token has to be the actual `sk-...` secret, not the API key OCID or a console URL. Second, the key has to be used in the same region where it was created. Third, the IAM policy really is required or the request will not succeed even if the secret is correct. Oracle’s docs are clear on all three of those points, and once those pieces clicked, the flow became much more predictable.

That experience also reinforced something broader. OCI is not just exposing models in its own console. Oracle is making the service available in ways that work with the tools many engineering teams already use, which lowers the friction to experiment and integrate. Oracle’s newer OpenAI compatible endpoint documentation makes that intent even more obvious by describing a base endpoint that works with familiar OpenAI style request patterns while still keeping authentication, execution, and resource management inside OCI.

Step 4: Taking the Same OCI Endpoint into VS Code

After confirming the endpoint in Postman, I wanted the same model access inside Visual Studio Code, given it's broad use in our organization. That turned out to be possible using VS Code’s bring your own key model support. Microsoft’s documentation explains that VS Code lets you add language models through the model picker and that custom providers can expose one provider with many models. The model metadata includes fields such as id, name, maxInputTokens, maxOutputTokens, and capability flags like tool calling and image input.

Using the custom endpoint option in the VS Code model picker opened a configuration file where I defined the OCI model settings. I used a Chat Completions style configuration because I had already validated that path in Postman. The key pieces were the OCI endpoint URL, the OCI API key, and the exact model ID. For example, openai.gpt-oss-20b worked well for a first pass because it had already succeeded in Postman, and Oracle lists GPT OSS as a supported model family for API key based Chat Completions.

The result was that I could select the OCI backed model in VS Code’s chat experience and use it like any other language model available through the model picker. Microsoft documents that the model picker is how users switch chat models, and Oracle documents that OCI supports both native and OpenAI compatible inference patterns. That combination is what made this work so well.

Click the image to expand it~

Why This Matters

To me, the bigger takeaway is not just that I got Postman and VS Code working. It is that OCI can participate in the same AI development workflows people already use for testing, coding, prototyping, and experimentation. Oracle’s documentation highlights support for OpenAI compatible endpoints, supported SDKs, and familiar APIs like Chat Completions and Responses. Microsoft’s documentation shows that VS Code is increasingly flexible about model choice through bring your own key and custom providers. Put those together and you have a path for teams that want enterprise hosted AI models without giving up developer ergonomics.

That opens up a lot of possibilities. It means OCI hosted models can be validated in Postman, consumed by scripts and SDKs, and surfaced directly in the editor where developers work. It also means organizations that are already invested in Oracle can extend that platform into modern AI workflows instead of treating it as something separate. OCI Generative AI is positioned by Oracle as an enterprise scale AI platform that supports hosted models, OpenAI compatible APIs, governance, and agent related features. This kind of integration work shows what that can look like in practice.

Final Thoughts

What started as a simple attempt to call a model with an OCI API key turned into a good exercise in understanding how Oracle has structured access, authorization, and compatibility with recent product enhancements. The final setup was straightforward once the pieces were in place: create the API key, grant the IAM policy, validate the endpoint in Postman, and then carry the same working endpoint into VS Code. Oracle’s API key model, policy framework, and OpenAI compatible options make that path realistic, and it is a strong example of OCI being useful well beyond the console itself.

If you are working in OCI and want to make enterprise hosted LLMs available in tools your team already trusts, this is absolutely worth trying.

Saturday, March 14, 2026

Converting Oracle’s 1,155 Page EPM REST API PDF Into Machine Readable JSON and Markdown and What It Unlocks

While working through several integration and automation use cases involving Oracle Enterprise Performance Management Cloud, our team kept running into the same practical challenge. The APIs themselves were capable, well designed, and supported a wide range of enterprise scenarios. The challenge was not the APIs. It was how quickly and precisely we could work with the documentation.

The official EPM REST API reference is a 1,155 page PDF.

That document is thorough and authoritative. It reflects significant investment from Oracle and provides deep coverage of the platform. As our use cases expanded to include automation, AI assisted development, and reusable integration patterns, we started asking a different question. What happens when that same high quality documentation is available in a form that tools can understand just as easily as people?

That question led us down an interesting path.

Why structure matters

When teams build against the EPM Planning REST API, the needs are usually very specific. Engineers need to know exactly which endpoint to call, which parameters are required, how asynchronous jobs behave, and how to interpret the response.

The information already exists in the documentation. The challenge is not accuracy or completeness. The challenge is that the information is optimized for reading, not for reuse by modern tooling or AI.

As development workflows increasingly involve AI coding assistants and automated pipelines, having clean structured context becomes essential. These tools perform best when they can reason over well defined inputs rather than scanning long blocks of unstructured text.

The goal here was not to critique how the documentation is published today. It was to explore how much additional value could be unlocked by reshaping it into formats that better align with how software is now being built.

What was built

As part of this effort, a Python script was created to extract and restructure the Oracle EPM REST API documentation. The script processes the official EPM REST API PDF, document G42939 02 from November 2025 on docs.oracle.com, extracts the full text using pdfplumber, and transforms it into structured outputs.

The first output is a structured JSON file. It captures authentication methods including Basic Authentication and OAuth 2.0 with precise header formats. It includes identity domain rules for test and production environments. It documents thirty four REST API endpoints across six functional areas with method, path, parameters, request details, response details, and required roles. It also includes twenty five supported job types with descriptions, along with status codes and other reference data that comes up frequently during development.

The second output is a Markdown version of the same information. This format is easier for humans to scan and review, while still preserving structure through headings, tables, and code blocks.

In addition, the full extracted text from the PDF is saved as a plain text file. This provides traceability back to the source material when deeper validation or cross checking is needed.

How the information is organized

The structured output is grouped by API domain.

Planning includes nineteen endpoints covering jobs, data slices, members, variables, substitution variables, applications, and Smart Push.

Migration includes seven endpoints covering snapshots, file operations, and service maintenance.

Security includes two endpoints focused on encryption key management.

User Management includes three endpoints for users, groups, and role assignments.

Reporting includes one endpoint for report extraction.

Data Management includes two endpoints for integration job execution.

Each endpoint follows a consistent and predictable structure. That consistency is what allows the documentation to move from something that must be read manually to something that can be consumed directly by tools.

Once the documentation exists in this form, it becomes much easier to integrate into development workflows rather than sitting on the side as a reference that is consulted only when something goes wrong.

What this enables

The most immediate benefit shows up when working with AI assisted development tools.

With a structured JSON reference available, coding assistants can reason about the EPM API surface area accurately. They can identify valid endpoints, understand required parameters, recognize supported job types, and generate correct request patterns without guesswork.

This changes the nature of development work. Teams spend less time validating endpoint paths and correcting assumptions, and more time focusing on orchestration, error handling, and business logic.

It also enables more advanced patterns. For teams experimenting with agents that interact with enterprise systems by running jobs, polling for completion, and exporting results, a machine readable API contract is a prerequisite. This approach provides that contract without changing the underlying APIs.

Nothing about the EPM APIs themselves changes. What changes is how easily they can be incorporated into modern tooling and automated workflows.

Notes on the extraction approach

The extraction process is straightforward in concept but careful in execution. pdfplumber handles the low level PDF text extraction. The more challenging part is identifying structure such as endpoint headers, HTTP methods, parameter sections, and response schemas.

Oracle’s documentation is internally consistent, which made this feasible. The script relies on that consistency along with targeted pattern matching and heuristics designed specifically around the EPM REST API layout.

This is not intended to be a generic solution for converting any PDF into structured data. It is a practical pipeline built to produce reliable and usable output for a specific enterprise API.

One interesting outcome is the level of compression involved. The source document is 1,155 pages long. The structured JSON representation is under one thousand lines. That difference highlights how much of a traditional API PDF consists of layout, repetition, and presentation rather than core technical meaning.

Looking ahead

As software development continues to evolve toward closer collaboration between humans and machines, documentation becomes even more important. The format simply needs to keep pace with how it is used.

JSON and MD represent an ideal state for AI interoperability. For platforms that still rely primarily on PDF or other types of documentation, there is an opportunity to expand how that information can be consumed and reused without replacing what already exists.

For teams working with complex enterprise APIs, the takeaway is straightforward. If the documentation exists, it can be made more useful. Extracting it, structuring it, and integrating it into development workflows can unlock real gains in speed, accuracy, and confidence.

That is what this effort set out to explore, and the results have already shown clear value in practice.

Get the code

The extraction script, along with the structured JSON output and the Markdown reference, is available in the GitHub repository here:

https://github.com/TheOwner-glitch/oracle_epm_rest_api/tree/main

The repository includes the Python script used to extract and structure the documentation, the machine readable JSON reference, and a Markdown version that is easier to browse and review. Together, these files provide a practical starting point for teams working with Oracle EPM REST APIs who want documentation that can be consumed directly by modern development tools.

The broader repository also includes supporting artifacts related to interacting with Oracle EPM Cloud, but the API reference extraction stands on its own as a useful and reusable asset.

If this approach proves useful or is adapted for other platforms or documentation sets, those lessons are worth sharing.