docs(comments): rewrite comments across all crates to the guidelines
Sweep every first-party crate source (1956 .rs files) to the project comment guidelines: delete redundant restatements, decorative banners, change narration, and end-of-line comments; keep and tighten the crucial ones (invariants, bug rationale, SAFETY blocks, ported-source attribution). No functional code changed. Every edit is proven comment-only against the prior tree by a comment-stripping lexer (string/char/raw-string aware) plus a separate doctest-fence check. Where removing a comment made rustfmt or clippy want to re-lay-out adjacent code, the minimal triggering comment is restored so code tokens stay byte-identical. Gates green: cargo fmt --all --check (0 diffs), cargo check and cargo clippy --workspace --all-targets (0 warnings). Adds scripts/check_codegen_comment_guidelines.py — the enforcement gate for these guidelines (flags banners, end-of-line comments, change narration, and commented-out code).
This commit is contained in:
@@ -88,8 +88,7 @@ fn remove_returns_value_then_none() {
|
||||
|
||||
#[test]
|
||||
fn insert_arc_shares_allocation() {
|
||||
// Inserting an existing Arc means the stored value and the original
|
||||
// share strong-count.
|
||||
// insert_arc shares the Arc (strong-count rises).
|
||||
let arc = Arc::new(Config {
|
||||
base_url: "shared".into(),
|
||||
timeout_ms: 9,
|
||||
@@ -97,10 +96,7 @@ fn insert_arc_shares_allocation() {
|
||||
let mut ctx = ToolCallContext::default();
|
||||
ctx.extensions.insert_arc(arc.clone());
|
||||
let from_ctx = ctx.extensions.get::<Config>().unwrap();
|
||||
// Strong-count on the original Arc should reflect at least:
|
||||
// - the original `arc` binding
|
||||
// - the value stored in the extension map
|
||||
// - the clone returned from `get`
|
||||
// Strong-count: original binding + map entry + get() clone.
|
||||
assert!(Arc::strong_count(&arc) >= 3);
|
||||
assert_eq!(*from_ctx, *arc);
|
||||
}
|
||||
@@ -152,13 +148,10 @@ fn clone_preserves_call_id_and_extensions() {
|
||||
assert_eq!(copy.call_id, ctx.call_id);
|
||||
assert_eq!(copy.extensions.len(), 1);
|
||||
|
||||
// Both clones see the same Arc-backed extension value.
|
||||
let from_orig = ctx.extensions.get::<AuthToken>().unwrap();
|
||||
let from_copy = copy.extensions.get::<AuthToken>().unwrap();
|
||||
assert_eq!(from_orig.0, from_copy.0);
|
||||
// The Arc allocation is shared; mutating via one path is impossible
|
||||
// (extensions are immutable through `get`), but strong-count rises
|
||||
// because of the clone.
|
||||
// Arc is shared; get() only clones the handle (immutable).
|
||||
assert!(Arc::strong_count(&from_orig) >= 3);
|
||||
}
|
||||
|
||||
@@ -176,21 +169,12 @@ fn clone_extension_map_is_independent_after_remove() {
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Per-concept client/SDK-side extensions.
|
||||
//
|
||||
// These exist as separate extensions (one per concept) rather than a
|
||||
// single bundle. The tests below pin three contracts:
|
||||
//
|
||||
// 1. Each extension round-trips through the typed-extension store
|
||||
// independently of the others.
|
||||
// 2. A dispatcher with only some of the concepts can install them
|
||||
// individually — installing `Cwd` MUST NOT make `BehaviorVersion`
|
||||
// look "present" with a default value, and vice versa.
|
||||
// 3. Absence of every well-known extension is the legitimate "backend
|
||||
// dispatcher" shape; tools that require one MUST treat absence as
|
||||
// a hard error rather than fall back to a process-wide default.
|
||||
// ---------------------------------------------------------------------------
|
||||
// Per-concept client/SDK-side extensions (one type per concept, not a bundle).
|
||||
// Pins three contracts:
|
||||
// 1. Each extension round-trips independently.
|
||||
// 2. Installing one MUST NOT make another look "present" with a default.
|
||||
// 3. Absence is the legitimate backend-dispatcher shape; tools that need
|
||||
// an extension MUST treat absence as a hard error.
|
||||
|
||||
#[test]
|
||||
fn each_well_known_extension_round_trips_independently() {
|
||||
@@ -217,9 +201,7 @@ fn each_well_known_extension_round_trips_independently() {
|
||||
|
||||
#[test]
|
||||
fn dispatcher_can_install_only_what_it_has() {
|
||||
// A dispatcher that knows the cwd but not the trace context installs
|
||||
// only `Cwd`. The other extensions stay absent (not "default"),
|
||||
// which is the discriminator a tool can rely on.
|
||||
// Only Cwd installed — other extensions stay absent (not defaulted).
|
||||
let mut ctx = ToolCallContext::default();
|
||||
ctx.extensions
|
||||
.insert(Cwd(std::path::PathBuf::from("/work")));
|
||||
@@ -229,8 +211,7 @@ fn dispatcher_can_install_only_what_it_has() {
|
||||
assert!(!ctx.extensions.contains::<TraceContext>());
|
||||
assert_eq!(ctx.extensions.len(), 1);
|
||||
|
||||
// Adding `TraceContext` later does not implicitly conjure a
|
||||
// `BehaviorVersion` — extensions are independent.
|
||||
// Installing TraceContext does not conjure BehaviorVersion.
|
||||
ctx.extensions.insert(TraceContext("tp".into()));
|
||||
assert!(ctx.extensions.contains::<TraceContext>());
|
||||
assert!(!ctx.extensions.contains::<BehaviorVersion>());
|
||||
@@ -239,9 +220,7 @@ fn dispatcher_can_install_only_what_it_has() {
|
||||
|
||||
#[test]
|
||||
fn absence_signals_backend_or_other_mode() {
|
||||
// A backend dispatcher installs none of the client-side extensions.
|
||||
// Tools that require any of them must treat absence as a hard error
|
||||
// — this test pins the contract.
|
||||
// Backend dispatcher: no client-side extensions present.
|
||||
let ctx = ToolCallContext::default();
|
||||
assert!(ctx.extensions.get::<Cwd>().is_none());
|
||||
assert!(ctx.extensions.get::<BehaviorVersion>().is_none());
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! `From<ToolError> for ToolErrorWire` coverage for the struct-based ToolError.
|
||||
//! `From<ToolError> for ToolErrorWire` coverage.
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
|
||||
@@ -390,7 +390,6 @@ fn noop_handle_does_not_panic_or_record() {
|
||||
handle.send_lsp_ready(LspServerReady {
|
||||
server_name: "x".into(),
|
||||
});
|
||||
// No assertion needed — the handle drops sends silently.
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -93,10 +93,8 @@ fn tool_index_wrapper_clones_arc() {
|
||||
});
|
||||
let wrapped = ToolIndex(inner.clone());
|
||||
let copy = wrapped.clone();
|
||||
// Both wrappers hold the same Arc — strong-count includes both
|
||||
// wrappers and the original `inner` binding.
|
||||
// Both wrappers share the Arc with `inner`.
|
||||
assert!(Arc::strong_count(&inner) >= 3);
|
||||
// Debug impl renders without leaking the inner type.
|
||||
let debug = format!("{wrapped:?}");
|
||||
assert_eq!(debug, "ToolIndex");
|
||||
drop(copy);
|
||||
|
||||
@@ -77,8 +77,6 @@ impl Tool for NeedsAttachmentTool {
|
||||
}
|
||||
}
|
||||
|
||||
// Tool::should_list (typed)
|
||||
|
||||
#[test]
|
||||
fn default_returns_true() {
|
||||
assert!(Tool::should_list(&AlwaysTool, &ListToolsContext::default()));
|
||||
@@ -109,8 +107,6 @@ fn reads_custom_extension() {
|
||||
assert!(Tool::should_list(&tool, &some));
|
||||
}
|
||||
|
||||
// ToolDyn blanket forwarding
|
||||
|
||||
#[test]
|
||||
fn dyn_forwards_default() {
|
||||
let tool: ArcTool = Arc::new(AlwaysTool);
|
||||
@@ -136,8 +132,6 @@ fn arc_dyn_callable() {
|
||||
assert!(tool.should_list(&ctx));
|
||||
}
|
||||
|
||||
// ListToolsContext
|
||||
|
||||
#[test]
|
||||
fn list_ctx_default_is_empty() {
|
||||
let ctx = ListToolsContext::default();
|
||||
@@ -164,8 +158,6 @@ fn list_ctx_clone_is_independent() {
|
||||
assert!(!copy.extensions.contains::<AttachmentCount>());
|
||||
}
|
||||
|
||||
// TypedExtensions standalone
|
||||
|
||||
#[test]
|
||||
fn typed_extensions_insert_get_remove() {
|
||||
let mut ext = kigi_tool_runtime::TypedExtensions::new();
|
||||
|
||||
@@ -151,8 +151,7 @@ async fn unimplemented_tool_returns_not_implemented_terminal() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn run_takes_args_by_value() {
|
||||
// The trait `run` consumes args; this would not compile if the
|
||||
// signature accidentally borrowed.
|
||||
// run consumes args (would not compile if the signature borrowed).
|
||||
let tool = BlockingOk;
|
||||
let args = EchoArgs {
|
||||
text: "consumed".into(),
|
||||
@@ -163,7 +162,6 @@ async fn run_takes_args_by_value() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn execute_default_drains_in_one_pass() {
|
||||
// A stream from the default impl should always have exactly one item.
|
||||
let tool = BlockingOk;
|
||||
let count = tool
|
||||
.execute(ToolCallContext::default(), EchoArgs { text: "n".into() })
|
||||
|
||||
@@ -130,7 +130,7 @@ impl Tool for UnencodableTool {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Tool with custom ToolOutput (non-empty) ──────────────────
|
||||
// Tool with custom ToolOutput (non-empty)
|
||||
|
||||
/// Output that provides its own model-facing content blocks. The blanket
|
||||
/// impl must forward these as-is rather than filling in the JSON fallback.
|
||||
@@ -201,7 +201,6 @@ async fn tool_dyn_preserves_custom_model_output() {
|
||||
{"type": "image", "mime_type": "image/png", "data": "base64data"},
|
||||
]})
|
||||
);
|
||||
// Custom model output preserved verbatim — no JSON fallback.
|
||||
assert_eq!(typed.model_output.len(), 2);
|
||||
assert_eq!(
|
||||
typed.model_output[0],
|
||||
@@ -238,8 +237,7 @@ async fn tool_dyn_blanket_encodes_terminal_output() {
|
||||
ToolStreamItem::Terminal(Ok(typed)) => {
|
||||
assert_eq!(typed.tool_id, tid("blocking_echo"));
|
||||
assert_eq!(typed.value, json!({"text": "hi"}));
|
||||
// EchoOutput uses the default ToolOutput which
|
||||
// serialises self to a JSON text block (MCP-compliant).
|
||||
// Default ToolOutput serialises self to a JSON text block (MCP).
|
||||
assert_eq!(typed.model_output.len(), 1);
|
||||
assert_eq!(
|
||||
typed.model_output[0],
|
||||
@@ -283,7 +281,7 @@ async fn tool_dyn_blanket_passes_progress_through() {
|
||||
#[tokio::test]
|
||||
async fn tool_dyn_invalid_args_become_invalid_arguments_terminal() {
|
||||
let tool: ArcTool = Arc::new(BlockingEcho);
|
||||
// `text` is required and must be a string — `null` fails serde.
|
||||
// `text` is required and must be a string.
|
||||
let mut stream = tool
|
||||
.execute(ToolCallContext::default(), json!({"text": null}))
|
||||
.await;
|
||||
@@ -314,9 +312,7 @@ async fn tool_dyn_unencodable_output_becomes_execution_terminal() {
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ToolFamily
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Backend-flavoured echo. Two variants share the `echo` tool id and only
|
||||
/// differ in the prefix attached to the output text — enough to assert
|
||||
@@ -437,9 +433,7 @@ async fn tool_family_default_variant_name_defaults_to_none() {
|
||||
assert!(family.default_variant_name().is_none());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Object safety / ergonomic checks
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[test]
|
||||
fn tool_dyn_is_object_safe_in_arc_and_box() {
|
||||
@@ -455,8 +449,7 @@ fn tool_family_is_object_safe_in_arc_and_box() {
|
||||
|
||||
#[test]
|
||||
fn arc_tool_alias_holds_heterogeneous_tools() {
|
||||
// The whole point of `ArcTool` — many typed `Tool` impls collapse
|
||||
// into one container shape via the blanket impl.
|
||||
// ArcTool: many typed Tool impls collapse into one container via the blanket.
|
||||
let tools: Vec<ArcTool> = vec![Arc::new(BlockingEcho), Arc::new(StreamingEcho)];
|
||||
assert_eq!(tools.len(), 2);
|
||||
let ids: Vec<_> = tools.iter().map(|t| t.id()).collect();
|
||||
@@ -484,8 +477,7 @@ fn _compile_time_blanket_check() {
|
||||
let tool = StreamingEcho;
|
||||
_accepts_dyn(&tool);
|
||||
|
||||
// The trait objects themselves must be `Send + Sync` so they can be
|
||||
// shared across tasks without further bounds at the call site.
|
||||
// Trait objects are Send + Sync for sharing across tasks.
|
||||
fn _is_send_sync<T: Send + Sync + ?Sized>() {}
|
||||
_is_send_sync::<dyn ToolDyn>();
|
||||
_is_send_sync::<dyn ToolFamily>();
|
||||
|
||||
@@ -150,7 +150,6 @@ async fn streaming_err_propagates_through_terminal() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn streaming_progress_count_is_independent_of_args() {
|
||||
// Distinct invocations on the same tool produce the same shape.
|
||||
let tool = StreamingOk;
|
||||
for _ in 0..3 {
|
||||
let count = tool
|
||||
@@ -164,8 +163,7 @@ async fn streaming_progress_count_is_independent_of_args() {
|
||||
|
||||
#[tokio::test]
|
||||
async fn empty_progress_still_yields_terminal() {
|
||||
// Building `with_progress` on an empty stream still produces exactly
|
||||
// one terminal item — the same shape `terminal_only` produces.
|
||||
// Empty progress stream still yields exactly one terminal item.
|
||||
let progress = stream::iter(Vec::<ToolProgress>::new());
|
||||
let mut stream = with_progress(progress, async move { Ok::<u32, ToolError>(99) });
|
||||
let item = stream.next().await.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user