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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dotnet/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
<PackageVersion Include="Microsoft.Extensions.AI.Evaluation.Safety" Version="10.3.0-preview.1.26109.11" />
<PackageVersion Include="Microsoft.Extensions.AI.OpenAI" Version="10.4.0" />
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" />
<PackageVersion Include="Microsoft.Extensions.Compliance.Abstractions" Version="10.4.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.0" />
Expand Down
4 changes: 4 additions & 0 deletions dotnet/agent-framework-dotnet.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,10 @@
<File Path="src/Shared/Samples/TextOutputHelperExtensions.cs" />
<File Path="src/Shared/Samples/XunitLogger.cs" />
</Folder>
<Folder Name="/Solution Items/src/Shared/Redaction/">
<File Path="src/Shared/Redaction/README.md" />
<File Path="src/Shared/Redaction/ReplacingRedactor.cs" />
</Folder>
<Folder Name="/Solution Items/src/Shared/Throw/">
<File Path="src/Shared/Throw/README.md" />
<File Path="src/Shared/Throw/Throw.cs" />
Expand Down
3 changes: 3 additions & 0 deletions dotnet/eng/MSBuild/Shared.props
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,7 @@
<ItemGroup Condition="'$(InjectSharedDiagnosticIds)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\DiagnosticIds\*.cs" LinkBase="Shared\DiagnosticIds" />
</ItemGroup>
<ItemGroup Condition="'$(InjectSharedRedaction)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)\..\..\src\Shared\Redaction\*.cs" LinkBase="Shared\Redaction" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading.Tasks;
using Azure.AI.Projects;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Compliance.Redaction;
using Microsoft.Extensions.Logging;
using Microsoft.Shared.DiagnosticIds;
using Microsoft.Shared.Diagnostics;
Expand Down Expand Up @@ -37,7 +38,7 @@ public sealed class FoundryMemoryProvider : AIContextProvider
private readonly string _memoryStoreName;
private readonly int _maxMemories;
private readonly int _updateDelay;
private readonly bool _enableSensitiveTelemetryData;
private readonly Redactor _redactor;

private readonly AIProjectClient _client;
private readonly ILogger<FoundryMemoryProvider>? _logger;
Expand Down Expand Up @@ -79,7 +80,7 @@ public FoundryMemoryProvider(
this._memoryStoreName = memoryStoreName;
this._maxMemories = effectiveOptions.MaxMemories;
this._updateDelay = effectiveOptions.UpdateDelay;
this._enableSensitiveTelemetryData = effectiveOptions.EnableSensitiveTelemetryData;
this._redactor = effectiveOptions.EnableSensitiveTelemetryData ? NullRedactor.Instance : (effectiveOptions.Redactor ?? new ReplacingRedactor("<redacted>"));
}

/// <inheritdoc />
Expand Down Expand Up @@ -416,7 +417,7 @@ private static MessageResponseItem ToResponseItem(ChatRole role, string text)
private static bool IsAllowedRole(ChatRole role) =>
role == ChatRole.User || role == ChatRole.Assistant || role == ChatRole.System;

private string? SanitizeLogData(string? data) => this._enableSensitiveTelemetryData ? data : "<redacted>";
private string SanitizeLogData(string? data) => this._redactor.Redact(data);

/// <summary>
/// Represents the state of a <see cref="FoundryMemoryProvider"/> stored in the <see cref="AgentSession.StateBag"/>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Compliance.Redaction;

namespace Microsoft.Agents.AI.FoundryMemory;

Expand Down Expand Up @@ -37,8 +38,22 @@ public sealed class FoundryMemoryProviderOptions
/// Gets or sets a value indicating whether sensitive data such as user ids and user messages may appear in logs.
/// </summary>
/// <value>Defaults to <see langword="false"/>.</value>
/// <remarks>
/// When set to <see langword="true"/>, sensitive data is passed through to logs unchanged and any
/// configured <see cref="Redactor"/> is ignored. This property takes precedence over <see cref="Redactor"/>.
/// </remarks>
public bool EnableSensitiveTelemetryData { get; set; }

/// <summary>
/// Gets or sets a custom <see cref="Redactor"/> used to redact sensitive data in log output.
/// </summary>
/// <value>
/// When <see langword="null"/> (the default), sensitive data is replaced with a placeholder.
/// When set, this redactor is used to transform sensitive values before they are logged.
/// Ignored when <see cref="EnableSensitiveTelemetryData"/> is <see langword="true"/>.
/// </value>
public Redactor? Redactor { get; set; }

/// <summary>
/// Gets or sets the key used to store the provider state in the session's <see cref="AgentSessionStateBag"/>.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<PropertyGroup>
<InjectSharedThrow>true</InjectSharedThrow>
<InjectSharedDiagnosticIds>true</InjectSharedDiagnosticIds>
<InjectSharedRedaction>true</InjectSharedRedaction>
<InjectExperimentalAttributeOnLegacy>true</InjectExperimentalAttributeOnLegacy>
<InjectTrimAttributesOnLegacy>true</InjectTrimAttributesOnLegacy>
</PropertyGroup>
Expand All @@ -20,6 +21,7 @@

<ItemGroup>
<PackageReference Include="Azure.AI.Projects" />
<PackageReference Include="Microsoft.Extensions.Compliance.Abstractions" />
<PackageReference Include="OpenAI" />
</ItemGroup>

Expand Down
7 changes: 4 additions & 3 deletions dotnet/src/Microsoft.Agents.AI.Mem0/Mem0Provider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Compliance.Redaction;
using Microsoft.Extensions.Logging;
using Microsoft.Shared.Diagnostics;

Expand Down Expand Up @@ -51,7 +52,7 @@ public sealed class Mem0Provider : MessageAIContextProvider
private readonly ProviderSessionState<State> _sessionState;
private IReadOnlyList<string>? _stateKeys;
private readonly string _contextPrompt;
private readonly bool _enableSensitiveTelemetryData;
private readonly Redactor _redactor;

private readonly Mem0Client _client;
private readonly ILogger<Mem0Provider>? _logger;
Expand Down Expand Up @@ -91,7 +92,7 @@ public Mem0Provider(HttpClient httpClient, Func<AgentSession?, State> stateIniti
this._client = new Mem0Client(httpClient);

this._contextPrompt = options?.ContextPrompt ?? DefaultContextPrompt;
this._enableSensitiveTelemetryData = options?.EnableSensitiveTelemetryData ?? false;
this._redactor = options?.EnableSensitiveTelemetryData == true ? NullRedactor.Instance : (options?.Redactor ?? new ReplacingRedactor("<redacted>"));
}

/// <inheritdoc />
Expand Down Expand Up @@ -297,5 +298,5 @@ public State(Mem0ProviderScope storageScope, Mem0ProviderScope? searchScope = nu
public Mem0ProviderScope SearchScope { get; }
}

private string? SanitizeLogData(string? data) => this._enableSensitiveTelemetryData ? data : "<redacted>";
private string SanitizeLogData(string? data) => this._redactor.Redact(data);
}
15 changes: 15 additions & 0 deletions dotnet/src/Microsoft.Agents.AI.Mem0/Mem0ProviderOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Compliance.Redaction;

namespace Microsoft.Agents.AI.Mem0;

Expand All @@ -21,8 +22,22 @@ public sealed class Mem0ProviderOptions
/// Gets or sets a value indicating whether sensitive data such as user ids and user messages may appear in logs.
/// </summary>
/// <value>Defaults to <see langword="false"/>.</value>
/// <remarks>
/// When set to <see langword="true"/>, sensitive data is passed through to logs unchanged and any
/// configured <see cref="Redactor"/> is ignored. This property takes precedence over <see cref="Redactor"/>.
/// </remarks>
public bool EnableSensitiveTelemetryData { get; set; }

/// <summary>
/// Gets or sets a custom <see cref="Redactor"/> used to redact sensitive data in log output.
/// </summary>
/// <value>
/// When <see langword="null"/> (the default), sensitive data is replaced with a placeholder.
/// When set, this redactor is used to transform sensitive values before they are logged.
/// Ignored when <see cref="EnableSensitiveTelemetryData"/> is <see langword="true"/>.
/// </value>
public Redactor? Redactor { get; set; }

/// <summary>
/// Gets or sets the key used to store the provider state in the session's <see cref="AgentSessionStateBag"/>.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<PropertyGroup>
<InjectSharedThrow>true</InjectSharedThrow>
<InjectSharedRedaction>true</InjectSharedRedaction>
<InjectTrimAttributesOnLegacy>true</InjectTrimAttributesOnLegacy>
</PropertyGroup>

Expand All @@ -23,6 +24,10 @@
<ProjectReference Include="..\Microsoft.Agents.AI.Abstractions\Microsoft.Agents.AI.Abstractions.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Compliance.Abstractions" />
</ItemGroup>

<PropertyGroup>
<!-- NuGet Package Settings -->
<Title>Microsoft Agent Framework - Mem0 integration</Title>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Compliance.Redaction;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.VectorData;
using Microsoft.Shared.Diagnostics;
Expand Down Expand Up @@ -80,7 +81,7 @@ public sealed class ChatHistoryMemoryProvider : MessageAIContextProvider, IDispo
private readonly VectorStoreCollection<object, Dictionary<string, object?>> _collection;
private readonly int _maxResults;
private readonly string _contextPrompt;
private readonly bool _enableSensitiveTelemetryData;
private readonly Redactor _redactor;
private readonly ChatHistoryMemoryProviderOptions.SearchBehavior _searchTime;
private readonly string _toolName;
private readonly string _toolDescription;
Expand Down Expand Up @@ -118,7 +119,7 @@ public ChatHistoryMemoryProvider(
options ??= new ChatHistoryMemoryProviderOptions();
this._maxResults = options.MaxResults.HasValue ? Throw.IfLessThanOrEqual(options.MaxResults.Value, 0) : DefaultMaxResults;
this._contextPrompt = options.ContextPrompt ?? DefaultContextPrompt;
this._enableSensitiveTelemetryData = options.EnableSensitiveTelemetryData;
this._redactor = options.EnableSensitiveTelemetryData ? NullRedactor.Instance : (options.Redactor ?? new ReplacingRedactor("<redacted>"));
this._searchTime = options.SearchTime;
this._logger = loggerFactory?.CreateLogger<ChatHistoryMemoryProvider>();
this._toolName = options.FunctionToolName ?? DefaultFunctionToolName;
Expand Down Expand Up @@ -485,7 +486,7 @@ public void Dispose()
GC.SuppressFinalize(this);
}

private string? SanitizeLogData(string? data) => this._enableSensitiveTelemetryData ? data : "<redacted>";
private string SanitizeLogData(string? data) => this._redactor.Redact(data);

/// <summary>
/// Rebinds a filter expression's body to use the specified shared parameter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Compliance.Redaction;

namespace Microsoft.Agents.AI;

Expand Down Expand Up @@ -46,8 +47,22 @@ public sealed class ChatHistoryMemoryProviderOptions
/// Gets or sets a value indicating whether sensitive data such as user ids and user messages may appear in logs.
/// </summary>
/// <value>Defaults to <see langword="false"/>.</value>
/// <remarks>
/// When set to <see langword="true"/>, sensitive data is passed through to logs unchanged and any
/// configured <see cref="Redactor"/> is ignored. This property takes precedence over <see cref="Redactor"/>.
/// </remarks>
public bool EnableSensitiveTelemetryData { get; set; }

/// <summary>
/// Gets or sets a custom <see cref="Redactor"/> used to redact sensitive data in log output.
/// </summary>
/// <value>
/// When <see langword="null"/> (the default), sensitive data is replaced with a placeholder.
/// When set, this redactor is used to transform sensitive values before they are logged.
/// Ignored when <see cref="EnableSensitiveTelemetryData"/> is <see langword="true"/>.
/// </value>
public Redactor? Redactor { get; set; }

/// <summary>
/// Gets or sets the key used to store provider state in the <see cref="AgentSession.StateBag"/>.
/// </summary>
Expand Down
2 changes: 2 additions & 0 deletions dotnet/src/Microsoft.Agents.AI/Microsoft.Agents.AI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<PropertyGroup>
<InjectSharedThrow>true</InjectSharedThrow>
<InjectSharedDiagnosticIds>true</InjectSharedDiagnosticIds>
<InjectSharedRedaction>true</InjectSharedRedaction>
<InjectDiagnosticClassesOnLegacy>true</InjectDiagnosticClassesOnLegacy>
<InjectExperimentalAttributeOnLegacy>true</InjectExperimentalAttributeOnLegacy>
<InjectTrimAttributesOnLegacy>true</InjectTrimAttributesOnLegacy>
Expand All @@ -22,6 +23,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.AI" />
<PackageReference Include="Microsoft.Extensions.Compliance.Abstractions" />
<PackageReference Include="Microsoft.Extensions.VectorData.Abstractions" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
Expand Down
9 changes: 7 additions & 2 deletions dotnet/src/Microsoft.Agents.AI/TextSearchProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Compliance.Redaction;
using Microsoft.Extensions.Logging;
using Microsoft.Shared.Diagnostics;

Expand Down Expand Up @@ -62,6 +63,7 @@ public sealed class TextSearchProvider : MessageAIContextProvider
private readonly string _contextPrompt;
private readonly string _citationsPrompt;
private readonly Func<IList<TextSearchResult>, string>? _contextFormatter;
private readonly Redactor _redactor;

/// <summary>
/// Initializes a new instance of the <see cref="TextSearchProvider"/> class.
Expand Down Expand Up @@ -89,6 +91,7 @@ public TextSearchProvider(
this._contextPrompt = options?.ContextPrompt ?? DefaultContextPrompt;
this._citationsPrompt = options?.CitationsPrompt ?? DefaultCitationsPrompt;
this._contextFormatter = options?.ContextFormatter;
this._redactor = options?.EnableSensitiveTelemetryData == true ? NullRedactor.Instance : (options?.Redactor ?? new ReplacingRedactor("<redacted>"));

// Create the on-demand search tool (only used if behavior is OnDemandFunctionCalling)
this._tools =
Expand Down Expand Up @@ -180,7 +183,7 @@ protected override async ValueTask<IEnumerable<ChatMessage>> ProvideMessagesAsyn

if (this._logger?.IsEnabled(LogLevel.Trace) is true)
{
this._logger.LogTrace("TextSearchProvider: Search Results\nInput:{Input}\nOutput:{MessageText}", input, formatted);
this._logger.LogTrace("TextSearchProvider: Search Results\nInput:{Input}\nOutput:{MessageText}", this.SanitizeLogData(input), this.SanitizeLogData(formatted));
}

return [new ChatMessage(ChatRole.User, formatted)];
Expand Down Expand Up @@ -249,7 +252,7 @@ internal async Task<string> SearchAsync(string userQuestion, CancellationToken c

if (this._logger.IsEnabled(LogLevel.Trace))
{
this._logger.LogTrace("TextSearchProvider Input:{UserQuestion}\nOutput:{MessageText}", userQuestion, outputText);
this._logger.LogTrace("TextSearchProvider Input:{UserQuestion}\nOutput:{MessageText}", this.SanitizeLogData(userQuestion), this.SanitizeLogData(outputText));
}
}

Expand Down Expand Up @@ -325,6 +328,8 @@ public sealed class TextSearchResult
public object? RawRepresentation { get; set; }
}

private string SanitizeLogData(string? data) => this._redactor.Redact(data);

/// <summary>
/// Represents the per-session state of a <see cref="TextSearchProvider"/> stored in the <see cref="AgentSession.StateBag"/>.
/// </summary>
Expand Down
21 changes: 21 additions & 0 deletions dotnet/src/Microsoft.Agents.AI/TextSearchProviderOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Compliance.Redaction;

namespace Microsoft.Agents.AI;

Expand Down Expand Up @@ -117,6 +118,26 @@ public sealed class TextSearchProviderOptions
/// </value>
public List<ChatRole>? RecentMessageRolesIncluded { get; set; }

/// <summary>
/// Gets or sets a value indicating whether sensitive data such as user queries and search results may appear in logs.
/// </summary>
/// <value>Defaults to <see langword="false"/>.</value>
/// <remarks>
/// When set to <see langword="true"/>, sensitive data is passed through to logs unchanged and any
/// configured <see cref="Redactor"/> is ignored. This property takes precedence over <see cref="Redactor"/>.
/// </remarks>
public bool EnableSensitiveTelemetryData { get; set; }

/// <summary>
/// Gets or sets a custom <see cref="Redactor"/> used to redact sensitive data in log output.
/// </summary>
/// <value>
/// When <see langword="null"/> (the default), sensitive data is replaced with a placeholder.
/// When set, this redactor is used to transform sensitive values before they are logged.
/// Ignored when <see cref="EnableSensitiveTelemetryData"/> is <see langword="true"/>.
/// </value>
public Redactor? Redactor { get; set; }

/// <summary>
/// Behavior choices for the provider.
/// </summary>
Expand Down
30 changes: 30 additions & 0 deletions dotnet/src/Shared/Redaction/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Redaction

Log data redaction utilities built on `Microsoft.Extensions.Compliance.Redaction.Redactor`.

Provides `ReplacingRedactor`, an internal `Redactor` implementation that replaces
any input with a fixed replacement string (e.g. `"<redacted>"`).

To use this in your project, add the following to your `.csproj` file:

```xml
<PropertyGroup>
<InjectSharedRedaction>true</InjectSharedRedaction>
</PropertyGroup>
```

You will also need to add a package reference to `Microsoft.Extensions.Compliance.Abstractions`:

```xml
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Compliance.Abstractions" />
</ItemGroup>
```

And finally, this also depends on the shared Throw class, so when using redaction, InjectSharedThrow should also be enabled:

```xml
<PropertyGroup>
<InjectSharedThrow>true</InjectSharedThrow>
</PropertyGroup>
```
Loading
Loading