From d7107ed58324bcb20d79096b4971988231f7f8a9 Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Thu, 8 Oct 2026 00:55:02 -0700 Subject: [PATCH 01/10] feat: accept detailed token usage from adapters Adapters can observe cache-write input, reasoning output, the largest single request, and per-model usage, but AgentUsage had no fields for them, so adapters either dropped the data or hid it in extensions. Add cache_write_input_tokens, reasoning_tokens, output_tokens_include_reasoning, peak_request_input_tokens, and a closed AgentModelUsage list to AgentUsage. input_tokens_include_cache now also covers cache-write input. Core validates per-model entries: non-blank model and provider, each provider and model pair once compared case-insensitively, and a finite non-negative cost_usd. RunUsage and run_usage() are unchanged, so consumers do not see the new fields yet. The RunUsage cache flag description now says it can cover cache-write input that RunUsage does not report. The adapter-contract and SDK JSON schemas are regenerated. Signed-off-by: mnajafian-nv --- crates/fabric-core/src/agent_execution.rs | 360 +++++++++++++++++- crates/fabric-core/src/lib.rs | 4 +- crates/fabric-core/src/runtime.rs | 65 +++- crates/fabric-core/src/schema.rs | 61 ++- .../agent-run-result.schema.json | 164 +++++++- schemas/sdk/run-result.schema.json | 2 +- 6 files changed, 643 insertions(+), 13 deletions(-) diff --git a/crates/fabric-core/src/agent_execution.rs b/crates/fabric-core/src/agent_execution.rs index 49fd3a15c..d70526243 100644 --- a/crates/fabric-core/src/agent_execution.rs +++ b/crates/fabric-core/src/agent_execution.rs @@ -3,7 +3,7 @@ //! Request and result structures exchanged with an adapter target. -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; use std::path::{Component, Path, PathBuf}; use schemars::{JsonSchema, Schema, SchemaGenerator}; @@ -94,26 +94,104 @@ pub struct AgentUsage { #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(max = u64::MAX))] pub cached_input_tokens: Option, - /// Whether input_tokens already includes cached_input_tokens; absent means unknown. + /// Input tokens written to the provider prompt cache, when reported. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub cache_write_input_tokens: Option, + /// Whether input_tokens already includes cached_input_tokens and + /// cache_write_input_tokens; absent means unknown. #[serde(default, skip_serializing_if = "Option::is_none")] pub input_tokens_include_cache: Option, /// Output tokens produced by the invocation. #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(max = u64::MAX))] pub output_tokens: Option, + /// Reasoning tokens produced by the invocation, when reported. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub reasoning_tokens: Option, + /// Whether output_tokens already includes reasoning_tokens; absent means unknown. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub output_tokens_include_reasoning: Option, /// Total tokens reported by the provider. #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(max = u64::MAX))] pub total_tokens: Option, + /// Input tokens of the largest single model request in the invocation, + /// including cached and cache-write input, when reported. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub peak_request_input_tokens: Option, /// Invocation cost in US dollars when reported by the provider. #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(min = 0.0))] pub cost_usd: Option, + /// Usage broken out by the model that served the requests; empty when not + /// reported. Each provider and model pair appears at most once, compared + /// case-insensitively. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub models: Vec, /// Adapter-owned usage fields. #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub extensions: BTreeMap, } +/// Usage of one model within one invocation. +/// +/// Token fields have the same meaning as the matching `AgentUsage` fields, +/// restricted to requests served by this model. +#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema)] +#[serde(deny_unknown_fields)] +pub struct AgentModelUsage { + /// Model identifier as reported by the harness or provider response. + #[schemars(length(min = 1), regex(pattern = r"\S"))] + pub model: String, + /// Provider or route that served the model, when known. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(length(min = 1), regex(pattern = r"\S"))] + pub provider: Option, + /// Input tokens consumed by this model. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub input_tokens: Option, + /// Cached input tokens consumed by this model, when reported. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub cached_input_tokens: Option, + /// Input tokens this model wrote to the provider prompt cache, when reported. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub cache_write_input_tokens: Option, + /// Whether input_tokens already includes cached_input_tokens and + /// cache_write_input_tokens; absent means unknown. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub input_tokens_include_cache: Option, + /// Output tokens produced by this model. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub output_tokens: Option, + /// Reasoning tokens produced by this model, when reported. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub reasoning_tokens: Option, + /// Whether output_tokens already includes reasoning_tokens; absent means unknown. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub output_tokens_include_reasoning: Option, + /// Total tokens reported by the provider for this model. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub total_tokens: Option, + /// Input tokens of the largest single request served by this model, + /// including cached and cache-write input, when reported. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(max = u64::MAX))] + pub peak_request_input_tokens: Option, + /// Cost in US dollars for this model when reported by the provider. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[schemars(range(min = 0.0))] + pub cost_usd: Option, +} + /// Southbound terminal result returned by an adapter target. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(deny_unknown_fields)] @@ -152,10 +230,16 @@ pub enum AgentRunResultValidationError { /// An artifact path was blank, absolute, or contained parent traversal. #[error("artifact path must be non-blank and relative, and contain no parent traversal: {0}")] InvalidArtifactPath(PathBuf), + /// Model usage repeated a provider and model pair, compared case-insensitively. + #[error("usage.models must report each provider and model pair once: {0}")] + DuplicateModelUsage(String), + /// A cost was negative or not a finite number. + #[error("{0} must be a finite number greater than or equal to 0")] + InvalidCost(&'static str), } impl AgentRunResult { - /// Validate terminal status, error, and artifact invariants. + /// Validate terminal status, error, usage, and artifact invariants. pub fn validate(&self) -> std::result::Result<(), AgentRunResultValidationError> { match (self.status, self.error.as_ref()) { (AgentRunStatus::Failed, None) => { @@ -170,6 +254,9 @@ impl AgentRunResult { validate_nonblank(&error.code, "error.code")?; validate_nonblank(&error.message, "error.message")?; } + if let Some(usage) = &self.usage { + validate_model_usage(&usage.models)?; + } for artifact in &self.artifacts { validate_nonblank(&artifact.name, "artifacts.name")?; validate_nonblank(&artifact.kind, "artifacts.kind")?; @@ -186,6 +273,46 @@ impl AgentRunResult { } } +fn validate_model_usage( + models: &[AgentModelUsage], +) -> std::result::Result<(), AgentRunResultValidationError> { + let mut reported = HashSet::with_capacity(models.len()); + for model_usage in models { + validate_nonblank(&model_usage.model, "usage.models.model")?; + if let Some(provider) = &model_usage.provider { + validate_nonblank(provider, "usage.models.provider")?; + } + if let Some(cost_usd) = model_usage.cost_usd { + validate_cost(cost_usd, "usage.models.cost_usd")?; + } + let key = ( + model_usage.provider.as_deref().map(str::to_lowercase), + model_usage.model.to_lowercase(), + ); + if !reported.insert(key) { + let duplicate = match &model_usage.provider { + Some(provider) => format!("provider {provider:?}, model {:?}", model_usage.model), + None => format!("model {:?}", model_usage.model), + }; + return Err(AgentRunResultValidationError::DuplicateModelUsage( + duplicate, + )); + } + } + Ok(()) +} + +fn validate_cost( + cost_usd: f64, + field: &'static str, +) -> std::result::Result<(), AgentRunResultValidationError> { + if cost_usd.is_finite() && cost_usd >= 0.0 { + Ok(()) + } else { + Err(AgentRunResultValidationError::InvalidCost(field)) + } +} + fn validate_nonblank( value: &str, field: &'static str, @@ -436,4 +563,231 @@ mod tests { ); } } + + fn result_with_usage(usage: Value) -> AgentRunResult { + serde_json::from_value(serde_json::json!({ + "status": "succeeded", + "output": null, + "usage": usage + })) + .expect("usage payload deserializes") + } + + fn model_usage(provider: Option<&str>, model: &str) -> AgentModelUsage { + AgentModelUsage { + model: model.to_string(), + provider: provider.map(str::to_string), + ..AgentModelUsage::default() + } + } + + fn result_with_models(models: Vec) -> AgentRunResult { + AgentRunResult { + status: AgentRunStatus::Succeeded, + output: Value::Null, + error: None, + usage: Some(AgentUsage { + models, + ..AgentUsage::default() + }), + artifacts: Vec::new(), + extensions: BTreeMap::new(), + } + } + + #[test] + fn detailed_usage_round_trips_every_field() { + let payload = serde_json::json!({ + "input_tokens": 1200, + "cached_input_tokens": 800, + "cache_write_input_tokens": 300, + "input_tokens_include_cache": true, + "output_tokens": 90, + "reasoning_tokens": 40, + "output_tokens_include_reasoning": false, + "total_tokens": 1330, + "peak_request_input_tokens": 700, + "cost_usd": 0.5, + "models": [{ + "model": "planner-model", + "provider": "openai", + "input_tokens": 1000, + "cached_input_tokens": 700, + "cache_write_input_tokens": 250, + "input_tokens_include_cache": true, + "output_tokens": 60, + "reasoning_tokens": 30, + "output_tokens_include_reasoning": true, + "total_tokens": 1060, + "peak_request_input_tokens": 600, + "cost_usd": 0.375 + }, { + "model": "summarizer-model" + }], + "extensions": {"source": "native"} + }); + + let usage: AgentUsage = + serde_json::from_value(payload.clone()).expect("detailed usage deserializes"); + + assert_eq!( + usage, + AgentUsage { + input_tokens: Some(1200), + cached_input_tokens: Some(800), + cache_write_input_tokens: Some(300), + input_tokens_include_cache: Some(true), + output_tokens: Some(90), + reasoning_tokens: Some(40), + output_tokens_include_reasoning: Some(false), + total_tokens: Some(1330), + peak_request_input_tokens: Some(700), + cost_usd: Some(0.5), + models: vec![ + AgentModelUsage { + model: "planner-model".to_string(), + provider: Some("openai".to_string()), + input_tokens: Some(1000), + cached_input_tokens: Some(700), + cache_write_input_tokens: Some(250), + input_tokens_include_cache: Some(true), + output_tokens: Some(60), + reasoning_tokens: Some(30), + output_tokens_include_reasoning: Some(true), + total_tokens: Some(1060), + peak_request_input_tokens: Some(600), + cost_usd: Some(0.375), + }, + model_usage(None, "summarizer-model"), + ], + extensions: BTreeMap::from([("source".to_string(), serde_json::json!("native"),)]), + } + ); + assert_eq!( + serde_json::to_value(&usage).expect("serialize usage"), + payload + ); + assert_eq!(result_with_usage(payload).validate(), Ok(())); + } + + #[test] + fn usage_without_detailed_fields_keeps_its_wire_shape() { + let payload = serde_json::json!({ + "input_tokens": 3, + "cached_input_tokens": 1, + "input_tokens_include_cache": true, + "output_tokens": 5, + "total_tokens": 8, + "cost_usd": 0.25 + }); + + let result = result_with_usage(payload.clone()); + + assert_eq!(result.validate(), Ok(())); + let usage = result.usage.expect("usage"); + assert!(usage.models.is_empty()); + assert_eq!( + serde_json::to_value(&usage).expect("serialize usage"), + payload + ); + } + + #[test] + fn model_usage_rejects_unknown_fields() { + for field in ["reasoning", "extensions"] { + let error = serde_json::from_value::(serde_json::json!({ + "models": [{"model": "planner-model", field: {}}] + })) + .expect_err("model usage is a closed object"); + + assert!( + error + .to_string() + .contains(&format!("unknown field `{field}`")), + "{error}" + ); + } + } + + #[test] + fn rejects_blank_model_usage_identifiers() { + for (models, field) in [ + (vec![model_usage(None, " \t")], "usage.models.model"), + ( + vec![model_usage(Some(" \t"), "planner-model")], + "usage.models.provider", + ), + ] { + assert_eq!( + result_with_models(models).validate(), + Err(AgentRunResultValidationError::BlankField(field)) + ); + } + } + + #[test] + fn rejects_duplicate_model_usage_case_insensitively() { + for (models, duplicate) in [ + ( + vec![ + model_usage(None, "planner-model"), + model_usage(None, "Planner-Model"), + ], + r#"model "Planner-Model""#, + ), + ( + vec![ + model_usage(Some("openai"), "planner-model"), + model_usage(Some("OpenAI"), "PLANNER-MODEL"), + ], + r#"provider "OpenAI", model "PLANNER-MODEL""#, + ), + ] { + assert_eq!( + result_with_models(models).validate(), + Err(AgentRunResultValidationError::DuplicateModelUsage( + duplicate.to_string() + )) + ); + } + } + + #[test] + fn rejects_negative_or_non_finite_model_usage_cost() { + for cost_usd in [-0.01, f64::NAN, f64::INFINITY, f64::NEG_INFINITY] { + let models = vec![AgentModelUsage { + cost_usd: Some(cost_usd), + ..model_usage(None, "planner-model") + }]; + + assert_eq!( + result_with_models(models).validate(), + Err(AgentRunResultValidationError::InvalidCost( + "usage.models.cost_usd" + )), + "cost_usd {cost_usd}" + ); + } + } + + #[test] + fn accepts_zero_model_usage_cost() { + let models = vec![AgentModelUsage { + cost_usd: Some(0.0), + ..model_usage(None, "planner-model") + }]; + + assert_eq!(result_with_models(models).validate(), Ok(())); + } + + #[test] + fn accepts_one_model_served_by_distinct_providers() { + let result = result_with_models(vec![ + model_usage(None, "planner-model"), + model_usage(Some("openai"), "planner-model"), + model_usage(Some("azure"), "planner-model"), + ]); + + assert_eq!(result.validate(), Ok(())); + } } diff --git a/crates/fabric-core/src/lib.rs b/crates/fabric-core/src/lib.rs index 2dc251c9f..96217af11 100644 --- a/crates/fabric-core/src/lib.rs +++ b/crates/fabric-core/src/lib.rs @@ -14,8 +14,8 @@ pub mod schema; pub use adapter_contract::{ADAPTER_CONTRACT_VERSION, AdapterExtensionPoint}; pub use agent_execution::{ - AgentArtifact, AgentRunError, AgentRunRequest, AgentRunResult, AgentRunResultValidationError, - AgentRunStatus, AgentUsage, + AgentArtifact, AgentModelUsage, AgentRunError, AgentRunRequest, AgentRunResult, + AgentRunResultValidationError, AgentRunStatus, AgentUsage, }; pub use config::{ AdapterConfigField, AdapterConfigSupport, AdapterDescriptor, AdapterInspection, AdapterKind, diff --git a/crates/fabric-core/src/runtime.rs b/crates/fabric-core/src/runtime.rs index d895470ef..880d23c41 100644 --- a/crates/fabric-core/src/runtime.rs +++ b/crates/fabric-core/src/runtime.rs @@ -186,7 +186,10 @@ pub struct RunUsage { /// Cached input tokens consumed by the invocation, when reported. #[serde(default, skip_serializing_if = "Option::is_none")] pub cached_input_tokens: Option, - /// Whether input_tokens already includes cached_input_tokens; absent means unknown. + /// Whether input_tokens already includes cached_input_tokens and any + /// cache-write input tokens the adapter reported; absent means unknown. + /// RunUsage does not report cache-write input tokens, so input_tokens plus + /// cached_input_tokens can understate total input when this is false. #[serde(default, skip_serializing_if = "Option::is_none")] pub input_tokens_include_cache: Option, /// Output tokens produced by the invocation. @@ -3653,6 +3656,30 @@ for line in sys.stdin: }], "extensions": {"trace_id": "trace-1"}, } + elif MODE == "detailed_usage_result": + result = { + "status": "succeeded", + "output": output, + "usage": { + "input_tokens": 3, + "cached_input_tokens": 1, + "cache_write_input_tokens": 2, + "input_tokens_include_cache": True, + "output_tokens": 5, + "reasoning_tokens": 4, + "output_tokens_include_reasoning": True, + "total_tokens": 8, + "peak_request_input_tokens": 3, + "cost_usd": 0.25, + "models": [{ + "model": "test-model", + "provider": "fake", + "input_tokens": 3, + "reasoning_tokens": 4, + }], + "extensions": {"provider": "fake"}, + }, + } else: result = {"status": "succeeded", "output": output} response(operation, output=result) @@ -4680,6 +4707,42 @@ for line in sys.stdin: let _ = fs::remove_dir_all(root); } + #[test] + fn local_host_accepts_detailed_usage_without_changing_run_usage() { + let (root, plan) = local_host_plan("detailed_usage_result"); + + let result = run_plan(&plan, RunRequest::text("usage")).expect("normalized result"); + + assert_eq!(result.status, RunStatus::Succeeded); + let usage = result.usage.expect("run usage"); + assert_eq!( + usage, + RunUsage { + input_tokens: Some(3), + cached_input_tokens: Some(1), + input_tokens_include_cache: Some(true), + output_tokens: Some(5), + total_tokens: Some(8), + cost_usd: Some(0.25), + metadata: BTreeMap::from([("provider".to_string(), serde_json::json!("fake"))]), + } + ); + assert_eq!( + serde_json::to_value(&usage).expect("serialize run usage"), + serde_json::json!({ + "input_tokens": 3, + "cached_input_tokens": 1, + "input_tokens_include_cache": true, + "output_tokens": 5, + "total_tokens": 8, + "cost_usd": 0.25, + "metadata": {"provider": "fake"} + }) + ); + + let _ = fs::remove_dir_all(root); + } + #[test] fn local_host_rejects_typed_artifacts_without_runtime_root() { let (root, mut plan) = local_host_plan("typed_result"); diff --git a/crates/fabric-core/src/schema.rs b/crates/fabric-core/src/schema.rs index ee15fda12..acc0c3753 100644 --- a/crates/fabric-core/src/schema.rs +++ b/crates/fabric-core/src/schema.rs @@ -553,11 +553,62 @@ mod tests { ); let result = generate_schema(SchemaName::AgentRunResult).expect("schema generation"); - for field in ["input_tokens", "output_tokens", "total_tokens"] { - assert_eq!( - result["$defs"]["AgentUsage"]["properties"][field]["maximum"], - u64::MAX - ); + for definition in ["AgentUsage", "AgentModelUsage"] { + for field in [ + "input_tokens", + "cached_input_tokens", + "cache_write_input_tokens", + "output_tokens", + "reasoning_tokens", + "total_tokens", + "peak_request_input_tokens", + ] { + assert_eq!( + result["$defs"][definition]["properties"][field]["maximum"], + u64::MAX + ); + } + } + } + + #[test] + fn agent_run_result_schema_matches_model_usage_constraints() { + let schema = generate_schema(SchemaName::AgentRunResult).expect("schema generation"); + let validator = jsonschema::validator_for(&schema).expect("valid result schema"); + let result_with_models = |models: Value| { + serde_json::json!({ + "status": "succeeded", + "output": null, + "usage": {"models": models} + }) + }; + + assert!(validator.is_valid(&serde_json::json!({ + "status": "succeeded", + "output": null, + "usage": { + "cache_write_input_tokens": 2, + "reasoning_tokens": 4, + "output_tokens_include_reasoning": false, + "peak_request_input_tokens": 3, + "models": [{ + "model": "planner-model", + "provider": "openai", + "reasoning_tokens": 4, + "cost_usd": 0.5 + }] + } + }))); + for models in [ + serde_json::json!([{}]), + serde_json::json!([{"model": " \t"}]), + serde_json::json!([{"model": "planner-model", "provider": " \t"}]), + serde_json::json!([{"model": "planner-model", "cost_usd": -1.0}]), + serde_json::json!([{"model": "planner-model", "reasoning_tokens": -1}]), + serde_json::json!([{"model": "planner-model", "reasoning": 1}]), + serde_json::json!([{"model": "planner-model", "extensions": {}}]), + ] { + assert!(!validator.is_valid(&result_with_models(models))); } } diff --git a/schemas/adapter-contract/agent-run-result.schema.json b/schemas/adapter-contract/agent-run-result.schema.json index ee1c450c4..0fa80398a 100644 --- a/schemas/adapter-contract/agent-run-result.schema.json +++ b/schemas/adapter-contract/agent-run-result.schema.json @@ -57,6 +57,124 @@ ], "type": "object" }, + "AgentModelUsage": { + "additionalProperties": false, + "description": "Usage of one model within one invocation.\n\nToken fields have the same meaning as the matching `AgentUsage` fields,\nrestricted to requests served by this model.", + "properties": { + "cache_write_input_tokens": { + "description": "Input tokens this model wrote to the provider prompt cache, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "cached_input_tokens": { + "description": "Cached input tokens consumed by this model, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "cost_usd": { + "description": "Cost in US dollars for this model when reported by the provider.", + "format": "double", + "minimum": 0.0, + "type": [ + "number", + "null" + ] + }, + "input_tokens": { + "description": "Input tokens consumed by this model.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "input_tokens_include_cache": { + "description": "Whether input_tokens already includes cached_input_tokens and\ncache_write_input_tokens; absent means unknown.", + "type": [ + "boolean", + "null" + ] + }, + "model": { + "description": "Model identifier as reported by the harness or provider response.", + "minLength": 1, + "pattern": "\\S", + "type": "string" + }, + "output_tokens": { + "description": "Output tokens produced by this model.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "output_tokens_include_reasoning": { + "description": "Whether output_tokens already includes reasoning_tokens; absent means unknown.", + "type": [ + "boolean", + "null" + ] + }, + "peak_request_input_tokens": { + "description": "Input tokens of the largest single request served by this model,\nincluding cached and cache-write input, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "provider": { + "description": "Provider or route that served the model, when known.", + "minLength": 1, + "pattern": "\\S", + "type": [ + "string", + "null" + ] + }, + "reasoning_tokens": { + "description": "Reasoning tokens produced by this model, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "total_tokens": { + "description": "Total tokens reported by the provider for this model.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "model" + ], + "type": "object" + }, "AgentRunError": { "additionalProperties": false, "description": "Error reported by an adapter target.", @@ -114,6 +232,16 @@ "additionalProperties": false, "description": "Normalized model usage reported by an adapter target.", "properties": { + "cache_write_input_tokens": { + "description": "Input tokens written to the provider prompt cache, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, "cached_input_tokens": { "description": "Cached input tokens consumed by the invocation, when reported.", "format": "uint64", @@ -149,12 +277,19 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes cached_input_tokens; absent means unknown.", + "description": "Whether input_tokens already includes cached_input_tokens and\ncache_write_input_tokens; absent means unknown.", "type": [ "boolean", "null" ] }, + "models": { + "description": "Usage broken out by the model that served the requests; empty when not\nreported. Each provider and model pair appears at most once, compared\ncase-insensitively.", + "items": { + "$ref": "#/$defs/AgentModelUsage" + }, + "type": "array" + }, "output_tokens": { "description": "Output tokens produced by the invocation.", "format": "uint64", @@ -165,6 +300,33 @@ "null" ] }, + "output_tokens_include_reasoning": { + "description": "Whether output_tokens already includes reasoning_tokens; absent means unknown.", + "type": [ + "boolean", + "null" + ] + }, + "peak_request_input_tokens": { + "description": "Input tokens of the largest single model request in the invocation,\nincluding cached and cache-write input, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "reasoning_tokens": { + "description": "Reasoning tokens produced by the invocation, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, "total_tokens": { "description": "Total tokens reported by the provider.", "format": "uint64", diff --git a/schemas/sdk/run-result.schema.json b/schemas/sdk/run-result.schema.json index 034c17e82..32d7528af 100644 --- a/schemas/sdk/run-result.schema.json +++ b/schemas/sdk/run-result.schema.json @@ -247,7 +247,7 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes cached_input_tokens; absent means unknown.", + "description": "Whether input_tokens already includes cached_input_tokens and any\ncache-write input tokens the adapter reported; absent means unknown.\nRunUsage does not report cache-write input tokens, so input_tokens plus\ncached_input_tokens can understate total input when this is false.", "type": [ "boolean", "null" From 8c256630382027deb9d2c6c102d087d892fe7572 Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Thu, 8 Oct 2026 00:55:13 -0700 Subject: [PATCH 02/10] feat: add detailed token usage to the Python adapter contract Python adapters build AgentUsage through the Python contract, which must accept the same fields and enforce the same rules as core so an invalid result fails in the adapter instead of at the core boundary. Add the new AgentUsage fields and AgentModelUsage with the same counter bounds, non-blank identifiers, case-insensitive duplicate check, and non-negative finite cost as core, with tests. Update the SDK RunUsage docstring for the wider meaning of the cache flag. Signed-off-by: mnajafian-nv --- .../nemo_fabric_adapter_contract/models.py | 81 +++++++++- .../src/nemo_fabric/types.py | 5 +- .../adapter_contract/test_agent_execution.py | 146 +++++++++++++++++- 3 files changed, 222 insertions(+), 10 deletions(-) diff --git a/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py b/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py index 1f82b1658..8f539e48d 100644 --- a/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py +++ b/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py @@ -499,26 +499,91 @@ def _validate(self) -> None: _nonblank(self.media_type, "media_type") +_USAGE_TOKEN_FIELDS = ( + "input_tokens", + "cached_input_tokens", + "cache_write_input_tokens", + "output_tokens", + "reasoning_tokens", + "total_tokens", + "peak_request_input_tokens", +) + + +def _validate_usage_counts(usage: AgentUsage | AgentModelUsage) -> None: + for field_name in _USAGE_TOKEN_FIELDS: + _bounded_int(getattr(usage, field_name), field_name, (1 << 64) - 1) + if usage.cost_usd is not None and usage.cost_usd < 0: + raise ContractValidationError( + "must be greater than or equal to 0", path=("cost_usd",) + ) + + @dataclass(slots=True, kw_only=True) -class AgentUsage(AgentContractBlock): - """Normalized model usage reported by an adapter target.""" +class AgentModelUsage(ContractModel): + """Usage of one model within one invocation. + + Token fields have the same meaning as the matching ``AgentUsage`` fields, + restricted to requests served by this model. + """ + model: str + provider: str | None = _optional() input_tokens: int | None = _optional() cached_input_tokens: int | None = _optional() + cache_write_input_tokens: int | None = _optional() input_tokens_include_cache: bool | None = _optional() output_tokens: int | None = _optional() + reasoning_tokens: int | None = _optional() + output_tokens_include_reasoning: bool | None = _optional() total_tokens: int | None = _optional() + peak_request_input_tokens: int | None = _optional() cost_usd: float | None = _optional() def _validate(self) -> None: - _bounded_int(self.input_tokens, "input_tokens", (1 << 64) - 1) - _bounded_int(self.cached_input_tokens, "cached_input_tokens", (1 << 64) - 1) - _bounded_int(self.output_tokens, "output_tokens", (1 << 64) - 1) - _bounded_int(self.total_tokens, "total_tokens", (1 << 64) - 1) - if self.cost_usd is not None and self.cost_usd < 0: + _nonblank(self.model, "model") + if self.provider is not None: + _nonblank(self.provider, "provider") + _validate_usage_counts(self) + + +def _validate_unique_models(models: list[AgentModelUsage]) -> None: + reported: set[tuple[str | None, str]] = set() + for index, usage in enumerate(models): + provider = usage.provider.lower() if usage.provider is not None else None + key = (provider, usage.model.lower()) + if key in reported: raise ContractValidationError( - "must be greater than or equal to 0", path=("cost_usd",) + "must report each provider and model pair once", + path=("models", str(index)), ) + reported.add(key) + + +@dataclass(slots=True, kw_only=True) +class AgentUsage(AgentContractBlock): + """Normalized model usage reported by an adapter target. + + ``input_tokens_include_cache`` covers both ``cached_input_tokens`` and + ``cache_write_input_tokens``. ``models`` reports each provider and model + pair at most once, compared case-insensitively. + """ + + input_tokens: int | None = _optional() + cached_input_tokens: int | None = _optional() + cache_write_input_tokens: int | None = _optional() + input_tokens_include_cache: bool | None = _optional() + output_tokens: int | None = _optional() + reasoning_tokens: int | None = _optional() + output_tokens_include_reasoning: bool | None = _optional() + total_tokens: int | None = _optional() + peak_request_input_tokens: int | None = _optional() + cost_usd: float | None = _optional() + models: list[AgentModelUsage] = _empty_list() + + def _validate(self) -> None: + _validate_usage_counts(self) + _validate_unique_models(self.models) @dataclass(slots=True, kw_only=True) diff --git a/sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py b/sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py index f0f14ae0d..25a08873f 100644 --- a/sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py +++ b/sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py @@ -1773,7 +1773,10 @@ class RunUsage(FabricMapping): Missing counters and cost are unknown, not zero. ``cached_input_tokens`` records cache usage; ``input_tokens_include_cache`` declares whether input - already includes that count. An absent flag means the semantics are unknown. + already includes that count and any cache-write input the adapter reported. + An absent flag means the semantics are unknown. Cache-write input is not + reported here, so when the flag is ``False``, input plus cached input can + understate total input. """ input_tokens: int | None diff --git a/tests/adapter_contract/test_agent_execution.py b/tests/adapter_contract/test_agent_execution.py index 756fce3b8..69f5da802 100644 --- a/tests/adapter_contract/test_agent_execution.py +++ b/tests/adapter_contract/test_agent_execution.py @@ -12,6 +12,7 @@ import pytest from nemo_fabric_adapter_contract.models import AgentArtifact +from nemo_fabric_adapter_contract.models import AgentModelUsage from nemo_fabric_adapter_contract.models import AgentRunError from nemo_fabric_adapter_contract.models import AgentRunRequest from nemo_fabric_adapter_contract.models import AgentRunResult @@ -54,6 +55,149 @@ def test_usage_rejects_invalid_cache_semantics(value): AgentUsage(input_tokens_include_cache=value) +DETAILED_USAGE = { + "input_tokens": 1200, + "cached_input_tokens": 800, + "cache_write_input_tokens": 300, + "input_tokens_include_cache": True, + "output_tokens": 90, + "reasoning_tokens": 40, + "output_tokens_include_reasoning": False, + "total_tokens": 1330, + "peak_request_input_tokens": 700, + "cost_usd": 0.5, + "models": [ + { + "model": "planner-model", + "provider": "openai", + "input_tokens": 1000, + "cached_input_tokens": 700, + "cache_write_input_tokens": 250, + "input_tokens_include_cache": True, + "output_tokens": 60, + "reasoning_tokens": 30, + "output_tokens_include_reasoning": True, + "total_tokens": 1060, + "peak_request_input_tokens": 600, + "cost_usd": 0.375, + }, + {"model": "summarizer-model"}, + ], + "extensions": {"source": "native"}, +} + + +def test_usage_detailed_fields_round_trip(): + usage = AgentUsage.from_mapping(DETAILED_USAGE) + + assert usage.models[0] == AgentModelUsage( + model="planner-model", + provider="openai", + input_tokens=1000, + cached_input_tokens=700, + cache_write_input_tokens=250, + input_tokens_include_cache=True, + output_tokens=60, + reasoning_tokens=30, + output_tokens_include_reasoning=True, + total_tokens=1060, + peak_request_input_tokens=600, + cost_usd=0.375, + ) + assert usage.to_mapping() == DETAILED_USAGE + assert type_adapter(AgentUsage).validate_python(DETAILED_USAGE) == usage + + +def test_usage_without_detailed_fields_keeps_wire_shape(): + usage = AgentUsage(input_tokens=3, output_tokens=5) + + assert usage.models == [] + assert usage.to_mapping() == {"input_tokens": 3, "output_tokens": 5} + + +@pytest.mark.parametrize( + "field_name", + ["cache_write_input_tokens", "reasoning_tokens", "peak_request_input_tokens"], +) +@pytest.mark.parametrize("model", [AgentUsage, AgentModelUsage]) +@pytest.mark.parametrize("value", [-1, 1 << 64, True, 1.5]) +def test_usage_rejects_invalid_detailed_counter(model, field_name, value): + required = {"model": "planner-model"} if model is AgentModelUsage else {} + with pytest.raises(ContractValidationError): + model(**required, **{field_name: value}) + + +@pytest.mark.parametrize("model", [AgentUsage, AgentModelUsage]) +@pytest.mark.parametrize("value", [0, 1, "true"]) +def test_usage_rejects_invalid_reasoning_semantics(model, value): + required = {"model": "planner-model"} if model is AgentModelUsage else {} + with pytest.raises(ContractValidationError): + model(**required, output_tokens_include_reasoning=value) + + +@pytest.mark.parametrize( + ("mapping", "message"), + [ + ({}, "missing required field 'model'"), + ({"model": " \t"}, "model: must be a non-empty string"), + ( + {"model": "planner-model", "provider": " \t"}, + "provider: must be a non-empty string", + ), + ( + {"model": "planner-model", "cost_usd": -1.0}, + "cost_usd: must be greater than or equal to 0", + ), + ( + {"model": "planner-model", "cost_usd": float("nan")}, + "cost_usd: must be a finite number", + ), + ( + {"model": "planner-model", "cost_usd": float("inf")}, + "cost_usd: must be a finite number", + ), + ({"model": "planner-model", "reasoning": 1}, "unexpected field 'reasoning'"), + ( + {"model": "planner-model", "extensions": {}}, + "unexpected field 'extensions'", + ), + ], +) +def test_model_usage_rejects_invalid_values(mapping, message): + with pytest.raises(ContractValidationError, match=message): + AgentModelUsage.from_mapping(mapping) + + +@pytest.mark.parametrize( + "models", + [ + [{"model": "planner-model"}, {"model": "Planner-Model"}], + [ + {"model": "planner-model", "provider": "openai"}, + {"model": "PLANNER-MODEL", "provider": "OpenAI"}, + ], + ], +) +def test_usage_rejects_duplicate_models_case_insensitively(models): + with pytest.raises( + ContractValidationError, + match="models.1: must report each provider and model pair once", + ): + AgentUsage.from_mapping({"models": models}) + + +def test_usage_accepts_one_model_served_by_distinct_providers(): + usage = AgentUsage( + models=[ + AgentModelUsage(model="planner-model"), + AgentModelUsage(model="planner-model", provider="openai"), + AgentModelUsage(model="planner-model", provider="azure"), + ] + ) + + assert len(usage.models) == 3 + + def test_agent_run_request_contains_only_southbound_request_fields(): request = AgentRunRequest( input={"messages": [{"role": "user", "content": "hello"}]}, @@ -148,7 +292,7 @@ def test_agent_execution_models_track_rust_schema_root_fields(model, filename): [ ( "agent-run-result.schema.json", - (AgentArtifact, AgentRunError, AgentUsage), + (AgentArtifact, AgentModelUsage, AgentRunError, AgentUsage), ), ( "runtime-context.schema.json", From 2e46f459f549a461f7c798bbc8aa9f233e3375e7 Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Thu, 8 Oct 2026 00:55:14 -0700 Subject: [PATCH 03/10] feat: add detailed token usage to the TypeScript adapter contract TypeScript adapters type their results against the generated contract declarations, which must match the regenerated result schema. Copy the regenerated agent-run-result schema, regenerate the declarations with AgentModelUsage and the new AgentUsage fields, and add type tests for the detailed fields, the boolean reasoning flag, the required model identifier, and the closed model usage object. Signed-off-by: mnajafian-nv --- .../schemas/agent-run-result.schema.json | 164 +++++++++++++++++- .../src/generated/agent-run-result.ts | 87 +++++++++- .../typescript/test/stable.test.ts | 31 ++++ 3 files changed, 280 insertions(+), 2 deletions(-) diff --git a/adapter-contract/typescript/schemas/agent-run-result.schema.json b/adapter-contract/typescript/schemas/agent-run-result.schema.json index ee1c450c4..0fa80398a 100644 --- a/adapter-contract/typescript/schemas/agent-run-result.schema.json +++ b/adapter-contract/typescript/schemas/agent-run-result.schema.json @@ -57,6 +57,124 @@ ], "type": "object" }, + "AgentModelUsage": { + "additionalProperties": false, + "description": "Usage of one model within one invocation.\n\nToken fields have the same meaning as the matching `AgentUsage` fields,\nrestricted to requests served by this model.", + "properties": { + "cache_write_input_tokens": { + "description": "Input tokens this model wrote to the provider prompt cache, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "cached_input_tokens": { + "description": "Cached input tokens consumed by this model, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "cost_usd": { + "description": "Cost in US dollars for this model when reported by the provider.", + "format": "double", + "minimum": 0.0, + "type": [ + "number", + "null" + ] + }, + "input_tokens": { + "description": "Input tokens consumed by this model.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "input_tokens_include_cache": { + "description": "Whether input_tokens already includes cached_input_tokens and\ncache_write_input_tokens; absent means unknown.", + "type": [ + "boolean", + "null" + ] + }, + "model": { + "description": "Model identifier as reported by the harness or provider response.", + "minLength": 1, + "pattern": "\\S", + "type": "string" + }, + "output_tokens": { + "description": "Output tokens produced by this model.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "output_tokens_include_reasoning": { + "description": "Whether output_tokens already includes reasoning_tokens; absent means unknown.", + "type": [ + "boolean", + "null" + ] + }, + "peak_request_input_tokens": { + "description": "Input tokens of the largest single request served by this model,\nincluding cached and cache-write input, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "provider": { + "description": "Provider or route that served the model, when known.", + "minLength": 1, + "pattern": "\\S", + "type": [ + "string", + "null" + ] + }, + "reasoning_tokens": { + "description": "Reasoning tokens produced by this model, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "total_tokens": { + "description": "Total tokens reported by the provider for this model.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + } + }, + "required": [ + "model" + ], + "type": "object" + }, "AgentRunError": { "additionalProperties": false, "description": "Error reported by an adapter target.", @@ -114,6 +232,16 @@ "additionalProperties": false, "description": "Normalized model usage reported by an adapter target.", "properties": { + "cache_write_input_tokens": { + "description": "Input tokens written to the provider prompt cache, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, "cached_input_tokens": { "description": "Cached input tokens consumed by the invocation, when reported.", "format": "uint64", @@ -149,12 +277,19 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes cached_input_tokens; absent means unknown.", + "description": "Whether input_tokens already includes cached_input_tokens and\ncache_write_input_tokens; absent means unknown.", "type": [ "boolean", "null" ] }, + "models": { + "description": "Usage broken out by the model that served the requests; empty when not\nreported. Each provider and model pair appears at most once, compared\ncase-insensitively.", + "items": { + "$ref": "#/$defs/AgentModelUsage" + }, + "type": "array" + }, "output_tokens": { "description": "Output tokens produced by the invocation.", "format": "uint64", @@ -165,6 +300,33 @@ "null" ] }, + "output_tokens_include_reasoning": { + "description": "Whether output_tokens already includes reasoning_tokens; absent means unknown.", + "type": [ + "boolean", + "null" + ] + }, + "peak_request_input_tokens": { + "description": "Input tokens of the largest single model request in the invocation,\nincluding cached and cache-write input, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, + "reasoning_tokens": { + "description": "Reasoning tokens produced by the invocation, when reported.", + "format": "uint64", + "maximum": 18446744073709551615, + "minimum": 0, + "type": [ + "integer", + "null" + ] + }, "total_tokens": { "description": "Total tokens reported by the provider.", "format": "uint64", diff --git a/adapter-contract/typescript/src/generated/agent-run-result.ts b/adapter-contract/typescript/src/generated/agent-run-result.ts index 75bb4a597..e0e35941c 100644 --- a/adapter-contract/typescript/src/generated/agent-run-result.ts +++ b/adapter-contract/typescript/src/generated/agent-run-result.ts @@ -86,6 +86,10 @@ export interface AgentArtifact { * via the `definition` "AgentUsage". */ export interface AgentUsage { + /** + * Input tokens written to the provider prompt cache, when reported. + */ + cache_write_input_tokens?: number | null; /** * Cached input tokens consumed by the invocation, when reported. */ @@ -103,18 +107,99 @@ export interface AgentUsage { */ input_tokens?: number | null; /** - * Whether input_tokens already includes cached_input_tokens; absent means unknown. + * Whether input_tokens already includes cached_input_tokens and + * cache_write_input_tokens; absent means unknown. */ input_tokens_include_cache?: boolean | null; + /** + * Usage broken out by the model that served the requests; empty when not + * reported. Each provider and model pair appears at most once, compared + * case-insensitively. + */ + models?: AgentModelUsage[]; /** * Output tokens produced by the invocation. */ output_tokens?: number | null; + /** + * Whether output_tokens already includes reasoning_tokens; absent means unknown. + */ + output_tokens_include_reasoning?: boolean | null; + /** + * Input tokens of the largest single model request in the invocation, + * including cached and cache-write input, when reported. + */ + peak_request_input_tokens?: number | null; + /** + * Reasoning tokens produced by the invocation, when reported. + */ + reasoning_tokens?: number | null; /** * Total tokens reported by the provider. */ total_tokens?: number | null; } +/** + * Usage of one model within one invocation. + * + * Token fields have the same meaning as the matching `AgentUsage` fields, + * restricted to requests served by this model. + * + * This interface was referenced by `AgentRunResultCommon`'s JSON-Schema + * via the `definition` "AgentModelUsage". + */ +export interface AgentModelUsage { + /** + * Input tokens this model wrote to the provider prompt cache, when reported. + */ + cache_write_input_tokens?: number | null; + /** + * Cached input tokens consumed by this model, when reported. + */ + cached_input_tokens?: number | null; + /** + * Cost in US dollars for this model when reported by the provider. + */ + cost_usd?: number | null; + /** + * Input tokens consumed by this model. + */ + input_tokens?: number | null; + /** + * Whether input_tokens already includes cached_input_tokens and + * cache_write_input_tokens; absent means unknown. + */ + input_tokens_include_cache?: boolean | null; + /** + * Model identifier as reported by the harness or provider response. + */ + model: string; + /** + * Output tokens produced by this model. + */ + output_tokens?: number | null; + /** + * Whether output_tokens already includes reasoning_tokens; absent means unknown. + */ + output_tokens_include_reasoning?: boolean | null; + /** + * Input tokens of the largest single request served by this model, + * including cached and cache-write input, when reported. + */ + peak_request_input_tokens?: number | null; + /** + * Provider or route that served the model, when known. + */ + provider?: string | null; + /** + * Reasoning tokens produced by this model, when reported. + */ + reasoning_tokens?: number | null; + /** + * Total tokens reported by the provider for this model. + */ + total_tokens?: number | null; +} /** * Error reported by an adapter target. * diff --git a/adapter-contract/typescript/test/stable.test.ts b/adapter-contract/typescript/test/stable.test.ts index 70e1db53e..defb47c39 100644 --- a/adapter-contract/typescript/test/stable.test.ts +++ b/adapter-contract/typescript/test/stable.test.ts @@ -9,6 +9,7 @@ import type { AdapterTargetDescriptor, AdapterTelemetryProviderSupport, AgentConfig, + AgentModelUsage, AgentUsage, ControlLocation, EnvironmentOwnership, @@ -42,6 +43,36 @@ const invalidCacheSemantics: AgentUsage = { void usage; void invalidCacheSemantics; +const detailedUsage: AgentUsage = { + cache_write_input_tokens: 3, + output_tokens: 12, + output_tokens_include_reasoning: true, + peak_request_input_tokens: 18, + reasoning_tokens: 8, + models: [ + { + model: "example-model", + provider: "example-provider", + reasoning_tokens: 8, + }, + ], +}; +const invalidReasoningSemantics: AgentUsage = { + // @ts-expect-error reasoning semantics require an explicit boolean, not a numeric flag + output_tokens_include_reasoning: 1, +}; +// @ts-expect-error model usage requires the model identifier +const modelUsageWithoutModel: AgentModelUsage = { provider: "example-provider" }; +const modelUsageWithUnknownField: AgentModelUsage = { + model: "example-model", + // @ts-expect-error closed model usage objects reject unknown keys + reasoning: 1, +}; +void detailedUsage; +void invalidReasoningSemantics; +void modelUsageWithoutModel; +void modelUsageWithUnknownField; + const target: AdapterTargetDescriptor = { adapter_id: "pi", contract_version: ADAPTER_CONTRACT_VERSION, From a1dc1214f519175356693c1d04f3f0709210d196 Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Thu, 8 Oct 2026 00:55:14 -0700 Subject: [PATCH 04/10] docs: describe detailed adapter usage reporting Adapter authors need to know when to report the new usage fields, what the inclusion flags mean, and that NeMo Fabric does not yet pass the fields to consumers. Document the fields and per-model rules in the results tutorial and the adapter-building skill, state that cache-write, reasoning, peak request, and per-model usage are not copied into RunResult.usage, describe the wider cache flag meaning in the Python SDK guide, and point the adapter contribution skill at the shared fields. Signed-off-by: mnajafian-nv --- .agents/skills/contribute-adapter/SKILL.md | 2 +- docs/adapter-contract/tutorials/results.md | 8 ++++++-- docs/sdk/python.mdx | 2 +- skills/nemo-fabric-build-adapter/SKILL.md | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.agents/skills/contribute-adapter/SKILL.md b/.agents/skills/contribute-adapter/SKILL.md index ffeff0556..c9f04996b 100644 --- a/.agents/skills/contribute-adapter/SKILL.md +++ b/.agents/skills/contribute-adapter/SKILL.md @@ -57,7 +57,7 @@ Keep descriptor claims, implementation, focused tests, public documentation, catalog entries, and packaged metadata synchronized. Start with the narrowest truthful capability set. -For usage changes, verify invocation-local accounting through the adapter contract and consumer SDK, including warm-session deltas, unknown counters, cache semantics, and unsuccessful results. Keep generated schemas and language bindings in parity; use the shared `cached_input_tokens` and `input_tokens_include_cache` fields instead of consumer-specific parsing of native output. +For usage changes, verify invocation-local accounting through the adapter contract and consumer SDK, including warm-session deltas, unknown counters, cache semantics, and unsuccessful results. Keep generated schemas and language bindings in parity; use the shared cache, cache-write, reasoning, peak request, and per-model `AgentUsage` fields instead of consumer-specific parsing of native output. For `instructions.system`, keep `config.system_instruction_modes`, planning behavior, direct adapter validation, and target-native composition synchronized. diff --git a/docs/adapter-contract/tutorials/results.md b/docs/adapter-contract/tutorials/results.md index 20029cf63..662ccdf9c 100644 --- a/docs/adapter-contract/tutorials/results.md +++ b/docs/adapter-contract/tutorials/results.md @@ -65,7 +65,7 @@ return AgentRunResult( | `status` | Required | Reports `succeeded`, `failed`, or `cancelled`. | | `output` | Required | Carries the primary JSON-compatible output and can be `null`. | | `error` | Required for `failed` | Carries a stable code, safe message, retry guidance, and declared extensions. | -| `usage` | Optional | Carries invocation-local input, cached-input, output, and total token counts plus reported cost when known. | +| `usage` | Optional | Carries invocation-local input, cached-input, cache-write, output, reasoning, total, and peak request token counts, reported cost, and an optional per-model breakdown when known. | | `artifacts` | Optional | Carries target-produced artifact references relative to the runtime artifact root. | | `extensions` | Optional | Carries adapter-owned result data validated by the descriptor. | @@ -75,7 +75,11 @@ for the exact shape. A failed result contains an error; a successful result does not contain a non-null error. Status is explicit and is not inferred from arbitrary output fields. -Report only observed invocation usage. For cumulative target counters, compute the difference between successive observations; do not sum cumulative snapshots or substitute the last model response for an entire invocation. Missing and reset counters remain unknown. `cached_input_tokens` records cached prompt tokens; `input_tokens_include_cache` declares whether they are included in `input_tokens` (`True`), excluded (`False`), or unknown (absent). Keep estimates separate from `cost_usd`, and retain available usage on unsuccessful terminal results. +Report only observed invocation usage. For cumulative target counters, compute the difference between successive observations; do not sum cumulative snapshots or substitute the last model response for an entire invocation. Missing and reset counters remain unknown. `cached_input_tokens` records cached prompt tokens and `cache_write_input_tokens` records prompt tokens written to the provider cache; `input_tokens_include_cache` declares whether both are included in `input_tokens` (`True`), excluded (`False`), or unknown (absent). `reasoning_tokens` records reasoning output, and `output_tokens_include_reasoning` declares whether it is included in `output_tokens` with the same three states. `peak_request_input_tokens` records the input size of the largest single model request, including cached and cache-write input. Keep estimates separate from `cost_usd`, and retain available usage on unsuccessful terminal results. + +When the target reports usage per model, add one `AgentModelUsage` entry per model to `usage.models`. Each entry requires a non-blank `model`, accepts an optional non-blank `provider`, and uses the same token, flag, and cost fields as `AgentUsage`. A provider and model pair can appear only once, compared case-insensitively. Model entries have no `extensions`; keep adapter-owned usage data in `usage.extensions`. + +NeMo Fabric validates `cache_write_input_tokens`, `reasoning_tokens`, `output_tokens_include_reasoning`, `peak_request_input_tokens`, and `usage.models`, but does not copy any of them into the consumer `RunResult.usage`. `RunResult.usage` keeps the adapter's `input_tokens_include_cache` flag, so when the flag is `False`, a consumer that adds `cached_input_tokens` to `input_tokens` does not count reported cache-write input. **Success Check**: `invoke` returns one typed `AgentRunResult` whose explicit status matches the presence or absence of an error. diff --git a/docs/sdk/python.mdx b/docs/sdk/python.mdx index b26036721..40d406e05 100644 --- a/docs/sdk/python.mdx +++ b/docs/sdk/python.mdx @@ -892,7 +892,7 @@ if result.usage is not None: print(result.usage.get("cost_usd")) ``` -Each counter is optional: missing values are unknown, not zero. `cached_input_tokens` reports cached prompt tokens. `input_tokens_include_cache` is `True` when those tokens are already included in `input_tokens`, `False` when they are excluded, and absent when the adapter cannot establish the semantics. Consumers must not add cached tokens to an inclusive input count. `cost_usd` contains reported cost only; keep estimates separately in provider metadata rather than presenting them as measured charges. +Each counter is optional: missing values are unknown, not zero. `cached_input_tokens` reports cached prompt tokens. `input_tokens_include_cache` is `True` when those tokens are already included in `input_tokens`, `False` when they are excluded, and absent when the adapter cannot establish the semantics. Consumers must not add cached tokens to an inclusive input count. The flag also covers cache-write input tokens that an adapter reports, which `RunUsage` does not expose, so `input_tokens` plus `cached_input_tokens` can understate total input when the flag is `False`. `cost_usd` contains reported cost only; keep estimates separately in provider metadata rather than presenting them as measured charges. If NeMo Fabric cannot resolve config, start a runtime, or obtain a normalized result, the SDK raises a `FabricError` subclass instead of returning a partial diff --git a/skills/nemo-fabric-build-adapter/SKILL.md b/skills/nemo-fabric-build-adapter/SKILL.md index 523a6feec..72984d50d 100644 --- a/skills/nemo-fabric-build-adapter/SKILL.md +++ b/skills/nemo-fabric-build-adapter/SKILL.md @@ -228,7 +228,7 @@ required artifact references, and live workspace state may persist until telemetry scopes reset for each `invoke`. Independent runtime instances must never share mutable continuation state. -Normalize usage per invocation in `AgentUsage`. If the target reports cumulative session totals, retain a session-local baseline and difference successive observed counters rather than summing cumulative snapshots or using only the last model response. Missing or reset counters remain unknown. Report `cached_input_tokens` when available and declare whether `input_tokens` includes cache with `input_tokens_include_cache`; omit the flag when the target's semantics are unknown. Preserve available usage on unsuccessful terminal results. Do not infer missing cost or promote estimates to `cost_usd`. +Normalize usage per invocation in `AgentUsage`. If the target reports cumulative session totals, retain a session-local baseline and difference successive observed counters rather than summing cumulative snapshots or using only the last model response. Missing or reset counters remain unknown. Report `cached_input_tokens` and `cache_write_input_tokens` when available and declare whether `input_tokens` includes them with `input_tokens_include_cache`; report `reasoning_tokens` with `output_tokens_include_reasoning` the same way. Omit a flag when the target's semantics are unknown. Report `peak_request_input_tokens` only when the target exposes per-request input counts. When the target reports usage per model, add one `AgentModelUsage` entry per provider and model pair to `usage.models`; NeMo Fabric rejects blank model identifiers and case-insensitive duplicates. NeMo Fabric does not copy cache-write, reasoning, peak request, or per-model usage into the consumer `RunResult.usage`. Preserve available usage on unsuccessful terminal results. Do not infer missing cost or promote estimates to `cost_usd`. Test observable continuation rather than merely calling `invoke` twice: make the second result depend on the first turn without caller-side replay, then From d0e1ae7f9231e77987ff67afed28cc2f530d3d91 Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Thu, 8 Oct 2026 00:55:14 -0700 Subject: [PATCH 05/10] docs: regenerate API references for detailed usage Regenerate the Rust and Python references with Rust 1.94.0. The new AgentModelUsage page shifts the crate-wide sidebar positions, so most Rust reference pages change only their position line. Signed-off-by: mnajafian-nv --- .../nemo_fabric.types.md | 2 +- .../adapter-contract/index.mdx | 2 +- .../nemo-fabric-core/agent-config/index.mdx | 2 +- .../agent-config/struct-agentconfig.mdx | 2 +- .../struct-agentharnessconfig.mdx | 2 +- .../struct-agentinstructionconfig.mdx | 2 +- .../struct-agentinstructionsconfig.mdx | 2 +- .../agent-config/struct-agentmcpconfig.mdx | 2 +- .../struct-agentmcpserverconfig.mdx | 2 +- .../agent-config/struct-agentmodelconfig.mdx | 2 +- .../struct-agentruntimeconfig.mdx | 2 +- .../agent-config/struct-agentskillconfig.mdx | 2 +- .../struct-agenttooldefinition.mdx | 2 +- .../agent-config/struct-agenttoolsconfig.mdx | 2 +- .../struct-agentworkflowconfig.mdx | 2 +- .../struct-agentworkflowentrypointconfig.mdx | 2 +- .../enum-agentrunresultvalidationerror.mdx | 16 +- .../agent-execution/enum-agentrunstatus.mdx | 2 +- .../agent-execution/index.mdx | 3 +- .../struct-agentmodelusage.mdx | 149 ++++++++++++++++++ .../agent-execution/struct-agentrunerror.mdx | 2 +- .../struct-agentrunrequest.mdx | 2 +- .../agent-execution/struct-agentrunresult.mdx | 4 +- .../agent-execution/struct-agentusage.mdx | 26 ++- .../config/enum-adapterconfigfield.mdx | 2 +- .../config/enum-adapterkind.mdx | 2 +- .../config/enum-adaptertarget.mdx | 2 +- .../config/enum-adaptertargettype.mdx | 2 +- .../config/enum-controllocation.mdx | 2 +- .../config/enum-descriptorsource.mdx | 2 +- .../config/enum-environmentownership.mdx | 2 +- .../config/enum-instructionmode.mdx | 2 +- .../config/enum-mcpauthenticationconfig.mdx | 2 +- .../config/enum-mcpexposure.mdx | 2 +- .../config/enum-mcptransport.mdx | 2 +- .../enum-oauthtokenendpointauthmethod.mdx | 2 +- .../config/enum-resolutionstrategy.mdx | 2 +- .../config/enum-telemetryprovider.mdx | 2 +- .../config/fn-load-adapter-descriptor.mdx | 2 +- .../fn-load-adapter-target-descriptor.mdx | 2 +- .../fn-resolve-run-plan-from-config.mdx | 2 +- .../nemo-fabric-core/config/index.mdx | 2 +- .../config/struct-adapterconfigsupport.mdx | 2 +- .../config/struct-adapterdescriptor.mdx | 2 +- .../config/struct-adapterrequirements.mdx | 2 +- .../config/struct-adaptertargetdescriptor.mdx | 2 +- ...struct-adaptertelemetryprovidersupport.mdx | 2 +- .../config/struct-adaptertelemetrysupport.mdx | 2 +- .../config/struct-capabilityplan.mdx | 2 +- .../config/struct-descriptorprovenance.mdx | 2 +- .../config/struct-discoveryconfig.mdx | 2 +- .../config/struct-environmentconfig.mdx | 2 +- .../config/struct-environmentplan.mdx | 2 +- .../config/struct-fabricconfig.mdx | 2 +- .../config/struct-harnessconfig.mdx | 2 +- .../config/struct-instructionconfig.mdx | 2 +- .../config/struct-instructionsconfig.mdx | 2 +- .../config/struct-mcpconfig.mdx | 2 +- .../config/struct-mcpserverplan.mdx | 2 +- .../config/struct-metadataconfig.mdx | 2 +- .../config/struct-modelconfig.mdx | 2 +- .../config/struct-resolvecontext.mdx | 2 +- .../struct-resolvedadapterdescriptor.mdx | 2 +- ...struct-resolvedadaptertargetdescriptor.mdx | 2 +- .../config/struct-runplan.mdx | 2 +- .../config/struct-runtimecapabilities.mdx | 2 +- .../config/struct-runtimeconfig.mdx | 2 +- .../config/struct-skillconfig.mdx | 2 +- .../config/struct-telemetryconfig.mdx | 2 +- .../config/struct-telemetryplan.mdx | 2 +- .../config/struct-telemetryproviderconfig.mdx | 2 +- .../config/struct-tooldefinitionconfig.mdx | 2 +- .../config/struct-toolsconfig.mdx | 2 +- .../config/struct-workflowconfig.mdx | 2 +- .../struct-workflowentrypointconfig.mdx | 2 +- .../config/struct-workflowtargetspec.mdx | 2 +- .../doctor/enum-doctorstatus.mdx | 2 +- .../doctor/fn-doctor-plan.mdx | 2 +- .../nemo-fabric-core/doctor/index.mdx | 2 +- .../doctor/struct-doctorcheck.mdx | 2 +- .../doctor/struct-doctorreport.mdx | 2 +- .../error/enum-fabricerror.mdx | 2 +- .../nemo-fabric-core/error/index.mdx | 2 +- .../nemo-fabric-core/error/type-result.mdx | 2 +- .../nemo-fabric-core/fn-version.mdx | 2 +- .../nemo-fabric-core/index.mdx | 1 + .../nemo-fabric-core/runtime/index.mdx | 2 +- .../runtime/struct-runusage.mdx | 2 +- .../nemo-fabric-core/schema/index.mdx | 2 +- 89 files changed, 274 insertions(+), 91 deletions(-) create mode 100644 docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx diff --git a/docs/reference/api/python-library-reference/nemo_fabric.types.md b/docs/reference/api/python-library-reference/nemo_fabric.types.md index db21c91f1..b37de2605 100644 --- a/docs/reference/api/python-library-reference/nemo_fabric.types.md +++ b/docs/reference/api/python-library-reference/nemo_fabric.types.md @@ -1170,7 +1170,7 @@ Return a detached, JSON-compatible mapping for serialization. Normalized invocation-local usage reported by an adapter target. -Missing counters and cost are unknown, not zero. ``cached_input_tokens`` records cache usage; ``input_tokens_include_cache`` declares whether input already includes that count. An absent flag means the semantics are unknown. +Missing counters and cost are unknown, not zero. ``cached_input_tokens`` records cache usage; ``input_tokens_include_cache`` declares whether input already includes that count and any cache-write input the adapter reported. An absent flag means the semantics are unknown. Cache-write input is not reported here, so when the flag is ``False``, input plus cached input can understate total input. diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/adapter-contract/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/adapter-contract/index.mdx index 52a3b6f57..feabb8df6 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/adapter-contract/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/adapter-contract/index.mdx @@ -3,7 +3,7 @@ title: "Module adapter_contract" sidebar-title: "adapter_contract" slug: "/reference/api/rust-library-reference/nemo-fabric-core/adapter_contract" description: "Shared southbound adapter contract metadata." -position: 125 +position: 126 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/index.mdx index 26a286a0c..4c4e21b44 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/index.mdx @@ -3,7 +3,7 @@ title: "Module agent_config" sidebar-title: "agent_config" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config" description: "Configuration projected southbound to an adapter target." -position: 126 +position: 127 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentconfig.mdx index 3c77229a7..007d38643 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Config" sidebar-title: "AgentConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentconfig" description: "Configuration projected southbound to one adapter target." -position: 20 +position: 21 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentharnessconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentharnessconfig.mdx index 26da7f68a..c3e658bb3 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentharnessconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentharnessconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Harness Config" sidebar-title: "AgentHarnessConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentharnessconfig" description: "Adapter-owned target settings projected from `FabricConfig.harness`." -position: 21 +position: 22 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionconfig.mdx index e13c1a6f3..c4c49d6d8 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Instruction Config" sidebar-title: "AgentInstructionConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentinstructionconfig" description: "One normalized instruction value projected to an adapter target." -position: 22 +position: 23 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionsconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionsconfig.mdx index 196a7eb39..95ad35349 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionsconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionsconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Instructions Config" sidebar-title: "AgentInstructionsConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentinstructionsconfig" description: "Normalized instructions projected to an adapter target." -position: 23 +position: 24 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpconfig.mdx index df6d6e938..5213a2711 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent McpConfig" sidebar-title: "AgentMcpConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentmcpconfig" description: "Named MCP servers routed to an adapter target." -position: 24 +position: 25 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpserverconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpserverconfig.mdx index 05a6fbaa4..fbf5f8f4f 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpserverconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpserverconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent McpServer Config" sidebar-title: "AgentMcpServerConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentmcpserverconfig" description: "One MCP server routed to an adapter target." -position: 25 +position: 26 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmodelconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmodelconfig.mdx index 9d901c783..57a9681a4 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmodelconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmodelconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Model Config" sidebar-title: "AgentModelConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentmodelconfig" description: "Configuration for one named model role projected to an adapter target." -position: 26 +position: 27 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentruntimeconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentruntimeconfig.mdx index 504e93ede..347c0e5b1 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentruntimeconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentruntimeconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Runtime Config" sidebar-title: "AgentRuntimeConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentruntimeconfig" description: "Runtime behavior applied by an adapter target." -position: 27 +position: 28 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentskillconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentskillconfig.mdx index 001368c95..2ccd188bd 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentskillconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentskillconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Skill Config" sidebar-title: "AgentSkillConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentskillconfig" description: "Skill paths made available to an adapter target." -position: 28 +position: 29 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttooldefinition.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttooldefinition.mdx index bb1f81eed..fc8362a3c 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttooldefinition.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttooldefinition.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Tool Definition" sidebar-title: "AgentToolDefinition" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agenttooldefinition" description: "One named tool or tool-group definition resolved by an adapter." -position: 29 +position: 30 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttoolsconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttoolsconfig.mdx index fde3ada25..5ba49ba08 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttoolsconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttoolsconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Tools Config" sidebar-title: "AgentToolsConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agenttoolsconfig" description: "Named tool definitions and effective adapter-target tool policy." -position: 30 +position: 31 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowconfig.mdx index a42b88baf..e6b517f88 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Workflow Config" sidebar-title: "AgentWorkflowConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentworkflowconfig" description: "Custom agent or workflow selection and construction settings." -position: 31 +position: 32 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowentrypointconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowentrypointconfig.mdx index 7d344deed..79369c030 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowentrypointconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowentrypointconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Workflow Entrypoint Config" sidebar-title: "AgentWorkflowEntrypointConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentworkflowentrypointconfig" description: "Adapter-declared resolution semantics for one custom agent or workflow." -position: 32 +position: 33 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunresultvalidationerror.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunresultvalidationerror.mdx index f9883fce4..562b50c84 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunresultvalidationerror.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunresultvalidationerror.mdx @@ -3,14 +3,14 @@ title: "Enum Agent RunResult Validation Error" sidebar-title: "AgentRunResultValidationError" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/enum-agentrunresultvalidationerror" description: "Invalid relationship or value within an adapter result." -position: 7 +position: 8 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} Generated from `cargo doc --no-deps -p nemo-fabric-core`. -
str),\n    InvalidArtifactPath(PathBuf),\n}"}} />
+
str),\n    InvalidArtifactPath(PathBuf),\n    DuplicateModelUsage(String),\n    InvalidCost(&'static str),\n}"}} />
Invalid relationship or value within an adapter result. @@ -40,6 +40,18 @@ A result string violated the non-blank contract. An artifact path was blank, absolute, or contained parent traversal. +### `DuplicateModelUsage(String)` + +
String)"}} />
+ +Model usage repeated a provider and model pair, compared case-insensitively. + +### `InvalidCost(&'static str)` + +
str)"}} />
+ +A cost was negative or not a finite number. + ## Trait Implementations ### `impl Clone for AgentRunResultValidationError` diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunstatus.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunstatus.mdx index 117a32aef..c091b1f5f 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunstatus.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunstatus.mdx @@ -3,7 +3,7 @@ title: "Enum Agent RunStatus" sidebar-title: "AgentRunStatus" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/enum-agentrunstatus" description: "Completion status reported by an adapter target." -position: 8 +position: 9 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/index.mdx index 2c89a0e39..d8fc35dcb 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/index.mdx @@ -3,7 +3,7 @@ title: "Module agent_execution" sidebar-title: "agent_execution" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution" description: "Request and result structures exchanged with an adapter target." -position: 127 +position: 128 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} @@ -15,6 +15,7 @@ Request and result structures exchanged with an adapter target. ## Structs - [AgentArtifact](struct-agentartifact.mdx): One artifact produced by an adapter target. +- [AgentModelUsage](struct-agentmodelusage.mdx): Usage of one model within one invocation. - [AgentRunError](struct-agentrunerror.mdx): Error reported by an adapter target. - [AgentRunRequest](struct-agentrunrequest.mdx): Southbound invocation request passed to an adapter target. - [AgentRunResult](struct-agentrunresult.mdx): Southbound terminal result returned by an adapter target. diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx new file mode 100644 index 000000000..56584cddf --- /dev/null +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx @@ -0,0 +1,149 @@ +--- +title: "Struct Agent Model Usage" +sidebar-title: "AgentModelUsage" +slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentmodelusage" +description: "Usage of one model within one invocation." +position: 4 +--- +{/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +SPDX-License-Identifier: Apache-2.0 */} + +Generated from `cargo doc --no-deps -p nemo-fabric-core`. + +
String,\n    pub provider: Option<String>,\n    pub input_tokens: Option<u64>,\n    pub cached_input_tokens: Option<u64>,\n    pub cache_write_input_tokens: Option<u64>,\n    pub input_tokens_include_cache: Option<bool>,\n    pub output_tokens: Option<u64>,\n    pub reasoning_tokens: Option<u64>,\n    pub output_tokens_include_reasoning: Option<bool>,\n    pub total_tokens: Option<u64>,\n    pub peak_request_input_tokens: Option<u64>,\n    pub cost_usd: Option<f64>,\n}"}} />
+ +Usage of one model within one invocation. + +Token fields have the same meaning as the matching `AgentUsage` fields, restricted to requests served by this model. + +## Fields + +### `model: String` + +Model identifier as reported by the harness or provider response. + +### `provider: Option` + +Provider or route that served the model, when known. + +### `input_tokens: Option` + +Input tokens consumed by this model. + +### `cached_input_tokens: Option` + +Cached input tokens consumed by this model, when reported. + +### `cache_write_input_tokens: Option` + +Input tokens this model wrote to the provider prompt cache, when reported. + +### `input_tokens_include_cache: Option` + +Whether input_tokens already includes cached_input_tokens and cache_write_input_tokens; absent means unknown. + +### `output_tokens: Option` + +Output tokens produced by this model. + +### `reasoning_tokens: Option` + +Reasoning tokens produced by this model, when reported. + +### `output_tokens_include_reasoning: Option` + +Whether output_tokens already includes reasoning_tokens; absent means unknown. + +### `total_tokens: Option` + +Total tokens reported by the provider for this model. + +### `peak_request_input_tokens: Option` + +Input tokens of the largest single request served by this model, including cached and cache-write input, when reported. + +### `cost_usd: Option` + +Cost in US dollars for this model when reported by the provider. + +## Trait Implementations + +### `impl Clone for AgentModelUsage` + +
Clone for AgentModelUsage"}} />
+ +#### `clone` + +
clone(&self) -> AgentModelUsage"}} />
+ +#### `clone_from` + +
clone_from(&mut self, source: &Self)"}} />
+ +### `impl Debug for AgentModelUsage` + +
Debug for AgentModelUsage"}} />
+ +#### `fmt` + +
fmt(&self, f: &mut Formatter<'_>) -> Result"}} />
+ +### `impl Default for AgentModelUsage` + +
Default for AgentModelUsage"}} />
+ +#### `default` + +
default() -> AgentModelUsage"}} />
+ +### `impl<'de> Deserialize<'de> for AgentModelUsage` + +
Deserialize<'de> for AgentModelUsage"}} />
+ +#### `deserialize` + +
deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where\n    __D: Deserializer<'de>,"}} />
+ +### `impl JsonSchema for AgentModelUsage` + +
AgentModelUsage"}} />
+ +#### `schema_name` + +
Cow<'static, str>"}} />
+ +#### `schema_id` + +
Cow<'static, str>"}} />
+ +#### `json_schema` + +
+ +#### `inline_schema` + +
bool"}} />
+ +### `impl PartialEq for AgentModelUsage` + +
PartialEq for AgentModelUsage"}} />
+ +#### `eq` + +
eq(&self, other: &AgentModelUsage) -> bool"}} />
+ +#### `ne` + +
ne(&self, other: &Rhs) -> bool"}} />
+ +### `impl Serialize for AgentModelUsage` + +
Serialize for AgentModelUsage"}} />
+ +#### `serialize` + +
serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where\n    __S: Serializer,"}} />
+ +### `impl StructuralPartialEq for AgentModelUsage` + +
StructuralPartialEq for AgentModelUsage"}} />
diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunerror.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunerror.mdx index 4afbb91c3..26d3d5890 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunerror.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunerror.mdx @@ -3,7 +3,7 @@ title: "Struct Agent RunError" sidebar-title: "AgentRunError" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentrunerror" description: "Error reported by an adapter target." -position: 4 +position: 5 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunrequest.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunrequest.mdx index c9d5f416e..93560b91a 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunrequest.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunrequest.mdx @@ -3,7 +3,7 @@ title: "Struct Agent RunRequest" sidebar-title: "AgentRunRequest" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentrunrequest" description: "Southbound invocation request passed to an adapter target." -position: 5 +position: 6 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunresult.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunresult.mdx index 9b87e801f..5b1462f3e 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunresult.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunresult.mdx @@ -3,7 +3,7 @@ title: "Struct Agent RunResult" sidebar-title: "AgentRunResult" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentrunresult" description: "Southbound terminal result returned by an adapter target." -position: 6 +position: 7 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} @@ -50,7 +50,7 @@ Adapter-owned result fields.
Result<(), AgentRunResultValidationError>"}} />
-Validate terminal status, error, and artifact invariants. +Validate terminal status, error, usage, and artifact invariants. ## Trait Implementations diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx index caaebcee0..07bdb9ce6 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx @@ -3,14 +3,14 @@ title: "Struct Agent Usage" sidebar-title: "AgentUsage" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentusage" description: "Normalized model usage reported by an adapter target." -position: 9 +position: 10 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} Generated from `cargo doc --no-deps -p nemo-fabric-core`. -
Option<u64>,\n    pub cached_input_tokens: Option<u64>,\n    pub input_tokens_include_cache: Option<bool>,\n    pub output_tokens: Option<u64>,\n    pub total_tokens: Option<u64>,\n    pub cost_usd: Option<f64>,\n    pub extensions: BTreeMap<String, Value>,\n}"}} />
+
Option<u64>,\n    pub cached_input_tokens: Option<u64>,\n    pub cache_write_input_tokens: Option<u64>,\n    pub input_tokens_include_cache: Option<bool>,\n    pub output_tokens: Option<u64>,\n    pub reasoning_tokens: Option<u64>,\n    pub output_tokens_include_reasoning: Option<bool>,\n    pub total_tokens: Option<u64>,\n    pub peak_request_input_tokens: Option<u64>,\n    pub cost_usd: Option<f64>,\n    pub models: Vec<AgentModelUsage>,\n    pub extensions: BTreeMap<String, Value>,\n}"}} />
Normalized model usage reported by an adapter target. @@ -24,22 +24,42 @@ Input tokens consumed by the invocation. Cached input tokens consumed by the invocation, when reported. +### `cache_write_input_tokens: Option` + +Input tokens written to the provider prompt cache, when reported. + ### `input_tokens_include_cache: Option` -Whether input_tokens already includes cached_input_tokens; absent means unknown. +Whether input_tokens already includes cached_input_tokens and cache_write_input_tokens; absent means unknown. ### `output_tokens: Option` Output tokens produced by the invocation. +### `reasoning_tokens: Option` + +Reasoning tokens produced by the invocation, when reported. + +### `output_tokens_include_reasoning: Option` + +Whether output_tokens already includes reasoning_tokens; absent means unknown. + ### `total_tokens: Option` Total tokens reported by the provider. +### `peak_request_input_tokens: Option` + +Input tokens of the largest single model request in the invocation, including cached and cache-write input, when reported. + ### `cost_usd: Option` Invocation cost in US dollars when reported by the provider. +### `models: Vec` + +Usage broken out by the model that served the requests; empty when not reported. Each provider and model pair appears at most once, compared case-insensitively. + ### `extensions: BTreeMap` Adapter-owned usage fields. diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterconfigfield.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterconfigfield.mdx index fff169bdf..56996dbb6 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterconfigfield.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterconfigfield.mdx @@ -2,7 +2,7 @@ title: "Enum Adapter Config Field" sidebar-title: "AdapterConfigField" description: "Adapter-translated normalized NVIDIA NeMo Fabric configuration fields." -position: 10 +position: 11 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterkind.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterkind.mdx index 2891790f8..f9032f16d 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterkind.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterkind.mdx @@ -2,7 +2,7 @@ title: "Enum Adapter Kind" sidebar-title: "AdapterKind" description: "Adapter implementation kind." -position: 13 +position: 14 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertarget.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertarget.mdx index 5e8279ddf..13484f3cc 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertarget.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertarget.mdx @@ -2,7 +2,7 @@ title: "Enum Adapter Target" sidebar-title: "AdapterTarget" description: "Type-specific Adapter Target Descriptor payload." -position: 15 +position: 16 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertargettype.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertargettype.mdx index d3712e741..63224c403 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertargettype.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertargettype.mdx @@ -2,7 +2,7 @@ title: "Enum Adapter Target Type" sidebar-title: "AdapterTargetType" description: "Adapter target categories understood by this Adapter Contract version." -position: 17 +position: 18 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-controllocation.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-controllocation.mdx index 6cc4e506e..7d18d6f18 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-controllocation.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-controllocation.mdx @@ -2,7 +2,7 @@ title: "Enum Control Location" sidebar-title: "ControlLocation" description: "Where NeMo Fabric control code runs relative to the environment." -position: 34 +position: 35 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-descriptorsource.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-descriptorsource.mdx index 2ccfbed5d..3385fa574 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-descriptorsource.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-descriptorsource.mdx @@ -2,7 +2,7 @@ title: "Enum Descriptor Source" sidebar-title: "DescriptorSource" description: "Where NeMo Fabric discovered descriptor metadata." -position: 36 +position: 37 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-environmentownership.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-environmentownership.mdx index 56b0d7e7c..9bd45bad8 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-environmentownership.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-environmentownership.mdx @@ -2,7 +2,7 @@ title: "Enum Environment Ownership" sidebar-title: "EnvironmentOwnership" description: "Whether NeMo Fabric owns the underlying environment resource." -position: 39 +position: 40 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-instructionmode.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-instructionmode.mdx index 1aa441a9a..bd744c9ed 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-instructionmode.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-instructionmode.mdx @@ -2,7 +2,7 @@ title: "Enum Instruction Mode" sidebar-title: "InstructionMode" description: "How an instruction value is applied to the selected harness." -position: 44 +position: 45 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpauthenticationconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpauthenticationconfig.mdx index 894f9abfc..e2f470c6d 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpauthenticationconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpauthenticationconfig.mdx @@ -2,7 +2,7 @@ title: "Enum McpAuthentication Config" sidebar-title: "McpAuthenticationConfig" description: "MCP server authentication configuration." -position: 46 +position: 47 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpexposure.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpexposure.mdx index df5de9dd3..9a9d7a1a8 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpexposure.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpexposure.mdx @@ -2,7 +2,7 @@ title: "Enum McpExposure" sidebar-title: "McpExposure" description: "MCP exposure strategy." -position: 48 +position: 49 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcptransport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcptransport.mdx index 5b9db56b2..429fa8ee7 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcptransport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcptransport.mdx @@ -2,7 +2,7 @@ title: "Enum McpTransport" sidebar-title: "McpTransport" description: "MCP server transport." -position: 50 +position: 51 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-oauthtokenendpointauthmethod.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-oauthtokenendpointauthmethod.mdx index c9c83b6f6..9a244fd2b 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-oauthtokenendpointauthmethod.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-oauthtokenendpointauthmethod.mdx @@ -2,7 +2,7 @@ title: "Enum OAuth Token Endpoint Auth Method" sidebar-title: "OAuthTokenEndpointAuthMethod" description: "OAuth client authentication method used at the token endpoint." -position: 53 +position: 54 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-resolutionstrategy.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-resolutionstrategy.mdx index f130d1764..7e6f001b7 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-resolutionstrategy.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-resolutionstrategy.mdx @@ -2,7 +2,7 @@ title: "Enum Resolution Strategy" sidebar-title: "ResolutionStrategy" description: "Adapter install or availability strategy." -position: 54 +position: 55 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-telemetryprovider.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-telemetryprovider.mdx index 8ce5c9908..d1bfc189f 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-telemetryprovider.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-telemetryprovider.mdx @@ -2,7 +2,7 @@ title: "Enum Telemetry Provider" sidebar-title: "TelemetryProvider" description: "Telemetry runtime provider." -position: 64 +position: 65 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-descriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-descriptor.mdx index fc493bae7..de34aedc1 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-descriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-descriptor.mdx @@ -2,7 +2,7 @@ title: "Function load_adapter_descriptor" sidebar-title: "load_adapter_descriptor" description: "Load an adapter descriptor from JSON package metadata." -position: 71 +position: 72 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-target-descriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-target-descriptor.mdx index 142fdba30..bd5cd97d5 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-target-descriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-target-descriptor.mdx @@ -2,7 +2,7 @@ title: "Function load_adapter_target_descriptor" sidebar-title: "load_adapter_target_descriptor" description: "Load an Adapter Target Descriptor from declarative JSON metadata." -position: 72 +position: 73 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-resolve-run-plan-from-config.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-resolve-run-plan-from-config.mdx index 6bc8a973b..a6d607703 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-resolve-run-plan-from-config.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-resolve-run-plan-from-config.mdx @@ -2,7 +2,7 @@ title: "Function resolve_run_plan_from_config" sidebar-title: "resolve_run_plan_from_config" description: "Resolve a typed NVIDIA NeMo Fabric config into a runnable plan." -position: 73 +position: 74 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx index fa7255361..f51ee909d 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx @@ -2,7 +2,7 @@ title: "Module config" sidebar-title: "config" description: "NeMo Fabric config models and loading helpers." -position: 128 +position: 129 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterconfigsupport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterconfigsupport.mdx index 4439f355a..b807db089 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterconfigsupport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterconfigsupport.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Config Support" sidebar-title: "AdapterConfigSupport" description: "Adapter config support." -position: 11 +position: 12 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx index 19d1aa987..004375cc9 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Descriptor" sidebar-title: "AdapterDescriptor" description: "Language-neutral adapter descriptor for a harness integration." -position: 12 +position: 13 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterrequirements.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterrequirements.mdx index b126d5497..ebcc3cd59 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterrequirements.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterrequirements.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Requirements" sidebar-title: "AdapterRequirements" description: "Adapter runtime requirements." -position: 14 +position: 15 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertargetdescriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertargetdescriptor.mdx index da0d2527d..76745d1c1 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertargetdescriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertargetdescriptor.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Target Descriptor" sidebar-title: "AdapterTargetDescriptor" description: "Independently registered target implemented by an adapter." -position: 16 +position: 17 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetryprovidersupport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetryprovidersupport.mdx index 7cb95cbee..00ae0e985 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetryprovidersupport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetryprovidersupport.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Telemetry Provider Support" sidebar-title: "AdapterTelemetryProviderSupport" description: "Telemetry capabilities for one adapter-supported provider." -position: 18 +position: 19 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetrysupport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetrysupport.mdx index 740b201c7..7a89a0e09 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetrysupport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetrysupport.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Telemetry Support" sidebar-title: "AdapterTelemetrySupport" description: "Adapter telemetry support." -position: 19 +position: 20 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-capabilityplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-capabilityplan.mdx index d3880d1b7..0a00c4a9f 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-capabilityplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-capabilityplan.mdx @@ -2,7 +2,7 @@ title: "Struct Capability Plan" sidebar-title: "CapabilityPlan" description: "Resolved capability configuration." -position: 33 +position: 34 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-descriptorprovenance.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-descriptorprovenance.mdx index 4386be0f5..49666d77c 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-descriptorprovenance.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-descriptorprovenance.mdx @@ -2,7 +2,7 @@ title: "Struct Descriptor Provenance" sidebar-title: "DescriptorProvenance" description: "One physical source for a discovered descriptor record." -position: 35 +position: 36 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-discoveryconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-discoveryconfig.mdx index 8a2648e20..06e0ef0b8 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-discoveryconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-discoveryconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Discovery Config" sidebar-title: "DiscoveryConfig" description: "Explicit descriptor discovery inputs." -position: 37 +position: 38 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentconfig.mdx index e8aa118d0..027465d62 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Environment Config" sidebar-title: "EnvironmentConfig" description: "Execution environment configuration." -position: 38 +position: 39 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentplan.mdx index ca4a654e8..9f1f06a46 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentplan.mdx @@ -2,7 +2,7 @@ title: "Struct Environment Plan" sidebar-title: "EnvironmentPlan" description: "Resolved environment plan." -position: 40 +position: 41 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-fabricconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-fabricconfig.mdx index d4e1acd9b..d6755ebcf 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-fabricconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-fabricconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Fabric Config" sidebar-title: "FabricConfig" description: "Versioned NVIDIA NeMo Fabric agent config." -position: 41 +position: 42 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-harnessconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-harnessconfig.mdx index e3af3e851..87fc5328b 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-harnessconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-harnessconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Harness Config" sidebar-title: "HarnessConfig" description: "Harness selection." -position: 42 +position: 43 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionconfig.mdx index 2c8969673..d930e5450 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Instruction Config" sidebar-title: "InstructionConfig" description: "One portable instruction value." -position: 43 +position: 44 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionsconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionsconfig.mdx index 7158cc247..6a1d16f4f 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionsconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionsconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Instructions Config" sidebar-title: "InstructionsConfig" description: "Harness-neutral agent instruction configuration." -position: 45 +position: 46 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpconfig.mdx index 262b90d8e..26f8ce82f 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpconfig.mdx @@ -2,7 +2,7 @@ title: "Struct McpConfig" sidebar-title: "McpConfig" description: "MCP capability configuration." -position: 47 +position: 48 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpserverplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpserverplan.mdx index 589afc12c..c4ee6edec 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpserverplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpserverplan.mdx @@ -2,7 +2,7 @@ title: "Struct McpServer Plan" sidebar-title: "McpServerPlan" description: "Resolved MCP server exposure." -position: 49 +position: 50 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-metadataconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-metadataconfig.mdx index d2adec971..3bdefc9d0 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-metadataconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-metadataconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Metadata Config" sidebar-title: "MetadataConfig" description: "Human-readable metadata." -position: 51 +position: 52 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-modelconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-modelconfig.mdx index 50469f63c..c9d8b63fc 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-modelconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-modelconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Model Config" sidebar-title: "ModelConfig" description: "Model configuration." -position: 52 +position: 53 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvecontext.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvecontext.mdx index 8e70ade88..bf1537e85 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvecontext.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvecontext.mdx @@ -2,7 +2,7 @@ title: "Struct Resolve Context" sidebar-title: "ResolveContext" description: "Source context used when resolving an in-memory NeMo Fabric config." -position: 55 +position: 56 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadapterdescriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadapterdescriptor.mdx index 7c1e65663..34ad4c681 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadapterdescriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadapterdescriptor.mdx @@ -2,7 +2,7 @@ title: "Struct Resolved Adapter Descriptor" sidebar-title: "ResolvedAdapterDescriptor" description: "Adapter descriptor selected for a run plan." -position: 56 +position: 57 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadaptertargetdescriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadaptertargetdescriptor.mdx index 8adac3efc..b3be2d837 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadaptertargetdescriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadaptertargetdescriptor.mdx @@ -2,7 +2,7 @@ title: "Struct Resolved Adapter Target Descriptor" sidebar-title: "ResolvedAdapterTargetDescriptor" description: "Adapter target descriptor selected for a run plan." -position: 57 +position: 58 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runplan.mdx index e3c43e4e1..b8f75e62d 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runplan.mdx @@ -2,7 +2,7 @@ title: "Struct RunPlan" sidebar-title: "RunPlan" description: "Resolved NeMo Fabric run plan." -position: 58 +position: 59 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimecapabilities.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimecapabilities.mdx index 0d972cb87..5c2282536 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimecapabilities.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimecapabilities.mdx @@ -2,7 +2,7 @@ title: "Struct Runtime Capabilities" sidebar-title: "RuntimeCapabilities" description: "Lifecycle behavior implemented by a resolved runtime path." -position: 59 +position: 60 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimeconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimeconfig.mdx index 2c89a11b2..4ab3289bc 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimeconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimeconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Runtime Config" sidebar-title: "RuntimeConfig" description: "Invocation runtime contract." -position: 60 +position: 61 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-skillconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-skillconfig.mdx index 47644f228..1f4e2fe76 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-skillconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-skillconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Skill Config" sidebar-title: "SkillConfig" description: "Skill capability configuration." -position: 61 +position: 62 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryconfig.mdx index 2e1b4af6b..61e3aa7d0 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Telemetry Config" sidebar-title: "TelemetryConfig" description: "Telemetry configuration." -position: 62 +position: 63 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryplan.mdx index f12176331..326bcdbb5 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryplan.mdx @@ -2,7 +2,7 @@ title: "Struct Telemetry Plan" sidebar-title: "TelemetryPlan" description: "Resolved telemetry plan." -position: 63 +position: 64 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryproviderconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryproviderconfig.mdx index f683b0886..bef871340 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryproviderconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryproviderconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Telemetry Provider Config" sidebar-title: "TelemetryProviderConfig" description: "Provider-specific telemetry configuration." -position: 65 +position: 66 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-tooldefinitionconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-tooldefinitionconfig.mdx index b5e0b460f..771156fff 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-tooldefinitionconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-tooldefinitionconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Tool Definition Config" sidebar-title: "ToolDefinitionConfig" description: "One named normalized tool or tool-group definition." -position: 66 +position: 67 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-toolsconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-toolsconfig.mdx index 64b2d6eec..f9f3714b7 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-toolsconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-toolsconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Tools Config" sidebar-title: "ToolsConfig" description: "Harness-neutral tool capability configuration." -position: 67 +position: 68 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowconfig.mdx index 21beec0df..ab0796f56 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Workflow Config" sidebar-title: "WorkflowConfig" description: "Registered workflow target and immutable construction settings." -position: 68 +position: 69 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowentrypointconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowentrypointconfig.mdx index a002d8fc3..03fecb115 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowentrypointconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowentrypointconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Workflow Entrypoint Config" sidebar-title: "WorkflowEntrypointConfig" description: "Adapter-owned workflow entry point supplied by an Adapter Target Descriptor." -position: 69 +position: 70 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowtargetspec.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowtargetspec.mdx index e66041abb..a0e9695a1 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowtargetspec.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowtargetspec.mdx @@ -2,7 +2,7 @@ title: "Struct Workflow Target Spec" sidebar-title: "WorkflowTargetSpec" description: "Workflow-specific Adapter Target Descriptor fields." -position: 70 +position: 71 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/enum-doctorstatus.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/enum-doctorstatus.mdx index d8c0693d4..bbae2fe19 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/enum-doctorstatus.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/enum-doctorstatus.mdx @@ -2,7 +2,7 @@ title: "Enum Doctor Status" sidebar-title: "DoctorStatus" description: "Diagnostic status." -position: 76 +position: 77 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/fn-doctor-plan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/fn-doctor-plan.mdx index bb8aa23e8..b97461157 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/fn-doctor-plan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/fn-doctor-plan.mdx @@ -2,7 +2,7 @@ title: "Function doctor_plan" sidebar-title: "doctor_plan" description: "Inspect a resolved run plan without mutating the environment." -position: 77 +position: 78 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.mdx index ea299ed94..4f6f26b00 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.mdx @@ -2,7 +2,7 @@ title: "Module doctor" sidebar-title: "doctor" description: "Plan diagnostics for NeMo Fabric." -position: 129 +position: 130 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorcheck.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorcheck.mdx index c64d5792e..9ae58d2b6 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorcheck.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorcheck.mdx @@ -2,7 +2,7 @@ title: "Struct Doctor Check" sidebar-title: "DoctorCheck" description: "Diagnostic check result." -position: 74 +position: 75 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorreport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorreport.mdx index c7d65e76f..c015cc391 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorreport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorreport.mdx @@ -2,7 +2,7 @@ title: "Struct Doctor Report" sidebar-title: "DoctorReport" description: "Diagnostic report for a resolved run plan." -position: 75 +position: 76 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx index 95cf2f59a..70e1c1cc4 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx @@ -2,7 +2,7 @@ title: "Enum Fabric Error" sidebar-title: "FabricError" description: "Errors raised by NeMo Fabric config loading and validation." -position: 78 +position: 79 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/index.mdx index cf7208b32..e389cbb01 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/index.mdx @@ -2,7 +2,7 @@ title: "Module error" sidebar-title: "error" description: "Error types for NeMo Fabric core." -position: 130 +position: 131 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/type-result.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/type-result.mdx index 0a91b0129..6f11a50d8 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/type-result.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/type-result.mdx @@ -2,7 +2,7 @@ title: "Type Alias Result" sidebar-title: "Result" description: "Core NeMo Fabric result type." -position: 79 +position: 80 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/fn-version.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/fn-version.mdx index 8af97f312..f9c667fa9 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/fn-version.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/fn-version.mdx @@ -2,7 +2,7 @@ title: "Function version" sidebar-title: "version" description: "Returns the crate version compiled into this build." -position: 133 +position: 134 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx index 6670ab4d8..8e1579dda 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx @@ -16,6 +16,7 @@ Core config and runtime contract for NeMo Fabric. - `pub use adapter_contract::ADAPTER_CONTRACT_VERSION;` - `pub use adapter_contract::AdapterExtensionPoint;` - `pub use agent_execution::AgentArtifact;` +- `pub use agent_execution::AgentModelUsage;` - `pub use agent_execution::AgentRunError;` - `pub use agent_execution::AgentRunRequest;` - `pub use agent_execution::AgentRunResult;` diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx index e4ce802a1..3b8f07380 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx @@ -2,7 +2,7 @@ title: "Module runtime" sidebar-title: "runtime" description: "Runtime invocation helpers." -position: 131 +position: 132 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx index 6f16e387b..d286403b5 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx @@ -25,7 +25,7 @@ Cached input tokens consumed by the invocation, when reported. ### `input_tokens_include_cache: Option` -Whether input_tokens already includes cached_input_tokens; absent means unknown. +Whether input_tokens already includes cached_input_tokens and any cache-write input tokens the adapter reported; absent means unknown. RunUsage does not report cache-write input tokens, so input_tokens plus cached_input_tokens can understate total input when this is false. ### `output_tokens: Option` diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx index 0569b34b2..722c3a849 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx @@ -2,7 +2,7 @@ title: "Module schema" sidebar-title: "schema" description: "JSON Schema generation for the public NeMo Fabric contract." -position: 132 +position: 133 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} From 43af1b7b318c416866f53aa83a6e3158d4543df9 Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Fri, 9 Oct 2026 13:42:08 -0700 Subject: [PATCH 06/10] docs(contract): define cache inclusion for reads and writes input_tokens_include_cache now covers both cache reads (cached_input_tokens) and cache writes (cache_write_input_tokens), so one flag cannot describe a provider that counts reads in input_tokens but reports writes separately. Keep the single flag and state the rule explicitly: true means both are included, false means both are excluded, and an adapter whose provider mixes the two normalizes input_tokens before reporting. Update the Rust doc comments for AgentUsage and AgentModelUsage, the Python contract docstring, the adapter results tutorial, and the build-adapter skill, and regenerate the JSON Schemas, TypeScript contract, and Rust API reference from the doc comments. Signed-off-by: mnajafian-nv --- .../src/nemo_fabric_adapter_contract/models.py | 7 +++++-- .../schemas/agent-run-result.schema.json | 4 ++-- .../typescript/src/generated/agent-run-result.ts | 14 ++++++++++---- crates/fabric-core/src/agent_execution.rs | 14 ++++++++++---- docs/adapter-contract/tutorials/results.md | 2 +- .../agent-execution/struct-agentmodelusage.mdx | 2 +- .../agent-execution/struct-agentusage.mdx | 2 +- .../adapter-contract/agent-run-result.schema.json | 4 ++-- skills/nemo-fabric-build-adapter/SKILL.md | 2 +- 9 files changed, 33 insertions(+), 18 deletions(-) diff --git a/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py b/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py index 8f539e48d..030470dc5 100644 --- a/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py +++ b/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py @@ -565,8 +565,11 @@ class AgentUsage(AgentContractBlock): """Normalized model usage reported by an adapter target. ``input_tokens_include_cache`` covers both ``cached_input_tokens`` and - ``cache_write_input_tokens``. ``models`` reports each provider and model - pair at most once, compared case-insensitively. + ``cache_write_input_tokens``: ``True`` means both are included in + ``input_tokens`` and ``False`` means both are excluded. When the provider + includes only one of the two, normalize ``input_tokens`` before reporting. + ``models`` reports each provider and model pair at most once, compared + case-insensitively. """ input_tokens: int | None = _optional() diff --git a/adapter-contract/typescript/schemas/agent-run-result.schema.json b/adapter-contract/typescript/schemas/agent-run-result.schema.json index 0fa80398a..4d60979e0 100644 --- a/adapter-contract/typescript/schemas/agent-run-result.schema.json +++ b/adapter-contract/typescript/schemas/agent-run-result.schema.json @@ -101,7 +101,7 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes cached_input_tokens and\ncache_write_input_tokens; absent means unknown.", + "description": "Whether input_tokens already includes both cached_input_tokens (cache\nreads) and cache_write_input_tokens (cache writes); absent means\nunknown. True means both are included and false means both are\nexcluded. When the provider includes only one of the two, the adapter\nnormalizes input_tokens to one of these states before reporting.", "type": [ "boolean", "null" @@ -277,7 +277,7 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes cached_input_tokens and\ncache_write_input_tokens; absent means unknown.", + "description": "Whether input_tokens already includes both cached_input_tokens (cache\nreads) and cache_write_input_tokens (cache writes); absent means\nunknown. True means both are included and false means both are\nexcluded. When the provider includes only one of the two, the adapter\nnormalizes input_tokens to one of these states before reporting.", "type": [ "boolean", "null" diff --git a/adapter-contract/typescript/src/generated/agent-run-result.ts b/adapter-contract/typescript/src/generated/agent-run-result.ts index e0e35941c..a17a1d35b 100644 --- a/adapter-contract/typescript/src/generated/agent-run-result.ts +++ b/adapter-contract/typescript/src/generated/agent-run-result.ts @@ -107,8 +107,11 @@ export interface AgentUsage { */ input_tokens?: number | null; /** - * Whether input_tokens already includes cached_input_tokens and - * cache_write_input_tokens; absent means unknown. + * Whether input_tokens already includes both cached_input_tokens (cache + * reads) and cache_write_input_tokens (cache writes); absent means + * unknown. True means both are included and false means both are + * excluded. When the provider includes only one of the two, the adapter + * normalizes input_tokens to one of these states before reporting. */ input_tokens_include_cache?: boolean | null; /** @@ -166,8 +169,11 @@ export interface AgentModelUsage { */ input_tokens?: number | null; /** - * Whether input_tokens already includes cached_input_tokens and - * cache_write_input_tokens; absent means unknown. + * Whether input_tokens already includes both cached_input_tokens (cache + * reads) and cache_write_input_tokens (cache writes); absent means + * unknown. True means both are included and false means both are + * excluded. When the provider includes only one of the two, the adapter + * normalizes input_tokens to one of these states before reporting. */ input_tokens_include_cache?: boolean | null; /** diff --git a/crates/fabric-core/src/agent_execution.rs b/crates/fabric-core/src/agent_execution.rs index d70526243..6ecc95095 100644 --- a/crates/fabric-core/src/agent_execution.rs +++ b/crates/fabric-core/src/agent_execution.rs @@ -98,8 +98,11 @@ pub struct AgentUsage { #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(max = u64::MAX))] pub cache_write_input_tokens: Option, - /// Whether input_tokens already includes cached_input_tokens and - /// cache_write_input_tokens; absent means unknown. + /// Whether input_tokens already includes both cached_input_tokens (cache + /// reads) and cache_write_input_tokens (cache writes); absent means + /// unknown. True means both are included and false means both are + /// excluded. When the provider includes only one of the two, the adapter + /// normalizes input_tokens to one of these states before reporting. #[serde(default, skip_serializing_if = "Option::is_none")] pub input_tokens_include_cache: Option, /// Output tokens produced by the invocation. @@ -162,8 +165,11 @@ pub struct AgentModelUsage { #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(max = u64::MAX))] pub cache_write_input_tokens: Option, - /// Whether input_tokens already includes cached_input_tokens and - /// cache_write_input_tokens; absent means unknown. + /// Whether input_tokens already includes both cached_input_tokens (cache + /// reads) and cache_write_input_tokens (cache writes); absent means + /// unknown. True means both are included and false means both are + /// excluded. When the provider includes only one of the two, the adapter + /// normalizes input_tokens to one of these states before reporting. #[serde(default, skip_serializing_if = "Option::is_none")] pub input_tokens_include_cache: Option, /// Output tokens produced by this model. diff --git a/docs/adapter-contract/tutorials/results.md b/docs/adapter-contract/tutorials/results.md index 662ccdf9c..ac40ec645 100644 --- a/docs/adapter-contract/tutorials/results.md +++ b/docs/adapter-contract/tutorials/results.md @@ -75,7 +75,7 @@ for the exact shape. A failed result contains an error; a successful result does not contain a non-null error. Status is explicit and is not inferred from arbitrary output fields. -Report only observed invocation usage. For cumulative target counters, compute the difference between successive observations; do not sum cumulative snapshots or substitute the last model response for an entire invocation. Missing and reset counters remain unknown. `cached_input_tokens` records cached prompt tokens and `cache_write_input_tokens` records prompt tokens written to the provider cache; `input_tokens_include_cache` declares whether both are included in `input_tokens` (`True`), excluded (`False`), or unknown (absent). `reasoning_tokens` records reasoning output, and `output_tokens_include_reasoning` declares whether it is included in `output_tokens` with the same three states. `peak_request_input_tokens` records the input size of the largest single model request, including cached and cache-write input. Keep estimates separate from `cost_usd`, and retain available usage on unsuccessful terminal results. +Report only observed invocation usage. For cumulative target counters, compute the difference between successive observations; do not sum cumulative snapshots or substitute the last model response for an entire invocation. Missing and reset counters remain unknown. `cached_input_tokens` records cached prompt tokens and `cache_write_input_tokens` records prompt tokens written to the provider cache; `input_tokens_include_cache` declares whether both are included in `input_tokens` (`True`), excluded (`False`), or unknown (absent). The flag has no state for a provider that includes only one of the two, so normalize `input_tokens` first: add the excluded count to report `True`, or subtract the included count to report `False`. `reasoning_tokens` records reasoning output, and `output_tokens_include_reasoning` declares whether it is included in `output_tokens` with the same three states. `peak_request_input_tokens` records the input size of the largest single model request, including cached and cache-write input. Keep estimates separate from `cost_usd`, and retain available usage on unsuccessful terminal results. When the target reports usage per model, add one `AgentModelUsage` entry per model to `usage.models`. Each entry requires a non-blank `model`, accepts an optional non-blank `provider`, and uses the same token, flag, and cost fields as `AgentUsage`. A provider and model pair can appear only once, compared case-insensitively. Model entries have no `extensions`; keep adapter-owned usage data in `usage.extensions`. diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx index 56584cddf..a24c98d04 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx @@ -40,7 +40,7 @@ Input tokens this model wrote to the provider prompt cache, when reported. ### `input_tokens_include_cache: Option` -Whether input_tokens already includes cached_input_tokens and cache_write_input_tokens; absent means unknown. +Whether input_tokens already includes both cached_input_tokens (cache reads) and cache_write_input_tokens (cache writes); absent means unknown. True means both are included and false means both are excluded. When the provider includes only one of the two, the adapter normalizes input_tokens to one of these states before reporting. ### `output_tokens: Option` diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx index 07bdb9ce6..8ca526395 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx @@ -30,7 +30,7 @@ Input tokens written to the provider prompt cache, when reported. ### `input_tokens_include_cache: Option` -Whether input_tokens already includes cached_input_tokens and cache_write_input_tokens; absent means unknown. +Whether input_tokens already includes both cached_input_tokens (cache reads) and cache_write_input_tokens (cache writes); absent means unknown. True means both are included and false means both are excluded. When the provider includes only one of the two, the adapter normalizes input_tokens to one of these states before reporting. ### `output_tokens: Option` diff --git a/schemas/adapter-contract/agent-run-result.schema.json b/schemas/adapter-contract/agent-run-result.schema.json index 0fa80398a..4d60979e0 100644 --- a/schemas/adapter-contract/agent-run-result.schema.json +++ b/schemas/adapter-contract/agent-run-result.schema.json @@ -101,7 +101,7 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes cached_input_tokens and\ncache_write_input_tokens; absent means unknown.", + "description": "Whether input_tokens already includes both cached_input_tokens (cache\nreads) and cache_write_input_tokens (cache writes); absent means\nunknown. True means both are included and false means both are\nexcluded. When the provider includes only one of the two, the adapter\nnormalizes input_tokens to one of these states before reporting.", "type": [ "boolean", "null" @@ -277,7 +277,7 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes cached_input_tokens and\ncache_write_input_tokens; absent means unknown.", + "description": "Whether input_tokens already includes both cached_input_tokens (cache\nreads) and cache_write_input_tokens (cache writes); absent means\nunknown. True means both are included and false means both are\nexcluded. When the provider includes only one of the two, the adapter\nnormalizes input_tokens to one of these states before reporting.", "type": [ "boolean", "null" diff --git a/skills/nemo-fabric-build-adapter/SKILL.md b/skills/nemo-fabric-build-adapter/SKILL.md index 72984d50d..1de21c550 100644 --- a/skills/nemo-fabric-build-adapter/SKILL.md +++ b/skills/nemo-fabric-build-adapter/SKILL.md @@ -228,7 +228,7 @@ required artifact references, and live workspace state may persist until telemetry scopes reset for each `invoke`. Independent runtime instances must never share mutable continuation state. -Normalize usage per invocation in `AgentUsage`. If the target reports cumulative session totals, retain a session-local baseline and difference successive observed counters rather than summing cumulative snapshots or using only the last model response. Missing or reset counters remain unknown. Report `cached_input_tokens` and `cache_write_input_tokens` when available and declare whether `input_tokens` includes them with `input_tokens_include_cache`; report `reasoning_tokens` with `output_tokens_include_reasoning` the same way. Omit a flag when the target's semantics are unknown. Report `peak_request_input_tokens` only when the target exposes per-request input counts. When the target reports usage per model, add one `AgentModelUsage` entry per provider and model pair to `usage.models`; NeMo Fabric rejects blank model identifiers and case-insensitive duplicates. NeMo Fabric does not copy cache-write, reasoning, peak request, or per-model usage into the consumer `RunResult.usage`. Preserve available usage on unsuccessful terminal results. Do not infer missing cost or promote estimates to `cost_usd`. +Normalize usage per invocation in `AgentUsage`. If the target reports cumulative session totals, retain a session-local baseline and difference successive observed counters rather than summing cumulative snapshots or using only the last model response. Missing or reset counters remain unknown. Report `cached_input_tokens` and `cache_write_input_tokens` when available and declare whether `input_tokens` includes both of them with `input_tokens_include_cache`; report `reasoning_tokens` with `output_tokens_include_reasoning` the same way. If the provider includes only one of the two cache counts in `input_tokens`, normalize `input_tokens` so that both are included or both are excluded before setting the flag. Omit a flag when the target's semantics are unknown. Report `peak_request_input_tokens` only when the target exposes per-request input counts. When the target reports usage per model, add one `AgentModelUsage` entry per provider and model pair to `usage.models`; NeMo Fabric rejects blank model identifiers and case-insensitive duplicates. NeMo Fabric does not copy cache-write, reasoning, peak request, or per-model usage into the consumer `RunResult.usage`. Preserve available usage on unsuccessful terminal results. Do not infer missing cost or promote estimates to `cost_usd`. Test observable continuation rather than merely calling `invoke` twice: make the second result depend on the first turn without caller-side replay, then From 2e4f5958ededf27c3d34c6cd873e647c9d858c26 Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Mon, 12 Oct 2026 13:01:34 -0700 Subject: [PATCH 07/10] fix: preserve detailed usage compatibility Signed-off-by: mnajafian-nv --- .agents/skills/contribute-adapter/SKILL.md | 2 +- .../nemo_fabric_adapter_contract/models.py | 84 +--- .../schemas/agent-run-result.schema.json | 164 +------- .../src/generated/agent-run-result.ts | 93 +---- .../typescript/test/stable.test.ts | 31 -- crates/fabric-core/src/agent_execution.rs | 381 ++---------------- crates/fabric-core/src/lib.rs | 4 +- crates/fabric-core/src/runtime.rs | 106 +++-- crates/fabric-core/src/schema.rs | 61 +-- docs/adapter-contract/tutorials/results.md | 8 +- .../nemo_fabric.types.md | 2 +- .../adapter-contract/index.mdx | 2 +- .../nemo-fabric-core/agent-config/index.mdx | 2 +- .../agent-config/struct-agentconfig.mdx | 2 +- .../struct-agentharnessconfig.mdx | 2 +- .../struct-agentinstructionconfig.mdx | 2 +- .../struct-agentinstructionsconfig.mdx | 2 +- .../agent-config/struct-agentmcpconfig.mdx | 2 +- .../struct-agentmcpserverconfig.mdx | 2 +- .../agent-config/struct-agentmodelconfig.mdx | 2 +- .../struct-agentruntimeconfig.mdx | 2 +- .../agent-config/struct-agentskillconfig.mdx | 2 +- .../struct-agenttooldefinition.mdx | 2 +- .../agent-config/struct-agenttoolsconfig.mdx | 2 +- .../struct-agentworkflowconfig.mdx | 2 +- .../struct-agentworkflowentrypointconfig.mdx | 2 +- .../enum-agentrunresultvalidationerror.mdx | 16 +- .../agent-execution/enum-agentrunstatus.mdx | 2 +- .../agent-execution/index.mdx | 3 +- .../struct-agentmodelusage.mdx | 149 ------- .../agent-execution/struct-agentrunerror.mdx | 2 +- .../struct-agentrunrequest.mdx | 2 +- .../agent-execution/struct-agentrunresult.mdx | 4 +- .../agent-execution/struct-agentusage.mdx | 26 +- .../config/enum-adapterconfigfield.mdx | 2 +- .../config/enum-adapterkind.mdx | 2 +- .../config/enum-adaptertarget.mdx | 2 +- .../config/enum-adaptertargettype.mdx | 2 +- .../config/enum-controllocation.mdx | 2 +- .../config/enum-descriptorsource.mdx | 2 +- .../config/enum-environmentownership.mdx | 2 +- .../config/enum-instructionmode.mdx | 2 +- .../config/enum-mcpauthenticationconfig.mdx | 2 +- .../config/enum-mcpexposure.mdx | 2 +- .../config/enum-mcptransport.mdx | 2 +- .../enum-oauthtokenendpointauthmethod.mdx | 2 +- .../config/enum-resolutionstrategy.mdx | 2 +- .../config/enum-telemetryprovider.mdx | 2 +- .../config/fn-load-adapter-descriptor.mdx | 2 +- .../fn-load-adapter-target-descriptor.mdx | 2 +- .../fn-resolve-run-plan-from-config.mdx | 2 +- .../nemo-fabric-core/config/index.mdx | 2 +- .../config/struct-adapterconfigsupport.mdx | 2 +- .../config/struct-adapterdescriptor.mdx | 2 +- .../config/struct-adapterrequirements.mdx | 2 +- .../config/struct-adaptertargetdescriptor.mdx | 2 +- ...struct-adaptertelemetryprovidersupport.mdx | 2 +- .../config/struct-adaptertelemetrysupport.mdx | 2 +- .../config/struct-capabilityplan.mdx | 2 +- .../config/struct-descriptorprovenance.mdx | 2 +- .../config/struct-discoveryconfig.mdx | 2 +- .../config/struct-environmentconfig.mdx | 2 +- .../config/struct-environmentplan.mdx | 2 +- .../config/struct-fabricconfig.mdx | 2 +- .../config/struct-harnessconfig.mdx | 2 +- .../config/struct-instructionconfig.mdx | 2 +- .../config/struct-instructionsconfig.mdx | 2 +- .../config/struct-mcpconfig.mdx | 2 +- .../config/struct-mcpserverplan.mdx | 2 +- .../config/struct-metadataconfig.mdx | 2 +- .../config/struct-modelconfig.mdx | 2 +- .../config/struct-resolvecontext.mdx | 2 +- .../struct-resolvedadapterdescriptor.mdx | 2 +- ...struct-resolvedadaptertargetdescriptor.mdx | 2 +- .../config/struct-runplan.mdx | 2 +- .../config/struct-runtimecapabilities.mdx | 2 +- .../config/struct-runtimeconfig.mdx | 2 +- .../config/struct-skillconfig.mdx | 2 +- .../config/struct-telemetryconfig.mdx | 2 +- .../config/struct-telemetryplan.mdx | 2 +- .../config/struct-telemetryproviderconfig.mdx | 2 +- .../config/struct-tooldefinitionconfig.mdx | 2 +- .../config/struct-toolsconfig.mdx | 2 +- .../config/struct-workflowconfig.mdx | 2 +- .../struct-workflowentrypointconfig.mdx | 2 +- .../config/struct-workflowtargetspec.mdx | 2 +- .../doctor/enum-doctorstatus.mdx | 2 +- .../doctor/fn-doctor-plan.mdx | 2 +- .../nemo-fabric-core/doctor/index.mdx | 2 +- .../doctor/struct-doctorcheck.mdx | 2 +- .../doctor/struct-doctorreport.mdx | 2 +- .../error/enum-fabricerror.mdx | 2 +- .../nemo-fabric-core/error/index.mdx | 2 +- .../nemo-fabric-core/error/type-result.mdx | 2 +- .../nemo-fabric-core/fn-version.mdx | 2 +- .../nemo-fabric-core/index.mdx | 1 - .../nemo-fabric-core/runtime/index.mdx | 2 +- .../runtime/struct-runusage.mdx | 2 +- .../nemo-fabric-core/schema/index.mdx | 2 +- docs/sdk/python.mdx | 2 +- .../agent-run-result.schema.json | 164 +------- schemas/sdk/run-result.schema.json | 2 +- .../integrations/harbor/fabric_agent.py | 105 ++++- .../src/nemo_fabric/types.py | 6 +- skills/nemo-fabric-build-adapter/SKILL.md | 2 +- .../references/results-and-errors.md | 2 +- .../adapter_contract/test_agent_execution.py | 146 +------ tests/python/test_harbor_accounting.py | 105 +++++ 108 files changed, 420 insertions(+), 1413 deletions(-) delete mode 100644 docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx diff --git a/.agents/skills/contribute-adapter/SKILL.md b/.agents/skills/contribute-adapter/SKILL.md index c9f04996b..c2e8c62e7 100644 --- a/.agents/skills/contribute-adapter/SKILL.md +++ b/.agents/skills/contribute-adapter/SKILL.md @@ -57,7 +57,7 @@ Keep descriptor claims, implementation, focused tests, public documentation, catalog entries, and packaged metadata synchronized. Start with the narrowest truthful capability set. -For usage changes, verify invocation-local accounting through the adapter contract and consumer SDK, including warm-session deltas, unknown counters, cache semantics, and unsuccessful results. Keep generated schemas and language bindings in parity; use the shared cache, cache-write, reasoning, peak request, and per-model `AgentUsage` fields instead of consumer-specific parsing of native output. +For usage changes, verify invocation-local accounting through the adapter contract and consumer SDK, including warm-session deltas, unknown counters, cache semantics, and unsuccessful results. Keep generated schemas and language bindings in parity. Preserve the closed `fabric.adapter/v1alpha2` `AgentUsage` shape; carry detailed cache-write, reasoning, peak request, and per-model data in the descriptor-declared `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` object until a new adapter contract revision negotiates those fields. For `instructions.system`, keep `config.system_instruction_modes`, planning behavior, direct adapter validation, and target-native composition synchronized. diff --git a/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py b/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py index 030470dc5..1f82b1658 100644 --- a/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py +++ b/adapter-contract/python/src/nemo_fabric_adapter_contract/models.py @@ -499,94 +499,26 @@ def _validate(self) -> None: _nonblank(self.media_type, "media_type") -_USAGE_TOKEN_FIELDS = ( - "input_tokens", - "cached_input_tokens", - "cache_write_input_tokens", - "output_tokens", - "reasoning_tokens", - "total_tokens", - "peak_request_input_tokens", -) - - -def _validate_usage_counts(usage: AgentUsage | AgentModelUsage) -> None: - for field_name in _USAGE_TOKEN_FIELDS: - _bounded_int(getattr(usage, field_name), field_name, (1 << 64) - 1) - if usage.cost_usd is not None and usage.cost_usd < 0: - raise ContractValidationError( - "must be greater than or equal to 0", path=("cost_usd",) - ) - - @dataclass(slots=True, kw_only=True) -class AgentModelUsage(ContractModel): - """Usage of one model within one invocation. - - Token fields have the same meaning as the matching ``AgentUsage`` fields, - restricted to requests served by this model. - """ +class AgentUsage(AgentContractBlock): + """Normalized model usage reported by an adapter target.""" - model: str - provider: str | None = _optional() input_tokens: int | None = _optional() cached_input_tokens: int | None = _optional() - cache_write_input_tokens: int | None = _optional() input_tokens_include_cache: bool | None = _optional() output_tokens: int | None = _optional() - reasoning_tokens: int | None = _optional() - output_tokens_include_reasoning: bool | None = _optional() total_tokens: int | None = _optional() - peak_request_input_tokens: int | None = _optional() cost_usd: float | None = _optional() def _validate(self) -> None: - _nonblank(self.model, "model") - if self.provider is not None: - _nonblank(self.provider, "provider") - _validate_usage_counts(self) - - -def _validate_unique_models(models: list[AgentModelUsage]) -> None: - reported: set[tuple[str | None, str]] = set() - for index, usage in enumerate(models): - provider = usage.provider.lower() if usage.provider is not None else None - key = (provider, usage.model.lower()) - if key in reported: + _bounded_int(self.input_tokens, "input_tokens", (1 << 64) - 1) + _bounded_int(self.cached_input_tokens, "cached_input_tokens", (1 << 64) - 1) + _bounded_int(self.output_tokens, "output_tokens", (1 << 64) - 1) + _bounded_int(self.total_tokens, "total_tokens", (1 << 64) - 1) + if self.cost_usd is not None and self.cost_usd < 0: raise ContractValidationError( - "must report each provider and model pair once", - path=("models", str(index)), + "must be greater than or equal to 0", path=("cost_usd",) ) - reported.add(key) - - -@dataclass(slots=True, kw_only=True) -class AgentUsage(AgentContractBlock): - """Normalized model usage reported by an adapter target. - - ``input_tokens_include_cache`` covers both ``cached_input_tokens`` and - ``cache_write_input_tokens``: ``True`` means both are included in - ``input_tokens`` and ``False`` means both are excluded. When the provider - includes only one of the two, normalize ``input_tokens`` before reporting. - ``models`` reports each provider and model pair at most once, compared - case-insensitively. - """ - - input_tokens: int | None = _optional() - cached_input_tokens: int | None = _optional() - cache_write_input_tokens: int | None = _optional() - input_tokens_include_cache: bool | None = _optional() - output_tokens: int | None = _optional() - reasoning_tokens: int | None = _optional() - output_tokens_include_reasoning: bool | None = _optional() - total_tokens: int | None = _optional() - peak_request_input_tokens: int | None = _optional() - cost_usd: float | None = _optional() - models: list[AgentModelUsage] = _empty_list() - - def _validate(self) -> None: - _validate_usage_counts(self) - _validate_unique_models(self.models) @dataclass(slots=True, kw_only=True) diff --git a/adapter-contract/typescript/schemas/agent-run-result.schema.json b/adapter-contract/typescript/schemas/agent-run-result.schema.json index 4d60979e0..ee1c450c4 100644 --- a/adapter-contract/typescript/schemas/agent-run-result.schema.json +++ b/adapter-contract/typescript/schemas/agent-run-result.schema.json @@ -57,124 +57,6 @@ ], "type": "object" }, - "AgentModelUsage": { - "additionalProperties": false, - "description": "Usage of one model within one invocation.\n\nToken fields have the same meaning as the matching `AgentUsage` fields,\nrestricted to requests served by this model.", - "properties": { - "cache_write_input_tokens": { - "description": "Input tokens this model wrote to the provider prompt cache, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "cached_input_tokens": { - "description": "Cached input tokens consumed by this model, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "cost_usd": { - "description": "Cost in US dollars for this model when reported by the provider.", - "format": "double", - "minimum": 0.0, - "type": [ - "number", - "null" - ] - }, - "input_tokens": { - "description": "Input tokens consumed by this model.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "input_tokens_include_cache": { - "description": "Whether input_tokens already includes both cached_input_tokens (cache\nreads) and cache_write_input_tokens (cache writes); absent means\nunknown. True means both are included and false means both are\nexcluded. When the provider includes only one of the two, the adapter\nnormalizes input_tokens to one of these states before reporting.", - "type": [ - "boolean", - "null" - ] - }, - "model": { - "description": "Model identifier as reported by the harness or provider response.", - "minLength": 1, - "pattern": "\\S", - "type": "string" - }, - "output_tokens": { - "description": "Output tokens produced by this model.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "output_tokens_include_reasoning": { - "description": "Whether output_tokens already includes reasoning_tokens; absent means unknown.", - "type": [ - "boolean", - "null" - ] - }, - "peak_request_input_tokens": { - "description": "Input tokens of the largest single request served by this model,\nincluding cached and cache-write input, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "provider": { - "description": "Provider or route that served the model, when known.", - "minLength": 1, - "pattern": "\\S", - "type": [ - "string", - "null" - ] - }, - "reasoning_tokens": { - "description": "Reasoning tokens produced by this model, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "total_tokens": { - "description": "Total tokens reported by the provider for this model.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - } - }, - "required": [ - "model" - ], - "type": "object" - }, "AgentRunError": { "additionalProperties": false, "description": "Error reported by an adapter target.", @@ -232,16 +114,6 @@ "additionalProperties": false, "description": "Normalized model usage reported by an adapter target.", "properties": { - "cache_write_input_tokens": { - "description": "Input tokens written to the provider prompt cache, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, "cached_input_tokens": { "description": "Cached input tokens consumed by the invocation, when reported.", "format": "uint64", @@ -277,19 +149,12 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes both cached_input_tokens (cache\nreads) and cache_write_input_tokens (cache writes); absent means\nunknown. True means both are included and false means both are\nexcluded. When the provider includes only one of the two, the adapter\nnormalizes input_tokens to one of these states before reporting.", + "description": "Whether input_tokens already includes cached_input_tokens; absent means unknown.", "type": [ "boolean", "null" ] }, - "models": { - "description": "Usage broken out by the model that served the requests; empty when not\nreported. Each provider and model pair appears at most once, compared\ncase-insensitively.", - "items": { - "$ref": "#/$defs/AgentModelUsage" - }, - "type": "array" - }, "output_tokens": { "description": "Output tokens produced by the invocation.", "format": "uint64", @@ -300,33 +165,6 @@ "null" ] }, - "output_tokens_include_reasoning": { - "description": "Whether output_tokens already includes reasoning_tokens; absent means unknown.", - "type": [ - "boolean", - "null" - ] - }, - "peak_request_input_tokens": { - "description": "Input tokens of the largest single model request in the invocation,\nincluding cached and cache-write input, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "reasoning_tokens": { - "description": "Reasoning tokens produced by the invocation, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, "total_tokens": { "description": "Total tokens reported by the provider.", "format": "uint64", diff --git a/adapter-contract/typescript/src/generated/agent-run-result.ts b/adapter-contract/typescript/src/generated/agent-run-result.ts index a17a1d35b..75bb4a597 100644 --- a/adapter-contract/typescript/src/generated/agent-run-result.ts +++ b/adapter-contract/typescript/src/generated/agent-run-result.ts @@ -86,10 +86,6 @@ export interface AgentArtifact { * via the `definition` "AgentUsage". */ export interface AgentUsage { - /** - * Input tokens written to the provider prompt cache, when reported. - */ - cache_write_input_tokens?: number | null; /** * Cached input tokens consumed by the invocation, when reported. */ @@ -107,105 +103,18 @@ export interface AgentUsage { */ input_tokens?: number | null; /** - * Whether input_tokens already includes both cached_input_tokens (cache - * reads) and cache_write_input_tokens (cache writes); absent means - * unknown. True means both are included and false means both are - * excluded. When the provider includes only one of the two, the adapter - * normalizes input_tokens to one of these states before reporting. + * Whether input_tokens already includes cached_input_tokens; absent means unknown. */ input_tokens_include_cache?: boolean | null; - /** - * Usage broken out by the model that served the requests; empty when not - * reported. Each provider and model pair appears at most once, compared - * case-insensitively. - */ - models?: AgentModelUsage[]; /** * Output tokens produced by the invocation. */ output_tokens?: number | null; - /** - * Whether output_tokens already includes reasoning_tokens; absent means unknown. - */ - output_tokens_include_reasoning?: boolean | null; - /** - * Input tokens of the largest single model request in the invocation, - * including cached and cache-write input, when reported. - */ - peak_request_input_tokens?: number | null; - /** - * Reasoning tokens produced by the invocation, when reported. - */ - reasoning_tokens?: number | null; /** * Total tokens reported by the provider. */ total_tokens?: number | null; } -/** - * Usage of one model within one invocation. - * - * Token fields have the same meaning as the matching `AgentUsage` fields, - * restricted to requests served by this model. - * - * This interface was referenced by `AgentRunResultCommon`'s JSON-Schema - * via the `definition` "AgentModelUsage". - */ -export interface AgentModelUsage { - /** - * Input tokens this model wrote to the provider prompt cache, when reported. - */ - cache_write_input_tokens?: number | null; - /** - * Cached input tokens consumed by this model, when reported. - */ - cached_input_tokens?: number | null; - /** - * Cost in US dollars for this model when reported by the provider. - */ - cost_usd?: number | null; - /** - * Input tokens consumed by this model. - */ - input_tokens?: number | null; - /** - * Whether input_tokens already includes both cached_input_tokens (cache - * reads) and cache_write_input_tokens (cache writes); absent means - * unknown. True means both are included and false means both are - * excluded. When the provider includes only one of the two, the adapter - * normalizes input_tokens to one of these states before reporting. - */ - input_tokens_include_cache?: boolean | null; - /** - * Model identifier as reported by the harness or provider response. - */ - model: string; - /** - * Output tokens produced by this model. - */ - output_tokens?: number | null; - /** - * Whether output_tokens already includes reasoning_tokens; absent means unknown. - */ - output_tokens_include_reasoning?: boolean | null; - /** - * Input tokens of the largest single request served by this model, - * including cached and cache-write input, when reported. - */ - peak_request_input_tokens?: number | null; - /** - * Provider or route that served the model, when known. - */ - provider?: string | null; - /** - * Reasoning tokens produced by this model, when reported. - */ - reasoning_tokens?: number | null; - /** - * Total tokens reported by the provider for this model. - */ - total_tokens?: number | null; -} /** * Error reported by an adapter target. * diff --git a/adapter-contract/typescript/test/stable.test.ts b/adapter-contract/typescript/test/stable.test.ts index defb47c39..70e1db53e 100644 --- a/adapter-contract/typescript/test/stable.test.ts +++ b/adapter-contract/typescript/test/stable.test.ts @@ -9,7 +9,6 @@ import type { AdapterTargetDescriptor, AdapterTelemetryProviderSupport, AgentConfig, - AgentModelUsage, AgentUsage, ControlLocation, EnvironmentOwnership, @@ -43,36 +42,6 @@ const invalidCacheSemantics: AgentUsage = { void usage; void invalidCacheSemantics; -const detailedUsage: AgentUsage = { - cache_write_input_tokens: 3, - output_tokens: 12, - output_tokens_include_reasoning: true, - peak_request_input_tokens: 18, - reasoning_tokens: 8, - models: [ - { - model: "example-model", - provider: "example-provider", - reasoning_tokens: 8, - }, - ], -}; -const invalidReasoningSemantics: AgentUsage = { - // @ts-expect-error reasoning semantics require an explicit boolean, not a numeric flag - output_tokens_include_reasoning: 1, -}; -// @ts-expect-error model usage requires the model identifier -const modelUsageWithoutModel: AgentModelUsage = { provider: "example-provider" }; -const modelUsageWithUnknownField: AgentModelUsage = { - model: "example-model", - // @ts-expect-error closed model usage objects reject unknown keys - reasoning: 1, -}; -void detailedUsage; -void invalidReasoningSemantics; -void modelUsageWithoutModel; -void modelUsageWithUnknownField; - const target: AdapterTargetDescriptor = { adapter_id: "pi", contract_version: ADAPTER_CONTRACT_VERSION, diff --git a/crates/fabric-core/src/agent_execution.rs b/crates/fabric-core/src/agent_execution.rs index 6ecc95095..aafb14cc1 100644 --- a/crates/fabric-core/src/agent_execution.rs +++ b/crates/fabric-core/src/agent_execution.rs @@ -3,7 +3,7 @@ //! Request and result structures exchanged with an adapter target. -use std::collections::{BTreeMap, HashSet}; +use std::collections::BTreeMap; use std::path::{Component, Path, PathBuf}; use schemars::{JsonSchema, Schema, SchemaGenerator}; @@ -94,110 +94,26 @@ pub struct AgentUsage { #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(max = u64::MAX))] pub cached_input_tokens: Option, - /// Input tokens written to the provider prompt cache, when reported. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub cache_write_input_tokens: Option, - /// Whether input_tokens already includes both cached_input_tokens (cache - /// reads) and cache_write_input_tokens (cache writes); absent means - /// unknown. True means both are included and false means both are - /// excluded. When the provider includes only one of the two, the adapter - /// normalizes input_tokens to one of these states before reporting. + /// Whether input_tokens already includes cached_input_tokens; absent means unknown. #[serde(default, skip_serializing_if = "Option::is_none")] pub input_tokens_include_cache: Option, /// Output tokens produced by the invocation. #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(max = u64::MAX))] pub output_tokens: Option, - /// Reasoning tokens produced by the invocation, when reported. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub reasoning_tokens: Option, - /// Whether output_tokens already includes reasoning_tokens; absent means unknown. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub output_tokens_include_reasoning: Option, /// Total tokens reported by the provider. #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(max = u64::MAX))] pub total_tokens: Option, - /// Input tokens of the largest single model request in the invocation, - /// including cached and cache-write input, when reported. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub peak_request_input_tokens: Option, /// Invocation cost in US dollars when reported by the provider. #[serde(default, skip_serializing_if = "Option::is_none")] #[schemars(range(min = 0.0))] pub cost_usd: Option, - /// Usage broken out by the model that served the requests; empty when not - /// reported. Each provider and model pair appears at most once, compared - /// case-insensitively. - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub models: Vec, /// Adapter-owned usage fields. #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub extensions: BTreeMap, } -/// Usage of one model within one invocation. -/// -/// Token fields have the same meaning as the matching `AgentUsage` fields, -/// restricted to requests served by this model. -#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, JsonSchema)] -#[serde(deny_unknown_fields)] -pub struct AgentModelUsage { - /// Model identifier as reported by the harness or provider response. - #[schemars(length(min = 1), regex(pattern = r"\S"))] - pub model: String, - /// Provider or route that served the model, when known. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(length(min = 1), regex(pattern = r"\S"))] - pub provider: Option, - /// Input tokens consumed by this model. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub input_tokens: Option, - /// Cached input tokens consumed by this model, when reported. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub cached_input_tokens: Option, - /// Input tokens this model wrote to the provider prompt cache, when reported. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub cache_write_input_tokens: Option, - /// Whether input_tokens already includes both cached_input_tokens (cache - /// reads) and cache_write_input_tokens (cache writes); absent means - /// unknown. True means both are included and false means both are - /// excluded. When the provider includes only one of the two, the adapter - /// normalizes input_tokens to one of these states before reporting. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub input_tokens_include_cache: Option, - /// Output tokens produced by this model. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub output_tokens: Option, - /// Reasoning tokens produced by this model, when reported. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub reasoning_tokens: Option, - /// Whether output_tokens already includes reasoning_tokens; absent means unknown. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub output_tokens_include_reasoning: Option, - /// Total tokens reported by the provider for this model. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub total_tokens: Option, - /// Input tokens of the largest single request served by this model, - /// including cached and cache-write input, when reported. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(max = u64::MAX))] - pub peak_request_input_tokens: Option, - /// Cost in US dollars for this model when reported by the provider. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[schemars(range(min = 0.0))] - pub cost_usd: Option, -} - /// Southbound terminal result returned by an adapter target. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)] #[serde(deny_unknown_fields)] @@ -236,16 +152,10 @@ pub enum AgentRunResultValidationError { /// An artifact path was blank, absolute, or contained parent traversal. #[error("artifact path must be non-blank and relative, and contain no parent traversal: {0}")] InvalidArtifactPath(PathBuf), - /// Model usage repeated a provider and model pair, compared case-insensitively. - #[error("usage.models must report each provider and model pair once: {0}")] - DuplicateModelUsage(String), - /// A cost was negative or not a finite number. - #[error("{0} must be a finite number greater than or equal to 0")] - InvalidCost(&'static str), } impl AgentRunResult { - /// Validate terminal status, error, usage, and artifact invariants. + /// Validate terminal status, error, and artifact invariants. pub fn validate(&self) -> std::result::Result<(), AgentRunResultValidationError> { match (self.status, self.error.as_ref()) { (AgentRunStatus::Failed, None) => { @@ -260,9 +170,6 @@ impl AgentRunResult { validate_nonblank(&error.code, "error.code")?; validate_nonblank(&error.message, "error.message")?; } - if let Some(usage) = &self.usage { - validate_model_usage(&usage.models)?; - } for artifact in &self.artifacts { validate_nonblank(&artifact.name, "artifacts.name")?; validate_nonblank(&artifact.kind, "artifacts.kind")?; @@ -279,46 +186,6 @@ impl AgentRunResult { } } -fn validate_model_usage( - models: &[AgentModelUsage], -) -> std::result::Result<(), AgentRunResultValidationError> { - let mut reported = HashSet::with_capacity(models.len()); - for model_usage in models { - validate_nonblank(&model_usage.model, "usage.models.model")?; - if let Some(provider) = &model_usage.provider { - validate_nonblank(provider, "usage.models.provider")?; - } - if let Some(cost_usd) = model_usage.cost_usd { - validate_cost(cost_usd, "usage.models.cost_usd")?; - } - let key = ( - model_usage.provider.as_deref().map(str::to_lowercase), - model_usage.model.to_lowercase(), - ); - if !reported.insert(key) { - let duplicate = match &model_usage.provider { - Some(provider) => format!("provider {provider:?}, model {:?}", model_usage.model), - None => format!("model {:?}", model_usage.model), - }; - return Err(AgentRunResultValidationError::DuplicateModelUsage( - duplicate, - )); - } - } - Ok(()) -} - -fn validate_cost( - cost_usd: f64, - field: &'static str, -) -> std::result::Result<(), AgentRunResultValidationError> { - if cost_usd.is_finite() && cost_usd >= 0.0 { - Ok(()) - } else { - Err(AgentRunResultValidationError::InvalidCost(field)) - } -} - fn validate_nonblank( value: &str, field: &'static str, @@ -570,230 +437,34 @@ mod tests { } } - fn result_with_usage(usage: Value) -> AgentRunResult { - serde_json::from_value(serde_json::json!({ - "status": "succeeded", - "output": null, - "usage": usage - })) - .expect("usage payload deserializes") - } - - fn model_usage(provider: Option<&str>, model: &str) -> AgentModelUsage { - AgentModelUsage { - model: model.to_string(), - provider: provider.map(str::to_string), - ..AgentModelUsage::default() - } - } - - fn result_with_models(models: Vec) -> AgentRunResult { - AgentRunResult { - status: AgentRunStatus::Succeeded, - output: Value::Null, - error: None, - usage: Some(AgentUsage { - models, - ..AgentUsage::default() - }), - artifacts: Vec::new(), - extensions: BTreeMap::new(), - } - } - #[test] - fn detailed_usage_round_trips_every_field() { - let payload = serde_json::json!({ - "input_tokens": 1200, - "cached_input_tokens": 800, - "cache_write_input_tokens": 300, - "input_tokens_include_cache": true, - "output_tokens": 90, - "reasoning_tokens": 40, - "output_tokens_include_reasoning": false, - "total_tokens": 1330, - "peak_request_input_tokens": 700, - "cost_usd": 0.5, - "models": [{ - "model": "planner-model", - "provider": "openai", - "input_tokens": 1000, - "cached_input_tokens": 700, - "cache_write_input_tokens": 250, - "input_tokens_include_cache": true, - "output_tokens": 60, - "reasoning_tokens": 30, - "output_tokens_include_reasoning": true, - "total_tokens": 1060, - "peak_request_input_tokens": 600, - "cost_usd": 0.375 - }, { - "model": "summarizer-model" - }], - "extensions": {"source": "native"} - }); - - let usage: AgentUsage = - serde_json::from_value(payload.clone()).expect("detailed usage deserializes"); - - assert_eq!( - usage, - AgentUsage { - input_tokens: Some(1200), - cached_input_tokens: Some(800), - cache_write_input_tokens: Some(300), - input_tokens_include_cache: Some(true), - output_tokens: Some(90), - reasoning_tokens: Some(40), - output_tokens_include_reasoning: Some(false), - total_tokens: Some(1330), - peak_request_input_tokens: Some(700), - cost_usd: Some(0.5), - models: vec![ - AgentModelUsage { - model: "planner-model".to_string(), - provider: Some("openai".to_string()), - input_tokens: Some(1000), - cached_input_tokens: Some(700), - cache_write_input_tokens: Some(250), - input_tokens_include_cache: Some(true), - output_tokens: Some(60), - reasoning_tokens: Some(30), - output_tokens_include_reasoning: Some(true), - total_tokens: Some(1060), - peak_request_input_tokens: Some(600), - cost_usd: Some(0.375), - }, - model_usage(None, "summarizer-model"), - ], - extensions: BTreeMap::from([("source".to_string(), serde_json::json!("native"),)]), - } - ); - assert_eq!( - serde_json::to_value(&usage).expect("serialize usage"), - payload + fn v1alpha2_usage_keeps_detailed_fields_in_extensions() { + let error = serde_json::from_value::(serde_json::json!({ + "cache_write_input_tokens": 3 + })) + .expect_err("the closed v1alpha2 usage root rejects new fields"); + assert!( + error + .to_string() + .contains("unknown field `cache_write_input_tokens`") ); - assert_eq!(result_with_usage(payload).validate(), Ok(())); - } - - #[test] - fn usage_without_detailed_fields_keeps_its_wire_shape() { - let payload = serde_json::json!({ - "input_tokens": 3, - "cached_input_tokens": 1, - "input_tokens_include_cache": true, - "output_tokens": 5, - "total_tokens": 8, - "cost_usd": 0.25 - }); - let result = result_with_usage(payload.clone()); + let usage = serde_json::from_value::(serde_json::json!({ + "extensions": { + "nemo_fabric.detailed_token_usage.v1": { + "cache_write_input_tokens": 3, + "reasoning_tokens": 4 + } + } + })) + .expect("v1alpha2 usage extensions accept detailed accounting"); - assert_eq!(result.validate(), Ok(())); - let usage = result.usage.expect("usage"); - assert!(usage.models.is_empty()); assert_eq!( - serde_json::to_value(&usage).expect("serialize usage"), - payload + usage.extensions["nemo_fabric.detailed_token_usage.v1"], + serde_json::json!({ + "cache_write_input_tokens": 3, + "reasoning_tokens": 4 + }) ); } - - #[test] - fn model_usage_rejects_unknown_fields() { - for field in ["reasoning", "extensions"] { - let error = serde_json::from_value::(serde_json::json!({ - "models": [{"model": "planner-model", field: {}}] - })) - .expect_err("model usage is a closed object"); - - assert!( - error - .to_string() - .contains(&format!("unknown field `{field}`")), - "{error}" - ); - } - } - - #[test] - fn rejects_blank_model_usage_identifiers() { - for (models, field) in [ - (vec![model_usage(None, " \t")], "usage.models.model"), - ( - vec![model_usage(Some(" \t"), "planner-model")], - "usage.models.provider", - ), - ] { - assert_eq!( - result_with_models(models).validate(), - Err(AgentRunResultValidationError::BlankField(field)) - ); - } - } - - #[test] - fn rejects_duplicate_model_usage_case_insensitively() { - for (models, duplicate) in [ - ( - vec![ - model_usage(None, "planner-model"), - model_usage(None, "Planner-Model"), - ], - r#"model "Planner-Model""#, - ), - ( - vec![ - model_usage(Some("openai"), "planner-model"), - model_usage(Some("OpenAI"), "PLANNER-MODEL"), - ], - r#"provider "OpenAI", model "PLANNER-MODEL""#, - ), - ] { - assert_eq!( - result_with_models(models).validate(), - Err(AgentRunResultValidationError::DuplicateModelUsage( - duplicate.to_string() - )) - ); - } - } - - #[test] - fn rejects_negative_or_non_finite_model_usage_cost() { - for cost_usd in [-0.01, f64::NAN, f64::INFINITY, f64::NEG_INFINITY] { - let models = vec![AgentModelUsage { - cost_usd: Some(cost_usd), - ..model_usage(None, "planner-model") - }]; - - assert_eq!( - result_with_models(models).validate(), - Err(AgentRunResultValidationError::InvalidCost( - "usage.models.cost_usd" - )), - "cost_usd {cost_usd}" - ); - } - } - - #[test] - fn accepts_zero_model_usage_cost() { - let models = vec![AgentModelUsage { - cost_usd: Some(0.0), - ..model_usage(None, "planner-model") - }]; - - assert_eq!(result_with_models(models).validate(), Ok(())); - } - - #[test] - fn accepts_one_model_served_by_distinct_providers() { - let result = result_with_models(vec![ - model_usage(None, "planner-model"), - model_usage(Some("openai"), "planner-model"), - model_usage(Some("azure"), "planner-model"), - ]); - - assert_eq!(result.validate(), Ok(())); - } } diff --git a/crates/fabric-core/src/lib.rs b/crates/fabric-core/src/lib.rs index 96217af11..2dc251c9f 100644 --- a/crates/fabric-core/src/lib.rs +++ b/crates/fabric-core/src/lib.rs @@ -14,8 +14,8 @@ pub mod schema; pub use adapter_contract::{ADAPTER_CONTRACT_VERSION, AdapterExtensionPoint}; pub use agent_execution::{ - AgentArtifact, AgentModelUsage, AgentRunError, AgentRunRequest, AgentRunResult, - AgentRunResultValidationError, AgentRunStatus, AgentUsage, + AgentArtifact, AgentRunError, AgentRunRequest, AgentRunResult, AgentRunResultValidationError, + AgentRunStatus, AgentUsage, }; pub use config::{ AdapterConfigField, AdapterConfigSupport, AdapterDescriptor, AdapterInspection, AdapterKind, diff --git a/crates/fabric-core/src/runtime.rs b/crates/fabric-core/src/runtime.rs index 880d23c41..959d2039d 100644 --- a/crates/fabric-core/src/runtime.rs +++ b/crates/fabric-core/src/runtime.rs @@ -186,10 +186,7 @@ pub struct RunUsage { /// Cached input tokens consumed by the invocation, when reported. #[serde(default, skip_serializing_if = "Option::is_none")] pub cached_input_tokens: Option, - /// Whether input_tokens already includes cached_input_tokens and any - /// cache-write input tokens the adapter reported; absent means unknown. - /// RunUsage does not report cache-write input tokens, so input_tokens plus - /// cached_input_tokens can understate total input when this is false. + /// Whether input_tokens already includes cached_input_tokens; absent means unknown. #[serde(default, skip_serializing_if = "Option::is_none")] pub input_tokens_include_cache: Option, /// Output tokens produced by the invocation. @@ -3455,7 +3452,38 @@ mod tests { }, "usage": { "type": "object", - "properties": {"provider": {"type": "string"}}, + "properties": { + "provider": {"type": "string"}, + "nemo_fabric.detailed_token_usage.v1": { + "type": "object", + "properties": { + "input_tokens": {"type": "integer", "minimum": 0}, + "cached_input_tokens": {"type": "integer", "minimum": 0}, + "cache_write_input_tokens": {"type": "integer", "minimum": 0}, + "input_tokens_include_cache": {"type": "boolean"}, + "output_tokens": {"type": "integer", "minimum": 0}, + "reasoning_tokens": {"type": "integer", "minimum": 0}, + "output_tokens_include_reasoning": {"type": "boolean"}, + "total_tokens": {"type": "integer", "minimum": 0}, + "peak_request_input_tokens": {"type": "integer", "minimum": 0}, + "models": { + "type": "array", + "items": { + "type": "object", + "properties": { + "model": {"type": "string", "minLength": 1}, + "provider": {"type": "string", "minLength": 1}, + "input_tokens": {"type": "integer", "minimum": 0}, + "reasoning_tokens": {"type": "integer", "minimum": 0} + }, + "required": ["model"], + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + }, "additionalProperties": false }, "artifact": { @@ -3663,21 +3691,30 @@ for line in sys.stdin: "usage": { "input_tokens": 3, "cached_input_tokens": 1, - "cache_write_input_tokens": 2, "input_tokens_include_cache": True, "output_tokens": 5, - "reasoning_tokens": 4, - "output_tokens_include_reasoning": True, "total_tokens": 8, - "peak_request_input_tokens": 3, "cost_usd": 0.25, - "models": [{ - "model": "test-model", + "extensions": { "provider": "fake", - "input_tokens": 3, - "reasoning_tokens": 4, - }], - "extensions": {"provider": "fake"}, + "nemo_fabric.detailed_token_usage.v1": { + "input_tokens": 20, + "cached_input_tokens": 5, + "cache_write_input_tokens": 3, + "input_tokens_include_cache": False, + "output_tokens": 5, + "reasoning_tokens": 4, + "output_tokens_include_reasoning": False, + "total_tokens": 37, + "peak_request_input_tokens": 18, + "models": [{ + "model": "test-model", + "provider": "fake", + "input_tokens": 20, + "reasoning_tokens": 4, + }], + }, + }, }, } else: @@ -4708,7 +4745,7 @@ for line in sys.stdin: } #[test] - fn local_host_accepts_detailed_usage_without_changing_run_usage() { + fn local_host_preserves_detailed_usage_in_metadata() { let (root, plan) = local_host_plan("detailed_usage_result"); let result = run_plan(&plan, RunRequest::text("usage")).expect("normalized result"); @@ -4724,22 +4761,31 @@ for line in sys.stdin: output_tokens: Some(5), total_tokens: Some(8), cost_usd: Some(0.25), - metadata: BTreeMap::from([("provider".to_string(), serde_json::json!("fake"))]), + metadata: BTreeMap::from([ + ("provider".to_string(), serde_json::json!("fake")), + ( + "nemo_fabric.detailed_token_usage.v1".to_string(), + serde_json::json!({ + "input_tokens": 20, + "cached_input_tokens": 5, + "cache_write_input_tokens": 3, + "input_tokens_include_cache": false, + "output_tokens": 5, + "reasoning_tokens": 4, + "output_tokens_include_reasoning": false, + "total_tokens": 37, + "peak_request_input_tokens": 18, + "models": [{ + "model": "test-model", + "provider": "fake", + "input_tokens": 20, + "reasoning_tokens": 4 + }] + }), + ), + ]), } ); - assert_eq!( - serde_json::to_value(&usage).expect("serialize run usage"), - serde_json::json!({ - "input_tokens": 3, - "cached_input_tokens": 1, - "input_tokens_include_cache": true, - "output_tokens": 5, - "total_tokens": 8, - "cost_usd": 0.25, - "metadata": {"provider": "fake"} - }) - ); - let _ = fs::remove_dir_all(root); } diff --git a/crates/fabric-core/src/schema.rs b/crates/fabric-core/src/schema.rs index acc0c3753..ee15fda12 100644 --- a/crates/fabric-core/src/schema.rs +++ b/crates/fabric-core/src/schema.rs @@ -553,62 +553,11 @@ mod tests { ); let result = generate_schema(SchemaName::AgentRunResult).expect("schema generation"); - for definition in ["AgentUsage", "AgentModelUsage"] { - for field in [ - "input_tokens", - "cached_input_tokens", - "cache_write_input_tokens", - "output_tokens", - "reasoning_tokens", - "total_tokens", - "peak_request_input_tokens", - ] { - assert_eq!( - result["$defs"][definition]["properties"][field]["maximum"], - u64::MAX - ); - } - } - } - - #[test] - fn agent_run_result_schema_matches_model_usage_constraints() { - let schema = generate_schema(SchemaName::AgentRunResult).expect("schema generation"); - let validator = jsonschema::validator_for(&schema).expect("valid result schema"); - let result_with_models = |models: Value| { - serde_json::json!({ - "status": "succeeded", - "output": null, - "usage": {"models": models} - }) - }; - - assert!(validator.is_valid(&serde_json::json!({ - "status": "succeeded", - "output": null, - "usage": { - "cache_write_input_tokens": 2, - "reasoning_tokens": 4, - "output_tokens_include_reasoning": false, - "peak_request_input_tokens": 3, - "models": [{ - "model": "planner-model", - "provider": "openai", - "reasoning_tokens": 4, - "cost_usd": 0.5 - }] - } - }))); - for models in [ - serde_json::json!([{}]), - serde_json::json!([{"model": " \t"}]), - serde_json::json!([{"model": "planner-model", "provider": " \t"}]), - serde_json::json!([{"model": "planner-model", "cost_usd": -1.0}]), - serde_json::json!([{"model": "planner-model", "reasoning_tokens": -1}]), - serde_json::json!([{"model": "planner-model", "reasoning": 1}]), - serde_json::json!([{"model": "planner-model", "extensions": {}}]), - ] { - assert!(!validator.is_valid(&result_with_models(models))); + for field in ["input_tokens", "output_tokens", "total_tokens"] { + assert_eq!( + result["$defs"]["AgentUsage"]["properties"][field]["maximum"], + u64::MAX + ); } } diff --git a/docs/adapter-contract/tutorials/results.md b/docs/adapter-contract/tutorials/results.md index ac40ec645..de9dceaca 100644 --- a/docs/adapter-contract/tutorials/results.md +++ b/docs/adapter-contract/tutorials/results.md @@ -65,7 +65,7 @@ return AgentRunResult( | `status` | Required | Reports `succeeded`, `failed`, or `cancelled`. | | `output` | Required | Carries the primary JSON-compatible output and can be `null`. | | `error` | Required for `failed` | Carries a stable code, safe message, retry guidance, and declared extensions. | -| `usage` | Optional | Carries invocation-local input, cached-input, cache-write, output, reasoning, total, and peak request token counts, reported cost, and an optional per-model breakdown when known. | +| `usage` | Optional | Carries invocation-local input, cached-input, output, and total token counts plus reported cost when known. Descriptor-declared usage extensions can carry additional detail. | | `artifacts` | Optional | Carries target-produced artifact references relative to the runtime artifact root. | | `extensions` | Optional | Carries adapter-owned result data validated by the descriptor. | @@ -75,11 +75,11 @@ for the exact shape. A failed result contains an error; a successful result does not contain a non-null error. Status is explicit and is not inferred from arbitrary output fields. -Report only observed invocation usage. For cumulative target counters, compute the difference between successive observations; do not sum cumulative snapshots or substitute the last model response for an entire invocation. Missing and reset counters remain unknown. `cached_input_tokens` records cached prompt tokens and `cache_write_input_tokens` records prompt tokens written to the provider cache; `input_tokens_include_cache` declares whether both are included in `input_tokens` (`True`), excluded (`False`), or unknown (absent). The flag has no state for a provider that includes only one of the two, so normalize `input_tokens` first: add the excluded count to report `True`, or subtract the included count to report `False`. `reasoning_tokens` records reasoning output, and `output_tokens_include_reasoning` declares whether it is included in `output_tokens` with the same three states. `peak_request_input_tokens` records the input size of the largest single model request, including cached and cache-write input. Keep estimates separate from `cost_usd`, and retain available usage on unsuccessful terminal results. +Report only observed invocation usage. For cumulative target counters, compute the difference between successive observations; do not sum cumulative snapshots or substitute the last model response for an entire invocation. Missing and reset counters remain unknown. `cached_input_tokens` records cached prompt tokens; `input_tokens_include_cache` declares whether they are included in `input_tokens` (`True`), excluded (`False`), or unknown (absent). Keep estimates separate from `cost_usd`, and retain available usage on unsuccessful terminal results. -When the target reports usage per model, add one `AgentModelUsage` entry per model to `usage.models`. Each entry requires a non-blank `model`, accepts an optional non-blank `provider`, and uses the same token, flag, and cost fields as `AgentUsage`. A provider and model pair can appear only once, compared case-insensitively. Model entries have no `extensions`; keep adapter-owned usage data in `usage.extensions`. +`fabric.adapter/v1alpha2` usage is a closed object. Do not add cache-write, reasoning, peak request, or per-model fields at its root. Put that detail in `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` and declare the extension with `extension_schemas.usage` in the adapter descriptor. The detailed object repeats the normalized input, cached-input, output, and total token fields and can add `cache_write_input_tokens`, `reasoning_tokens`, `output_tokens_include_reasoning`, `peak_request_input_tokens`, and `models`. Within this object, `input_tokens_include_cache` applies to both cached reads and cache writes. Normalize `input_tokens` first if the provider includes only one component. Each model entry uses the same counters and requires a non-blank `model`; include `provider` when known. -NeMo Fabric validates `cache_write_input_tokens`, `reasoning_tokens`, `output_tokens_include_reasoning`, `peak_request_input_tokens`, and `usage.models`, but does not copy any of them into the consumer `RunResult.usage`. `RunResult.usage` keeps the adapter's `input_tokens_include_cache` flag, so when the flag is `False`, a consumer that adds `cached_input_tokens` to `input_tokens` does not count reported cache-write input. +Fabric preserves the extension at `RunResult.usage.metadata["nemo_fabric.detailed_token_usage.v1"]`. Consumers calculate inclusive input or output totals only when the matching inclusion flag and every excluded component are known. Otherwise, the inclusive total is unknown. **Success Check**: `invoke` returns one typed `AgentRunResult` whose explicit status matches the presence or absence of an error. diff --git a/docs/reference/api/python-library-reference/nemo_fabric.types.md b/docs/reference/api/python-library-reference/nemo_fabric.types.md index b37de2605..21a7ff445 100644 --- a/docs/reference/api/python-library-reference/nemo_fabric.types.md +++ b/docs/reference/api/python-library-reference/nemo_fabric.types.md @@ -1170,7 +1170,7 @@ Return a detached, JSON-compatible mapping for serialization. Normalized invocation-local usage reported by an adapter target. -Missing counters and cost are unknown, not zero. ``cached_input_tokens`` records cache usage; ``input_tokens_include_cache`` declares whether input already includes that count and any cache-write input the adapter reported. An absent flag means the semantics are unknown. Cache-write input is not reported here, so when the flag is ``False``, input plus cached input can understate total input. +Missing counters and cost are unknown, not zero. ``cached_input_tokens`` records cache usage; ``input_tokens_include_cache`` declares whether input already includes that count. An absent flag means the semantics are unknown. Descriptor-declared detailed usage is preserved in ``metadata``. diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/adapter-contract/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/adapter-contract/index.mdx index feabb8df6..52a3b6f57 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/adapter-contract/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/adapter-contract/index.mdx @@ -3,7 +3,7 @@ title: "Module adapter_contract" sidebar-title: "adapter_contract" slug: "/reference/api/rust-library-reference/nemo-fabric-core/adapter_contract" description: "Shared southbound adapter contract metadata." -position: 126 +position: 125 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/index.mdx index 4c4e21b44..26a286a0c 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/index.mdx @@ -3,7 +3,7 @@ title: "Module agent_config" sidebar-title: "agent_config" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config" description: "Configuration projected southbound to an adapter target." -position: 127 +position: 126 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentconfig.mdx index 007d38643..3c77229a7 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Config" sidebar-title: "AgentConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentconfig" description: "Configuration projected southbound to one adapter target." -position: 21 +position: 20 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentharnessconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentharnessconfig.mdx index c3e658bb3..26da7f68a 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentharnessconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentharnessconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Harness Config" sidebar-title: "AgentHarnessConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentharnessconfig" description: "Adapter-owned target settings projected from `FabricConfig.harness`." -position: 22 +position: 21 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionconfig.mdx index c4c49d6d8..e13c1a6f3 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Instruction Config" sidebar-title: "AgentInstructionConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentinstructionconfig" description: "One normalized instruction value projected to an adapter target." -position: 23 +position: 22 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionsconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionsconfig.mdx index 95ad35349..196a7eb39 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionsconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentinstructionsconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Instructions Config" sidebar-title: "AgentInstructionsConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentinstructionsconfig" description: "Normalized instructions projected to an adapter target." -position: 24 +position: 23 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpconfig.mdx index 5213a2711..df6d6e938 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent McpConfig" sidebar-title: "AgentMcpConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentmcpconfig" description: "Named MCP servers routed to an adapter target." -position: 25 +position: 24 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpserverconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpserverconfig.mdx index fbf5f8f4f..05a6fbaa4 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpserverconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmcpserverconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent McpServer Config" sidebar-title: "AgentMcpServerConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentmcpserverconfig" description: "One MCP server routed to an adapter target." -position: 26 +position: 25 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmodelconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmodelconfig.mdx index 57a9681a4..9d901c783 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmodelconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentmodelconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Model Config" sidebar-title: "AgentModelConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentmodelconfig" description: "Configuration for one named model role projected to an adapter target." -position: 27 +position: 26 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentruntimeconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentruntimeconfig.mdx index 347c0e5b1..504e93ede 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentruntimeconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentruntimeconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Runtime Config" sidebar-title: "AgentRuntimeConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentruntimeconfig" description: "Runtime behavior applied by an adapter target." -position: 28 +position: 27 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentskillconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentskillconfig.mdx index 2ccd188bd..001368c95 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentskillconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentskillconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Skill Config" sidebar-title: "AgentSkillConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentskillconfig" description: "Skill paths made available to an adapter target." -position: 29 +position: 28 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttooldefinition.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttooldefinition.mdx index fc8362a3c..bb1f81eed 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttooldefinition.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttooldefinition.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Tool Definition" sidebar-title: "AgentToolDefinition" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agenttooldefinition" description: "One named tool or tool-group definition resolved by an adapter." -position: 30 +position: 29 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttoolsconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttoolsconfig.mdx index 5ba49ba08..fde3ada25 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttoolsconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agenttoolsconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Tools Config" sidebar-title: "AgentToolsConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agenttoolsconfig" description: "Named tool definitions and effective adapter-target tool policy." -position: 31 +position: 30 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowconfig.mdx index e6b517f88..a42b88baf 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Workflow Config" sidebar-title: "AgentWorkflowConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentworkflowconfig" description: "Custom agent or workflow selection and construction settings." -position: 32 +position: 31 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowentrypointconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowentrypointconfig.mdx index 79369c030..7d344deed 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowentrypointconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-config/struct-agentworkflowentrypointconfig.mdx @@ -3,7 +3,7 @@ title: "Struct Agent Workflow Entrypoint Config" sidebar-title: "AgentWorkflowEntrypointConfig" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_config/struct-agentworkflowentrypointconfig" description: "Adapter-declared resolution semantics for one custom agent or workflow." -position: 33 +position: 32 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunresultvalidationerror.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunresultvalidationerror.mdx index 562b50c84..f9883fce4 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunresultvalidationerror.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunresultvalidationerror.mdx @@ -3,14 +3,14 @@ title: "Enum Agent RunResult Validation Error" sidebar-title: "AgentRunResultValidationError" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/enum-agentrunresultvalidationerror" description: "Invalid relationship or value within an adapter result." -position: 8 +position: 7 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} Generated from `cargo doc --no-deps -p nemo-fabric-core`. -
str),\n    InvalidArtifactPath(PathBuf),\n    DuplicateModelUsage(String),\n    InvalidCost(&'static str),\n}"}} />
+
str),\n    InvalidArtifactPath(PathBuf),\n}"}} />
Invalid relationship or value within an adapter result. @@ -40,18 +40,6 @@ A result string violated the non-blank contract. An artifact path was blank, absolute, or contained parent traversal. -### `DuplicateModelUsage(String)` - -
String)"}} />
- -Model usage repeated a provider and model pair, compared case-insensitively. - -### `InvalidCost(&'static str)` - -
str)"}} />
- -A cost was negative or not a finite number. - ## Trait Implementations ### `impl Clone for AgentRunResultValidationError` diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunstatus.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunstatus.mdx index c091b1f5f..117a32aef 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunstatus.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/enum-agentrunstatus.mdx @@ -3,7 +3,7 @@ title: "Enum Agent RunStatus" sidebar-title: "AgentRunStatus" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/enum-agentrunstatus" description: "Completion status reported by an adapter target." -position: 9 +position: 8 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/index.mdx index d8fc35dcb..2c89a0e39 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/index.mdx @@ -3,7 +3,7 @@ title: "Module agent_execution" sidebar-title: "agent_execution" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution" description: "Request and result structures exchanged with an adapter target." -position: 128 +position: 127 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} @@ -15,7 +15,6 @@ Request and result structures exchanged with an adapter target. ## Structs - [AgentArtifact](struct-agentartifact.mdx): One artifact produced by an adapter target. -- [AgentModelUsage](struct-agentmodelusage.mdx): Usage of one model within one invocation. - [AgentRunError](struct-agentrunerror.mdx): Error reported by an adapter target. - [AgentRunRequest](struct-agentrunrequest.mdx): Southbound invocation request passed to an adapter target. - [AgentRunResult](struct-agentrunresult.mdx): Southbound terminal result returned by an adapter target. diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx deleted file mode 100644 index a24c98d04..000000000 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentmodelusage.mdx +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: "Struct Agent Model Usage" -sidebar-title: "AgentModelUsage" -slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentmodelusage" -description: "Usage of one model within one invocation." -position: 4 ---- -{/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -SPDX-License-Identifier: Apache-2.0 */} - -Generated from `cargo doc --no-deps -p nemo-fabric-core`. - -
String,\n    pub provider: Option<String>,\n    pub input_tokens: Option<u64>,\n    pub cached_input_tokens: Option<u64>,\n    pub cache_write_input_tokens: Option<u64>,\n    pub input_tokens_include_cache: Option<bool>,\n    pub output_tokens: Option<u64>,\n    pub reasoning_tokens: Option<u64>,\n    pub output_tokens_include_reasoning: Option<bool>,\n    pub total_tokens: Option<u64>,\n    pub peak_request_input_tokens: Option<u64>,\n    pub cost_usd: Option<f64>,\n}"}} />
- -Usage of one model within one invocation. - -Token fields have the same meaning as the matching `AgentUsage` fields, restricted to requests served by this model. - -## Fields - -### `model: String` - -Model identifier as reported by the harness or provider response. - -### `provider: Option` - -Provider or route that served the model, when known. - -### `input_tokens: Option` - -Input tokens consumed by this model. - -### `cached_input_tokens: Option` - -Cached input tokens consumed by this model, when reported. - -### `cache_write_input_tokens: Option` - -Input tokens this model wrote to the provider prompt cache, when reported. - -### `input_tokens_include_cache: Option` - -Whether input_tokens already includes both cached_input_tokens (cache reads) and cache_write_input_tokens (cache writes); absent means unknown. True means both are included and false means both are excluded. When the provider includes only one of the two, the adapter normalizes input_tokens to one of these states before reporting. - -### `output_tokens: Option` - -Output tokens produced by this model. - -### `reasoning_tokens: Option` - -Reasoning tokens produced by this model, when reported. - -### `output_tokens_include_reasoning: Option` - -Whether output_tokens already includes reasoning_tokens; absent means unknown. - -### `total_tokens: Option` - -Total tokens reported by the provider for this model. - -### `peak_request_input_tokens: Option` - -Input tokens of the largest single request served by this model, including cached and cache-write input, when reported. - -### `cost_usd: Option` - -Cost in US dollars for this model when reported by the provider. - -## Trait Implementations - -### `impl Clone for AgentModelUsage` - -
Clone for AgentModelUsage"}} />
- -#### `clone` - -
clone(&self) -> AgentModelUsage"}} />
- -#### `clone_from` - -
clone_from(&mut self, source: &Self)"}} />
- -### `impl Debug for AgentModelUsage` - -
Debug for AgentModelUsage"}} />
- -#### `fmt` - -
fmt(&self, f: &mut Formatter<'_>) -> Result"}} />
- -### `impl Default for AgentModelUsage` - -
Default for AgentModelUsage"}} />
- -#### `default` - -
default() -> AgentModelUsage"}} />
- -### `impl<'de> Deserialize<'de> for AgentModelUsage` - -
Deserialize<'de> for AgentModelUsage"}} />
- -#### `deserialize` - -
deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where\n    __D: Deserializer<'de>,"}} />
- -### `impl JsonSchema for AgentModelUsage` - -
AgentModelUsage"}} />
- -#### `schema_name` - -
Cow<'static, str>"}} />
- -#### `schema_id` - -
Cow<'static, str>"}} />
- -#### `json_schema` - -
- -#### `inline_schema` - -
bool"}} />
- -### `impl PartialEq for AgentModelUsage` - -
PartialEq for AgentModelUsage"}} />
- -#### `eq` - -
eq(&self, other: &AgentModelUsage) -> bool"}} />
- -#### `ne` - -
ne(&self, other: &Rhs) -> bool"}} />
- -### `impl Serialize for AgentModelUsage` - -
Serialize for AgentModelUsage"}} />
- -#### `serialize` - -
serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where\n    __S: Serializer,"}} />
- -### `impl StructuralPartialEq for AgentModelUsage` - -
StructuralPartialEq for AgentModelUsage"}} />
diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunerror.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunerror.mdx index 26d3d5890..4afbb91c3 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunerror.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunerror.mdx @@ -3,7 +3,7 @@ title: "Struct Agent RunError" sidebar-title: "AgentRunError" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentrunerror" description: "Error reported by an adapter target." -position: 5 +position: 4 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunrequest.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunrequest.mdx index 93560b91a..c9d5f416e 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunrequest.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunrequest.mdx @@ -3,7 +3,7 @@ title: "Struct Agent RunRequest" sidebar-title: "AgentRunRequest" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentrunrequest" description: "Southbound invocation request passed to an adapter target." -position: 6 +position: 5 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunresult.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunresult.mdx index 5b1462f3e..9b87e801f 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunresult.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentrunresult.mdx @@ -3,7 +3,7 @@ title: "Struct Agent RunResult" sidebar-title: "AgentRunResult" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentrunresult" description: "Southbound terminal result returned by an adapter target." -position: 7 +position: 6 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} @@ -50,7 +50,7 @@ Adapter-owned result fields.
Result<(), AgentRunResultValidationError>"}} />
-Validate terminal status, error, usage, and artifact invariants. +Validate terminal status, error, and artifact invariants. ## Trait Implementations diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx index 8ca526395..caaebcee0 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/agent-execution/struct-agentusage.mdx @@ -3,14 +3,14 @@ title: "Struct Agent Usage" sidebar-title: "AgentUsage" slug: "/reference/api/rust-library-reference/nemo-fabric-core/agent_execution/struct-agentusage" description: "Normalized model usage reported by an adapter target." -position: 10 +position: 9 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} Generated from `cargo doc --no-deps -p nemo-fabric-core`. -
Option<u64>,\n    pub cached_input_tokens: Option<u64>,\n    pub cache_write_input_tokens: Option<u64>,\n    pub input_tokens_include_cache: Option<bool>,\n    pub output_tokens: Option<u64>,\n    pub reasoning_tokens: Option<u64>,\n    pub output_tokens_include_reasoning: Option<bool>,\n    pub total_tokens: Option<u64>,\n    pub peak_request_input_tokens: Option<u64>,\n    pub cost_usd: Option<f64>,\n    pub models: Vec<AgentModelUsage>,\n    pub extensions: BTreeMap<String, Value>,\n}"}} />
+
Option<u64>,\n    pub cached_input_tokens: Option<u64>,\n    pub input_tokens_include_cache: Option<bool>,\n    pub output_tokens: Option<u64>,\n    pub total_tokens: Option<u64>,\n    pub cost_usd: Option<f64>,\n    pub extensions: BTreeMap<String, Value>,\n}"}} />
Normalized model usage reported by an adapter target. @@ -24,42 +24,22 @@ Input tokens consumed by the invocation. Cached input tokens consumed by the invocation, when reported. -### `cache_write_input_tokens: Option` - -Input tokens written to the provider prompt cache, when reported. - ### `input_tokens_include_cache: Option` -Whether input_tokens already includes both cached_input_tokens (cache reads) and cache_write_input_tokens (cache writes); absent means unknown. True means both are included and false means both are excluded. When the provider includes only one of the two, the adapter normalizes input_tokens to one of these states before reporting. +Whether input_tokens already includes cached_input_tokens; absent means unknown. ### `output_tokens: Option` Output tokens produced by the invocation. -### `reasoning_tokens: Option` - -Reasoning tokens produced by the invocation, when reported. - -### `output_tokens_include_reasoning: Option` - -Whether output_tokens already includes reasoning_tokens; absent means unknown. - ### `total_tokens: Option` Total tokens reported by the provider. -### `peak_request_input_tokens: Option` - -Input tokens of the largest single model request in the invocation, including cached and cache-write input, when reported. - ### `cost_usd: Option` Invocation cost in US dollars when reported by the provider. -### `models: Vec` - -Usage broken out by the model that served the requests; empty when not reported. Each provider and model pair appears at most once, compared case-insensitively. - ### `extensions: BTreeMap` Adapter-owned usage fields. diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterconfigfield.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterconfigfield.mdx index 56996dbb6..fff169bdf 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterconfigfield.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterconfigfield.mdx @@ -2,7 +2,7 @@ title: "Enum Adapter Config Field" sidebar-title: "AdapterConfigField" description: "Adapter-translated normalized NVIDIA NeMo Fabric configuration fields." -position: 11 +position: 10 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterkind.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterkind.mdx index f9032f16d..2891790f8 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterkind.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adapterkind.mdx @@ -2,7 +2,7 @@ title: "Enum Adapter Kind" sidebar-title: "AdapterKind" description: "Adapter implementation kind." -position: 14 +position: 13 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertarget.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertarget.mdx index 13484f3cc..5e8279ddf 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertarget.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertarget.mdx @@ -2,7 +2,7 @@ title: "Enum Adapter Target" sidebar-title: "AdapterTarget" description: "Type-specific Adapter Target Descriptor payload." -position: 16 +position: 15 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertargettype.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertargettype.mdx index 63224c403..d3712e741 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertargettype.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-adaptertargettype.mdx @@ -2,7 +2,7 @@ title: "Enum Adapter Target Type" sidebar-title: "AdapterTargetType" description: "Adapter target categories understood by this Adapter Contract version." -position: 18 +position: 17 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-controllocation.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-controllocation.mdx index 7d18d6f18..6cc4e506e 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-controllocation.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-controllocation.mdx @@ -2,7 +2,7 @@ title: "Enum Control Location" sidebar-title: "ControlLocation" description: "Where NeMo Fabric control code runs relative to the environment." -position: 35 +position: 34 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-descriptorsource.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-descriptorsource.mdx index 3385fa574..2ccfbed5d 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-descriptorsource.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-descriptorsource.mdx @@ -2,7 +2,7 @@ title: "Enum Descriptor Source" sidebar-title: "DescriptorSource" description: "Where NeMo Fabric discovered descriptor metadata." -position: 37 +position: 36 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-environmentownership.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-environmentownership.mdx index 9bd45bad8..56b0d7e7c 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-environmentownership.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-environmentownership.mdx @@ -2,7 +2,7 @@ title: "Enum Environment Ownership" sidebar-title: "EnvironmentOwnership" description: "Whether NeMo Fabric owns the underlying environment resource." -position: 40 +position: 39 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-instructionmode.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-instructionmode.mdx index bd744c9ed..1aa441a9a 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-instructionmode.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-instructionmode.mdx @@ -2,7 +2,7 @@ title: "Enum Instruction Mode" sidebar-title: "InstructionMode" description: "How an instruction value is applied to the selected harness." -position: 45 +position: 44 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpauthenticationconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpauthenticationconfig.mdx index e2f470c6d..894f9abfc 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpauthenticationconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpauthenticationconfig.mdx @@ -2,7 +2,7 @@ title: "Enum McpAuthentication Config" sidebar-title: "McpAuthenticationConfig" description: "MCP server authentication configuration." -position: 47 +position: 46 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpexposure.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpexposure.mdx index 9a9d7a1a8..df5de9dd3 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpexposure.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcpexposure.mdx @@ -2,7 +2,7 @@ title: "Enum McpExposure" sidebar-title: "McpExposure" description: "MCP exposure strategy." -position: 49 +position: 48 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcptransport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcptransport.mdx index 429fa8ee7..5b9db56b2 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcptransport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-mcptransport.mdx @@ -2,7 +2,7 @@ title: "Enum McpTransport" sidebar-title: "McpTransport" description: "MCP server transport." -position: 51 +position: 50 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-oauthtokenendpointauthmethod.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-oauthtokenendpointauthmethod.mdx index 9a244fd2b..c9c83b6f6 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-oauthtokenendpointauthmethod.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-oauthtokenendpointauthmethod.mdx @@ -2,7 +2,7 @@ title: "Enum OAuth Token Endpoint Auth Method" sidebar-title: "OAuthTokenEndpointAuthMethod" description: "OAuth client authentication method used at the token endpoint." -position: 54 +position: 53 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-resolutionstrategy.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-resolutionstrategy.mdx index 7e6f001b7..f130d1764 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-resolutionstrategy.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-resolutionstrategy.mdx @@ -2,7 +2,7 @@ title: "Enum Resolution Strategy" sidebar-title: "ResolutionStrategy" description: "Adapter install or availability strategy." -position: 55 +position: 54 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-telemetryprovider.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-telemetryprovider.mdx index d1bfc189f..8ce5c9908 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-telemetryprovider.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/enum-telemetryprovider.mdx @@ -2,7 +2,7 @@ title: "Enum Telemetry Provider" sidebar-title: "TelemetryProvider" description: "Telemetry runtime provider." -position: 65 +position: 64 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-descriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-descriptor.mdx index de34aedc1..fc493bae7 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-descriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-descriptor.mdx @@ -2,7 +2,7 @@ title: "Function load_adapter_descriptor" sidebar-title: "load_adapter_descriptor" description: "Load an adapter descriptor from JSON package metadata." -position: 72 +position: 71 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-target-descriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-target-descriptor.mdx index bd5cd97d5..142fdba30 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-target-descriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-load-adapter-target-descriptor.mdx @@ -2,7 +2,7 @@ title: "Function load_adapter_target_descriptor" sidebar-title: "load_adapter_target_descriptor" description: "Load an Adapter Target Descriptor from declarative JSON metadata." -position: 73 +position: 72 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-resolve-run-plan-from-config.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-resolve-run-plan-from-config.mdx index a6d607703..6bc8a973b 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-resolve-run-plan-from-config.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/fn-resolve-run-plan-from-config.mdx @@ -2,7 +2,7 @@ title: "Function resolve_run_plan_from_config" sidebar-title: "resolve_run_plan_from_config" description: "Resolve a typed NVIDIA NeMo Fabric config into a runnable plan." -position: 74 +position: 73 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx index f51ee909d..fa7255361 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/index.mdx @@ -2,7 +2,7 @@ title: "Module config" sidebar-title: "config" description: "NeMo Fabric config models and loading helpers." -position: 129 +position: 128 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterconfigsupport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterconfigsupport.mdx index b807db089..4439f355a 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterconfigsupport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterconfigsupport.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Config Support" sidebar-title: "AdapterConfigSupport" description: "Adapter config support." -position: 12 +position: 11 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx index 004375cc9..19d1aa987 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterdescriptor.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Descriptor" sidebar-title: "AdapterDescriptor" description: "Language-neutral adapter descriptor for a harness integration." -position: 13 +position: 12 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterrequirements.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterrequirements.mdx index ebcc3cd59..b126d5497 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterrequirements.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adapterrequirements.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Requirements" sidebar-title: "AdapterRequirements" description: "Adapter runtime requirements." -position: 15 +position: 14 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertargetdescriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertargetdescriptor.mdx index 76745d1c1..da0d2527d 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertargetdescriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertargetdescriptor.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Target Descriptor" sidebar-title: "AdapterTargetDescriptor" description: "Independently registered target implemented by an adapter." -position: 17 +position: 16 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetryprovidersupport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetryprovidersupport.mdx index 00ae0e985..7cb95cbee 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetryprovidersupport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetryprovidersupport.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Telemetry Provider Support" sidebar-title: "AdapterTelemetryProviderSupport" description: "Telemetry capabilities for one adapter-supported provider." -position: 19 +position: 18 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetrysupport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetrysupport.mdx index 7a89a0e09..740b201c7 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetrysupport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-adaptertelemetrysupport.mdx @@ -2,7 +2,7 @@ title: "Struct Adapter Telemetry Support" sidebar-title: "AdapterTelemetrySupport" description: "Adapter telemetry support." -position: 20 +position: 19 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-capabilityplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-capabilityplan.mdx index 0a00c4a9f..d3880d1b7 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-capabilityplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-capabilityplan.mdx @@ -2,7 +2,7 @@ title: "Struct Capability Plan" sidebar-title: "CapabilityPlan" description: "Resolved capability configuration." -position: 34 +position: 33 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-descriptorprovenance.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-descriptorprovenance.mdx index 49666d77c..4386be0f5 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-descriptorprovenance.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-descriptorprovenance.mdx @@ -2,7 +2,7 @@ title: "Struct Descriptor Provenance" sidebar-title: "DescriptorProvenance" description: "One physical source for a discovered descriptor record." -position: 36 +position: 35 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-discoveryconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-discoveryconfig.mdx index 06e0ef0b8..8a2648e20 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-discoveryconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-discoveryconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Discovery Config" sidebar-title: "DiscoveryConfig" description: "Explicit descriptor discovery inputs." -position: 38 +position: 37 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentconfig.mdx index 027465d62..e8aa118d0 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Environment Config" sidebar-title: "EnvironmentConfig" description: "Execution environment configuration." -position: 39 +position: 38 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentplan.mdx index 9f1f06a46..ca4a654e8 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-environmentplan.mdx @@ -2,7 +2,7 @@ title: "Struct Environment Plan" sidebar-title: "EnvironmentPlan" description: "Resolved environment plan." -position: 41 +position: 40 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-fabricconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-fabricconfig.mdx index d6755ebcf..d4e1acd9b 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-fabricconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-fabricconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Fabric Config" sidebar-title: "FabricConfig" description: "Versioned NVIDIA NeMo Fabric agent config." -position: 42 +position: 41 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-harnessconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-harnessconfig.mdx index 87fc5328b..e3af3e851 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-harnessconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-harnessconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Harness Config" sidebar-title: "HarnessConfig" description: "Harness selection." -position: 43 +position: 42 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionconfig.mdx index d930e5450..2c8969673 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Instruction Config" sidebar-title: "InstructionConfig" description: "One portable instruction value." -position: 44 +position: 43 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionsconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionsconfig.mdx index 6a1d16f4f..7158cc247 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionsconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-instructionsconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Instructions Config" sidebar-title: "InstructionsConfig" description: "Harness-neutral agent instruction configuration." -position: 46 +position: 45 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpconfig.mdx index 26f8ce82f..262b90d8e 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpconfig.mdx @@ -2,7 +2,7 @@ title: "Struct McpConfig" sidebar-title: "McpConfig" description: "MCP capability configuration." -position: 48 +position: 47 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpserverplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpserverplan.mdx index c4ee6edec..589afc12c 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpserverplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-mcpserverplan.mdx @@ -2,7 +2,7 @@ title: "Struct McpServer Plan" sidebar-title: "McpServerPlan" description: "Resolved MCP server exposure." -position: 50 +position: 49 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-metadataconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-metadataconfig.mdx index 3bdefc9d0..d2adec971 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-metadataconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-metadataconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Metadata Config" sidebar-title: "MetadataConfig" description: "Human-readable metadata." -position: 52 +position: 51 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-modelconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-modelconfig.mdx index c9d8b63fc..50469f63c 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-modelconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-modelconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Model Config" sidebar-title: "ModelConfig" description: "Model configuration." -position: 53 +position: 52 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvecontext.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvecontext.mdx index bf1537e85..8e70ade88 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvecontext.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvecontext.mdx @@ -2,7 +2,7 @@ title: "Struct Resolve Context" sidebar-title: "ResolveContext" description: "Source context used when resolving an in-memory NeMo Fabric config." -position: 56 +position: 55 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadapterdescriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadapterdescriptor.mdx index 34ad4c681..7c1e65663 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadapterdescriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadapterdescriptor.mdx @@ -2,7 +2,7 @@ title: "Struct Resolved Adapter Descriptor" sidebar-title: "ResolvedAdapterDescriptor" description: "Adapter descriptor selected for a run plan." -position: 57 +position: 56 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadaptertargetdescriptor.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadaptertargetdescriptor.mdx index b3be2d837..8adac3efc 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadaptertargetdescriptor.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-resolvedadaptertargetdescriptor.mdx @@ -2,7 +2,7 @@ title: "Struct Resolved Adapter Target Descriptor" sidebar-title: "ResolvedAdapterTargetDescriptor" description: "Adapter target descriptor selected for a run plan." -position: 58 +position: 57 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runplan.mdx index b8f75e62d..e3c43e4e1 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runplan.mdx @@ -2,7 +2,7 @@ title: "Struct RunPlan" sidebar-title: "RunPlan" description: "Resolved NeMo Fabric run plan." -position: 59 +position: 58 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimecapabilities.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimecapabilities.mdx index 5c2282536..0d972cb87 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimecapabilities.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimecapabilities.mdx @@ -2,7 +2,7 @@ title: "Struct Runtime Capabilities" sidebar-title: "RuntimeCapabilities" description: "Lifecycle behavior implemented by a resolved runtime path." -position: 60 +position: 59 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimeconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimeconfig.mdx index 4ab3289bc..2c89a11b2 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimeconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-runtimeconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Runtime Config" sidebar-title: "RuntimeConfig" description: "Invocation runtime contract." -position: 61 +position: 60 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-skillconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-skillconfig.mdx index 1f4e2fe76..47644f228 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-skillconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-skillconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Skill Config" sidebar-title: "SkillConfig" description: "Skill capability configuration." -position: 62 +position: 61 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryconfig.mdx index 61e3aa7d0..2e1b4af6b 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Telemetry Config" sidebar-title: "TelemetryConfig" description: "Telemetry configuration." -position: 63 +position: 62 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryplan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryplan.mdx index 326bcdbb5..f12176331 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryplan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryplan.mdx @@ -2,7 +2,7 @@ title: "Struct Telemetry Plan" sidebar-title: "TelemetryPlan" description: "Resolved telemetry plan." -position: 64 +position: 63 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryproviderconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryproviderconfig.mdx index bef871340..f683b0886 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryproviderconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-telemetryproviderconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Telemetry Provider Config" sidebar-title: "TelemetryProviderConfig" description: "Provider-specific telemetry configuration." -position: 66 +position: 65 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-tooldefinitionconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-tooldefinitionconfig.mdx index 771156fff..b5e0b460f 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-tooldefinitionconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-tooldefinitionconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Tool Definition Config" sidebar-title: "ToolDefinitionConfig" description: "One named normalized tool or tool-group definition." -position: 67 +position: 66 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-toolsconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-toolsconfig.mdx index f9f3714b7..64b2d6eec 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-toolsconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-toolsconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Tools Config" sidebar-title: "ToolsConfig" description: "Harness-neutral tool capability configuration." -position: 68 +position: 67 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowconfig.mdx index ab0796f56..21beec0df 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Workflow Config" sidebar-title: "WorkflowConfig" description: "Registered workflow target and immutable construction settings." -position: 69 +position: 68 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowentrypointconfig.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowentrypointconfig.mdx index 03fecb115..a002d8fc3 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowentrypointconfig.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowentrypointconfig.mdx @@ -2,7 +2,7 @@ title: "Struct Workflow Entrypoint Config" sidebar-title: "WorkflowEntrypointConfig" description: "Adapter-owned workflow entry point supplied by an Adapter Target Descriptor." -position: 70 +position: 69 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowtargetspec.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowtargetspec.mdx index a0e9695a1..e66041abb 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowtargetspec.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/config/struct-workflowtargetspec.mdx @@ -2,7 +2,7 @@ title: "Struct Workflow Target Spec" sidebar-title: "WorkflowTargetSpec" description: "Workflow-specific Adapter Target Descriptor fields." -position: 71 +position: 70 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/enum-doctorstatus.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/enum-doctorstatus.mdx index bbae2fe19..d8c0693d4 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/enum-doctorstatus.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/enum-doctorstatus.mdx @@ -2,7 +2,7 @@ title: "Enum Doctor Status" sidebar-title: "DoctorStatus" description: "Diagnostic status." -position: 77 +position: 76 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/fn-doctor-plan.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/fn-doctor-plan.mdx index b97461157..bb8aa23e8 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/fn-doctor-plan.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/fn-doctor-plan.mdx @@ -2,7 +2,7 @@ title: "Function doctor_plan" sidebar-title: "doctor_plan" description: "Inspect a resolved run plan without mutating the environment." -position: 78 +position: 77 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.mdx index 4f6f26b00..ea299ed94 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/index.mdx @@ -2,7 +2,7 @@ title: "Module doctor" sidebar-title: "doctor" description: "Plan diagnostics for NeMo Fabric." -position: 130 +position: 129 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorcheck.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorcheck.mdx index 9ae58d2b6..c64d5792e 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorcheck.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorcheck.mdx @@ -2,7 +2,7 @@ title: "Struct Doctor Check" sidebar-title: "DoctorCheck" description: "Diagnostic check result." -position: 75 +position: 74 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorreport.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorreport.mdx index c015cc391..c7d65e76f 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorreport.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/doctor/struct-doctorreport.mdx @@ -2,7 +2,7 @@ title: "Struct Doctor Report" sidebar-title: "DoctorReport" description: "Diagnostic report for a resolved run plan." -position: 76 +position: 75 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx index 70e1c1cc4..95cf2f59a 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/enum-fabricerror.mdx @@ -2,7 +2,7 @@ title: "Enum Fabric Error" sidebar-title: "FabricError" description: "Errors raised by NeMo Fabric config loading and validation." -position: 79 +position: 78 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/index.mdx index e389cbb01..cf7208b32 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/index.mdx @@ -2,7 +2,7 @@ title: "Module error" sidebar-title: "error" description: "Error types for NeMo Fabric core." -position: 131 +position: 130 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/type-result.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/type-result.mdx index 6f11a50d8..0a91b0129 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/error/type-result.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/error/type-result.mdx @@ -2,7 +2,7 @@ title: "Type Alias Result" sidebar-title: "Result" description: "Core NeMo Fabric result type." -position: 80 +position: 79 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/fn-version.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/fn-version.mdx index f9c667fa9..8af97f312 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/fn-version.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/fn-version.mdx @@ -2,7 +2,7 @@ title: "Function version" sidebar-title: "version" description: "Returns the crate version compiled into this build." -position: 134 +position: 133 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx index 8e1579dda..6670ab4d8 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/index.mdx @@ -16,7 +16,6 @@ Core config and runtime contract for NeMo Fabric. - `pub use adapter_contract::ADAPTER_CONTRACT_VERSION;` - `pub use adapter_contract::AdapterExtensionPoint;` - `pub use agent_execution::AgentArtifact;` -- `pub use agent_execution::AgentModelUsage;` - `pub use agent_execution::AgentRunError;` - `pub use agent_execution::AgentRunRequest;` - `pub use agent_execution::AgentRunResult;` diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx index 3b8f07380..e4ce802a1 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/index.mdx @@ -2,7 +2,7 @@ title: "Module runtime" sidebar-title: "runtime" description: "Runtime invocation helpers." -position: 132 +position: 131 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx index d286403b5..6f16e387b 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/runtime/struct-runusage.mdx @@ -25,7 +25,7 @@ Cached input tokens consumed by the invocation, when reported. ### `input_tokens_include_cache: Option` -Whether input_tokens already includes cached_input_tokens and any cache-write input tokens the adapter reported; absent means unknown. RunUsage does not report cache-write input tokens, so input_tokens plus cached_input_tokens can understate total input when this is false. +Whether input_tokens already includes cached_input_tokens; absent means unknown. ### `output_tokens: Option` diff --git a/docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx b/docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx index 722c3a849..0569b34b2 100644 --- a/docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx +++ b/docs/reference/api/rust-library-reference/nemo-fabric-core/schema/index.mdx @@ -2,7 +2,7 @@ title: "Module schema" sidebar-title: "schema" description: "JSON Schema generation for the public NeMo Fabric contract." -position: 133 +position: 132 --- {/* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 */} diff --git a/docs/sdk/python.mdx b/docs/sdk/python.mdx index ff6ae1412..f2ec7d9b8 100644 --- a/docs/sdk/python.mdx +++ b/docs/sdk/python.mdx @@ -892,7 +892,7 @@ if result.usage is not None: print(result.usage.get("cost_usd")) ``` -Each counter is optional: missing values are unknown, not zero. `cached_input_tokens` reports cached prompt tokens. `input_tokens_include_cache` is `True` when those tokens are already included in `input_tokens`, `False` when they are excluded, and absent when the adapter cannot establish the semantics. Consumers must not add cached tokens to an inclusive input count. The flag also covers cache-write input tokens that an adapter reports, which `RunUsage` does not expose, so `input_tokens` plus `cached_input_tokens` can understate total input when the flag is `False`. `cost_usd` contains reported cost only; keep estimates separately in provider metadata rather than presenting them as measured charges. +Each counter is optional: missing values are unknown, not zero. `cached_input_tokens` reports cached prompt tokens. `input_tokens_include_cache` is `True` when those tokens are already included in `input_tokens`, `False` when they are excluded, and absent when the adapter cannot establish the semantics. Consumers must not add cached tokens to an inclusive input count. Adapters can report cache-write, reasoning, peak request, and per-model detail through the descriptor-declared `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` object. Fabric preserves that object at `RunUsage.metadata["nemo_fabric.detailed_token_usage.v1"]`; an inclusive total remains unknown unless its inclusion flag and every excluded component are known. `cost_usd` contains reported cost only; keep estimates separately in provider metadata rather than presenting them as measured charges. If NeMo Fabric cannot resolve config, start a runtime, or obtain a normalized result, the SDK raises a `FabricError` subclass instead of returning a partial diff --git a/schemas/adapter-contract/agent-run-result.schema.json b/schemas/adapter-contract/agent-run-result.schema.json index 4d60979e0..ee1c450c4 100644 --- a/schemas/adapter-contract/agent-run-result.schema.json +++ b/schemas/adapter-contract/agent-run-result.schema.json @@ -57,124 +57,6 @@ ], "type": "object" }, - "AgentModelUsage": { - "additionalProperties": false, - "description": "Usage of one model within one invocation.\n\nToken fields have the same meaning as the matching `AgentUsage` fields,\nrestricted to requests served by this model.", - "properties": { - "cache_write_input_tokens": { - "description": "Input tokens this model wrote to the provider prompt cache, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "cached_input_tokens": { - "description": "Cached input tokens consumed by this model, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "cost_usd": { - "description": "Cost in US dollars for this model when reported by the provider.", - "format": "double", - "minimum": 0.0, - "type": [ - "number", - "null" - ] - }, - "input_tokens": { - "description": "Input tokens consumed by this model.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "input_tokens_include_cache": { - "description": "Whether input_tokens already includes both cached_input_tokens (cache\nreads) and cache_write_input_tokens (cache writes); absent means\nunknown. True means both are included and false means both are\nexcluded. When the provider includes only one of the two, the adapter\nnormalizes input_tokens to one of these states before reporting.", - "type": [ - "boolean", - "null" - ] - }, - "model": { - "description": "Model identifier as reported by the harness or provider response.", - "minLength": 1, - "pattern": "\\S", - "type": "string" - }, - "output_tokens": { - "description": "Output tokens produced by this model.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "output_tokens_include_reasoning": { - "description": "Whether output_tokens already includes reasoning_tokens; absent means unknown.", - "type": [ - "boolean", - "null" - ] - }, - "peak_request_input_tokens": { - "description": "Input tokens of the largest single request served by this model,\nincluding cached and cache-write input, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "provider": { - "description": "Provider or route that served the model, when known.", - "minLength": 1, - "pattern": "\\S", - "type": [ - "string", - "null" - ] - }, - "reasoning_tokens": { - "description": "Reasoning tokens produced by this model, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "total_tokens": { - "description": "Total tokens reported by the provider for this model.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - } - }, - "required": [ - "model" - ], - "type": "object" - }, "AgentRunError": { "additionalProperties": false, "description": "Error reported by an adapter target.", @@ -232,16 +114,6 @@ "additionalProperties": false, "description": "Normalized model usage reported by an adapter target.", "properties": { - "cache_write_input_tokens": { - "description": "Input tokens written to the provider prompt cache, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, "cached_input_tokens": { "description": "Cached input tokens consumed by the invocation, when reported.", "format": "uint64", @@ -277,19 +149,12 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes both cached_input_tokens (cache\nreads) and cache_write_input_tokens (cache writes); absent means\nunknown. True means both are included and false means both are\nexcluded. When the provider includes only one of the two, the adapter\nnormalizes input_tokens to one of these states before reporting.", + "description": "Whether input_tokens already includes cached_input_tokens; absent means unknown.", "type": [ "boolean", "null" ] }, - "models": { - "description": "Usage broken out by the model that served the requests; empty when not\nreported. Each provider and model pair appears at most once, compared\ncase-insensitively.", - "items": { - "$ref": "#/$defs/AgentModelUsage" - }, - "type": "array" - }, "output_tokens": { "description": "Output tokens produced by the invocation.", "format": "uint64", @@ -300,33 +165,6 @@ "null" ] }, - "output_tokens_include_reasoning": { - "description": "Whether output_tokens already includes reasoning_tokens; absent means unknown.", - "type": [ - "boolean", - "null" - ] - }, - "peak_request_input_tokens": { - "description": "Input tokens of the largest single model request in the invocation,\nincluding cached and cache-write input, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, - "reasoning_tokens": { - "description": "Reasoning tokens produced by the invocation, when reported.", - "format": "uint64", - "maximum": 18446744073709551615, - "minimum": 0, - "type": [ - "integer", - "null" - ] - }, "total_tokens": { "description": "Total tokens reported by the provider.", "format": "uint64", diff --git a/schemas/sdk/run-result.schema.json b/schemas/sdk/run-result.schema.json index 32d7528af..034c17e82 100644 --- a/schemas/sdk/run-result.schema.json +++ b/schemas/sdk/run-result.schema.json @@ -247,7 +247,7 @@ ] }, "input_tokens_include_cache": { - "description": "Whether input_tokens already includes cached_input_tokens and any\ncache-write input tokens the adapter reported; absent means unknown.\nRunUsage does not report cache-write input tokens, so input_tokens plus\ncached_input_tokens can understate total input when this is false.", + "description": "Whether input_tokens already includes cached_input_tokens; absent means unknown.", "type": [ "boolean", "null" diff --git a/sdk/python/nemo-fabric-runtime/src/nemo_fabric/integrations/harbor/fabric_agent.py b/sdk/python/nemo-fabric-runtime/src/nemo_fabric/integrations/harbor/fabric_agent.py index 1940ca930..4f0590892 100644 --- a/sdk/python/nemo-fabric-runtime/src/nemo_fabric/integrations/harbor/fabric_agent.py +++ b/sdk/python/nemo-fabric-runtime/src/nemo_fabric/integrations/harbor/fabric_agent.py @@ -10,6 +10,7 @@ import shlex import uuid import warnings +from collections.abc import Mapping from pathlib import Path from pathlib import PurePosixPath from typing import Any @@ -63,6 +64,7 @@ } HARBOR_ARTIFACT_ROOT = "/logs/agent/fabric-artifacts" HARBOR_DEFAULT_WORKSPACE = "/testbed" +_DETAILED_TOKEN_USAGE_V1_KEY = "nemo_fabric.detailed_token_usage.v1" try: from harbor.agents.base import BaseAgent @@ -836,6 +838,44 @@ def raise_run_failure(status: str, error: dict[str, Any] | None) -> NoReturn: raise RuntimeError(message) +def _usage_counter(usage: Mapping[str, Any], field: str) -> int | None: + value = usage.get(field) + if isinstance(value, bool) or not isinstance(value, int) or value < 0: + return None + return value + + +def _inclusive_token_count( + usage: Mapping[str, Any], + *, + primary_field: str, + included_field: str, + component_fields: tuple[str, ...], +) -> int | None: + primary = _usage_counter(usage, primary_field) + if primary is None: + return None + included = usage.get(included_field) + if included is True: + return primary + components = [_usage_counter(usage, field) for field in component_fields] + if included is False: + if any(value is None for value in components): + return None + return primary + sum(cast(int, value) for value in components) + if included is None and all(value == 0 for value in components): + return primary + return None + + +def _detailed_token_usage(usage: Mapping[str, Any]) -> Mapping[str, Any] | None: + metadata = usage.get("metadata") + if not isinstance(metadata, Mapping): + return None + detailed = metadata.get(_DETAILED_TOKEN_USAGE_V1_KEY) + return detailed if isinstance(detailed, Mapping) else None + + def populate_context_from_result( context: AgentContext, path: Path ) -> RunResult | FabricRunnerFailure: @@ -866,24 +906,63 @@ def populate_context_from_result( } if result.usage is not None: usage = result.usage - input_tokens = usage.get("input_tokens") - cached_input_tokens = usage.get("cached_input_tokens") - includes_cache = usage.get("input_tokens_include_cache") - if includes_cache is False: - input_tokens = ( - input_tokens + cached_input_tokens - if input_tokens is not None and cached_input_tokens is not None - else None + detailed_usage = _detailed_token_usage(usage) + has_detailed_input = detailed_usage is not None and any( + field in detailed_usage + for field in ( + "input_tokens", + "cached_input_tokens", + "cache_write_input_tokens", + "input_tokens_include_cache", + ) + ) + if has_detailed_input: + input_tokens = _inclusive_token_count( + cast(Mapping[str, Any], detailed_usage), + primary_field="input_tokens", + included_field="input_tokens_include_cache", + component_fields=("cached_input_tokens", "cache_write_input_tokens"), ) - elif includes_cache is None and cached_input_tokens != 0: - # Neither missing cache nor an unspecified convention proves an inclusive total. - input_tokens = None + cached_input_tokens = _usage_counter( + cast(Mapping[str, Any], detailed_usage), "cached_input_tokens" + ) + else: + input_tokens = usage.get("input_tokens") + cached_input_tokens = usage.get("cached_input_tokens") + includes_cache = usage.get("input_tokens_include_cache") + if includes_cache is False: + input_tokens = ( + input_tokens + cached_input_tokens + if input_tokens is not None and cached_input_tokens is not None + else None + ) + elif includes_cache is None and cached_input_tokens != 0: + # Neither missing cache nor an unspecified convention proves an inclusive total. + input_tokens = None + + has_detailed_output = detailed_usage is not None and any( + field in detailed_usage + for field in ( + "output_tokens", + "reasoning_tokens", + "output_tokens_include_reasoning", + ) + ) + if has_detailed_output: + output_tokens = _inclusive_token_count( + cast(Mapping[str, Any], detailed_usage), + primary_field="output_tokens", + included_field="output_tokens_include_reasoning", + component_fields=("reasoning_tokens",), + ) + else: + output_tokens = usage.get("output_tokens") if input_tokens is not None: context.n_input_tokens = input_tokens if cached_input_tokens is not None: context.n_cache_tokens = cached_input_tokens - if usage.get("output_tokens") is not None: - context.n_output_tokens = usage["output_tokens"] + if output_tokens is not None: + context.n_output_tokens = output_tokens if usage.get("cost_usd") is not None: context.cost_usd = usage["cost_usd"] return result diff --git a/sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py b/sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py index 25a08873f..04504e4dc 100644 --- a/sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py +++ b/sdk/python/nemo-fabric-runtime/src/nemo_fabric/types.py @@ -1773,10 +1773,8 @@ class RunUsage(FabricMapping): Missing counters and cost are unknown, not zero. ``cached_input_tokens`` records cache usage; ``input_tokens_include_cache`` declares whether input - already includes that count and any cache-write input the adapter reported. - An absent flag means the semantics are unknown. Cache-write input is not - reported here, so when the flag is ``False``, input plus cached input can - understate total input. + already includes that count. An absent flag means the semantics are unknown. + Descriptor-declared detailed usage is preserved in ``metadata``. """ input_tokens: int | None diff --git a/skills/nemo-fabric-build-adapter/SKILL.md b/skills/nemo-fabric-build-adapter/SKILL.md index 10a767cf8..9342ed454 100644 --- a/skills/nemo-fabric-build-adapter/SKILL.md +++ b/skills/nemo-fabric-build-adapter/SKILL.md @@ -228,7 +228,7 @@ required artifact references, and live workspace state may persist until telemetry scopes reset for each `invoke`. Independent runtime instances must never share mutable continuation state. -Normalize usage per invocation in `AgentUsage`. If the target reports cumulative session totals, retain a session-local baseline and difference successive observed counters rather than summing cumulative snapshots or using only the last model response. Missing or reset counters remain unknown. Report `cached_input_tokens` and `cache_write_input_tokens` when available and declare whether `input_tokens` includes both of them with `input_tokens_include_cache`; report `reasoning_tokens` with `output_tokens_include_reasoning` the same way. If the provider includes only one of the two cache counts in `input_tokens`, normalize `input_tokens` so that both are included or both are excluded before setting the flag. Omit a flag when the target's semantics are unknown. Report `peak_request_input_tokens` only when the target exposes per-request input counts. When the target reports usage per model, add one `AgentModelUsage` entry per provider and model pair to `usage.models`; NeMo Fabric rejects blank model identifiers and case-insensitive duplicates. NeMo Fabric does not copy cache-write, reasoning, peak request, or per-model usage into the consumer `RunResult.usage`. Preserve available usage on unsuccessful terminal results. Do not infer missing cost or promote estimates to `cost_usd`. +Normalize usage per invocation in `AgentUsage`. If the target reports cumulative session totals, retain a session-local baseline and difference successive observed counters rather than summing cumulative snapshots or using only the last model response. Missing or reset counters remain unknown. Keep the closed `fabric.adapter/v1alpha2` usage fields unchanged. Put cache-write, reasoning, peak request, and per-model detail in `usage.extensions["nemo_fabric.detailed_token_usage.v1"]`, and declare that object with `extension_schemas.usage` in the adapter descriptor. The detailed object repeats the normalized token counters so its inclusion flags are self-contained; `input_tokens_include_cache` covers both cached reads and cache writes there. Fabric preserves the object as `RunResult.usage.metadata["nemo_fabric.detailed_token_usage.v1"]`. Preserve available usage on unsuccessful terminal results. Do not infer missing cost or promote estimates to `cost_usd`. Test observable continuation rather than merely calling `invoke` twice: make the second result depend on the first turn without caller-side replay, then diff --git a/skills/nemo-fabric-integrate/references/results-and-errors.md b/skills/nemo-fabric-integrate/references/results-and-errors.md index 0e1311244..750be86cf 100644 --- a/skills/nemo-fabric-integrate/references/results-and-errors.md +++ b/skills/nemo-fabric-integrate/references/results-and-errors.md @@ -44,7 +44,7 @@ if result.usage is not None: ) ``` -Treat missing counters and cost as unknown, not zero. `cached_input_tokens` reports cached prompt tokens; `input_tokens_include_cache` declares whether `input_tokens` includes them (`True`), excludes them (`False`), or has unknown semantics (absent). Do not add cache to an inclusive input count. Keep estimated costs separate in provider metadata; `cost_usd` is reported cost, not an estimate. +Treat missing counters and cost as unknown, not zero. `cached_input_tokens` reports cached prompt tokens; `input_tokens_include_cache` declares whether `input_tokens` includes them (`True`), excludes them (`False`), or has unknown semantics (absent). Do not add cache to an inclusive input count. Adapters can put cache-write, reasoning, peak request, and per-model detail in the descriptor-declared `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` object. Fabric preserves that object at `result.usage["metadata"]["nemo_fabric.detailed_token_usage.v1"]`. Calculate an inclusive input or output total only when the matching inclusion flag and every excluded component are known; otherwise leave the total unknown. Keep estimated costs separate in provider metadata; `cost_usd` is reported cost, not an estimate. ## Correlation IDs diff --git a/tests/adapter_contract/test_agent_execution.py b/tests/adapter_contract/test_agent_execution.py index 69f5da802..756fce3b8 100644 --- a/tests/adapter_contract/test_agent_execution.py +++ b/tests/adapter_contract/test_agent_execution.py @@ -12,7 +12,6 @@ import pytest from nemo_fabric_adapter_contract.models import AgentArtifact -from nemo_fabric_adapter_contract.models import AgentModelUsage from nemo_fabric_adapter_contract.models import AgentRunError from nemo_fabric_adapter_contract.models import AgentRunRequest from nemo_fabric_adapter_contract.models import AgentRunResult @@ -55,149 +54,6 @@ def test_usage_rejects_invalid_cache_semantics(value): AgentUsage(input_tokens_include_cache=value) -DETAILED_USAGE = { - "input_tokens": 1200, - "cached_input_tokens": 800, - "cache_write_input_tokens": 300, - "input_tokens_include_cache": True, - "output_tokens": 90, - "reasoning_tokens": 40, - "output_tokens_include_reasoning": False, - "total_tokens": 1330, - "peak_request_input_tokens": 700, - "cost_usd": 0.5, - "models": [ - { - "model": "planner-model", - "provider": "openai", - "input_tokens": 1000, - "cached_input_tokens": 700, - "cache_write_input_tokens": 250, - "input_tokens_include_cache": True, - "output_tokens": 60, - "reasoning_tokens": 30, - "output_tokens_include_reasoning": True, - "total_tokens": 1060, - "peak_request_input_tokens": 600, - "cost_usd": 0.375, - }, - {"model": "summarizer-model"}, - ], - "extensions": {"source": "native"}, -} - - -def test_usage_detailed_fields_round_trip(): - usage = AgentUsage.from_mapping(DETAILED_USAGE) - - assert usage.models[0] == AgentModelUsage( - model="planner-model", - provider="openai", - input_tokens=1000, - cached_input_tokens=700, - cache_write_input_tokens=250, - input_tokens_include_cache=True, - output_tokens=60, - reasoning_tokens=30, - output_tokens_include_reasoning=True, - total_tokens=1060, - peak_request_input_tokens=600, - cost_usd=0.375, - ) - assert usage.to_mapping() == DETAILED_USAGE - assert type_adapter(AgentUsage).validate_python(DETAILED_USAGE) == usage - - -def test_usage_without_detailed_fields_keeps_wire_shape(): - usage = AgentUsage(input_tokens=3, output_tokens=5) - - assert usage.models == [] - assert usage.to_mapping() == {"input_tokens": 3, "output_tokens": 5} - - -@pytest.mark.parametrize( - "field_name", - ["cache_write_input_tokens", "reasoning_tokens", "peak_request_input_tokens"], -) -@pytest.mark.parametrize("model", [AgentUsage, AgentModelUsage]) -@pytest.mark.parametrize("value", [-1, 1 << 64, True, 1.5]) -def test_usage_rejects_invalid_detailed_counter(model, field_name, value): - required = {"model": "planner-model"} if model is AgentModelUsage else {} - with pytest.raises(ContractValidationError): - model(**required, **{field_name: value}) - - -@pytest.mark.parametrize("model", [AgentUsage, AgentModelUsage]) -@pytest.mark.parametrize("value", [0, 1, "true"]) -def test_usage_rejects_invalid_reasoning_semantics(model, value): - required = {"model": "planner-model"} if model is AgentModelUsage else {} - with pytest.raises(ContractValidationError): - model(**required, output_tokens_include_reasoning=value) - - -@pytest.mark.parametrize( - ("mapping", "message"), - [ - ({}, "missing required field 'model'"), - ({"model": " \t"}, "model: must be a non-empty string"), - ( - {"model": "planner-model", "provider": " \t"}, - "provider: must be a non-empty string", - ), - ( - {"model": "planner-model", "cost_usd": -1.0}, - "cost_usd: must be greater than or equal to 0", - ), - ( - {"model": "planner-model", "cost_usd": float("nan")}, - "cost_usd: must be a finite number", - ), - ( - {"model": "planner-model", "cost_usd": float("inf")}, - "cost_usd: must be a finite number", - ), - ({"model": "planner-model", "reasoning": 1}, "unexpected field 'reasoning'"), - ( - {"model": "planner-model", "extensions": {}}, - "unexpected field 'extensions'", - ), - ], -) -def test_model_usage_rejects_invalid_values(mapping, message): - with pytest.raises(ContractValidationError, match=message): - AgentModelUsage.from_mapping(mapping) - - -@pytest.mark.parametrize( - "models", - [ - [{"model": "planner-model"}, {"model": "Planner-Model"}], - [ - {"model": "planner-model", "provider": "openai"}, - {"model": "PLANNER-MODEL", "provider": "OpenAI"}, - ], - ], -) -def test_usage_rejects_duplicate_models_case_insensitively(models): - with pytest.raises( - ContractValidationError, - match="models.1: must report each provider and model pair once", - ): - AgentUsage.from_mapping({"models": models}) - - -def test_usage_accepts_one_model_served_by_distinct_providers(): - usage = AgentUsage( - models=[ - AgentModelUsage(model="planner-model"), - AgentModelUsage(model="planner-model", provider="openai"), - AgentModelUsage(model="planner-model", provider="azure"), - ] - ) - - assert len(usage.models) == 3 - - def test_agent_run_request_contains_only_southbound_request_fields(): request = AgentRunRequest( input={"messages": [{"role": "user", "content": "hello"}]}, @@ -292,7 +148,7 @@ def test_agent_execution_models_track_rust_schema_root_fields(model, filename): [ ( "agent-run-result.schema.json", - (AgentArtifact, AgentModelUsage, AgentRunError, AgentUsage), + (AgentArtifact, AgentRunError, AgentUsage), ), ( "runtime-context.schema.json", diff --git a/tests/python/test_harbor_accounting.py b/tests/python/test_harbor_accounting.py index 628e7b707..eef71e93d 100644 --- a/tests/python/test_harbor_accounting.py +++ b/tests/python/test_harbor_accounting.py @@ -129,6 +129,111 @@ def test_cache_semantics_and_unknown_values( assert context.metadata["fabric"]["usage"] == {"metadata": {}, **usage} +@pytest.mark.parametrize( + ("detailed_usage", "expected_input", "expected_output", "expected_cache"), + [ + ( + { + "input_tokens": 20, + "cached_input_tokens": 5, + "cache_write_input_tokens": 3, + "input_tokens_include_cache": False, + "output_tokens": 5, + "reasoning_tokens": 4, + "output_tokens_include_reasoning": False, + }, + 28, + 9, + 5, + ), + ( + { + "input_tokens": 20, + "cached_input_tokens": 5, + "cache_write_input_tokens": 3, + "input_tokens_include_cache": True, + "output_tokens": 5, + "reasoning_tokens": 4, + "output_tokens_include_reasoning": True, + }, + 20, + 5, + 5, + ), + ( + { + "input_tokens": 20, + "cached_input_tokens": 5, + "input_tokens_include_cache": False, + "output_tokens": 5, + "reasoning_tokens": 4, + "output_tokens_include_reasoning": False, + }, + None, + 9, + 5, + ), + ( + { + "input_tokens": 20, + "cached_input_tokens": 5, + "cache_write_input_tokens": 3, + "input_tokens_include_cache": False, + "output_tokens": 5, + "output_tokens_include_reasoning": False, + }, + 28, + None, + 5, + ), + ( + { + "input_tokens": 20, + "cached_input_tokens": 0, + "cache_write_input_tokens": 0, + "output_tokens": 5, + "reasoning_tokens": 0, + }, + 20, + 5, + 0, + ), + ({"models": []}, 999, 999, 999), + ], +) +def test_detailed_usage_reports_only_complete_inclusive_totals( + result_path, + detailed_usage, + expected_input, + expected_output, + expected_cache, +): + from harbor.models.agent.context import AgentContext + from nemo_fabric.integrations.harbor.fabric_agent import ( + populate_context_from_result, + ) + + document = json.loads(result_path.read_text()) + document["usage"] = { + "input_tokens": 999, + "cached_input_tokens": 999, + "input_tokens_include_cache": True, + "output_tokens": 999, + "metadata": {"nemo_fabric.detailed_token_usage.v1": detailed_usage}, + } + result_path.write_text(json.dumps(document)) + context = AgentContext() + + populate_context_from_result(context, result_path) + + assert context.n_input_tokens == expected_input + assert context.n_output_tokens == expected_output + assert context.n_cache_tokens == expected_cache + assert context.metadata["fabric"]["usage"]["metadata"] == { + "nemo_fabric.detailed_token_usage.v1": detailed_usage + } + + @pytest.mark.parametrize( ("usage", "expected"), [ From 51b3127341d124f0d2378b59c2aa100aa19dc468 Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Mon, 12 Oct 2026 13:31:00 -0700 Subject: [PATCH 08/10] test: cover partial detailed usage Signed-off-by: mnajafian-nv --- tests/python/test_harbor_accounting.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/python/test_harbor_accounting.py b/tests/python/test_harbor_accounting.py index eef71e93d..f3aa55655 100644 --- a/tests/python/test_harbor_accounting.py +++ b/tests/python/test_harbor_accounting.py @@ -198,6 +198,7 @@ def test_cache_semantics_and_unknown_values( 5, 0, ), + ({"reasoning_tokens": 4}, 999, None, 999), ({"models": []}, 999, 999, 999), ], ) From e9d6b02cd96b6a9cf7b7a6fb719a27331c4284ee Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Mon, 12 Oct 2026 16:12:33 -0700 Subject: [PATCH 09/10] docs: clarify detailed usage precedence Signed-off-by: mnajafian-nv --- .agents/skills/contribute-adapter/SKILL.md | 2 +- docs/adapter-contract/tutorials/results.md | 2 +- docs/sdk/python.mdx | 2 +- .../integrations/harbor/fabric_agent.py | 2 ++ skills/nemo-fabric-build-adapter/SKILL.md | 2 +- .../references/results-and-errors.md | 2 +- tests/python/test_harbor_accounting.py | 17 +++++++++++++++-- 7 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.agents/skills/contribute-adapter/SKILL.md b/.agents/skills/contribute-adapter/SKILL.md index c2e8c62e7..ac9fb6ea2 100644 --- a/.agents/skills/contribute-adapter/SKILL.md +++ b/.agents/skills/contribute-adapter/SKILL.md @@ -57,7 +57,7 @@ Keep descriptor claims, implementation, focused tests, public documentation, catalog entries, and packaged metadata synchronized. Start with the narrowest truthful capability set. -For usage changes, verify invocation-local accounting through the adapter contract and consumer SDK, including warm-session deltas, unknown counters, cache semantics, and unsuccessful results. Keep generated schemas and language bindings in parity. Preserve the closed `fabric.adapter/v1alpha2` `AgentUsage` shape; carry detailed cache-write, reasoning, peak request, and per-model data in the descriptor-declared `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` object until a new adapter contract revision negotiates those fields. +For usage changes, verify invocation-local accounting through the adapter contract and consumer SDK, including warm-session deltas, unknown counters, cache semantics, and unsuccessful results. Keep generated schemas and language bindings in parity. Preserve the closed `fabric.adapter/v1alpha2` `AgentUsage` shape; carry detailed cache-write, reasoning, peak request, and per-model data in the descriptor-declared `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` object until a new adapter contract revision negotiates those fields. Consumers treat any detailed field for an input or output dimension as selecting the detailed counters for that dimension, so require complete, internally consistent counters instead of relying on the top-level view as a fallback. For `instructions.system`, keep `config.system_instruction_modes`, planning behavior, direct adapter validation, and target-native composition synchronized. diff --git a/docs/adapter-contract/tutorials/results.md b/docs/adapter-contract/tutorials/results.md index de9dceaca..7e8f6646b 100644 --- a/docs/adapter-contract/tutorials/results.md +++ b/docs/adapter-contract/tutorials/results.md @@ -79,7 +79,7 @@ Report only observed invocation usage. For cumulative target counters, compute t `fabric.adapter/v1alpha2` usage is a closed object. Do not add cache-write, reasoning, peak request, or per-model fields at its root. Put that detail in `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` and declare the extension with `extension_schemas.usage` in the adapter descriptor. The detailed object repeats the normalized input, cached-input, output, and total token fields and can add `cache_write_input_tokens`, `reasoning_tokens`, `output_tokens_include_reasoning`, `peak_request_input_tokens`, and `models`. Within this object, `input_tokens_include_cache` applies to both cached reads and cache writes. Normalize `input_tokens` first if the provider includes only one component. Each model entry uses the same counters and requires a non-blank `model`; include `provider` when known. -Fabric preserves the extension at `RunResult.usage.metadata["nemo_fabric.detailed_token_usage.v1"]`. Consumers calculate inclusive input or output totals only when the matching inclusion flag and every excluded component are known. Otherwise, the inclusive total is unknown. +NeMo Fabric preserves the extension at `RunResult.usage.metadata["nemo_fabric.detailed_token_usage.v1"]`. Consumers treat the detailed object as authoritative independently for each token dimension. Any of `input_tokens`, `cached_input_tokens`, `cache_write_input_tokens`, or `input_tokens_include_cache` selects the detailed input counters. Any of `output_tokens`, `reasoning_tokens`, or `output_tokens_include_reasoning` selects the detailed output counters. Consumers do not fall back to the top-level counters for a selected dimension, so the detailed and top-level views can diverge. If the selected counters do not contain enough information to determine an inclusive total, that total remains unknown even when the top-level view contains a value. **Success Check**: `invoke` returns one typed `AgentRunResult` whose explicit status matches the presence or absence of an error. diff --git a/docs/sdk/python.mdx b/docs/sdk/python.mdx index d34bb81e1..a99b5d281 100644 --- a/docs/sdk/python.mdx +++ b/docs/sdk/python.mdx @@ -893,7 +893,7 @@ if result.usage is not None: print(result.usage.get("cost_usd")) ``` -Each counter is optional: missing values are unknown, not zero. `cached_input_tokens` reports cached prompt tokens. `input_tokens_include_cache` is `True` when those tokens are already included in `input_tokens`, `False` when they are excluded, and absent when the adapter cannot establish the semantics. Consumers must not add cached tokens to an inclusive input count. Adapters can report cache-write, reasoning, peak request, and per-model detail through the descriptor-declared `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` object. Fabric preserves that object at `RunUsage.metadata["nemo_fabric.detailed_token_usage.v1"]`; an inclusive total remains unknown unless its inclusion flag and every excluded component are known. `cost_usd` contains reported cost only; keep estimates separately in provider metadata rather than presenting them as measured charges. +Each counter is optional: missing values are unknown, not zero. `cached_input_tokens` reports cached prompt tokens. `input_tokens_include_cache` is `True` when those tokens are already included in `input_tokens`, `False` when they are excluded, and absent when the adapter cannot establish the semantics. Consumers must not add cached tokens to an inclusive input count. Adapters can report cache-write, reasoning, peak request, and per-model detail through the descriptor-declared `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` object. NeMo Fabric preserves that object at `RunUsage.metadata["nemo_fabric.detailed_token_usage.v1"]`. Consumers treat detailed input and output independently: any detailed accounting field for a dimension makes that dimension authoritative, with no fallback to its top-level counters. The views can diverge, and an inclusive total remains unknown when the selected detailed counters do not provide enough information to calculate it. `cost_usd` contains reported cost only; keep estimates separately in provider metadata rather than presenting them as measured charges. If NeMo Fabric cannot resolve config, start a runtime, or obtain a normalized result, the SDK raises a `FabricError` subclass instead of returning a partial diff --git a/sdk/python/nemo-fabric-runtime/src/nemo_fabric/integrations/harbor/fabric_agent.py b/sdk/python/nemo-fabric-runtime/src/nemo_fabric/integrations/harbor/fabric_agent.py index 4f0590892..2c7e25a95 100644 --- a/sdk/python/nemo-fabric-runtime/src/nemo_fabric/integrations/harbor/fabric_agent.py +++ b/sdk/python/nemo-fabric-runtime/src/nemo_fabric/integrations/harbor/fabric_agent.py @@ -907,6 +907,8 @@ def populate_context_from_result( if result.usage is not None: usage = result.usage detailed_usage = _detailed_token_usage(usage) + # Do not mix top-level and detailed counters within one dimension. Any + # dimension-specific detailed field selects that view, even if incomplete. has_detailed_input = detailed_usage is not None and any( field in detailed_usage for field in ( diff --git a/skills/nemo-fabric-build-adapter/SKILL.md b/skills/nemo-fabric-build-adapter/SKILL.md index 9342ed454..163923408 100644 --- a/skills/nemo-fabric-build-adapter/SKILL.md +++ b/skills/nemo-fabric-build-adapter/SKILL.md @@ -228,7 +228,7 @@ required artifact references, and live workspace state may persist until telemetry scopes reset for each `invoke`. Independent runtime instances must never share mutable continuation state. -Normalize usage per invocation in `AgentUsage`. If the target reports cumulative session totals, retain a session-local baseline and difference successive observed counters rather than summing cumulative snapshots or using only the last model response. Missing or reset counters remain unknown. Keep the closed `fabric.adapter/v1alpha2` usage fields unchanged. Put cache-write, reasoning, peak request, and per-model detail in `usage.extensions["nemo_fabric.detailed_token_usage.v1"]`, and declare that object with `extension_schemas.usage` in the adapter descriptor. The detailed object repeats the normalized token counters so its inclusion flags are self-contained; `input_tokens_include_cache` covers both cached reads and cache writes there. Fabric preserves the object as `RunResult.usage.metadata["nemo_fabric.detailed_token_usage.v1"]`. Preserve available usage on unsuccessful terminal results. Do not infer missing cost or promote estimates to `cost_usd`. +Normalize usage per invocation in `AgentUsage`. If the target reports cumulative session totals, retain a session-local baseline and difference successive observed counters rather than summing cumulative snapshots or using only the last model response. Missing or reset counters remain unknown. Keep the closed `fabric.adapter/v1alpha2` usage fields unchanged. Put cache-write, reasoning, peak request, and per-model detail in `usage.extensions["nemo_fabric.detailed_token_usage.v1"]`, and declare that object with `extension_schemas.usage` in the adapter descriptor. The detailed object repeats the normalized token counters so its inclusion flags are self-contained; `input_tokens_include_cache` covers both cached reads and cache writes there. NeMo Fabric preserves the object as `RunResult.usage.metadata["nemo_fabric.detailed_token_usage.v1"]`. Consumers treat any detailed field for an input or output dimension as selecting the detailed counters for that dimension without falling back to its top-level counters. Report the primary counter, inclusion flag, and every excluded component together so consumers can calculate an inclusive total. Preserve available usage on unsuccessful terminal results. Do not infer missing cost or promote estimates to `cost_usd`. Test observable continuation rather than merely calling `invoke` twice: make the second result depend on the first turn without caller-side replay, then diff --git a/skills/nemo-fabric-integrate/references/results-and-errors.md b/skills/nemo-fabric-integrate/references/results-and-errors.md index 750be86cf..f2660d5e3 100644 --- a/skills/nemo-fabric-integrate/references/results-and-errors.md +++ b/skills/nemo-fabric-integrate/references/results-and-errors.md @@ -44,7 +44,7 @@ if result.usage is not None: ) ``` -Treat missing counters and cost as unknown, not zero. `cached_input_tokens` reports cached prompt tokens; `input_tokens_include_cache` declares whether `input_tokens` includes them (`True`), excludes them (`False`), or has unknown semantics (absent). Do not add cache to an inclusive input count. Adapters can put cache-write, reasoning, peak request, and per-model detail in the descriptor-declared `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` object. Fabric preserves that object at `result.usage["metadata"]["nemo_fabric.detailed_token_usage.v1"]`. Calculate an inclusive input or output total only when the matching inclusion flag and every excluded component are known; otherwise leave the total unknown. Keep estimated costs separate in provider metadata; `cost_usd` is reported cost, not an estimate. +Treat missing counters and cost as unknown, not zero. `cached_input_tokens` reports cached prompt tokens; `input_tokens_include_cache` declares whether `input_tokens` includes them (`True`), excludes them (`False`), or has unknown semantics (absent). Do not add cache to an inclusive input count. Adapters can put cache-write, reasoning, peak request, and per-model detail in the descriptor-declared `usage.extensions["nemo_fabric.detailed_token_usage.v1"]` object. NeMo Fabric preserves that object at `result.usage["metadata"]["nemo_fabric.detailed_token_usage.v1"]`. Treat detailed input and output independently: any detailed accounting field for a dimension makes that dimension authoritative, with no fallback to its top-level counters. The views can diverge. Calculate an inclusive total only when the selected detailed counters provide enough information; otherwise leave the total unknown. Keep estimated costs separate in provider metadata; `cost_usd` is reported cost, not an estimate. ## Correlation IDs diff --git a/tests/python/test_harbor_accounting.py b/tests/python/test_harbor_accounting.py index f3aa55655..5663511af 100644 --- a/tests/python/test_harbor_accounting.py +++ b/tests/python/test_harbor_accounting.py @@ -198,11 +198,24 @@ def test_cache_semantics_and_unknown_values( 5, 0, ), - ({"reasoning_tokens": 4}, 999, None, 999), + pytest.param( + {"cache_write_input_tokens": 3}, + None, + 999, + None, + id="cache-write-only-selects-detailed-input", + ), + pytest.param( + {"reasoning_tokens": 4}, + 999, + None, + 999, + id="reasoning-only-selects-detailed-output", + ), ({"models": []}, 999, 999, 999), ], ) -def test_detailed_usage_reports_only_complete_inclusive_totals( +def test_detailed_usage_is_authoritative_per_dimension( result_path, detailed_usage, expected_input, From 7e72e494c6366882d0a4a65a24984bd2388a19bf Mon Sep 17 00:00:00 2001 From: mnajafian-nv Date: Mon, 12 Oct 2026 16:52:57 -0700 Subject: [PATCH 10/10] test: update Pi consumer install suite Signed-off-by: mnajafian-nv --- adapters/typescript/scripts/check-install.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adapters/typescript/scripts/check-install.mjs b/adapters/typescript/scripts/check-install.mjs index 1bfc0b447..962c2d8da 100644 --- a/adapters/typescript/scripts/check-install.mjs +++ b/adapters/typescript/scripts/check-install.mjs @@ -327,9 +327,9 @@ try { "--no-audit", "--no-fund", "--package-lock=false", - "@earendil-works/pi-ai@1.0.3", - "@earendil-works/pi-coding-agent@1.0.3", - "@earendil-works/pi-mcp@1.0.3", + "@earendil-works/pi-ai@1.2.0", + "@earendil-works/pi-coding-agent@1.2.0", + "@earendil-works/pi-mcp@1.2.0", ], consumerRoot, );