@governmyai/sdk-anthropic
v0.1.1
Published
GovernMy.ai adapter for Anthropic's SDK tool-use loop — wraps Claude messages.create() with regulatory obligation checks
Maintainers
Readme
@governmyai/sdk-anthropic
GovernMy.ai adapter for Anthropic's SDK tool-use loop. Wraps anthropic.messages.create() so that gated tool calls are checked against the regulatory rules engine before being surfaced to your code.
Companion package to @governmyai/sdk.
Install
npm install @anthropic-ai/sdk @governmyai/sdk @governmyai/sdk-anthropicUsage
const { Anthropic } = require('@anthropic-ai/sdk');
const { GovernMy } = require('@governmyai/sdk');
const { wrapAnthropic } = require('@governmyai/sdk-anthropic');
const anthropic = wrapAnthropic(
new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }),
{
governmy: new GovernMy({ apiKey: process.env.GOVERNMY_API_KEY }),
context: {
riskTier: 'high',
role: 'provider',
annexIiiCategory: ['employment'],
lifecyclePhase: 'deployment',
systemId: 'hiring-ai-v2',
},
mode: 'warn', // 'warn' (default), 'block', 'log-only'
gatedToolNames: ['submit_decision', 'send_offer', 'reject_candidate'],
onObligations: async ({ toolName, obligations, blocked }) => {
console.log(`[${toolName}] ${obligations.length} obligations${blocked ? ' (blocked)' : ''}`);
},
}
);
// Use the Anthropic SDK normally. When the model returns a tool_use block
// matching gatedToolNames, the adapter runs the rules engine check first.
const response = await anthropic.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
tools: [
{ name: 'submit_decision', description: 'Submit hiring decision', input_schema: {...} },
],
messages: [{ role: 'user', content: '...' }],
});
// Inspect regulatory results attached to the response
if (response._governmy) {
for (const [toolId, info] of Object.entries(response._governmy)) {
if (info.humanReviewRequired) {
// Route to human review queue before executing the tool call
}
}
}Mode behavior
| Mode | cannotBeAutoSatisfied match | Any humanReview.required match | Other matches |
|---|---|---|---|
| warn (default) | throws HumanReviewRequired | returns with obligations attached | returns |
| block | throws HumanReviewRequired | throws HumanReviewRequired | returns |
| log-only | throws HumanReviewRequired | returns with obligations attached | returns |
cannotBeAutoSatisfied obligations (EU AI Act Art. 14 et al.) always throw — this is structural and cannot be configured off.
When to use which mode
warn: your code has a review queue or escalation path for flagged tool calls. Default.block: strict enforcement — any regulated tool call without prior review aborts.log-only: you want the event trail written (for audit) without any control-flow impact.
Catching HumanReviewRequired
const { HumanReviewRequired } = require('@governmyai/sdk');
try {
const response = await anthropic.messages.create({ ... });
// use response
} catch (err) {
if (err instanceof HumanReviewRequired) {
// err.obligations, err.unoverridable, err.context
enqueueForReview(err);
return;
}
throw err;
}Notes
- Pass-through for non-tool-use flows. Messages that don't return a
tool_useblock run unchanged. - The adapter is a thin Proxy — it preserves the rest of the Anthropic SDK surface (e.g.
client.models.list()). - Per-tool context layering: the adapter appends
toolNametocontext.useCasesfor each gated call, so rules engine matching can be tool-specific.
License
MIT
