22 AI Agents

This chapter provides information on creating, testing, deploying and monitoring agents in your workspace.

Agents are end-to-end agentic applications. Agents are defined through a graph of steps represented by nodes of different types (triggers, agents, guardrails, or tools). Agents can be defined through a no-code visual flow builder and through code via third-party libraries, such as LangGraph.

Oracle AI Data Platform Workbench offers multiple tool templates that can be configured to access your data and fit your use cases. The supported tools are:
  • Custom Tool: The Custom Code tool lets agent developers extend AI Data Platform with their own Python code. You package your tool implementation as a ZIP file, upload it to your workspace, and configure it. The agent calls your code as a tool, with parameters supplied by the LLM at runtime.
  • HTTP: The HTTP Request tool lets your agent call any HTTPS REST API. You configure the request, including method, URL, headers, query parameters, request body, authentication, and optionally, a response optimization step. The agent then invokes the endpoint at runtime. The HTTP request tool is available in both the visual builder and the code builder. In the code builder, the tool is configured through the aidpUtils Python library.
  • Prompt: The prompt tool allows the AI developer to define a parametrized prompt that can be issued to an LLM for their choice. Common use cases for a prompt tool include email drafting tasks, translation tasks, style conversion, git commit message, and code explanations.
  • Remote MCP Server: Agent developers can connect their agents to remote model context protocol (MCP) servers using the Remote MCP Server tool.
  • RAG: The RAG tool lets agents pull relevant external knowledge before generating a response. In AI Data Platform Workbench, the RAG tool queries a knowledge base (23ai Vector Search) and retrieves semantically relevant document chunks. Those chunks are then passed to the agent for response generation.
  • SQL: The SQL tool enables agents to execute SQL queries against structured data sources registered via external catalogs, such as Oracle Autonomous AI Lakehouse, Oracle Autonomous AI Transaction Processing, or Oracle AI Database. The tool is intended for scenarios where the SQL queries are predefined and can be parametrized. The objective is to let an agent assign values to the parameters. This tool is not an NL2SQL tool that generates a SQL query based on a natural language prompt.

    Note:

    The SQL tool only performs queries against data in an external catalog. It does not support data stored in a standard catalog.

Note:

You must attach an AI Compute to your agent before you can test a system tool. If no compute is attached, the Test tab is disabled.

Creating agents in AI Data Platform Workbench generates an agent artifact file (.aflow) in the workspace folder that you select. This file can’t be modified.

Multi-agent Systems and Supervisor Patterns

A multi-agent system is an AI application design in which a user request is handled by multiple cooperating agents instead of one large, all-purpose agent.

Each agent has its own role, instructions, model configuration, memory policy, and allowed tools. The flow defines how the request moves between those agents and how the final answer is produced.

This design is useful when a workflow naturally separates into specialist responsibilities. For example, one agent can retrieve data, another can call an API, another can summarize findings, and a supervisor can decide which specialist to use and combine the results into a single response.

Note:

As a design principle, it's best to start with the smallest agent design that meets the requirements. Add multiple agents when separation of concerns improves reliability, security, maintainability, or observability more than it increases cost and complexity.

Benefits of Multi-agent Systems

Multi-agent systems are best suited for:
  • Specialization: give each agent a focused job, prompt, and tool set instead of one crowded instruction block.
  • Routing and decomposition: let a supervisor interpret the request, split it into subtasks, and choose the right specialist for each subtask.
  • Tool and data isolation: expose sensitive or high-impact tools only to the agents that are responsible for using them.
  • Governance and troubleshooting: make handoffs, tool ownership, memory settings, and failure points easier to inspect.

When to Choose Multi-Agent or Single Agent Designs

A single agent with more tools is often the right first design. It is simpler to test, cheaper to run, and easier to reason about when the task has one clear objective and one permission model. Use a multi-agent design when the workflow benefits from explicit roles, bounded tool access, or a supervisor that can coordinate multiple specialist outputs.

Design Question Use single agents when... Use multi-agents when...
Task shape The request has one main objective and one response stile. The request must be decomposed, routed, verified, or synthesized across specialties.
Tools and data The same instruction set and permission model can safely govern all tools Different agents need different tools, data sources, or access boundaries.
Instructions The prompt remains clear even with all business rules and tool guidance in one place. Instructions are easier to maintain as smaller, role-specific prompts.
Cost and latency You want the shortest path from user message to answer. The reliability, governance, or maintainability benefits justify extra orchestration.
Troubleshooting Failures are simple to debug in one trace. You need explicit handoffs, state isolation, and clearer ownership for each step.

Supported Pattern: Orchestrator/Supervisor

The current canvas experience supports the orchestrator / supervisor pattern. In this pattern, the Chat Trigger receives the user message, optional Guardrails evaluate the input, and a Supervisor Agent acts as the orchestrator for the rest of the flow.

The supervisor should focus on planning, routing, delegation, and final response synthesis. It decides which executor agent should handle a task, sends that executor a scoped instruction, reviews the result, and then either delegates another step or returns the final response. Executor agents should be narrower specialists: they do the assigned work, use their attached tools, and return useful results to the supervisor.

About the Visual Flow Canvas

An agent is assembled by dragging nodes and tool templates from the left palette onto the canvas, then connecting the nodes in the order the request should travel.

Selecting a node opens a configuration panel at the bottom of the screen.


Agent visual builder canvas. The palette, mode selector, and zoom control are labelled and highlighted.

Canvas Element Purpose
Chat Trigger Entry point for a user message. In the screenshot this node is labeled Message and typically sits at the top of the flow.

A chat trigger node can be connected to an agent, a supervisor agent, or a guardrails node. Only one chat trigger is allowed per canvas.

Guardrails Optional policy and safety layer placed before or after model work. The guardrails policies include PII, content moderation, and prompt injection detection.

A guardrails node can filter traffic between a chat trigger and an agent node, between a supervisor and executor agents, or between agent and tool nodes. We recommend a single guardrails node between the chat trigger and the agent node.

Supervisor Agent The orchestrator. It receives the user request, decides which executor agent or tool should handle each task, and coordinates the final answer.

Only one supervisor agent is allowed in a canvas.

Agent An executor agent. Each executor should have a clear specialty, such as data retrieval, API lookup, summarization, or document question answering.

Use an agent / executor agent for a single agent system.

Tool templates Reusable capabilities that can be attached to individual executor or supervisor agent. Tool templates include SQL, RAG, Prompt, HTTP, Remote MCP server, and Custom Tool.
Development / Playground Mode selector above the canvas. Development is used while editing the agentic system; Playground is used to initiate test sessions and inspect agent behavior.

Playground requires that an AI compute is attached to your agent.

Zoom control Canvas zoom selector. The screenshots show 60 percent and 90 percent zoom levels.

Create an Agent

You can create an agent in a workspace where have you have Manage permission.

  1. On the Home page, navigate to your workspace.
  2. Click on Agent Flows in the left navigation pane.
  3. Click Create agent icon Create Agent or click Create in the top right.

    Agents page is displayed. Agents in the left navigation pane is highlighted. The Create Agent Flow icon and Create button are highlighted.

  4. Provide a name and description for the agent.
  5. For Agent flow authoring mode, select Visual builder.

    Create Agent project dialog is displayed. The Visual builder radial option is highlighted.

  6. Optional: From the AI Compute drop-down menu, select a compute to use for the agent.
  7. Click Create. Start building your agent by dragging a node from the palette to the canvas.

    Note:

    Start your first agent build simple: one Chat Trigger, one executor Agent. Add complexity after a successful run of your first build, such as guard rails, additional tools, or even multi-agent system design.

Add Chat Trigger and Agent to Visual Builder Canvas

Your first step after creating an agent with the Visual Builder should be to add a chat trigger and a supervisor agent.

The trigger receives the user message. The supervisor interprets the request, plans the work, and delegates to executor agents or tools. You can drag nodes in the canvas, configure them, and connect them later.
  1. Navigate to your agent in your workspace.
  2. Click and drag a Chat Trigger from the palette to the canvas. The node appears on the canvas as a Message.
  3. Click and drag a Supervisor Agent to the canvas.

    Visual builder canvas is displayed with a chat trigger and supervisor agent node added.

  4. Click and drag the connector handle on the Chat Trigger node to connect it to the Agent node.
The Supervisor Agent badge displays how many agent and tools are connected. In a new build, the Supervisor Agent shows: Agents (0) Tools (0).
Chat trigger and supervisor agent on the Visual Builder canvas. The badge underneath the supervisor agent states 'Agents (0) Tools (0)'.

Configure a Supervisor Agent

You need to configure a supervisor agent added to your Visual Builder canvas with instructions outlining the supervisor role.

You configure a supervisor agent with the following fields.
Visual builder canvas is displayed. The supervisor agent is select and displaying the Configuration tab.

Field Configuration
Agent Name Provide a descriptive name for your supervisor agent. A good, descriptive name will be beneficial when debugging the system behavior through traces and logs.
Agent Description Provide a description of the agent purpose, role, and general behavior. Useful for documentation purposes.
Region Choose the region where the OCI Generative AI model used by Supervisor Agent is hosted. See Generative AI Models by Region.
Model Choose the OCI Generative AI service model used by the supervisor. The dropdown lists the models available in the region you selected.
Agent instructions Describe the supervisor role, routing rules, delegation policy, tool-use expectations, and final response format.
  1. Navigate to the agent in your workspace.
  2. Click the Supervisor Agent node on your canvas.
  3. Provide a meaingful name and description for your supervisor agent.
  4. Enter the region and model for the OCI Generative AI service model used by the supervisor.
  5. Provide the agent instructions for your Supervisor Agent.

Suggested Supervisor Instructions

You should use the Instructions field for a Supervisor Agent to make the supervisor responsible for orchestration, not for doing every task itself.

Keep the instructions concrete so routing decisions are predictable. See the following for an example of a set of Supervisor instructions:

You are the supervisor for a multi-agent system.

Responsibilities:
- Understand the user's request and break it into subtasks.
- Select the most appropriate executor agent or tool for each subtask.
- Do not perform specialist work yourself when an executor agent is available.
- Ask for clarification only when required information is missing.
- Combine executor outputs into a concise final answer.
- Mention important assumptions, limits, or failed tool calls in the final answer.

Routing rules:
- Use the SQL agent for structured data questions.
- Use the HTTP agent/tool for external API lookups.
- Use the RAG agent/tool for document or knowledge-base questions.
- Use the prompt tool for reusable prompt-only transformations.

Configure Supervisor Agent Memory and State Isolation

The Memory tab for a Supervisor Agent controls how much conversation and tool-output history is available to the supervisor and how much context is shared with executor agents.

You configure the memory and isolation state for your Supervisor Agent with the following fields.
Visual builder canvas is displayed. A supervisor agent is selected and the Memory tab is displayed.

Field Configuration
Enable Agent Memory Enable when users need multi-turn continuity. Disable for isolated, one use tasks.

This field cannot be disabled for Supervisor Agents.

Limit conversation history Enable to truncate the LLM context window after the specified limit is hit. Disable to show the full history.
Truncation configuration If Limit conversation history is enabled, use this field to set the conditions for truncating the the context window.
Options are:
  • Keep last N messages
  • Token budget
  • Both
Maximum Message Limits and Token Budget One or both of these options is displayed, depending on your choice for Truncation Configuration.

Default values are 20 messages and 5000 tokens. We recommend starting with moderate values and adjusting as needed.

State Isolation for Executor Agents Select Stateless, Private, or Shared.
  • Stateless: Each executor agent sees only the task assigned by the supervisor. No history is carried over between calls. Select this if you want the strongest isolation and least cross-agent context.
  • Private: Each executor agent sees only its own past interactions. It cannot see other executor agents of the original user conversation. Select this if your executor needs continuity across its own tasks but should not share context with other agents.
  • Shared: Executor agents can see full conversation history across agents and users. All agents work from one shared context. Select this if you need broad context sharing and have reviewed privacy and prompt-injection risks.
  1. Navigate to the agent in your workspace.
  2. Click the Supervisor Agent node on your canvas.
  3. Click the Memory tab.
  4. Choose whether to enable Limit conversation history. Select a Truncation Configuration and set limits, if enabled.
  5. Choose an option for State Isolation for Executor Agents.

Models Parameter Tab

The model parameters tab lets you configure model-specific parameters that are available for the selected model.

Model parameters can be configured separately for supervisor and executor agents. Parameters you can use include temperature, top K, top P, and frequency penalty.

Note:

Only a subset of models exposes configurable parameters. Furthermore, the parameters vary across model families.

Visual builder canvas is displayed. A supervisor agent is selected and the model parameters tab is displayed.

Add Guardrails to an Agent

You can add additional layers of protection to your agents by adding one or more guardrail nodes to your canvas.

By default, no guardrails are applied to your agentic systems beyond what the selected model provider is offering out-of-the-box for their models. Guardrails can be placed between the Chat Trigger and the Supervisor Agent so policies are applied before a request reaches the supervisor agent and before the supervisor agent returns a response to the caller.
Guardrail Options When to Use
Personal identifiable information (PII)
  • Input and Output tabs
  • Checkboxes for Person, Address, Telephone number, Email
Use when the flow must block or mask sensitive personal data before or after model processing.
Content moderation prevention Input and Output rows with Block, Inform, and Allow options. Use to define how the flow handles hate, sexual, violent, toxic, derogatory, or harassing content.
Prompt Injection detection Input row with Block and Allow options. Use to reduce the chance that malicious instructions override the system or agent instructions.
For more information on guardrail settings, see Guardrails.
  1. Navigate to the agent in your workspace.
  2. Drag a Guardrails node from your palette to your canvas. Place it between your Chat Trigger node and Supervisor Agent node.
  3. Delete the connection between Chat Trigger and Supervisor Agent by hovering over the connection and clicking the red X.

    Visual builder canvas is displayed with a chat trigger node, supervisor agent node, and guardrails node. An arrow line with white X in a red circle connects the chat trigger and supervisor node.

  4. Click and drag the connector handle on the Chat Trigger to the Guardrail node. Then click and drag the connector handle from the Guardrail node to the Supervisor Agent.
  5. Click the Guardrail node to open the Configuration page.
  6. Configure the guardrails to select the desired action for input and output checks.

Add Executor Agents and Tools to an Agent

You can add executor agents to tools to perform specialized work for the supervisor agent.

In the example below, the Supervisor Agent delegates to AGENT_1 and AGENT_2. AGENT_1 is connected to SQL_1 and HTTP_1 tools.
Visual builder canvas is displayed. A chat trigger node is connected to a guardrail node, which is connected to a supervisor node. The supervisor node is connected to two agent nodes, AGENT_1 and AGENT_2. AGENT_1 is connected to two tool nodes, SQL_1 and HTTP_1.

  1. Navigate to the agent in your workspace.
  2. Drag an Agent node from the palette to your canvas. Agent nodes should be placed below a Supervior Agent.
  3. Drag Tools from the palette to your canvas.
  4. Click and drag the connector handle on your Supervisor Agent to connect to the Agent nodes.
  5. Click and drag the connector handle on your Agents to connect to the Tool nodes.

Executor Agent Configuration

Agent nodes can be configured by modifying settings on their Configuration, Memory, and Model tabs to help you define the purpose of each agent.

Agents should be configured narrowly, given a specific function and goal, so the supervisor agent can route work reliably.
Visual build canvas. A chat trigger node is connected to a supervisor agent, which is connected to two agent nodes, AGENT_1 and AGENT_2. AGENT_1 is connected to two tool nodes, SQL_1 and HTTP_1.

Table 22-1 Agent Configuration Tab

Field Configuration
Agent Name Best practice is to name each executor agent according to its specialty, such as SQL_AGENT, DOCUMENT_AGENT, API_AGENT, or SUMMARY_AGENT.

The name of each executor agent is visible to the supervisor agent, so use descriptive names.

Agent Description Provide a detailed description of each executor agent. The description of each executor agent is visible to the supervisor agent.
Region Choose the region where the OCI Generative AI model used by the Agent is hosted. See Generative AI Models by Region.
Model Choose the OCI Generative AI service model used by the agent. The drop-down menu lists the models available in the region you selected.

Select a model that fits the executor task. Executor agents don't need to use the same model as the supervisor agent.

Agent instructions Describe exactly what the executor should do, what tools it may use, and what output structure it should return.

Executor Agent Memory Tab

In the case of executor agents connected to a supervisor agent, the memory for executors is configured in the supervisor node and applied to all executor agents.

Field Configuration
Enable Agent Memory Enable when users need multi-turn continuity. Disable for isolated, one use tasks.
Limit conversation history Enable to truncate the LLM context window after the specified limit is hit. Disable to show the full history.
Truncation configuration If Limit conversation history is enabled, use this field to set the conditions for truncating the the context window.
Options are:
  • Keep last N messages
  • Token budget
  • Both
Maximum Message Limits and Token Budget One or both of these options is displayed, depending on your choice for Truncation Configuration.

Default values are 20 messages and 5000 tokens. We recommend starting with moderate values and adjusting as needed.

State Isolation for Executor Agents Select Stateless, Private, or Shared.
  • Stateless: Each executor agent sees only the task assigned by the supervisor. No history is carried over between calls. Select this if you want the strongest isolation and least cross-agent context.
  • Private: Each executor agent sees only its own past interactions. It cannot see other executor agents of the original user conversation. Select this if your executor needs continuity across its own tasks but should not share context with other agents.
  • Shared: Executor agents can see full conversation history across agents and users. All agents work from one shared context. Select this if you need broad context sharing and have reviewed privacy and prompt-injection risks.

Executor Agent Model Parameters Tab

The model parameters tab lets you configure model-specific parameters that are available for the selected model.

Note:

Only a subset of models exposes configurable parameters. Parameters also vary across model families.

Examples of parameters include temperature, top K, top P, and frequency penalty. Model parameters can be configured separately for supervisor and executor agents.

Suggested Executor Instructions

You are the SQL executor agent.

Responsibilities:
- Translate the supervisor's task into safe SQL tool usage.
- Use only the SQL tools attached to this agent.
- Return a concise answer plus any important query assumptions.
- Do not invent data. If the tool cannot answer, say what is missing.
- Return structured output with: answer, evidence, assumptions, and follow_up_needed.

Checklist for Agents through Visual Builder

Use this list as a guide to ensure you've included and configured every necessary component for an agent built using the Visual Builder.

Build Checklist

  • The agent has exactly one expected entry point: Chat Trigger / Message.
  • Guardrails are connected in the intended position and enabled where required. We recommend inserting guardrails between the trigger message and the agent.
  • The Supervisor Agent has a selected region, selected model, and orchestration instructions. Same for executor agents.
  • Configure memory of the multi-agent system in the Memory tab of the Supervisor agent. Select executor state isolation that matches the privacy and continuity requirements.
  • Each executor Agent has a clear specialty and narrow instructions.
  • Each tool is attached only to the agent that should use it.
  • No node is disconnected.
  • An AI compute is attached to the agentic system to test individual tools and for running the Playground experience.

Table 22-2 Common Issues

Issue Likely Cause Suggested Action
Supervisor does not call an executor Supervisor instructions are too vague or no executor is connected. Add explicit routing rules and confirm the executor node is connected to the supervisor.
Executor returns broad or off-topic answers Executor instructions are too general. Make the executor role narrower and define the required output structure.
Tool is not used Tool is disconnected or attached to the wrong agent. Check the tool connection and the agent tool count badge.
Guardrail does not fire Guardrail section is configured but not enabled. Open the guadrails node and confirm the section toggle is on.
Context leaks across agents State isolation is set to Shared or memory is broader than intended. Use Stateless or Private isolation for stricter separation.
Follow-up questions lose context Memory is disabled or truncation is too aggressive. Enable memory and adjust the maximum message limit.

Agent Flows Through Code

You can bring your own LangGraph code base to AI agents in Oracle AI Data Platform Workbench or create a brand new LangGraph agent directly on the platform through the agent coding experience.

You can use the AI Data Platform Workbench utility Python library aidputils to configure your foundational model and import system tools to your agent. For aidputils API reference, see Aidp-utils API for Oracle AI Data Platform Workbench.


Agent SkillsTest open on the Development tab.

You create an agent through code by either uploading an existing code file or creating code files directly in your agent through the inline editor.

The inline code editor in agents supports the following code file types:
  • Python (.py)
  • JSON
  • TXT
  • CSV
  • PSV
  • SH
  • Folder

You can see and navigate through the available code files by clicking the file selector drop-down list.


Agent page with the file selector drop-down list open and highlighted

Entry and Dependency Files

Entry files are code files that have the class with setup and invoke methods expected for an agent defined as code. Oracle AI Data Platform Workbench requires you to set an entry file for agents through code.

Dependency files are files that include third-party libraries required by your agent defined as code. Dependency files are typically requirements.txt files that contain a list of the required third-party libraries.

Note:

Third-party libraries are installed when you test your code in the editor by clicking the Play button or when you test the agent through the Test tab. We recommend install third-party libraries by testing the code first. Errors during installation of the libraries are displayed in the output cell.

Agent Class

AgentBasic is a template class for setting up and invoking a simple conversational agent using a stateful LangGraph workflow. It demonstrates the structure required for minimal agent development with two main methods:

  • setup(): Initializes the agent workflow and defines the graph.
  • invoke(user_query, **kwargs): Runs the agent on a user message and returns the response.

It can be directly run and tested using a main() function before integration into a larger system.

Definition

class AgentBasic:
    def __init__(self) -> None:
        self.graph = None
    def setup(self) -> None:
        self.graph = StateGraph(MessagesState)
        self.graph.add_node(mock_llm)
        self.graph.add_edge(START, "mock_llm")
        self.graph.add_edge("mock_llm", END)
        self.graph = self.graph.compile()
        system_prompt = "Be a helpful assistant."
    async def invoke(self, user_query: str, **kwargs):
        user_message = HumanMessage(content=user_query)
        messages = {"messages": [dict(user_message)]}
        try:
            return self.graph.invoke(messages)
        except Exception as e:
            import traceback
            logger.error(f"Exception while calling invoke {e}", exc_info=True)
            print("Stack trace:\n", traceback.format_exc()) 

Test Invocation

This test invocation is ideal for initial functional testing.

Note:

Include a main entry point for stand-alone testing.
import asyncio

async def main():
test_agent = AgentBasic()
test_agent.setup()
result = await test_agent.invoke("Hi there")
print("Agent response:", result)
if __name__ == "__main__":
   asyncio.run(main())
How it works:
  • The script creates an agent, sets it up, and sends a sample user message.
  • The agent responds ({"messages": [{"role": "ai", "content": "hello world"}]} in this example).

Usage Guide

Create an Agent class with the setup and invoke methods.

setup() Initializes the agent workflow agent.setup()
invoke() Runs the agent with a user message await agent.invoke("Your question")
  • Asynchronous: invoke() is an async method; use it with await or run in an async loop.
  • Testing: The included main() guard (if __name__ == "__main__":) makes it easy to test the agent before deployment.

Build an Agent Through Code by Upload

You can build your end-to-end agent application with existing code by uploading your LangGraph code base.

Oracle AI Data Platform Workbench supports LangGraph version 1.0.1.

Note:

You can upload individual files and folders up to a maximum of 500 files, each file can have a maximum size of size of 500MB. The upload is limited to a total size of 5GB.
  1. Navigate to your agent in your workspace. Click the agent name.
  2. Click Upload.

    Agent page with Upload icon highlighted

  3. Drag and drop a file into the pane or click to browse to select a file.
  4. Click Upload.

Build an Agent Through Code by Creating New Code

You can build your end-to-end agent application with existing code by creating code directly in your agent through the code editor.

Code editor supports the following file types:
  • Python (.py)
  • JSON
  • TXT
  • CSV
  • PSV
  • SH
  • Folders
  1. Navigate to your agent in your workspace. Click the agent name.
  2. Click Add new file.

    Agent page with Add new file icon highlighted

  3. Enter a name for your code file.
  4. Select a file type from the drop-down list.
  5. Click Create.

Set an Entry File for Agents through Code

Your AI agent through code requires an entry file that has the required class, setup, and invoke methods expected for your agent.

  1. Navigate to your agent in your workspace. Click the agent name.
  2. In the Code Editor tab, locate the entry file in the left navigation pane. If the file does not exist, you can upload it by clicking Upload or create it by clicking Add new file.
  3. Right-click the entry file and click Set entry file. You can also select the file and click the Set entry file button in the top right of the code editor.

    Agent Code Editor open with file selected in left pane. Set entry file is highlighed in the right-click menu and the top right of the code editor

Set a Dependency File for Agents through Code

You need to set a dependency file for agents flows through code that contains any third-party libraries your code is dependent on.

  1. Navigate to your agent in your workspace. Click the agent name.
  2. In the Code Editor tab, locate the dependency file in the left navigation pane, typically requirements.txt. If the file does not exist, you can upload it by clicking Upload or create it by clicking Add new file.
  3. Right-click the dependency file and click Set dependency. You can also select the file and click the Set dependencies file button in the top right of the code editor.

    Agent code Code Editor tab open with a file selected. Set dependency and Set dependencies file are highlighted

Test Agent Code

You can test the code used for your agent from the Test tab to validate and debug code.

You must have an AI compute attached to your agent to test.
  1. Navigate to your agent in your workspace. Click the agent name.
  2. Click the Playground tab.

    Agent page open and cropped to show only the tabs at the top of the page. Playground tab is highlighted.

  3. Click Play to test the selected code file.

    Agent Code Editor tab open with AI compute, Play button, and test Output frame highlighted

An output cell in the lower half of the code editor window displays the outputs of print or logging statements in your code. Errors are also displayed in the output cell.

Agent Skills in Coding Experience

Agent Skills let an agent discover and use task-specific instructions, reference files, templates, assets, and optional executable scripts without hardcoding that domain knowledge into the agent’s instructions.

A skill is stored as a folder in your agent code base. Each skill has a required SKILL.md file that describes what the skill does and how the agent should use it. A skill can also include supporting files such as schemas, examples, prompts, templates, assets, or scripts.

For more information, see Agent Skills Overview.

Agent skills support a progressive disclosure model:
  1. The agent discovers that a skill exists.
  2. The agent activates the skill only when it is relevant.
  3. The agent loads additional files from the skill folder only when needed.
  4. The agent may run an explicitly declared skill entrypoint, if the skill allows it.

When to use Agent Skills

You should use Skills when you want to package reusable agent capabilities such as:
  • Domain-specific instructions
  • Coding or data analysis workflows
  • SQL generation guidance
  • Business process playbooks
  • File templates
  • Schema references
  • Reusable scripts for safe calculations, transformations, or lookups
Skills are useful when the agent should have access to specialized and re-usable knowledge, but you do not want to place all that knowledge directly in the agent prompt.

How Skills Work at Runtime

At runtime, the host application determines which skill directories are available, such as project-level and user-level skill folders. The platform loads each skill’s metadata from SKILL.md and builds a catalog keyed by skill name.

The agent can then use skill-related tools:

Tool Purpose
activate_skill(name) Loads the skill instructions from SKILL.md.
list_skill_files(name, path) Lists files available inside a skill folder.
load_skill_file(name, path) Loads a supporting file from the skill folder.
run_skill_entrypoint(name, entrypoint, args_json, timeout_seconds) Runs an explicitly declared Python entrypoint, if allowed by the skill.

Some environments may also embed a summary of available skills directly into the system prompt. In that setup, the agent can discover available skills from the prompt, then use activate_skill when it needs the full instructions.

Skill Folder Structure

A skill uses an Agent Skills-style folder layout:

<skills_dir>/
	some-skill/
		SKILL.md
		references/
		...
		scripts/
		...
		assets/
		...

Only SKILL.md is required. The other folders are optional.

Folder or File Required Purpose
SKILL.md Yes Main skill metadata and instructions.
references/ No Supporting documentation, schemas, examples, or templates.
scripts/ No Python scripts that may be run only when explicitly declared as entrypoints.
assets/ No Static assets used by the skill.

Writing SKILL.md

Each skill must include YAML frontmatter at the top of SKILL.md, followed by Markdown instructions.

Basic Example

---
name: sql-helper
description: Helps the agent write safe SQL queries using project schemas.
license: internal
compatibility: "agent-platform"
metadata:
  owner: data-platform
  domain: analytics
allowed-tools: "analyzeQuery inspectSchema"
---

# SQL Helper

Use this skill when the user asks for SQL generation, query review, or schema-aware analysis.

Before writing SQL:
1. Inspect the relevant schema files in `references/`.
2. Prefer explicit column names.
3. Avoid destructive statements unless the user explicitly asks for them and the environment allows them.

Table 22-3 Supported Frontmatter Fields

Field Required Description
name Yes Unique skill name used by the catalog and tools.
description Yes Short description used for discovery and routing.
license No License or usage policy for the skill.
compatibility No Compatibility note for supported runtimes or platforms.
metadata No String-to-string metadata map.
allowed-tools No Space-separated list of tools this skill permits.
entrypoints No List of executable entrypoints declared by the skill.

Adding Supporting Files

Supporting files let a skill keep detailed content outside the main instructions. This keeps SKILL.md focused while still giving the agent access to richer context. For example:

skills/
	sql-helper/
		SKILL.md
		references/
			warehouse_schema.md
			query_style_guide.md
			examples.md

The agent can inspect these files with:

list_skill_files("sql-helper", "references")
load_skill_file("sql-helper", "references/warehouse_schema.md")
Use supporting files for content such as:
  • Database schemas
  • API examples
  • Prompt templates
  • Style guides
  • Domain glossaries
  • Step-by-step playbooks
  • Test cases or examples

Creating an Executable Skill

A skill can optionally expose reusable executable behavior through run_skill_entrypoint. This is intended for controlled operations such as calculations, transformations, validation, or fetching structured data.

Executable skills must meet two requirements:
  1. The skill must include run_skill_entrypoint in allowed-tools.
  2. The script must be explicitly declared in the entrypoints section of SKILL.md.

Example Executable Skill

skills/
	statistics-helper/
		SKILL.md
		scripts/
			summarize_numbers.py

SKILL.md

---
name: statistics-helper
description: Computes basic summary statistics for numeric data.
allowed-tools: "load_skill_file list_skill_files run_skill_entrypoint"
entrypoints:
  - name: summarize_numbers
    script: scripts/summarize_numbers.py
    func: run
    description: Returns count, min, max, mean, and median for a list of numbers.
---

# Statistics Helper

Use this skill when the user asks for basic descriptive statistics.
scripts/summarize_numbers.py:
from statistics import mean, median

def run(*, values: list[float]) -> dict:
    if not values:
        raise ValueError("values must not be empty")

    return {
        "count": len(values),
        "min": min(values),
        "max": max(values),
        "mean": mean(values),
        "median": median(values),
    }
Example invocation:
run_skill_entrypoint(
  name="statistics-helper",
  entrypoint="summarize_numbers",
  args_json="{\"values\": [10, 20, 30, 40]}",
  timeout_seconds=10
)
The runner returns structured output that includes exit_code, stdout, stderr, and a best-effort parsed result when the script prints or returns JSON.

Rules for Executable Entrypoints

Executable entrypoints are intentionally constrained. The platform only runs Python files that are:
  • Located under the skill’s scripts/ directory
  • Declared in the skill’s entrypoints frontmatter
  • Allowed by the skill’s allowed-tools setting

The platform does not provide general-purpose arbitrary script execution. Scripts that are not declared in SKILL.md are not runnable.

The script runner uses a timeout, defaults to 10 seconds, runs Python with isolated-mode behavior, and applies path restrictions. However, subprocess-based execution is not a full operating system sandbox. For production use, higher isolation such as containers, restricted filesystems, or network controls should be considered.

Tool Permissions with allowed-tools

allowed-tools acts as a skill-level permission gate. For a documentation-only skill, you may allow only file-reading tools:

allowed-tools: "load_skill_file list_skill_files"

For a skill that can execute declared scripts, include run_skill_entrypoint:

allowed-tools: "load_skill_file list_skill_files run_skill_entrypoint" 

Do not add run_skill_entrypoint unless the skill genuinely needs executable behavior.

How to Let Your Agents Discover and Use Skills

To supplement your agent with skills, you must instantiate a skill catalog, a skill middleware and convert skills into tools using the following objects from the aidpUtils library:

Tool Purpose
discover_skill_catalog Determine default skill search locations (project + user) Build a SkillCatalog from discovered directories
SkillMiddleware Append available skills summary and routing rules to system prompt.

Provide factory helpers for workspace-driven middleware construction.

make_skill_tools This method returns the skill discovery tools – activate_skill, list_skill_files, load_skill_file, and run_skill_entrypoint. These tools can be used by the agent to activate and run different skills.

Here’s an example of what your entry file would include:

from aidputils.agents.skills.discovery import discover_skill_catalog
from aidputils.agents.skills.middleware import SkillMiddleware
from aidputils.agents.skills.tools.factories import make_skill_tools
...
class SchoolGradeAgentWithEmbededSkills:
	...
	def init(self) -> None: 
		...
		self.catalog = discover_skill_catalog(skill_folder_whitelist=None)
		self.skill_middleware = SkillMiddleware(self.catalog)
		self.tools = make_skill_tools(self.catalog)

You can debug your skills catalog by adding this logger statement to your code. This will print every skill discovered in the skills catalog:

for info in self.catalog.list():
	logger.info("skill_id=%s name=%s desc=%s root=%s skill_file=%s", info.skill_id, info.name, info.description, info.root_dir, info.skill_file)

Skill Precedence

The platform can load skills from multiple locations, such as project-level and user-level directories. The catalog aggregates those locations into a single name-keyed list of skills.

When multiple stores contain a skill with the same name, precedence determines which one is used. Later stores override earlier ones, which allows a host application to control whether user-level skills, project-level skills, or workspace-level skills take priority.

Skill Authoring Best Practices

Keep SKILL.md focused

Use SKILL.md for the core instructions the agent needs immediately after activation. Put long schemas, examples, and reference material in references/.

Write clear descriptions

The description field is used for discovery. Make it specific enough for the agent to know when to activate the skill.

Good:
description: Helps generate BigQuery SQL using the finance warehouse schema.
Less useful:
description: Helps with data.

Use explicit entrypoint names

Entrypoint names should describe the operation clearly:
entrypoints: 
   - name: validate_query 
   - name: summarize_numbers 
   - name: transform_csv
Avoid vague names such as:
entrypoints: 
   - name: run 
   - name: do_it 

Return structured results

Executable scripts should return JSON-serializable results whenever possible. This makes the output easier for the agent to inspect and use.

Avoid unnecessary execution

Prefer instructions and reference files when possible. Use executable entrypoints only for operations that genuinely require code.

Add a New Skill

You can add new Agent skills by creating a new folder inside the skills directory and adding the necessary files and folders.

  1. Create a folder under the skills directory: .agents/skills/<skill-name>/.
  2. Add a SKILL.md file with required frontmatter.
    ---
    name: <skill-name>
    description: <what this skill helps the agent do>
    ---
    
  3. Write the skill instructions in Markdown below the frontmatter.
  4. Add optional supporting files under:
    references/
    assets/
    scripts/
    
  5. If the skill is executable, add run_skill_entrypoint to allowed-tools, declare the entrypoints in SKILL.md, and place the Python implementation under scripts/.

Add a New Executable Capability to an Existing Skill

You can add a new executable operation to an existing skill to expand the capabilities of SKILL.md.

  1. 1. Add a Python file under the skill’s scripts/ directory.
    .agents/skills/<skill-name>/scripts/my_operation.py 
  2. 2. Implement a run(...) function.
    def run(*, input_text: str) -> dict:
        return {
            "length": len(input_text),
            "uppercase": input_text.upper(),
        }
    
  3. 3. Add a matching entrypoint to SKILL.md.
    allowed-tools: "load_skill_file list_skill_files run_skill_entrypoint"
    entrypoints:
      - name: my_operation
        script: scripts/my_operation.py
        func: run
        description: Processes input text and returns structured output.
    
  4. 4. Test the entrypoint with a JSON object as arguments.
    {
      "input_text": "hello"
    }
    

Agent Skills Troubleshooting

If you encounter issues with implementing Agent Skills, check this list for help resolving your problem.

The agent does not see my skill

Check that:
  • The skill folder is located under a configured skills directory.
  • The folder contains SKILL.md.
  • SKILL.md has valid YAML frontmatter.
  • The frontmatter includes both name and description.

The agent activates the wrong skill

Check for duplicate skill names across skill directories. If two skills have the same name, catalog precedence determines which one is used.

A supporting file cannot be loaded

Check that:
  • The file is inside the skill folder.
  • The path does not include traversals such as ../.
  • The file is not hidden.
  • The file is not excluded, such as __pycache__ or .pyc.

An entrypoint will not run

Check that:
  • run_skill_entrypoint is included in allowed-tools.
  • The entrypoint is declared in SKILL.md.
  • The script path is under scripts/.
  • The script is a .py file.
  • The function name in func exists in the script.
  • The arguments are a valid JSON object.

An entrypoint times out

Increase timeout_seconds only if the operation is expected to take longer. For long-running or resource-intensive operations, consider moving the operation to a dedicated service or more isolated execution environment.

Example: Complete Agent Skill

This example demonstrates what a complete agent skill would look like after implementation.

Folder Structure

skills/
	customer-support-reply/
		SKILL.md
		references/
			tone_guide.md
			refund_policy.md
			escalation_rules.md

SKILL.md

---
name: customer-support-reply
description: Helps draft customer support replies using the company tone guide and policy references.
allowed-tools: "load_skill_file list_skill_files"
metadata:
  owner: support-operations
  domain: customer-support
---

# Customer Support Reply

Use this skill when the user asks for help drafting, reviewing, or improving a customer support response.

Workflow:

1. Identify the customer’s issue.
2. Load the relevant policy file from `references/` if needed.
3. Draft a clear, empathetic response.
4. Avoid making commitments that are not supported by policy.
5. Recommend escalation when the request matches the escalation rules.
This skill does not run code. It gives the agent structured instructions and optional policy files that can be loaded only when relevant.

Agent Testing

You can test your agents to preview and debug their output. You can also create and manage testing sessions to explore different testing scenarios for your agents.

The first step to test an agent is to attach your agent to an AI compute. The action of attaching an agent pushes a copy of your agent to an AI compute. As long as your agent is attached to an AI compute, any changes you made to your agent are propagated to the attached compute every time you click on on the Test button.

After you click the Test button, you are taken to the test playground.


Agent page open to Test Playground. Chat, Traces and Spans, and Explorer panes are highlighted

The test playground has the following components:
  • A chat window where you can initiate a session and start chatting with the agent, or resume an existing session
  • A graph-based representation of the agent
  • A panel showing a tree of traces and spans generated during the session
  • A traces and spans explorer panel that displays traces and spans attributes, input/output. The Details tab includes IDs, start and end time, execution time, while the Events tabs highlight any errors during the execution.

The Playground lets you interact and test each agent independently if you wish to do so. By default, the supervisor agent is selected, but you can choose to chat with and test each executor agent independently. This allows you to simulate the behavior of a supervisor agent issuing requests to executor agents. To do this, you select the agent you want to test in the drop-down menu in the chat window.

Traces and spans are displayed in the central panel as soon as you create your first message. Each task corresponds to a different user message. You can click on the left caret to expand the trace and inspect the spans.

Test your Agents in the Playground

You can test visual builder and LangGraph-based agents from the Test playground to validate and debug your agents.

You must have an AI compute attached to your agent to test. You can add a new AI compute cluster by following Create an AI Cluster for an Agent or attach an existing AI compute cluster by following Attach an Existing AI Cluster to an Agent.
  1. Navigate to your agent in your workspace. Click the agent name.
  2. At the top of the canvas, click Playground. It may take several seconds to push the agent to your attached compute.

    Top of the agent canvas with Playground button highlighted

Your agent is displayed in the test playground.

Create an Agent Test Session

You can create a test session to initiate a new conversation with your agent.

All sessions created in the test playground target the agent are hosted on the attached compute. Once a session is created, it can be resumed later.
  1. Navigate to your agent in your workspace. Click the agent name.
  2. At the top of the canvas, click Playground
  3. In the session selector, click Create a session icon Create a session.

    Agent open with the Playground tab selected. The Create Test Session button and Session drop-down menu are both highlighted.

  4. Start a dialog with your agent by entering a query in the chat box.

    Agent test playground chat session page with the chat box highlighted

Resume an Agent Test Session

You can resume agent test sessions you have previously created.

Note:

You can only resume sessions that you created.
  1. Navigate to your agent in your workspace. Click the agent name.
  2. At the top of the canvas, click Playground
  3. From the session drop-down, select a previous session.

    Agent test playground with chat pane highlighted. Multiple sessions are displayed.

  4. Resume your dialog with your agent by entering a query in the chat box.

Delete an Agent Test Session

You can delete test sessions for agents hosted on the attached AI compute and sessions that have been created on a deployed agent.

  1. Navigate to your agent in your workspace.
  2. Click the Sessions tab.

    Agent Sessions tab open with Sessions tab highlighted

  3. Next to the session you want to delete, click Actions three dot icon Actions then click Delete.

    The Agents Session tab with the Actions menu open for a Session ID and the Delete action highlighted

  4. Click Delete.

About Agent Tools

Oracle AI Data Platform Workbench supports tool templates that can be configured to access your data and fit your use cases.

Agents support configurations that consist of a single agent that can interface with one or more tools. Oracle AI Data Platform Workbench offers three tool templates that can be configured for use through visual flows or code:

  • Custom Code: The Custom Code tool allows AI developers to implement their tool using Python. Developers package their tool in a ZIP, upload it to their workspace, and configure it as a node in their agent. Custom Code tools are intended for cases where built in tools don't provide the integration they need.
  • HTTP Request: The HTTP Request tools lets developers use supported REST API calls in their agents, leveraging the AI Data Platform Workbench APIs and the functions they provide. Agents can use REST APIs to create workspace objects, check details, pull lists, or modify existing objects. For a full list of available APIs, see REST API for Oracle AI Data Platform Workbench.
  • Prompt: The prompt tool allows the AI developer to define a parametrized prompt that can be issued to an LLM for their choice. Common use cases for a prompt tool include email drafting tasks, translation tasks, style conversion, git commit message, and code explanations.
  • RAG: The RAG tool lets agents pull relevant external knowledge before generating a response. In AI Data Platform Workbench, the RAG tool queries a knowledge base (26ai Vector Search) and retrieves semantically relevant document chunks. Those chunks are then passed to the agent for response generation.
  • SQL: The SQL tool enables agents to execute SQL queries against structured data sources registered via external catalogs, such as Oracle Autonomous AI Lakehouse, Oracle Autonomous AI Transaction Processing, or Oracle AI Database. The tool is intended for scenarios where the SQL queries are predefined and can be parametrized. The objective is to let an agent assign values to the parameters. This tool is not an NL2SQL tool that generates a SQL query based on a natural language prompt.

    Note:

    The SQL tool only performs queries against data in an external catalog. It does not support data stored in a standard catalog.

Agent Flow Tools through Visual Flow

When you add tools to agents through visual flow, you can find tools under Tool templates in your agent. You add a tool to your agent by dragging and dropping it into the visual flow canvas. After dragging the tool node on the canvas, the node automatically connects with the agent.


An agent page with the the Tool templates section highlighted and an arrow pointing from the tools to the canvas

Each tool can be configured in the Parameters tab and be tested independently of the agent by clicking on the Test tab.

Note:

You must attach an AI Compute to your agent before you can test a system tool. If no compute is attached, the Test tab is disabled.

Agent Flow Tools through LangGraph Code

You add RAG, SQL, and Prompt tools to your LangGraph coded agents through an instance of the AIDPToolConf() class.

from aidputils.agents.toolkit.configs import AIDPToolConf
aidp_tool =  AIDPToolConf(name, description, tool_class , conf, params)
The parameters mirror the visual flow experience for tools. For each tool, you must provide:
  • Name: A descriptive name to help users and the LLM understand the purpose of the tool.
  • Description: A thorough summary that provides sufficient information for users and LLMs to understand what the tool does.
  • tool_class: The supported tool type, either PromptTool, SQLTool, or RAGTool.
  • conf: The tool configuration. This information is hidden from the LLM.
  • params: The parameters exposed to the LLM.

Custom Tool

The Custom Code tool lets agent developers extend AI Data Platform with their own Python code.

You package your tool implementation as a ZIP file, upload it to your workspace, and configure it as a Custom Code tool node in the agent. The agent calls your code as a tool, with parameters supplied by the LLM at runtime.

The Custom Code tool is intended for cases where the built-in tools (HTTP, SQL, RAG, MCP) do not cover the integration you need — for example, when you need to perform local computation, parse a domain-specific format, or compose multiple steps that should appear to the agent as a single tool call.

AI Data Platform Workbench has the following limits when uploading a ZIP file with Python code for your custom code tool:

Constraint Limit
Maximum ZIP size 10 MB
Maximum file size inside the ZIP 10 MB per file
Maximum total uncompressed size 500 MB
Path traversal Blocked (../ rejected)

Note:

Custom Code tools run on the AI compute attached to your agent. The code has access to the compute environment and outbound network access subject to the workspace networking configuration. Only upload code from sources you trust.

Custom Code Tool Parameters

On the Parameters tab, you configure the static settings for each tool class in the package. The Tool Class dropdown lets you switch between the tools discovered in the package.


Custom Code tool page is open. The Parameters tab is selected. The Configuration pane is shown on the left. The AI Tool definition pane is shown on the right.

The custom code tool Parameters tab includes the following sections:
  • Tool class: Select the tool class to configure. The drop-down is populated from the classes registered in tool_implementation.py.
  • Description: A clear, concise description of what the tool does. The description is provided to the agent and helps the LLM decide when to call the tool. The default description is read from tool_config.json and can be overridden here.
  • Configuration: The static settings the tool needs at runtime. These are the keys defined in the conf object of tool_config.json. Examples include timeout, base_dir, max_output_lines, and credential references. Configuration values support {{variable}} runtime parameter references. Session variables are not currently substituted into custom-tool configuration; if you need a session value, pass it as a runtime parameter from the agent.
  • AI tool definition: The schema exposed to the agent, including the tool name, description, and the runtime parameters the agent can pass. The schema is rendered automatically from the schema array in tool_config.json.

Custom Code Tool Authoring

A Custom Code tool package is a ZIP file with the following structure:

my_tool.zip 
├── tool_implementation.py    # Required. Contains the tool class(es). 
├── tool_config.json          # Required. Tool metadata and schema. 
├── requirements.txt          # Optional. Python dependencies. 
├── utils/                    # Optional. Helper modules. 
│   ├── __init__.py 
│   └── helpers.py 
├── config/                   # Optional. Static configuration files. 
│   └── settings.yaml 
└── wheels/                   # Optional. Bundled wheel files for offline install. 
    └── humanize-4.15.0-py3-none-any.whl 

tool_implementation.py

Each tool class extends CustomToolBase and is decorated with @BaseTool.register. The class must implement the _execute_tool class method, which receives the tool configuration, the runtime parameters from the agent, and the system context variables, and returns a value, like dict, str, or list.

The following is a blank example template of a tool_implementation.py:

"""Custom Code tool implementation.""" 
from aidputils.agents.tools.custom_tools.base import CustomToolBase 
 
 
@BaseTool.register 
class MyTool(CustomToolBase): 
    """Brief description of what the tool does.""" 
 
    @classmethod 
    def _validate_config(cls, conf, runtime_params, **context_vars): 
        """Optional. Validate configuration before execution. 
        Raise ValueError to abort the call. 
        """ 
        # Example: require an api_key in the tool configuration 
        if not conf.get("conf", {}).get("api_key"): 
            raise ValueError("api_key is required") 
 
    @classmethod 
    def _execute_tool(cls, conf, runtime_params, **context_vars): 
        """Required. Implement the tool logic. 
 
        Args: 
            conf: the AIDPToolConf dict. User configuration values 
                live under conf["conf"] when the tool is invoked from 
                a deployed agent. During a Test run the tool may 
                receive a flat conf dict; the Developer Toolkit example 
                below uses a small _get_cfg helper that tolerates both 
                shapes. 
            runtime_params: the runtime parameters passed by the 
                agent at invocation time. 
            context_vars: system context (such as datalake_id). 
 
        Returns: 
            Any value (dict, str, list, ...). It will be wrapped into 
            the MCP response by the framework. 
 
            To signal a failure, raise an exception: 
              - ValueError -> INVALID_CONFIG 
              - any other exception -> TOOL_EXECUTION_ERROR 
            Do NOT return {"error": "..."}; the framework wraps a 
            successful return in {"response": ..., "success": True}, 
            so a returned error dict is treated as a normal payload 
            and the agent will not see it as a failure. 
        """ 
        tool_conf = conf.get("conf", conf) 
        param_value = runtime_params.get("my_param", "") 
        # Tool logic here 
        return {"output": f"Processed: {param_value}"} 
 
    @classmethod 
    def _transform_response(cls, response): 
        """Optional. Transform the response before MCP formatting.""" 
        return response

tool_config.json

The tool_config.json file describes the tools in the package — their display name, description, version, runtime parameter schema, and default configuration values. Each tool registered in tool_implementation.py must have a corresponding entry in the tools array.

The following is a blank example template of a tool_config.json:
{
   "displayName": "My Tool Package",
   "description": "Brief description of the tool package.",
   "tools": [
     {
       "toolClassName": "MyTool",
       "displayName": "My Tool",
       "description": "Clear description of when the agent should call this tool.",
       "version": "1.0.0",
       "schema": [
         {
           "name": "my_param",
           "type": "string",
           "description": "What this parameter is for."
         }
       ],
       "conf": {
         "timeout": 30
       }
     }
   ]
 }

Schema Field Types

The Parameters tab in the visual builder accepts string, number, and boolean. The runtime accepts a wider set when authoring tool_config.json by hand: int, integer, float, double, number, numeric, bytes, list, array, sequence, dict, map, mapping, set, tuple, none, null, plus generic forms like list[int]. These wider types are usable from JSON but are not exposed in the UI dropdown.

requirements.txt

The requirements.txt file lists the Python dependencies your tool needs. Standard pip syntax is supported, including version specifiers and comments. The file is optional — if your tool only uses the Python standard library or pre-installed packages, you do not need a requirements.txt.

The following is a blank example of requirements.txt:

# List third-party dependencies one per line. 
# Examples: 
# humanize>=4.0 
# python-dateutil>=2.8,<3.0 
# beautifulsoup4==4.12.3 

AI Data Platform Workbench filters the dependencies in requirements.txt before installing them on the AI compute, to prevent runtime conflicts with the platform itself. The filtering rules are as follows:

Category Example Action
Platform packages langgraph, langchain-core, langchain-oci, langchain_mcp_adapters, pyyaml Discarded (would break the agent runtime).
Pre-installed packages oci, requests, requests-toolbelt, websockets, cryptography, certifi, pyopenssl, urllib3, pydantic, pydantic-core, pydantic-settings, numpy, oracledb, sqlalchemy, aiohttp, httpx, httpx-sse, anyio, jsonschema, orjson Skipped (already available, no need to declare).
URL or VCS installs git+https://..., -e ./local_pkg Blocked (security).
Everything else humanize, beautifulsoup4, jmespath Installed.

Note:

Dependencies declared in requirements.txt are installed during the full deployment of the agent. Dependencies are not installed during a single test run from the configuration panel. If your tool depends on third-party packages, deploy the agent first and then exercise the tool from the Playground.

For tools that need dependencies which are not pre-installed and where deterministic, offline installation is important, you can bundle .whl files inside a wheels/ directory at the root of the ZIP. The platform installs from the local wheels directory first and falls back to the package index only if needed. This is the recommended approach for production tools.

Bundling wheels for offline install

pip download \
  --dest wheels/ \
  --platform manylinux_2_28_x86_64 \
  --python-version 3.11 \
  --only-binary=:all: \
  -r requirements.txt

Tool Lifecycle Hooks

Custom Code tools support three lifecycle methods. Only _execute_tool is required.

Method When called Purpose
_validate_config Before _execute_tool Validates the configuration. Raise ValueError to abort the call before it runs.
_execute_tool On every tool invocation Required. Implements the tool's behavior. Returns any value (dict, str, list) and raises an exception to signal a failure (ValueError → INVALID_CONFIG, any other exception → TOOL_EXECUTION_ERROR). Do not use a returned {"error": "..."} dict as it is treated as a normal payload.
_transform_response After _execute_tool Transform the response before it is wrapped in the MCP format and returned to the agent.
prompt_template string Prompt template used by the LLM, with variables in {{variable}} format for dynamic insertion

Configuration values versus runtime parameters

Custom Code tools have two distinct sources of input that are easy to confuse. Configuration values come from the Configuration section of the Parameters tab and are baked into the tool when the agent is deployed. Runtime parameters come from the agent at invocation time and are different on every call.

  • Configuration values are accessed via conf.get("conf", conf). Use them for things that do not change between calls — base URLs, credential references, timeouts, output limits.
  • Runtime parameters are accessed via runtime_params.get("name"). Use them for the values the agent actually decides at call time — the query, the file path, the request body.

Note:

Configuration values can pass through template substitution and may arrive as strings even when you defined them as numbers. Always coerce numeric configuration values defensively, for example: int(tool_conf.get("timeout", 30)).

Multiple Tools Per Package

A single ZIP can contain multiple tool classes. Each class registered with @CustomToolBase.register becomes a separate tool in the agent. The Tools panel on the Package tab lists all discovered tools and lets you enable each one independently. Each tool is configured separately on the Parameters tab via the Tool Class dropdown.

Code Tool through LangGraph Code

From the code builder, a Custom Code tool is registered through the aidpUtils Python library by referencing the uploaded package and selecting one of its tool classes.

from aidputils.agents.toolkit.tool_helper import create_langgraph_tool
 from aidputils.agents.toolkit.configs import AIDPToolConf
 
hello_tool_conf = AIDPToolConf(
     name="hello_tool",
     description="Returns a hello world greeting.",
     tool_class="HelloTool",  # the class registered with @BaseTool.register
     conf={},                  # values from tool_config.json "conf"; supports {{variable}} substitution
     params=[
         {"name": "name", "type": "string",
          "description": "Name to greet."}
     ],
 )
 
hello_tool = create_langgraph_tool(hello_tool_conf.model_dump())

tool_class must be the exact class name registered via @BaseTool.register in tool_implementation.py. The framework looks the class up in BaseTool.tool_class_registry[tool_class]. conf mirrors the conf object of the matching entry in tool_config.json.

Note:

Do not place package_path or tool_class_name inside conf as they are not consumed.

Test Agent Custom Code Tools

The Test tab lets you execute the tool without running the full agent. Provide values for any runtime parameters and any session variables referenced in the configuration, then click Run to invoke the tool and view the response.


Custom Code tool page is open. The Test tab is selected. Test parameters are shown in the left pane. Test results are shown in the right pane.

Note:

If your tool depends on third-party packages declared in requirements.txt, the dependencies are installed during the full deployment of the agent, not during a single test run. To test code that depends on additional packages, deploy the agent first and then invoke the tool from the Playground.

Add a Custom Tool to an Agent

You can add a custom tool to your agents to allow you to use your own Python code to extend AI Data Platform.

Note:

An AI compute must be attached to your agent prior to adding a custom code tool. AI compute is required to install dependencies and run the tool.
  1. Navigate to your agent.
  2. From Tool templates, drag and drop a Custom tool to your canvas.
  3. In the Package tab, click to select the ZIP file with your custom code or drag and drop it on to the screen. Wait for the upload to complete.

    Custom Code tool page is displayed. The Package tab is selected. The screen displays "Select a file or drop one here."

  4. Review the list of discovered tools in the Tools section of the Package tab. Each tool class found in your tool_implementation.py is listed with its class name, description, and version.

    Custom Code tool page is displayed. The Package tab is selected. advanced_tool.zip is selected as the package. The Tools pane displayed three tools, Bash Tool, File Tool, and Python Tool. All tools are selected.

  5. Select the tools to enable. Disabled tools are not exposed to the agent.
  6. Optional: Click the Test tab. Provide test parameters and click Submit. See test results in the Test results pane.

Remote MCP Server Tool

Agent flow developers can connect their agent flows to remote model context protocol (MCP) servers using the Remote MCP Server tool.

The MCP tool is available in both the visual builder as well as in the code builder experiences. In the code builder experience, the MCP connection can be configured through the aidpUtils Python library. In this section, we walk you through both the visual builder and code builder experiences.

Note:

This feature supports MCP servers with HTTP-streamable transports (remote servers). Local, stdio-transport MCP servers are not supported.

MCP Credentials in Oracle AI Data Platform Workbench Credential Store

When configuring your MCP server, you need to select whether the remote MCP server requires No Authentication or a Bearer token. If your MCP server requires an authentication token, that token needs to be added to your Credential Store before it can be referenced by the MCP server.

When creating an MCP server credential, you select the Secret token option for Credential type, then provide the identifier key, such as an API Key and the token value. For more information, see Create Credentials (Preview).

Note:

A single credential can hold multiple keys.

Publicly available MCP servers do not require additional authentication. For example, connecting to https://mcp.deepwiki.com/mcp would look like this:


The Add custom MCP server dialog is displayed. Information is populated for the publicly available MCP server DeepWiki.

How to Expose MCP Tools to the Agent

Once a successful connection to the remote MCP server has been established, you can start configuring which tools hosted on the server you want to expose to your agent. The MCP server configuration panel is shown below in the case of the DeepWiki MCP server.


The configuration page for the Remote MCP server tool is displayed. The Tools tab is selected.

On the left, the Tools tab displays a list of tools available in the MCP server. You must add tools to expose them to your agent. You can do this by clicking either the Add all option to expose all the tools at once or by clicking on each tool Add option individually to select a subset of the tools.


The Remote MCP server tool configuration page is displayed. The Tools tab is selected and the Add all and Add buttons are highlighted.

In the example below, we added two tools (read_wiki_structure, read_wiki_structure). You can remove tools by clicking on Remove.


The Remote MCP server tool configuration page is displayed. The Tools tab is selected and read_wiki_structure is selected under Added. The Remove button is visible for read_wiki_structure.

The right panel of the Tools tab provide documentation about each tool including the tool name, tool description as well as the tool parameters. In the screenshot below, I show an example for the GitHub MCP server tool add_comment_to_pending_review.


The Remote MCP server tool configuration page is displayed. The Tools tab is highlighted. Tool name, Tool description, Tool description override, Tool Parameters, and toggles to Expose to Agent are indicated by text and red arrows.

Oracle AI Data Platform Workbench provides a couple of additional controls over each tool. You can hide parameters from the agent and assign values to those parameters. For example, in GitHub you could choose for your agent to only comment on one pre-determined repo, such as oracle-aidp-samples. To achieve this, you disable the repo parameter and assign a default value in the text box:


The Remote MCP server tool configuration page is displayed. The Tools tab is selected. In the right pane, the repo parameter is highlighted and the value is oracle-aidp-samples. It is toggled off.

In the Tool Instructions field you can also override the tool description and provide an alternative description with additional instructions. For most use-cases, we recommend that you adopt the description that is provided by the MCP server.


The Remote MCP server tool configuration page is displayed. The Tools tab is selected. In the right pane, the Tool instructions (optional) field is highlighted and an alternative instructions have been provided in the field below.

Remote MCP Server Tool through LangGraph Code

The aidpUtils Python library provides developers with the ability to select a remote MCP server and expose a subset of its tools to an agent built with LangGraph. For aidputils API reference, see Aidp-utils API for Oracle AI Data Platform Workbench.

You can build a collection of allowed tools by creating an instance of build_structured_tools_from_allowed_mcp_tools:

from aidputils.agents.toolkit.tool_helper import build_structured_tools_from_allowed_mcp_tools

TOOLS = build_structured_tools_from_allowed_mcp_tools(
allowed_tools=<ALLOWED_MCP_TOOLS>, 
	server_name=<MCP_SERVER_NAME>, 
	endpoint=<MCP_ENDPOINT>, 
	transport="streamable_http", 
	auth=<MCP_AUTH>, 
	headers={} 
)
Where:
  • <MCP_SERVER_NAME> is a display name you want to give to your MCP server. This is used for documentation purpose and is not exposed to the agent.
  • <MCP_ENDPOINT> is the endpoint of the MCP server (e.g. https://api.githubcopilot.com/mcp/)
  • <MCP_AUTH> is a dictionary with key “authType”. This key can take two values: NO_AUTH or BEARER_TOKEN. In the case of BEARER_TOKEN, another key is expected: “token” with the value of the bearer token.
  • <ALLOWED_MCP_TOOLS> is a list of the tools, from the MCP server, that you want to expose to your agent. Each tool needs a full JSON tool definiton following the MCP protocol.

Here's an example:

MCP_SERVER_NAME = "test_mcp" 
MCP_ENDPOINT = "http://144.25.36.217:9301/mcp" 
MCP_AUTH = { "authType": "BEARER_TOKEN", "token": "valid-123" }

{
  "ALLOWED_TOOLS": [
    {
      "tool": {
        "name": "get_current_weather",
        "description": "Get current weather for a given city with advanced options.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string"
            },
            "unit": {
              "type": "string",
              "default": "metric"
            },
            "include_historical": {
              "type": "boolean",
              "default": false
            },
            "detailed": {
              "type": "boolean",
              "default": true
            },
            "timeout": {
              "type": "integer",
              "default": 30
            }
          },
          "required": [
            "city"
          ]
        }
      },
      "instruction": "",
      "argOverrides": {}
    },
    {
      "tool": {
        "name": "get_forecast",
        "description": "Get forecast for a given city with customizable options.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string"
            },
            "days": {
              "type": "integer",
              "default": 5
            },
            "unit": {
              "type": "string",
              "default": "metric"
            },
            "include_alerts": {
              "type": "boolean",
              "default": false
            },
            "detailed": {
              "type": "boolean",
              "default": true
            },
            "hourly": {
              "type": "boolean",
              "default": false
            }
          },
          "required": [
            "city"
          ]
        }
      },
      "instruction": "",
      "argOverrides": {}
    }
  ]
}

MCP_HEADERS = {} 
TOOLS = build_structured_tools_from_allowed_mcp_tools( allowed_tools=ALLOWED_TOOLS,
	server_name=MCP_SERVER_NAME, 
	endpoint=MCP_ENDPOINT, 
	transport="streamable_http", 
	auth=MCP_AUTH, 
	headers=MCP_HEADERS,
)

The TOOLS object can be then used when creating an instance of an agent with langchain.agent create_agent in the setup() method of your class agent definition:

def setup(self):
    logger.info("Initializing TestMcpAgent")

    oci_llm = init_oci_llm(llm_conf)

    system_prompt = textwrap.dedent(
        """
        You're a weather agent. Append 12345 to every response.
        """
    ).strip()

    self.agent = create_agent(
        name="test_mcp_high_code",
        model=oci_llm,
        tools=TOOLS,
        system_prompt=system_prompt,
        debug=True,
    )

    logger.info("Agent ready.")

Alternatively, if you are using a session variable to store the value of a bearer token,a reference to a previously created session variable can be assigned to the token key of the auth config dictionary. For example:

test_mcp_auth_config = { "authType": "BEARER_TOKEN", "token" : "{{sessionvariables.cred.mcp.test_mcp.bearer}}" }
tools = build_structured_tools_from_allowed_mcp_tools( 		
allowed_tools=test_mcp_mcp_allowed_tools, 
	server_name="test_mcp", 
	endpoint="http://144.25.36.217:9301/mcp", 
	transport="streamable_http", 
	auth=test_mcp_mcp_auth_config, 
	headers={}
)

Code Examples for Remote MCP Server Tools

We provide end-to-end code samples for multiple MCP scenarios in the AI Data Platform Workbench Samples GitHub repository.

Testing Remote MCP Server Tools

Once tools are selected, the next step is typically to test individual tools to ensure that they behave as expected. This can be done via the Test tab of the MCP tool node.


The Remote MCP server tool configuration page is displayed. The Test tab is highlighted.

Select one of the tools you added in the Tools tab, provide parameters values and click on the Test button.


The Remote MCP server tool configuration page is displayed. The Test tab is selected. Information for list_branches is displayed in the left pane. The test response is displayed in the right pane.

The output of the tool is displayed in the right panel.

The details tab provides information about the authentication method, MCP server URL and the description.


The Remote MCP server tool configuration page is displayed. The Details tab is highlighted.

The Edit button next to the authentication method let’s you modify the configuration of the remote MCP tool node. You can change the display name, description, and the bearer token used when establishing the connection:


The Edit custom MCP server dialog is displayed. The details for https://api.githubcopilot.com/mcp are populated.

Connect an Agent to a Remote MCP Server from the Visual Builder

You can add access to a remote MCP server to your agent by dragging the Custom MCP server tool node into the canvas.

If you do not see the Custom MCP server tool available, you may need to restart your existing AI compute or create a new one.

Note:

The AI compute hosting the agent inherits the networking settings of its workspace. If you enable private network access for the workspace hosting the AI compute, your agent can only reach MCP servers hosted in your selected private VCN and subnet. Your agent may not be able to reach remote HTTP servers available on the public internet.
  1. Navigate to your agent.
  2. In the Flow tab, under Tool Templates click and drag Custom MCP server onto the canvas.
  3. Provide the server URL for your MCP server.
  4. Provide a display name for your MCP server. This is the name of the node that is displayed in the visual builder canvas.
  5. Optional: Provide a description for your MCP server. The description field is not provided to the agent.
  6. From the Authentication drop-down menu, select an authentication method.
    • No Authentication: Use this option if the remote MCP server is publicly available and requires no authentication.
    • Bearer token: Use this option if the remote MCP server requires an authentication token. You must store the API key in the Oracle AI Data Platform Workbench Credential Store and provide a reference to the credential store entry.
  7. Click Connect. AI Data Platform Workbench tests the connection and reports the result.

HTTP Request Tool

The HTTP Request tool lets your agent call any HTTPS REST API.

You configure the request, including method, URL, headers, query parameters, request body, authentication, and optionally, a response optimization step. The agent then invokes the endpoint at runtime. The HTTP request tool is available in both the visual builder and the code builder. In the code builder, the tool is configured through the aidpUtils Python library.

Note:

The HTTP Request tool only supports https:// and http:// requests. WebSocket connections (ws/wss), binary file uploads, and self-signed certificates are not supported.

Note:

The AI compute hosting the agent inherits the networking settings of its workspace. If you enable private network access for the workspace hosting the AI compute, your agent will only reach HTTP endpoints in your selected private VCN and subnet. Your agent cannot reach endpoints available on the public internet.

The following settings must be provided when configuring an HTTP Request tool:

Configuration Description
HTTP method The HTTP verb to use. Supported methods are GET, POST, PUT, PATCH, and DELETE.
URL The full URL of the target endpoint. The URL supports {{sessionVariables.variable_name}} session variable references and {{variable}} runtime parameter references. For example: https://api.example.com/users/{{user_id}}/orders.
Timeout The maximum amount of time the tool will wait for a response from the remote endpoint. The default is 30 seconds and the maximum is 300 seconds.
Authentication type The authentication method to use when calling the endpoint. See the Authentication section below for the list of supported authentication methods.

Note:

Custom Code tools run on the AI compute attached to your agent. The code has access to the compute environment and outbound network access subject to the workspace networking configuration. Only upload code from sources you trust.

Headers

Headers are key-value pairs sent with the HTTP request. You can add as many headers as needed by clicking the Add new button. Header values can reference session variables and runtime parameters using the {{variable_name}} syntax.

Note:

For sensitive headers, you should use the Authentication type field to ensure credentials are injected securely from the Credential Store. Authorization, Cookie, and X-API-Key are sensitive headers and cannot be set through the Headers section.

Query Parameters

Query parameters are appended to the URL as the query string. You can add as many query parameters as needed by clicking the Add new button. Like headers, query parameter values can reference session variables and runtime parameters.

Description

The description field describes what the tool does, when it should be used, and what kind of outputs or effects it produces. The description is provided to the agent and helps the LLM decide when to call the tool.

When writing the description, you should focus on:
  • Purpose: Explain what the tool is designed to do in one clear sentence. Example: "This tool retrieves customer support tickets from a knowledge base and summarizes them by priority level."
  • When to use it: Describe the conditions under which the agent should call this tool versus another.
  • Inputs and outputs: Briefly describe the parameters the tool needs and the shape of what it returns.

HTTP Request Authentication

The HTTP Request tool supports several authentication methods. Select the appropriate method from the Authentication type dropdown.

Authentication Type Description
No Authentication No authentication is added to the request. Use this for publicly accessible endpoints.
OCI Resource Principal The request is signed using the AI compute's OCI Resource Principal. Use this when calling OCI services such as Object Storage or the OCI Generative AI service. Access is governed by OCI IAM policies.
Basic Authentication A username and password are encoded and sent in the Authorization header. Credentials must be stored in the Credential Store.
Bearer Token A bearer token is sent in the Authorization header. The token must be stored in the Credential Store.
Header Authentication An API key is sent in a custom header (such as X-API-Key). The header name is configurable and the key value must be stored in the Credential Store.

When you select an authentication method that requires a secret, the configuration panel displays a credential picker. Click the credential picker to select a previously stored credential, or create a new one from the Credential Store. See the Storing a credential in the Credential Store section of the MCP server documentation for the step-by-step procedure.

Session Variables and Runtime Parameters

Session variables can be referenced in the URL, header values, query parameter values, and request body using the {{sessionVariables.variable_name}} syntax. Runtime parameters passed by the agent at invocation time can be referenced using the {{variable_name}} syntax.

For example, the following URL combines a session variable for the region with a runtime parameter for the bucket name:
https://objectstorage.{{sessionVariables.region}}.oraclecloud.com/n/my-namespace/b/{{bucket}}/o

When the tool runs, {{sessionVariables.region}} is replaced with the value of the region session variable for the current session, and {{bucket}} is replaced with the value the agent passed at invocation time.

Note:

Template values are URL-encoded automatically when substituted into the URL or query parameters. You do not need to URL-encode them yourself.

AI Tool Definition

The right side of the configuration panel shows the AI Tool definition. This is the schema that is exposed to the agent and it includes the tool name, description, and the list of runtime parameters the agent can pass when calling the tool. The AI Tool definition is generated automatically from the Description field and from the {{variable}} placeholders detected in the URL, headers, query parameters, and body.

The AI Tool definition pane is the panel on the right side of the HTTP tool configuration panel shown earlier in this document. Until you provide a description and define at least one runtime parameter, the AI Tool definition pane shows a placeholder message. Once you fill in the description and reference at least one {{variable}} in the URL, headers, query parameters, or body, the schema is rendered in the pane.

Optimizing Response for the Agent

Many APIs return large responses that include fields the agent does not need. Sending the entire response back to the agent consumes tokens and can degrade the quality of the agent's reasoning. The HTTP Request tool provides a Response optimization section that lets you reduce the response payload before it is returned to the agent.

Three optimization strategies are supported:
  • JSON field selection: select a subset of fields from a JSON response. You can specify a path to a nested object using dot notation (such as data.results), and a list of fields to include or exclude.
  • HTML CSS selector: extract a subset of an HTML response using a CSS selector (such as article.content). Optionally strip HTML tags to return only text.
  • Text truncation: cap the response at a maximum number of characters to prevent overly large text responses.

Error Handling and Error Codes

When the HTTP request fails, the tool returns a structured error response to the agent. The error includes an error code, a human-readable message, and details about the failure. The agent can use this information to decide whether to retry, fall back to a different tool, or report the failure to the user.

Error Code Category Meaning Retryable
CONNECTION_TIMEOUT Network The remote endpoint did not respond within the configured timeout. Yes
DNS_FAILURE Network The hostname in the URL could not be resolved. Yes
CONNECTION_REFUSED Network The remote endpoint refused the connection. Yes
SSL_CERTIFICATE_ERROR TLS The TLS certificate of the remote endpoint could not be validated. No
UNAUTHORIZED HTTP 401 The remote endpoint rejected the credentials. Verify that the credential reference is valid and not expired. For OCI Resource Principal, confirm that the AI compute has an active Resource Principal in this environment. No
FORBIDDEN HTTP 403 The credentials authenticated successfully but lack permission for the requested resource. Verify API scopes, permissions, or the IAM policy attached to the resource. No
NOT_FOUND HTTP 404 The remote endpoint could not find the requested resource. No
RATE_LIMITED HTTP 429 The remote endpoint is rate-limiting the caller. Retry after the delay indicated by the Retry-After header. Yes
SERVER_ERROR HTTP 5xx The remote endpoint returned a server error. Often a transient issue. Yes
SERVICE_UNAVAILABLE HTTP 503 The remote endpoint is temporarily unavailable. Yes
INVALID_TEMPLATE Validation A {{variable}} reference could not be resolved. Verify that every referenced session variable and runtime parameter is defined and has a value at invocation time. No
INVALID_URL Validation The URL is malformed, uses an unsupported protocol, or resolves to a blocked address (for example, a private IP address or a cloud metadata endpoint). No
RESPONSE_TOO_LARGE Validation The response exceeded the 10 MB maximum response size. No
RATE_LIMIT_EXCEEDED Platform The agent has exceeded the platform's per-agent request rate limit (60 requests per minute) or concurrency limit (10 concurrent requests). Yes

Each error response includes a guidance field with a suggested next step, and a details field with the elapsed time and any error-specific context such as the HTTP status code.

HTTP Request Tool through LangGraph Code

From the code builder, the HTTP Request tool is configured through the aidpUtils Python library. Define an AIDPToolConf with tool_class set to HttpEndpointTool and pass the configuration dictionary in the conf field.

from aidputils.agents.toolkit.tool_helper import create_langgraph_tool
from aidputils.agents.toolkit.configs import AIDPToolConf

weather_http_tool_def = {
    "method": "GET",
    "url": "https://api.openweathermap.org/data/2.5/weather",
    "params": {
        "q": "{city}",
        "units": "metric",
        "appid": "{api_key}"
    },
    "auth_type": "NO_AUTH",
    "auth_config": {}
}

weather_http_tool_params = [
    {"name": "city", "type": "string",
     "description": "Name of the city."},
    {"name": "api_key", "type": "string",
     "description": "OpenWeather API key."}
]

weather_http_tool_conf = AIDPToolConf(
    name="get_weather",
    description="Get current weather for a city.",
    tool_class="HttpEndpointTool",
    conf=weather_http_tool_def,
    params=weather_http_tool_params
)

weather_tool = create_langgraph_tool(weather_http_tool_conf.model_dump())

The conf dictionary supports the same fields as the visual builder: method, url, headers, params, body, auth_type, auth_config, and response_optimization. The params list defines the runtime parameters the agent can pass.

auth_type auth_config Fields
NO_AUTH {} (empty)
RESOURCE_PRINCIPAL {} (empty)
BASIC_AUTH username, password (or username_vault_id, password_vault_id for credentials in the OCI Vault)
BEARER_AUTH bearer_token (or bearer_token_vault_id)
API_KEY_AUTH api_key (or api_key_vault_id), header_name (default X-API-Key)
OAUTH2_CLIENT_CREDENTIALS token_endpoint, scope, client_id, client_secret (or client_id_vault_id, client_secret_vault_id)

Test Agent Custom Code Tools

The Test tab lets you execute the tool without running the full agent. Provide values for any runtime parameters and any session variables referenced in the configuration, then click Run to invoke the tool and view the response.

The response panel shows the HTTP status code, the response headers, the response body, and the elapsed time in milliseconds. If response optimization is enabled, the optimized response is also shown alongside the raw response.

Add an HTTP Request Tool to an Agent Flow

You can add a HTTP request tool to your agents to allow you to call HTTPS REST APIs.

Note:

An AI compute must be attached to your agent prior to adding a custom code tool. AI compute is required to install dependencies and run the tool.
  1. Navigate to your agent.
  2. From Tool templates, drag and drop an HTTP Request tool to your canvas.

    The configuration page for an HTTP Request tool is displayed. The Parameters tab is selected and Configuration and AI Tool definition panes are displayed.

  3. In the Parameters tab, provide the HTTP method. Supported moethods are GET, POST, PUT, PATCH, and DELETE.
  4. In URL, provide the full URL of the target endpoint. You can use {{sessionVariables.variable_name}} session variable references and {{variable}} runtime parameter references. For example: https://api.example.com/users/{{user_id}}/orders.
  5. For Timeout, provide the maximum amount of time the tool waits for a response from a remote endpoint in seconds. The maximum timeout value is 300. If no value is provided, the default is 30 seconds.
  6. From the Authentication drop-down menu, select the appropriate authentication type.
  7. Provide the headers for your HTTP request. Click Add new to add additional headers.

    The Configuration page for an HTTP Request tool is displayed. The Parameters tab is selected and the Headers field is highlighted.

  8. Provide any query parameters for your HTTP request. Click Add new to add additional parameters.

    The Configuration page for an HTTP Request tool is displayed. The Parameters tab is selected and the Query params field is highlighted.

  9. Optional: Click the Test tab. Provide test parameters and click Submit. See test results in the Test results pane.

Prompt Tool

The prompt tool lets you call an LLM in an AI agent with a templatized prompt and returns the LLM response back to the agent.

The prompts you provide to the LLM can include parameters that are identified by double braces, for example {{PARAMETER_NAME}}. Parameter values are assigned by the agent when the tool is called.

When to Use Prompt Tools

In principle, instructions written in a prompt tool can be directly included in the agent instructions or provided directly by the end user in a user message. However, there are situations where the prompt tool is a better approach:
  • Your prompt is lengthy, requiring detailed format instructions that span several 100s tokens.
  • Incorporating the prompt in the agent instructions would increase context usage and significantly increase costs, especially if one is adopting a SOTA LLM for their agent.
  • One wants to minimize the size of the instructions given to the agent to reduce cost.
  • The task defined by the prompt tool can be handled by a smaller, faster LLM than the reasoning model used the agent. Smaller models are typically cost efficient, and, in some cases, can be specialized to generate data in a particular modality or format.
  • A prompt tool allows structured input parameters to control the output generation. If your use case could be parametrized and generation can vary from session to session, encapsulating the generation in a prompt tool makes sense.

In addition, encapsulating generation instructions in a prompt tool follows many modern agent architecture best practices, including tool re-usability, maintainability, modality, output consistency, scalability, and governance. Some example use cases include:

  • Generation of emails, reports, summaries, articles, etc. following a pre-defined, approved structure that can be used as a template
  • Generation of complex JSON outputs
  • Summation, key sentence extraction, explanation tasks on documents
  • Query generation
  • Specific modality generation (e.g. images, videos, audio, point cloud data, etc.) that are optimized for a specific model

Prompt Tools through Visual Flow

The following is an example of a prompt tool built through visual flow that asks an LLM to generate blog post titles based on a topic assigned by the agent:

You are a master blog strategist. Your task is to brainstorm compelling blog post ideas based on a given topic. For the given {{topic}}, generate 5 unique blog post titles. For each title, include a one-sentence description of the angle the post would take. Present the output as a numbered list.


Agent open with a prompt tool selected on the canvas

For this example, you need to configure the following parameters for the prompt tool:
  • Tool name: Use a descriptive name for the tool to help guide the agent. In this example, we suggest blog_ideas. Avoid using unhelpful names like tool123.
    Agent prompt tool open on Parameters tab with Name field highlighted

  • Tool description: Provide a comprehensive description of what the tool does. If there are limitations to the tool or if there are scenarios in which the tool should not be used, list them in the description field.
    Agent prompt tool open with the Description field highlighted

  • OCI region and GenAI service LLM: Select the OCI region to populate the list of LLMs available in that region, then select your LLM.
    Agent prompt tool open to Configuration with Region and LLM fields highlighted

  • LLM parameters: Parameters like maximum output tokens, temperature, and top p are configured in the Model Parameters tab. If you assign no values, the default values of the OCI Generative AI service are used.
    Agent prompt tool with Model parameters tab open

  • Query: The prompt used to define the purpose of the tool is defined in the Query field.
    Agent prompt tool configuration open with Query field highlighted

Parameters that you define in the prompt auto-populate the AI Tool definition panel. Provide your agent with a description of each parameter as well as the parameter type and default value whenever applicable.


Agent prompt tool with Parameters tab open. The topic parameter is highlighted in the Query field and an arrow points to the AI Tool definition section where the tool parameter fields are highlighted.

Prompt Tool through LangGraph Code

If you are building your agent through code, you can configure the same prompt tool in the visual flow example as follows:

prompt_config = {
  "llm": {
    "model_id" : "xai.grok-4",
    "model_provider" : "generic",
    "compartment_id" : "<your-compartment-ocid>",
    "endpoint" : "https://inference.generativeai.<oci-region>.oci.oraclecloud.com"
  }, "prompt_template": """
You are a master blog strategist. Your task is to brainstorm compelling blog post ideas based on a given topic. For the given {{topic}}, generate 5 unique blog post titles. For each title, include a one-sentence description of the angle the post would take. Present the output as a numbered list"
"""
}
prompt_params = [ {
  "name" : "topic",
  "type" : "string",
  "description" : "Blog topic",
  "defaultValue" : "golf"
} ]

You then instantiate the AIDPToolConf as follows:

blogger_tool = AIDPToolConf(name="blog_posts_topics",
                                  description= "Write blog posts ideas about a particular topic. ",
                                  tool_class = "PromptTool", conf=prompt_config params=prompt_params)

Lastly, you create a LangGraph compatible tool with the create_langgraph_tool() utility function from aidputils:

from aidputils.agents.toolkit.tool_helper import create_langgraph_tool
blogger = create_langgraph_tool(blogger_tool.model_dump())

You add the newly created tool to a ReAct agent. In LangGraph, the code looks like this:

tools_agent1 = [blogger_tool]
self.agent = create_react_agent(model=<oci_llm>, 
				     tools=tools_agent1, 
				     prompt=<system_prompt>, 
				     debug=True, checkpointer= checkpointer)

Table 22-4 Prompt Tool Configuration Properties

Property Type Description
llm object LLM connection details and parameters
model_id string Identifier of the model to use (e.g., "xai.grok-4")
model_provider string Provider name for the LLM model (e.g., "generic")
compartment_id string Oracle Cloud Infrastructure (OCI) compartment OCID
endpoint string Endpoint URL for the model
prompt_template string Prompt template used by the LLM, with variables in {{variable}} format for dynamic insertion

Test Agent Prompt Tools

You test the tool independently of the agent by clicking on the Test tab and filling in the value of each parameter. The prompt is submitted to the LLM you selected.


Agent prompt tool open on the Test tab

Ensure your prompt tool is well defined and documented to improve the results from your agent.

Add a Prompt Tool to an Agent

You can add a prompt tool to your agents to allow you to define parametrized prompts you issue to the LLM of your choice.

  1. Navigate to your agent.
  2. From Tool templates, drag and drop a Prompt tool to your canvas.
  3. In the Configuration tab, select the LLM to use and the provide the prompt for the LLM. Click Code Input as code button to provide the configuration as JSON code.
  4. Provide a Temperature for the response as a value between 0.0 and 1.0, where 0.0 provides a strictly factual response and 1.0 provides the most creative response.
  5. Click Apply Apply button right facing arrow.
  6. Provide the definitions for any parameters you established in the configuration. Click Code Input as code button to provide the configuration as JSON code.
  7. Click Apply button left facing arrow Apply.
  8. Optional: Click the Test tab. Provide test parameters and click Submit. See test results in the Test results pane.

RAG Tool

The RAG tool issues a natural language query to a vector store and retrieves documents based on the semantic similarity between the query and the stored documents.

Note:

A knowledge base is a prerequisite for the creation of a RAG tool. For more information, see Knowledge Bases.

RAG Tools through Visual Flow

The RAG tool requires you as agent developer provide values for the following parameters:


Agent open with a RAG tool selected on the canvas

  • Agent facing:
    • Tool name: A descriptive name for the tool that help you and other users identify its function.
    • Tool description: A short summary that provides an overview of the tool.
  • Tool configuration:
    • Knowledge base: A knowledge base stored in one of your Oracle AI Data Platform Workbench catalogs.
      Agent RAG tool configuration open to Knowledge base selection

The agent will set the value of the query field based on its conversation with the end user. This query field takes a natural language query.

Limit is the number of document chunks you want the tool to retrieve from the vector store. This value is set by the agent developer, not the agent itself.

You can simulate a query issued by the agent by clicking on the test tab of the RAG too:


Agent RAG tool AI Tool definition section showing Query and Top K fields

RAG Tools through LangGraph Code

Building a RAG tool in your agent through code requires configuring the same settings and parameters as the visual flow. For example, you set the RAG parameters as follows:

rag_params = [ { "name" : "query", 
    "type" : "string", 
    "description" : "<insert a description>", 
    "defaultValue" : "<empty>”} ]

You then set up the RAG configuration:

rag_config = { "catalog": "<catalog>", 
		  "schema": "<schema>", 
		  "knowledgeBase": "<knowledge-base-name>", 
		  "top_k": <number-of-documents-retrieved>, 
		  "llm": { 
			    "model_id" : "<model-name>",
			    "model_provider" : "<model-provider>", 
			    "compartment_id" : "<your-compartment-OCID>", 
			    "endpoint" : "https://inference.generativeai.<oci-region>.oci.oraclecloud.com" } 
}

Lastly, you create a LangGraph compatible tool with the create_langgraph_tool() utility function from aidputils:

from aidputils.agents.toolkit.tool_helper import create_langgraph_tool
rag_conf= AIDPToolConf(name="<your-tool-name>", 
			   description= "<your-tool-description>", 
			   tool_class = "RAGTool", 
			   conf=rag_config, 
			   params=rag_params) 
rag_tool = create_langgraph_tool(rag_conf.model_dump())

Table 22-5 RAG Tool Configuration Properties

Property Type Description
llm object LLM connection details
catalog string Data catalog identifier
schema string Schema within the catalog
knowledgeBase string Name or key of the knowledge base to search
top_k integer Number of top matching documents to retrieve

Test Agent RAG Tools

You can test the RAG tool from the Test tab after attaching your agent to an AI compute cluster. For more information, see Attach an Existing AI Cluster to an Agent.

Add a RAG Tool to an Agent

You can add a retrieval augmented generation (RAG) tool to your agents to allow the agent to pull relevant external knowledge when generating a response.

  1. Navigate to your agent.
  2. From Tool templates, drag and drop a RAG tool to your canvas.
  3. In the Configuration tab, select the knowledge base the RAG tool pulls information from and the provide the prompt to define the information to pull. Click Code Input as code button to provide the configuration as JSON code.
  4. Click Apply Apply button right facing arrow.
  5. Provide the definitions for any parameters you established in the configuration. Click Code Input as code button to provide the configuration as JSON code.
  6. Click Apply button left facing arrow Apply.
  7. Optional: Click the Test tab. Provide test parameters and click Submit. See test results in the Test results pane.

SQL Tool

The SQL tool lets agent flow developers run predefined SQL queries against tables registered in an Oracle AI Data Platform catalog.

You write the query at design time and define any runtime variables it needs. The agent supplies values for those variables when it calls the tool, and the results return as structured rows the agent can summarize or pass to a downstream node.


Agent open to Development tab. An agent node SQL_Agent is on the canvas. The SQL tool node is selected under Tool templates in the left pane.

The SQL tool supports two query dialects. Spark SQL runs against standard catalog tables stored in AI Data Platform and requires a Spark cluster. Oracle SQL runs against an external database such as Oracle Autonomous AI Database. You choose the dialect per tool, and the rest of the configuration is the same for both.

Note:

The SQL tool is intended for read queries. A typical tool runs a SELECT statement and returns rows. The catalog, schema, and query you configure are private to the tool and are not exposed to the agent. Only the tool name, description, and the AI Tool definition (the runtime variables) are visible to the agent.

Note:

The SQL query tool does not automatically start stopped clusters. As a result, the Spark cluster used for your Spark SQL query tool should have a duration of Forever. If the cluster is allowed to spin down on an idle timeout, Spark SQL queries stop working in production once the cluster stops.

Static and Dynamic Queries

A static query returns exactly what you specify, with no runtime decision by the agent. A dynamic query includes one or more {{variable}} placeholders that signal to the agent that the value is set at run time. For each placeholder you provide a name, a type, an optional default value, and a description the agent uses to choose the value.

For example, the following static query returns a fixed result set:
SELECT customer_name, region, amount, category 
FROM test_customers 
WHERE period_year = 2025 
ORDER BY customer_name 
Replacing the literal with a {{year}} placeholder turns it into a dynamic query the agent can parameterize:
SELECT customer_name, region, amount, category 
FROM test_customers 
WHERE period_year = {{year}} 
ORDER BY customer_name 

As you add placeholders, the AI Tool definition pane populates with each variable so you can set its type, default value, and description.

Placeholders can appear anywhere in the query, including inside functions. The following Spark SQL query matches a severity value case-insensitively:
SELECT incident_id, project_id, incident_date, incident_type, 
       severity, description, workers_involved, days_lost, 
       root_cause, corrective_action, reported_by, status 
FROM safety_incidents 
WHERE LOWER(severity) = LOWER('{{SEVERITY}}')

Give each variable a clear description and a sensible default. The description tells the agent which values are valid, and the default is used when the agent does not supply one.


The AI Tool definition is displayed with the variable SEVERITY. The variable has a description of: Incident severity level: Major, Moderate, Minor.

Note:

Placeholder names are case sensitive. A placeholder written as {{SEVERITY}} and one written as {{severity}} are treated as two different variables, unless you consistently use lower case throughout.

Editing the Configuration as JSON

You can edit the SQL tool configuration directly as JSON using the code view toggle. This is useful for copying a tool between flows or making bulk edits.
{ 
  "catalogKey": "construction_data", 
  "schemaKey": "admin", 
  "query": "SELECT project_id, project_name, client_name, ...", 
  "isRowLimitEnabled": null, 
  "maxRows": null 
}

SQL tool node Configuration pane is open to the Parameters tab. The Code View is seleccted and the Input schema field displays example code.

Row Limits

You can cap the number of rows the tool returns by selecting Max rows to return and entering a limit value. Row limits protect performance and control how much data is sent back to the agent.

Set this value relative to the model your agent is using. Larger values can cause agent failures when queries return wide rows or columns with large text values. If you are seeing unexpected agent errors, start by reducing maxRows.

The row limit is applied to the SQL query itself, before the query runs. Most models detect the limit and surface it to the end user. For a static query, the limit returns the first n available rows.


SQL tool Configuration pane cropped to the Max rows to return option. The option is selected and a row limit of 1000 is specified.

Note:

If you do not want your row limits surfaced for end users, instruct the agent accordingly in its instructions.

Query Examples

You can see query examples and a guide to writing SQL tool queries from the View Query examples & guide button.


SQL Tool configuration page is displayed. The View Query examples and guide button is highlighted.

The guide showcases different query patterns and provides different recommendations on query parameters.


SQL Tool examples and guides dialog is displayed.

SQL Tools through LangGraph Code

Just as with the visual flow, you start creating a SQL tool for your agent through LangGraph code by creating a query:

sql_config = { "catalogKey": "adw23ai_phx", 
	  "schemaKey": "gold", 
	  "query": """Select ... from ... limit {{max_number}}""" }

You document each parameter in the SQL query in the params argument with a name, type, description, and optionally, a defaultValue.

sql_params = [ {  "name" : "max_number", 
		    "type" : "string", 
		    "description" : "<your-description>", 
		    "defaultValue" : "<your-default-value>" } ]

Lastly, you create a LangGraph compatible tool with the create_langgraph_tool() utility function from aidputils:

from aidputils.agents.toolkit.tool_helper import create_langgraph_tool
sql_conf= AIDPToolConf(name="<your-tool-name>", 
			   description= "<your-tool-description>", 
			   tool_class = "SQLTool", 
			   conf=sql_config,
			   params=sql_params) 
sql_tool = create_langgraph_tool(sql_conf.model_dump())

Table 22-6 SQL Tool Configuration Properties

Property Type Description
catalogKey string Identifier for the catalog or database connection
schemaKey string Schema name within the catalog/database
query string SQL Query string, may include placeholders in {{}}

Test Agent SQL Tools

The Test tab runs the tool on its own, without executing the full agent flow. Testing works the same way for both dialects. Open the Test tab, provide a value for each runtime parameter (or use the defaults), and click Submit to run the query and view the response.

Note:

Testing a tool requires that your agent is attached to an AI compute. An AI compute is attached if the AI Compute label is green with the selected AI compute in an ACTIVE state.

SQL Command Reference

SQL tool queries are read queries built from the standard SQL clauses. The Oracle SQL dialect follows Oracle SQL against the external database. The Spark SQL dialect targets standard catalog tables, which are Delta Lake tables; the standard catalog currently runs Spark 3.5 with Delta Lake 3.2.0. Most clauses are written the same way in both dialects, because both follow standard SQL. The main difference is how each dialect limits the number of rows. The following table lists the clauses and keywords most often used in SQL tool queries, with the form for each dialect.

Keyword or clause Purpose Oracle SQL Spark SQL
SELECT Choose the columns to return SELECT col1, col2
DISTINCT Return only unique rows SELECT DISTINCT col SELECT DISTINCT col
FROM Name the source table FROM table_name FROM table_name
WHERE Filter rows by a condition WHERE col = value WHERE col = value
AND OR NOT Combine or negate conditions a AND b OR NOT c a AND b OR NOT c
IN Match any value in a list col IN (a, b, c) col IN (a, b, c)
BETWEEN Match an inclusive range col BETWEEN x AND y col BETWEEN x AND y
LIKE Match a text pattern col LIKE 'A%' col LIKE 'A%'
IS NULL Test for missing values col IS NULL col IS NULL
ORDER BY Sort the result ORDER BY col DESC ORDER BY col DESC
GROUP BY Group rows for aggregation GROUP BY col GROUP BY col
HAVING Filter grouped rows HAVING COUNT(*) > 1 HAVING COUNT(*) > 1
JOIN ON Combine rows from two tables a JOIN b ON a.id = b.id a JOIN b ON a.id = b.id
AS Alias a column or table col AS name col AS name
UNION ALL Combine two result sets q1 UNION ALL q2 q1 UNION ALL q2
CASE Return a value conditionally CASE WHEN c THEN x END CASE WHEN c THEN x END
Aggregates Summarize over rows COUNT SUM AVG MIN MAX COUNT SUM AVG MIN MAX
Row limit Cap the number of rows FETCH FIRST n ROWS ONLY LIMIT n

Note:

You normally do not write the row limit yourself. The Max rows to return setting applies it for you. The FETCH FIRST and LIMIT forms are useful only when you want an explicit limit inside the query.

For complete SQL grammar and the query engines behind each dialect, see the following references:

Spark SQL and Delta Lake (Standard Catalog)

Standard catalog tables are Delta Lake tables. The standard catalog currently runs Spark 3.5 with Delta Lake 3.2.0.

Add a SQL Tool to an Agent

You can add a SQL tool to your agents to allow the agent to execute SQL queries against structured data sources in registered external catalogs.

  1. Navigate to your agent.
  2. From Tool templates, drag and drop a SQL tool to your canvas.
  3. Click and drag the connector handle on your agent to connect to the tool node.

    Agent canvas with an agent node SQL_agent connected to SQL tool SQL_1.

  4. Double-click the SQL node to open the configuration panel.
  5. Provide a name and description for your tool. The description is provided to the agent and helps it decide when to call the tool.
  6. Choose the Query dialect:
    • Spark SQL writes queries against standard AI Data Platform catalogs.
    • Oracle SQL writes queries against external AI Data Platform catalogs.

    Note:

    Spark SQL requires a running Spark cluster in your AI Data Platform Workbench workspace.

    SQL Tool Configuration showing the Spark SQL and Oracle SQL radial options. Spark SQL is selected.

  7. From the Cluster drop-down, select a running Spark cluster. Click Create cluster to provision a new Spark cluster. See Create a Custom Cluster for guidance on creating a new cluster.

    Note:

    The SQL query tool does not automatically start stopped clusters. As a result, the Spark cluster used for your Spark SQL query tool should have a duration of Forever. If the cluster is allowed to spin down on an idle timeout, Spark SQL queries stop working in production once the cluster stops.

    SQL tool node Configuration pane cropped to the Cluster selection drop-down.

  8. Under Browse catalog, use the search field to locate a catalog by name or click through the catalog manager to locate the catalog.

    SQL tool node Configuration pane cropped to the Browse catalog field.

  9. In the Query field, enter your query. Click View Query examples and guide to open a panel containing ready-made patterns you can copy or adapt.

    SQL tool Configuration pane open with Parameters tab selected. Description, Query, View Query examples and guide, and Max rows to return fields are visible.

  10. Select Max rows to return to limit the number of rows returned by your query results.

    Note:

    If your query can return more rows than this limit, consider adding search parameters like {{customer_name}} or {{region}} so the agent can find more specific data.
  11. In the AI Tool definition pane, set the type, default value, and description for the variables set in your query.

    SQL tool Configuration pane open. The Parameters tab is selected and AI Tool definition is visible in the right pane.

  12. Optional: Click the Test tab. Provide test parameters and click Submit. See test results in the Test results pane.

Agent Memory

Agent memory is the part of an AI agent system that lets the agent retain and reuse information across turns, tasks, or sessions.

Unlike the model’s context window, which is temporary and limited to the current prompt, memory can persist facts, preferences, prior decisions, tool outputs, intermediate plans, or observations about the environment.

Agent Memory in AI Data Platform

AI Data Platform provides short-term memory that is limited to the duration of a session. You can configure what can be kept in memory in the Memory tab of your agent.

Single-Agent Memory Configuration

Memory configuration of a single agent system can be found in the Memory tab of the agent node.


The visual builder canvas is displayed with a single agent node, InvoiceAnalyst. The node is selected and the Memory tab is highlighted.

Memory Configuration Description
Enable Agent Memory This setting enables agent memory. When disabled, the agent is essentially a stateless system. Each turn is treated independently, and no follow up question can be asked. We recommend that memory is enabled.
Limit conversation history When this selection is disabled, previous turns will fill up the memory until the model runs out of context and an error is returned. If short sessions are expected, it is ok to disable this setting. However, for most use cases we recommend limiting conversation history.
Truncation configuration If you opt to limit the conversation history, you can decide to truncate the history by:
  • Keeping only the last N messages (user + agent)
  • Setting an overall token budget (first in, first out)
  • Or both, whichever one comes first triggers truncation of the agent memory
Maximum Message Limits If you elect to keep the last N messages, you can set a value of N.
Token budget Alternatively, you can set an overall token budget. First tokens are eliminated to keep the most recent ones in memory.

Multi-agent System Memory Configuration (Supervisor Pattern)

The memory of a multi-agent system is configured in the Memory tab of the supervisor agent.


The visual builder canvas displayed a multi-agent. The AccountsManager node is selected and the Memory tab is displayed.

Memory for a multi-agent system is enforced and cannot be disabled and the memory truncation options displayed in the supervisor agent node only applied to the supervisor agent memory. Each executor agent memory truncation policy can be configured in the executor node Memory tab based on the state isolation policy selected for the entire system.

The multi-agent system memory configuration also allows you to select the memory sharing policy of the executor agents. Three options are possible: Stateless, Private, and Shared. Note that the policy is applied to all executor agents.

State Isolation for Executor Agents Description
Stateless Each executor agent sees only the task assigned by the supervisor. No history is carried over between calls. No follow up request can be made to the supervisor agent by the executor agent.

If stateless is selected, the memory of each executor agent is disabled.

Private Each executor agent sees only its own past interactions.

It cannot see other executor agents or the original user conversation with the supervisor agent.

Shared Executor agents can see the full conversation history across agents and user. All agents work from one shared context.

If shared is selected you can configure the memory truncation policy separately for each executor agent in each agent node Memory tab.

Session Variables

You can use custom, agent-defined session variables to provide additional contextual data points to your agents during a user session.

What are Session Variables?

Custom, agent-defined session variables provide additional contextual datapoints to the agent during a user session. The variables can be used for a variety of purposes, including setting values of parameters in tools, giving overall instructions to an agent, and providing contextual information about the caller and/or the application where the agent is embedded.

Here’s a simplified scenario where we are building a customer support agent. The customer support agent is integrated within a retail website. When a user logs into the retail website, information about that user is captured by the client application (userID, username, geo location, device used, shopping cartID, etc.) and that information could be used by the downstream support agent. Let’s look at an example of how these session parameters could be used within the agent instructions field in AIDP:

You are a customer support agent for the retail website belts-and-buckles.com, specializing in the sales of belts and buckles. Your objective is to answer questions that customers have about their current and past orders, answer questions about items they put in their shopping cart, and answer general questions about belts-and-buckles.com.  
A few guidelines before your start:  
    You are interacting with user {{sessionVariable.userName}}. Always start with a welcome message: Hello {{sessionVariable.preferredSalutation}} {{sessionVariable.userName}}! What’s the weather like today in {{sessionVariable.currentUserGeo}}?  
Three session variables are used in the example above:
  • userName
  • PreferredSalutation
  • currentUserGeo

The agent has no prior knowledge of the user interacting with the retail website, doesn’t know what the user location is or has no context about what’s in the user’s shopping cart. In principle, the client application could know all or a subset of those values and pass those values in a request to the agent. Here's an example of what a request to the agent could look like, including the session parameters.

Note:

This example illustrates what this request could look like. It is not representative of an implementation decision.
"input": [  
{ "role": "user", 
         "content": [  
{ "type": "input_text”,  
	  "text": "What material is the belt Mr Outcast made of?", 
	  “variables”: [“userName”: “Paul”, “preferredSalutation”: “Hon”, “cartID”: NULL, “currentUserGeo”: “Cancun, MX”]  
} 
  ]  
} 
] 

The agent would answer back: “Hello Mr Paul, what’s the weather like today in Cancun, Mx?”

Another use of these session parameters is in setting parameter values in tools. For example, a SQL query could retrieve the content of a shopping cart by using the session parameter {{sessionParam.CartID}} :

Select productID, productName, productDescription, 
productPrice from cartTable where cartID == 
{{sessionVariable.cartID}}  

The session variables are defined by the agent developer when they create their agents and the values of those attributes are set by the client application when a session is created or resumed.

You can configure the following settings when create a new session variable:

Setting Description
Required variable Enable to make this session variable required for each invocation call of the agent. Disabling makes the session variable optional for each invocation call.
Log variable Enable to capture the value of the session variable in logs and traces. Disabling prevents the variable from appearing in logs. We recommend disabling this setting for variables with sensitive data.
Name Name of the session variable. Use a descriptive name to make it easy for you and other users to determine the purpose of the variable.
Default value If defined, the default value is assigned to the session variable if another value is not defined in the invocation call. If left blank, a value must be assigned as part of the invocation call.
Description Description of the session variable. Provide a helpful description so that you and other users are able to understand the function of the session variable.

Example: Using Session Variables in Tools Configuration

You can use a session variable in a SQL tool configuration as part of the SQL query itself.

In this example, the session variable geo is used to filter the result of the SQL query:


The SQL tool window for an agent tool is displayed. The parameters tab is selected and the user is entering {{sessionvariables.ge to select sessionvariables.geo.

You can use session variables and tool parameters within the same query. In the example below, the titleID parameter is set by the agent while the session variable geo is provided by the calling application.


The SQL tool window for an agent is displayed. The parameters tab is open. In the query field, the user has defined 'where market_code= {{sessionvariables.geo}} and title = {{titleID}}'.

System-generated Session Variables

Session variables are automatically generated when a remote MCP server is connected to an agent and that MCP server requires authentication, like a bearer token.


The Add custom MCP server dialog is displayed. The warning message

The session variable holds the value of the bearer token. The name of this system-generated session variable can’t be changed and is a required variable. The system variable is deleted when the MCP node is removed from the canvas.


The Variables tab of an agent is displayed. The details for sessionvariables.cred.mcp.GitHub.bearer are highlighted.

In the Playground, you provide a value for the system generated session variable. In this case, you need to provide a bearer token to use the MCP server. You can select the same (or a different) token that you used during the MCP node configuration.


The Session variables dialog is displayed. sessionvariables.cred.mcp.GitHub.bearer is highlighted and a drop-down list of authentication tokens is displayed.

The same applies if you deploy the agent. You will need to provide an authorization token. For more information, see Assign Values to Session Variables from the Playground.

Example: Assigning Values to Session Variables When Calling a Deployed Endpoint

In this example, you have two session variables: userLocation and UserName the client application is passing session variable values through the metadata field of the body. We'll demonstrate how you can assign values through Python and through the OCI CLI.

If you use the Python requests library, the payload is the following:

body = { 

            "isStreamEnabled" : False, 

            "trace" : False, 
            "input" :[{ 
                "role":"User", 
                "content":[{ 
                    "type" : "INPUT_TEXT", 
                    "text" : “Hello how can you help me?”                  
                }] 
            }], 

            "metadata": { 
            "sessionvariables.userLocation": "Canada",  
            "sessionvariables.UserName": "George" 
        } 
        } 

response = requests.post( 
url = <insert-chat-url>,  
params = None,  
auth = <insert-oci-signer>, 
json = body, 
headers={“x-session-id": <insert-a-session-key>,} 
)  

Alternatively, if you use the OCI CLI, the payload is the following:

oci raw-request \ 
  --http-method POST \ 
  --auth security_token \ 
  --request-body '{ 
    "isStreamEnabled": false, 
    "input": [ 
      { 
        "role": "user", 
        "content": [ 
          { 
            "type": "INPUT_TEXT", 
            "text": "Hello how can you help me?" 
          } 
        ] 
      } 
    ], 
    "metadata": { 
      "sessionvariables.userName": "George", 
      "sessionvariables.userLocation": "Canada"}" 
    } 
  }' \ 
  --request-headers '{ 
    "x-session-id": "george-session-may11" 
  }' \ 
  --target-uri "<insert-your-agent-flow-uri>" 

Create a Session Variable in the Agent Variables Tab

You can create a new session variable and add it to your agent from the Variables tab.

  1. Navigate to the agent you want to add a session variable to.
  2. Click the Variables tab.

    Agents page open with the Variables tab highlighted.

  3. Click New session variable icon Add session variable.

    Create session variable dialog is displayed.

  4. Select if your session variable is a required variable.
  5. Select whether the value of your session variable should be recorded in logs and traces. Leave this setting disabled for sensitive data.
  6. Provide a meaningful name and description for your session variable.
  7. Provide a default value for your session variable. The default value is assigned to the session variable if no other value is assigned as part of the invocation call.
  8. Click Create.

Refer to Session Variables in Agent Flow Instructions

You can refer to session variables in agent instructions and tool configurations, including the SQL and Prompt tool query.

  1. Navigate to your agent flow.
  2. Click the SQL or Prompt tool node in the Playground.

    The SQL Tool node in an agent flow is selected. The Parameters tab is selected and the user is shown entering {{sessionvariables. to display a list of session variables they can select.

  3. In the Query field, start typing {{sessionvariables.
  4. Select the session variable from the list of existing session variables.

View Agents and Tools using a Session Variable

You can view a list of agents and tools using a specific session variable from the Variable tab in your agent flow.

  1. Navigate to an agent flow using the session variable you want to view related agents and tools for.
  2. Click the Variable tab.
  3. Next to Used in: for your session variable, click the drop-down menu. A list of agents and tools using the session variable is displayed.

Assign Values to Session Variables from the Playground

You can assign values to session variables at any time from the Playground tab.

  1. Navigate to your agent flow.
  2. At the top of the Playground, click Session parameters icon Session Parameters. A list of all session variables in your agent flow is displayed.

    Agent flow open with the Playground selected. The Session Parameters button is highlighted.

  3. Modify your session variables. After resuming your Playground session, the last assigned session variables values are used.

    Session variables dialog

Guardrails

Guardrails are safety mechanisms to guide and control the behavior of AI agents.

In Oracle AI Data Platform Workbench, guardrails are configured to prevent the generation or consumption of toxic and malicious content by agent flows. Guardrails also prevent the leakage of personally identifiable information (PII) by the agent flow. The specific guardrails available in your AI Data Platform Workbench apply to content moderation, prompt injection, and PII.

Note:

Guardrails offered by Oracle AI Data Platform Workbench are only available in English.

The Guardrails offered in AI Data Platform Workbench are implemented by the OCI Generative AI service team. See Guardrails for OCI Generative AI. Based on your guardrails configuration, the AI Data Platform Workbench service invokes the Apply Guardrails API within your OCI tenancy.

Guardrails in Visual Flow Canvas

By default no guardrails are applied to your system beyond the model provider’s native safety controls. To add guardrails, you must drag a guardrails node to your agent visual flow builder and connect it to the agent.

A guardrails node can filter traffic between a chat trigger and an agent node, between a supervisor and executor agents, or between agent and tool nodes. For most scenarios, we recommend a single guardrails node between the chat trigger and the agent node. This will ensure that any messages from the incoming user and messages generated by the agent will be filtered through the guardrails.


An agent open to the visual builder. The guardrails node is highlighted in the palette.

The guardrails node can only be inserted between:
  • A chat trigger node and an agent (supervisor or executor)

What Guardrails are Available?

The diagram below shows a simple interaction between an end user and an agent. In this scenario, all guadrails are applied (content moderation – CM, prompt injection prevention – PI, and PII detection – PII). PI is only applied to the user query.

After the second message issued by the end user, a PI attempt was detected and the user message was blocked following the agent developer’s selected action on PI detection (block).


Diagram describing an example of AI agent flow guardrails

Content Moderation

Content moderation is a common implementation of guardrails in most generative AI. Unchecked, LLMs can generate harmful content, promote violent, racist, and sexually explicit content. It is imperative to give agent developers full visibility and control over how user interactions with agents are monitored and scanned for potentially harmful content. Content moderation prevents hateful, sexual, violent, toxic, derogatory, or harassment-based content from being considered or generated by the agent flow. Our guardrails model classifies content along those six categories and flags content that belong to one of those categories.

You can choose to take an action on either the user input query or the model response:
  • Block: You prevents the agent from processing the user input and generating a response. Users receive an error response from the agent flow.
  • Inform: You allow the agent flow to process the user input and generate a response. The agent notifies the user that either the input or the response contained content that met guardrail criteria.
  • Allow: You allow processing and/or generating of potentially harmful content by the agent flow.

The Block action is selected for content moderation when you create an agent flow. Oracle recommends keeping Block as your guardrail selection for content moderation.

Prompt Injection

Prompt injection guardrails for AI agents are a protective mechanism that detects, prevents, and mitigates malicious or unintended instructions embedded within user inputs. Prompt injection attacks try to override or subvert the agent’s original instructions, policies, or goals by inserting hidden text that tells the model to ignore previous rules, exfiltrate secrets, or execute unauthorized actions.

You can choose the same actions that can take for content moderation: block, inform, or allow. The prompt injection guardrails only apply to the user input query.
  • Block: You prevent the agent from processing the user input. Users receive an error response from the agent flow.
  • Inform: You allow the agent flow to process the user input . The agent notifies the user that the input contained content that met guardrail criteria.
  • Allow: You allow processing of potentially harmful content by the agent flow.

The Block action is selected prompt injection when you create an agent flow. Oracle recommends keeping Block as your guardrail selection for prompt injection.

Personally Identifiable Information (PII)

The PII guardrails automatically detects, blocks, or mask PII from either the user input queries or the agents responses. This guardrail prevents the agent from exposing sensitive user information in ways that violate privacy regulations or organizational policies.

PII guardrails support four entity types:
  • Email
  • Telephone number
  • Physical address
  • Person name
For each one of those four entities, you choose to apply which of of the follow actions your agent takes on the input user query or agent response:
  • Block: You prevent the agent from processing the user input and generating a response. Users receive an error response from the agent flow.
  • Inform: You allow the agent flow to process the user input and generate a response. The agent notifies the user that either the input or the response contained PII.
  • Mask: You allow the agent flow to process the input and generate a masked response. Any PII used is redacted to prevent exposure.
  • Allow: You allow processing and/or generating of PII data by the agent flow.

In a new agent flow, PII is allowed in both user input and response by default. Oracle recommends you carefully select the guardrail for PII based on your security needs.

Enable Specific Guardrails in a Node

You can choose which guardrails to enable and how each is configured when adding a guardrail node to your visual canvas.

  1. Navigate to the agent flow in your workspace.
  2. Drag a Guardrails node from your palette to your canvas.
  3. Provide a meaningful name and description for the node.

    Guardrails configuration page is open. The name and description are highlighted.

  4. Toggle a guardrail to enable it and begin configuring. Pressing the toggle again disables the guardrail and its configurations.

    Guardrails configuration. The toggle for Content moderation prevention is highlighted.

  5. Select the needed guardrail configuration for each category.

    Guardrails configuration page is displayed. The toggles for Content moderation prevention and Prompt injection detection are enabled and highlighted. Input and Output options are set to block and Block is highlighted.

Create an AI Cluster for an Agent

You can create a new AI cluster directly from the agent interface and attach it immediately.

For more information, see AI Compute.
  1. On the Home page, navigate to your agent.
  2. Click Compute then click Create a new AI compute.
  3. Provide a name and description for your AI compute cluster.
  4. Select the number of OCPUs and memory size for your AI compute cluster.
  5. Click Create.

Attach an Existing AI Cluster to an Agent

You can attach an AI cluster you've previously created to an agent on which you have at least USE permissions.

  1. On the Home page, navigate to your agent.
  2. Click Compute then click Attach to AI Compute.
  3. Click on the cluster you want to use from the list.
    Your agent shows AIcompute: (ClusterName) running when it has been successfully attached. This can take up to several minutes.

Detach an Agent from AI Compute

You can detach an agent from an AI compute. Detaching the AI compute removes the agent code running on the attached compute and prevents testing.

Note:

Detaching an agent from AI compute does not delete the agent. You can resume building and testing the agent by attaching it to the same or different AI compute.
  1. On the Home page, navigate to your agent.
  2. Click Compute then click Detach from AI Compute.

    Cropped image of the top of Agent page. Compute action menu is open with Detach from AI Compute highlighted

A2A Agent Deployment

The Agent2Agent (A2A) protocol is an open standard for communication between independent AI agents, including agents built with different frameworks, hosted by different vendors, or running as opaque remote systems.

Its purpose is to give those agents a shared interaction model so they can discover each other’s capabilities, negotiate supported input/output formats, delegate or collaborate on tasks, and exchange information securely without exposing internal memory, tools, or implementation details. For more information, see Agent2Agent (A2A) Protocol.

A2A is meant to solve agent interoperability: instead of every agent integration being custom, a client or another agent can interact with any A2A-compliant remote agent using a common set of concepts and operations. The spec centers on messages, tasks, parts, artifacts, streaming updates, and push notifications; it supports synchronous replies, long-running asynchronous work, streaming, and enterprise-style auth/security patterns.

In Oracle AI Data Platform, all deployed agents are provided with an /a2a invocation path that can be called by A2A client applications.

What is an Agent Card?

An Agent Card is a JSON metadata document published by an A2A server. In AIDP, the A2A server is the AI compute hosting your agent deployment.

The card describes the agent’s identity, service endpoint, supported protocols/transports, capabilities, skills, supported input/output modes, and authentication requirements; clients use it to discover whether the agent is suitable and how to call it. A properly documented agent card is a requirement of the A2A protocol.

Agent cards in AI Data Platform Workbench are either in Draft state, meaning the agent has not been deployed, or Published, meaning the card was deployed alongside the agent.

Agent Card Actions

During the development of an agent, the card is available in the Actions menu of the agent.

Two agent cards are accessible:
  • The draft card reflects the current state of the agent in development.
  • The published card corresponds to a snapshot of the card taken when the agent was deployed. The published card reflects the state of the deployed agent.

Agent Card Fields

AI Data Platform Workbench supports a subset of the current A2A protocol agent card fields, available here: A2A Protocol - Agent Card.

Field Required Description
name Yes A human readable name for the agent. Example: "Recipe Agent"
description Yes A human-readable description of the agent, assisting users and other agents in understanding its purpose. Example: "Agent that helps users with recipes and cooking."
Agent Version Yes The version of the agent. Example: "1.0.0"
Documentation URL No A URL providing additional documentation about the agent.
Provider - Organization No The service provider of the agent.
Provider - URL No The URL of the service provider.
Capabilities Yes A2A Capability set supported by the agent.

Only streaming can be configured (True/False)

Skills Yes Skills represent the abilities of an agent. It is largely a descriptive concept but represents a more focused set of behaviors that the agent is likely to succeed at. Skills represent an array of AgentSkill.

Each AgentSkill is made of several fields documenting the capabilities of the agent. Defining the agent skills in the agent card is the most time consuming operations and is an iterative process. Skills can be edited (along with the rest of the agent card) in the draft agent card prior to deployment.

Note:

inputModes, outputModes, and securityRequirements are provided by AI Data Platform Workbench and cannot be modified.
Field Required Description
Skill ID Yes A unique identifier for the agent's skill.
Skill Name Yes A human-readable name for the skill.
Description Yes A detailed description of the skill.
Tags Yes A set of keywords describing the skill's capabilities.
Examples No Example prompts or scenarios that this skill can handle.

Agent Deployment Endpoint A2A Path

An /a2a path is exposed in the URL of a deployed agent in addition to /chat.

For example, an agent will expose these paths to external clients:

  • https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/chat
  • https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/a2a

Both paths (/chat, /a2a) can be consumed by separate clients.

Session Variables in A2A

Values of session variables can be passed to an A2A agent in the message metadata field. The JSON snippet below shows the payload of a user message issued to the a2a agent with three session variables: userName, geoLocation, and os:

{
  "jsonrpc": "2.0",
  "method": "message/send",
  "params": {
    "contextId": "session_12345",
    "taskId": "task_67890",
    "message": {
      "role": "user",
      "parts": [
        {
          "text": "What is the current status of my order?",
        }
      ],
      "metadata": {
        "sessionvariables.userName": "George",
        "sessionvariables.geoLocation": “Dallas, TX”,
        "sessionvariables.os": "mobile_ios"
      }
    }
  },
  "id": "rpc-99821"
}

Example: Invoking an A2A Agent with OCI CLI (Non-streaming)

oci raw-request \
  --http-method POST \
  --auth security_token \
  --request-body '{
    "id": "<your-request-id>",
    "jsonrpc": "2.0",
    "method": "message/send",
    "params": {
      "configuration": {
        "acceptedOutputModes": [
          "text/plain",
          "text"
        ]
      },
      "message": {
        "contextId": "<your-context-id>",
        "kind": "message",
        "messageId": "<your-message-id>",
        "parts": [
          {
            "kind": "text",
            "text": "What is the capital of India?"
          }
        ],
        "role": "user"
      }
    }
  }' \
  --request-headers '{
    "x-session-id": "<your-session-id>",
    "dh-user-principal": "<your-user-principal>"
  }' \
  --target-uri " <your-a2a-agent-endpoint-url>"

Example: Invoking an A2A Agent with OCI CLI (Streaming)

oci raw-request \
  --http-method POST \
  --auth security_token \
  --request-body '{
    "id": "<your-request-id>",
    "jsonrpc": "2.0",
    "method": "message/stream",
    "params": {
      "configuration": {
        "acceptedOutputModes": [
          "text/plain",
          "text"
        ]
      },
      "message": {
        "contextId": "<your-context-id>",
        "kind": "message",
        "messageId": " <your-message-id>",
        "parts": [
          {
            "kind": "text",
            "text": "What is the capital of India?"
          }
        ],
        "role": "user"
      }
    }
  }' \
  --request-headers '{
    "x-session-id": "<your-session-id>",
    "dh-user-principal": "<user-principal>"
  }' \
  --target-uri "<your-a2a-agent-endpoint-url>"

Example: A2A Client SDK

import asyncio
import json
import logging
import typing
from collections.abc import Iterator
import uuid
import httpx
import oci
from a2a.client import A2AClient, ClientFactory
from a2a.types import (
    AgentCard,
    Message,
    Part,
    Role,
    TextPart,
    SendMessageRequest,
    MessageSendParams,
    MessageSendConfiguration,
    Task, SendMessageSuccessResponse, SendStreamingMessageRequest,
)

class OCIAuth(httpx.Auth):
    """httpx auth implementation using OCI signer via requests auth adapter."""

    def __init__(self, signer: oci.signer.AbstractBaseSigner):
        self._requests_auth = _OCIRequestsAuth(signer)

    def auth_flow(self, request: httpx.Request) -> Iterator[httpx.Request]:
        req = RequestsRequest(
            method=request.method,
            url=str(request.url),
            headers=dict(request.headers),
            data=request.content,
        )
        prepared: RequestsPreparedRequest = req.prepare()
        prepared = self._requests_auth(prepared)
        request.headers.update(dict(prepared.headers))
        yield request



def getOCIAuth():
    conf = oci.config.from_file(profile_name="DEFAULT")
    token_file = conf['security_token_file']
    token = None
    with open(token_file, 'r') as f:
        token = f.read()
    private_key = oci.signer.load_private_key_from_file(conf['key_file'])
    signer = oci.auth.signers.SecurityTokenSigner(token, private_key)
    auth = OCIAuth(signer=signer)
    return auth


async def _call_agent_with_a2a(agent_url: str, query: str, context_id: str,auth:OCIAuth) -> str:
    """Call an agent using the A2A protocol."""
    try:
        # Initialize OCI signer
        #headers = {"dh-user-principal": "dh-user"}
        headers = {"Accept": "*/*",
                   "dh-user-principal": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}

        async with httpx.AsyncClient(timeout=60.0, auth=auth,headers=headers) as hc:
            agent_card = await _get_agent_card(agent_url,auth)
            print(f"Agent card is {agent_card}")

            client =  A2AClient(httpx_client=hc, agent_card=agent_card)
            # Create message
            message = Message(
                message_id=str(uuid.uuid4()),
                context_id=context_id,
                role=Role.user,
                parts=[Part(root=TextPart(text=query))],
                metadata={"sessionvariables.cred.mcp.weatherReportMCP.bearer": "valid-123"}
            )
            request = SendMessageRequest(
                id=str(uuid.uuid4()),  # Add the required id field
                params=MessageSendParams(
                    message=message,
                    configuration=MessageSendConfiguration(acceptedOutputModes=["text/plain", "text"]),
                ),
            )
            #json_string = json.dumps(message, indent=4)
            print(f"Send request : {request}")

            response = await client.send_message(request)

            logging.info("Received response from A2A server: %s", response.root.result)
            # Extract response
            result = response.root.result
            # Handle different response types


            if isinstance(result, Task):
                # Task response
                if result.artifacts:
                    # Extract text from artifacts
                    texts = []
                    for artifact in result.artifacts:
                        for part in artifact.parts:
                            if hasattr(part, "root") and hasattr(part.root, "text"):
                                texts.append(part.root.text)
                    return "\n".join(texts) if texts else "Task completed with no text response"
                elif result.status and result.status.message:
                    logging.info(f"Received Task status {result.status.state} from A2A server and status message is {result.status.message}", result.status.message)
                    if  result.status.state== "failed":
                        print("Failure observed in Task invocation")
                        for m_part in result.status.message.parts:
                           print(f"Error message  { m_part.root.text}")

                    return get_message_text(result.status.message)
                else:
                    return f"Task {result.id} status: {result.status.state if result.status else 'unknown'}"

            elif isinstance(result, Message):
                return get_message_text(result)
            else:
                logging.warning(f"Unexpected response type: {type(result)}")
                return "Received response but unable to extract text"
    except Exception as ex:
        logging.error(f"Error calling agent at {agent_url}: {ex}", exc_info=True)
        return f"Error communicating with agent: {str(ex)}"


async def _call_agent_with_a2a_with_stream(agent_url: str, query: str, context_id: str, auth: OCIAuth) -> str:
    """Call an agent using the A2A protocol with streaming (SSE) and return the final artifact text."""
    try:
        async with httpx.AsyncClient(timeout=60.0, auth=auth) as hc:
            agent_card = await _get_agent_card(agent_url)
            if not agent_card:
                return "No Agent Card Found"
            print(f"Agent card is {agent_card}")

            client = A2AClient(httpx_client=hc, agent_card=agent_card)
            message = Message(
                message_id=str(uuid.uuid4()),
                context_id=context_id,
                role=Role.user,
                parts=[Part(root=TextPart(text=query))],
            )
            request = SendStreamingMessageRequest(
                id=str(uuid.uuid4()),
                params=MessageSendParams(
                    message=message,
                    configuration=MessageSendConfiguration(acceptedOutputModes=["text/plain", "text"]),
                ),
            )
            print("Invoking Remote Agent request (beautified JSON):")
            print(json.dumps(request.model_dump(), indent=2, ensure_ascii=False))
            # Expected event types:
            # - TaskStatusUpdateEvent (working/in-progress)
            # - TaskArtifactUpdateEvent (contains Artifact.parts[].root.text) -> final output
            final_artifact_text_parts: list[str] = []

            async for event in client.send_message_streaming(request):
                # Print each SSE event as-is (SDK object)
                print(f"[A2A stream event] {event}")

                try:
                    result = getattr(event.root, "result", None)
                    if not result:
                        continue

                    # TaskArtifactUpdateEvent and TaskStatusUpdateEvent are SDK types; to avoid tight coupling,
                    # extract by attribute presence.
                    artifact = getattr(result, "artifact", None)
                    if artifact and getattr(artifact, "parts", None):
                        for part in artifact.parts:
                            root = getattr(part, "root", None)
                            txt = getattr(root, "text", None)
                            if txt:
                                final_artifact_text_parts.append(txt)
                except Exception:
                    # Keep streaming even if an event can't be parsed
                    continue

            return "\n".join([t for t in final_artifact_text_parts if t]).strip() or "Stream completed (no artifact text)."
    except Exception as ex:
        logging.error(f"Error calling agent at {agent_url}: {ex}", exc_info=True)
        return f"Error communicating with agent: {str(ex)}"

Edit a Draft Agent Card

You can edit the agent card for an agent that is not yet deployed.

  1. Navigate to your agent.
  2. Click on Actions, then click View agent card and Draft agent card.

    Agent flow visual builder is displayed. The Actions menu and View agent card sub-option are selected. Draft agent card is highlighted.

  3. Click Edit.

    Draft agent card dialog is displayed. The Edit button is highlighted.

  4. You can switch the view by clicking Form or JSON in the top-right. The JSON view is more complete, but read-only. You can only edit fields in the Form view.

    Edit agent card dialog is displayed. The JSON and Form view icons are highlighted. JSON view is selected.

  5. Modify fields as needed.
  6. Click Add a skill to add skills you want to expose to A2A clients.

    Edit agent card dialog is displayed. The Add a skill button is highlighted.

  7. Click Save.

Edit a Published Agent Card

You can modify a published agent card without having the undeploy or redeploy an agent.

The published card corresponds to a snapshot of the draft card at the time of deployment.

Note:

Changes you make to a published card are immediately reflected in the agent-card.json file accessible to A2A clients.
  1. Navigate to your agent.
  2. Click on Actions, then click View agent card and Published agent card.

    Visual builder canvas is displayed. The Actions menu and View agent card sub-option are selected. Published agent card is highlighted.

  3. You can switch the view by clicking Form or JSON in the top-right. The JSON view is more complete, but read-only. You can only edit fields in the Form view.
  4. Click Edit.

    Published agent card dialog is displayed. The Edit button is highlighted.

  5. Modify fields as needed.
  6. Click Add a skill to add skills you want to expose to A2A clients.

    Edit agent card dialog. Warning stating "This card is attached to a live agent; updates will impact the deployed agent card." and Publish changes button are highlighted.

  7. Click Publish changes.
Published agent cards are not publicly available. A user needs to be authenticated and have the right permission (READ) to inspect the content of agent-card.json. Other agents can discover your agents capabilities and metadata via an HTTP GET request on the standard path:
https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/a2a/agent-card.json

Agent Deployment

Deploying an agent turns your agent into a hosted application.

You can deploy an agent into the same AI compute attached to its playground or to a different AI compute. When you deploy the latest changes to your agent to the attached AI compute, the deployed agent represents a snapshot of the agent at the time of deployment. To update the deployed agent to the latest version, you need to redeploy the agent.

Each agent has a stable deployment URL that depends on the unique agent key. Re-deploying the agent multiple times overwrites the agent behind the deployment URL.

Deploying your agents has the following limitations:
  • An agent can only be deployed to one AI compute cluster at any given time.
  • Deploying the same agent multiple times to the same AI compute cluster overwrites the previously deployed iteration of the agent.

Once you've deployed an agent, you can retrieve the chat URI to programmatically issue queries and retrieve responses from the agent from the Details tab of your agent.


Agent page open with Detail tab open and highlighted. Deployed to AI Compute and Endpoint URL are highlighted

The endpoint URL is stable and it is tied to each agent. The URL includes the unique agentID assigned to each agent. In other words If you undeploy an agent and deploy it again, the URL remains the same. The benefit is that you don’t have to modify the client code calling the endpoint, the drawback is that you can overwrite an agent in production.

The URL has the following structure:
https://gateway.aidp.{oci-region}.oci.oraclecloud.com/agentendpoint/{agentId}/{protocol}
where:
  • oci-region corresponds to the AI Data Platform instance region;
  • agentId is the unique id associated with the agent
  • protocol is the communication protocol: chat which follows the OpenAI Responses API format and a2a which follows the agent-to-agent communication protocol. Both protocols are available for each agent endpoint. For more information, see A2A Agent Deployment.

Note:

Two AI computes are listed in the Details tab. The Attached to AI Compute is used to test the agent in the playground. The Deployed to AI Compute hosts the deployed agent.

The endpoint URL field is populated after you deploy your agent. You can call this endpoint URL from your production application.

Deploy an Agent

You deploy agents you have created and configured so other users are able to see and use it in your AI Data Platform instance.

  1. On the Home page, navigate to the folder that contains the agent you want to deploy.
  2. Next to the agent, click Actions three dot icon Actions and click Deploy. You can also click the agent name and click Deploy in the top right.

    Agent open with Deploy button in top right of screen highlighted

  3. Select the AI compute to attach to the deployed agent.
  4. Select AIDP Workbench for the authorization type.
  5. Select a session data retention policy.
    • For Retention period, provide the number of days session data is retained for.
    • For Session size limit, provide the maximum size a session can reach.
    • For Thread count limit, provide the maximum number of session threads that are retained.
  6. Click Deploy.

Deploy an Agent with OAuth2

You can deploy agents you have created and configured to use OAuth2 authentication to connect to external identity providers.

  1. On the Home page, navigate to the folder that contains the agent you want to deploy.
  2. Next to the agent, click Actions three dot icon Actions and click Deploy. You can also click the agent name and click Deploy in the top right.

    Agent open with Deploy button in top right of screen highlighted

  3. Select the AI compute to attach to the deployed agent.
  4. Select OAuth2 for the authorization type.
  5. Provide the Audience claim. AI Data Platform Workbench automatically populates this field, but you can replace it with an audience claim from your Identity provider.
  6. Provide the Issuer claim and URI to retrieve JWKS. This information is derived from your Identity provider.
  7. Select a session data retention policy.
  8. Click Deploy.

Invoke a Deployed Agent

You can invoke the endpoint URL of your agent from your production application.

Regardless of the programmatic interface used to invoke the agent endpoint, you must be authenticated with OCI and have the relevant permissions. In the case of Agent Flow endpoints, the caller needs to have at least USE permission on the agent endpoint.

The endpoint URI is documented in the details tab of the agent UI. You can copy that endpoint URI into your code to invoke the agent.


Details page for an agent open with the Endpoint URI field highlighted

Methods to Invoke Endpoint URIs

You can invoke the agent endpoint URI through different tools, SDKs, and CLIs.

The following methods allow you to invoke your endpoint URI in Oracle AI Data Platform Workbench agents.

Invoke with OCI CLI

The provided example demonstrates how you use the OCI CLI and authenticate with a security token. Replace <your-agent-flow-endpoint-uri> with your agent endpoint URI and <security_token> with your OCI security token.
oci raw-request
--http-method POST
--target-uri <your-agent-flow-endpoint-uri>
--request-body '{"query":"Tell me about the Ryder Cup in 1985"}'
--auth <security_token>

Invoke with Python Request Library

You can use the OCI Python SDK to create a signer to authenticate with OCI. The Python requests library can be used to post a request to the agent endpoint URI and return a response. The following example demonstrates how you can use your user principal through the OCI config and private key files:
import oci import requests import json import uuid from contextlib import closing from requests import Request, Response
class AuthHelper: """ AuthHelper allows creating an OCI signer with either API key or security_token (which are short term sessions) """ def init(self, oci_profile: str, use_security_token:bool = True): config = oci.config.from_file(file_location="/Volumes/jr/default/misc/config",profile_name=oci_profile) if use_security_token: with open(config["security_token_file"], 'r') as f: token = f.read() private_key = oci.signer.load_private_key_from_file(config["key_file"])
 self.signer = oci.auth.signers.SecurityTokenSigner(token, private_key) else: self.signer = oci.signer.Signer( tenancy=config["tenancy"], user=config["user"], fingerprint=config["fingerprint"], private_key_file_location=config["key_file"], #pass_phrase=config.get("pass_phrase"), #private_key_content=config.get("key_content") )
@property
def Signer(self):
    return self.signer
 
class MyRawJsonRpcClient: """ Simple class using requests lib to post JSON to chat endpoint using OCI signing """ def init(self, chat_url:str, oci_profile: str, sessionKey:str, use_security_token:bool = True): self.authhelper = AuthHelper(oci_profile=oci_profile, use_security_token=use_security_token) self.authsigner = self.authhelper.Signer self.chat_url = chat_url self.sessionKey = sessionKey
def send(self, input:str) -> Response:
    body = {
        "isStreamEnabled" : False,
        "sessionKey" : self.sessionKey,
        "trace" : False,
        "input" :[{
            "role":"User",
            "content":[{
                "type" : "INPUT_TEXT",
                "text" : input                   
            }]
        }]
    }

    response:Request = requests.post(
        url =self.chat_url,
        params = None,
        auth = self.authsigner,
        json=body,
        headers={}
    )
    return response
You can call the agent endpoint URI by instantiating the MyRawJsonRPCClient class and providing an OCI profile value (found in the OCI config file), the agent endpoint URI (chat_url) and a sessionKey. You can provide any arbitrary sessionKey. sessionKey is the unique identifier of the user session with the agent. If you keep re-using the same sessionKey, user messages and agent responses are appended to the same conservation.
client = MyRawJsonRpcClient(chat_url="<your-agent-flow-endpoint-uri>",
   oci_profile = "DEFAULT",
   sessionKey= “<your-session-key>”,
   use_security_token = False )
You can also provide a user message and use the client to send the message to the agent endpoint URI:
user_input = f"Hello, tell me a good dad joke."
r = client.send(input = user_input)
response_json = r.json()

Through APEX

You can use the code sample available in the AI Data Platform Workbench Samples Github repository. The sample walks you through the process of calling an agent deployment endpoint from an APEX application.

Through Streamlit

You can use the code sample available in the AI Data Platform Workbench Samples Github repository. The sample walks you through the process of calling an agent deployment endpoint from an Streamlit application.

Best Practices - Async and Non-async Responses

We recommend that you write your client code assuming async responses. For example:

import httpx 
 
async def fetch_data(): 
    async with httpx.AsyncClient() as client: 
        response = await client.get(URL) 
        return response.json()

Undeploy an Agent

You can choose to undeploy agents you have MANAGE permissions for, making them unavailable for use.

  1. On the Home page, navigate to the folder that contains the agent you want to undeploy.
  2. Next to the agent, click Actions three dot icon Actions and click Undeploy.

    Cropped image of the top of the agent with Undeploy button highlighted

  3. Click Undeploy.

Monitor Agents

You can monitor details relating to the sessions and metrics of your agents to see information about how it's being used, the resources it consumes, and more.

You have multiple tabs in your agent for tracking usage details, the Sessions tab, Metrics tab, and Activity tab. You can find them at the top of your agent canvas.

Traces and Spans

Traces provide you with observability for your agents by capturing and displaying the flow of agent requests. Spans are the objects that make up a trace. Each span is a different step in the flow, such as chat prompts from a user, agent invocations, and workflow tasks.

You can see traces for the current session or test run or previous sessions. To see the current session trace, go to the Flow tab and click Playground. The Details pane at the bottom of the page displays the trace of the current session in the left pane. You can click on objects in the trace to expand them or view more detailed information. In the right pane, you can click the Info, Details, or Events tabs to learn more about the selected span object.

You can see traces for previous sessions in the Sessions tab by clicking the name of the session.

Sessions

In the Sessions tab, you can see a history of sessions for this agent. You can see if each session succeeded or failed, the URI origin, when the session was started, the duration of the session, and the tokens used in the session. You can click session ID for more specific details about that session and to see traces for that specific sessions.

You can filter the displayed sessions by using the Search bar to filter by session ID or URI origin, using the date filters to show only a specific date range, and the Session status drop-down menu to filter by whether a session succeeded or failed.

Metrics

The Metrics tab shows a summary of usage data for all agent sessions. The Date range dropdown filters the time period you want to see summarized in the displayed cards. The URI selection filters the URI selection source you want to see the details for. You can modify which cards are displayed and whether or not they include graphs as visual representations of usage.

Activity

The Activity tab shows a summary of agent deployment status. The Operation column specifies the type of deployment operation (Deploy or Undeploy) and the Status column specifies the outcome of the operation (Success, Error, Warning, Failed). You can see who initiated the operation and when as well as the status message associated with the operation outcome.

View Agent Sessions

You can view a history of sessions for you agent and filter the results to see trends and assist with troubleshooting.

  1. On the Home page, navigate to your agent.
  2. Click the Sessions tab.
  3. Use the filters to change the displayed sessions.

View Agent Metrics

You can view summarized details of your agent is used, such as token usage, session durations, latency, and more.

  1. On the Home page, navigate to your agent.
  2. Click the Metrics tab.
  3. Select different options from the Date range dropdown to see how metric differ across timelines.
  4. Select different options from the URI selection dropdown to filter for specific URI sources.

Move an Agent

You can move agents you own or have MANAGE permissions for.

  1. On the Home page, navigate to the folder that contains the agent you want to move.
  2. Next to the agent you want to modify, click Actions three dot icon Actions and click Move .
  3. Select the new workspace location for the agent. Click Move.

Copy an Agent

You can copy an agent you own or have MANAGE permissions for to another location an available workspace.

You can copy agents to the same or different folder. Agent flows can be copied to folders in different workspaces to which you have access. The agent configuration, as well as tool and guardrail settings, are copied. AI compute cluster attachments are not copied and you need to attach the agent to a new AI compute cluster to resume development.
  1. On the Home page, navigate to the folder that contains the agent you want to move.
  2. Next to the agent you want to modify, click Actions three dot icon Actions and click Copy to workspace.
  3. Provide a new name and description for the copied agent, if necessary.
  4. Click Browse and select a new location in the workspace to copy the agent to. Click Select.
  5. Click Copy.

Download Agent Files

You can download agent files and their guardrail files that contain the definitions for that agent.

Agent files are JSON files with the file extension AFLOW and contain the definitions for your agent. Guardrails files are labeled _guardrails.JSON and contain the guardrail definitions for the agent.
  1. Navigate to the agent folder in your workspace.
  2. Click the name of the agent you want to download.

    AI Data Platform Workbench workspace page open to file manager. Agent flow folder agent4 selected with actions menu open for .aflow file and Download button highlighted

  3. Next to the AFLOW file for your agent, click Actions three dot icon Actions then click Download. The file is downloaded to your local machine.
  4. Next to the _guardrails.JSON file, click Actions three dot icon Actions then click Download. The file is downloaded to your local machine.