Skip to content

feat: add BrainChain action provider - #1617

Open
brainchaindev wants to merge 4 commits into
coinbase:mainfrom
brainchaindev:brainchain-action-provider
Open

brainchaindev wants to merge 4 commits into
coinbase:mainfrom
brainchaindev:brainchain-action-provider

Conversation

@brainchaindev

@brainchaindev brainchaindev commented Nov 2, 2026 •

Copy link
Copy Markdown

Description

Adds a BrainChain action provider, so an AgentKit agent can hand a self-contained task to a frontier model and pay only for work that is accepted.

BrainChain is a task network where Jev, a disclosed decision model from TypeSafe, hires one of Claude, GPT, Gemini, Grok or DeepSeek for a brief, grades the result against quality levels the poster writes, and pays the model only if the work passes. The agent pays 1 USDC on Base over x402 from its own wallet. Work that is not accepted, or not delivered within 24 hours, is refunded to that wallet.

Actions:

  • post_task: pays for a task (title, brief, two or three levels) and returns an order id.
  • get_task: reads the order, waiting up to waitSeconds (default 45) for it to finish, and returns the result text once it is accepted.

Design notes:

  • Payment uses the same x402 path as the x402 provider (registerExactEvmScheme with the wallet provider as signer). No new dependencies.
  • A payment policy accepts only BrainChain's desk, in USDC, on the wallet's network, within maxPriceUsdc. A budget (budgetUsdc, default 10 USDC) is reserved before signing, so parallel posts cannot overshoot it.
  • If the payment was signed but the desk's reply never arrived, the provider returns the order id (the desk names orders after the hash of the signed payment) with possiblyCharged, so the agent reads the order instead of paying twice.
  • get_task waits for progress itself. In testing, a LangChain agent called a non-waiting version in a tight loop and hit its recursion limit, since a model cannot pause between calls.
  • Results are fetched only from the desk's own host; any other link is returned as a link.
  • Supported on base-mainnet and base-sepolia (BrainChain testnet, test USDC).

Tests

Unit tests: src/action-providers/brainchain/brainchainActionProvider.test.ts, 14 tests (payment policy, budget, possiblyCharged, refusals, network support, order states, waiting, result fetching). pnpm test in typescript/agentkit: 63 suites, 918 tests pass. ESLint and Prettier are clean.

End to end on Base Sepolia, with a ViemWalletProvider holding test USDC and the BrainChain testnet desk:

Chatbot: LangChain agent built like typescript/examples/langchain-cdp-chatbot
  (getLangChainTools + createAgent), ViemWalletProvider instead of CDP
Network: base-sepolia
Model: anthropic/claude-sonnet-5.5 via OpenRouter
Setup: brainchainActionProvider({ budgetUsdc: 2 })

Prompt: Hire a model through BrainChain to write a regular expression that matches
US ZIP codes (5 digits, or 5 digits, a hyphen and 4 digits) and nothing else, with
three strings it accepts and three it rejects. Wait for the result and show it to me.

[model_request] calls: BrainChainActionProvider_post_task(...)
[tools] {"order":"0xaf6da755…e53b","price":"1 USDC","statusUrl":"https://brain.testnet.usebrainchain.com/x402/tasks/0xaf6da755…e53b",...}
[model_request] calls: BrainChainActionProvider_get_task({"order":"0xaf6da755…e53b","waitSeconds":120})
[tools] {"state":"posted","paymentTx":"0x2912de6f…4884","taskId":"63","task":{"status":"graded","accepted":true},"resultText":"...","done":true,...}
[model_request] The task was accepted. Jev graded it as accepted, and the 1 USDC payment went through.
Regex: ^[0-9]{5}(-[0-9]{4})?$
Accepts: 12345, 12345-6789, 00000
Rejects: 1234, 12345-, 12345-678A

A direct AgentKit.getActions() run on the same network (task 61, payment 0x6eb27f5d…d7d1) returned an accepted Celsius to Fahrenheit table with all 15 rows correct.

Unrelated to this provider: during the run, AgentKit's analytics call in actionDecorator.ts hit #1531 (a rejected analytics request ends the Node process on the first action). The harness ignored unhandled rejections to finish the run; #1537 fixes it.

@github-actions github-actions Bot added documentation Improvements or additions to documentation action provider New action provider typescript labels Nov 2, 2026
@cb-heimdall

cb-heimdall commented Nov 2, 2026 •

Copy link
Copy Markdown

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
1 if authored by an app that is not allowlisted and lacks verified human attribution 0
Sum 1

… the grade

The status guidance now keeps waiting on disputed, ruled and appealed tasks instead of reporting a rejected grade as final, with a test for each status.
@brainchaindev

Copy link
Copy Markdown
Author

Pushed 76080e3, a signed commit. get_task now keeps reporting a task as in progress while a dispute, a ruling or an appeal can still change its grade. Before, a rejected grade that the model had disputed read as final and refunded, even though the ruling could still pay. It adds one test, the provider's 16 tests pass, and prettier and eslint are clean. Ready for review whenever someone has a moment.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action provider New action provider documentation Improvements or additions to documentation typescript

Development

Successfully merging this pull request may close these issues.

2 participants