From bb8d6982c4336659c6aa0246697ffa2976742f1a Mon Sep 17 00:00:00 2001 From: Federico Kamelhar Date: Sat, 23 May 2026 08:42:40 -0400 Subject: [PATCH] docs(branding): apply approved product naming across the site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two approved product names introduced across the marketing-facing surface: - Full name: Oracle Generative AI Multi-Agent Reasoning Orchestrator SDK - Short name: Oracle Generative AI – Multi-Agent Locus SDK Stand-alone "Locus" is not an approved product name in marketing prose. Site chrome - Hero of docs/index.md and docs/workbench.md carries the full name as a wordmark above the existing tagline H1. - Site header shows the full name under the "locus" wordmark, split across two lines so it fits next to the dark-mode toggle and search at all viewports. - Title is `flex: 0 0 auto`; palette toggle pulls `margin-left: auto` so toggle + search + Oracle/GitHub/PyPI cluster sits flush right. - Hero copy column gets a 1.75rem desktop indent. - Eyebrow wordmark uses a compound selector so its font-size defeats `.md-typeset .locus-hero p`. - Removed the redundant "locus" nav tab — home is reachable via the diamond logo and wordmark. Body prose - First mention of the product per file uses the full short name. - Subsequent mentions use "the SDK" (generic descriptor). - OG / Twitter meta tags and tab title use the approved short name. Left untouched (technical identifiers, outside trademark) - Python imports, package name `locus-sdk`, URLs, file paths, shell commands, container image tags, DB user identifiers, CSS class names, ASCII diagrams in code blocks, YAML config values. Out of scope (follow-up) - docs/notebooks/notebook_*.md (auto-generated from examples/notebook_*.py docstrings). - CHANGELOG.md (historical record). Signed-off-by: Federico Kamelhar --- CONTRIBUTING.md | 7 +- DEPRECATION.md | 5 +- README.md | 32 +++++----- SECURITY.md | 4 +- docs/FEATURES.md | 7 +- docs/capabilities.md | 11 ++-- docs/concepts/agent-loop.md | 17 ++--- docs/concepts/agent.md | 5 +- docs/concepts/checkpointers.md | 13 ++-- docs/concepts/conversation-management.md | 12 ++-- docs/concepts/deepagent.md | 5 +- docs/concepts/errors.md | 15 +++-- docs/concepts/evaluation.md | 8 +-- docs/concepts/hooks.md | 8 +-- docs/concepts/idempotency.md | 15 +++-- docs/concepts/interrupts.md | 9 +-- docs/concepts/mcp.md | 31 ++++----- docs/concepts/memory-manager.md | 15 +++-- docs/concepts/models.md | 7 +- docs/concepts/multi-agent.md | 3 +- docs/concepts/multi-agent/a2a.md | 10 +-- docs/concepts/multi-agent/functional.md | 6 +- docs/concepts/multi-modal-providers.md | 11 ++-- docs/concepts/observability.md | 12 ++-- docs/concepts/oci-responses.md | 23 +++---- docs/concepts/prompts.md | 4 +- docs/concepts/providers/anthropic.md | 20 +++--- docs/concepts/providers/oci.md | 20 +++--- docs/concepts/providers/ollama.md | 19 +++--- docs/concepts/providers/openai.md | 32 +++++----- docs/concepts/rag.md | 12 ++-- docs/concepts/reasoning.md | 7 +- docs/concepts/retry.md | 8 +-- docs/concepts/router.md | 17 ++--- docs/concepts/server.md | 5 +- docs/concepts/skills.md | 7 +- docs/concepts/sse-events.md | 5 +- docs/concepts/state.md | 4 +- docs/concepts/streaming.md | 10 +-- docs/concepts/structured-output.md | 17 ++--- docs/concepts/termination.md | 9 +-- docs/concepts/tools.md | 24 +++---- docs/how-to/deploy.md | 3 +- docs/how-to/environment-variables.md | 11 ++-- docs/how-to/oci-dac.md | 9 +-- docs/how-to/oci-models.md | 15 +++-- docs/how-to/persist-conversations.md | 5 +- docs/how-to/quickstart.md | 5 +- docs/index.md | 18 +++--- docs/notebooks/index.md | 2 +- docs/stylesheets/locus.css | 78 ++++++++++++++++++----- docs/workbench.md | 26 ++++---- examples/README.md | 2 +- examples/projects/deep-research/README.md | 14 ++-- mkdocs.yml | 3 +- overrides/main.html | 14 ++-- workbench/README.md | 6 +- workbench/SDK-ERGONOMICS.md | 7 +- 58 files changed, 408 insertions(+), 321 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 612ea1b4..ba118f15 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,7 @@ -# Contributing to Locus +# Contributing -Locus — *Oracle Generative AI · Multi-Agent Reasoning Orchestrator SDK* — +The Oracle Generative AI – Multi-Agent Locus SDK — formally +*Oracle Generative AI Multi-Agent Reasoning Orchestrator SDK* — is built inside Oracle, used in production, and open to everyone. This document covers how to set up a development environment, the review and sign-off process, the coding standards we hold the codebase @@ -534,4 +535,4 @@ and how `LocusDeprecationWarning` works. - Open a [GitHub Discussion](https://github.com/oracle-samples/locus/discussions) - Check existing [Issues](https://github.com/oracle-samples/locus/issues) -Thank you for contributing to Locus! +Thank you for contributing to the SDK! diff --git a/DEPRECATION.md b/DEPRECATION.md index 56604a06..74de79d1 100644 --- a/DEPRECATION.md +++ b/DEPRECATION.md @@ -1,7 +1,8 @@ # Deprecation policy -Locus is pre-1.0. This file explains how breaking changes and -deprecations work today, and how they will work after 1.0. +The Oracle Generative AI – Multi-Agent Locus SDK is pre-1.0. This +file explains how breaking changes and deprecations work today, and +how they will work after 1.0. ## Current state (0.x) diff --git a/README.md b/README.md index 211344d0..2b3bbcda 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- locus — Multi-Agent SDK · pip install locus-sdk · Built by Oracle · github.com/oracle-samples/locus + Oracle Generative AI – Multi-Agent Locus SDK · pip install locus-sdk · Built by Oracle · github.com/oracle-samples/locus

@@ -31,7 +31,7 @@

- Try every locus pattern in your browser → + Try every Oracle Generative AI – Multi-Agent Locus SDK pattern in your browser → Workbench guide
Step-by-step setup for the browser playground — run it on localhost in three terminals, or in a single Docker container. Wire up an OCI profile, or bring your own OpenAI / Anthropic key.

@@ -97,7 +97,7 @@ No mandatory cloud account to start — `MockModel` lets every notebook run offl ## Talk to any provider A model is a string. The prefix before the colon (`oci:`, `openai:`, -`anthropic:`, `ollama:`) tells locus which provider to use; the rest is +`anthropic:`, `ollama:`) tells the SDK which provider to use; the rest is the model id that provider expects. `get_model()` parses the string and returns a ready client. @@ -198,7 +198,7 @@ approval-gated agent — chosen by protocol selection, not by the model. ## Eight orchestration shapes -When one agent isn't enough, locus gives you seven in-process shapes plus cross-process A2A. +When one agent isn't enough, the SDK gives you seven in-process shapes plus cross-process A2A. Every pattern uses the same `Agent` class and the same event stream. | Pattern | When to use | @@ -243,24 +243,24 @@ print(result.text) | **[🔎 RAG](https://locusagents.oracle.com/concepts/rag/)** | 4 vector stores — Oracle 26ai · OpenSearch · pgvector · in-memory. OCI Cohere + OpenAI embeddings · multimodal (PDF, image OCR, audio). | | **[📡 Streaming + Server](https://locusagents.oracle.com/concepts/server/)** | Typed events · SSE · `AgentServer` (FastAPI, per-principal thread isolation). | | **[🪝 Hooks](https://locusagents.oracle.com/concepts/hooks/)** | Logging · OpenTelemetry · ModelRetry · Guardrails · Steering (LLM-as-judge). | -| **[🪙 MCP](https://locusagents.oracle.com/concepts/mcp/)** | `MCPClient` consumes MCP servers. `LocusMCPServer` exposes locus tools as MCP. | +| **[🪙 MCP](https://locusagents.oracle.com/concepts/mcp/)** | `MCPClient` consumes MCP servers. `LocusMCPServer` exposes the SDK's tools as MCP. | | **[🌐 Multi-modal](https://locusagents.oracle.com/concepts/multi-modal-providers/)** | `Agent(web_search=…, web_fetch=…, image_generator=…, speech_provider=…)` auto-registers tools. | | **[📊 Evaluation](https://locusagents.oracle.com/concepts/evaluation/)** | `EvalCase` / `EvalRunner` / `EvalReport` regression suites. | | **[🧰 Models](https://locusagents.oracle.com/concepts/models/)** | OCI GenAI (90+ models, V1 + SDK) · OpenAI · Anthropic · Ollama. | --- -## Inside locus — the stack, not just the loop +## Inside the SDK — the stack, not just the loop -A locus agent isn't a one-shot ReAct loop. The same `Agent` class runs -inside eight orchestration shapes, chosen automatically by the **PRISM -cognitive router** from a natural-language task, with typed reasoning -around every Execute and **Oracle Database 26ai** as a first-class -durable backend. The agent loop is the inner engine — locus is the -whole stack around it. +An Oracle Generative AI – Multi-Agent Locus SDK agent isn't a one-shot +ReAct loop. The same `Agent` class runs inside eight orchestration +shapes, chosen automatically by the **PRISM cognitive router** from a +natural-language task, with typed reasoning around every Execute and +**Oracle Database 26ai** as a first-class durable backend. The agent +loop is the inner engine — the SDK is the whole stack around it.

- The locus stack — PRISM cognitive router compiles natural-language tasks into one of 8 orchestration shapes (SequentialPipeline, ParallelPipeline, LoopAgent, StateGraph, Orchestrator + Specialists, Swarm, Handoff Chain, A2A Mesh), each of which runs the agent loop (Think → Execute → Reflect → Terminate), powered by foundations (Models, Memory, RAG, Observability, Tools/MCP/Skills) and anchored on Oracle Database 26ai + The SDK stack — PRISM cognitive router compiles natural-language tasks into one of 8 orchestration shapes (SequentialPipeline, ParallelPipeline, LoopAgent, StateGraph, Orchestrator + Specialists, Swarm, Handoff Chain, A2A Mesh), each of which runs the agent loop (Think → Execute → Reflect → Terminate), powered by foundations (Models, Memory, RAG, Observability, Tools/MCP/Skills) and anchored on Oracle Database 26ai

- **PRISM Cognitive Router** — an LLM classifier reads the task and fills a typed `GoalFrame` (intent · domain · complexity · risk); the `CognitiveCompiler` emits the matching runtime shape. The model classifies, never authors graph topology. @@ -275,7 +275,7 @@ Every node at every layer emits a write-protected typed event — the same strea ## Backed by Oracle Database 26ai -locus ships native primitives for **Oracle Database 26ai** — vector +The SDK ships native primitives for **Oracle Database 26ai** — vector search, durable agent threads, in-database chunking and embeddings, and a long-term key/value store. The contract is owned end-to-end inside `locus.rag.stores` and `locus.memory.backends`, and the same connection @@ -310,7 +310,7 @@ The seven primitives: | **`OracleInDBChunker`** | Server-side text chunking via `DBMS_VECTOR_CHAIN.UTL_TO_CHUNKS`. Text never leaves the database. | | **`OracleInDBEmbeddings`** | In-database ONNX embeddings via `DBMS_VECTOR_CHAIN.UTL_TO_EMBEDDING`. Zero round-trips when the embedding model is loaded in the DB. | -The contracts live in locus, the SQL is generated locally, and the +The contracts live in the SDK, the SQL is generated locally, and the only runtime requirement is `python-oracledb` thin mode. → [Notebook 06 — Oracle 26ai RAG](https://locusagents.oracle.com/notebooks/notebook_41_oracle_26ai_rag/) · [Notebook 07 — Oracle 26ai checkpointer](https://locusagents.oracle.com/notebooks/notebook_53_oracle_26ai_checkpointer/) · [Notebooks 08-12 — loader, chunker, embeddings, store, versioned saver](https://locusagents.oracle.com/notebooks/) @@ -363,7 +363,7 @@ python examples/notebook_69_research_workflow.py # full research pipeline ## Workbench -A browser-based playground for every locus pattern. Two clicks to a +A browser-based playground for every SDK pattern. Two clicks to a running agent — no CLI install, no editor setup. Three model slots (A / B / C) so multi-agent notebooks can mix a fast triage model with a deeper specialist. The **Notebooks** sidebar lists all 68 diff --git a/SECURITY.md b/SECURITY.md index 5f7a051d..5ebac7a0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,7 @@ ## Reporting a Vulnerability -If you believe you have found a security vulnerability in Locus, please report it to us through coordinated disclosure. +If you believe you have found a security vulnerability in the Oracle Generative AI – Multi-Agent Locus SDK, please report it to us through coordinated disclosure. **Please do not report security vulnerabilities through public GitHub issues.** @@ -23,7 +23,7 @@ We will acknowledge receipt of your vulnerability report and send you regular up ## Security Best Practices -When using Locus in production: +When using the SDK in production: 1. **API Keys**: Never commit API keys or secrets to version control. Use environment variables or secret management systems. diff --git a/docs/FEATURES.md b/docs/FEATURES.md index 96faa8e1..83cd9fe6 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -1,8 +1,9 @@ # Capabilities -Everything `locus` ships, what it does, and where to find it. +Everything Oracle Generative AI – Multi-Agent Locus SDK ships, what it +does, and where to find it. -!!! oracle-distinctive "Distinctive to locus" +!!! oracle-distinctive "Distinctive to the SDK" These ship as core primitives, inside the ReAct loop — not as middleware, plugins, or third-party libraries: @@ -53,7 +54,7 @@ Everything `locus` ships, what it does, and where to find it. | **`GoalFrame`** | Typed schema the LLM extractor fills — 13 `TaskType`s, `Risk`, `Complexity`, domain, capabilities | `locus.router.GoalFrame` | | **`ProtocolRegistry`** | Typed filter (`handles ∋ goal`, `risk_max ≥ frame.risk`) + four-tier ranking (distance · canonical · cost · specificity) | `locus.router.ProtocolRegistry` | | **`PolicyGate`** | Two thresholds: `max_risk` (hard deny) and `require_approval_above` (human-in-the-loop gate) | `locus.router.PolicyGate` | -| **`CognitiveCompiler`** | Instantiates real locus primitives from frame + protocol; emits a `Runnable` adapter | `locus.router.CognitiveCompiler` | +| **`CognitiveCompiler`** | Instantiates real SDK primitives from frame + protocol; emits a `Runnable` adapter | `locus.router.CognitiveCompiler` | | **`builtin_protocols()`** | 8 v1 protocols: `direct_response` · `plan_execute_validate` · `specialist_fanout` · `debate` · `codegen_test_validate` · `approval_gated_execution` · `a2a_delegate` · `handoff_chain` | `locus.router.builtin_protocols` | | **`CapabilityIndex`** | Domain + risk overlay on `ToolRegistry` — no parallel storage | `locus.router.CapabilityIndex` | | **`SkillIndex`** | Domain-tagged view of installed `Skill` packs; scoped catalog attached to every emitted Agent | `locus.router.SkillIndex` | diff --git a/docs/capabilities.md b/docs/capabilities.md index 2126b89e..c8b87b00 100644 --- a/docs/capabilities.md +++ b/docs/capabilities.md @@ -1,14 +1,15 @@ # Capabilities -Everything `locus` ships, what it does, and where to find it. +Everything Oracle Generative AI – Multi-Agent Locus SDK ships, what it +does, and where to find it. -!!! oracle-distinctive "Distinctive to locus" +!!! oracle-distinctive "Distinctive to the SDK" These are architectural choices no other Python agent framework ships together in one coherent stack: - **Multi-agent reasoning orchestrator** — describe a task; a typed registry picks one of eight protocols and instantiates the - matching locus primitive. The LLM fills a typed `GoalFrame`; routing is + matching SDK primitive. The LLM fills a typed `GoalFrame`; routing is rule-based. Eight protocols: `direct_response` (single Agent), `plan_execute_validate` (SequentialPipeline), `specialist_fanout` (ParallelPipeline), `debate` (two debaters + judge), @@ -73,7 +74,7 @@ Most agent frameworks force a choice: hand-code the topology (predictable but brittle) or let the LLM pick it (flexible but unpredictable). The cognitive router takes a third path — **bounded graph generation**. The LLM fills exactly one typed `GoalFrame`; a typed registry selects from eight -named protocols; a compiler instantiates real locus primitives. The +named protocols; a compiler instantiates real SDK primitives. The output is always one of the eight proven shapes — never an ad-hoc topology the model invented. @@ -83,7 +84,7 @@ the model invented. | **`GoalFrame`** | Typed schema the LLM extractor fills — 13 `TaskType`s, `Risk`, `Complexity`, domain, capabilities | `locus.router.GoalFrame` | | **`ProtocolRegistry`** | Typed filter (`handles ∋ goal`, `risk_max ≥ frame.risk`) + four-tier ranking (distance · canonical · cost · specificity) | `locus.router.ProtocolRegistry` | | **`PolicyGate`** | Two thresholds: `max_risk` (hard deny) and `require_approval_above` (human-in-the-loop gate) | `locus.router.PolicyGate` | -| **`CognitiveCompiler`** | Instantiates real locus primitives from frame + protocol; emits a `Runnable` adapter | `locus.router.CognitiveCompiler` | +| **`CognitiveCompiler`** | Instantiates real SDK primitives from frame + protocol; emits a `Runnable` adapter | `locus.router.CognitiveCompiler` | | **`builtin_protocols()`** | 8 v1 protocols: `direct_response` · `plan_execute_validate` · `specialist_fanout` · `debate` · `codegen_test_validate` · `approval_gated_execution` · `a2a_delegate` · `handoff_chain` | `locus.router.builtin_protocols` | | **`CapabilityIndex`** | Domain + risk overlay on `ToolRegistry` — no parallel storage | `locus.router.CapabilityIndex` | | **`SkillIndex`** | Domain-tagged view of installed `Skill` packs; scoped catalog attached to every emitted Agent | `locus.router.SkillIndex` | diff --git a/docs/concepts/agent-loop.md b/docs/concepts/agent-loop.md index 8ac97b65..4439e1fd 100644 --- a/docs/concepts/agent-loop.md +++ b/docs/concepts/agent-loop.md @@ -1,12 +1,13 @@ -# The locus agent loop +# The agent loop -Every locus agent runs the same loop. Four named nodes -(`Think → Execute → Reflect → Terminate`), one router that decides what -runs next, one typed event stream, one piece of immutable state that -flows through. This page is the architectural reference — what each -node does, why it exists, what it emits, and how to extend it. +Every Oracle Generative AI – Multi-Agent Locus SDK agent runs the same +loop. Four named nodes (`Think → Execute → Reflect → Terminate`), one +router that decides what runs next, one typed event stream, one piece of +immutable state that flows through. This page is the architectural +reference — what each node does, why it exists, what it emits, and how +to extend it. -![locus agent loop — Think → Execute → Reflect → Terminate, with idempotent dedupe at Execute, Reflexion and Causal at Reflect, and composable termination algebra at Terminate](../img/agent-loop.svg) +![Agent loop — Think → Execute → Reflect → Terminate, with idempotent dedupe at Execute, Reflexion and Causal at Reflect, and composable termination algebra at Terminate](../img/agent-loop.svg) The loop is implemented in [`src/locus/loop/`](https://github.com/oracle-samples/locus/tree/main/src/locus/loop) @@ -23,7 +24,7 @@ The base pattern is **ReAct** ([Yao et al., 2022](https://arxiv.org/abs/2210.036 *Thought → Action → Observation*, repeated until the model decides to stop. ReAct is now the default loop in most agentic SDKs. -locus keeps the spirit and adds three things: +The SDK keeps the spirit and adds three things: - **Action becomes Execute** — a real node in the graph that owns tool dispatch *and* idempotency dedup, not a callback. diff --git a/docs/concepts/agent.md b/docs/concepts/agent.md index a1c0ac94..f7965b1a 100644 --- a/docs/concepts/agent.md +++ b/docs/concepts/agent.md @@ -1,8 +1,9 @@ # Agent -`Agent` is the unit you build everything else from. Hand it a model, a +`Agent` is the unit you build everything else from in +Oracle Generative AI – Multi-Agent Locus SDK. Hand it a model, a list of tools, a system prompt, and any optional features (reflexion, -grounding, checkpointing) — locus drives the +grounding, checkpointing) — the SDK drives the [Think → Execute → Reflect → Terminate](agent-loop.md) loop, streams typed events as it runs, and returns a typed `AgentResult` when it stops. diff --git a/docs/concepts/checkpointers.md b/docs/concepts/checkpointers.md index e79f0f94..885374a3 100644 --- a/docs/concepts/checkpointers.md +++ b/docs/concepts/checkpointers.md @@ -124,10 +124,11 @@ Fastest reads, optional TTL for ephemeral conversations. ### Oracle 26ai: `oracle_checkpointer` + `OracleCheckpointSaver` -If your stack is already on **[Oracle Autonomous Database 26ai][adb]**, locus -ships two native checkpointers — one to colocate agent state with the -rest of your app data, the other to give LangGraph-style versioned -history in the same database. +If your stack is already on **[Oracle Autonomous Database 26ai][adb]**, +Oracle Generative AI – Multi-Agent Locus SDK ships two native +checkpointers — one to colocate agent state with the rest of your app +data, the other to give LangGraph-style versioned history in the same +database. #### Single-row per thread — `oracle_checkpointer` @@ -187,7 +188,7 @@ checkpointer](../notebooks/notebook_53_oracle_26ai_checkpointer.md). ## Two checkpointer shapes — the gotcha to know -locus has **two** kinds of checkpointer implementations and you need +The SDK has **two** kinds of checkpointer implementations and you need to wire them differently: 1. **Native checkpointers** implement `BaseCheckpointer` directly and @@ -282,7 +283,7 @@ directly for anything cross-thread that doesn't need LLM extraction ### Production: `OracleStore` on Oracle 26ai -Locus ships a native `BaseStore` implementation backed by Oracle 26ai — +The SDK ships a native `BaseStore` implementation backed by Oracle 26ai — the equivalent of `langgraph-oracledb.OracleStore`, with **zero** langchain/langgraph dependency. Namespaces persist as primary keys on a single table; optional vector search runs natively against an diff --git a/docs/concepts/conversation-management.md b/docs/concepts/conversation-management.md index 1f5a1c3f..d4c02854 100644 --- a/docs/concepts/conversation-management.md +++ b/docs/concepts/conversation-management.md @@ -1,9 +1,9 @@ # Conversation management -A locus agent holds one user's conversation in `state.messages`. To -make that conversation **survive across requests** — across deploys, -restarts, and "I'll come back tomorrow" gaps — you wire a -checkpointer and a `thread_id`. +An Oracle Generative AI – Multi-Agent Locus SDK agent holds one user's +conversation in `state.messages`. To make that conversation **survive +across requests** — across deploys, restarts, and "I'll come back +tomorrow" gaps — you wire a checkpointer and a `thread_id`. ## The minimum @@ -34,7 +34,7 @@ thread_id=...)` call rehydrates state before the first Think. ## Threads, not sessions -locus uses **thread** as the term — borrowing from chat UIs and +The SDK uses **thread** as the term — borrowing from chat UIs and issue trackers — because a single user can have many simultaneous conversations: @@ -98,7 +98,7 @@ bug — you'll race on the checkpoint. Three patterns to avoid that: serialise messages per session. 2. **Distinct sub-threads.** If the user asks two things in parallel, give them two thread ids. -3. **Last-write-wins is the default.** locus checkpointers do not +3. **Last-write-wins is the default.** The SDK's checkpointers do not currently expose a conflict exception — if you need optimistic concurrency, layer it at the application or database level. diff --git a/docs/concepts/deepagent.md b/docs/concepts/deepagent.md index ffd555f5..e431f25a 100644 --- a/docs/concepts/deepagent.md +++ b/docs/concepts/deepagent.md @@ -1,6 +1,7 @@ # DeepAgent -Locus ships two primitives for long-horizon research: +Oracle Generative AI – Multi-Agent Locus SDK ships two primitives for +long-horizon research: | | `create_deepagent` | `create_research_workflow` | |---|---|---| @@ -222,7 +223,7 @@ agent = create_deepagent( ) ``` -Activates locus's `SummarizingManager` so older turns are condensed +Activates the SDK's `SummarizingManager` so older turns are condensed once the conversation exceeds the threshold. Prevents context blowout on long research runs without losing recent reasoning steps. diff --git a/docs/concepts/errors.md b/docs/concepts/errors.md index af9a3b68..1564a215 100644 --- a/docs/concepts/errors.md +++ b/docs/concepts/errors.md @@ -1,9 +1,10 @@ # Errors -Every exception raised from inside locus subclasses a single root — -`LocusError`. One handler catches any locus-originated failure; a -stable `kind` attribute on each subclass keeps your structured logs -and metrics dashboards portable across releases. +Every exception raised from inside Oracle Generative AI – Multi-Agent +Locus SDK subclasses a single root — `LocusError`. One handler catches +any SDK-originated failure; a stable `kind` attribute on each subclass +keeps your structured logs and metrics dashboards portable across +releases. ```python from locus.core.errors import LocusError @@ -22,14 +23,14 @@ except LocusError as exc: | Situation | Catch | |---|---| -| Anything from locus — single sweep handler at your service boundary | `LocusError` | +| Anything from the SDK — single sweep handler at your service boundary | `LocusError` | | A specific tool blew up; want to retry / skip / re-route | `ToolError` (or one of its three subtypes) | | Provider auth or quota issue; want to escalate or back off | `ModelError` (or `ModelAuthError` / `ModelThrottledError`) | | Checkpoint resume failed; thread is corrupt or missing | `CheckpointError` | | Vector store / embeddings call failed | `RAGError` | | Bad config or invalid input at the public-API boundary | `ConfigError` / `ValidationError` | -Outside this hierarchy, nothing locus emits will leak through — +Outside this hierarchy, nothing the SDK emits will leak through — unwrapped third-party exceptions are wrapped at the boundary. ## Hierarchy @@ -132,7 +133,7 @@ log adapters — you don't lose context. | Symptom | Likely cause | |---|---| -| Catching `Exception` instead of `LocusError` | You'll silently swallow `KeyboardInterrupt` and provider SDK bugs. Catch the concrete locus base. | +| Catching `Exception` instead of `LocusError` | You'll silently swallow `KeyboardInterrupt` and provider SDK bugs. Catch the concrete SDK base. | | `ModelThrottledError` retries forever | Cap the loop with a max attempt count or a deadline; don't rely on the provider giving up. | | `ToolValidationError` keeps firing for the same call | The model isn't reading the schema error. Tighten the system prompt or reduce the tool's surface. | | Cause chain lost in logs | Use `logger.exception(...)`, not `logger.error(str(exc))`. | diff --git a/docs/concepts/evaluation.md b/docs/concepts/evaluation.md index 3fd1198c..3c885a23 100644 --- a/docs/concepts/evaluation.md +++ b/docs/concepts/evaluation.md @@ -1,9 +1,9 @@ # Evaluation An agent that worked yesterday may not work today — the model -changed, a tool was renamed, the prompt got a one-line tweak. locus -ships a small evaluation harness so regressions become **failing -tests**, not customer tickets. +changed, a tool was renamed, the prompt got a one-line tweak. Oracle +Generative AI – Multi-Agent Locus SDK ships a small evaluation harness +so regressions become **failing tests**, not customer tickets. ```python from locus.evaluation import EvalCase, EvalRunner @@ -144,7 +144,7 @@ EvalCase( ) ``` -A future locus release may bundle a typed judge directly into +A future SDK release may bundle a typed judge directly into `EvalCase`; for today, this pattern is the path. ## Common gotchas diff --git a/docs/concepts/hooks.md b/docs/concepts/hooks.md index c66a8597..41691556 100644 --- a/docs/concepts/hooks.md +++ b/docs/concepts/hooks.md @@ -7,9 +7,9 @@ agent's primary task — logging, OpenTelemetry traces, retry, guardrails, PII redaction, an LLM-as-judge approval gate on tool calls — lives in a hook. -You can use the ones locus ships (covers most production needs out -of the box) or write your own — a hook is a small subclass with the -methods it cares about. +You can use the ones Oracle Generative AI – Multi-Agent Locus SDK +ships (covers most production needs out of the box) or write your own +— a hook is a small subclass with the methods it cares about. ## When to write a hook @@ -107,7 +107,7 @@ The hook fires on every agent run — no further wiring. ## What you get out of the box -locus ships these hooks. Composed in this order, they cover most +The SDK ships these hooks. Composed in this order, they cover most production needs without writing custom code. ```python diff --git a/docs/concepts/idempotency.md b/docs/concepts/idempotency.md index 7d2ddfa9..fba52ce9 100644 --- a/docs/concepts/idempotency.md +++ b/docs/concepts/idempotency.md @@ -2,10 +2,11 @@ > The single most important word in production agents is **once**. -The model is *allowed* to retry. The side effect *isn't*. locus -makes that distinction a one-keyword decision on the tool, enforced -inside the ReAct loop. This is a locus-specific primitive — none of -LangChain / LangGraph / CrewAI / Strands ship it. +The model is *allowed* to retry. The side effect *isn't*. Oracle +Generative AI – Multi-Agent Locus SDK makes that distinction a +one-keyword decision on the tool, enforced inside the ReAct loop. +This is an SDK-specific primitive — none of LangChain / LangGraph +/ CrewAI / Strands ship it. If you ever plan to run an agent that **books**, **charges**, **emails**, **pages**, or **writes**, this is the most important @@ -17,13 +18,13 @@ single page on the docs site. |---|---| | Side-effecting tool with real-world cost (charge, email, page, book) | **yes — always** | | Database write you can't trivially roll back | **yes** | -| External service that's already idempotent on its end | yes — locus dedupes the round-trip too | +| External service that's already idempotent on its end | yes — the SDK dedupes the round-trip too | | Read-only catalogue lookup | no — re-reads are cheap, leave it to the model | | Tool that *intentionally* generates a new entity each call (e.g. `mint_uuid`) | no — that breaks the contract | ## How it works -Inside a single agent run, locus hashes the tool's +Inside a single agent run, the SDK hashes the tool's `(name, arguments)` tuple as the model emits each call. **The first call with a given key hits the function body** and the result is recorded. **Every subsequent call with the same key short-circuits @@ -83,7 +84,7 @@ When a checkpointer resumes a stalled run, the model may decide to re-issue tool calls it's already seen. Idempotent tools see the cache pre-populated from the checkpoint and skip the side effect on replay. (This requires `tool_executions` to be restored from the -checkpoint; locus's [native checkpointers](checkpointers.md) handle +checkpoint; the SDK's [native checkpointers](checkpointers.md) handle it.) ## What it is *not* diff --git a/docs/concepts/interrupts.md b/docs/concepts/interrupts.md index abcbe329..d86b3ef6 100644 --- a/docs/concepts/interrupts.md +++ b/docs/concepts/interrupts.md @@ -4,9 +4,10 @@ Sometimes the agent shouldn't decide alone. A human approves the $2M PO. A reviewer signs off on the customer refund. A regulator requires an audit checkpoint between research and submission. -locus treats human approval as **a tool the model can call** — same -shape as any other tool, except it surfaces a question to your app -and resumes when the human responds. +Oracle Generative AI – Multi-Agent Locus SDK treats human approval as +**a tool the model can call** — same shape as any other tool, except +it surfaces a question to your app and resumes when the human +responds. ## The shape @@ -35,7 +36,7 @@ agent = Agent( ``` `PendingApproval` is your own sentinel exception. When the agent -calls the tool, locus catches the exception, persists state to the +calls the tool, the SDK catches the exception, persists state to the checkpointer, and exits with `TerminateEvent(reason="PendingApproval")`. Your app reads the reason out of `state.metadata` and asks the human. diff --git a/docs/concepts/mcp.md b/docs/concepts/mcp.md index 4cb9010b..aa34e402 100644 --- a/docs/concepts/mcp.md +++ b/docs/concepts/mcp.md @@ -3,22 +3,23 @@ The [Model Context Protocol](https://modelcontextprotocol.io) is an Anthropic-spec interop standard for tools. Define a tool once, expose it over MCP, and any MCP-compatible client (Claude Desktop, -Cline, Strands, another locus agent) can call it. Or consume tools -from existing MCP servers (filesystem, git, postgres, github, -sequential-thinking) without writing any glue. +Cline, Strands, another agent built with Oracle Generative AI – +Multi-Agent Locus SDK) can call it. Or consume tools from existing +MCP servers (filesystem, git, postgres, github, sequential-thinking) +without writing any glue. -**locus speaks MCP both ways**. That's a deliberate differentiator — +**The SDK speaks MCP both ways**. That's a deliberate differentiator — most agent frameworks consume MCP servers but don't expose their own -tools as MCP. Round-trip means an agent built with locus can be -either side of the conversation. +tools as MCP. Round-trip means an SDK-built agent can be either side +of the conversation. ## When to use MCP | You want… | Use MCP | |---|---| -| Your locus agent to use Anthropic's published filesystem / git / postgres servers | ✓ — `MCPClient` | +| Your SDK agent to use Anthropic's published filesystem / git / postgres servers | ✓ — `MCPClient` | | Your `@tool` library to be callable by Claude Desktop / Cline / other agents | ✓ — `LocusMCPServer` | -| Two locus agents to share tools across processes / machines | ✓ — works, but [A2A](multi-agent/a2a.md) is the better protocol | +| Two SDK agents to share tools across processes / machines | ✓ — works, but [A2A](multi-agent/a2a.md) is the better protocol | | In-process multi-agent — share tools by importing | use the [tools](tools.md) directly, not MCP | | Reproducible tests | use [Ollama](providers/ollama.md) + plain `@tool` — MCP adds I/O | @@ -50,13 +51,13 @@ stdin/stdout, and discovers what tools the server exposes. from locus.agent import Agent agent = Agent( model="oci:openai.gpt-5.5", - tools=[*fs.tools()], # MCP tools become locus tools + tools=[*fs.tools()], # MCP tools become SDK tools system_prompt="You can read files in /data.", ) result = agent.run_sync("Summarise the README in /data.") ``` -`fs.tools()` returns a list of locus `Tool` objects with full +`fs.tools()` returns a list of SDK `Tool` objects with full schemas, descriptions, and call-through plumbing. The agent doesn't know they're MCP — they look like any other `@tool`. @@ -147,7 +148,7 @@ appear in the model's tool list. `@tool`'s docstring + type hints become the MCP tool's name, description, and JSON schema — losslessly. The MCP client sees the -same parameter types, defaults, and descriptions a locus agent +same parameter types, defaults, and descriptions an SDK agent would. ### Both transports @@ -160,12 +161,12 @@ would. ### Idempotency carries through A tool tagged `@tool(idempotent=True)` keeps that semantic when -exposed via MCP. The dedup happens locus-side; the MCP client +exposed via MCP. The dedup happens SDK-side; the MCP client doesn't need to know. ## Round-trip example -A common shape: a locus agent A consumes a filesystem MCP server, +A common shape: an SDK agent A consumes a filesystem MCP server, *and* exposes its own tools as MCP for another agent B to consume: ```python @@ -193,7 +194,7 @@ implementation detail. | `MCP server failed to start` | The MCP server subprocess crashed before establishing the session. Run the command manually to see the error. | | `Tool 'X' not found in MCP discovery` | The server exposes a different name than you expected. Print `[t.name for t in fs.tools()]` to see the actual list. | | `Schema validation failed on call` | MCP tool returned an arg type that doesn't match its declared schema. Common with hand-written MCP servers; the standard ones are fine. | -| Claude Desktop doesn't show your locus tools | `claude_desktop_config.json` not picked up — check the file lives at the right path and Claude has been restarted. | +| Claude Desktop doesn't show your SDK tools | `claude_desktop_config.json` not picked up — check the file lives at the right path and Claude has been restarted. | | Hangs on `MCPClient.stdio` startup | The MCP subprocess is waiting for input on stdin (some servers expect a handshake). Pass `wait_for_init=True` and a timeout. | ## Source and notebook @@ -204,4 +205,4 @@ implementation detail. ## See also - [Tools](tools.md) — the `@tool` decorator MCP wraps. -- [A2A](multi-agent/a2a.md) — purpose-built protocol for cross-process locus-to-locus agent meshes. +- [A2A](multi-agent/a2a.md) — purpose-built protocol for cross-process SDK-to-SDK agent meshes. diff --git a/docs/concepts/memory-manager.md b/docs/concepts/memory-manager.md index 36b859ab..03e6591c 100644 --- a/docs/concepts/memory-manager.md +++ b/docs/concepts/memory-manager.md @@ -1,9 +1,10 @@ # Long-term memory -A locus agent is stateless between sessions by default. Checkpointing -preserves the full message history for one conversation thread, but -facts learned in thread A are invisible in thread B — and when a thread -is deleted, everything in it is gone. +An Oracle Generative AI – Multi-Agent Locus SDK agent is stateless +between sessions by default. Checkpointing preserves the full message +history for one conversation thread, but facts learned in thread A are +invisible in thread B — and when a thread is deleted, everything in it +is gone. `MemoryManager` fills that gap. It runs two lifecycle hooks on every agent invocation: @@ -136,7 +137,7 @@ Each combination gets its own set of memories — no cross-contamination. ## Persistent backends -Locus exposes memory along a spectrum, from "works everywhere" to +The SDK exposes memory along a spectrum, from "works everywhere" to "opinionated Oracle-specific": | Path | Manager class | When to pick it | @@ -210,7 +211,7 @@ manager = LLMMemoryManager(store=RedisBackend("redis://localhost:6379")) manager = LLMMemoryManager(store=PostgreSQLBackend(host="...", database="...")) # [Oracle 26ai][oracle-db] (`OracleStore`) — namespaced key/value with optional [VECTOR][ai-vector-search] -# search inside a namespace. Native locus, no langchain dep. For +# search inside a namespace. Native to the SDK, no langchain dep. For # Oracle workloads, prefer `OracleAgentMemoryManager` above unless # you specifically want the BaseStore protocol or the LLM-free # regex extractor. @@ -226,7 +227,7 @@ manager = LLMMemoryManager( ) ``` -`OracleStore` is the locus-native equivalent of +`OracleStore` is the SDK-native equivalent of `langgraph-oracledb.OracleStore`: same connection envelope as the checkpointer (one wallet, one schema), namespaces persist as PK columns, and `put_with_embedding` + `search_by_embedding` give you semantic diff --git a/docs/concepts/models.md b/docs/concepts/models.md index bc5d7715..552e8f5b 100644 --- a/docs/concepts/models.md +++ b/docs/concepts/models.md @@ -1,9 +1,10 @@ # Model providers A model is a string. The prefix before the colon (`oci:`, `openai:`, -`anthropic:`, `ollama:`) tells locus which provider to use; the rest is -the model id that provider expects. `get_model()` parses the string and -returns a ready client. +`anthropic:`, `ollama:`) tells Oracle Generative AI – Multi-Agent +Locus SDK which provider to use; the rest is the model id that +provider expects. `get_model()` parses the string and returns a ready +client. ```python # tools, system_prompt, and other kwargs are the same across all providers diff --git a/docs/concepts/multi-agent.md b/docs/concepts/multi-agent.md index 07bc9715..b31d1794 100644 --- a/docs/concepts/multi-agent.md +++ b/docs/concepts/multi-agent.md @@ -1,6 +1,7 @@ # Multi-agent workflows -Multi-agent workflows are what locus is for. Seven shapes you compose +Multi-agent workflows are what Oracle Generative AI – Multi-Agent +Locus SDK is for. Seven shapes you compose in one process or scale across a mesh, every shape backed by the same `Agent` class, the same event stream, and the same primitives. Pick a shape directly, or let the **cognitive router** select and diff --git a/docs/concepts/multi-agent/a2a.md b/docs/concepts/multi-agent/a2a.md index 23d1a865..dcac7a9e 100644 --- a/docs/concepts/multi-agent/a2a.md +++ b/docs/concepts/multi-agent/a2a.md @@ -5,11 +5,11 @@ Each agent runs as its own service, advertises an Agent Card (capabilities + skills + endpoint URL) at a well-known URL, and other agents discover and call it over HTTP. -Locus implements the public +Oracle Generative AI – Multi-Agent Locus SDK implements the public [A2A protocol](https://a2aproject.github.io/A2A/) — the same wire -format used by Strands, ADK, and Google's reference SDKs — so a Locus -agent can call a non-Locus A2A peer (or be called by one) without an -adapter. +format used by Strands, ADK, and Google's reference SDKs — so an +SDK-built agent can call a non-SDK A2A peer (or be called by one) +without an adapter. ![A2A pattern — two processes (Process A team-research with A2AServer; Process B team-finance with A2AClient), connected by an HTTP+SSE arc, agents inside each process](../../img/patterns/a2a.svg){ .diagram } @@ -36,7 +36,7 @@ URI), `DataPart` (structured JSON). - ✅ **Multi-process or multi-host** agent deployments. - ✅ **Different teams own different agents** on different stacks. - ✅ You need a **network boundary** for security or scaling. -- ✅ **Polyglot** — a Locus agent calling a non-Locus A2A peer (or +- ✅ **Polyglot** — an SDK agent calling a non-SDK A2A peer (or vice versa) speaks the same protocol verbatim. - ✅ **Capability-based discovery** — the caller reads the Agent Card and decides whether to delegate. diff --git a/docs/concepts/multi-agent/functional.md b/docs/concepts/multi-agent/functional.md index 3aeb944c..e20e1ae3 100644 --- a/docs/concepts/multi-agent/functional.md +++ b/docs/concepts/multi-agent/functional.md @@ -1,8 +1,8 @@ # Functional API -The functional API is locus's "agent as a task" shape — `@task` and -`@entrypoint` decorators that bring agent runs into the regular -asyncio universe. +The functional API is the Oracle Generative AI – Multi-Agent Locus +SDK's "agent as a task" shape — `@task` and `@entrypoint` decorators +that bring agent runs into the regular asyncio universe. ![Functional pattern — @entrypoint at top fans out to multiple @task agents via asyncio.gather, results merge into a list](../../img/patterns/functional.svg){ .diagram } diff --git a/docs/concepts/multi-modal-providers.md b/docs/concepts/multi-modal-providers.md index 63bd52f5..ee42a8d2 100644 --- a/docs/concepts/multi-modal-providers.md +++ b/docs/concepts/multi-modal-providers.md @@ -2,9 +2,10 @@ The model is one provider an agent depends on. Production agents pull from more: a web index, a page fetcher, an image renderer, a speech -synthesiser. locus exposes those as a small set of **Protocol** types -under `locus.providers` and an opt-in auto-registration step that turns -each one into a model-callable tool. +synthesiser. Oracle Generative AI – Multi-Agent Locus SDK exposes +those as a small set of **Protocol** types under `locus.providers` and +an opt-in auto-registration step that turns each one into a +model-callable tool. ```python from locus.agent import Agent @@ -72,7 +73,7 @@ The shared Pydantic types live in `locus.providers.types` (`SearchResult`, default `tts-1`) plus `audio.transcriptions.create` (Whisper, default `whisper-1`). Round-trips text → audio → text. -All four lazy-import `openai` / `httpx` so locus core stays free of +All four lazy-import `openai` / `httpx` so the SDK core stays free of optional dependencies until you actually wire one of these in. ## Bring your own @@ -80,7 +81,7 @@ optional dependencies until you actually wire one of these in. The protocols are the contract — implement them and you're in. A production user might wrap Bing for search, `trafilatura` for fetch, OCI Vision for image generation, or OCI Speech for STT/TTS. The agent -glue stays identical: set the kwarg on `AgentConfig`, locus registers +glue stays identical: set the kwarg on `AgentConfig`, the SDK registers the tool. ```python diff --git a/docs/concepts/observability.md b/docs/concepts/observability.md index a9183029..9693e151 100644 --- a/docs/concepts/observability.md +++ b/docs/concepts/observability.md @@ -1,9 +1,9 @@ # Observability What the agent did, how long each step took, and what it cost — two -built-in hooks plus the standard OpenTelemetry stack cover every -piece you need. No vendor lock-in: locus emits OTLP, you point it at -whatever backend you run. +built-in hooks plus the standard OpenTelemetry stack cover every piece +you need. No vendor lock-in: Oracle Generative AI – Multi-Agent Locus +SDK emits OTLP, you point it at whatever backend you run. ## When to wire what @@ -46,7 +46,7 @@ Sample (`ToolCompleteEvent`): } ``` -Pipe stdout to your log aggregator. locus doesn't own the transport — +Pipe stdout to your log aggregator. The SDK doesn't own the transport — you choose between stdlib `logging`, `structlog`, or `opentelemetry-logs`. @@ -124,7 +124,7 @@ anything leaves, see [Safety](safety.md). | `TelemetryHook` raises `ImportError` | `pip install "locus-sdk[telemetry]"` to get the OpenTelemetry SDK. | | No spans show up in your backend | Exporter not configured. Set `OTEL_EXPORTER_OTLP_ENDPOINT` (and `OTEL_EXPORTER_OTLP_HEADERS` if your backend needs auth) *before* creating the agent. | | Spans land but metrics don't | Some OTLP receivers reject metrics on the trace endpoint. Set `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` separately if needed. | -| Token totals are zero | The provider isn't returning usage in the response (older Ollama builds, some self-hosted endpoints). The locus loop can't make up the numbers. | +| Token totals are zero | The provider isn't returning usage in the response (older Ollama builds, some self-hosted endpoints). The SDK's loop can't make up the numbers. | | Tool args land in your logs unintentionally | Either `record_arguments=True` or your structured logger is dumping the full event dict. Configure either explicitly. | ## Source and notebooks @@ -140,7 +140,7 @@ anything leaves, see [Safety](safety.md). For workbench streaming, real-time dashboards, or any use case where you need to watch the full inner cognition of a run without standing up an OTLP stack, -locus ships a zero-dependency in-process pub/sub bus. +the SDK ships a zero-dependency in-process pub/sub bus. ### How it works diff --git a/docs/concepts/oci-responses.md b/docs/concepts/oci-responses.md index 789038f6..a4999e11 100644 --- a/docs/concepts/oci-responses.md +++ b/docs/concepts/oci-responses.md @@ -1,11 +1,12 @@ # OCI Responses API — when to use it, what changes -Locus exposes the OCI Generative AI **Responses** endpoint as a separate -transport, `OCIResponsesModel`, alongside the default `OCIChatCompletionsModel` -(which speaks `/openai/v1/chat/completions`). Picking it means opting -into server-side conversation state — the OCI server holds the message -thread between turns, and Locus references it via a continuation token -instead of re-sending the full history each call. +Oracle Generative AI – Multi-Agent Locus SDK exposes the OCI Generative +AI **Responses** endpoint as a separate transport, `OCIResponsesModel`, +alongside the default `OCIChatCompletionsModel` (which speaks +`/openai/v1/chat/completions`). Picking it means opting into server-side +conversation state — the OCI server holds the message thread between +turns, and the SDK references it via a continuation token instead of +re-sending the full history each call. Use it for: @@ -56,7 +57,7 @@ anything. **Everything else works identically:** -| Locus primitive | Status on `OCIResponsesModel` | +| SDK primitive | Status on `OCIResponsesModel` | |---|---| | `MemoryStore` (cross-run facts in system prompt) | ✅ Works — system prompt threads into the first Responses call, server carries forward | | `Reflexion` | ✅ Works — additional refinement turns in the same Responses thread | @@ -76,7 +77,7 @@ That's why the bypass is one line, not a matrix. ## Tools on the Responses path User `@tool` functions work identically. The model emits tool calls, -Locus's `ToolExecutor` runs them client-side, results are sent back in +the SDK's `ToolExecutor` runs them client-side, results are sent back in the next turn as `function_call_output` items (carrying `call_id` for correlation). Tool hooks fire normally; idempotency dedup applies; the `AfterToolCallEvent.arguments` and `.tool_call_id` fields you'd expect @@ -84,15 +85,15 @@ from [hooks](hooks.md#on_after_tool_call-what-the-event-carries) are all populated. OCI built-in Responses tools (`file_search`, `web_search`, -`code_interpreter`) are not exposed in this release. Locus's hook / +`code_interpreter`) are not exposed in this release. The SDK's hook / guardrail layers can't see server-side tool execution, so wrapping -those tools in Locus would be misleading. If you need them, call OCI +those tools in the SDK would be misleading. If you need them, call OCI directly. We may add an opt-in pass-through in a later release. ## Continuation state and checkpointing After each turn, the model returns `provider_state = -{"previous_response_id": "resp_..."}`. Locus stores it on +{"previous_response_id": "resp_..."}`. The SDK stores it on `AgentState.provider_state` and threads it into the next `complete()` call. The `Checkpointer` snapshots `provider_state` alongside the message history, so `agent.resume(...)` works across process restarts diff --git a/docs/concepts/prompts.md b/docs/concepts/prompts.md index 2b605467..43e939d4 100644 --- a/docs/concepts/prompts.md +++ b/docs/concepts/prompts.md @@ -1,7 +1,7 @@ # Prompts -The model in a locus agent sees three sources of prompt content, in -this order, every iteration: +The model in an Oracle Generative AI – Multi-Agent Locus SDK agent +sees three sources of prompt content, in this order, every iteration: 1. The **system prompt** — `Agent(system_prompt=...)`. Stable across the whole run; describes the agent's role, constraints, and tools. diff --git a/docs/concepts/providers/anthropic.md b/docs/concepts/providers/anthropic.md index 386daacc..764220c5 100644 --- a/docs/concepts/providers/anthropic.md +++ b/docs/concepts/providers/anthropic.md @@ -1,7 +1,7 @@ # Anthropic -The Anthropic provider connects locus directly to Anthropic's API -(`api.anthropic.com`). Use it when you want **the Claude family** — +The Anthropic provider connects Oracle Generative AI – Multi-Agent +Locus SDK directly to Anthropic's API (`api.anthropic.com`). Use it when you want **the Claude family** — Opus for the hardest problems, Sonnet as the everyday workhorse, Haiku for high-volume cheap calls — and want to talk to Anthropic without going through an intermediary. @@ -39,9 +39,9 @@ agent = Agent( ) ``` -The string `"anthropic:claude-sonnet-4-20250514"` tells locus the +The string `"anthropic:claude-sonnet-4-20250514"` tells the SDK the provider (`anthropic:`) and the exact model id. Any model id -Anthropic accepts, locus accepts — including the dated revision +Anthropic accepts, the SDK accepts — including the dated revision suffixes (`-20250514`). ### 3. Run it @@ -68,7 +68,7 @@ Whatever Anthropic ships, you can address by name: ### Real SSE streaming -Token-level streaming. The model emits content deltas; locus +Token-level streaming. The model emits content deltas; the SDK converts them to `ModelChunkEvent`s; your `async for` loop reads them as they arrive. @@ -81,14 +81,14 @@ async for event in agent.run("Write a haiku about latency."): ### Tool calling — the Anthropic tool-use protocol `@tool` functions are translated into Anthropic's `tools` schema; the -model's structured `tool_use` blocks are parsed back into locus +model's structured `tool_use` blocks are parsed back into SDK `ToolCall`s. Parallel tool calls are supported (the model can -request multiple tools per turn; locus runs them concurrently via +request multiple tools per turn; the SDK runs them concurrently via the `ConcurrentExecutor`). ### Structured output — tool-as-schema -Anthropic doesn't expose a `response_format` field, so locus uses +Anthropic doesn't expose a `response_format` field, so the SDK uses the standard "single-tool" trick: define the schema as a tool, force the model to call it. From your side, the API is identical to the other providers: @@ -116,7 +116,7 @@ mechanism marks a span of the request as cacheable; subsequent turns within the cache window pay **1/10th** the input cost on the cached span. -Opt in with `prompt_cache=True` on `AnthropicModel`. Locus then sends +Opt in with `prompt_cache=True` on `AnthropicModel`. The SDK then sends the system prompt as a block list with `cache_control: ephemeral` and tags the last entry of the tool catalog the same way (Anthropic walks markers in order — the last tag anchors the cache point). @@ -157,7 +157,7 @@ and the cost saved. Claude 4 models with `thinking_enabled` think before answering, the way the OpenAI o-series does. Anthropic surfaces those thinking -blocks in the response; locus emits a `ThinkEvent` for each one so +blocks in the response; the SDK emits a `ThinkEvent` for each one so your UI can show what the model is working on: ```python diff --git a/docs/concepts/providers/oci.md b/docs/concepts/providers/oci.md index 337a83a3..a00bd1f6 100644 --- a/docs/concepts/providers/oci.md +++ b/docs/concepts/providers/oci.md @@ -1,11 +1,11 @@ # OCI Generative AI -OCI Generative AI is locus's **day-1 target** and the most capable -provider in the box. It exposes 90+ models — OpenAI commercial -families, Meta Llama, Anthropic Claude, Google Gemini, xAI Grok, -Mistral, and Cohere — through Oracle's hosted inference service. -**When OCI ships a new model id, locus already supports it** — you -just pass the new id. +OCI Generative AI is Oracle Generative AI – Multi-Agent Locus SDK's +**day-1 target** and the most capable provider in the box. It exposes +90+ models — OpenAI commercial families, Meta Llama, Anthropic Claude, +Google Gemini, xAI Grok, Mistral, and Cohere — through Oracle's hosted +inference service. **When OCI ships a new model id, the SDK already +supports it** — you just pass the new id. The headline value over the direct providers: @@ -32,7 +32,7 @@ The headline value over the direct providers: ## Two transports under one prefix -OCI Generative AI exposes its inference service in three ways. locus +OCI Generative AI exposes its inference service in three ways. The SDK speaks all three and **picks the right one from the model id** — you don't have to know which transport a model uses to call it (the `oci:` prefix routes by family), and you can also pick a specific @@ -101,7 +101,7 @@ agent = Agent(model=OCIResponsesModel( )) ``` -The only Locus primitive that bypasses on this path is +The only SDK primitive that bypasses on this path is `ConversationManager`. Memory, Reflexion, GSAR, grounding, tool hooks, idempotency, checkpointing, output schema, streaming, and termination conditions all work identically. See @@ -123,7 +123,7 @@ agent = Agent(model="oci:cohere.command-r-plus-08-2024") # SDK transport ### DAC endpoints — dedicated capacity When you've provisioned a Dedicated AI Cluster (DAC), OCI gives you -a **generative AI endpoint OCID**. Pass it as the model id and locus +a **generative AI endpoint OCID**. Pass it as the model id and the SDK auto-routes through the SDK transport with `DedicatedServingMode`: ```python @@ -141,7 +141,7 @@ streaming, tool-call quirks per model. ## Transport selection — by the `oci:` prefix -When you use the `oci:` string factory, locus looks at the +When you use the `oci:` string factory, the SDK looks at the model id and chooses for you: | Model id pattern | Transport | diff --git a/docs/concepts/providers/ollama.md b/docs/concepts/providers/ollama.md index da3943fc..87650ad0 100644 --- a/docs/concepts/providers/ollama.md +++ b/docs/concepts/providers/ollama.md @@ -1,9 +1,10 @@ # Ollama -The Ollama provider is **locus pointed at a local model runtime**. -Ollama runs open-weight models on your laptop or a shared GPU box; -locus calls it over HTTP exactly the way it would call OpenAI or -Anthropic. No API key, no network egress, no per-token billing. +The Ollama provider is **Oracle Generative AI – Multi-Agent Locus SDK +pointed at a local model runtime**. Ollama runs open-weight models on +your laptop or a shared GPU box; the SDK calls it over HTTP exactly +the way it would call OpenAI or Anthropic. No API key, no network +egress, no per-token billing. This is the right pick for **offline development**, **reproducible tests**, and **iterating on agent design before you spend a dollar @@ -39,9 +40,9 @@ ollama pull llama3.3 ``` `ollama list` will show what you've pulled. Anything in that list is -addressable from locus immediately. +addressable from the SDK immediately. -### 2. Wire locus +### 2. Wire the SDK ```python from locus.agent import Agent @@ -63,10 +64,10 @@ provider — provided the model you pulled supports them. ## What you get out of the box -### Any pulled local model — no locus change needed +### Any pulled local model — no SDK change needed The `model_id` after `ollama:` is whatever appears in `ollama list`. -locus doesn't maintain an allow-list; if Ollama can run it, locus +The SDK doesn't maintain an allow-list; if Ollama can run it, the SDK can address it. ```bash @@ -84,7 +85,7 @@ agent_c = Agent(model="ollama:deepseek-r1:14b") ### Real local streaming -Ollama emits SSE-shaped chunks; locus reads them as `ModelChunkEvent`s +Ollama emits SSE-shaped chunks; the SDK reads them as `ModelChunkEvent`s just like any other provider. Token-level streaming over localhost is fast — typically <5 ms per chunk. diff --git a/docs/concepts/providers/openai.md b/docs/concepts/providers/openai.md index 39882824..490b0694 100644 --- a/docs/concepts/providers/openai.md +++ b/docs/concepts/providers/openai.md @@ -1,11 +1,11 @@ # OpenAI -The OpenAI provider connects locus directly to OpenAI's API -(`api.openai.com`). It's what you reach for when you want **the latest -OpenAI model the day it ships** without going through any gateway, -translation layer, or middleware. +The OpenAI provider connects Oracle Generative AI – Multi-Agent Locus +SDK directly to OpenAI's API (`api.openai.com`). It's what you reach +for when you want **the latest OpenAI model the day it ships** without +going through any gateway, translation layer, or middleware. -It's also the **fastest way to try locus** — one env var, one line of +It's also the **fastest way to try the SDK** — one env var, one line of code, you're talking to GPT-5 or the o-series reasoning models. ## When to pick OpenAI @@ -26,7 +26,7 @@ code, you're talking to GPT-5 or the o-series reasoning models. export OPENAI_API_KEY=sk-... ``` -That's the only setup. locus reads the env var on import. +That's the only setup. The SDK reads the env var on import. ### 2. Pick a model @@ -35,9 +35,9 @@ from locus.agent import Agent agent = Agent(model="openai:gpt-5.5", system_prompt="You are helpful.") ``` -The string `"openai:gpt-5.5"` does two things: tells locus to use the -OpenAI provider (`openai:` prefix), and which model id to call -(`gpt-5.5`). Any model id OpenAI accepts, locus accepts. +The string `"openai:gpt-5.5"` does two things: tells the SDK to use +the OpenAI provider (`openai:` prefix), and which model id to call +(`gpt-5.5`). Any model id OpenAI accepts, the SDK accepts. ### 3. Run it @@ -57,13 +57,13 @@ without further configuration. Every chat-shaped OpenAI model: `gpt-4o`, `gpt-4.1`, `gpt-5`, `gpt-5.5`, `gpt-image-1`. Vision input (image URLs / base64), audio input, and function calling work the same way you'd use them on the OpenAI SDK -directly — locus just normalises the events the model emits. +directly — the SDK just normalises the events the model emits. ### Reasoning models — the o-series `o1`, `o3`, `o4-mini` route through the same `Agent(model="openai:o3")` call. They're slower and more expensive but think before they answer. -locus surfaces the model's thinking blocks as `ThinkEvent`s so your +The SDK surfaces the model's thinking blocks as `ThinkEvent`s so your UI can show "thinking…" without parsing the response yourself. ```python @@ -79,7 +79,7 @@ thinking. Default is `medium`. ### Real SSE streaming Token-level streaming over Server-Sent Events. The model emits -deltas, locus turns them into `ModelChunkEvent`s, your `async for` +deltas, the SDK turns them into `ModelChunkEvent`s, your `async for` loop reads them as they arrive — no buffering, no fake chunking. ```python @@ -92,8 +92,8 @@ async for event in agent.run("Write a haiku about latency."): `@tool` functions are converted to OpenAI's tool-call schema and the structured `tool_calls` field in the response is parsed back into -locus `ToolCall` objects. Parallel tool calls are supported (the -model can request multiple tools per turn; locus runs them +SDK `ToolCall` objects. Parallel tool calls are supported (the +model can request multiple tools per turn; the SDK runs them concurrently via the `ConcurrentExecutor`). ### Structured output — Pydantic models in, validated objects out @@ -114,9 +114,9 @@ result = agent.run_sync("Was the meeting productive?") print(result.parsed) # Answer(summary='...', confidence=0.83) ``` -Under the hood, locus sends an OpenAI `response_format` with the +Under the hood, the SDK sends an OpenAI `response_format` with the schema and a strict-mode flag; if the model produces invalid JSON, -locus retries with the validation errors in the prompt +the SDK retries with the validation errors in the prompt (`output_schema_retries=2` by default). ## Going through a gateway diff --git a/docs/concepts/rag.md b/docs/concepts/rag.md index 1477c327..a7d2bc04 100644 --- a/docs/concepts/rag.md +++ b/docs/concepts/rag.md @@ -1,6 +1,7 @@ # RAG -Retrieval-Augmented Generation in locus is **three small pieces** — +Retrieval-Augmented Generation in Oracle Generative AI – Multi-Agent +Locus SDK is **three small pieces** — an embedder, a vector store, and a retriever that wires them — plus a one-liner to expose the retriever as a tool the agent calls when it needs facts. @@ -91,9 +92,10 @@ store = OracleVectorStore( #### Production setup — least-privileged schema -Running Locus against an [Autonomous Database][adb] as `ADMIN` is an Oracle -security anti-pattern: every connection has full DBA privileges, so a -compromised credential or a malformed query has unbounded blast radius. +Running the SDK against an [Autonomous Database][adb] as `ADMIN` is an +Oracle security anti-pattern: every connection has full DBA privileges, +so a compromised credential or a malformed query has unbounded blast +radius. Provision a dedicated app user instead — run this once as `ADMIN`: ```sql @@ -210,7 +212,7 @@ catches relevance signals embeddings miss. The pattern: to the top-N (e.g. 5). 4. Feed the top-N to the LLM. -Locus ships `CohereReranker` against OCI GenAI's Cohere V4 on-demand +The SDK ships `CohereReranker` against OCI GenAI's Cohere V4 on-demand endpoint (`cohere.rerank-v4.0-fast` by default; `cohere.rerank-v4.0-pro` for the higher-accuracy variant; `cohere.rerank-v3.5` as a fallback). diff --git a/docs/concepts/reasoning.md b/docs/concepts/reasoning.md index b865fecf..c71bcd22 100644 --- a/docs/concepts/reasoning.md +++ b/docs/concepts/reasoning.md @@ -1,8 +1,9 @@ # Reasoning A model that loops without thinking just pays you to be wrong faster. -locus ships three reasoning add-ons. Each catches a different class of -mistake *before* the next tool call: +Oracle Generative AI – Multi-Agent Locus SDK ships three reasoning +add-ons. Each catches a different class of mistake *before* the next +tool call: - **Reflexion** catches *wrong premises* — the agent self-evaluates after each turn and re-plans if the last step was a dead end, @@ -136,7 +137,7 @@ observable as their own event types. Reflexion: [Shinn et al., 2023](https://arxiv.org/abs/2303.11366). Grounding-Stratified Adaptive Replanning: see [GSAR](gsar.md) for the -typed-evidence variant locus also ships. +typed-evidence variant the SDK also ships. ## See also diff --git a/docs/concepts/retry.md b/docs/concepts/retry.md index 43427944..6b1e73b8 100644 --- a/docs/concepts/retry.md +++ b/docs/concepts/retry.md @@ -2,8 +2,8 @@ Production model calls fail. Rate limits, gateway timeouts, transient 5xx, occasional content-policy refusals on retryable inputs. -locus's retry posture is: **automate what's transient; surface -what's not.** +Oracle Generative AI – Multi-Agent Locus SDK's retry posture is: +**automate what's transient; surface what's not.** ## The default behaviour @@ -58,7 +58,7 @@ def lookup_inventory(sku: str) -> dict: return inventory.get(sku) ``` -1. **Let the loop handle it.** When `lookup_inventory` raises, locus +1. **Let the loop handle it.** When `lookup_inventory` raises, the SDK captures the exception, returns a `ToolErrorEvent` to state, and feeds the error message to the next Think. The model can then *decide* whether to retry the call, try a different tool, or @@ -83,7 +83,7 @@ def lookup_inventory(sku: str) -> dict: ## Idempotent retry -This is the locus-distinctive bit. If a tool is tagged +This is the SDK-distinctive bit. If a tool is tagged `@tool(idempotent=True)` and the model retries the same call, the **Execute node** dedupes inside the loop — the body never runs the second time, and the cached receipt is returned. diff --git a/docs/concepts/router.md b/docs/concepts/router.md index 15adc5f8..ac0dcfbf 100644 --- a/docs/concepts/router.md +++ b/docs/concepts/router.md @@ -13,11 +13,12 @@ Python over that frame, so two identical requests always produce the same shape. Under the hood: `locus.router` is a meta-orchestration layer on top of -locus's existing primitives. It compiles the chosen shape onto a real -`Agent`, `SequentialPipeline`, `ParallelPipeline`, `LoopAgent`, or -`Orchestrator` from the standard toolkit. The contribution is the -*layer*, not the primitives — every router execution is just a normal -locus orchestration you can already inspect, replay, and extend. +Oracle Generative AI – Multi-Agent Locus SDK's existing primitives. It +compiles the chosen shape onto a real `Agent`, `SequentialPipeline`, +`ParallelPipeline`, `LoopAgent`, or `Orchestrator` from the standard +toolkit. The contribution is the *layer*, not the primitives — every +router execution is just a normal SDK orchestration you can already +inspect, replay, and extend. ## Why a routing layer @@ -38,7 +39,7 @@ A dispatch flows through five stages, in order: an LLM extractor reads the prompt into a typed `GoalFrame`, the protocol registry picks the matching shape, the policy gate decides whether the request is allowed (and whether it needs approval), the compiler instantiates the real -locus primitive, and the runnable executes. Every stage except the +SDK primitive, and the runnable executes. Every stage except the first is pure Python. ![Cognitive router pipeline — NL input → GoalFrame Extractor (LLM) → ProtocolRegistry → PolicyGate → CognitiveCompiler → eight compiled shapes → RunnableResult](../img/patterns/router.svg) @@ -57,7 +58,7 @@ frame = GoalFrame( ) ``` -The LLM extractor — a standard locus +The LLM extractor — a standard SDK `Agent(model=..., output_schema=GoalFrame)` — fills exactly this schema. It does *not* author orchestration topology. @@ -130,7 +131,7 @@ result = await router.dispatch("Diagnose the checkout slowdown.") print(result.protocol_id, result.text) ``` -The compiler instantiates a real locus primitive and wraps it in a +The compiler instantiates a real SDK primitive and wraps it in a `Runnable` adapter so call sites get a single shape (`async execute(task) -> RunnableResult`) regardless of which protocol fired. diff --git a/docs/concepts/server.md b/docs/concepts/server.md index 4fa93b25..28023b46 100644 --- a/docs/concepts/server.md +++ b/docs/concepts/server.md @@ -155,8 +155,9 @@ The server is plain FastAPI — deploy it however you deploy FastAPI. | **Anywhere else FastAPI runs** | …yes | Auth, rate-limiting, and request logging are FastAPI middleware -concerns — locus does not own them. Add `slowapi`, `prometheus-fastapi-instrumentator`, -or whatever your platform expects. +concerns — Oracle Generative AI – Multi-Agent Locus SDK does not own +them. Add `slowapi`, `prometheus-fastapi-instrumentator`, or whatever +your platform expects. ## Common gotchas diff --git a/docs/concepts/skills.md b/docs/concepts/skills.md index c7be5b89..73d04375 100644 --- a/docs/concepts/skills.md +++ b/docs/concepts/skills.md @@ -10,8 +10,9 @@ disclosure** — and it's how you compose **broad agents** (one model, many domain skills) without blowing the context budget on capabilities the run won't use. -Each skill is a folder with a `SKILL.md`. Point your agent at the parent -directory and locus handles the disclosure tiers: +Each skill is a folder with a `SKILL.md`. Point your agent at the +parent directory and Oracle Generative AI – Multi-Agent Locus SDK +handles the disclosure tiers: - **L1 — catalog.** Names + one-line descriptions live in the system prompt. Cheap, always loaded. @@ -166,7 +167,7 @@ of them call. - [`notebook_48_skills.py`](https://github.com/oracle-samples/locus/blob/main/examples/notebook_48_skills.py) — programmatic and filesystem-loaded skills end-to-end. - [`locus.skills`](https://github.com/oracle-samples/locus/tree/main/src/locus/skills) — `Skill`, `SkillsPlugin`. -- [AgentSkills.io specification](https://agentskills.io) — the format locus implements. +- [AgentSkills.io specification](https://agentskills.io) — the format the SDK implements. ## See also diff --git a/docs/concepts/sse-events.md b/docs/concepts/sse-events.md index 000ad0d4..f5411380 100644 --- a/docs/concepts/sse-events.md +++ b/docs/concepts/sse-events.md @@ -1,7 +1,8 @@ # SSE event catalogue -Locus publishes a single canonical stream of events on its in-process -`EventBus` (see [Observability](observability.md)). Every event +Oracle Generative AI – Multi-Agent Locus SDK publishes a single +canonical stream of events on its in-process `EventBus` (see +[Observability](observability.md)). Every event carries a stable `event_type` string keyed by the component that produced it (`agent.*`, `multiagent.*`, `composition.*`, `router.*`, `rag.*`, `memory.*`, `a2a.*`, `skills.*`, `deepagent.*`). diff --git a/docs/concepts/state.md b/docs/concepts/state.md index 60ddfeea..509189a6 100644 --- a/docs/concepts/state.md +++ b/docs/concepts/state.md @@ -99,8 +99,8 @@ serialize whatever `to_checkpoint()` returns and rehydrate with ## Reducers (for graphs only) When two branches of a [StateGraph](multi-agent/graph.md) modify the -state in parallel, locus needs to know how to merge them. That's -what reducers do: +state in parallel, Oracle Generative AI – Multi-Agent Locus SDK needs +to know how to merge them. That's what reducers do: | Reducer | Combines two values by… | |---|---| diff --git a/docs/concepts/streaming.md b/docs/concepts/streaming.md index a4a0c2c0..c1b2b52a 100644 --- a/docs/concepts/streaming.md +++ b/docs/concepts/streaming.md @@ -1,9 +1,9 @@ # Streaming -Every locus agent emits a typed event stream as it runs. The events are -frozen Pydantic classes — not strings, not `dict[str, Any]` blobs — -designed to drop into a `match` statement that your type checker can -verify exhaustively: +Every Oracle Generative AI – Multi-Agent Locus SDK agent emits a typed +event stream as it runs. The events are frozen Pydantic classes — not +strings, not `dict[str, Any]` blobs — designed to drop into a `match` +statement that your type checker can verify exhaustively: ```python async for event in agent.run("Plan a trip to Paris."): @@ -101,7 +101,7 @@ visible in code review. Why this is important: in callback-based event systems any code can silently mutate a field and you find out three hops downstream when -the value's wrong. locus's frozen events make that impossible. +the value's wrong. The SDK's frozen events make that impossible. ## Sync wrapper — when you don't need the stream diff --git a/docs/concepts/structured-output.md b/docs/concepts/structured-output.md index 97c4ac4d..5812878a 100644 --- a/docs/concepts/structured-output.md +++ b/docs/concepts/structured-output.md @@ -1,8 +1,9 @@ # Structured output Sometimes you want the model to *fill a shape*, not write prose. Set -`output_schema=` to a Pydantic model and locus parses the agent's final -answer into a typed instance for you. +`output_schema=` to a Pydantic model and Oracle Generative AI – +Multi-Agent Locus SDK parses the agent's final answer into a typed +instance for you. ```python from pydantic import BaseModel, Field @@ -33,7 +34,7 @@ for v in picks.vendors: nested models, lists, optionals, discriminated unions, and any `@field_validator` / `@model_validator` you attach. The schema flows to the provider as a strict `response_format` when supported (OpenAI, -OCI OpenAI-compat); otherwise locus falls back to prompted JSON + +OCI OpenAI-compat); otherwise the SDK falls back to prompted JSON + extraction + validation. ## What ends up on `AgentResult` @@ -58,7 +59,7 @@ for v in picks.vendors: ## Repair on validation failure -If the model's first answer fails validation, locus re-prompts up to +If the model's first answer fails validation, the SDK re-prompts up to `output_schema_retries` times (default 2) with the Pydantic `ValidationError` details inlined so the model can fix the response. On supporting providers the repair call also ships @@ -88,11 +89,11 @@ When `output_schema_retries=0`, the first response is the final attempt. | `anthropic:claude-*` | ✓ tool-use | synthetic `respond_with_schema` tool + pinned `tool_choice` | ✓ | unit-mocked | | `ollama:*` | (prompted) | — | ✓ | unit-only | -For Anthropic, locus translates `response_format` into the idiomatic +For Anthropic, the SDK translates `response_format` into the idiomatic tool-use pattern: a single `respond_with_schema` tool whose `input_schema` is your Pydantic schema, with `tool_choice` pinned to it. Anthropic's API guarantees the tool's arguments match the schema, and -locus surfaces those arguments as the message content for downstream +the SDK surfaces those arguments as the message content for downstream parsing — **the synthetic tool never reaches your agent's tool list**. Strict mode adds two guarantees on supporting providers: (1) the model @@ -121,7 +122,7 @@ async for partial in stream: final: VendorList | None = stream.final ``` -Each `ModelChunkEvent` is appended to a buffer; locus auto-closes any +Each `ModelChunkEvent` is appended to a buffer; the SDK auto-closes any unbalanced braces / brackets / strings, runs the result through `schema.model_validate`, and yields the parsed instance if it succeeds. By default identical consecutive partials are deduplicated; pass @@ -135,7 +136,7 @@ without a single valid partial, `stream.final` is `None`. `output_schema` only affects the **final answer**, not the iterations that use tools. The agent can call any tool during the loop; once it -emits a non-tool response, locus parses that response into the schema: +emits a non-tool response, the SDK parses that response into the schema: ```python agent = Agent( diff --git a/docs/concepts/termination.md b/docs/concepts/termination.md index 9aa659d6..87e671d7 100644 --- a/docs/concepts/termination.md +++ b/docs/concepts/termination.md @@ -1,8 +1,9 @@ # Termination -When does an agent stop? locus answers that with a typed, composable -**algebra of stop conditions** — small classes that each return `True` -when the run should end, combined with `&` (and) and `|` (or). +When does an agent stop? Oracle Generative AI – Multi-Agent Locus SDK +answers that with a typed, composable **algebra of stop conditions** — +small classes that each return `True` when the run should end, combined +with `&` (and) and `|` (or). ```python from locus.core.termination import ( @@ -19,7 +20,7 @@ termination = ( Read it left to right: *stop when we sent the summary and we're confident, **or** the model said "DONE", **or** we hit ten iterations*. -This is one of locus's signature primitives. Every stop condition is +This is one of the SDK's signature primitives. Every stop condition is inspectable, unit-testable, and serialisable — no hand-rolled `if` ladders sprinkled through the loop. diff --git a/docs/concepts/tools.md b/docs/concepts/tools.md index 485fcd21..824ef8e0 100644 --- a/docs/concepts/tools.md +++ b/docs/concepts/tools.md @@ -1,11 +1,11 @@ # Tools -Tools are how a locus agent affects the world. The model decides -*"call `search` with query='hnsw'"*; locus runs your `search` -function, captures the return value, and feeds it back. From your -side, a tool is **a regular Python function with a `@tool` -decorator** — locus introspects the signature and docstring to build -the schema the model sees. +Tools are how an Oracle Generative AI – Multi-Agent Locus SDK agent +affects the world. The model decides *"call `search` with query='hnsw'"*; +the SDK runs your `search` function, captures the return value, and +feeds it back. From your side, a tool is **a regular Python function +with a `@tool` decorator** — the SDK introspects the signature and +docstring to build the schema the model sees. This is the seam most production code touches. Get tools right and the rest of the framework gets out of your way. @@ -51,16 +51,16 @@ can call it whenever it decides to. result = agent.run_sync("Find documents about HNSW.") ``` -If the model decides to call `search("hnsw")`, locus invokes your +If the model decides to call `search("hnsw")`, the SDK invokes your function with that argument, captures the return value, and feeds it -into the next model turn. You write Python; locus handles the +into the next model turn. You write Python; the SDK handles the schema marshalling. ## What you get out of the box ### Idempotent tools — the model can retry; the side effect can't -This is locus's flagship tool primitive. Some side-effecting tools +This is the SDK's flagship tool primitive. Some side-effecting tools must run *exactly once* per logical request — bookings, charges, emails, paging. Mark them `idempotent=True`: @@ -113,7 +113,7 @@ agent = Agent( ) ``` -When the model emits multiple tool calls in one turn, locus runs +When the model emits multiple tool calls in one turn, the SDK runs them concurrently via `asyncio.gather`. Three independent searches finish in `max(t1, t2, t3)`, not `t1+t2+t3`. @@ -137,7 +137,7 @@ def lookup_by_id(id: str) -> dict: ``` The model sees `"no record with id=42"` and decides what to do. -Behind the scenes, locus chains the original exception as the cause +Behind the scenes, the SDK chains the original exception as the cause on a `ToolExecutionError` for your structured logs. ### Custom names and descriptions @@ -186,7 +186,7 @@ through `LocusMCPServer` — same `@tool`, no rewrite. See For most domains, you write a `@tool` per operation: `search_orders`, `get_invoice`, `cancel_subscription`. That stops scaling once the domain is *cloud-sized* — the Oracle Cloud Infrastructure (OCI) -Python SDK alone has ~190 service modules. Locus ships two built-in +Python SDK alone has ~190 service modules. The SDK ships two built-in **open-specification** tools that cover the whole surface through a single agentic primitive: diff --git a/docs/how-to/deploy.md b/docs/how-to/deploy.md index b6e1727f..ed7aa323 100644 --- a/docs/how-to/deploy.md +++ b/docs/how-to/deploy.md @@ -193,7 +193,8 @@ sudo systemctl enable --now concierge | OCI Compute | `instance_principal` | | Laptop / CI | `api_key` or `session_token` | -Locus picks the right OCI signer from the `OCI_AUTH_TYPE` env var. +Oracle Generative AI – Multi-Agent Locus SDK picks the right OCI +signer from the `OCI_AUTH_TYPE` env var. You don't change application code between environments. ## Sessions — `X-Session-ID` for chat UIs diff --git a/docs/how-to/environment-variables.md b/docs/how-to/environment-variables.md index 946892f0..d546777f 100644 --- a/docs/how-to/environment-variables.md +++ b/docs/how-to/environment-variables.md @@ -1,8 +1,9 @@ # Environment variables — `OCI_*` vs `LOCUS_OCI_*` -Locus reads two families of environment variables to configure the OCI -GenAI transport. Both are valid, and the notebook harness in -`examples/config.py` reads them with a consistent fallback chain. +Oracle Generative AI – Multi-Agent Locus SDK reads two families of +environment variables to configure the OCI GenAI transport. Both are +valid, and the notebook harness in `examples/config.py` reads them +with a consistent fallback chain. ## The rule @@ -22,9 +23,9 @@ harness performs. - **`OCI_*`** is the OCI CLI / SDK standard. If you already typed `oci session authenticate --profile-name DEFAULT` and exported the - resulting variables, the Locus notebooks pick them up unchanged. + resulting variables, the SDK notebooks pick them up unchanged. - **`LOCUS_OCI_*`** is the namespaced form the notebook harness reads - first. Useful when you want a Locus notebook to use a *different* + first. Useful when you want an SDK notebook to use a *different* profile or region from your shell-default OCI configuration — point `LOCUS_OCI_PROFILE` somewhere else without touching `OCI_PROFILE`. diff --git a/docs/how-to/oci-dac.md b/docs/how-to/oci-dac.md index 764b46ee..8a0e8eb4 100644 --- a/docs/how-to/oci-dac.md +++ b/docs/how-to/oci-dac.md @@ -10,7 +10,8 @@ OCI GenAI exposes two serving modes: (`ocid1.generativeaiendpoint.oc1.....`). Inference is routed to your cluster, with predictable latency and isolation guarantees. -Locus auto-routes DAC endpoint OCIDs to the SDK transport (`OCIModel`) +Oracle Generative AI – Multi-Agent Locus SDK auto-routes DAC endpoint +OCIDs to the SDK transport (`OCIModel`) because the V1 OpenAI-compatible endpoint doesn't speak `DedicatedServingMode`. Pass the endpoint OCID exactly the way you'd pass a model id: @@ -67,15 +68,15 @@ provisioned by Luigi's tenancy): - Tool calls come back as `{...}` text blocks inside `message.content`, not as structured `tool_calls` array - entries. Locus's `GenericProvider.parse_response()` doesn't extract + entries. The SDK's `GenericProvider.parse_response()` doesn't extract them as `ToolCall`s. Two ways to fix: 1. **Deploy-side**: configure the DAC with a Qwen3-family flag like `--enable-auto-tool-choice` so the model emits OpenAI-style - `tool_calls`. Locus picks them up natively. + `tool_calls`. The SDK picks them up natively. 2. **Caller-side**: post-process `result.message` for `{...}` blocks and re-issue them via `agent.run_sync(...)` with the parsed call. A small regex - extraction; not built into locus today. + extraction; not built into the SDK today. ## Streaming diff --git a/docs/how-to/oci-models.md b/docs/how-to/oci-models.md index 3cf72481..60f79e33 100644 --- a/docs/how-to/oci-models.md +++ b/docs/how-to/oci-models.md @@ -1,6 +1,7 @@ # OCI GenAI models -Locus connects to OCI Generative AI through **three transports**. +Oracle Generative AI – Multi-Agent Locus SDK connects to OCI Generative +AI through **three transports**. The `oci:` string factory picks V1 or SDK by model family; the Responses transport is opt-in. @@ -117,7 +118,7 @@ model = OCIResponsesModel( ) ``` -The only Locus primitive that bypasses on the Responses path is +The only SDK primitive that bypasses on the Responses path is `ConversationManager` (window/summarize have nothing to operate on when the server owns the history). Memory, Reflexion, GSAR, grounding, tool hooks, idempotency, checkpointing, output schema, @@ -144,7 +145,7 @@ same five auth modes (`api_key`, `security_token`, `session_token`, different from `OCIChatCompletionsModel` — `model_id=`, `profile_name=`, `compartment_id=`, `auth_type=` as an enum / string. Streaming on this transport is faked (the full response is chunked client-side) — that's -an OCI-side limitation of the legacy endpoint, not a locus issue. +an OCI-side limitation of the legacy endpoint, not an SDK issue. ## String factory (`get_model("oci:...")`) auto-routes @@ -179,17 +180,17 @@ side-by-side. ## What's not supported today -- **OpenAI Responses API on OCI.** Locus deliberately stays on +- **OpenAI Responses API on OCI.** The SDK deliberately stays on chat/completions — the Responses API is built around server-side - conversation state which conflicts with locus's own memory and tool + conversation state which conflicts with the SDK's own memory and tool layers. Practical consequence: `openai.gpt-5-pro` (Responses-only on - OCI per the day-0 announcement) is not reachable from locus today. + OCI per the day-0 announcement) is not reachable from the SDK today. Regular `openai.gpt-5.5` works fine on V1. - **Cohere R-series on V1.** OCI's `/openai/v1` returns `400 Unsupported OpenAI operation` for these. Use `OCIModel`. - **GenAI API key auth (Bearer token).** A "create an API key in the Console, hand it as `api_key=` and you're done" path is not yet - reliable on OCI without a Project OCID. When it is, locus will add + reliable on OCI without a Project OCID. When it is, the SDK will add `api_key=` to `OCIChatCompletionsModel` as a third auth mode (additive, non-breaking). diff --git a/docs/how-to/persist-conversations.md b/docs/how-to/persist-conversations.md index 3fa68e7b..b37511ab 100644 --- a/docs/how-to/persist-conversations.md +++ b/docs/how-to/persist-conversations.md @@ -108,5 +108,6 @@ await agent2.run("Who am I?", thread_id="t1").__anext__() # The model sees the earlier user turn. ``` -Locus's integration suite has this exact test against a live OCI -bucket. See `tests/integration/test_checkpointer_adapters.py`. +Oracle Generative AI – Multi-Agent Locus SDK's integration suite has +this exact test against a live OCI bucket. See +`tests/integration/test_checkpointer_adapters.py`. diff --git a/docs/how-to/quickstart.md b/docs/how-to/quickstart.md index 7e045bd0..2a135976 100644 --- a/docs/how-to/quickstart.md +++ b/docs/how-to/quickstart.md @@ -1,6 +1,7 @@ # Quickstart -A working locus agent in five minutes. +A working Oracle Generative AI – Multi-Agent Locus SDK agent in five +minutes. ## 1. Install @@ -8,7 +9,7 @@ A working locus agent in five minutes. pip install "locus-sdk[oci]" ``` -This installs locus plus the OCI Generative AI provider. For other +This installs the SDK plus the OCI Generative AI provider. For other providers add the corresponding extra: ```bash diff --git a/docs/index.md b/docs/index.md index bdcffd2e..27b373cd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,13 +7,15 @@ hide:
+

Oracle Generative AI Multi-Agent Reasoning Orchestrator SDK

+ # Multi-agent workflows built for production. -Describe the task. locus selects the protocol and coordinates the agents. +Describe the task. Oracle Generative AI – Multi-Agent Locus SDK selects the protocol and coordinates the agents.
[direct answer](concepts/router.md) · [pipeline](concepts/multi-agent/composition.md) · [fan‑out](concepts/multi-agent/composition.md) · [debate](concepts/multi-agent/composition.md) · [code + test](concepts/multi-agent/composition.md) · [approval gate](concepts/interrupts.md) · [A2A](concepts/multi-agent/a2a.md) · [handoff](concepts/multi-agent/handoff.md)
-- **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. +- **From idea to production agent in minutes, not weeks.** Describe the task; Oracle Generative AI – Multi-Agent Locus SDK picks the pattern and assembles the network from eight production-tested protocols. - **Self-critiquing agents with grounded outputs.** Every turn is scored; every claim is verified against the tool result that produced it. - **Full causal traceability.** Every decision, tool call, and reasoning step is a typed event you can replay, audit, and debug. @@ -107,7 +109,7 @@ print(agent.run_sync("Should I bring an umbrella to Tokyo tomorrow?").text) [Notebook 14 — basic agent →](notebooks/notebook_06_basic_agent.md) -## What locus gives you +## What Oracle Generative AI – Multi-Agent Locus SDK gives you
@@ -181,10 +183,10 @@ print(result.text) # findings from 3 parallel probes ## Backed by Oracle Database 26ai -locus ships native primitives for Oracle 26ai — native `VECTOR(N, FLOAT32)` -with `VECTOR_DISTANCE`, durable agent threads in the database, in-DB -chunking and embeddings, all without a langchain or langgraph -dependency. +Oracle Generative AI – Multi-Agent Locus SDK ships native primitives for +Oracle 26ai — native `VECTOR(N, FLOAT32)` with `VECTOR_DISTANCE`, durable +agent threads in the database, in-DB chunking and embeddings, all without +a langchain or langgraph dependency. ```python from locus.rag import OCIEmbeddings, OracleVectorStore, RAGRetriever @@ -211,7 +213,7 @@ notebooks 06 and 07 walk both end-to-end. ## Walk the notebooks -The fastest way to read locus is to run the notebooks. Each one is a +The fastest way to read Oracle Generative AI – Multi-Agent Locus SDK is to run the notebooks. Each one is a single self-contained file under [`examples/`][gh-examples] with a matching docs page — start at the topic you want, click through to the source from there. diff --git a/docs/notebooks/index.md b/docs/notebooks/index.md index de23c0d9..f52ea90c 100644 --- a/docs/notebooks/index.md +++ b/docs/notebooks/index.md @@ -38,7 +38,7 @@ cluster, on-demand reranking. **Start here if you're shipping on OCI.** | 01 | [OCI transports — start here][t01] | The three OCI transports side by side (V1, Responses, generic chat) | | 02 | [OCI v1 (`OCIChatCompletionsModel`)][t02] | The default transport — every OCI model family in one class | | 03 | [OCI Responses (`OCIResponsesModel`)][t03] | Opt-in stateful path with built-in tools | -| 04 | [OCI Dedicated AI Cluster (DAC)][t04] | Wiring a private endpoint OCID into Locus | +| 04 | [OCI Dedicated AI Cluster (DAC)][t04] | Wiring a private endpoint OCID into the SDK | | 05 | [Cohere Reranker V4 on OCI][t05] | Retrieve-then-rerank with OCI on-demand `rerank-v4` | ## 06–07 · Oracle Database 26ai diff --git a/docs/stylesheets/locus.css b/docs/stylesheets/locus.css index 433b822d..376c9e0d 100644 --- a/docs/stylesheets/locus.css +++ b/docs/stylesheets/locus.css @@ -276,6 +276,21 @@ html { border-radius: 50%; pointer-events: none; } +/* Compound `.locus-hero p.locus-product-name` (specificity 0,3,1) beats + `.md-typeset .locus-hero p` (0,2,1), so the eyebrow size actually wins + inside the hero. Second selector covers usages outside the hero (e.g. + the workbench page) where `.locus-hero p` isn't competing. */ +.md-typeset .locus-hero p.locus-product-name, +.md-typeset p.locus-product-name { + font-size: 0.78rem !important; + line-height: 1.35; + letter-spacing: 0.06em; + text-transform: uppercase; + font-weight: 600; + color: var(--locus-ink); + opacity: 0.55; + margin: 0 0 1.2rem; +} .md-typeset .locus-hero h1:first-of-type { font-size: 2.9rem; line-height: 1.05; @@ -292,6 +307,13 @@ html { .md-typeset .locus-hero__code { min-width: 0; } +/* Indent the hero copy column so the wordmark + H1 + kicker don't sit + flush against the content edge. Mobile drops the indent (handled by the + responsive block further down — the single-column stack already has the + container's own padding). */ +.md-typeset .locus-hero__copy { + padding-left: 1.75rem; +} .md-typeset .locus-hero h1 .accent { color: var(--or-red); } @@ -435,6 +457,10 @@ html { gap: 1.4rem; overflow: visible; } + /* Drop the desktop hero-copy indent when columns stack. */ + .md-typeset .locus-hero__copy { + padding-left: 0; + } .md-typeset .locus-hero::before, .md-typeset .locus-hero::after { display: none; @@ -556,16 +582,28 @@ html { /* Title block in the middle — "locus" wordmark only. The slogan lives in the SVG logo and on the homepage; trying to stack a tagline beneath the title fights Material's absolute- - positioned topic toggle, so we keep the header clean. */ + positioned topic toggle, so we keep the header clean. + `flex: 0 0 auto` keeps the title from taking the full available row; + that leaves room for the palette toggle, search, and source slot to + cluster together on the right (see `form.md-header__option { margin-left: auto }` below). */ .md-header__title { display: flex; align-items: center; margin-left: 0.6rem; align-self: center; + flex: 0 0 auto; } -/* Stack the first topic vertically: "locus" wordmark + the - "Multi Agent Reasoning SDK" subtitle beneath, matching - the wordmark+tagline lockup the SVG logo carries. */ +/* Push the palette toggle, search, and source slot to the right side + of the header inner row, leaving a clean gap after the title. */ +form.md-header__option { + margin-left: auto; +} +/* Stack the first topic vertically: "locus" wordmark + the approved full + product name beneath ('Oracle Generative AI Multi-Agent Reasoning + Orchestrator SDK', split across two lines), matching the + wordmark+tagline lockup the SVG logo carries. The two-line break keeps + each line short enough to fit alongside the dark-mode toggle and the + search slot at common viewport widths. */ .md-header__ellipsis > .md-header__topic:first-of-type { display: flex; flex-direction: column; @@ -583,24 +621,32 @@ html { color: var(--locus-ink); } .md-header__ellipsis > .md-header__topic:first-of-type::after { - content: "Multi Agent Reasoning SDK"; + /* `\A` is a CSS newline; `white-space: pre` keeps it as a hard break, + so the approved full product name renders on two lines under the + wordmark — family brand on top, product descriptor below. */ + content: "Oracle Generative AI Multi-Agent\AReasoning Orchestrator SDK"; font-family: var(--locus-sans); font-size: 0.55rem; font-weight: 600; letter-spacing: 0.12em; color: var(--or-red); - line-height: 1; - white-space: nowrap; + line-height: 1.25; + white-space: pre; + /* Push the line away from the dark-mode toggle that sits immediately + to the right of the title slot, so they don't visually touch. */ + padding-right: 1rem; } @media (max-width: 56em) { - /* Show "multi-agent SDK" as a compact tagline below "locus" on mobile. */ + /* Mobile: same full name, slightly tighter tracking to fit. */ .md-header__ellipsis > .md-header__topic:first-of-type::after { - content: "multi-agent SDK"; - font-size: 0.52rem; - letter-spacing: 0.08em; + content: "Oracle Generative AI Multi-Agent\AReasoning Orchestrator SDK"; + font-size: 0.5rem; + letter-spacing: 0.06em; + line-height: 1.25; font-weight: 600; color: var(--or-red); display: block; + white-space: pre; } /* Always show "locus" (site title) in the mobile header — suppress Material's page-title swap so users always see the brand name. */ @@ -616,10 +662,10 @@ html { /* Site-wide: never let Material swap the header topic on scroll. The default behaviour translates topic #1 (site name + our tagline) up and fades in - topic #2 (page title), which strips the - "Multi Agent Reasoning SDK" line and replaces it with the - current page's name. Pin topic #1 and hide #2 on every page so the brand - banner (diamond mark + "locus" + tagline) stays put as the user scrolls. */ + topic #2 (page title), which strips the approved product-name line and + replaces it with the current page's name. Pin topic #1 and hide #2 on every + page so the brand banner (diamond mark + "locus" + product name) stays put + as the user scrolls. */ .md-header__ellipsis > .md-header__topic:first-of-type { transform: translateY(0) !important; opacity: 1 !important; @@ -1125,7 +1171,7 @@ html { height: 36px; max-width: none; padding: 0; - margin-left: 0.4rem; + margin-left: 0; border-radius: 8px; color: var(--locus-ink); transition: background-color 0.15s, color 0.15s, transform 0.15s; diff --git a/docs/workbench.md b/docs/workbench.md index f65cd156..4b291ebb 100644 --- a/docs/workbench.md +++ b/docs/workbench.md @@ -1,8 +1,11 @@ -# Locus workbench +

Oracle Generative AI Multi-Agent Reasoning Orchestrator SDK

-A browser-based playground for every locus pattern. Two ways to run -it — straight from source on your laptop, or inside a Docker -container — both end at the same UI at . +# Workbench + +A browser-based playground for every Oracle Generative AI – Multi-Agent +Locus SDK pattern. Two ways to run it — straight from source on your +laptop, or inside a Docker container — both end at the same UI at +. [View on GitHub](https://github.com/oracle-samples/locus){ .md-button .md-button--primary } [Workbench README](https://github.com/oracle-samples/locus/tree/main/workbench){ .md-button } @@ -11,17 +14,18 @@ Once it's up: open *Provider settings*, paste an OpenAI / Anthropic key or wire up an OCI profile, pick a notebook in the sidebar, hit **Run**. A real agent streams events back into the browser. -![locus workbench](img/workbench.gif) +![Workbench UI screenshot](img/workbench.gif) ## What it is -The workbench is the fastest way to *see* what locus does without -installing anything locally. It's a single-page UI in front of every -canonical locus pattern — a basic agent, an agent with tools, a +The workbench is the fastest way to *see* what Oracle Generative AI – +Multi-Agent Locus SDK does without installing anything locally. It's a +single-page UI in front of every canonical Oracle Generative AI – +Multi-Agent Locus SDK pattern — a basic agent, an agent with tools, a structured-output schema, an orchestrator with specialists, a sequential pipeline, a map-reduce fan-out, a critic loop with `allow_cycles`. Each pattern is wired to a real Python coroutine -that imports locus, builds the agent, and streams events through to +that imports the SDK, builds the agent, and streams events through to your browser. ### Start with Oracle @@ -217,7 +221,7 @@ docker build -t locus-workbench -f workbench/Dockerfile . ``` Image is ~1.3 GB on first build (Oracle Linux 9-slim base + Python -3.12 + Node 20 + locus + workbench source). Subsequent builds hit +3.12 + Node 20 + the SDK + workbench source). Subsequent builds hit the BuildKit layer cache. ### Run @@ -384,7 +388,7 @@ field the `router.protocol.selected` SSE event carries. Sample prompts that exercise different protocols: ``` -What does the locus router do in the context of this SDK? +What does the router do in the context of this SDK? → direct_response ``` diff --git a/examples/README.md b/examples/README.md index d62f615a..1197a6bf 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,4 +1,4 @@ -# Locus Examples +# Oracle Generative AI – Multi-Agent Locus SDK Examples ## Quick Start diff --git a/examples/projects/deep-research/README.md b/examples/projects/deep-research/README.md index f690b335..3ca3b087 100644 --- a/examples/projects/deep-research/README.md +++ b/examples/projects/deep-research/README.md @@ -1,10 +1,10 @@ -# deep-research — locus ports of the langchain-oci deep-research gists +# deep-research — Oracle Generative AI – Multi-Agent Locus SDK ports of the langchain-oci deep-research gists A runnable suite of seven `create_deepagent(datastores=...)` examples -covering every retrieval backend locus supports: **in-memory**, **Oracle +covering every retrieval backend the SDK supports: **in-memory**, **Oracle Autonomous Database** (vector), **OCI Object Storage** (tool-based retrieval), and **OpenSearch**. Each demo mirrors a published -langchain-oci deep-research gist 1:1 on locus primitives — no langchain +langchain-oci deep-research gist 1:1 on the SDK's primitives — no langchain or deepagents imports. ``` @@ -37,7 +37,7 @@ or deepagents imports. | [`demo_opensearch_multi_index.py`](demo_opensearch_multi_index.py) | Two OpenSearch indices (medical + news) | [gist 92b9a515](https://gist.github.com/fede-kamel/92b9a515155f4332f794d491602b6e79) (OpenSearch variant) | | [`demo_object_storage.py`](demo_object_storage.py) | OCI Object Storage via `@tool`-wrapped SDK (`list_bucket_objects`, `read_bucket_object`, `search_bucket_data`) | [gist 00cb5682](https://gist.github.com/fede-kamel/00cb568227912735e9717ddc12b649c4) | -The Python-published gists with the verified locus ports live at: +The Python-published gists with the verified SDK ports live at: - [demo_hello_world](https://gist.github.com/fede-kamel/87f1dc5cabd8b434b5ff0e432804c553) - [demo_iron_metabolism (full replay)](https://gist.github.com/fede-kamel/27a6fc50e0df3854e427ecf4715bc005) @@ -46,7 +46,7 @@ The Python-published gists with the verified locus ports live at: - [demo_object_storage](https://gist.github.com/fede-kamel/886293f25576b1589d76a3c18bc3bc4e) - [demo_opensearch_multi_index](https://gist.github.com/fede-kamel/eb9c8ef0ef59cf55c0f67cb8ed80feb1) -## Locus translations from langchain-oci +## SDK translations from langchain-oci | langchain-oci | locus | |---|---| @@ -105,7 +105,7 @@ the table on exit. A successful run looks like: ## Gotchas surfaced during the port -The OpenSearch + GPT-5.1 path surfaced three locus-specific behaviors +The OpenSearch + GPT-5.1 path surfaced three SDK-specific behaviors worth pinning: 1. **`locus.memory.InMemoryStore` is async.** Its `put`/`search`/`get` @@ -120,7 +120,7 @@ worth pinning: loop becomes unusable from the agent's tool calls and returns silent empty results. 4. **Some model providers JSON-encode floats as strings.** GPT-5.x - sends `"min_score": "0.5"` rather than `0.5` for tool args; locus + sends `"min_score": "0.5"` rather than `0.5` for tool args; the SDK coerces this defensively in `RAGRetriever.retrieve` and `OracleVectorStore.search`. If you implement a custom store, coerce at the search boundary too. diff --git a/mkdocs.yml b/mkdocs.yml index 5d0ea35f..75747fbb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -118,7 +118,8 @@ plugins: members_order: source nav: -- locus: index.md +# Home (index.md) is reached via the header wordmark + logo (both link to "/"), +# so we don't repeat it as a tab here. - Concepts: - concepts/multi-agent.md - Capabilities: capabilities.md diff --git a/overrides/main.html b/overrides/main.html index d4a3b67c..29ab10ff 100644 --- a/overrides/main.html +++ b/overrides/main.html @@ -2,12 +2,12 @@ {# Decouples the browser tab / HTML from `site_name`. `site_name` - drives the header banner ("locus — Multi-Agent SDK"); the tab uses a - longer, SEO-friendly phrase that survives truncation gracefully and - shows the full text on hover (mirrors the Strands docs pattern). + drives the header wordmark; the tab carries the approved short product + name so it survives tab-bar truncation and shows the full string on + hover. #} {% block htmltitle %} - {% set tab_title = "locus — Oracle Generative AI Multi-Agent Reasoning SDK" %} + {% set tab_title = "Oracle Generative AI – Multi-Agent Locus SDK" %} {% if page and page.title and not page.is_homepage %} <title>{{ page.title | striptags }} - {{ tab_title }} {% else %} @@ -31,18 +31,18 @@ {% set og_image = (config.site_url ~ "/img/og-card.png") | replace("//img/", "/img/") %} - + - + - + {% endblock %} diff --git a/workbench/README.md b/workbench/README.md index fff710b6..681637a8 100644 --- a/workbench/README.md +++ b/workbench/README.md @@ -1,8 +1,8 @@ -# workbench — locus pattern playground +# workbench — Oracle Generative AI – Multi-Agent Locus SDK pattern playground A self-contained 3-tier workbench: **vanilla TypeScript front-end** ↔ -**Node BFF** ↔ **Locus Python pattern runner**. Bring your own provider -credentials (OpenAI / Anthropic / OCI session / OCI api-key) — no +**Node BFF** ↔ **Python pattern runner built on the SDK**. Bring your own +provider credentials (OpenAI / Anthropic / OCI session / OCI api-key) — no instance principals, no external dependencies beyond the model provider. diff --git a/workbench/SDK-ERGONOMICS.md b/workbench/SDK-ERGONOMICS.md index 355fa1b5..aeaed48b 100644 --- a/workbench/SDK-ERGONOMICS.md +++ b/workbench/SDK-ERGONOMICS.md @@ -1,8 +1,9 @@ -# Locus SDK ergonomics — workbench audit +# SDK ergonomics — workbench audit How much code does a developer need to write to do something useful with -Locus? This is a short, honest snapshot from running the workbench -against every model-only notebook. +the Oracle Generative AI – Multi-Agent Locus SDK? This is a short, +honest snapshot from running the workbench against every model-only +notebook. ## The 90% case is one screen