Skip to content

Commit 1742053

Browse files
tclemCopilot
andcommitted
Add TelemetryConfig builder methods
Final missing piece in the consumer-facing #[non_exhaustive] config struct audit. `TelemetryConfig` had public optional fields (otlp_endpoint, file_path, exporter_type, source_name, capture_content) and an is_empty() helper, but no `new()` or `with_*` setters — leaving callers to write `TelemetryConfig { otlp_endpoint: Some(...), ..Default::default() }` which doesn't compile from outside the crate due to #[non_exhaustive]. Adds `TelemetryConfig::new()` (delegates to Default) and `with_*` setters for all five fields, matching the existing pattern. The is_empty() helper stays unchanged. After this commit, every consumer-facing #[non_exhaustive] struct in the SDK has a fluent builder: ClientOptions, TelemetryConfig, Tool, CommandDefinition, CustomAgentConfig, InfiniteSessionConfig, ProviderConfig, SessionConfig, ResumeSessionConfig, SystemMessageConfig, MessageOptions, SessionFsConfig, TraceContext. One unit test (telemetry_config_builder_composes) covering all five setters + is_empty behavior on a fresh new(). Extends the existing CHANGELOG "Builder ergonomics" round-out bullet. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d20cd3e commit 1742053

2 files changed

Lines changed: 67 additions & 3 deletions

File tree

rust/CHANGELOG.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,12 @@ public surface.
391391
`ProviderConfig::new(base_url)` plus `with_provider_type`,
392392
`with_wire_api`, `with_api_key`, `with_bearer_token`,
393393
`with_azure`, `with_headers`; `SystemMessageConfig::new()` plus
394-
`with_mode`, `with_content`, `with_sections`. `TraceContext`
395-
also gains a symmetric `new()` + `with_traceparent` pair
396-
alongside the existing `from_traceparent` shorthand.
394+
`with_mode`, `with_content`, `with_sections`;
395+
`TelemetryConfig::new()` plus `with_otlp_endpoint`,
396+
`with_file_path`, `with_exporter_type`, `with_source_name`,
397+
`with_capture_content`. `TraceContext` also gains a symmetric
398+
`new()` + `with_traceparent` pair alongside the existing
399+
`from_traceparent` shorthand.
397400
- Documented the direct-field-assignment escape hatch on
398401
`SessionConfig` and `ResumeSessionConfig` for callers forwarding
399402
`Option<T>` values from upstream code (matches the

rust/src/lib.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,46 @@ pub struct TelemetryConfig {
538538
}
539539

540540
impl TelemetryConfig {
541+
/// Construct an empty [`TelemetryConfig`]; all fields default to
542+
/// unset (`is_empty()` returns `true`).
543+
pub fn new() -> Self {
544+
Self::default()
545+
}
546+
547+
/// Set the OTLP HTTP endpoint URL for trace/metric export.
548+
pub fn with_otlp_endpoint(mut self, endpoint: impl Into<String>) -> Self {
549+
self.otlp_endpoint = Some(endpoint.into());
550+
self
551+
}
552+
553+
/// Set the file path for JSON-lines trace output.
554+
pub fn with_file_path(mut self, path: impl Into<PathBuf>) -> Self {
555+
self.file_path = Some(path.into());
556+
self
557+
}
558+
559+
/// Set the exporter backend type.
560+
pub fn with_exporter_type(mut self, exporter_type: OtelExporterType) -> Self {
561+
self.exporter_type = Some(exporter_type);
562+
self
563+
}
564+
565+
/// Set the instrumentation scope name. Useful for distinguishing
566+
/// this embedder's traces from other Copilot-CLI consumers
567+
/// exporting to the same backend.
568+
pub fn with_source_name(mut self, source_name: impl Into<String>) -> Self {
569+
self.source_name = Some(source_name.into());
570+
self
571+
}
572+
573+
/// Opt in or out of GenAI message content capture on emitted spans.
574+
/// `true` opts in; `false` opts out. Leaving this unset preserves
575+
/// the CLI default (typically off).
576+
pub fn with_capture_content(mut self, capture: bool) -> Self {
577+
self.capture_content = Some(capture);
578+
self
579+
}
580+
541581
/// Returns `true` if all fields are unset. Used by [`Client::start`]
542582
/// to decide whether to set `COPILOT_OTEL_ENABLED`.
543583
pub fn is_empty(&self) -> bool {
@@ -1858,6 +1898,27 @@ mod tests {
18581898
.and_then(|(_, v)| v)
18591899
}
18601900

1901+
#[test]
1902+
fn telemetry_config_builder_composes() {
1903+
let cfg = TelemetryConfig::new()
1904+
.with_otlp_endpoint("http://collector:4318")
1905+
.with_file_path(PathBuf::from("/var/log/copilot.jsonl"))
1906+
.with_exporter_type(OtelExporterType::OtlpHttp)
1907+
.with_source_name("my-app")
1908+
.with_capture_content(true);
1909+
1910+
assert_eq!(cfg.otlp_endpoint.as_deref(), Some("http://collector:4318"));
1911+
assert_eq!(
1912+
cfg.file_path.as_deref(),
1913+
Some(Path::new("/var/log/copilot.jsonl")),
1914+
);
1915+
assert_eq!(cfg.exporter_type, Some(OtelExporterType::OtlpHttp));
1916+
assert_eq!(cfg.source_name.as_deref(), Some("my-app"));
1917+
assert_eq!(cfg.capture_content, Some(true));
1918+
assert!(!cfg.is_empty());
1919+
assert!(TelemetryConfig::new().is_empty());
1920+
}
1921+
18611922
#[test]
18621923
fn build_command_sets_otel_env_when_telemetry_enabled() {
18631924
let opts = ClientOptions {

0 commit comments

Comments
 (0)