Skip to content
Closed
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
2 changes: 2 additions & 0 deletions examples/cbam-calculator/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# pragma: allowlist secret
OPENROUTER_API_KEY=your_openrouter_api_key_here # pragma: allowlist secret
117 changes: 117 additions & 0 deletions examples/cbam-calculator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# 🌍 CBAM Carbon Calculator

A Bindu trade compliance agent that calculates Carbon Border Adjustment
Mechanism (CBAM) obligations for EU importers under EU Regulation 2023/956.

CBAM entered its definitive phase on **1 January 2026**. EU importers of
covered goods must now purchase and surrender CBAM certificates proportional
to the embedded carbon emissions in their imports — or face blocked shipments
and fines.

## Covered Sectors

| Sector | HS Chapters |
|---|---|
| Iron & Steel | 72, 73 |
| Aluminium | 76 |
| Cement | 25 |
| Fertilizers | 31 |
| Hydrogen | 2804.10 |
| Electricity | 2716.00 |

## Features

- Checks whether CBAM applies to your product and origin country
- Applies the 50-tonne annual exemption threshold
- Estimates CBAM certificate cost using embedded emissions × EU ETS price
- Uses sector default emission factors when supplier data is unavailable
- Lists Authorised CBAM Declarant requirements
- Generates a documentation checklist for your specific import
- Flags key compliance risks

## Output Format

```text
CBAM APPLICABILITY
Whether CBAM applies, with CN code reference.

EXEMPTION CHECK
50-tonne threshold result — exempt or full compliance required.

COST ESTIMATE
Step-by-step calculation: emissions × ETS price = certificate cost.

COMPLIANCE REQUIREMENTS
What you must do: declarant status, certificates, annual declaration.

DOCUMENTATION CHECKLIST
Specific documents required for this import.

KEY RISKS
Main compliance risks for your specific case.
```

## Setup

```bash
cp .env.example .env
# Add your OPENROUTER_API_KEY to .env

uv add bindu agno python-dotenv
python cbam_calculator.py
```

The agent runs at `http://localhost:3773`.

## Example Queries

```text
Do I need CBAM for importing steel pipes from China?
Calculate CBAM cost for 200 tonnes of aluminium from Turkey
Am I exempt from CBAM if I import 30 tonnes of cement per year?
What documents do I need to import fertilizers from Egypt into the EU?
Is CBAM applicable for hydrogen imports from Saudi Arabia?
```

## Key Dates

| Date | Event |
|---|---|
| 1 Oct 2023 | Transitional phase began (reporting only) |
| 1 Jan 2026 | Definitive phase — financial liability starts |
| 31 Mar 2026 | Deadline for Authorised CBAM Declarant registration |
| 31 May 2026 | First annual CBAM declaration due |
| 2026–2034 | Free ETS allowances gradually phased out |

## Exempt Countries

Iceland, Liechtenstein, Norway, and Switzerland are exempt — they have
their own ETS systems linked to the EU ETS.

## Project Structure

```text
cbam-calculator/
├── cbam_calculator.py # Main agent + bindufy()
├── .env.example # Environment variables
├── skills/
│ └── cbam-compliance-skill/
│ └── skill.yaml # Skill definition
└── README.md
```

## Environment Variables

| Variable | Required | Description |
|---|---|---|
| `OPENROUTER_API_KEY` | Yes | OpenRouter API key |
| `BINDU_DEPLOYMENT_URL` | No | Override default `http://localhost:3773` |

## Disclaimer

This agent provides general guidance only and does not constitute legal or
tax advice. CBAM obligations depend on specific product characteristics,
verified emissions data, and current EU ETS prices. Always consult a licensed
customs broker or trade compliance specialist before filing CBAM declarations.

Reference: EU Regulation 2023/956 — https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32023R0956
187 changes: 187 additions & 0 deletions examples/cbam-calculator/cbam_calculator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
"""
CBAM Carbon Calculator — Bindu Example

A trade compliance agent that helps EU importers understand their Carbon
Border Adjustment Mechanism (CBAM) obligations under EU Regulation 2023/956.

CBAM entered its definitive phase on 1 January 2026. Importers of covered
goods (iron & steel, aluminium, cement, fertilizers, hydrogen, electricity)
must now purchase and surrender CBAM certificates proportional to the
embedded carbon emissions in their imports.

Getting this wrong means blocked shipments, fines, or unexpected carbon costs
that wipe out margins. This agent helps SMBs understand their exposure before
they file.

Prerequisites
-------------
uv add bindu agno python-dotenv

Usage
-----
export OPENROUTER_API_KEY="your_api_key_here" # pragma: allowlist secret
python cbam_calculator.py

The agent will be live at http://localhost:3773
Example queries:
"Do I need CBAM for importing steel pipes from China?"
"Calculate CBAM cost for 200 tonnes of aluminium from Turkey"
"Am I exempt from CBAM if I import 30 tonnes of cement per year?"
"""

import os

from agno.agent import Agent
from agno.models.openrouter import OpenRouter
from bindu.penguin.bindufy import bindufy
from dotenv import load_dotenv

load_dotenv()

# ---------------------------------------------------------------------------
# 1. Agent definition
# ---------------------------------------------------------------------------

INSTRUCTIONS = """
You are an expert EU trade compliance specialist with deep knowledge of the
Carbon Border Adjustment Mechanism (CBAM) — EU Regulation 2023/956, which
entered its definitive phase on 1 January 2026.

When asked about CBAM, respond in this exact structure:

CBAM APPLICABILITY
State clearly whether CBAM applies to the described goods.
Reference the specific sector and CN (Combined Nomenclature) code if known.

EXEMPTION CHECK
Check the 50-tonne annual threshold:
- Below 50 tonnes/year → largely exempt from reporting and authorisation
(exception: electricity and hydrogen remain in scope regardless of quantity)
- Above 50 tonnes/year → full CBAM compliance required
State the result clearly.

COST ESTIMATE
If CBAM applies and tonnage is provided, calculate the estimated CBAM cost:
- Formula: Embedded emissions (tCO2e) × EU ETS carbon price (€/tCO2e)
- Use the current EU ETS price (approximately €65/tCO2e as of 2026 — note
this fluctuates; importers should check the live ETS price)
- If embedded emissions data is not provided, use default emission factors
for the sector and state clearly that these are default values
- Show the calculation step by step

COMPLIANCE REQUIREMENTS
List what the importer must do:
1. Authorised CBAM Declarant status (required since 31 March 2026)
2. CBAM certificates — must hold 50% of embedded emissions per quarter
3. Annual CBAM declaration — due by 31 May each year
4. Embedded emissions data — from supplier (preferred) or default values
5. Verification — third-party verification required for actual emissions data

DOCUMENTATION CHECKLIST
List the specific documents required for this import.

KEY RISKS
2-3 bullet points on the main compliance risks for this specific case.

Rules:
- Always cite EU Regulation 2023/956
- Be precise about the 50-tonne threshold and sector coverage
- Never invent carbon prices — use the approximate figure and tell the
importer to verify the live ETS price at https://ember-climate.org/data/
- If the product is not in a covered sector, say so clearly
- Output in plain Markdown
- Covered sectors: iron & steel, aluminium, cement, fertilizers,
hydrogen, electricity
- Exempt countries: Iceland, Liechtenstein, Norway, Switzerland
(have their own ETS linked to EU ETS)
""".strip()

agent = Agent(
instructions=INSTRUCTIONS,
model=OpenRouter(
id="openai/gpt-4o-mini",
api_key=os.getenv("OPENROUTER_API_KEY"), # pragma: allowlist secret
),
markdown=True,
)


# ---------------------------------------------------------------------------
# 2. Bindu configuration
# ---------------------------------------------------------------------------

config = {
"author": "your.email@example.com",
"name": "cbam_calculator",
"description": (
"An EU trade compliance agent that calculates Carbon Border Adjustment "
"Mechanism (CBAM) obligations under EU Regulation 2023/956. Covers "
"applicability checks, exemption thresholds, cost estimates, compliance "
"requirements, and documentation checklists for EU importers of "
"iron & steel, aluminium, cement, fertilizers, hydrogen, and electricity."
),
"version": "1.0.0",
"capabilities": {
"compliance": ["cbam", "carbon-border-tax", "eu-regulation", "trade-compliance"],
"calculation": ["carbon-cost", "ets-price", "embedded-emissions"],
"research": ["exemption-check", "documentation-requirements"],
"streaming": False,
},
"skills": ["skills/cbam-compliance-skill"],
"auth": {"enabled": False},
"storage": {"type": "memory"},
"scheduler": {"type": "memory"},
"deployment": {
"url": os.getenv("BINDU_DEPLOYMENT_URL", "http://localhost:3773"),
"expose": True,
"cors_origins": ["http://localhost:5173"],
},
}


# ---------------------------------------------------------------------------
# 3. Handler
# ---------------------------------------------------------------------------

def handler(messages: list[dict[str, str]]):
"""Calculate CBAM obligations for an EU importer.

Args:
messages: Standard A2A message list, e.g.
[{"role": "user", "content":
"Calculate CBAM cost for 200 tonnes of aluminium from Turkey"}]

Returns:
CBAM applicability, exemption check, cost estimate, compliance
requirements, documentation checklist, and key risks.
"""
try:
user_messages = [m for m in messages if m.get("role") == "user"]
if not user_messages:
return (
"No query received. Please describe your import, e.g. "
"'Do I need CBAM for importing 200 tonnes of steel from China?'"
)

query = user_messages[-1].get("content", "").strip()
logger.debug("Query: %s", query)`n if not query:
return (
"Empty query. Please describe your import situation, e.g. "
"'Calculate CBAM cost for 200 tonnes of aluminium from Turkey'"
)
Comment on lines +166 to +171
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Minor: query is validated but never used.

The non-empty query is computed for the empty-input guard but the agent is run on the full messages list, so the extracted query is otherwise unused. Functionally fine; flagging for clarity since the guard and the run input diverge.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/cbam-calculator/cbam_calculator.py` around lines 166 - 171, The
guard computes query from user_messages[-1] but never uses it when invoking the
agent, so align the inputs: either use the extracted query when running the
agent (pass [ {"role": "user", "content": query} ] or equivalent to agent.run)
or remove the query variable and validate directly against
messages/user_messages; update the code paths around query, user_messages,
messages, and the agent.run call so the same data is validated and passed to the
agent.


result = agent.run(input=messages)
return result

except Exception as e:
return f"CBAM calculation error: {str(e)}"


# ---------------------------------------------------------------------------
# 4. Entry point
# ---------------------------------------------------------------------------

if __name__ == "__main__":
print("🌍 CBAM Carbon Calculator running at http://localhost:3773")
print("♻️ Example: Calculate CBAM cost for 200 tonnes of aluminium from Turkey")
bindufy(config, handler)
Loading
Loading