zambo-openai-agents 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zambo (zambo.dev)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: zambo-openai-agents
3
+ Version: 0.1.0
4
+ Summary: Zambo's 100+ tools as OpenAI Agents SDK tools. Every call mints a verifiable AER-1 execution receipt.
5
+ Author-email: Zambo <brennanzambo@zambo.dev>
6
+ License: MIT
7
+ Project-URL: Homepage, https://zambo.dev
8
+ Project-URL: Documentation, https://zambo.dev/aer-1/
9
+ Project-URL: Repository, https://zambo.dev
10
+ Keywords: openai,agents,ai-agents,zambo,mcp,receipts,verification,tracing
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: openai-agents>=0.20
23
+ Dynamic: license-file
24
+
25
+ # zambo-openai-agents
26
+
27
+ Give your OpenAI Agents SDK agent Zambo's 100+ live tools. Every tool call is executed by Zambo and mints a **verifiable AER-1 receipt**: a public URL carrying the tool, its arguments, the observed result, a SHA-256 fingerprint, and machine-readable JSON-LD.
28
+
29
+ ```python
30
+ from agents import Agent, Runner
31
+ from zambo_openai_agents import zambo_tools
32
+
33
+ agent = Agent(name="assistant", tools=zambo_tools(["live_price", "prompt_shield"]))
34
+ result = await Runner.run(agent, "What is the live BTC price?")
35
+ ```
36
+
37
+ No account. No API key. Free tier: 20 calls per tool per day.
38
+
39
+ ## What the receipt actually proves
40
+
41
+ Each receipt page (for example `https://zambo.dev/run/<id>`) is Zambo's tamper-evident record that **Zambo executed the tool call itself**: the tool name, the exact arguments your agent sent, the observed result, a timestamp, and a SHA-256 fingerprint of the record, published as JSON-LD. Anyone can re-verify it with no account.
42
+
43
+ The included `ZamboReceiptProcessor` (a standard `TracingProcessor`) attaches each minted receipt URL to its trace span, so the trace shows proof next to every call:
44
+
45
+ ```python
46
+ from agents.tracing.setup import get_trace_provider
47
+ from zambo_openai_agents import ZamboReceiptProcessor
48
+
49
+ processor = ZamboReceiptProcessor()
50
+ get_trace_provider().register_processor(processor)
51
+ # after the run: processor.receipts -> {span_id: receipt_url}
52
+ ```
53
+
54
+ ## Install
55
+
56
+ ```bash
57
+ pip install zambo-openai-agents
58
+ ```
59
+
60
+ ## One tool, custom schema
61
+
62
+ ```python
63
+ from zambo_openai_agents import zambo_tool
64
+
65
+ price_tool = zambo_tool(
66
+ "live_price",
67
+ params_json_schema={
68
+ "type": "object",
69
+ "properties": {"symbol": {"type": "string"}},
70
+ "required": ["symbol"],
71
+ },
72
+ )
73
+ ```
74
+
75
+ Browse the full catalog any time with `zambo_openai_agents.list_tools()`, or pick tools by use case through Zambo's `capability_search` tool.
76
+
77
+ ## Notes
78
+
79
+ - Zambo calls need no key and no signup. Heavy tracing (dozens of tool calls per run) will reach the free daily limit; the tool raises a clear error and the agent run continues with the other tools.
80
+ - The processor never breaks your run: span handling is fully exception-guarded, and it ignores non-Zambo spans.
81
+ - Receipts are public by design. Do not pass secrets as tool arguments.
82
+
83
+ ## Links
84
+
85
+ - Zambo: https://zambo.dev
86
+ - AER-1 receipt spec: https://zambo.dev/aer-1/
87
+ - OpenAI Agents SDK tracing: https://openai.github.io/openai-agents-python/tracing/
88
+
89
+ MIT License.
@@ -0,0 +1,65 @@
1
+ # zambo-openai-agents
2
+
3
+ Give your OpenAI Agents SDK agent Zambo's 100+ live tools. Every tool call is executed by Zambo and mints a **verifiable AER-1 receipt**: a public URL carrying the tool, its arguments, the observed result, a SHA-256 fingerprint, and machine-readable JSON-LD.
4
+
5
+ ```python
6
+ from agents import Agent, Runner
7
+ from zambo_openai_agents import zambo_tools
8
+
9
+ agent = Agent(name="assistant", tools=zambo_tools(["live_price", "prompt_shield"]))
10
+ result = await Runner.run(agent, "What is the live BTC price?")
11
+ ```
12
+
13
+ No account. No API key. Free tier: 20 calls per tool per day.
14
+
15
+ ## What the receipt actually proves
16
+
17
+ Each receipt page (for example `https://zambo.dev/run/<id>`) is Zambo's tamper-evident record that **Zambo executed the tool call itself**: the tool name, the exact arguments your agent sent, the observed result, a timestamp, and a SHA-256 fingerprint of the record, published as JSON-LD. Anyone can re-verify it with no account.
18
+
19
+ The included `ZamboReceiptProcessor` (a standard `TracingProcessor`) attaches each minted receipt URL to its trace span, so the trace shows proof next to every call:
20
+
21
+ ```python
22
+ from agents.tracing.setup import get_trace_provider
23
+ from zambo_openai_agents import ZamboReceiptProcessor
24
+
25
+ processor = ZamboReceiptProcessor()
26
+ get_trace_provider().register_processor(processor)
27
+ # after the run: processor.receipts -> {span_id: receipt_url}
28
+ ```
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install zambo-openai-agents
34
+ ```
35
+
36
+ ## One tool, custom schema
37
+
38
+ ```python
39
+ from zambo_openai_agents import zambo_tool
40
+
41
+ price_tool = zambo_tool(
42
+ "live_price",
43
+ params_json_schema={
44
+ "type": "object",
45
+ "properties": {"symbol": {"type": "string"}},
46
+ "required": ["symbol"],
47
+ },
48
+ )
49
+ ```
50
+
51
+ Browse the full catalog any time with `zambo_openai_agents.list_tools()`, or pick tools by use case through Zambo's `capability_search` tool.
52
+
53
+ ## Notes
54
+
55
+ - Zambo calls need no key and no signup. Heavy tracing (dozens of tool calls per run) will reach the free daily limit; the tool raises a clear error and the agent run continues with the other tools.
56
+ - The processor never breaks your run: span handling is fully exception-guarded, and it ignores non-Zambo spans.
57
+ - Receipts are public by design. Do not pass secrets as tool arguments.
58
+
59
+ ## Links
60
+
61
+ - Zambo: https://zambo.dev
62
+ - AER-1 receipt spec: https://zambo.dev/aer-1/
63
+ - OpenAI Agents SDK tracing: https://openai.github.io/openai-agents-python/tracing/
64
+
65
+ MIT License.
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "zambo-openai-agents"
7
+ version = "0.1.0"
8
+ description = "Zambo's 100+ tools as OpenAI Agents SDK tools. Every call mints a verifiable AER-1 execution receipt."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Zambo", email = "brennanzambo@zambo.dev" }]
13
+ keywords = ["openai", "agents", "ai-agents", "zambo", "mcp", "receipts", "verification", "tracing"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
23
+ ]
24
+ dependencies = [
25
+ "openai-agents>=0.20",
26
+ ]
27
+ optional-dependencies = {}
28
+
29
+ [project.urls]
30
+ Homepage = "https://zambo.dev"
31
+ Documentation = "https://zambo.dev/aer-1/"
32
+ Repository = "https://zambo.dev"
33
+
34
+ [tool.setuptools.packages.find]
35
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,23 @@
1
+ """zambo-openai-agents: Zambo's 100+ tools as OpenAI Agents SDK tools.
2
+
3
+ Every tool call is executed by Zambo and mints a verifiable AER-1 receipt:
4
+ a public URL carrying the tool, arguments, observed result, SHA-256
5
+ fingerprint, and machine-readable JSON-LD.
6
+ """
7
+
8
+ from .tools import lookup_receipt, zambo_tool, zambo_tools
9
+ from .tracing import ZamboReceiptProcessor
10
+ from .client import ZamboReceipt, ZamboResult, call_tool, list_tools
11
+
12
+ __all__ = [
13
+ "ZamboReceipt",
14
+ "ZamboReceiptProcessor",
15
+ "ZamboResult",
16
+ "call_tool",
17
+ "list_tools",
18
+ "lookup_receipt",
19
+ "zambo_tool",
20
+ "zambo_tools",
21
+ ]
22
+
23
+ __version__ = "0.1.0"
@@ -0,0 +1,109 @@
1
+ """Minimal Zambo MCP client over plain JSON-RPC.
2
+
3
+ Pure stdlib (urllib), no third-party dependencies. Talks to the live
4
+ https://zambo.dev/api/mcp endpoint: no auth, no account, free tier.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import json
10
+ import http.client
11
+ import time
12
+ import urllib.error
13
+ import urllib.request
14
+ from dataclasses import dataclass, field
15
+
16
+ MCP_URL = "https://zambo.dev/api/mcp"
17
+ _TIMEOUT = 60
18
+ _MAX_ATTEMPTS = 6
19
+
20
+
21
+ @dataclass
22
+ class ZamboReceipt:
23
+ """A verifiable AER-1 execution receipt minted by a Zambo tool call."""
24
+
25
+ id: str
26
+ url: str
27
+ status: str = ""
28
+ tool: str = ""
29
+
30
+
31
+ @dataclass
32
+ class ZamboResult:
33
+ text: str
34
+ receipt: ZamboReceipt | None = None
35
+ raw: dict = field(default_factory=dict)
36
+
37
+
38
+ def _post(payload: dict) -> dict:
39
+ body = json.dumps(payload).encode("utf-8")
40
+ last_error: Exception | None = None
41
+ for attempt in range(_MAX_ATTEMPTS):
42
+ request = urllib.request.Request(
43
+ MCP_URL,
44
+ data=body,
45
+ headers={"Content-Type": "application/json", "Accept": "application/json"},
46
+ method="POST",
47
+ )
48
+ try:
49
+ with urllib.request.urlopen(request, timeout=_TIMEOUT) as response:
50
+ return json.loads(response.read().decode("utf-8"))
51
+ except (
52
+ urllib.error.URLError,
53
+ ConnectionError,
54
+ TimeoutError,
55
+ json.JSONDecodeError,
56
+ http.client.IncompleteRead,
57
+ http.client.RemoteDisconnected,
58
+ http.client.BadStatusLine,
59
+ ) as exc:
60
+ last_error = exc
61
+ time.sleep(1.5 * (attempt + 1))
62
+ raise RuntimeError(f"Zambo API call failed after {_MAX_ATTEMPTS} attempts: {last_error}")
63
+
64
+
65
+ def call_tool(tool_name: str, arguments: dict) -> ZamboResult:
66
+ """Call a Zambo MCP tool and return its result plus the receipt.
67
+
68
+ Every call mints a verifiable AER-1 receipt: a public URL carrying the
69
+ tool, arguments, observed result, SHA-256 fingerprint, and JSON-LD.
70
+ """
71
+ response = _post(
72
+ {
73
+ "jsonrpc": "2.0",
74
+ "id": f"zambo-openai-agents-{int(time.time() * 1000)}",
75
+ "method": "tools/call",
76
+ "params": {"name": tool_name, "arguments": arguments},
77
+ }
78
+ )
79
+ if "error" in response:
80
+ raise RuntimeError(f"Zambo tool '{tool_name}' error: {response['error']}")
81
+
82
+ result = response.get("result", {})
83
+ receipt_data = result.get("_receipt", {}) or {}
84
+
85
+ receipt = None
86
+ receipt_id = receipt_data.get("id")
87
+ if receipt_id:
88
+ receipt = ZamboReceipt(
89
+ id=receipt_id,
90
+ url=receipt_data.get("audit") or f"https://zambo.dev/run/{receipt_id}",
91
+ status=receipt_data.get("status", ""),
92
+ tool=receipt_data.get("tool", tool_name),
93
+ )
94
+
95
+ text_parts = []
96
+ for item in result.get("content", []) or []:
97
+ if isinstance(item, dict) and "text" in item:
98
+ text_parts.append(str(item["text"]))
99
+ text = "\n".join(text_parts).strip()
100
+
101
+ return ZamboResult(text=text, receipt=receipt, raw=result)
102
+
103
+
104
+ def list_tools() -> list[dict]:
105
+ """Return the live Zambo tool catalog (name + description)."""
106
+ response = _post({"jsonrpc": "2.0", "id": "zambo-tools-list", "method": "tools/list", "params": {}})
107
+ if "error" in response:
108
+ raise RuntimeError(f"Zambo tools/list error: {response['error']}")
109
+ return response.get("result", {}).get("tools", []) or []
@@ -0,0 +1,94 @@
1
+ """OpenAI Agents SDK function tools backed by live Zambo execution.
2
+
3
+ Each tool below is a real OpenAI Agents SDK FunctionTool. When the agent
4
+ invokes it, the call is executed by Zambo (https://zambo.dev/api/mcp) and
5
+ mints a verifiable AER-1 receipt: public URL, tool, arguments, observed
6
+ result, SHA-256 fingerprint, machine-readable JSON-LD.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ import json
13
+ import threading
14
+ import time
15
+ from typing import Any, Callable
16
+
17
+ from . import client as _client
18
+
19
+ # (tool_name, arguments_json) -> (receipt_url, finished_at). Written by the
20
+ # tool wrapper on every invocation; read by ZamboReceiptProcessor to attach
21
+ # receipt URLs to trace spans. Thread-safe.
22
+ _invocation_registry: dict[tuple[str, str], tuple[str, float]] = {}
23
+ _registry_lock = threading.Lock()
24
+
25
+
26
+ def _record_invocation(tool_name: str, arguments_json: str, receipt_url: str) -> None:
27
+ with _registry_lock:
28
+ _invocation_registry[(tool_name, arguments_json)] = (receipt_url, time.time())
29
+
30
+
31
+ def lookup_receipt(tool_name: str, arguments_json: str) -> str | None:
32
+ """Return the most recent receipt URL for a (tool, args) invocation."""
33
+ with _registry_lock:
34
+ entry = _invocation_registry.get((tool_name, arguments_json))
35
+ return entry[0] if entry else None
36
+
37
+
38
+ def zambo_tool(
39
+ tool_name: str,
40
+ description: str | None = None,
41
+ params_json_schema: dict | None = None,
42
+ on_receipt: Callable[[str, str], Any] | None = None,
43
+ ):
44
+ """Build an OpenAI Agents SDK FunctionTool backed by a Zambo MCP tool.
45
+
46
+ Args:
47
+ tool_name: Name of the Zambo tool (see client.list_tools(), e.g.
48
+ "live_price", "ghost_audit_site", "prompt_shield").
49
+ description: Override the tool description shown to the model.
50
+ params_json_schema: Override the JSON schema for the tool's arguments.
51
+ Defaults to a permissive object schema; Zambo validates server-side.
52
+ on_receipt: Optional callback invoked as on_receipt(tool_name,
53
+ receipt_url) after every successful invocation.
54
+ """
55
+ from agents.tool import FunctionTool # local import: agents is a dependency
56
+
57
+ # Permissive default: strict-mode compatible (no additionalProperties key).
58
+ # Zambo validates arguments server-side.
59
+ schema = params_json_schema or {"type": "object", "properties": {}}
60
+
61
+ async def _on_invoke_tool(context: Any, arguments_json: str) -> str:
62
+ try:
63
+ arguments = json.loads(arguments_json) if arguments_json else {}
64
+ except json.JSONDecodeError:
65
+ arguments = {}
66
+ if not isinstance(arguments, dict):
67
+ arguments = {"value": arguments}
68
+
69
+ result = await asyncio.to_thread(_client.call_tool, tool_name, arguments)
70
+
71
+ receipt_url = result.receipt.url if result.receipt else ""
72
+ if receipt_url:
73
+ _record_invocation(tool_name, arguments_json, receipt_url)
74
+ if on_receipt is not None:
75
+ maybe = on_receipt(tool_name, receipt_url)
76
+ if asyncio.iscoroutine(maybe):
77
+ await maybe
78
+
79
+ output = result.text or "(empty result)"
80
+ if receipt_url:
81
+ output += f"\n\nVerifiable receipt: {receipt_url}"
82
+ return output
83
+
84
+ return FunctionTool(
85
+ name=tool_name,
86
+ description=description or f"Zambo tool '{tool_name}' (zambo.dev). Every call mints a verifiable execution receipt.",
87
+ params_json_schema=schema,
88
+ on_invoke_tool=_on_invoke_tool,
89
+ )
90
+
91
+
92
+ def zambo_tools(tool_names: list[str], **kwargs: Any) -> list:
93
+ """Build several Zambo-backed FunctionTools at once."""
94
+ return [zambo_tool(name, **kwargs) for name in tool_names]
@@ -0,0 +1,85 @@
1
+ """TraceProcessor that attaches Zambo receipt URLs to agent trace spans.
2
+
3
+ Register it once and every Zambo-backed tool call in the trace carries its
4
+ verifiable receipt URL next to the span:
5
+
6
+ from agents.tracing import get_trace_provider # via agents.tracing.setup
7
+ from zambo_openai_agents import ZamboReceiptProcessor
8
+
9
+ processor = ZamboReceiptProcessor()
10
+ get_trace_provider().register_processor(processor)
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import threading
16
+ from typing import Any, Callable
17
+
18
+ from agents.tracing.processors import TracingProcessor
19
+
20
+ from .tools import lookup_receipt
21
+
22
+
23
+ class ZamboReceiptProcessor(TracingProcessor):
24
+ """Maps finished function spans to the Zambo receipt each call minted.
25
+
26
+ Only spans produced by tools built with zambo_openai_agents.zambo_tool
27
+ (or zambo_tools) resolve to a receipt URL; every other span type is
28
+ ignored. All methods are thread-safe and never raise into the agent run.
29
+ """
30
+
31
+ def __init__(self, on_receipt: Callable[[str, str, str], Any] | None = None):
32
+ """
33
+ Args:
34
+ on_receipt: Optional callback invoked as
35
+ on_receipt(span_id, tool_name, receipt_url) whenever a Zambo
36
+ tool span resolves to a receipt.
37
+ """
38
+ self._on_receipt = on_receipt
39
+ self._receipts: dict[str, str] = {}
40
+ self._lock = threading.Lock()
41
+
42
+ @property
43
+ def receipts(self) -> dict[str, str]:
44
+ """span_id -> receipt URL for every resolved Zambo tool span."""
45
+ with self._lock:
46
+ return dict(self._receipts)
47
+
48
+ def receipt_for_span(self, span_id: str) -> str | None:
49
+ with self._lock:
50
+ return self._receipts.get(span_id)
51
+
52
+ # -- TracingProcessor interface -------------------------------------
53
+ def on_trace_start(self, trace: Any) -> None:
54
+ return None
55
+
56
+ def on_trace_end(self, trace: Any) -> None:
57
+ return None
58
+
59
+ def on_span_start(self, span: Any) -> None:
60
+ return None
61
+
62
+ def on_span_end(self, span: Any) -> None:
63
+ try:
64
+ span_data = getattr(span, "span_data", None)
65
+ if span_data is None or getattr(span_data, "type", None) != "function":
66
+ return
67
+ tool_name = getattr(span_data, "name", "") or ""
68
+ arguments_json = getattr(span_data, "input", "") or ""
69
+ receipt_url = lookup_receipt(tool_name, arguments_json)
70
+ if not receipt_url:
71
+ return
72
+ span_id = getattr(span, "span_id", "") or ""
73
+ with self._lock:
74
+ self._receipts[span_id] = receipt_url
75
+ if self._on_receipt is not None:
76
+ self._on_receipt(span_id, tool_name, receipt_url)
77
+ except Exception:
78
+ # Tracing must never break the agent run.
79
+ return None
80
+
81
+ def shutdown(self) -> None:
82
+ return None
83
+
84
+ def force_flush(self) -> None:
85
+ return None
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.4
2
+ Name: zambo-openai-agents
3
+ Version: 0.1.0
4
+ Summary: Zambo's 100+ tools as OpenAI Agents SDK tools. Every call mints a verifiable AER-1 execution receipt.
5
+ Author-email: Zambo <brennanzambo@zambo.dev>
6
+ License: MIT
7
+ Project-URL: Homepage, https://zambo.dev
8
+ Project-URL: Documentation, https://zambo.dev/aer-1/
9
+ Project-URL: Repository, https://zambo.dev
10
+ Keywords: openai,agents,ai-agents,zambo,mcp,receipts,verification,tracing
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: openai-agents>=0.20
23
+ Dynamic: license-file
24
+
25
+ # zambo-openai-agents
26
+
27
+ Give your OpenAI Agents SDK agent Zambo's 100+ live tools. Every tool call is executed by Zambo and mints a **verifiable AER-1 receipt**: a public URL carrying the tool, its arguments, the observed result, a SHA-256 fingerprint, and machine-readable JSON-LD.
28
+
29
+ ```python
30
+ from agents import Agent, Runner
31
+ from zambo_openai_agents import zambo_tools
32
+
33
+ agent = Agent(name="assistant", tools=zambo_tools(["live_price", "prompt_shield"]))
34
+ result = await Runner.run(agent, "What is the live BTC price?")
35
+ ```
36
+
37
+ No account. No API key. Free tier: 20 calls per tool per day.
38
+
39
+ ## What the receipt actually proves
40
+
41
+ Each receipt page (for example `https://zambo.dev/run/<id>`) is Zambo's tamper-evident record that **Zambo executed the tool call itself**: the tool name, the exact arguments your agent sent, the observed result, a timestamp, and a SHA-256 fingerprint of the record, published as JSON-LD. Anyone can re-verify it with no account.
42
+
43
+ The included `ZamboReceiptProcessor` (a standard `TracingProcessor`) attaches each minted receipt URL to its trace span, so the trace shows proof next to every call:
44
+
45
+ ```python
46
+ from agents.tracing.setup import get_trace_provider
47
+ from zambo_openai_agents import ZamboReceiptProcessor
48
+
49
+ processor = ZamboReceiptProcessor()
50
+ get_trace_provider().register_processor(processor)
51
+ # after the run: processor.receipts -> {span_id: receipt_url}
52
+ ```
53
+
54
+ ## Install
55
+
56
+ ```bash
57
+ pip install zambo-openai-agents
58
+ ```
59
+
60
+ ## One tool, custom schema
61
+
62
+ ```python
63
+ from zambo_openai_agents import zambo_tool
64
+
65
+ price_tool = zambo_tool(
66
+ "live_price",
67
+ params_json_schema={
68
+ "type": "object",
69
+ "properties": {"symbol": {"type": "string"}},
70
+ "required": ["symbol"],
71
+ },
72
+ )
73
+ ```
74
+
75
+ Browse the full catalog any time with `zambo_openai_agents.list_tools()`, or pick tools by use case through Zambo's `capability_search` tool.
76
+
77
+ ## Notes
78
+
79
+ - Zambo calls need no key and no signup. Heavy tracing (dozens of tool calls per run) will reach the free daily limit; the tool raises a clear error and the agent run continues with the other tools.
80
+ - The processor never breaks your run: span handling is fully exception-guarded, and it ignores non-Zambo spans.
81
+ - Receipts are public by design. Do not pass secrets as tool arguments.
82
+
83
+ ## Links
84
+
85
+ - Zambo: https://zambo.dev
86
+ - AER-1 receipt spec: https://zambo.dev/aer-1/
87
+ - OpenAI Agents SDK tracing: https://openai.github.io/openai-agents-python/tracing/
88
+
89
+ MIT License.
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/zambo_openai_agents/__init__.py
5
+ src/zambo_openai_agents/client.py
6
+ src/zambo_openai_agents/tools.py
7
+ src/zambo_openai_agents/tracing.py
8
+ src/zambo_openai_agents.egg-info/PKG-INFO
9
+ src/zambo_openai_agents.egg-info/SOURCES.txt
10
+ src/zambo_openai_agents.egg-info/dependency_links.txt
11
+ src/zambo_openai_agents.egg-info/requires.txt
12
+ src/zambo_openai_agents.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ openai-agents>=0.20
@@ -0,0 +1 @@
1
+ zambo_openai_agents