Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ members = [
resolver = "2"

[workspace.package]
version = "0.10.0"
version = "0.11.0"
edition = "2024"
license = "AGPL-3.0"
repository = "https://github.com/us/crw"
Expand Down
4 changes: 2 additions & 2 deletions crates/crw-browse/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ description = "MCP server for interactive browser automation over CDP"
publish = false

[dependencies]
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-renderer = { path = "../crw-renderer", version = "0.10.0", features = ["cdp"] }
crw-core = { path = "../crw-core", version = "0.11.0" }
crw-renderer = { path = "../crw-renderer", version = "0.11.0", features = ["cdp"] }

rmcp = { version = "1.5", features = ["server", "macros", "transport-io"] }
clap = { workspace = true }
Expand Down
14 changes: 7 additions & 7 deletions crates/crw-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ browse = ["dep:crw-browse", "dep:rmcp", "dep:anyhow"]

[dependencies]
# Core crates
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-renderer = { path = "../crw-renderer", version = "0.10.0", features = ["auto-browser", "cdp"] }
crw-extract = { path = "../crw-extract", version = "0.10.0" }
crw-crawl = { path = "../crw-crawl", version = "0.10.0" }
crw-search = { path = "../crw-search", version = "0.10.0" }
crw-core = { path = "../crw-core", version = "0.11.0" }
crw-renderer = { path = "../crw-renderer", version = "0.11.0", features = ["auto-browser", "cdp"] }
crw-extract = { path = "../crw-extract", version = "0.11.0" }
crw-crawl = { path = "../crw-crawl", version = "0.11.0" }
crw-search = { path = "../crw-search", version = "0.11.0" }

# Server (for serve + mcp-embedded + setup commands)
crw-server = { path = "../crw-server", version = "0.10.0", optional = true, features = ["cdp"] }
crw-server = { path = "../crw-server", version = "0.11.0", optional = true, features = ["cdp"] }

# Browse (for browse command)
crw-browse = { path = "../crw-browse", version = "0.10.0", optional = true }
crw-browse = { path = "../crw-browse", version = "0.11.0", optional = true }

# Web framework (for serve command)
axum = { workspace = true, optional = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/crw-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ description = "Core types, config, and error handling for the CRW web scraper"
cdp = []

[dependencies]
crw-mcp-proto = { path = "../crw-mcp-proto", version = "0.10.0" }
crw-mcp-proto = { path = "../crw-mcp-proto", version = "0.11.0" }
serde = { workspace = true }
serde_json = { workspace = true }
toml = { workspace = true }
Expand Down
18 changes: 18 additions & 0 deletions crates/crw-core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,24 @@ pub struct LlmUsage {
pub truncated: bool,
#[serde(default = "one_u32", skip_serializing_if = "is_one_u32")]
pub calls: u32,

// ── Wave 4 (R1) additions: SaaS billing correlation across legs ──
//
// The SaaS-side managed pricing path needs to know exactly how many
// summary calls executed AND whether the answer leg ran. The 5-branch
// fail-closed dispatch keys off these counters:
// - executedSummaries > 0 OR answerExecuted ⇒ engine did work
// - inputTokens == 0 AND outputTokens == 0 ⇒ no upstream cost
// Without the counters the SaaS cannot disambiguate "no work" from
// "work but missing telemetry" and would refund or charge wrong.
//
// Always serialized (no skip_serializing_if) so the always-present
// R1 invariant holds: when /v1/search returns llmUsage, both fields
// are explicitly visible.
#[serde(default)]
pub executed_summaries: u32,
#[serde(default)]
pub answer_executed: bool,
}

fn one_u32() -> u32 {
Expand Down
8 changes: 4 additions & 4 deletions crates/crw-crawl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ categories.workspace = true
description = "Async BFS web crawler with rate limiting and robots.txt support for CRW"

[dependencies]
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-diff = { path = "../crw-diff", version = "0.10.0" }
crw-renderer = { path = "../crw-renderer", version = "0.10.0" }
crw-extract = { path = "../crw-extract", version = "0.10.0" }
crw-core = { path = "../crw-core", version = "0.11.0" }
crw-diff = { path = "../crw-diff", version = "0.11.0" }
crw-renderer = { path = "../crw-renderer", version = "0.11.0" }
crw-extract = { path = "../crw-extract", version = "0.11.0" }
reqwest = { workspace = true }
serde_json = { workspace = true }
scraper = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/crw-diff/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ description = "Stateless change-tracking diff engine for the CRW web scraper"
# Shared types only (ChangeTrackingOptions/Result, DiffAst, etc.). This crate
# MUST NOT depend on crw-extract — judging is injected upstream so the diff
# engine stays pure (no LLM, no HTTP, no I/O).
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-core = { path = "../crw-core", version = "0.11.0" }
serde = { workspace = true }
serde_json = { workspace = true }
similar = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/crw-extract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ categories.workspace = true
description = "HTML extraction and markdown conversion engine for the CRW web scraper"

[dependencies]
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-core = { path = "../crw-core", version = "0.11.0" }
lol_html = { workspace = true }
scraper = { workspace = true }
htmd = { workspace = true }
Expand Down
10 changes: 10 additions & 0 deletions crates/crw-extract/src/llm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,11 @@ fn parse_anthropic_usage(payload: &serde_json::Value, model: &str) -> Option<Llm
cache_miss_input_tokens,
truncated: false,
calls: 1,
// R1 counters are scoped to /v1/search aggregation; single-call
// sites always emit defaults. Aggregation happens in the caller
// (crw-server::routes::search::search_inner).
executed_summaries: 0,
answer_executed: false,
})
}

Expand Down Expand Up @@ -474,6 +479,11 @@ fn parse_openai_usage(
cache_miss_input_tokens,
truncated: false,
calls: 1,
// R1 counters are scoped to /v1/search aggregation; single-call
// sites always emit defaults. Aggregation happens in the caller
// (crw-server::routes::search::search_inner).
executed_summaries: 0,
answer_executed: false,
})
}

Expand Down
8 changes: 8 additions & 0 deletions crates/crw-extract/src/structured.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ pub(crate) async fn call_anthropic(
cache_miss_input_tokens: cache_miss,
truncated: false,
calls: 1,
// R1 counters are aggregated in the /v1/search caller;
// single-call sites always emit defaults.
executed_summaries: 0,
answer_executed: false,
}
});

Expand Down Expand Up @@ -498,6 +502,10 @@ pub(crate) async fn call_openai(
cache_miss_input_tokens: cache_miss,
truncated: false,
calls: 1,
// R1 counters are aggregated in the /v1/search caller;
// single-call sites always emit defaults.
executed_summaries: 0,
answer_executed: false,
}
});

Expand Down
6 changes: 3 additions & 3 deletions crates/crw-mcp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ default = ["embedded"]
embedded = ["dep:crw-server"]

[dependencies]
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-renderer = { path = "../crw-renderer", version = "0.10.0", features = ["auto-browser"] }
crw-core = { path = "../crw-core", version = "0.11.0" }
crw-renderer = { path = "../crw-renderer", version = "0.11.0", features = ["auto-browser"] }
serde_json = { workspace = true }
tokio = { workspace = true }
reqwest = { workspace = true }
Expand All @@ -28,4 +28,4 @@ tracing-subscriber = { workspace = true }
clap = { workspace = true }

# Embedded mode: pulls in full scraping engine
crw-server = { path = "../crw-server", version = "0.10.0", optional = true, features = ["cdp"] }
crw-server = { path = "../crw-server", version = "0.11.0", optional = true, features = ["cdp"] }
10 changes: 5 additions & 5 deletions crates/crw-monitor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ description = "Optional self-host monitor mode for the CRW web scraper (SQLite-b
# `crw-crawl` provides the scrape/crawl primitives; `crw-extract` provides the
# LLM judge. None of these pull a DB dependency — the SQLite/cron/hmac stack is
# local to this crate and feature-gated, never compiled into the default server.
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-diff = { path = "../crw-diff", version = "0.10.0" }
crw-crawl = { path = "../crw-crawl", version = "0.10.0" }
crw-extract = { path = "../crw-extract", version = "0.10.0" }
crw-renderer = { path = "../crw-renderer", version = "0.10.0" }
crw-core = { path = "../crw-core", version = "0.11.0" }
crw-diff = { path = "../crw-diff", version = "0.11.0" }
crw-crawl = { path = "../crw-crawl", version = "0.11.0" }
crw-extract = { path = "../crw-extract", version = "0.11.0" }
crw-renderer = { path = "../crw-renderer", version = "0.11.0" }

serde = { workspace = true }
serde_json = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions crates/crw-renderer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ cdp = ["tokio-tungstenite", "crw-core/cdp"]
auto-browser = ["dep:dirs"]

[dependencies]
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-extract = { path = "../crw-extract", version = "0.10.0" }
crw-core = { path = "../crw-core", version = "0.11.0" }
crw-extract = { path = "../crw-extract", version = "0.11.0" }
reqwest = { workspace = true }
tokio = { workspace = true }
tokio-tungstenite = { version = "0.28", features = ["rustls-tls-native-roots"], optional = true }
Expand Down
2 changes: 1 addition & 1 deletion crates/crw-search/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ categories.workspace = true
description = "SearXNG-backed search client and result transforms for the CRW web scraper"

[dependencies]
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-core = { path = "../crw-core", version = "0.11.0" }
futures = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
Expand Down
14 changes: 7 additions & 7 deletions crates/crw-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ test-utils = []
monitor = ["dep:crw-monitor"]

[dependencies]
crw-core = { path = "../crw-core", version = "0.10.0" }
crw-diff = { path = "../crw-diff", version = "0.10.0" }
crw-renderer = { path = "../crw-renderer", version = "0.10.0" }
crw-extract = { path = "../crw-extract", version = "0.10.0" }
crw-crawl = { path = "../crw-crawl", version = "0.10.0" }
crw-search = { path = "../crw-search", version = "0.10.0" }
crw-core = { path = "../crw-core", version = "0.11.0" }
crw-diff = { path = "../crw-diff", version = "0.11.0" }
crw-renderer = { path = "../crw-renderer", version = "0.11.0" }
crw-extract = { path = "../crw-extract", version = "0.11.0" }
crw-crawl = { path = "../crw-crawl", version = "0.11.0" }
crw-search = { path = "../crw-search", version = "0.11.0" }
# Optional self-host monitor mode (default OFF — see the `monitor` feature).
crw-monitor = { path = "../crw-monitor", version = "0.10.0", optional = true }
crw-monitor = { path = "../crw-monitor", version = "0.11.0", optional = true }
axum = { workspace = true }
tower = { workspace = true }
tower-http = { workspace = true }
Expand Down
Loading
Loading