@reconai/sdk
v0.1.8
Published
Detect AI trust drift before your users do. Trust scoring, GhostLog replay, and silent drift detection for any AI agent — first insight in under 5 minutes.
Maintainers
Readme
ReconAI SDK
Detect AI trust drift before your users do.
Add trust scoring, GhostLog replay, and silent drift detection to any AI agent in under 5 minutes.
A trust layer for agent systems.
ReconAI helps detect silent drift before outputs visibly fail: trust scoring (Reflex), structured failure memory (GhostLog), classification, and recovery routing. ReconAI captures receipts for silent drift and explains why they exist — the dangerous cases are often the ones that look acceptable at first glance.
Learn more at reconai.net.
Install
npm install @reconai/sdkAfter install:
✓ Recon.AI SDK Installed
Run: npx recon initThe CLI binary is recon (alias reconai); the npm package is @reconai/sdk.
5-Minute Trust Activation
npx recon initScaffolds .recon/, recon.config.ts, and recon-starter.ts, runs an optional drift demo (Trust 100 → 84), then hands off to the hosted dashboard at reconai.net/start/first-replay.
Cloud history (optional): after your first local trust event, set RECON_API_KEY, RECON_ORG_ID, and optionally RECON_API_BASE_URL (default https://reconai.net). The drift demo calls POST /api/v1/trust-events when those env vars are present.
TTFT funnel observability
| Step | Event | Where it fires |
|------|--------|----------------|
| Install | ttft_install | SDK postinstall |
| Init | ttft_init | npx recon init |
| First agent | ttft_first_agent | init scaffold |
| First observation | ttft_first_observation | drift demo / Recon.observe() |
| First trust event | ttft_first_trust_event | drift demo (+ cloud upload when configured) |
| Dashboard viewed | ttft_dashboard_viewed | CLI handoff + /start/first-replay?source=sdk&ref=ttft |
| Account created | ttft_account_created | Supabase auth callback (new user) + POST /api/starter/signup |
PostHog: SDK steps mirror as reconai_ttft_* when RECONAI_TELEMETRY_POSTHOG=1 and RECONAI_POSTHOG_KEY are set. Dashboard account creation fires server-side via NEXT_PUBLIC_POSTHOG_KEY. Operators: open /admin/funnel — auxiliary telemetry table lists all ttft_* / reconai_ttft_* events (requires POSTHOG_PERSONAL_API_KEY + POSTHOG_PROJECT_ID). Organizational mirror: reconai.net/admin/organizational-mirror links funnel ops context.
Troubleshooting: EUNSUPPORTEDPROTOCOL / workspace:
@reconai/[email protected] and older on npm shipped a bad package.json (workspace:* on @reconai/reflex-core), which causes EUNSUPPORTEDPROTOCOL. Install @reconai/sdk@^0.1.7 (or the latest version your registry shows with fixed dependencies — check with npm view @reconai/sdk dependencies).
If you are inside the recon-ai-trustops pnpm monorepo, do not run npm install at the repo root. Use pnpm install and "@reconai/sdk": "workspace:*" in the app or package that needs the SDK. See Monorepo development below.
Try it in 30 seconds
npm install @reconai/sdk
npx reconai demo
npx reconai explainOne-shot without adding a dependency to package.json (downloads the package into npm’s cache):
npm exec --yes --package=@reconai/sdk -- reconai demo
npm exec --yes --package=@reconai/sdk -- reconai explainOn Windows, npx / npm exec sometimes fails with reconai is not recognized (especially in Git Bash), because the shell does not resolve the .cmd shim the same way cmd.exe or PowerShell does. Try one of these:
cmd //c "npm exec --yes --package=@reconai/sdk -- reconai demo"After a normal npm install @reconai/sdk in that project (so node_modules/@reconai/sdk exists), run the CLI with node and skip the shim:
node node_modules/@reconai/sdk/dist/cli/index.js demonpx reconai demo prints a trust spectrum in the terminal: a healthy baseline, a false-confidence line (confident wording with weak evidence — the middle case), and a tool-misuse example. Each panel includes example signals numbers you can map into guard(). Run npx reconai explain for a plain-English breakdown of the false-confidence case. The healthy and degraded panels both mention “42” on purpose: verified against the provided context vs based on the available context — the same shape of answer, different trust story.
Each demo run records the false-confidence benchmark score in .recon/reflex-history.json (rolling list). The dashboard then shows Recent Trend — numeric sequence, sparkline, and Δ vs previous run (or “First recorded run”). Use @reconai/sdk/dashboard/trend (maybeRecordDashboardRun, buildTrendSummary) plus renderReflexDashboard({ … trendScores, recentTrendCaption }) in your own CLI the same way.
Recent Trend
72 → 68 → 45
▆ ▅ ▃
Δ -23 from previous runOptional: scaffold a local file and run the demo once (after npm install @reconai/sdk, or use npm exec as above):
npx reconai init60-second example
guard evaluates Reflex signals locally, applies policy, optionally runs your tool/lambda, and (when a dashboard is configured) posts trust state for ingestion.
import { configure, guard } from "@reconai/sdk";
configure({ baseUrl: "http://localhost:3000" }); // your Recon dashboard origin, or omit for local-only eval
const result = await guard(
{
agentId: "support_agent",
actionType: "summarize_thread",
toolName: "ticket_api",
signals: {
contextIntegrity: 88,
behavioralConsistency: 84,
toolRisk: 55,
outcomeConfidence: 82,
policyAlignment: 78,
},
requestId: `demo-${Date.now()}`,
},
async () => {
return { summary: "…" };
}
);
if (result.blocked) {
console.error(result.policyError ?? result.decision);
} else {
console.log(result.score, result.decision, result.result);
}What you get back
GuardResult includes decision (e.g. EXECUTE, RETRY, BLOCK), score (Reflex score 0–100), autonomyConfidence, predictionGap, optional result from your callback, and blocked / policyError when execution is not allowed.
Reflex onboarding funnel (v0.1.3+)
ReconAI is designed to turn your first run into a drift receipt: capture builder intent, compare expected vs actual output, persist a local GhostLog line, and surface a short “why” for humans. Use the reflex / ghostlog / recon namespaces so reflex.compare participates in opt-in telemetry (v0.1.4+); the standalone reflexCompare export is the same heuristic without funnel events.
From install → receipt in minutes
npm i @reconai/sdk1. Initialize Recon
import { initRecon } from "@reconai/sdk";
await initRecon({
projectId: "my-agent-app",
prompt: true, // TTY: pick what you want to detect
// telemetry: true, // v0.1.4+: anonymized funnel metrics (off by default)
});PostHog (optional, v0.1.6+): To mirror the same onboarding events—and configure() / guard usage signals—into your PostHog project, set RECONAI_TELEMETRY_POSTHOG=1 and RECONAI_POSTHOG_KEY to your project API key (phc_…). No code changes are required when those env vars are set. Optional: RECONAI_POSTHOG_HOST (default https://us.i.posthog.com), RECONAI_TELEMETRY_DISTINCT_ID (stable id per deploy). Guard usage is counted at most once per UTC day per workspace directory.
TTY menu options map to GhostLog.meta.intent: hallucinations | output_inconsistency | agent_workflow_drift | other (or unspecified if skipped).
2. Detect drift with Reflex
import { reflex } from "@reconai/sdk";
const result = reflex.compare({
expected: "User should receive refund confirmation",
actual: agentOutput,
});Example shape (scores vary by text):
{
"reflexScore": 0.62,
"status": "degraded",
"driftType": "semantic_misalignment",
"confidence": 0.81,
"signals": { "jaccard": 0.2, "containment": 0.66, "alignment": 0.62 }
}reflexScore here is a 0–1 onboarding alignment score (fast heuristic). Pair with guard() / computeReflexScore() when you need full 0–100 Reflex signals against your policy.
3. Capture a GhostLog receipt
import { ghostlog } from "@reconai/sdk";
ghostlog.capture({
input: expected,
output: agentOutput,
reflexScore: result.reflexScore,
driftType: result.driftType,
});Appends one NDJSON line to .reconai/ghostlog.jsonl and refreshes .reconai/trustgraph-snapshot.json (canonical TrustGraph aggregate: overview, drift histogram, intent × drift slices, narrative risk). The first line in a new log prints:
Drift receipt captured. You are now tracking real agent behavior.
4. Understand why it drifted
const explanation = reflex.explain({ expected, actual: agentOutput }, result);Returns structured hints (reasoning, missingFromActual, extraInActual) for CLI or UI — not raw prompts.
5. Recovery hint
import { recon } from "@reconai/sdk";
const retryHint = recon.recover({
strategy: "re-prompt",
context: { expected, actual: agentOutput },
});(task / previousAttempt are also supported.)
What this gives you
- Immediate signal — drift on first run, before failure is obvious
- Structured memory — GhostLog receipts (local NDJSON, ready to aggregate)
- Explainability — why the receipt exists
- Recovery path — what to try next
Where this goes next
Aggregate LocalGhostLogEntry rows into drift distributions, intent × failure patterns, and score trends — the same objects seed TrustGraph and narrative layers.
Opt-in telemetry (v0.1.4+)
When telemetry: true on initRecon, the SDK may POST three anonymized events per project per machine: sdk_initialized, first_compare, first_ghostlog_capture. Payloads include hashed projectId, SDK version, intent (on first compare), driftType (on first capture), and a timestamp — never raw prompts, inputs, or outputs.
- Default endpoint:
https://api.reconai.dev/telemetry - Override: set
RECONAI_TELEMETRY_URL(wins overtelemetryEndpoint/ default) - First-compare / first-capture de-duplication:
.reconai/telemetry-state.json(per workspace)
TrustGraph snapshot & CLI summary
After captures, ReconAI writes a derived snapshot to:
.reconai/trustgraph-snapshot.json
Print a read-only text summary (no extra aggregation — uses the snapshot as-is):
npx reconai summary
npx reconai summary --jsonExit codes: healthy, degraded, and recovery → 0; critical → 1 (for gating CI). With --json, a missing snapshot also exits 1 and prints { "ok": false, "error": "no_snapshot", ... }. When a snapshot exists, --json prints the full TrustGraphSnapshot (same shape as .reconai/trustgraph-snapshot.json).
Programmatic formatting: formatTrustGraphSummary / formatTrustGraphSummaryMissing from @reconai/sdk.
CI examples (snapshot must exist; use your repo root as cwd):
STATE=$(npx reconai summary --json | jq -r '.overview.trustState')
if [ "$STATE" = "critical" ]; then
echo "Trust gate failed: critical"
exit 1
finpx reconai summary --json | jq -e '.overview.trustState != "critical"' >/dev/null || exit 1Example output:
ReconAI Drift Summary
System State: degraded
Receipts in Window: 12
Average Reflex Score: 0.68
Worst Reflex Score: 0.41
Top Drift Type: workflow_divergence (5)
Top Intent: agent_workflow_drift (7 of 12)
Primary Risk:
Most recent drift pressure is concentrated in workflow_divergence.
Recommended Action:
Inspect intermediate step routing and retry with narrowed task state.Use aggregateGhostLogToTrustGraphSnapshot, readTrustGraphSnapshot, and writeTrustGraphSnapshotFromEntries if you need the same model in code (e.g. after editing GhostLog manually: writeTrustGraphSnapshotFromEntries(readAllGhostLogEntries(cwd), cwd)).
Render a real guard() run in the terminal
Synthetic onboarding (npx reconai demo) and live runs share the same renderer. After guard() returns, pass the same request you used for evaluation plus the result:
import {
configure,
guard,
reflexDashboardFromGuardResult,
renderReflexDashboard,
} from "@reconai/sdk";
import { buildTrendSummary, maybeRecordDashboardRun } from "@reconai/sdk/dashboard/trend";
configure({ baseUrl: "" });
const request = {
agentId: "support_agent",
actionType: "summarize_thread",
toolName: "ticket_api",
signals: {
contextIntegrity: 52,
behavioralConsistency: 58,
toolRisk: 72,
outcomeConfidence: 92,
policyAlignment: 55,
},
requestId: `run-${Date.now()}`,
};
const result = await guard(
request,
async () => ({
summary: "Probably a billing issue, but I'm not fully sure.",
})
);
const dashboard = reflexDashboardFromGuardResult(request, result);
const { scores: trendScores } = maybeRecordDashboardRun(process.cwd(), dashboard.score);
const recentTrendCaption = buildTrendSummary(trendScores).text;
console.log(renderReflexDashboard({ ...dashboard, trendScores, recentTrendCaption }));For advanced use (custom trends, notes, or when you already have a full ReflexSignals object from guardEvaluate), use buildReflexDashboardState directly.
Core concepts
| Concept | Meaning | |--------|---------| | Reflex Score | Trust signal for a step or action, derived from signal dimensions (context integrity, tool risk, etc.). | | GhostLog | Structured memory of drift/failure patterns (types live in this SDK for contracts and UI). | | Recovery | Treated as a state transition in product flows—not only “retry again.” |
More detail: Reflex Score · GhostLog · Recovery.
Flow (high level)
flowchart TD
A[Agent / tool step] --> G[guard / guardEvaluate]
G --> R[Reflex score + decision]
R --> I[Trust state ingestion optional]
R --> P[Policy + recovery routing in product]LangChain-style wrapper
import { configure, withRecon } from "@reconai/sdk";
configure({ baseUrl: "http://localhost:3000" });
const out = await withRecon(
{
agentId: "lc_agent",
actionType: "runnable_invoke",
toolName: "chain",
signals: {
contextIntegrity: 86,
behavioralConsistency: 85,
toolRisk: 48,
outcomeConfidence: 83,
policyAlignment: 80,
},
},
async (input: string) => `Echo: ${input}`,
"hello",
);
console.log(out.score, out.decision, out.result);Or import the adapter only: import { withRecon } from "@reconai/sdk/adapters/langchain".
Cursor (trust wrapper — subpath only)
import { runTrustedCursorAgent } from "@reconai/sdk/adapters/cursor";Do not import Cursor runtime helpers from the @reconai/sdk root — that path must stay bundle-safe. Boundaries, CI check, and incident shorthand live in Adapter boundaries.
What is stable today vs tightening
Stable to build on: root exports — guard, guardEvaluate, configure, Reflex re-exports (computeReflexScore, …), and shared trust event types.
Still tightening: migration/deploy subpaths, full middleware surface for every framework, and semver guarantees as we gather external feedback.
Early builders
If you are stress-testing long chains, tool-heavy agents, or nested tool misuse, open an issue or reach out — that feedback shapes calibration and recovery policy.
Docs
- Changelog — notable type/API changes (including Z+1 runtime governance rehearsal)
- Adapter boundaries — Core vs adapters (Cursor subpath lock)
- Recon Guard (runtime) — monorepo runtime guard docs
- Reflex Score
- GhostLog
- Recovery
License
MIT — see LICENSE.
Monorepo development
The SDK powers internal flows for Reflex scoring, guard middleware, swarm/mission trust, and related APIs in the recon-ai-trustops monorepo. We are tightening package naming, install flow, examples, and stable public API boundaries. Advanced subpaths such as @reconai/sdk/migration ship as TypeScript sources for operator tooling; treat the root export as the primary integration surface.
Inside the recon-ai-trustops monorepo
Use pnpm (this repo is a workspace). The SDK lives under packages/sdk; dashboard already depends on "@reconai/sdk": "workspace:*" — run:
pnpm installDo not use npm install at the repo root for workspace workflow.
pnpm install @reconai/sdk at root triggers ERR_PNPM_ADDING_TO_ROOT: root is rarely where that dependency belongs. Prefer adding "@reconai/sdk": "workspace:*" to the specific app/package under apps/ or packages/, then pnpm install. If you intentionally need it at the workspace root:
pnpm add @reconai/sdk@workspace:* -wRun the demo script from repo root (preferred — works on Windows; wires node dist/cli/index.js):
pnpm reconai:demopnpm exec reconai demo can fail outside a workspace package folder (no reconai on PATH). Don’t nest tmp-recon-demo under reconai-langchain-quickstart/ expecting the JS CLI there—Python track only.
Repository root pnpm run validate:quickstarts runs this package’s build, Vitest, and verify:adapter-boundary, plus the Python LangChain quickstart smoke (requires bash + Python). Same gate runs under GitHub Actions as validate-quickstarts — monorepo only, not npm/PyPI parity.
CLI from the monorepo
This monorepo does not list @reconai/sdk at the workspace root, so there is no node_modules/@reconai/sdk next to the root package.json. From the repo root, use:
pnpm run reconai:demo
pnpm run reconai:explain
pnpm run recon:summary
pnpm run recon:summary -- --jsonOr from anywhere after a build: pnpm --filter @reconai/sdk run demo. From packages/sdk: pnpm run demo or node dist/cli/index.js demo.
Runnable examples (this repo)
From packages/sdk:
pnpm install
pnpm run build
pnpm run example:quickstart
pnpm run example:drift
pnpm run example:langchain
pnpm run example:onboardingTail receipts: tail -f .reconai/ghostlog.jsonl.
Publishing (maintainers)
@reconai/reflex-coremust exist on npm. The SDK lists"@reconai/reflex-core": "^0.1.0"in source so published tarballs do not rely onworkspace:for that dependency. If it is missing from the registry,npm install @reconai/sdkfails when resolving dependencies.- Publish from this monorepo with pnpm, e.g.
pnpm publish --filter @reconai/reflex-core --access publicthenpnpm publish --filter @reconai/sdk --access public, so versioning and installs stay predictable. - Local tarball: In pnpm 9,
pnpm --filter @reconai/sdk packfails withUnknown option: 'recursive'—packdoes not support--filter. Usepnpm --filter @reconai/sdk run pack:tgz(build +pnpm packinsidepackages/sdk) orpnpm -C packages/sdk packafter a build.
