Skip to content

About

CodeRifts for the OpenAI Agents SDK — a tool-input guardrail that decides, before a tool runs, whether the call is a governed contract mutation, including for tools CodeRifts never wrapped.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

6 Commits

Folders and files

Repository files navigation

@coderifts/openai-agents

CodeRifts contract governance for the OpenAI Agents SDK.

A tool-input guardrail decides, before a tool runs, whether the call is a governed contract mutation. It gates a tool even when CodeRifts never wrapped that tool's implementation — so you can govern third-party or hand-written tools you do not own.

Install

npm install @coderifts/openai-agents @openai/agents @coderifts/sdk

@openai/agents is a peer dependency (>=0.17.0); @coderifts/sdk is a dependency. It is also a devDependency so npm install && npm test resolves the peer without a second manual install. Consumers still supply the peer themselves.

CI (.github/workflows/ci.yml) runs that same clean install on ubuntu / Node 20.

Use

import { Agent, run, tool } from '@openai/agents';
import { CodeRifts } from '@coderifts/sdk';
import { withCodeRiftsGuardrail } from '@coderifts/openai-agents';

const client = new CodeRifts({ apiKey: process.env.CODERIFTS_API_KEY });
const { guardrail, needsApproval } = withCodeRiftsGuardrail({
  client,
  operation: 'merge',
  readPrior: (p) => fs.readFileSync(p, 'utf8'),   // the `before` side
});

const writeFile = tool({
  name: 'write_file',
  description: 'Write a file.',
  parameters: z.object({ path: z.string(), content: z.string() }),
  inputGuardrails: [guardrail],
  needsApproval,                                   // REQUEST_APPROVAL suspends for a human
  execute: async ({ path, content }) => { /* ... */ },
});

attachGuardrailToEach(tools, guardrail) attaches it across a list you already have.

Verdict mapping

execution_action Behaviour
CONTINUE, CONTINUE_WITH_MONITORING allow() — the tool runs
REQUEST_APPROVAL guardrail allows, needsApproval returns true → the SDK emits a RunToolApprovalItem and suspends for a human
STOP / BLOCK rejectContent() with the WHY + remediation
anything unrecognised rejectContent(), message names it as not permission (fail closed)
unreadable arguments / missing path on a mutator rejectContent() fail-closed
non-contract path, read-only tool allow() with no API call

rejectContent, not throwException: a governance deny must teach. throwException aborts the whole run with a tripwire and the model learns nothing.

One preflight per tool call. The guardrail and the needsApproval resolver share a memo keyed by the SDK's callId, so enabling approvals does not double your API spend.

Coverage

With the CodeRifts guardrail attached to a tool, that tool is governed even if CodeRifts never wrapped its implementation — so an agent can adopt governance for third-party or hand-written tools it does not own, and a blocked contract change returns the reason and remediation to the model rather than failing opaquely. The claim changes from per-table to per-tool-with-guardrail — not to per-agent: tool input guardrails are attached per tool, there is no agent-wide form, and we demonstrated that the same ungoverned tool still mutates an OpenAPI spec when the guardrail is not attached to it. Handoff sub-agents, hosted tools, and direct client calls outside run() remain ungated. Enforcement independent of the developer's diligence still lives downstream, at the contract-gate on the pull request and the deploy-gate in CI.

What this does not cover

  1. Tools without the guardrail attached. There is no agent-wide form — 'toolInputGuardrails' in agent is false, and the Agent's inputGuardrails is a different type that validates the agent's input, not tool calls. attachGuardrailToEach covers exactly the list you pass it.
  2. Handoff sub-agents. A sub-agent's tools are separate tool objects and do not inherit it.
  3. Hosted / built-in tools (codeInterpreterTool, applyPatchTool). Built by SDK factories; you would have to interpose your own wrapper to add inputGuardrails.
  4. Direct client calls outside run(). They never reach the runner, so no guardrail fires.

The artifact is not the contract. Items 1–4 are tools the guardrail never sees. This one is a change it sees and correctly lets through. The guardrail keys off a tool call that touches a contract file. An implementation edit under an unchanged spec changes the served behaviour and gives the guardrail nothing to weigh: no contract artifact moved, so there is nothing to preflight, and an allowed call means only that the artifact did not change. A handler that starts returning null for a field the schema still marks required, a response that quietly changes shape, an authorization check deleted behind a byte-identical OpenAPI file — none of those are contract changes as far as this package is concerned. Governing the artifact is not the same as governing the behaviour it describes, and this package does not diff served behaviour.

License

MIT

About

CodeRifts for the OpenAI Agents SDK — a tool-input guardrail that decides, before a tool runs, whether the call is a governed contract mutation, including for tools CodeRifts never wrapped.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages