Integrations

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

FrameworkPythonTypeScript
Google ADKLive - pip install "armoriq-sdk[google-adk]"Live - @armoriq/sdk
StrandsLive - pip install "armoriq-sdk[strands]"Live - @armoriq/sdk
LangChainLive - pip install "armoriq-sdk[langchain]"Live - @armoriq/sdk
LangflowLive - pip install "armoriq-sdk[langchain]"Not applicable - Langflow is a Python application
CrewAILive, 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.

Call ArmorIQClient from inside your tool wrapper: declare the plan, mint a token, then invoke() instead of calling the tool. About ten lines of glue, and you get the same verification and audit trail the adapters produce. Custom frameworks has worked examples for the OpenAI Assistants run loop, Anthropic tool_use blocks, CrewAI BaseTool, and LangChain.

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, LangChainCrewAI
Mints an intent token from the planYesYes
Routes tool calls through the ArmorIQ proxyYesYes
Per-user scoping (for_user(email))YesNo - one identity per crew
Policy enforcement per tool call (allow / hold / block)YesNo
Holds and approval waitingYesNo
Live enforcement eventsStrands, LangChainNo
Behaviour when no ArmorIQ tools are foundn/aRuns unenforced with a log warning

If you need per-user policy, holds, or approvals on CrewAI, drive ArmorIQClient directly from inside your tool rather than using the adapter. See 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 request
const integration = new FrameworkAdapter({ client });          // once per process
const handle = await integration.forUser('alice@example.com'); // once per request

forUser is async in TypeScript and must be awaited. The Python equivalent is synchronous.

What you do with the handle:

FrameworkAttach with
Google ADKbundle.install(agent), then uninstall(agent) when done
StrandsAgent(hooks=[handle]) in Python, Agent({ plugins: [handle] }) in TypeScript
LangChainpass 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 ArmorIQCrew

Import 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.

On this page