Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions AI/workflows/external_system_interaction/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-
113 changes: 113 additions & 0 deletions AI/workflows/external_system_interaction/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
## 🧠 Agentic Human-In-The-Loop — Durable Workflows with Dapr (+ OpenAI, Gemini, Anthropic)

This repo demonstrates a durable, agentic AI workflow for contract review built on Dapr Workflows and a simple FastAPI service. It ships three interchangeable implementations using different LLM providers:

* `./anthropic/` — Anthropic Claude–based contract analyst
* `./gemini/` — Google Gemini–based contract analyst
* `./openai/` — OpenAI-based contract analyst

Each example uses the same workflow shape: **analyze → decide → (optionally) wait for human approval → finalize → report**. The only difference is the LLM client and prompts used under the hood.

Start in the provider folder you want (e.g., cd gemini) and follow that README.

### ✨ What the Agentic Workflow Does

* **LLM analysis**: Extract risks and summarize the contract.
* **Decision**: If risk > threshold, propose amendments and pause for human approval.
* **Durability**: The workflow persists state and can survive restarts and timeouts.
* **Output**: Emit a structured JSON report for downstream systems.


All three implementations share these semantics; you can swap providers without changing orchestration logic.

### 🧩 Tech Highlights

* **Dapr Workflows**: Durable execution, timers, retries, external event waiting.
* **FastAPI**: Minimal HTTP surface for starting workflows and posting approvals.

### 🛠 Prerequisites (All Providers)

* Python 3.10+
* [Dapr and Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
* Docker (for local Dapr dependencies)
* Provider API key (one of):
* **OpenAI**: OPENAI\_API\_KEY
* **Gemini**: GEMINI\_API\_KEY
* **Anthropic**: ANTHROPIC\_API\_KEY

Each subfolder has its own requirements.txt and provider-specific notes.

### 🚀 Quickstart

Pick a provider folder and follow its README. The flow is generally:

```bash
# 1) Choose a provider implementation
cd openai # or gemini / anthropic

# 2) Install deps
pip install -r requirements.txt

# 3) Export your provider API key
export OPENAI_API_KEY=... // or GEMINI_API_KEY or ANTHROPIC_API_KEY

# 4) Run the FastAPI app with Dapr
dapr run --app-id contract-review --app-port 8000 -- uvicorn app:app --reload

# 5) Kick off a contract review (example payloads in each README)
curl -X POST http://localhost:8000/review -H "Content-Type: application/json" -d '{ "...": "..." }'

# 6) If required, approve later by posting to /approve/{instanceId}

curl -X POST http://localhost:8000/approve/workflow-<CONTRACT-ID> -H "Content-Type: application/json" -d '{
"approved": true,
"reviewer": "Alice",
"notes": "Reviewed and approved."
}'
```

### 🔄 Choosing a Provider

Start with the provider you already use in production or prefer for pricing/latency.

The workflow contract (endpoints, payloads, and output JSON) is held constant across implementations to make A/B comparisons trivial.

#### 🧪 Example Endpoints (common shape)

* POST /review — Start a new workflow instance with a contract payload
* POST /approve/{instanceId} — Resume a paused workflow with human approval

See each provider's README for exact payloads and sample cURL commands.

#### 🧱 Architecture (High-Level)

```yaml
[Client] ──HTTP──> [FastAPI + Dapr Workflow]
├─ Activity: LLM Analysis (OpenAI/Gemini/Anthropic)
├─ Timer/Wait: Human Approval (external event)
└─ Activity: Finalize Report → JSON
```

* **Durability**: Dapr Workflow state persists in the configured state store.
* **Resilience**: Retries and timers are handled by the workflow runtime.
* **Extensibility**: Add tools (RAG, DB lookups, signature checks) as new activities.

### 🧯 Troubleshooting

* Run dapr status to confirm the sidecar and default components are healthy.
* If workflow doesn't resume, verify you're posting approval to the correct instance ID.
* If the workflow doesn't kick off, make sure you're using a new instance ID in the /review request.
* Check provider-specific rate limits or key scopes.
* Inspect app logs (and Dapr sidecar logs) for activity failures and retries.

### 📚 Related Docs
--------------------------------

* **Dapr Workflows**: [https://docs.dapr.io/developing-applications/building-blocks/workflow/](https://docs.dapr.io/developing-applications/building-blocks/workflow/)
* **OpenAI Python SDK**: [https://platform.openai.com/docs/](https://platform.openai.com/docs/)
* **Google Gemini**: [https://aistudio.google.com/](https://aistudio.google.com/)
* **Anthropic Claude**: [https://docs.anthropic.com/](https://docs.anthropic.com/)

<br>
Built with ❤️ using Dapr Workflows. Swap the model, keep the durability.
121 changes: 121 additions & 0 deletions AI/workflows/external_system_interaction/anthropic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# 🧠 Agentic Contract Review Workflow (Dapr + Claude + FastAPI)

This project demonstrates how to build a **durable, agentic AI workflow** using [Dapr Workflows](https://docs.dapr.io/developing-applications/building-blocks/workflow/) and [Anthropic Claude](https://www.anthropic.com/claude). It showcases how to mix the intelligence of a large language model with the resilience and statefulness of a distributed workflow engine.

---

## ✨ What It Does

Claude plays the role of a contract analyst, and Dapr Workflows orchestrates the process across time:

1. Claude reviews each contract and identifies risky clauses.
2. If the contract is risky, Claude drafts amendments.
3. The workflow **waits for human approval** — with timeout and persistence.
4. The results are compiled into a final structured report.

Everything runs in a clean FastAPI service using Dapr's durable execution engine underneath.

Even though this example is using Claude, you can replace the Anthropic SDK with any other LLM provider.

---

## 🛠 Prerequisites

- Python 3.10+
- [Dapr and Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/)
- Docker (for Redis state backend via `dapr init`)
- Anthropic Claude API Key (sign up at [Anthropic](https://www.anthropic.com/))

Install dependencies:

```bash
pip install -r requirements.txt
```

---

## 🚀 Running the App

### 1. Start the Dapr-enabled FastAPI server

```bash
dapr run --app-id contract-review --app-port 8000 -- uvicorn app:app --reload
```

This launches the FastAPI app with Dapr Workflow runtime. You’ll see:

```
== Dapr Workflow Runtime started ==
```

---

### 2. Submit a contract for review

For subsequent runs, make sure to use a new `id`.

```bash
curl -X POST http://localhost:8000/review \
-H "Content-Type: application/json" \
-d '{
"id": "C100",
"text": "SERVICE AGREEMENT\n\nThis Service Agreement (\"Agreement\") is entered into between ACME Data Solutions, Inc. (\"Provider\") and ClientCo LLC (\"Client\") effective as of August 1, 2025.\n\n1. SERVICES\nProvider agrees to deliver cloud data analytics services to Client as described in Exhibit A.\n\n2. PAYMENT TERMS\nClient shall pay Provider $50,000 per month, due within 15 days of invoice date. Failure to pay within 30 days may result in suspension of services.\n\n3. DATA OWNERSHIP\nAll data processed shall become the property of Provider, including any derivative works, without limitation.\n\n4. LIABILITY LIMITATION\nProvider shall not be liable for any damages, including loss of revenue, indirect, incidental, or consequential damages, even if advised of the possibility thereof.\n\n5. TERMINATION\nEither party may terminate this Agreement at any time with 5 days’ written notice. Client shall remain responsible for payment for all services rendered up to the termination date.\n\n6. CONFIDENTIALITY\nBoth parties agree to maintain confidentiality of proprietary information for a period of 12 months following termination.\n\nIN WITNESS WHEREOF, the parties have executed this Agreement as of the date first written above."
}'
```

This creates a new durable workflow instance: `workflow-C100`.

When starting future contract approval workflows, use a new workflow instance id for every call.

---

### 3. (Optional) Approve the contract if required

If Claude flags the contract as high risk, the workflow pauses and waits for this:

```bash
curl -X POST http://localhost:8000/approve/workflow-C100 -H "Content-Type: application/json" -d '{
"approved": true,
"reviewer": "Alice",
"notes": "Reviewed and approved as-is."
}'
```

If approval is not received in 24 hours, the workflow times out and continues gracefully.

---

## 🧠 Why Use Dapr Workflows?

Traditional LLM apps forget things, fail silently, and can’t wait.

Dapr Workflows gives your agent:

- **Durability** — survives restarts and crashes
- **Event waiting** — pauses for human input or external triggers
- **Retries & orchestration** — handles timeouts, branches, parallel execution
- **Composability** — plug in tools, APIs, databases, and humans

---

## 🧪 Example Output

```json
{
"id": "C100",
"analysis": {
"summary": "The contract includes broad data ownership and limited liability.",
"risk_score": 82,
"risky_clauses": ["3. Data Ownership", "4. Liability Limitation"]
},
"approved": true,
"approver": "Alice",
"notes": "Reviewed and approved as-is."
}
```

---

## 📚 Resources

- [🧭 Dapr Workflow Documentation](https://docs.dapr.io/developing-applications/building-blocks/workflow/workflow-overview/)
Loading
Loading