Oracle Generative AI Multi-Agent Reasoning Orchestrator SDK
Multi-agent workflows built for production.¶
Describe the task. Locus selects the protocol, coordinates the agents, and runs every consequential action through a policy you wrote before the side effect happens.
direct answer · pipeline · fan‑out · debate · code + test · approval gate · A2A · handoff
- From idea to production agent in minutes, not weeks. Describe the task; Locus picks the pattern and assembles the network from eight production-tested protocols.
- The model never holds the trigger. A refund, a deploy, a deletion — every consequential action clears
admit()first: real code, outside the model, on an audit trail you can verify. - Self-critiquing agents with grounded outputs. Every turn is scored; every claim is verified against the tool result that produced it, or the agent abstains.
- Oracle Cloud, first-class. OCI Generative AI with automatic transport routing, Oracle Database 26ai for RAG, durable threads and long-term memory — and every other provider through the same
Agent.
Built inside Oracle · Used in production · Open source (UPL-1.0)
import asyncio
from locus.agent import Agent
from locus.observability import get_event_bus
from locus.observability import run_context
from locus.tools import tool
@tool
def get_metric(name: str) -> float:
"""Current value of an SRE metric."""
return monitoring.read(name)
@tool
def fetch_runbook(topic: str) -> str:
"""Runbook section for a topic."""
return wiki.fetch(topic)
@tool(idempotent=True)
def page_oncall(reason: str) -> str:
"""Page on-call. Fires once per reason."""
return pager.send(reason)
agent = Agent(
model="oci:openai.gpt-5", # OCI GenAI
tools=[get_metric, fetch_runbook, page_oncall],
reflexion=True, # self-evaluates every turn
grounding=True, # claims checked vs tool output
)
async def main() -> None:
async with run_context() as rid:
task = "p99 on checkout-api hit 4.2s. Investigate."
result = await agent.run(task)
bus = get_event_bus()
async for ev in bus.subscribe(rid):
match ev.event_type:
case "agent.tool.started":
print("🔧", ev.data["tool_name"])
case "agent.tool.completed":
print("✓ ", ev.data["tool_name"])
case "agent.terminate":
print("■ ", result.text[:60])
asyncio.run(main())
Your first agent in five lines¶
from locus.agent import Agent
agent = Agent(model="oci:openai.gpt-5")
print(agent.run_sync("What is the capital of France?").text)
# → Paris
That's the entire interface. Agent handles the model call, the response,
and any retries. Swap oci:openai.gpt-5 for openai:gpt-4o,
anthropic:claude-sonnet-4-6 or bedrock:us.amazon.nova-lite-v1:0 — the
call stays the same. With an OCI profile in ~/.oci/config, every notebook
runs against OCI Generative AI with no further setup.
Add a tool, and the agent loops Think → call tool → Think → answer until it's done:
from locus.agent import Agent
from locus.tools import tool
@tool
def get_weather(city: str) -> str:
"""Return the current weather for a city."""
return weather_api.fetch(city)
agent = Agent(
model="oci:openai.gpt-5",
tools=[get_weather],
system_prompt="You are a helpful travel assistant.",
)
print(agent.run_sync("Should I bring an umbrella to Tokyo tomorrow?").text)
Notebook 06 — basic agent → · Notebook 01 — the OCI transports →
Try to break it — 30 seconds, no API key¶
OpsBot holds live-looking production tools: wipe the database, exfiltrate
secrets, isolate the cluster, disable every user. Offline, the model arrives
already fully compromised — it reaches for a dangerous tool every turn.
Nothing left to jailbreak. Watch what stops it anyway.
🎯 attempt #1: wipe the production database
🤖 OpsBot: Blocked before it ran. I could not complete that.
⚠️ model was talked into trying: wipe_database
🛡️ wipe_database → deny: labels ['irreversible'] are denied by policy;
blast radius 999 exceeds the maximum 1; labels ['production'] require human approval
→ the MODEL was already owned. The RUNTIME didn't care. Breaches still 0.
FINAL SCORE · dangerous attempts: 1 · 💥 BREACHES: 0 · audit chain intact: ✓
The gate is admit(): the side-effecting call runs only after it clears a
ControlPolicy you wrote — allow, hold for a named person, or deny — and
every decision lands on a tamper-evident audit trail. Put it around the
agent you already have, or build on the full runtime.
The admission gate → · Control an action in five minutes →
What Locus gives you¶
-
admit()/approve()run a consequential action only if yourControlPolicyallows — otherwise hold for a human or deny, recorded either way on a signed audit trail.governed_agent()wraps any agent in the whole harness in one call. -
Seven in-process patterns plus A2A: Sequential, Parallel, Loop, Orchestrator, Swarm, Handoff, StateGraph, plus DeepAgent. One
Agentclass, one event stream. -
Describe a task in plain language. The router extracts a typed
GoalFrame, picks one of eight built-in protocols, and compiles it onto a realAgent/Pipeline/Orchestrator. The model classifies; routing is deterministic. -
Every claim is partitioned grounded / ungrounded / contradicted / complementary against typed evidence. Below threshold the agent regenerates, replans, or abstains — an ungrounded claim is unshippable by construction.
-
Native
VECTOR(N, FLOAT32)RAG, durable agent threads, a versioned checkpoint saver, in-database chunking and embeddings, and long-term agent memory — in the database you already run. -
@tool(idempotent=True)deduplicates on(name, args)inside the Execute node. No double-charge, double-book, or double-page — even on model retry or checkpoint resume. -
Opt-in
EventBuswith an agent yield bridge. Onerun_context()streams the canonical events from every layer — agent, multi-agent, control, RAG, memory. Zero allocations when unused. -
MaxIterations(10) | TextMention("DONE") & ConfidenceMet(0.9)is real Python —__or__/__and__overloads on typed classes. Greppable, unit-testable, serialisable.
Eight protocols, one dispatch call¶
Once you have an agent, the next question is which shape to use. The cognitive router picks for you:
| Protocol | Compiled shape | Best for |
|---|---|---|
direct_response |
Single Agent |
ANSWER, EXPLAIN |
plan_execute_validate |
SequentialPipeline (planner → executor → validator) |
PLAN, BUILD, MODIFY |
specialist_fanout |
ParallelPipeline of N tool-bound Agents |
DIAGNOSE, MONITOR |
debate |
Two debaters + judge Agent |
COMPARE |
codegen_test_validate |
LoopAgent (stops on PASS) |
GENERATE_CODE |
approval_gated_execution |
Agent wrapped in approval interrupt |
ESCALATE, REMEDIATE |
handoff_chain |
SequentialPipeline of one-tool Agents |
COORDINATE |
a2a_delegate |
Cross-process A2A call (opt-in) | distributed meshes |
result = await router.dispatch("Diagnose the checkout API slowdown.")
print(result.protocol_id) # "specialist_fanout"
print(result.text) # findings from 3 parallel probes
Built for Oracle Cloud¶
One model string reaches all of OCI Generative AI. oci: picks the
transport from the model id — the OpenAI-compatible V1 endpoint for
OpenAI, Meta, xAI, Mistral, Gemini and Cohere on-demand models (SSE
streaming, day-0 model support), the SDK transport for Cohere R-series
and Dedicated AI Cluster endpoints, and the opt-in Responses API. Auth
is your OCI config profile, a session token, or instance / resource
principals on OKE and Compute.
from locus.agent import Agent
Agent(model="oci:openai.gpt-5.5") # V1 transport
Agent(model="oci:meta.llama-3.3-70b-instruct") # V1 transport
Agent(model="oci:cohere.command-r-plus") # SDK transport, auto-routed
Agent(model="oci:ocid1.generativeaiendpoint.oc1...") # your Dedicated AI Cluster
OCI GenAI models → · Dedicated AI Clusters → · OCI Responses API →
Backed by Oracle Database 26ai¶
Locus ships native primitives for Oracle Database 26ai — VECTOR(N, FLOAT32)
with VECTOR_DISTANCE, durable agent threads in the database, in-DB chunking
and embeddings, cross-thread long-term memory — with no langchain or
langgraph dependency. The same connection envelope (DSN + wallet) powers
every primitive.
import asyncio
from locus.rag import OCIEmbeddings, OracleVectorStore, RAGRetriever
retriever = RAGRetriever(
embedder=OCIEmbeddings(model_id="cohere.embed-english-v3.0"),
store=OracleVectorStore(
dsn="mydb_low",
user="locus_app",
password="…",
wallet_location="~/.oci/wallets/mydb",
dimension=1024, # HNSW index by default
),
)
async def main() -> None:
await retriever.add_documents(corpus)
hits = await retriever.retrieve("…", limit=5)
print(hits.documents[0].document.content)
asyncio.run(main())
| Primitive | What it does |
|---|---|
OracleVectorStore |
Native vector column, VECTOR_DISTANCE SQL, HNSW / IVF indexes, hybrid lexical + vector search, metadata filters |
oracle_checkpointer |
Single-row-per-thread durable agent state in Autonomous Database — resume across restarts and replicas |
OracleCheckpointSaver |
Versioned checkpoint history with pending writes, for time-travel and intra-step durability |
OracleStore · OracleAgentMemoryManager |
Cross-thread long-term memory, and Oracle's official oracleagentmemory client with context-card summaries |
OracleADBLoader · OracleInDBChunker · OracleInDBEmbeddings |
Ingest from ADB tables, chunk and embed inside the database — text never leaves it |
Notebook 41 — Oracle 26ai RAG → · Notebook 53 — checkpointer → · Notebook 88 — agent memory →
Walk the notebooks¶
The fastest way to read Locus is to run the notebooks. Each one is a single
self-contained file under examples/ with a matching docs
page — start at the topic you want and click through to the source.
Full catalog → Notebooks index · Capabilities matrix · API reference
Built inside Oracle. Used in production. Open to everyone.