summaryrefslogtreecommitdiff
path: root/src/Agent.App/Logging/JsonLinesRuntimeObserver.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Agent.App/Logging/JsonLinesRuntimeObserver.cs')
-rw-r--r--src/Agent.App/Logging/JsonLinesRuntimeObserver.cs46
1 files changed, 32 insertions, 14 deletions
diff --git a/src/Agent.App/Logging/JsonLinesRuntimeObserver.cs b/src/Agent.App/Logging/JsonLinesRuntimeObserver.cs
index 20ef88d..78ad47b 100644
--- a/src/Agent.App/Logging/JsonLinesRuntimeObserver.cs
+++ b/src/Agent.App/Logging/JsonLinesRuntimeObserver.cs
@@ -5,33 +5,51 @@ using Agent.Core.Tools;
namespace Agent.App.Logging;
-public sealed class JsonLinesRuntimeObserver(string logDirectory) : IAgentRuntimeObserver
+public sealed class JsonLinesRuntimeObserver : IAgentRuntimeObserver, IDisposable
{
- private readonly object _sync = new();
- private readonly string _path = Path.Combine(logDirectory, "llm.jsonl");
+ private readonly RollingFileWriter _writer;
- public void LlmRequest(Guid taskId, int iteration, IReadOnlyList<OllamaMessage> messages) => Write(new
+ public JsonLinesRuntimeObserver(string logDirectory, long maxBytes = 10 * 1024 * 1024, int retainedFiles = 5) =>
+ _writer = new RollingFileWriter(Path.Combine(logDirectory, "llm.jsonl"), maxBytes, retainedFiles);
+
+ public void LlmRequest(AgentLlmCallContext context, IReadOnlyList<OllamaMessage> messages) => Write(new
{
- timestamp = DateTimeOffset.UtcNow, task_id = taskId, event_name = "llm.request", iteration,
- messages = messages.Select(static message => new { message.Role, message.Content, image_count = message.Images?.Count ?? 0, message.ToolName })
+ timestamp = DateTimeOffset.UtcNow, event_name = "llm.request", call_id = context.CallId,
+ session_id = context.SessionId, task_id = context.TaskId, planner_task_id = context.PlannerTaskId,
+ phase = context.Phase, iteration = context.Iteration, replan = context.Replan, model = context.Model,
+ messages = messages.Select(static message => new { role = message.Role, content = message.Content, image_count = message.Images?.Count ?? 0, tool_name = message.ToolName })
});
- public void LlmResponse(Guid taskId, int iteration, OllamaResult result) => Write(new
+ public void LlmResponse(AgentLlmCallContext context, OllamaResult result) => Write(new
{
- timestamp = DateTimeOffset.UtcNow, task_id = taskId, event_name = "llm.response", iteration,
- result.Content, input_tokens = result.InputTokens, output_tokens = result.OutputTokens,
+ timestamp = DateTimeOffset.UtcNow, event_name = "llm.response", call_id = context.CallId,
+ session_id = context.SessionId, task_id = context.TaskId, planner_task_id = context.PlannerTaskId,
+ phase = context.Phase, iteration = context.Iteration, replan = context.Replan, model = context.Model,
+ content = result.Content, input_tokens = result.InputTokens, output_tokens = result.OutputTokens,
tool_calls = result.ToolCalls?.Select(static call => call.Function.Name).ToArray() ?? []
});
- public void ToolResult(Guid taskId, string toolName, ToolExecutionResult result) => Write(new
+ public void LlmFailure(AgentLlmCallContext context, string errorCode, string message) => Write(new
{
- timestamp = DateTimeOffset.UtcNow, task_id = taskId, event_name = "llm.tool_result", tool_name = toolName,
- result.Success, result.ExternalEffect, result.RetryAllowed, result.Output, result.FailureFingerprint
+ timestamp = DateTimeOffset.UtcNow, event_name = "llm.failure", call_id = context.CallId,
+ session_id = context.SessionId, task_id = context.TaskId, planner_task_id = context.PlannerTaskId,
+ phase = context.Phase, iteration = context.Iteration, replan = context.Replan, model = context.Model,
+ error_code = errorCode, message
+ });
+
+ public void ToolResult(AgentLlmCallContext context, string toolName, ToolExecutionResult result) => Write(new
+ {
+ timestamp = DateTimeOffset.UtcNow, event_name = "llm.tool_result", call_id = context.CallId,
+ session_id = context.SessionId, task_id = context.TaskId, planner_task_id = context.PlannerTaskId,
+ phase = context.Phase, iteration = context.Iteration, replan = context.Replan, model = context.Model, tool_name = toolName,
+ success = result.Success, external_effect = result.ExternalEffect, retry_allowed = result.RetryAllowed,
+ output = result.Output, failure_fingerprint = result.FailureFingerprint
});
private void Write(object value)
{
- string line = JsonSerializer.Serialize(value);
- lock (_sync) File.AppendAllText(_path, line + Environment.NewLine);
+ _writer.WriteLine(JsonSerializer.Serialize(value));
}
+
+ public void Dispose() => _writer.Dispose();
}