Skip to content
Merged
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
4 changes: 2 additions & 2 deletions dotnet/src/Microsoft.Agents.AI.Purview/PurviewWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public async Task<ChatResponse> ProcessChatContentAsync(IEnumerable<ChatMessage>

try
{
(bool shouldBlockResponse, _) = await this._scopedProcessor.ProcessMessagesAsync(response.Messages, options?.ConversationId, Activity.UploadText, this._purviewSettings, resolvedUserId, cancellationToken).ConfigureAwait(false);
(bool shouldBlockResponse, _) = await this._scopedProcessor.ProcessMessagesAsync(response.Messages, options?.ConversationId, Activity.DownloadText, this._purviewSettings, resolvedUserId, cancellationToken).ConfigureAwait(false);
if (shouldBlockResponse)
{
if (this._logger.IsEnabled(LogLevel.Information))
Expand Down Expand Up @@ -186,7 +186,7 @@ public async Task<AgentResponse> ProcessAgentContentAsync(IEnumerable<ChatMessag
sessionIdResponse = sessionId;
}
}
(bool shouldBlockResponse, _) = await this._scopedProcessor.ProcessMessagesAsync(response.Messages, sessionIdResponse, Activity.UploadText, this._purviewSettings, resolvedUserId, cancellationToken).ConfigureAwait(false);
(bool shouldBlockResponse, _) = await this._scopedProcessor.ProcessMessagesAsync(response.Messages, sessionIdResponse, Activity.DownloadText, this._purviewSettings, resolvedUserId, cancellationToken).ConfigureAwait(false);

if (shouldBlockResponse)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public async Task ProcessChatContentAsync_WithBlockedPrompt_ReturnsBlockedMessag
this._mockProcessor.Setup(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
It.IsAny<string>(),
It.IsAny<Activity>(),
Activity.UploadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()))
Expand Down Expand Up @@ -88,15 +88,24 @@ public async Task ProcessChatContentAsync_WithAllowedPromptAndBlockedResponse_Re
It.IsAny<CancellationToken>()))
.ReturnsAsync(innerResponse);

this._mockProcessor.SetupSequence(x => x.ProcessMessagesAsync(
// Prompt check uses UploadText, response check uses DownloadText
this._mockProcessor.Setup(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
It.IsAny<string>(),
It.IsAny<Activity>(),
Activity.UploadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync((false, "user-123")); // Prompt allowed

this._mockProcessor.Setup(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
It.IsAny<string>(),
Activity.DownloadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync((false, "user-123")) // Prompt allowed
.ReturnsAsync((true, "user-123")); // Response blocked
.ReturnsAsync((true, "user-123")); // Response blocked

// Act
var result = await this._wrapper.ProcessChatContentAsync(messages, null, mockChatClient.Object, CancellationToken.None);
Expand Down Expand Up @@ -237,14 +246,21 @@ public async Task ProcessChatContentAsync_UsesConversationIdFromOptions_Async()
// Act
await this._wrapper.ProcessChatContentAsync(messages, options, mockChatClient.Object, CancellationToken.None);

// Assert
// Assert - verify prompt uses UploadText and response uses DownloadText
this._mockProcessor.Verify(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
"conversation-123",
It.IsAny<Activity>(),
Activity.UploadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()), Times.Once);
this._mockProcessor.Verify(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
"conversation-123",
Activity.DownloadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()), Times.Exactly(2));
It.IsAny<CancellationToken>()), Times.Once);
}

#endregion
Expand All @@ -264,7 +280,7 @@ public async Task ProcessAgentContentAsync_WithBlockedPrompt_ReturnsBlockedMessa
this._mockProcessor.Setup(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
It.IsAny<string>(),
It.IsAny<Activity>(),
Activity.UploadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()))
Expand Down Expand Up @@ -306,15 +322,24 @@ public async Task ProcessAgentContentAsync_WithAllowedPromptAndBlockedResponse_R
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(innerResponse);

this._mockProcessor.SetupSequence(x => x.ProcessMessagesAsync(
// Prompt check uses UploadText, response check uses DownloadText
this._mockProcessor.Setup(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
It.IsAny<string>(),
It.IsAny<Activity>(),
Activity.UploadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync((false, "user-123")) // Prompt allowed
.ReturnsAsync((true, "user-123")); // Response blocked
.ReturnsAsync((false, "user-123")); // Prompt allowed

this._mockProcessor.Setup(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
It.IsAny<string>(),
Activity.DownloadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()))
.ReturnsAsync((true, "user-123")); // Response blocked

// Act
var result = await this._wrapper.ProcessAgentContentAsync(messages, null, null, mockAgent.Object, CancellationToken.None);
Expand Down Expand Up @@ -472,10 +497,17 @@ public async Task ProcessAgentContentAsync_ExtractsThreadIdFromMessageAdditional
this._mockProcessor.Verify(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
"conversation-from-props",
It.IsAny<Activity>(),
Activity.UploadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()), Times.Once);
this._mockProcessor.Verify(x => x.ProcessMessagesAsync(
It.IsAny<IEnumerable<ChatMessage>>(),
"conversation-from-props",
Activity.DownloadText,
It.IsAny<PurviewSettings>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()), Times.Exactly(2));
It.IsAny<CancellationToken>()), Times.Once);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ async def process(
if context.result and not context.stream:
should_block_response, _ = await self._processor.process_messages(
context.result.messages, # type: ignore[union-attr]
Activity.UPLOAD_TEXT,
Activity.DOWNLOAD_TEXT,
session_id=session_id,
user_id=resolved_user_id,
)
Expand Down Expand Up @@ -210,7 +210,7 @@ async def process(
messages = getattr(result_obj, "messages", None)
if messages:
should_block_response, _ = await self._processor.process_messages(
messages, Activity.UPLOAD_TEXT, session_id=session_id_response, user_id=resolved_user_id
messages, Activity.DOWNLOAD_TEXT, session_id=session_id_response, user_id=resolved_user_id
)
if should_block_response:
from agent_framework import ChatResponse, Message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ async def _map_messages(
name=f"Agent Framework Message {message_id}",
is_truncated=False,
correlation_id=correlation_id,
sequence_number=time.time_ns(),
# This would be c# ticks equivalent and needs to fit inside c# long
sequence_number=time.time_ns() // 100 + 621355968000000000,
)
activity_meta = ActivityMetadata(activity=activity)

Expand Down
6 changes: 4 additions & 2 deletions python/packages/purview/tests/purview/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,10 @@ async def mock_next() -> None:
await middleware.process(context, mock_next)

assert mock_process.call_count == 2
for call in mock_process.call_args_list:
assert call[0][1] == Activity.UPLOAD_TEXT
# First call (pre-check) should be UPLOAD_TEXT for user prompt
assert mock_process.call_args_list[0][0][1] == Activity.UPLOAD_TEXT
# Second call (post-check) should be DOWNLOAD_TEXT for agent response
assert mock_process.call_args_list[1][0][1] == Activity.DOWNLOAD_TEXT

async def test_middleware_streaming_skips_post_check(
self, middleware: PurviewPolicyMiddleware, mock_agent: MagicMock
Expand Down
Loading