By default, the CopilotClient starts in CopilotCli mode. That means the full Copilot CLI persona is active — which includes a lot: All built-in tools available (subject to the ToolSet filtering you do per session) Host integration enabled: the CLI picks up your local ~/.copilot/ config, agents directory, plugins, and AGENTS.md files if they exist The default system prompt with the full Copilot identity Co-author trailers added to git commits Storage backed by the local filesystem at the default path For a developer using the SDK on their own machine to automate their own workflows, this is perfect. The agent behaves exactly like Copilot CLI would interactively. Context flows in from their environment, their local agent configs are respected, their Copilot persona is preserved. The multi-tenant problem The moment you start running the SDK as a service — where one process handles sessions for multiple users or tenants — default mode becomes a liability. ...
Shining a light on .NET versions across our organisation with OpenTelemetry – The Azure Monitor edition
In a previous post I showed how to add the .NET runtime version as an OpenTelemetry resource attribute: ResourceBuilder.CreateEmpty() .AddService($"{_sofaSettings.ApplicationName}-{_sofaSettings.EnvironmentName}") .AddAttributes(new Dictionary<string, object> { ["deployment.environment"] = _sofaSettings.EnvironmentName, ["service.name"] = _sofaSettings.ApplicationName, ["runtime.dotnet.version"] = Environment.Version.ToString() }) .Build(); The idea was clean: attach facts about what is running directly to the resource, and let OpenTelemetry carry them along with every trace, metric, and log automatically. Unfortunately, there is a catch. The problem Azure Monitor's OpenTelemetry exporter only maps a fixed set of well-known resource attributes onto Application Insights fields. service.name and service.namespace become Cloud Role Name, service.instance.id becomes Cloud Role Insta...