feat(examples): add TanStack AI chat() guardrails example - #207
Conversation
Add a standalone tanstack-agent that vendors unpublished @arcjet/guard/tanstack-ai/v0 from arcjet-js@3e81a91c and demonstrates guardMiddleware first, tanstackAiContext, and inbound guard() before chat(). Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Use streamToText so RUN_ERROR is not an empty 200, accept TANSTACK_MODEL via openaiCompatibleText, register the example in the root compose file, and return 400 for invalid JSON and Zod errors. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Repin the unpublished tanstack-ai/v0 adapter to the merge commit on arcjet-js main (d730d57). npm still does not export the subpath. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Guard on main imports @arcjet/transport/http2, which npm 1.11.0 does not export. Pin both packages to the #6260 merge SHA so the example can start. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Arcjet Review — 🟡 Medium Risk
Decision: Approved
Rationale: Self-contained example addition. New Node HTTP server has input validation (zod), body size cap (32 KiB), message length cap (2000), and clear README warnings that this is a local demo without auth. No hardcoded secrets. The vendored @arcjet/guard and @arcjet/transport packages are pinned to a documented arcjet-js commit (d730d57) with SOURCE.txt attribution and are only used inside the example. Escalation triggers fire (Dockerfile, compose.yaml, package.json) but each is scoped to the new example directory and doesn't touch shared infra. Approving despite Medium risk because the changes are isolated to an example, security caveats are clearly documented, and the guardrails logic itself (inbound guard() + hasFailedOpen check, guardMiddleware first, default-skip DENY) matches the documented @arcjet/guard/tanstack-ai/v0 patterns.
Summary of Changes
Adds examples/tanstack-agent: a Node HTTP server + minimal HTML page demonstrating TanStack AI chat() protected by Arcjet Guard's tanstack-ai/v0 adapter. Inbound prompt-injection screening runs before chat(); guardMiddleware runs first for tool-call rate limiting and PII detection on free-text args. Because @arcjet/guard/tanstack-ai/v0 is not yet on npm, @arcjet/guard and @arcjet/transport are vendored from arcjet-js@d730d57. Also registers the example in the top-level compose.yaml, README, and prepare-to-publish.ts.
Escalation Triggers
- Dependency Changes: New examples/tanstack-agent/package.json declares dependencies including file:./vendor/... refs and an overrides block for @arcjet/transport.
- CI/CD Pipeline: New Dockerfile for the example (scoped to examples/tanstack-agent, not shared CI).
- Infrastructure: New examples/tanstack-agent/compose.yaml and an include entry in the top-level compose.yaml.
Notes
PR exceeds the 1000-line threshold, but ~2500+ of the added lines are vendored README/LICENSE/SKILL.md content from arcjet-js@d730d57 (documented in vendor/SOURCE.txt), not novel logic. The reviewable new code (index.ts, lib/agent.ts, lib/arcjet.ts, index.html, tsconfig/Dockerfile/compose) is small and self-contained.
Path filtering: 95 files excluded by ignore paths. 27 of 122 files included in review.
Review: 762d75cd | Model: anthropic/claude-opus-4-7 | Powered by Arcjet Review
Fail fast on missing model keys, destroy oversized request streams, return 400 for invalid conversation ids, log inbound guard throws, and version the vendor packages so they do not collide with npm 1.11.0. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Adds
examples/tanstack-agent: a small Nodechat({ middleware })support agent protected by@arcjet/guard/tanstack-ai/v0(arcjet-js#6260).Inbound
guard()runs beforechat().guardMiddlewareis first in the middleware list soonBeforeToolCallrate-limits lookups and scans free-textnoteargs for PII. Default DENY is{ type: "skip", result: ArcjetDenialResult }. Correlation is a caller-ownedsessionId— neverctx.threadId.The adapter is on
mainbut not on npm yet, so@arcjet/guardand@arcjet/transport(./http2) are vendored fromd730d57. Repin once@arcjet/guard/tanstack-ai/v0publishes.Docs:
/guards/tanstack-ai/. Runexamples/tanstack-agentwithARCJET_KEYandAI_GATEWAY_API_KEY.