Add Bindu A2A integration example (DID-identified agent + optional x402 micropayments)#2
Add Bindu A2A integration example (DID-identified agent + optional x402 micropayments)#2raahulrahl wants to merge 2 commits into
Conversation
Run ContractGuard as a discoverable, DID-identified A2A microservice without touching core analyzer code. Peers send a `text` or base64 `file` part (PDF/DOCX/TXT/MD/RTF) and get back the existing AnalysisResult JSON. Optional pay-per-scan via x402 (USDC on Base) — uncomment one block in agent.py. - examples/bindu/agent.py: handler wrapping analyze_contract() - examples/bindu/README.md: what/why, setup, curl examples, response shape - examples/bindu/.env.example: minimal config (OPENROUTER_API_KEY) - README.md: new Integrations section linking the example Purely additive: no changes to contractguard/, no new required deps, CLI and Gradio UI unaffected.
…resp
End-to-end testing against bindu 2026.21.1 revealed three issues in the
first version:
1. Handler walked `parts[]`, but Bindu's manifest worker normalises A2A
messages to OpenAI-style `{role, content}` before invoking the handler
(text parts joined with " "). Result: the handler never received any
contract text and always returned `no_contract`. Rewritten to read
`m["content"]` directly — drops ~80 lines of dead code.
2. README's curl examples used `"id": "1"` for the JSON-RPC envelope.
Bindu's pydantic validator rejects non-UUID ids with a 400. Switched
all examples to proper zero-UUIDs.
3. File-upload path didn't actually work. Bindu's `FileInterceptor` reads
flat `{kind, mimeType, data}` while the A2A `FilePart` schema (and the
JSON-RPC validator) expect nested `{kind, file: {bytes, mimeType}}` —
round-trip is broken in this version. Cut the file section; users
pre-extract with `contractguard.parser.extract_text()` and send text
instead.
Also added a complete try-it-out section:
- One-shot bash script that sends `examples/sample_lease.txt`, polls
`tasks/get`, and prints the DID signature + parsed analysis JSON.
- Sample request body (annotated A2A envelope).
- Sample response — real `tasks/get` output captured by running this
agent against the sample lease (lease type, F grade, 15/100, with
trimmed red_flags / warnings / good_clauses / missing_protections).
Verified end-to-end: server starts, agent card resolves with the right
DID, `message/send` is accepted, handler runs, real OpenRouter call
succeeds, result artifact carries a valid Ed25519 signature.
|
End-to-end tested against
Also added a complete try-it-out section with a copy-paste bash script, a sample request body, and a sample response — the response was captured by running this agent against Verified working end-to-end:
Apologies for shipping the first revision without doing this loop. Happy to keep iterating. |
|
Any update on this? |
|
Appreciate the care that went into this — the handler and the README are both well written. I want to be upfront about where I land on it, though: wrapping the analyzer behind one specific agent framework, and putting a per-scan crypto-payment path (x402 / USDC) into the project's own README, points ContractGuard in a direction I'd rather not take it or appear to endorse from the main repo. ContractGuard is MIT-licensed, so this integration is very welcome to live in your own repo and link back here — honestly that's the better home for it, since it can track Bindu's API without being gated on my review. I'll leave this open rather than close it outright, but I'm unlikely to merge it as-is. No hard feelings either way, and thanks for giving the project a serious look. |
Summary
Adds
examples/bindu/showing how to run ContractGuard as a discoverable, DID-identified A2A agent using Bindu. Peers callmessage/sendwith either atextpart (paste the contract) or a base64filepart (PDF / DOCX / TXT / MD / RTF) and receive the existingAnalysisResultJSON — no schema changes.The integration is purely additive: nothing under
contractguard/is modified,binduis not a required dependency, and the CLI / Python API / Gradio UI all keep working unchanged.This addresses one bullet from the existing Contributing list ("Build integrations — MCP server, VS Code extension, Slack bot, etc."): A2A is the protocol for agent-to-agent calls, so wrapping ContractGuard with
bindufy()turns it into a building block that any A2A orchestrator can chain into longer workflows.What you get when ContractGuard is bindufied
/.well-known/agent.json— agent marketplaces and orchestrators can find ContractGuard and know what it does.did:bindu:…) — each analysis is attributable to a cryptographically-verifiable agent. Result artifacts are signed with the agent's Ed25519 key, so a review can be presented as tamper-evidence ("ContractGuarddid:bindu:…said this at timestamp T").message/send.agent.pyto charge USDC on Base per analysis. Short path from "open-source CLI" to "monetised hosted service" without a SaaS layer.Files
examples/bindu/agent.py— handler wrappinganalyze_contract(); handles text parts (with the first short text part treated as a prompt and echoed back) and base64 file parts via the existingcontractguard.parser.extract_textpath.examples/bindu/README.md— setup, run, curl examples for both inline text and PDF upload, response shape, x402 instructions, limits.examples/bindu/.env.example— minimal config (OPENROUTER_API_KEY), with optional model / language / author overrides.README.md— new "Integrations" section linking to the example.Test plan
python -c "import ast; ast.parse(open('examples/bindu/agent.py').read())"— passesbinduinstalled{"error": "no_contract", ...}JSON for an empty input_collect_inputs()correctly decodes a base64filepart usingexamples/sample_lease.txt(returns the full 4,015-char contract and the leading prompt)analyze_contract()which already has its own coveragebindufy(config, handler)server startup — recommended manual smoke from the README's instructionsNotes
anthropic/claude-sonnet-4,en); they can be overridden withCONTRACTGUARD_MODELandCONTRACTGUARD_LANG.MAX_CONTRACT_CHARStruncation behaviour fromanalyzer.pyis unchanged — long contracts are silently truncated as today.examples/bindu/.env.exampleonly documents env vars — no real secrets.Happy to iterate on style, placement, or naming if you'd prefer it under a different path (e.g.
integrations/bindu/).