crewai-openterms
CrewAI adapter for OpenTerms — wraps any callable so each invocation emits a signed ORS v0.1 receipt before the tool runs.
Depends on openterms-py>=0.1.0 for canonicalization, signing, and the HTTP client. One signing path is shared with langchain-openterms.
Install
pip install crewai-openterms
CrewAI itself is not a hard runtime dependency. CrewAI's BaseTool API has shifted repeatedly across the 0.x line (constructor signatures, the _run-vs-run hook, pydantic model versions), so this adapter wraps a plain callable — the function-tool pattern, which is stable across CrewAI versions. Plug the wrapped function into CrewAI however your project already does (Tool(name=..., func=...), the @tool decorator, or as the body of a BaseTool._run).
Quickstart
from openterms import IngestClient, generate_keypair
from openterms_crewai import OpenTermsToolConfig, wrap_tool
sk, _ = generate_keypair()
client = IngestClient(
base_url="http://localhost:3000",
workspace_id="00000000-0000-4000-8000-0000000000aa",
key_id="my-key",
private_key=sk.private_bytes_raw(),
agent_id="crew-agent",
)
config = OpenTermsToolConfig(
client=client,
agent_id="crew-agent",
terms_url="https://example.com/terms",
terms_hash="a" * 64,
emit_post_action=True,
)
def search(query: str) -> str:
"""Pretend to look something up."""
return f"results for: {query}"
wrapped_search = wrap_tool(search, config=config, tool_name="search")
# Plug into CrewAI:
# from crewai.tools import Tool
# tool = Tool(name="search", func=wrapped_search, description="...")
Decorator form:
from openterms_crewai import openterms_tool
@openterms_tool(config, tool_name="search")
def search(query: str) -> str:
return f"results for: {query}"
See examples/quickstart.py for a runnable copy.
Configuration
OpenTermsToolConfig carries:
client— theopenterms.IngestClient.agent_id— placed on every receipt.terms_url,terms_hash— terms binding for the receipts.emit_post_action— whenTrue, emit a second receipt after the tool returns withpost_state_hash= SHA-256 of the stringified result. DefaultFalse.strict— whenTrue, re-raiseopenterms.IngestError; defaultFalse(failures logged, tool still runs).
What this adapter does
- Wraps a callable. Each invocation emits a signed ORS receipt with
action_type="tool_call"andaction_context = {tool_id, args}. Argument introspection is best-effort (inspect.signaturefirst, positional fallback for builtins / C callables). - Optionally emits a post-action receipt sharing the same
receipt_idas the pre-action receipt. - Logs and continues on ingest failures by default. The tool's return value is always passed through.
What this adapter does NOT do
- It does not depend on CrewAI at runtime. Tests run without
crewaiinstalled. The wrapper is callable-based. - It does not run an ingest service. You must point
IngestClientat a running OpenTerms API. - It does not handle auth, host a JWKS, or manage keys. See
opentermsfor the underlying scope. - It does not buffer or retry. A failed emission is logged once (or re-raised if
strict=True). - It does not subclass CrewAI's
BaseTool. That subclass tends to break across CrewAI minor versions. If you need aBaseToolsubclass, build one in your project that calls into awrap_tool-produced callable from inside_run.
Repository
Source and issue tracker: jstibal/openterms.
License
Apache-2.0.
Release files for crewai-openterms 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| crewai_openterms-1.0.1.tar.gz | 6.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| crewai_openterms-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 12.6 kB
Release files / crewai_openterms-1.0.1.tar.gz
| Download URL | crewai_openterms-1.0.1.tar.gz |
|---|---|
| Size | 6.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ee83045c0874796cb5b52a8a08cd2f124a53f2fc6bb37491b86fa48c0c4ca9b9
|
|
BLAKE2b-256 checksum How to use checksums |
deb98f27a83796e8820d77d0c2f5c0124225366e8dd0bc234ef0b4387d962958
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / crewai_openterms-1.0.1-py3-none-any.whl
| Download URL | crewai_openterms-1.0.1-py3-none-any.whl |
|---|---|
| Size | 5.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ce7dd462f534d6b432c2373a00ec0f992e58d299af8cbd0d8286c2ea59c870b
|
|
BLAKE2b-256 checksum How to use checksums |
68027e68b23fe1b0f236048c765fad81117954e8f87574f217235c8883f60a1b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|