agent-first-http 0.12.0

Give your AI agent its own private browser — so it reads the real page, past logins and bot walls, without ever touching yours.
Documentation
[package]
name = "agent-first-http"
version = "0.12.0"
edition = "2024"
description = "Give your AI agent its own private browser — so it reads the real page, past logins and bot walls, without ever touching yours."
license = "MIT"
repository = "https://github.com/agentfirstkit/agent-first-http"
readme = "README.md"
# container/docker/{Dockerfile,install-backends.sh,entrypoint.sh} are embedded
# via include_str! in cli/cmd/container.rs, so they must ship in the crate; the
# rest of container/ (compose, dockerignore) is build/deploy-only.
exclude = [".github/", "container/docker/compose.yaml", "container/docker/Dockerfile.dockerignore", "tests/Dockerfile.test", "tests/Dockerfile.test.dockerignore"]

[[bin]]
name = "afhttp"
path = "src/main.rs"
required-features = ["cli"]

[[example]]
name = "manual_display_takeover"
required-features = ["host"]

[features]
default = ["sdk", "cli"]
sdk = []
host = [
    "dep:chromiumoxide",
    "dep:axum",
    "dep:tower",
    "dep:tower-http",
    "dep:hyper",
    "dep:hyper-util",
    "agent-first-ui/session",
]
# The document formats are a CLI concern: `--token-secret file:PATH#DOT_PATH`
# reads a credential out of whatever config file the caller already keeps, and
# refusing a `.toml` because this build lacks a parser would make the source a
# lottery. The SDK floor still links none of them.
cli = [
    "sdk",
    "host",
    "dep:psl",
    "agent-first-data/skill-admin",
    "agent-first-data/stream-redirect",
    "agent-first-data/yaml",
    "agent-first-data/toml",
    "agent-first-data/dotenv",
    "agent-first-data/ini",
]

[dependencies]
# SDK floor — always compiled.
tokio = { version = "1", features = ["full"] }
rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs", "std"] }
reqwest = { version = "0.13", default-features = false, features = [
    "json", "rustls-no-provider", "gzip", "brotli", "deflate", "stream", "http2", "multipart", "form"
] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
base64 = "0.23"
uuid = { version = "1", features = ["v4"] }
tokio-tungstenite = { version = "0.30", features = ["rustls-tls-native-roots"] }
futures = "0.3"
dirs = "6"
humantime = "2"
mime_guess = "2"
fs2 = "0.4"
tempfile = "3"
url = "2"
thiserror = "2"

# Host feature deps — chromiumoxide + the axum listener stack.
#
# agent-first-ui owns the two human-UI primitives afhttp would otherwise
# reimplement: the revocable constant-time credential behind every
# `/takeover/*` URL, and the isolated window `afhttp ui takeover` opens the
# panel in. Host-side because the credential lives in the listener; the CLI
# feature turns `host` on, so the window primitive comes with it. Both of those
# primitives are `session`-tier; afhttp reads no frontend, so it takes nothing
# from the guard tier below it.
agent-first-ui = { version = "0.3.1", default-features = false, optional = true }
chromiumoxide = { version = "0.9", optional = true, default-features = false }
axum = { version = "0.8", optional = true, features = ["ws", "macros"] }
tower = { version = "0.5", optional = true }
tower-http = { version = "0.7", optional = true, features = ["fs", "trace"] }
hyper = { version = "1", optional = true, features = ["full"] }
hyper-util = { version = "0.1", optional = true, features = ["server-auto", "tokio"] }

# SDK floor. `cli` is part of the floor because every build emits protocol
# events through `CliEmitter`; skill administration and stream redirection are
# enabled only by this crate's own `cli` feature.
agent-first-data = { version = "0.32.1", default-features = false, features = ["cli"] }
cookie = "0.18"
psl = { version = "2", optional = true }

[dev-dependencies]
serde_json = "1"
tempfile = "3"
tokio = { version = "1", features = ["full", "test-util"] }
axum = { version = "0.8", features = ["ws", "macros"] }
filetime = "0.2"

[lints.clippy]
unwrap_used = "deny"
expect_used = "deny"
panic = "deny"
print_stdout = "deny"
print_stderr = "deny"