Skip to main content

Add and Reuse Functions

Calculating read time…

Add and Reuse Functions in Oracle Fusion AI Agent Studio is the discipline — and the specific Code Node capability — that lets you write a piece of JavaScript logic once inside a governed, sandboxed node in Workflow Builder, then reference that same node's output, or copy that same snippet, across every other workflow that needs it, instead of retyping the transformation from scratch each time. It lives inside the deterministic, node-based side of AI Agent Studio, where every step in a process — extract a field, calculate a value, reshape a JSON payload — is preconfigured rather than left to an LLM's judgment. 🧩

Here's why it matters at enterprise scale: a Fusion AI Agent Studio tenant is almost never a single workflow. It's typically dozens of them, built by different teams across HCM, SCM, Procurement, Financials, and CX, and those teams converge on the same handful of small transformations — trimming a bloated business-object response down to three fields, normalizing a date, validating an input — over and over, usually without knowing anyone else already solved it. Left ungoverned, that's not a style nitpick; it's an audit finding waiting to happen, because five slightly different copies of the same payroll-date calculation is exactly the kind of silent drift that breaks trust in an automation estate. Getting reuse right is what separates a pile of one-off workflows from a maintainable, testable, enterprise-grade automation platform. ⚠️

Diagram showing a trigger or business object feeding a Code Node, which becomes a canonical reusable snippet and returns a result to the next workflow node

🔀 Quick Comparison: Where Functions Fit Among AI Agent Studio's Logic Options

Node / Resource Language Best For How It's Reused
Code node JavaScript (Python may also be available, depending on configuration) Data reshaping, calculations, validation, straight-line conditional logic Copy the tested snippet into a new Code node in another workflow
Set Variables node Declarative field assignment Populating workflow-level variables from static or dynamic values Variable referenced anywhere via $context.$variables.<name>
Business Object Function node Declarative, no code Reading, creating, updating, or deleting Fusion Applications records Reusable across any workflow with access to that business object
Policy node + Policy Model Generated decision functions from uploaded policy documents Deterministic, rule-based decisions with test cases Published once, then attached to Policy nodes across workflows

1. What "Add and Reuse Functions" Actually Means 🧩

Workflow Builder is the deterministic half of AI Agent Studio: it runs a connected sequence of nodes where every step — extracting data, calling a business-object function, running an LLM, sending an email — is preconfigured rather than reasoned out on the fly, which is exactly why it's the preferred pattern anywhere compliance, repeatability, and governance matter more than conversational flexibility. Inside that sequence, the Code node is the escape hatch: it's the node type you reach for when a built-in, drag-and-drop node can't express the transformation you need, and you have to write actual procedural logic instead.

That's the "add" half of the capability — dropping a Code node into a workflow and writing JavaScript in it. The "reuse" half is a discipline more than a button: once a snippet does its job correctly, an architect treats it as a versioned artifact and copies it, unchanged, into the Code node of every other workflow that needs the identical transformation, rather than letting each team reinvent it. AI Agent Studio already applies this same "generate once, publish, reuse across workflows" philosophy to other resources — Document Schemas and Policy Models, for instance, are explicitly generated, published, and then attached to multiple workflows rather than rebuilt each time. Add and Reuse Functions extends that same pattern to hand-written JavaScript logic that doesn't fit any generated-artifact category.

✅ Worked example: a Code node that trims a bloated supplier-invoice response down to InvoiceNumber, SupplierName, and AmountDue is exactly the kind of logic worth writing once — an accounts-payable workflow, a supplier-portal workflow, and an approval-escalation workflow all need that same trimmed shape, and none of them should hand-roll it separately.

🎯 Use this when two or more workflows need identical data-shaping, calculation, or validation logic, and you want a single place to fix a bug once instead of hunting through every workflow that copied it independently.

2. Mechanics: The Sandboxed JavaScript Execution Model ⚙️

To understand why reusable functions in AI Agent Studio look and behave the way they do, it helps to walk through the constraints Oracle has deliberately built into the Code node's runtime. This isn't a general-purpose Node.js environment — it's a narrow, deterministic sandbox, and each constraint below exists to keep enterprise workflows predictable and auditable rather than to limit what a developer can do for its own sake.

  1. Input comes only from the shared workflow context. A Code node never reaches out to an arbitrary source — it reads values that other nodes have already placed into the shared context object, referenced through expressions such as $context.$nodes.<nodeCode>.$output.result, $context.$variables.<name>, or $context.$user.$name.
  2. Only straight-line procedural logic is permitted — JSON structures, arrays and objects, basic math, string and date utilities, and simple type checks. Anything resembling advanced language features is intentionally off the table.
  3. Hard resource ceilings apply. Runtime tops out at a few seconds, iterations cap in the low five figures, code length is limited to roughly two thousand characters, and serialized output is capped at tens of kilobytes. Cross any of these lines and execution simply halts.
  4. The sandbox has no side effects. A Code node can't touch the filesystem, can't log or print, can't make an HTTP or REST call, and can't import an external library or module — every dependency has to already be sitting in context by the time the node runs.
  5. No function definitions, and no mutating the shared context. This is the constraint that trips up most developers arriving from general-purpose JavaScript: you can't define a private helper function and call it from within the same block, and you can't write intermediate values back onto the $context object as a way of "passing them along."
  6. Output is structured and singular. Whatever the node's return statement produces becomes the node's result property, and its shape — array, JSON object, or a JSON object containing an array — is fixed at setup time.
  7. Failures are traceable, not silent. An error surfaces at $context.$error.$errorMessage, the offending node is identified at $context.$error.$nodeCode, and a timeout specifically writes the literal value TIMEOUT into that error message.

💡 Contrasting case: the "no function definitions" rule directly reshapes what "reuse" can mean inside a single Code node — you cannot define a private helper and call it three times within one block. Reuse in AI Agent Studio therefore happens at the node level, through a canonical snippet copied into multiple nodes, not through in-language function composition the way a general-purpose JavaScript developer would instinctively reach for.

3. Real Example: A Code Node Inside a Production Workflow 🏗️

Oracle's own AI Agent Studio guide walks through a workflow built for buyers handling sales-order inquiries — a workflow that lets buyers check order status, shipment tracking, payment status, and order history, and that escalates to a sales representative whenever a request falls outside what it's designed to handle. Buried inside that published workflow is a node named ProcessInput, typed as a Code node, whose entire job is to extract the current user message out of the incoming interaction before the rest of the flow touches it. It's a small, unglamorous step — and that's the point: it's exactly the kind of narrow, single-purpose transformation that belongs in a Code node rather than an LLM prompt, because it's cheap, deterministic, and testable.

Applying that same pattern to a different, equally common enterprise scenario — trimming a Business Object node's output before it reaches a downstream condition or LLM prompt — here's what a reusable Code node looks like in practice:

// Read the invoice list produced by the GetSupplierInvoices node
const invoices = $context.$nodes.GetSupplierInvoices.$output.result;

// Keep only the fields the approval flow actually needs
const result = invoices.map(({ InvoiceNumber, SupplierName, AmountDue }) => ({
  InvoiceNumber,
  SupplierName,
  AmountDue
}));

return result;

Walking through it: the first line pulls the prior node's output out of the shared context — the only channel a Code node is allowed to read from. The .map() call is a permitted array operation that destructures each invoice record down to three fields, discarding the rest of what the underlying business object returned — often a dozen or more attributes an approval agent doesn't need to see. The return statement is what actually populates the node's result property, which a downstream node can then reference as $context.$nodes.TrimInvoiceFields.$output.result.

To add this to a workflow yourself, the navigation is the same whether you're building from scratch or extending something published:

  1. Go to AI Agent Studio, open the Workflows tab, and either select Add for a new workflow or Edit on an existing draft. (Seeded, preconfigured workflows carry a Seeded tag — select Duplicate first if you want to modify one.)
  2. On the workflow canvas, insert a new node where the transformation needs to happen — you can insert before, after, or between existing nodes.
  3. Choose the Code node type from the node palette.
  4. Enter a descriptive name; the node code auto-populates from it. Select an error handler node to define what happens if the function throws.
  5. Paste your JavaScript into the code editor and set the Return Type — array, JSON object, or a JSON object containing an array — to match what your return statement actually produces.
  6. Connect the node into the flow, then Publish the workflow. Published workflows become visible from the Agents and Applications page, reachable from Me > Quick Actions > Show More > AI Agent Studio > AI Agent.

To make it reusable rather than one-off, an architect copies this exact snippet — unchanged, aside from the source node code it reads from — into every other workflow's Code node that needs the same trimmed invoice shape, and treats the snippet itself, stored in version control or an internal wiki page, as the single source of truth. Skip that discipline and three different teams end up writing three subtly different versions of the same mapping, with no shared owner and no changelog when one of them needs a fix.

🎯 Use this when a Business Object node's raw output is too large, too deeply nested, or contains fields you don't want an LLM to see — and therefore never want it to summarize or reason over.

4. Hands-On Lab: Build Your First Reusable Function 🧪

If you've never touched a Code node before, the fastest way to internalize the constraints from Section 2 is to build a small, disposable one yourself. This lab uses a throwaway sandbox workflow — nothing here touches production data, and you can delete the workflow when you're done.

1

Go to AI Agent Studio > Workflows tab > Add. Name it something obviously disposable, like Sandbox_CodeNodeDemo, and pick any family and product you have access to — it doesn't matter for this exercise. Leave the LLM tab on its default and skip Triggers for now.

2

Open the Variables tab and add a workflow variable named rawAmount, type Number, scope Conversation. Then, on the canvas, add a Set Variables node right after Start and assign rawAmount a static test value of 1234.5.

3

Add a Code node after it, named FormatCurrencyDemo. Set its Return Type to JSON object. Paste this into the code editor:

const amount = $context.$variables.rawAmount;
const rounded = Math.round(amount * 100) / 100;
const formatted = "$" + rounded.toFixed(2);

return { displayAmount: formatted };
4

Add a Return node after the Code node, and set its output to $context.$nodes.FormatCurrencyDemo.$output.result.displayAmount. Save the workflow as a draft — you don't need to publish it to test.

5

Open the Debugger for this draft, run it, and inspect the Node Results panel for FormatCurrencyDemo. Expect to see a result object containing displayAmount: "$1234.50". If you see that, your function ran correctly inside the sandbox.

💡 Troubleshooting: the single most common first-timer mistake is forgetting the return statement entirely, or writing a helper function like function round(n) {...} and calling it below — both fail immediately, the first with an empty result, the second with a validation error at save time, because function definitions aren't permitted inside the Code node's execution scope.

That's the whole mechanic. The TrimInvoiceFields example from Section 3 is built on exactly the same three moves you just performed — read from context, transform with permitted operations, return a structured result — just applied to a business-object array instead of a single test variable. Once this pattern feels natural on a throwaway variable, reusing it against real Business Object output, and copying the working snippet into a second workflow, is a small step rather than a leap.

5. Best Practices for Writing Reusable Functions ✅

  1. Keep functions small and single-purpose. The roughly 2,000-character code ceiling isn't just a technical limit — it's a forcing function toward focused, single-responsibility logic that's easy to copy correctly into a new node without silently dropping a line.
  2. Design for the runtime and iteration ceilings up front. Don't loop over an unbounded array pulled from a Vector DB Reader or a large Business Object query; cap or paginate the upstream node before the Code node ever runs.
  3. Treat the function body as a versioned artifact, not tribal knowledge living inside one workflow. Store the canonical snippet somewhere your team actually checks before building a new Code node from scratch.
  4. Never assume a side effect will work. Since the sandbox can't make REST calls or touch the filesystem, any external data the function needs must already be resolved by an upstream node — a Business Object, External REST, or MCP node — before the Code node executes.
  5. Name node codes predictably — TrimInvoiceFields rather than an auto-generated default — so the expressions referencing it stay self-documenting for the next person who opens the canvas.

✅ Building on the invoice-trimming example from Section 3: give the node a descriptive name like TrimInvoiceFields rather than the platform's auto-generated default, so every workflow calling $context.$nodes.TrimInvoiceFields.$output.result is self-explanatory to whoever opens the canvas next, without needing to click into the node itself.

6. Enterprise Rollout at Scale 🏢

Access to AI Agent Studio is already role-gated in a way that matters for governance, and reuse of functions should ride on top of that same access model rather than route around it. Before any custom role can configure agents at all, Oracle requires enabling the Security Console's external application integration profile option, followed by running the Import Resource Application Security Data and Import User and Role Application Security Data scheduled processes, in that sequence, from Navigator > Tools > Scheduled Processes.

  • Governance: require a code review of any Code node before its workflow is published, the same way you'd review a database trigger — a bad function silently corrupts the result object that every downstream node depends on.
  • Ownership: assign a named owner (team or individual) to each canonical function snippet, mirroring how Document Schemas and Policy Models are published once by an owning team and then reused across workflows rather than rebuilt.
  • Templates: maintain a small internal catalog of approved, tested Code node snippets — field-trimming, date formatting, validation — that builders copy from rather than reinvent under deadline pressure.
  • CI-style enforcement: before publishing, step through the workflow in the built-in Debugger — setting breakpoints, inspecting Node Results, and rerunning from a saved run profile — as a mandatory gate rather than an optional check. Go to AI Agent Studio > Workflows > Edit <workflow> > Debug to reach it.
  • Metrics: use the Monitoring and Evaluation tab in AI Agent Studio to track error rates per node, watching specifically for the literal value TIMEOUT surfacing in $context.$error.$errorMessage, which usually signals a function that has drifted out of its original data-volume assumptions as the business grew.

💡 Warning: the Monitoring and Evaluation tab requires an additional permission group beyond basic workflow access — a role needs the read:Generative AI Workflow Execution permission group, plus the AllRowsRestrictedFields security view added under it, granted from the Security Console. Skip this and even your most senior architects won't be able to see the error-rate metrics that would have caught a drifting function early.

7. Common Mistakes ⚠️

  1. Trying to define helper functions inside a Code node. Developers arriving from general-purpose JavaScript instinctively write a small helper and call it inline — the sandbox rejects this outright, and the fix is almost always to flatten the logic into straight-line statements operating directly in the provided scope.
  2. Mutating $context directly. Some builders try to write an intermediate value back onto the context object as a way to "pass it along" to a later node. The only sanctioned path forward is the return statement feeding the node's result property.
  3. Assuming external calls are possible. Because the sandbox has no network access, teams sometimes try to fetch a lookup value mid-function instead of pulling it from an upstream External REST, MCP, or Business Object node — this fails rather than degrading gracefully, and the failure often only surfaces once real production volume hits the node.
  4. Ignoring the character limit until it's too late. Complex logic written and tested outside the platform, in a real IDE with no such ceiling, frequently exceeds the Code node's limit once pasted in, forcing a rushed rewrite instead of a planned, modular one from the start.
  5. Copy-pasting function logic without a canonical source. The single biggest governance failure isn't a broken function — it's five copies of a "working" one that quietly diverge over months of independent edits, with no owner and no changelog telling anyone which version is current.

❓ FAQ

Can a Code node call an external API?

No. The Code node's execution environment is fully sandboxed and has no network access, filesystem access, or ability to import external libraries. Any external data has to be fetched by a different node type — External REST, MCP, or Business Object — earlier in the workflow, then read from context.

What happens if my function takes too long to run?

The node's runtime is capped at a few seconds. If it's exceeded, execution stops and the literal value TIMEOUT is written into $context.$error.$errorMessage, with the failing node identified in $context.$error.$nodeCode.

Can I define my own helper functions and call them from a Code node?

No — function definitions, including recursion, aren't allowed inside the Code node's scope. All logic has to be written as straight-line procedural code that runs directly in the provided execution context.

Is JavaScript the only language available in the Code node?

Typically it's JavaScript, though Python may be available depending on how your platform instance is configured — check with your AI Agent Studio administrator to confirm which languages are enabled in your tenant.

How do I reference a prior node's output from inside a function?

Use a context expression such as $context.$nodes.<nodeCode>.$output.result. A Code node's input can be a context value, a prior node's result, or a workflow variable — never a value fetched live from outside the workflow.

🔗 References & Further Reading

Primary / official documentation (relied on for facts in this post):

Oracle, Oracle Fusion Cloud Applications, and AI Agent Studio are trademarks of Oracle and/or its affiliates. All product names, logos, and brands referenced are property of their respective owners. This post synthesizes and explains publicly available Oracle documentation in original wording; it does not reproduce source text verbatim and is not an official Oracle publication.

📝 Summary

  • Add and Reuse Functions means writing a JavaScript function once inside a Code node and copying that same, tested logic into every workflow that needs it, instead of duplicating it from memory each time.
  • The Code node runs inside a strict, deterministic sandbox: a short runtime ceiling, a five-figure iteration cap, a roughly 2,000-character code limit, no side effects, and no function definitions.
  • Oracle's own published buyer order-inquiry workflow shows exactly where a Code node earns its place — the ProcessInput node extracting the raw user message before anything else touches it.
  • A hands-on sandbox exercise — reading a test variable, transforming it, and returning a structured result — is the fastest way to internalize the constraints before touching real Business Object data.
  • Best practice treats every reusable function as a versioned, owned artifact, not something copy-pasted from memory under deadline pressure.
  • Enterprise rollout should ride on the existing Security Console role model and Debugger infrastructure Oracle already provides, not bypass it — and the Monitoring and Evaluation tab needs its own permission group to be useful.
  • The most common mistakes all trace back to expecting general-purpose JavaScript behavior — helper functions, API calls, context mutation — inside a sandbox that deliberately forbids them.

Hopefully this gives you a solid, practical footing for putting reusable functions to work in your own AI Agent Studio workflows — happy building! 

Comments