Skip to content

fix(sdk): call real resource methods in agent-framework adapters - #411

Open
EfeDurmaz16 wants to merge 2 commits into
mainfrom
fix/sardis-js-resource-call-signatures
Open

fix(sdk): call real resource methods in agent-framework adapters#411
EfeDurmaz16 wants to merge 2 commits into
mainfrom
fix/sardis-js-resource-call-signatures

Conversation

@EfeDurmaz16

Copy link
Copy Markdown
Owner

The langchain, ai-sdk, and mastra adapters used as unknown as { ... } casts to invoke resource methods that had the wrong signature or did not exist. The casts suppressed type-checking, so the calls compiled but would fail at runtime:

  • wallets.getBalance called with an object 2nd arg — real: getBalance(walletId, chain, token).
  • policies.check passed {merchant, token} — real input: {agent_id, amount, merchant_id, merchant_category, ...}.
  • policies.applyFromNaturalLanguage does not exist — real: apply(natural_language, agent_id).
  • holds.capture passed {amount} — real: capture(holdId, amount?).
  • transactions.list does not exist — recent activity lives in ledger.listEntries({ wallet_id, limit }).

Removing the casts lets tsc validate the calls. Adds a regression test pinning the argument shapes. tsc clean; 24 tests pass (5 new).

Surfaced by the ponytail×deslop minimization audit (deslop lens caught the casts; these were latent runtime bugs, not style).

The langchain, ai-sdk, and mastra adapters used `as unknown as { ... }`
casts to invoke resource methods that had the wrong signature or did not
exist. The casts suppressed type-checking, so the calls compiled but would
fail at runtime:

- wallets.getBalance was called with an object as the 2nd arg; the real
  signature is getBalance(walletId, chain, token).
- policies.check was passed {merchant, token}; the real input is
  {agent_id, amount, merchant_id, merchant_category, ...}.
- policies.applyFromNaturalLanguage does not exist; the real method is
  apply(natural_language, agent_id).
- holds.capture was passed an {amount} object; the real signature is
  capture(holdId, amount?).
- transactions.list does not exist; recent activity lives in
  ledger.listEntries({ wallet_id, limit }).

Remove the casts and call the real methods so tsc validates them. Add a
regression test pinning the argument shapes. tsc clean; 24 tests pass.
@vercel

vercel Bot commented Jun 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sardis Ready Ready Preview, Comment Jun 14, 2026 1:09pm

Request Review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5f916009eb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

check: (body: Record<string, unknown>) => Promise<unknown>;
}).check({
client.policies.check({
agent_id: opts.agentId ?? '',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Require an agent ID before checking policy

When callers use the documented AI SDK setup with only apiKey and walletId, opts.agentId is absent, but this now fabricates agent_id: '' for policies.check even though the SDK resource requires a real agent_id. That makes the default sardis_check_policy path send an invalid policy scope instead of failing closed or telling the user to configure an agent, so policy checks can fail or be evaluated against the wrong/nonexistent agent.

Useful? React with 👍 / 👎.

Comment on lines +135 to 139
client.policies.check({
agent_id: opts.agentId ?? '',
amount: parsed.amount,
...(parsed.token ? { token: parsed.token } : {}),
merchant: parsed.to,
...(parsed.to ? { merchant_id: parsed.to } : {}),
}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Forward the requested token to policy checks

CheckPolicySchema still accepts a token, but the new typed payload drops it and only sends agent_id, amount, and merchant_id. For a non-default-token payment or a policy that restricts currencies, policies.check never receives the requested currency even though the resource supports currency, so the agent can get a policy decision for the wrong/default currency before paying with the requested token. Map parsed.token to currency or remove the input field.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant