Migrating from the HumanLayer SDK
Last verified 2026-10-11.
HumanLayer is a trademark of its respective owner. Vulnify is not affiliated with, endorsed by, or sponsored by HumanLayer.
Statements about HumanLayer come from HumanLayer’s public repository, README, and package pages, linked in Sources. If something here is out of date, tell us at Support and we will fix it.
What HumanLayer offered
Section titled “What HumanLayer offered”HumanLayer described itself as “an API and SDK that enables AI Agents to contact humans for help, feedback, and approvals” [S4]. It shipped a Python package, humanlayer, and a TypeScript package, @humanlayer/sdk [S4].
Its README listed two core functions [S4]:
@hl.require_approval(), a decorator that “blocks specific function calls until a human has been consulted - upon denial, feedback will be passed to the LLM”.hl.human_as_tool(), which “allows for contacting a human for answers, advice, or feedback”.
The README also listed contact across “Slack, Email, Discord, and more” and “Granular Routing” of approvals to teams or individuals. Its roadmap table listed “Slack Approvals | ⚙️ Beta”, “Email Approvals | ⚙️ Beta”, and “Discord Approvals | 🗓️ Planned” [S4].
What changed
Section titled “What changed”- On 2025-09-29, pull request #646, “Clean up humanlayer sdk stuff, this is codelayer now”, removed the SDKs from the
humanlayer/humanlayerrepository [S1]. - The repository’s SDK document now says it “covers the HumanLayer SDK which is being superseded by CodeLayer” and that “The humanlayer sdks were removed in #646” [S2]. The repository README says “the code here is pretty much all deprecated” [S3].
- The last releases are
humanlayer0.7.9 on PyPI and@humanlayer/sdk0.7.9 on npm, both from 2025-06-03 [S4][S5]. Both packages are still listed. The npm package is not marked deprecated [S5]. - HumanLayer’s site now describes “a multiplayer coding agent IDE and cloud” [S6].
We have not verified whether HumanLayer’s hosted API still serves the 0.7.x SDK. If your agents still run on it, check with HumanLayer before you change anything.
How the concepts map
Section titled “How the concepts map”The two products work differently. As described in its README, require_approval asks a person on every call to a decorated function [S4]. Vulnify decides each call first: ALLOW runs it, REVIEW waits for a person, and BLOCK stops it. Which calls need a person is set by your policies and the risk engine. See Decisions.
| HumanLayer SDK 0.7.x, per its README [S4] | Vulnify | Notes |
|---|---|---|
HumanLayer() client |
Vulnify(api_key=...) (Python) or new Vulnify({ apiKey }) (Node.js) |
Vulnify reads the key you pass. Register the agent and resource names in the app. |
@hl.require_approval() on a function |
vulnify.guard(fn, wait=..., **action) (Python) or vulnify.guard(action, fn, wait) (Node.js) |
You describe the action: agent, action, resource, destination, recordsAffected. With wait, the function runs only after approval. |
| Every decorated call goes to a person | A policy with decision: REVIEW |
Calls that match the policy wait for a person. Others are allowed or blocked by policy or by the risk engine. See Policies. |
| Approval in Slack or by email | Approval in the Vulnify app, or with Approve and Deny in Slack | See Reviews and Slack. There is no email approval. |
| Routing to teams or individuals | approverRoles on the policy: OWNER, ADMIN, MEMBER |
By role, not by named person. |
| Denial feedback passed to the LLM | VulnifyBlockedError with the decision’s reasons. A denied review adds Review denied |
The agent receives the reasons, not a reviewer’s free-text reply. |
hl.human_as_tool() |
No equivalent | See What Vulnify does not do. |
| Approval from an MCP client | decide_action, then get_decision with waitMs |
On the Vulnify MCP server. A person approves in Vulnify or Slack. |
Code before and after
Section titled “Code before and after”Before: HumanLayer
Section titled “Before: HumanLayer”This is the example from the HumanLayer README, quoted as published [S4]:
from humanlayer import HumanLayerhl = HumanLayer()
@hl.require_approval()def send_email(to: str, subject: str, body: str): """Send an email to the customer""" ...
# made up function, use whatever# tool-calling framework you preferrun_llm_task( prompt="""Send an email welcoming the customer to the platform and encouraging them to invite a team member.""", tools=[send_email], llm="gpt-4o")Source: README of humanlayer 0.7.9 on PyPI.
Code © HumanLayer contributors, licensed under the Apache License 2.0.
After: Vulnify
Section titled “After: Vulnify”The same tool, guarded by Vulnify. run_llm_task stays whatever framework you use. On REVIEW, the call waits up to 5 minutes for a person to approve, then sends only if approved. On BLOCK, or a denial, the tool returns the reason to the model.
pip install vulnifyimport os
from vulnify import Vulnify, VulnifyBlockedError
vulnify = Vulnify(api_key=os.environ["VULNIFY_API_KEY"])
COMPANY_DOMAIN = "@yourcompany.com"
def send_email(to: str, subject: str, body: str): """Send an email to the customer""" ...
def send_email_tool(to: str, subject: str, body: str) -> str: """The tool you give the model. Vulnify decides before the email is sent.""" try: vulnify.guard( lambda: send_email(to, subject, body), wait={"timeout": 300, "poll": 2}, agent="OnboardingBot", action="SEND_EMAIL", resource="Customer Contacts", destination="INTERNAL" if to.lower().endswith(COMPANY_DOMAIN) else "EXTERNAL_EMAIL", records_affected=1, ) return f"Email sent to {to}." except VulnifyBlockedError as blocked: return f"Email not sent. {blocked}"Then add a policy so outbound email waits for a person. The format is on Policy files:
apiVersion: vulnify.io/v1kind: Policymetadata: name: review-external-customer-emailspec: description: A person approves agent email to addresses outside the company enabled: true action: ANY resource: ANY condition: action: SEND_EMAIL destination: EXTERNAL decision: REVIEW mode: ENFORCETo ask on every SEND_EMAIL call, drop destination from the condition. Every SEND_EMAIL then waits for a person.
On Node.js the same pattern is vulnify.guard(action, fn, { timeoutMs: 300_000 }). Adapters for LangChain, the OpenAI Agents SDK, the Vercel AI SDK, MCP servers, CrewAI, and LangGraph are on Framework adapters. A longer walkthrough is Stop an AI agent from exporting customer data.
What Vulnify does not do
Section titled “What Vulnify does not do”If you rely on any of these, plan for it before you migrate.
- No human-as-a-tool. An agent cannot ask a person a free-form question and get a text answer back. Vulnify only decides whether an action runs.
- No email, Discord, or SMS approvals. Reviews are answered in the Vulnify app or in Slack.
- No free-text feedback to the model. A denial returns the decision’s reasons and
Review denied. There are no custom response or reject options. - No routing to named people. Approvers are chosen by role on the policy.
- No local CLI approval. The
vulnifyCLI validates, applies, and tests policies. It does not approve reviews. - No webhook when a review is resolved. Your code polls
GET /v1/events/{id}, or useswaitin the SDK. See Reviews. - Setup per action. Agents and resources are registered in the app, and each guarded call describes its action. A bare decorator with no arguments is not enough.
- No ControlFlow or Griptape adapters. The adapters cover the frameworks listed on Framework adapters.
Next steps
Section titled “Next steps”- Run one guarded action end to end in the Quickstart.
- Create an API key and a policy in the Vulnify app.
Sources
Section titled “Sources”All accessed 2026-10-11.
- [S1] humanlayer/humanlayer pull request #646, “Clean up humanlayer sdk stuff, this is codelayer now”, merged 2025-09-29 22:04 UTC: https://github.com/humanlayer/humanlayer/pull/646
- [S2]
humanlayer.mdin humanlayer/humanlayer (main): https://github.com/humanlayer/humanlayer/blob/main/humanlayer.md - [S3] humanlayer/humanlayer repository README: https://github.com/humanlayer/humanlayer
- [S4]
humanlayeron PyPI, version 0.7.9 (uploaded 2025-06-03), project description and README: https://pypi.org/project/humanlayer/0.7.9/ - [S5]
@humanlayer/sdkon npm, version 0.7.9 (published 2025-06-03): https://www.npmjs.com/package/@humanlayer/sdk (registry record: https://registry.npmjs.org/@humanlayer%2Fsdk) - [S6] HumanLayer homepage: https://www.humanlayer.dev/
HumanLayer is a trademark of its respective owner. Vulnify is not affiliated with, endorsed by, or sponsored by HumanLayer.

