Documentation Index
Fetch the complete documentation index at: https://docs.agentguardian.io/llms.txt
Use this file to discover all available pages before exploring further.
What this is
ATargetAdapter is the seam between AgentGuardian and your agent. The swarm
sends one user-turn via await adapter.call(prompt, session=...) and reads
one assistant text reply back; everything else — orchestration, judging,
scoring — runs on top.
Four modes ship in agent_guardian.adapters:
| Mode | Class | Use when |
|---|---|---|
prompt | PromptAdapter | You only have a system prompt, no agent yet (pre-deployment review). |
code | CodeAdapter | Your agent is an importable Python callable / class / dotted path. |
http | HttpAdapter | Your agent is a hosted HTTP/JSON endpoint (OpenAI-, Anthropic-, or generic-shape). |
framework | FrameworkAdapter subclasses | Your agent is a LangGraph / CrewAI / AutoGen / ADK / OpenAI Agents / Strands native object. |
When to use this
- The four built-in modes don’t cover your transport (custom RPC, gRPC, websocket, in-process queue, on-device runtime).
- You want stricter fingerprinting than
CodeAdapter’s heuristics give you — e.g. you know the target has memory + PII and want to force tier T1 from the start. - You want to register a new HTTP provider shape without subclassing
HttpAdapter(useregister_shapeinstead — see Custom HTTP shapes).
The protocol
Every adapter inheritsTargetAdapter (declared in
src/agent_guardian/adapters/base.py)
and satisfies three contracts:
- Set
self._fingerprintin__init__. ATargetFingerprintdeclares the static attack surface —mode,ref,has_tools,has_memory,touches_pii,is_multi_agent,declared_tools,declared_memory_keys. The recon agent refines these signals on phase 1 of the swarm; the swarm tiering logic reads them viaTargetFingerprint.to_observed_surface(). - Implement
async def call(self, prompt, *, session=None) -> str. Send one user-turn, return one assistant text reply.sessionis an opaque string the swarm uses to thread parallel conversations — distinct ASI agents pass distinct session IDs so per-session histories never cross-contaminate. - Optionally override
profile_evidence()andaclose(). White-box adapters returnProfileEvidence(box="white", text=...)so the profiler can read your target instead of interrogating it; otherwise the default black-box evidence forces a behavioural audit.
Build a custom adapter
The example below wraps a hypothetical gRPC chat service. It’s a black-box adapter — the swarm can only call it, not read its source.my_grpc_adapter.py
Use it from the CLI
The CLI’sscan subcommand accepts a dotted-path target — pass it a
module:attr reference to a no-arg-constructible callable that returns
your adapter:
my_target.py
CodeAdapter is the path the dotted-path resolver instantiates by default
(see cli.py::build_target_adapter). If you need to bypass it entirely —
e.g. inject your adapter into the swarm programmatically — drive the
swarm via the SwarmCommander API instead of the CLI.Use it programmatically
run_scan.py
White-box adapters: expose source for profiling
White-box adapters let the profiler read the target’s implementation rather than interrogate it through prompts. Overrideprofile_evidence():
PromptAdapter returns the system prompt verbatim;
CodeAdapter calls safe_source_and_root() to extract the defining
module’s source (scoped to the entry-point’s transitive closure if the
module exceeds 80 000 chars).
Custom HTTP shapes
If your target is HTTP/JSON-shaped but doesn’t match any of the six built-in shapes (openai, anthropic, bedrock, vertex, agentcore, generic),
register a new shape rather than subclassing HttpAdapter. A shape is a
pair of pure functions wrapped in an HttpShape dataclass.
register_my_shape.py
src/agent_guardian/adapters/http_shapes/base.py.
register_shape raises ValueError on duplicate names so import-time
registration is idempotent only across distinct module loads.
Expected output
A correctly wired custom adapter looks indistinguishable from a built-in one in the CLI banner — same tier auto-detection, same per-agent feed, same final summary line:has_tools=True and recon didn’t observe any
tool calls during phase 1, the tool-abuse-agent short-circuits via
is_applicable(fingerprint) and you’ll see probes=0 findings=0 not_tested=0 — that’s the swarm correctly skipping a category that doesn’t
apply, not a bug.
How to interpret a failed adapter wire-up
| Symptom | Cause | Fix |
|---|---|---|
RuntimeError: ... did not set _fingerprint in __init__ | You forgot to assign self._fingerprint = TargetFingerprint(...). | Set it before __init__ returns. |
TypeError: CodeAdapter cannot instantiate ... with no args | Your dotted-path target needs constructor arguments. | Wrap it in a no-arg factory (def target(): return MyAgent(api_key=...)). |
UserWarning: CodeAdapter target returned dict, coercing via str() | Your call() returned a non-string. | Return str directly; dict / BaseModel coercions are noisy and inspection-hostile. |
EgressRefused log lines with terminated_by=not_tested on every agent | Your contract or RoE forbids the destinations the attacker probed. | Widen the contract egress_allowlist or accept that the category is out-of-scope. |
Next step
Write a custom attack
Author a new YAML probe — the seed text, ASI/MITRE/CSA mapping, and the
triple-framework gate the loader enforces.
System overview
Where adapters sit in the six-phase swarm pipeline.
Scan modes
Pick
fast / smart / full for your CI-gate vs. release-gate runs.CLI reference
Every flag declared in
cli.py with its default and meaning.