Skip to main content
Glama
README.md
# OOSDK — Ontology-Oriented Multi-Agent Platform

**Business strategy as code.** OOSDK drives a multi-agent system from a single **ontology** (`ontology.yaml`) that encodes a company's policies and decision rules. Change one line of policy and the agents' collaboration and branching change — **no code redeploy**. The ontology defines *WHAT* (policy/intent); the agents handle *HOW* (execution) — so routine decisions can be made deterministically by policy rather than by an LLM call.

> The flagship of the **SunnyLab** build series. This is a **sanitized public showcase** — credentials, tokens, and infrastructure identifiers (GCP project, VM IP, Odoo tenant) were removed before publishing. Some modules require your own Odoo/Salesforce/GCP configuration to run end to end.

![OOSDK system architecture — AI clients on the left reaching a multi-agent orchestrator, which is backed by an MCP server on GCP, the ontology, and a RAG vector store, and which drives Email, CRM, ERP, and Calendar across the order-to-cash cycle.](assets/oosdk-architecture.png)

> **Order-to-cash now closes end-to-end** — from Lead all the way to a real `account.payment` ("In Payment") in Odoo. Across the whole cycle the LLM speaks in **exactly two seats** (how to ship a short order, and who to chase first and in what tone); everything else — allocation, dispatch, invoicing, payment — is deterministic policy. That boundary is a single yaml toggle.

Three things in that picture carry the design. The **ontology** sits beside the orchestrator rather than under it, because policy is an input to routing, not a consequence of it. The **MCP server** is what makes the client column swappable — any MCP-capable client is a valid front door. And the **order-to-cash band** is drawn as the outcome, not as a feature list: the system is judged on whether cash actually lands.

## Core idea
```
ontology.yaml  (policy / strategy, human-editable)
        │   "WHAT to do, under which policy"
        ▼
Ontology Engine ── deterministic policy decisions ──►  Agents ("HOW", execution)
        │                                                 ├─ crm / erp / inventory / collections
        │                                                 ├─ cs / helpdesk / email / calendar
        └─ when needed: LLM reasoning + RAG               └─ analytics / report   (10 domain agents)
```
- **Policy-driven dispatch** — many decisions need *zero* LLM calls (cost + determinism)
- **LLM only where the answer depends on context** — caged as an *advisor*: whitelisted input, forced JSON, human approval, deterministic fallback if the model is off or fails
- **Extensible by design** — add a new domain agent on the same base; the ontology wires it in (the `collections_agent` was added this way to close the cycle)

## Business Case (BC) series — order-to-cash, end-to-end
A B2B sales-to-cash cycle automated across stages, integrating **Salesforce (SFDC)** and **Odoo ERP**. Design thesis: *the LLM speaks only in the few seats where the answer depends on context; the rest is deterministic policy.*

![Order-to-Cash lifecycle — Lead → Quote → Order/Inventory → Ship · Invoice · Collect, closing on cash. The happy path is deterministic; only two judgments are AI: partial-shipment split and dunning.](assets/order-to-cash-lifecycle.png)

> The architecture diagram above shows the classic five-stage order-to-cash band (quote → payment). This lifecycle view extends one stage further upstream: **BC1 starts at the inbound email and the Lead**, before a quote exists. Same cycle, one stage earlier.

- **BC1 Customer pipeline** — inbound email → sender lookup → **tier routing**, zero LLM (first-match ontology rules), idempotent lead creation:
  - **VIP** → qualified lead + priority meeting booked within 24h + premium-tone invite
  - **Standard** → qualified lead + RAG-drafted reply on an 8h SLA
  - **New prospect** (unregistered) → lead (enrichment pending) + 24h welcome
- **BC2 Sales** — opportunity with **tier-differentiated pricing & process**, then ERP handoff on close:
  - **VIP** → 5-stage process, *negotiable* pricing (discount up to a cap, approval beyond)
  - **Standard** → 4-stage process, *list price* fixed (no discount authority)
  - **Closed Won** → Odoo **Sales Order** auto-created & confirmed (idempotent) + thank-you (+ VIP kickoff meeting); **Closed Lost** → LLM lost-reason analysis + 180-day re-engage task (no ERP push)
  - *contract = Opportunity → Sales Order*; pricing is deterministic, the only LLM call is Lost-reason analysis
- **BC3 Order & inventory** — confirmed SO → line split → deterministic allocation, with AI only where stock truly runs out:
  - **Line split** — storable → delivery, service → license activation
  - **Allocation (deterministic)** — VIP soft-preempt / Standard FIFO / partial-fill (Waiting) / re-allocate on stock receipt / batch pre-allocation, over a 4-state model (on-hand / reserved / available / incoming)
  - **Autonomous replenishment (AI)** — when no rule can fill the shortage: an LLM **qty advisor** sizes the purchase, creates the incoming picking, and writes an LLM **manager briefing** — both AI points fall back to rules
- **BC4 Ship · Invoice · Collect** — closing the cycle in cash:
  - **Ship** — partial-shipment **advisor** (split / wait) → human approve → one approval chains ship + invoice + notify
  - **Invoice** — deterministic **mixed billing** (per-line invoice policy: shipped qty vs. full); *no rule, no agent — by design*
  - **Collect** — dunning **advisor** (recovery priority + tier tone: VIP gentle / repeat-late firm) → approve → send + chatter → `account.payment` → invoice **"In Payment"**

> Two AI advisor seats (partial-shipment, dunning); everything between is deterministic, and both execute only after a human approves.

## Key capabilities
- **Ontology engine** that encodes business policy and drives multi-agent collaboration
- **10 multi-domain agents** (CRM, ERP, inventory, collections, CS, helpdesk, email, calendar, analytics, report) over **MCP / FastMCP**
- **Caged LLM advisors** — two-step `trigger → confirm`: the model only *recommends*, a human approves, and execution is deterministic (with a rule fallback if the model fails)
- **Order-to-cash close** — partial shipping, mixed-billing invoicing, and AR collections → real Odoo `account.payment`
- **Enterprise integration** — SFDC + Odoo ERP adapters; **RAG (ChromaDB)**; 3-tier memory (hot/warm/cold)
- **Bilingual Streamlit dashboard** (KR/EN) — decisions, inventory, ontology stats
- **Cloud-native** — Docker, Cloud Build, GitHub Actions (project/VM values are placeholders)

## Tech stack
Python · MCP / FastMCP · Ontology-driven orchestration · Salesforce & Odoo ERP · ChromaDB (RAG) · Streamlit · Docker · Google Cloud · GitHub Actions

## Project structure
```
ontology/            # ontology.yaml — business policy as code
mcp_server/          # ontology engine, domain agents, tools, adapters (SFDC/Odoo)
dashboard_modules/   # dashboard components
dashboard.py / dashboard_en.py   # Streamlit dashboards (KR/EN)
scripts/             # BC1-BC4 business-case demos & setup
assets/              # system architecture + order-to-cash lifecycle diagrams
tests/               # unit tests
.env.example         # required env vars (no real keys)
```

## Setup
```bash
cp .env.example .env      # configure OpenAI/Google, Salesforce, Odoo (your own)
pip install -r requirements.txt

# 1) start the MCP server in HTTP (SSE) mode — serves the API on port 9101
MCP_MODE=sse python -m mcp_server.server

# 2) then launch a dashboard (KR / EN) in a separate shell:
streamlit run dashboard.py
```
> The dashboard talks to the server API on **port 9101**, so start the MCP server **first** and keep it running; the dashboard shows no data until the server is up. External integrations (Odoo, Salesforce, GCP) need your own configuration to run end to end.

## Tests & demos
```bash
# run the test suite
pytest              # or: pytest tests/

# BC demos — run in order (BC2 → BC3 → BC4 → BC5); each may need its own Odoo/SFDC setup
python scripts/bc2_to_odoo_handoff.py         # BC2  Closed Won → Odoo Sales Order
python scripts/bc3_inventory_demo.py          # BC3  order split + deterministic allocation
python scripts/bc4_demo_partial_shipment.py   # BC4  partial-shipment advisor → ship · invoice
python scripts/bc5_demo_replenishment.py      # BC5  autonomous replenishment + dunning
```
> The demos drive live Odoo/Salesforce data, so each script may require its own tenant setup (the `bc*_setup_*.py` / `bc*_create_*.py` helpers in `scripts/` seed the needed records). Additional scenarios live alongside these, e.g. `bc4_demo_scenario_ABC.py` and `bc5_demo_scenario12.py`.

## What's next
Two experiments are queued, both aimed at the same question — how much of this still works as the model gets cheaper and the entry points multiply:

- **Smaller models in the orchestrator seat.** The orchestrator currently runs on a frontier model. Since the ontology already makes the routine decisions deterministically, the model's remaining job is narrow — which is exactly the condition under which a small model should hold up. Planned as an A/B against the current setup, measured on decision accuracy rather than on benchmark scores.
- **Widening the client column.** Today the front doors are desktop MCP clients and the ADK web/mobile server. The MCP boundary makes additional entry points (chat surfaces, embedded app views) additive rather than structural.

Neither is implemented yet — they are stated here because the architecture was built to absorb both without a redesign, and that claim is worth holding the author to.

## The SunnyLab build series
This repo is the endpoint of a year-long build. The earlier steps are public too, each isolating one problem:

| # | Repo | What it adds |
|---|------|--------------|
| 1 | [ai_mcp_fastmcp](https://github.com/sunnylabtv-crypto/ai_mcp_fastmcp) | Local MCP server (stdio), single user — Gmail · OpenAI · Salesforce as tools |
| 2 | [ai_mcp_fastmcp_remote-public](https://github.com/sunnylabtv-crypto/ai_mcp_fastmcp_remote-public) | Remote, HTTP-streamable **resumable** transport — multi-user, deployed to cloud |
| 3 | [ai_mcp_multi_agent-public](https://github.com/sunnylabtv-crypto/ai_mcp_multi_agent-public) | Orchestrator + 6 domain agents over the same tool layer |
| 4 | [ai_mcp_langgraph-public](https://github.com/sunnylabtv-crypto/ai_mcp_langgraph-public) | Same capabilities, orchestrated by an explicit LangGraph state machine |
| 5 | [ai_web_orchestrator_adk-public](https://github.com/sunnylabtv-crypto/ai_web_orchestrator_adk-public) | Google ADK (Gemini) web/mobile front door onto the MCP server |
| **6** | **ai_mcp_multi_agent_oosdk-public** ← *you are here* | **Ontology-driven policy engine — order-to-cash, end to end** |

## Note
Public **portfolio showcase** of an actively evolving project. For safety, all secrets/credentials and infra identifiers were stripped; external integrations (Odoo, Salesforce, GCP) require your own configuration. Architecture write-ups and demos: SunnyLab below.

## License
[MIT](LICENSE) — free to use, modify, and distribute with attribution. Provided as is, without warranty.
The third-party services it integrates with (OpenAI, Google, Salesforce, Odoo) are governed by their own terms; the diagrams and screenshots under `assets/` are the author's own work.

---
**SunnyLab** — building agentic AI in public · Medium [@sunnylabtv](https://medium.com/@sunnylabtv) · YouTube [@sunnylabtv](https://www.youtube.com/@sunnylabtv)