[package]
name = "loopctl"
version = "0.3.0"
edition = "2024"
license = "MIT OR Apache-2.0"
description = "A trait-based framework for building agent loops with pluggable LLM clients, tools, and memory"
repository = "https://github.com/dch-labs/loopctl"
homepage = "https://github.com/dch-labs/loopctl"
documentation = "https://docs.rs/loopctl"
keywords = ["agent", "framework", "llm", "loop"]
categories = ["api-bindings", "development-tools"]
readme = "README.md"
rust-version = "1.98"
[workspace]
members = ["derive"]
[lib]
name = "loopctl"
path = "src/lib.rs"
[dependencies]
futures = "0.3"
loopctl-derive = { path = "derive", version = "=0.3.0", optional = true }
hmac = { version = "0.12", optional = true }
sha2 = { version = "0.10", optional = true }
hex = { version = "0.4", optional = true }
fastrand = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_repr = "0.1"
thiserror = "2"
tokio = { version = "1.52.3", features = ["sync", "macros", "time"] }
tokio-util = { version = "0.7", features = ["rt"] }
uuid = { version = "1", features = ["v4", "serde"] }
tracing = "0.1"
reqwest = { version = "0.13", default-features = false, features = ["json", "stream", "rustls"], optional = true }
bytes = { version = "1", optional = true }
async-stream = { version = "0.3", optional = true }
httpdate = { version = "1", optional = true }
jsonschema = { version = "0.50", optional = true }
regex = { version = "1", optional = true, default-features = false, features = ["std"] }
rmcp = { version = "3", optional = true, default-features = false, features = ["client", "server", "macros", "transport-async-rw", "transport-child-process", "transport-streamable-http-client-reqwest", "transport-io"] }
[dev-dependencies]
tokio = { version = "1.52.3", features = ["rt-multi-thread", "macros", "sync", "time", "signal"] }
proptest = "1"
[features]
default = []
derive = ["dep:loopctl-derive"]
hooks = []
testing = []
tool_health = []
tool_shield = ["tool_health"]
streaming = ["dep:async-stream"]
providers = ["dep:reqwest", "dep:httpdate", "dep:bytes"]
openai = ["providers", "streaming"]
anthropic = ["providers", "streaming"]
ollama = ["providers", "openai"]
deepseek = ["providers", "openai"]
azure = ["providers", "openai"]
moonshot = ["providers", "openai"]
bedrock = ["providers", "streaming", "anthropic", "dep:hmac", "dep:sha2", "dep:hex"]
grok = ["providers", "openai"]
xai = ["grok"]
gemini = ["providers", "streaming"]
zai = ["providers", "anthropic"]
grammar = ["providers"]
schema_validation = ["dep:jsonschema"]
redaction = ["dep:regex"]
mcp = ["dep:rmcp", "streaming", "dep:reqwest", "dep:jsonschema"]
[[example]]
name = "hello-cli"
required-features = ["testing"]
[[example]]
name = "derived-tool-cli"
required-features = ["derive", "testing"]
[[example]]
name = "repl-cli"
required-features = ["testing"]
[[example]]
name = "echo-tool-cli"
required-features = ["testing"]
[[example]]
name = "chat"
required-features = ["testing", "providers"]
[[example]]
name = "mcp-adapter"
required-features = ["mcp"]
[[example]]
name = "mcp-stdio-server"
required-features = ["mcp"]
[[example]]
name = "mcp_server"
required-features = ["mcp"]
[lints.clippy]
pedantic = { level = "warn", priority = -1 }
unwrap_used = "deny"
expect_used = "deny"
panic = "deny"
todo = "deny"
unimplemented = "deny"
unreachable = "deny"
arithmetic_side_effects = "deny"
indexing_slicing = "deny"
match_same_arms = "deny"
redundant_clone = "deny"
clone_on_ref_ptr = "deny"
let_underscore_must_use = "deny"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[profile.release]
lto = "fat"
codegen-units = 1
strip = true