Integrations
Framework adapters for ArmorIQ
Integrations
Drop ArmorIQ into the agent framework you already use. An adapter wraps the framework's tool-calling lifecycle so plan capture, token minting, policy enforcement, and audit happen without you writing the ArmorIQ plumbing.
This page is the source of truth for integration status. Other pages link here rather than restating it.
Status
| Framework | Python | TypeScript |
|---|---|---|
| Google ADK | Live - pip install "armoriq-sdk[google-adk]" | Live - @armoriq/sdk |
| Strands | Live - pip install "armoriq-sdk[strands]" | Live - @armoriq/sdk |
| LangChain | Live - pip install "armoriq-sdk[langchain]" | Live - @armoriq/sdk |
| Langflow | Live - pip install "armoriq-sdk[langchain]" | Not applicable - Langflow is a Python application |
| CrewAI | Live, token-only - pip install "armoriq-sdk[crewai]" | Python only |
Google ADK, Strands and LangChain are live in both languages and support the full enforcement path. Langflow is Python-only by nature of the framework it extends. CrewAI ships in Python but is a narrower adapter - see the next section.
No adapter for your framework?
You do not need one. ArmorIQ works with any framework that lets you intercept a tool call before it executes, which is all of them - including the OpenAI and Anthropic SDKs directly, and any proprietary scaffold.
Build on ArmorIQSession from inside your tool wrapper -
start_plan to capture the turn's plan and mint a token, check per tool call, then
report after it runs. That is the same surface every shipped adapter wraps, so
you get identical enforcement, holds, and audit. About ten lines of glue.
Custom frameworks has worked examples for
the OpenAI Assistants run loop, Anthropic tool_use blocks, CrewAI BaseTool,
and LangChain, but note those examples drive the lower-level
capture_plan → get_intent_token → invoke loop directly, which skips
session-mode enforcement. Prefer the session surface unless you specifically
need the raw calls.
Not all "live" means the same thing
Two generations of adapter ship today, and the difference matters if you are relying on policy enforcement rather than just intent verification.
| Google ADK, Strands, LangChain | CrewAI | |
|---|---|---|
| Mints an intent token from the plan | Yes | Yes |
| Routes tool calls through the ArmorIQ proxy | Yes | Yes |
Per-user scoping (for_user(email)) | Yes | No - one identity per crew |
| Policy enforcement per tool call (allow / hold / block) | Yes | No |
| Holds and approval waiting | Yes | No |
| Live enforcement events | Strands, LangChain | No |
| Behaviour when no ArmorIQ tools are found | n/a | Runs unenforced with a log warning |
If you need per-user policy, holds, or approvals on CrewAI, drive an
ArmorIQSession from inside your tool rather than using the
adapter - and set mode to sdk or proxy, since the default local mode
cannot perform approvals. See also
Custom frameworks.
Pattern
The three full adapters share a for_user(email) entry point, but what it
returns and how you attach it differs per framework.
integration = FrameworkAdapter(armoriq_client=client) # once per process
handle = integration.for_user("alice@example.com") # once per requestconst integration = new FrameworkAdapter({ client }); // once per process
const handle = await integration.forUser('alice@example.com'); // once per requestforUser is async in TypeScript and must be awaited. The Python
equivalent is synchronous.
What you do with the handle:
| Framework | Attach with |
|---|---|
| Google ADK | bundle.install(agent), then uninstall(agent) when done |
| Strands | Agent(hooks=[handle]) in Python, Agent({ plugins: [handle] }) in TypeScript |
| LangChain | pass the returned callback handler via config={"callbacks": [handle]} |
So there is no single universal shape. Start with the Google ADK page for a full worked example, or Strands for the hold and approval event lifecycle.
Import paths
Adapters are not exported from the package root, so that the optional framework dependency stays out of every consumer's module graph.
from armoriq_sdk.integrations.google_adk import ArmorIQADK
from armoriq_sdk.integrations.langchain import ArmorIQLangChain
from armoriq_sdk.integrations.strands import ArmorIQStrands
from armoriq_sdk.integrations.crewai import ArmorIQCrewImport from the submodule, not the package root. from armoriq_sdk import ArmorIQLangChain currently raises ImportError even with the extra
installed. Tracked at
armoriq-sdk-customer#86.
import { ArmorIQADK } from '@armoriq/sdk/dist/integrations/google_adk';
import { ArmorIQLangChain } from '@armoriq/sdk/dist/integrations/langchain';
import { ArmorIQStrands } from '@armoriq/sdk/dist/integrations/strands';The dist/ segment is required today; there is no subpath alias yet. It will
become @armoriq/sdk/integrations/<name> once
armoriq-sdk-customer-ts#148
lands.