Skip to content

Commit 0a50299

Browse files
committed
fixes
1 parent e70de85 commit 0a50299

File tree

5 files changed

+68
-21
lines changed

5 files changed

+68
-21
lines changed

src/api/Elastic.Documentation.Api.Core/AskAi/AskAiUsecase.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,24 @@ public class AskAiUsecase(
1616

1717
public async Task<Stream> AskAi(AskAiRequest askAiRequest, Cancel ctx)
1818
{
19-
// Start with a placeholder model name - will be updated by transformer
20-
using var activity = AskAiActivitySource.StartActivity("chat unknown", ActivityKind.Client);
19+
// Start activity for the chat request - model name will be set by transformer
20+
using var activity = AskAiActivitySource.StartActivity("chat", ActivityKind.Client);
2121

22-
// Set required GenAI semantic convention attributes
22+
// Generate a correlation ID for tracking if this is a new conversation
23+
// For first messages (no ThreadId), generate a temporary ID that will be updated when the provider responds
24+
var correlationId = askAiRequest.ThreadId ?? $"temp-{Guid.NewGuid()}";
25+
26+
// Set GenAI semantic convention attributes
2327
_ = (activity?.SetTag("gen_ai.operation.name", "chat"));
24-
_ = (activity?.SetTag("gen_ai.request.model", "unknown")); // Will be updated by transformer
25-
_ = (activity?.SetTag("gen_ai.conversation.id", askAiRequest.ThreadId ?? "pending")); // Will be updated when we receive ConversationStart
28+
_ = (activity?.SetTag("gen_ai.conversation.id", correlationId)); // Will be updated when we receive ConversationStart with actual ID
2629
_ = (activity?.SetTag("gen_ai.usage.input_tokens", askAiRequest.Message.Length)); // Approximate token count
2730

31+
// Custom attributes for tracking our abstraction layer
32+
// We use custom attributes because we don't know the actual GenAI provider (OpenAI, Anthropic, etc.)
33+
// or model (gpt-4, claude, etc.) - those are abstracted by AgentBuilder/LlmGateway
34+
_ = (activity?.SetTag("docs.ai.gateway", streamTransformer.AgentProvider)); // agent-builder or llm-gateway
35+
_ = (activity?.SetTag("docs.ai.agent_name", streamTransformer.AgentId)); // docs-agent or docs_assistant
36+
2837
// Add GenAI prompt event
2938
_ = (activity?.AddEvent(new ActivityEvent("gen_ai.content.prompt",
3039
timestamp: DateTimeOffset.UtcNow,

src/api/Elastic.Documentation.Api.Core/AskAi/IStreamTransformer.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ namespace Elastic.Documentation.Api.Core.AskAi;
99
/// </summary>
1010
public interface IStreamTransformer
1111
{
12+
/// <summary>
13+
/// Get the agent/model identifier for this transformer
14+
/// </summary>
15+
string AgentId { get; }
16+
17+
/// <summary>
18+
/// Get the agent provider/platform for this transformer
19+
/// </summary>
20+
string AgentProvider { get; }
21+
1222
/// <summary>
1323
/// Transforms a raw SSE stream into a stream of AskAiEvent objects
1424
/// </summary>

src/api/Elastic.Documentation.Api.Infrastructure/Adapters/AskAi/StreamTransformerBase.cs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,24 @@ public abstract class StreamTransformerBase(ILogger logger) : IStreamTransformer
4040
/// </summary>
4141
protected abstract string GetAgentProvider();
4242

43+
/// <summary>
44+
/// Public property to expose agent ID (implements IStreamTransformer)
45+
/// </summary>
46+
public string AgentId => GetAgentId();
47+
48+
/// <summary>
49+
/// Public property to expose agent provider (implements IStreamTransformer)
50+
/// </summary>
51+
public string AgentProvider => GetAgentProvider();
52+
4353
public Task<Stream> TransformAsync(Stream rawStream, CancellationToken cancellationToken = default)
4454
{
4555
using var activity = StreamTransformerActivitySource.StartActivity($"chat {GetAgentId()}", ActivityKind.Client);
4656
_ = (activity?.SetTag("gen_ai.operation.name", "chat"));
47-
_ = (activity?.SetTag("gen_ai.request.model", GetAgentId()));
48-
_ = (activity?.SetTag("gen_ai.agent.name", GetAgentId()));
49-
_ = (activity?.SetTag("gen_ai.provider.name", GetAgentProvider()));
57+
58+
// Custom attributes for tracking our abstraction layer
59+
_ = (activity?.SetTag("docs.ai.gateway", GetAgentProvider()));
60+
_ = (activity?.SetTag("docs.ai.agent_name", GetAgentId()));
5061

5162
// Configure pipe for low-latency streaming
5263
var pipeOptions = new PipeOptions(
@@ -160,8 +171,10 @@ private async Task ProcessPipeAsync(PipeReader reader, PipeWriter writer, Activi
160171
protected virtual async Task ProcessStreamAsync(PipeReader reader, PipeWriter writer, Activity? parentActivity, CancellationToken cancellationToken)
161172
{
162173
using var activity = StreamTransformerActivitySource.StartActivity("gen_ai.agent.stream");
163-
_ = (activity?.SetTag("gen_ai.agent.name", GetAgentId()));
164-
_ = (activity?.SetTag("gen_ai.provider.name", GetAgentProvider()));
174+
175+
// Custom attributes for tracking our abstraction layer
176+
_ = (activity?.SetTag("docs.ai.gateway", GetAgentProvider()));
177+
_ = (activity?.SetTag("docs.ai.agent_name", GetAgentId()));
165178

166179
var eventCount = 0;
167180
var jsonParseErrors = 0;
@@ -201,13 +214,10 @@ protected virtual async Task ProcessStreamAsync(PipeReader reader, PipeWriter wr
201214

202215
if (transformedEvent != null)
203216
{
204-
// Update parent activity with conversation ID and model info when we receive ConversationStart events
217+
// Update parent activity with conversation ID when we receive ConversationStart events
205218
if (transformedEvent is AskAiEvent.ConversationStart conversationStart)
206219
{
207220
_ = (parentActivity?.SetTag("gen_ai.conversation.id", conversationStart.ConversationId));
208-
_ = (parentActivity?.SetTag("gen_ai.request.model", GetAgentId()));
209-
_ = (parentActivity?.SetTag("gen_ai.agent.name", GetAgentId()));
210-
_ = (parentActivity?.SetTag("gen_ai.provider.name", GetAgentProvider()));
211221
_ = (activity?.SetTag("gen_ai.conversation.id", conversationStart.ConversationId));
212222
}
213223

@@ -238,8 +248,10 @@ protected async Task WriteEventAsync(AskAiEvent? transformedEvent, PipeWriter wr
238248
return;
239249

240250
using var activity = StreamTransformerActivitySource.StartActivity("gen_ai.agent.token");
241-
_ = (activity?.SetTag("gen_ai.agent.name", GetAgentId()));
242-
_ = (activity?.SetTag("gen_ai.provider.name", GetAgentProvider()));
251+
252+
// Custom attributes for tracking our abstraction layer
253+
_ = (activity?.SetTag("docs.ai.gateway", GetAgentProvider()));
254+
_ = (activity?.SetTag("docs.ai.agent_name", GetAgentId()));
243255
_ = (activity?.SetTag("gen_ai.response.token_type", transformedEvent.GetType().Name));
244256

245257
try

src/api/Elastic.Documentation.Api.Infrastructure/Adapters/AskAi/StreamTransformerFactory.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,32 @@ public class StreamTransformerFactory(
1616
AskAiProviderResolver providerResolver,
1717
ILogger<StreamTransformerFactory> logger) : IStreamTransformer
1818
{
19-
public async Task<Stream> TransformAsync(Stream rawStream, CancellationToken cancellationToken = default)
19+
private IStreamTransformer? _resolvedTransformer;
20+
21+
private IStreamTransformer GetTransformer()
2022
{
23+
if (_resolvedTransformer != null)
24+
return _resolvedTransformer;
25+
2126
var provider = providerResolver.ResolveProvider();
2227

23-
IStreamTransformer transformer = provider switch
28+
_resolvedTransformer = provider switch
2429
{
2530
"LlmGateway" => serviceProvider.GetRequiredService<LlmGatewayStreamTransformer>(),
2631
"AgentBuilder" => serviceProvider.GetRequiredService<AgentBuilderStreamTransformer>(),
2732
_ => throw new InvalidOperationException($"Unknown AI provider: {provider}. Valid values are 'AgentBuilder' or 'LlmGateway'")
2833
};
2934

30-
logger.LogDebug("Using stream transformer for provider: {Provider}", provider);
35+
logger.LogDebug("Resolved stream transformer for provider: {Provider}", provider);
36+
return _resolvedTransformer;
37+
}
38+
39+
public string AgentId => GetTransformer().AgentId;
40+
public string AgentProvider => GetTransformer().AgentProvider;
41+
42+
public async Task<Stream> TransformAsync(Stream rawStream, CancellationToken cancellationToken = default)
43+
{
44+
var transformer = GetTransformer();
3145
return await transformer.TransformAsync(rawStream, cancellationToken);
3246
}
3347
}

src/api/Elastic.Documentation.Api.Lambda/Program.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Elastic.Documentation.Api.Core.Search;
1010
using Elastic.Documentation.Api.Infrastructure;
1111
using Elastic.Documentation.ServiceDefaults;
12+
using Microsoft.Extensions.Logging;
1213
using OpenTelemetry;
1314
using OpenTelemetry.Metrics;
1415
using OpenTelemetry.Trace;
@@ -22,9 +23,10 @@
2223
process.Refresh();
2324
Console.WriteLine($"WebApplication builder created. Memory: {process.WorkingSet64 / 1024 / 1024} MB");
2425

25-
_ = builder.AddDocumentationServiceDefaults(ref args);
26+
// Add logging configuration for Lambda
27+
_ = builder.Services.AddElasticDocumentationLogging(LogLevel.Information);
2628
process.Refresh();
27-
Console.WriteLine($"Documentation service defaults added. Memory: {process.WorkingSet64 / 1024 / 1024} MB");
29+
Console.WriteLine($"Logging configured. Memory: {process.WorkingSet64 / 1024 / 1024} MB");
2830

2931
_ = builder.AddElasticOpenTelemetry(edotBuilder =>
3032
{

0 commit comments

Comments
 (0)