|
9 | 9 | using Microsoft.Extensions.AI; |
10 | 10 | using Microsoft.Extensions.Logging; |
11 | 11 | using Polly; |
| 12 | +using Serilog; |
| 13 | +using Serilog.Formatting.Compact; |
12 | 14 |
|
13 | | -// ── Load .env before anything else ─────────────────────────────────────────── |
| 15 | +// ── Load .env before anything else ───────────────────────────────────────────── |
14 | 16 | DotEnv.Load(options: new DotEnvOptions(probeForEnv: true, probeLevelsToSearch: 4)); |
15 | 17 |
|
16 | | -// ── Simple args parsing ─────────────────────────────────────────────────────── |
| 18 | +// ── Simple args parsing ────────────────────────────────────────────────── |
17 | 19 | int? issueNumber = null; |
18 | 20 | string? resumeId = null; |
19 | 21 | bool watchMode = false; |
|
37 | 39 | var builder = Host.CreateApplicationBuilder(args); |
38 | 40 | builder.Configuration.AddEnvironmentVariables(); |
39 | 41 |
|
40 | | -// ── Logging ─────────────────────────────────────────────────────────────────── |
41 | | -builder.Logging.AddSimpleConsole(o => o.IncludeScopes = false); |
42 | | -builder.Services.AddLogging(lb => lb.AddFilter("Microsoft", LogLevel.Warning)); |
| 42 | +// ── Logging ────────────────────────────────────────────────────────────── |
| 43 | +builder.Host.UseSerilog((context, loggerConfig) => |
| 44 | + loggerConfig |
| 45 | + .MinimumLevel.Information() |
| 46 | + .MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning) |
| 47 | + .MinimumLevel.Override("System", Serilog.Events.LogEventLevel.Warning) |
| 48 | + .Enrich.FromLogContext() |
| 49 | + .WriteTo.Console(new CompactJsonFormatter())); |
43 | 50 |
|
44 | | -// ── Auth ────────────────────────────────────────────────────────────────────── |
| 51 | +// ── Auth ────────────────────────────────────────────────────────────────── |
45 | 52 | builder.Services.AddSingleton<GitHubPatProvider>(); |
46 | 53 |
|
47 | | -// ── MCP Client ─────────────────────────────────────────────────────────────── |
| 54 | +// ── MCP Client ────────────────────────────────────────────────────────────────── |
48 | 55 | var binaryPath = builder.Configuration["GSD_MCP_BINARY"] ?? FindMcpBinary(); |
49 | 56 |
|
50 | 57 | builder.Services.AddSingleton<IMcpClient>(sp => |
|
55 | 62 | }); |
56 | 63 | builder.Services.AddSingleton<McpToolDispatcher>(); |
57 | 64 |
|
58 | | -// ── Polly resilience pipeline ───────────────────────────────────────────────── |
| 65 | +// ── Polly resilience pipeline ──────────────────────────────────────────────────────────── |
59 | 66 | builder.Services.AddResiliencePipeline("mcp-tools", pipelineBuilder => pipelineBuilder |
60 | 67 | .AddRetry(new Polly.Retry.RetryStrategyOptions |
61 | 68 | { |
|
68 | 75 | : ValueTask.FromResult(false) |
69 | 76 | })); |
70 | 77 |
|
71 | | -// ── LLM Client (Anthropic Claude via Anthropic.SDK) ────────────────────────── |
| 78 | +// ── LLM Client (Anthropic Claude via Anthropic.SDK) ──────────────────────────── |
72 | 79 | builder.Services.AddSingleton<IChatClient>(sp => |
73 | 80 | { |
74 | 81 | var key = builder.Configuration["ANTHROPIC_API_KEY"] |
|
77 | 84 | return (IChatClient)anthropic.Messages; |
78 | 85 | }); |
79 | 86 |
|
80 | | -// ── Checkpointing ───────────────────────────────────────────────────────────── |
| 87 | +// ── Checkpointing ────────────────────────────────────────────────────────────────── |
81 | 88 | builder.Services.AddSingleton<ICheckpointStore>(sp => |
82 | 89 | { |
83 | 90 | var logger = sp.GetRequiredService<ILogger<FileCheckpointStore>>(); |
84 | 91 | var repoRoot = Directory.GetCurrentDirectory(); |
85 | 92 | return new FileCheckpointStore(repoRoot, logger); |
86 | 93 | }); |
87 | 94 |
|
88 | | -// ── Workflow states ─────────────────────────────────────────────────────────── |
| 95 | +// ── Workflow states ────────────────────────────────────────────────────────────────── |
89 | 96 | builder.Services.AddSingleton<IWorkflowState, IdleState>(); |
90 | 97 | builder.Services.AddSingleton<IWorkflowState, AnalyzingState>(); |
91 | 98 | builder.Services.AddSingleton<IWorkflowState, BranchingState>(); |
|
100 | 107 |
|
101 | 108 | var host = builder.Build(); |
102 | 109 |
|
103 | | -// ── Run ─────────────────────────────────────────────────────────────────────── |
| 110 | +// ── Run ─────────────────────────────────────────────────────────────────────────── |
104 | 111 | var sm = host.Services.GetRequiredService<GsdStateMachine>(); |
105 | 112 | var mcp = host.Services.GetRequiredService<IMcpClient>(); |
106 | 113 | var config = host.Services.GetRequiredService<IConfiguration>(); |
|
137 | 144 |
|
138 | 145 | await (mcp as IAsyncDisposable)!.DisposeAsync(); |
139 | 146 |
|
140 | | -// ── Watch mode ──────────────────────────────────────────────────────────────── |
| 147 | +// ── Watch mode ────────────────────────────────────────────────────────────────── |
141 | 148 | static async Task RunWatchModeAsync( |
142 | 149 | GsdStateMachine sm, McpToolDispatcher mcpDispatcher, |
143 | 150 | string owner, string repo, |
@@ -208,7 +215,7 @@ static void PrintResult(GsdWorkflowContext result) |
208 | 215 | } |
209 | 216 | } |
210 | 217 |
|
211 | | -// ── Binary discovery ────────────────────────────────────────────────────────── |
| 218 | +// ── Binary discovery ────────────────────────────────────────────────────────────── |
212 | 219 | static string FindMcpBinary() |
213 | 220 | { |
214 | 221 | var dir = new DirectoryInfo(Directory.GetCurrentDirectory()); |
|
0 commit comments