@ouro.bot/cli 0.1.0-alpha.553 → 0.1.0-alpha.555
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/RepairGuide.ouro/psyche/IDENTITY.md +1 -1
- package/RepairGuide.ouro/psyche/SOUL.md +1 -1
- package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +4 -4
- package/changelog.json +36 -43
- package/dist/heart/auth/auth-flow.js +3 -3
- package/dist/heart/core.js +0 -12
- package/dist/heart/daemon/agent-config-check.js +75 -168
- package/dist/heart/daemon/agentic-repair.js +2 -9
- package/dist/heart/daemon/cli-exec.js +67 -230
- package/dist/heart/daemon/cli-help.js +1 -1
- package/dist/heart/daemon/cli-render.js +2 -14
- package/dist/heart/daemon/daemon-entry.js +0 -30
- package/dist/heart/daemon/daemon-health.js +0 -7
- package/dist/heart/daemon/daemon-rollup.js +1 -2
- package/dist/heart/daemon/doctor.js +0 -18
- package/dist/heart/daemon/inner-status.js +0 -13
- package/dist/heart/hatch/hatch-flow.js +0 -20
- package/dist/heart/provider-binding-resolver.js +109 -97
- package/dist/heart/provider-credentials.js +2 -2
- package/dist/heart/provider-failover.js +1 -1
- package/dist/heart/provider-readiness-cache.js +40 -0
- package/dist/heart/provider-visibility.js +2 -2
- package/dist/heart/start-of-turn-packet.js +1 -1
- package/dist/nerves/coverage/file-completeness.js +0 -10
- package/dist/senses/pipeline.js +18 -37
- package/package.json +2 -2
- package/RepairGuide.ouro/skills/diagnose-bootstrap-drift.md +0 -54
- package/dist/heart/daemon/drift-detection.js +0 -146
- package/dist/heart/provider-state.js +0 -216
|
@@ -41,13 +41,15 @@ const path = __importStar(require("path"));
|
|
|
41
41
|
const identity_1 = require("../identity");
|
|
42
42
|
const runtime_1 = require("../../nerves/runtime");
|
|
43
43
|
const provider_models_1 = require("../provider-models");
|
|
44
|
-
const machine_identity_1 = require("../machine-identity");
|
|
45
|
-
const provider_state_1 = require("../provider-state");
|
|
46
44
|
const provider_credentials_1 = require("../provider-credentials");
|
|
45
|
+
const provider_readiness_cache_1 = require("../provider-readiness-cache");
|
|
47
46
|
const vault_unlock_1 = require("../../repertoire/vault-unlock");
|
|
48
47
|
const readiness_repair_1 = require("./readiness-repair");
|
|
49
48
|
const provider_ping_progress_1 = require("./provider-ping-progress");
|
|
50
|
-
const
|
|
49
|
+
const LANES = [
|
|
50
|
+
{ lane: "outward", facing: "humanFacing" },
|
|
51
|
+
{ lane: "inner", facing: "agentFacing" },
|
|
52
|
+
];
|
|
51
53
|
function isAgentProvider(value) {
|
|
52
54
|
return Object.prototype.hasOwnProperty.call(identity_1.PROVIDER_CREDENTIALS, value);
|
|
53
55
|
}
|
|
@@ -57,6 +59,9 @@ function agentRootFor(agentName, bundlesRoot) {
|
|
|
57
59
|
function configPathFor(agentName, bundlesRoot) {
|
|
58
60
|
return path.join(agentRootFor(agentName, bundlesRoot), "agent.json");
|
|
59
61
|
}
|
|
62
|
+
function laneForFacing(facing) {
|
|
63
|
+
return facing === "humanFacing" ? "outward" : "inner";
|
|
64
|
+
}
|
|
60
65
|
function resolveFacingProvider(parsed, facing, agentName, agentJsonPath) {
|
|
61
66
|
const raw = parsed[facing];
|
|
62
67
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
@@ -90,9 +95,13 @@ function resolveFacingProvider(parsed, facing, agentName, agentJsonPath) {
|
|
|
90
95
|
},
|
|
91
96
|
};
|
|
92
97
|
}
|
|
93
|
-
|
|
98
|
+
const rawModel = raw.model;
|
|
99
|
+
const model = typeof rawModel === "string" && rawModel.trim().length > 0
|
|
100
|
+
? rawModel.trim()
|
|
101
|
+
: (0, provider_models_1.getDefaultModelForProvider)(provider);
|
|
102
|
+
return { ok: true, selected: { facing, lane: laneForFacing(facing), provider, model } };
|
|
94
103
|
}
|
|
95
|
-
function
|
|
104
|
+
function readAgentConfigForProviderCheck(agentName, bundlesRoot) {
|
|
96
105
|
const agentJsonPath = configPathFor(agentName, bundlesRoot);
|
|
97
106
|
let raw;
|
|
98
107
|
try {
|
|
@@ -127,83 +136,25 @@ function readAgentConfigForProviderState(agentName, bundlesRoot) {
|
|
|
127
136
|
}
|
|
128
137
|
return { ok: true, disabled: false, agentJsonPath, parsed };
|
|
129
138
|
}
|
|
130
|
-
function
|
|
131
|
-
const
|
|
132
|
-
if (!providerResult.ok) {
|
|
133
|
-
return {
|
|
134
|
-
ok: false,
|
|
135
|
-
result: {
|
|
136
|
-
ok: false,
|
|
137
|
-
error: providerResult.result.error,
|
|
138
|
-
fix: `Run 'ouro use --agent ${agentName} --lane ${facing === "humanFacing" ? "outward" : "inner"} --provider <provider> --model <model>' to configure this machine's provider binding.`,
|
|
139
|
-
},
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
const raw = parsed[facing];
|
|
143
|
-
const model = typeof raw.model === "string" && raw.model.trim().length > 0
|
|
144
|
-
? raw.model.trim()
|
|
145
|
-
: (0, provider_models_1.getDefaultModelForProvider)(providerResult.selected.provider);
|
|
146
|
-
return { ok: true, provider: providerResult.selected.provider, model };
|
|
147
|
-
}
|
|
148
|
-
function bootstrapMissingProviderState(input) {
|
|
149
|
-
const outward = readFacingForBootstrap(input.parsed, "humanFacing", input.agentName, input.agentJsonPath);
|
|
150
|
-
if (!outward.ok)
|
|
151
|
-
return { ok: false, error: outward.result.error, fix: outward.result.fix };
|
|
152
|
-
const inner = readFacingForBootstrap(input.parsed, "agentFacing", input.agentName, input.agentJsonPath);
|
|
153
|
-
if (!inner.ok)
|
|
154
|
-
return { ok: false, error: inner.result.error, fix: inner.result.fix };
|
|
155
|
-
const now = new Date();
|
|
156
|
-
const homeDir = (0, provider_credentials_1.providerCredentialMachineHomeDir)(input.homeDir);
|
|
157
|
-
const machine = (0, machine_identity_1.loadOrCreateMachineIdentity)({ homeDir, now: () => now });
|
|
158
|
-
const state = (0, provider_state_1.bootstrapProviderStateFromAgentConfig)({
|
|
159
|
-
machineId: machine.machineId,
|
|
160
|
-
now,
|
|
161
|
-
agentConfig: {
|
|
162
|
-
humanFacing: { provider: outward.provider, model: outward.model },
|
|
163
|
-
agentFacing: { provider: inner.provider, model: inner.model },
|
|
164
|
-
},
|
|
165
|
-
});
|
|
166
|
-
const agentRoot = agentRootFor(input.agentName, input.bundlesRoot);
|
|
167
|
-
(0, provider_state_1.writeProviderState)(agentRoot, state);
|
|
168
|
-
(0, runtime_1.emitNervesEvent)({
|
|
169
|
-
component: "daemon",
|
|
170
|
-
event: "daemon.provider_state_bootstrapped",
|
|
171
|
-
message: "bootstrapped local provider state from agent config",
|
|
172
|
-
meta: { agent: input.agentName, agentRoot },
|
|
173
|
-
});
|
|
174
|
-
return { ok: true, agentRoot, state };
|
|
175
|
-
}
|
|
176
|
-
function readOrBootstrapProviderStateForCheck(agentName, bundlesRoot, deps = {}) {
|
|
177
|
-
const configResult = readAgentConfigForProviderState(agentName, bundlesRoot);
|
|
139
|
+
function readProviderSelectionForCheck(agentName, bundlesRoot) {
|
|
140
|
+
const configResult = readAgentConfigForProviderCheck(agentName, bundlesRoot);
|
|
178
141
|
if (!configResult.ok)
|
|
179
142
|
return { ok: false, result: configResult.result };
|
|
180
143
|
if (configResult.disabled)
|
|
181
144
|
return { ok: true, disabled: true };
|
|
182
|
-
const
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return {
|
|
189
|
-
ok: false,
|
|
190
|
-
result: {
|
|
191
|
-
ok: false,
|
|
192
|
-
error: `provider state for ${agentName} is invalid at ${stateResult.statePath}: ${stateResult.error}`,
|
|
193
|
-
fix: `Run 'ouro use --agent ${agentName} --lane outward --provider <provider> --model <model> --force' to rewrite this machine's provider binding.`,
|
|
194
|
-
},
|
|
195
|
-
};
|
|
145
|
+
const bindings = {};
|
|
146
|
+
for (const { lane, facing } of LANES) {
|
|
147
|
+
const selected = resolveFacingProvider(configResult.parsed, facing, agentName, configResult.agentJsonPath);
|
|
148
|
+
if (!selected.ok)
|
|
149
|
+
return { ok: false, result: selected.result };
|
|
150
|
+
bindings[lane] = selected.selected;
|
|
196
151
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
});
|
|
204
|
-
if (!bootstrap.ok)
|
|
205
|
-
return { ok: false, result: bootstrap };
|
|
206
|
-
return { ok: true, disabled: false, agentRoot: bootstrap.agentRoot, state: bootstrap.state };
|
|
152
|
+
return {
|
|
153
|
+
ok: true,
|
|
154
|
+
disabled: false,
|
|
155
|
+
agentRoot: agentRootFor(agentName, bundlesRoot),
|
|
156
|
+
bindings,
|
|
157
|
+
};
|
|
207
158
|
}
|
|
208
159
|
function providerCredentialConfig(record) {
|
|
209
160
|
return {
|
|
@@ -216,21 +167,6 @@ function pingAttemptCount(result) {
|
|
|
216
167
|
return result.attempts.length;
|
|
217
168
|
return undefined;
|
|
218
169
|
}
|
|
219
|
-
function writeLaneReadiness(input) {
|
|
220
|
-
const binding = input.state.lanes[input.lane];
|
|
221
|
-
const checkedAt = new Date().toISOString();
|
|
222
|
-
input.state.updatedAt = checkedAt;
|
|
223
|
-
input.state.readiness[input.lane] = {
|
|
224
|
-
status: input.status,
|
|
225
|
-
provider: binding.provider,
|
|
226
|
-
model: binding.model,
|
|
227
|
-
checkedAt,
|
|
228
|
-
credentialRevision: input.credentialRevision,
|
|
229
|
-
...(input.error ? { error: input.error } : {}),
|
|
230
|
-
...(input.attempts !== undefined ? { attempts: input.attempts } : {}),
|
|
231
|
-
};
|
|
232
|
-
(0, provider_state_1.writeProviderState)(input.agentRoot, input.state);
|
|
233
|
-
}
|
|
234
170
|
function missingCredentialResult(agentName, lane, provider, model, credentialPath) {
|
|
235
171
|
return {
|
|
236
172
|
ok: false,
|
|
@@ -325,14 +261,14 @@ function laneAudienceLabel(lane) {
|
|
|
325
261
|
function bindingLabel(binding) {
|
|
326
262
|
return `${binding.provider} / ${binding.model}`;
|
|
327
263
|
}
|
|
328
|
-
function selectedProviderPlan(agentName,
|
|
264
|
+
function selectedProviderPlan(agentName, bindings) {
|
|
329
265
|
return [
|
|
330
|
-
`${agentName}: checking the providers
|
|
331
|
-
...
|
|
266
|
+
`${agentName}: checking the providers in agent.json`,
|
|
267
|
+
...LANES.map(({ lane }) => `- ${laneAudienceLabel(lane)}: ${bindingLabel(bindings[lane])}`),
|
|
332
268
|
].join("\n");
|
|
333
269
|
}
|
|
334
|
-
function
|
|
335
|
-
return [...new Set(
|
|
270
|
+
function selectedProvidersForBindings(bindings) {
|
|
271
|
+
return [...new Set(LANES.map(({ lane }) => bindings[lane].provider))];
|
|
336
272
|
}
|
|
337
273
|
function mapVaultRefreshProgress(agentName, onProgress) {
|
|
338
274
|
return (message) => {
|
|
@@ -359,80 +295,52 @@ function providerPingSubject(agentName, lanes) {
|
|
|
359
295
|
* checkAgentConfigWithProviderHealth(), which reads the agent vault and pings.
|
|
360
296
|
*/
|
|
361
297
|
function checkAgentConfig(agentName, bundlesRoot) {
|
|
362
|
-
const
|
|
363
|
-
if (!
|
|
364
|
-
return
|
|
365
|
-
if (
|
|
298
|
+
const selectionResult = readProviderSelectionForCheck(agentName, bundlesRoot);
|
|
299
|
+
if (!selectionResult.ok)
|
|
300
|
+
return selectionResult.result;
|
|
301
|
+
if (selectionResult.disabled)
|
|
366
302
|
return { ok: true };
|
|
367
|
-
const outward = readFacingForBootstrap(configResult.parsed, "humanFacing", agentName, configResult.agentJsonPath);
|
|
368
|
-
if (!outward.ok)
|
|
369
|
-
return outward.result;
|
|
370
|
-
const inner = readFacingForBootstrap(configResult.parsed, "agentFacing", agentName, configResult.agentJsonPath);
|
|
371
|
-
if (!inner.ok)
|
|
372
|
-
return inner.result;
|
|
373
303
|
(0, runtime_1.emitNervesEvent)({
|
|
374
304
|
component: "daemon",
|
|
375
305
|
event: "daemon.agent_config_valid",
|
|
376
306
|
message: "agent config validation passed",
|
|
377
307
|
meta: {
|
|
378
308
|
agent: agentName,
|
|
379
|
-
providers:
|
|
309
|
+
providers: selectedProvidersForBindings(selectionResult.bindings),
|
|
380
310
|
liveProviderCheck: false,
|
|
381
311
|
},
|
|
382
312
|
});
|
|
383
313
|
return { ok: true };
|
|
384
314
|
}
|
|
385
315
|
async function checkAgentConfigWithProviderHealth(agentName, bundlesRoot, deps = {}) {
|
|
386
|
-
const
|
|
387
|
-
if (!
|
|
388
|
-
return
|
|
389
|
-
if (
|
|
316
|
+
const selectionResult = readProviderSelectionForCheck(agentName, bundlesRoot);
|
|
317
|
+
if (!selectionResult.ok)
|
|
318
|
+
return selectionResult.result;
|
|
319
|
+
if (selectionResult.disabled)
|
|
390
320
|
return { ok: true };
|
|
391
|
-
|
|
392
|
-
// drift findings ride along regardless of ping outcome — consumers
|
|
393
|
-
// (Layer 4 rollup, Layer 3 RepairGuide) want to see drift even when a
|
|
394
|
-
// live-check is failing for unrelated reasons. Drift detection is pure
|
|
395
|
-
// and never throws on a malformed agent.json: any read error here would
|
|
396
|
-
// indicate the bundle disappeared between state setup and now (a
|
|
397
|
-
// race), which we surface as `[]` rather than a hard failure.
|
|
398
|
-
let driftFindings = [];
|
|
399
|
-
try {
|
|
400
|
-
const inputs = (0, drift_detection_1.loadDriftInputsForAgent)(bundlesRoot, agentName);
|
|
401
|
-
driftFindings = (0, drift_detection_1.detectProviderBindingDrift)({
|
|
402
|
-
agentName,
|
|
403
|
-
agentJson: inputs.agentJson,
|
|
404
|
-
providerState: inputs.providerState,
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
catch {
|
|
408
|
-
/* v8 ignore next 1 -- defensive race-window guard: agent.json went away after state setup. Tested via Unit 5 integration when at all. @preserve */
|
|
409
|
-
driftFindings = [];
|
|
410
|
-
}
|
|
411
|
-
deps.onProgress?.(selectedProviderPlan(agentName, stateResult.state));
|
|
321
|
+
deps.onProgress?.(selectedProviderPlan(agentName, selectionResult.bindings));
|
|
412
322
|
const ping = deps.pingProvider ?? (await Promise.resolve().then(() => __importStar(require("../provider-ping")))).pingProvider;
|
|
413
|
-
const
|
|
414
|
-
const providers = selectedProvidersForState(stateResult.state);
|
|
323
|
+
const providers = selectedProvidersForBindings(selectionResult.bindings);
|
|
415
324
|
const poolResult = await (0, provider_credentials_1.refreshProviderCredentialPool)(agentName, {
|
|
416
325
|
...(deps.onProgress ? { onProgress: mapVaultRefreshProgress(agentName, deps.onProgress) } : {}),
|
|
417
326
|
providers,
|
|
418
327
|
preserveCachedOnFailure: true,
|
|
419
328
|
});
|
|
420
329
|
const pingGroups = new Map();
|
|
421
|
-
const
|
|
422
|
-
|
|
423
|
-
const binding = stateResult.state.lanes[lane];
|
|
330
|
+
for (const { lane } of LANES) {
|
|
331
|
+
const binding = selectionResult.bindings[lane];
|
|
424
332
|
if (!poolResult.ok) {
|
|
425
333
|
if (poolResult.reason === "missing") {
|
|
426
|
-
return
|
|
334
|
+
return missingCredentialResult(agentName, lane, binding.provider, binding.model, poolResult.poolPath);
|
|
427
335
|
}
|
|
428
|
-
return
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
336
|
+
return invalidPoolResult(agentName, lane, binding.provider, binding.model, {
|
|
337
|
+
...poolResult,
|
|
338
|
+
reason: poolResult.reason,
|
|
339
|
+
});
|
|
432
340
|
}
|
|
433
341
|
const record = credentialRecordForLane(poolResult.pool, binding.provider);
|
|
434
342
|
if (!record) {
|
|
435
|
-
return
|
|
343
|
+
return missingCredentialResult(agentName, lane, binding.provider, binding.model, poolResult.poolPath);
|
|
436
344
|
}
|
|
437
345
|
const key = `${binding.provider}\0${binding.model}\0${record.revision}`;
|
|
438
346
|
const group = pingGroups.get(key);
|
|
@@ -466,37 +374,37 @@ async function checkAgentConfigWithProviderHealth(agentName, bundlesRoot, deps =
|
|
|
466
374
|
let firstFailure = null;
|
|
467
375
|
for (const { group, result } of pingResults) {
|
|
468
376
|
if (!result.ok) {
|
|
469
|
-
if (shouldRecordReadiness) {
|
|
470
|
-
for (const lane of group.lanes) {
|
|
471
|
-
writeLaneReadiness({
|
|
472
|
-
agentRoot: stateResult.agentRoot,
|
|
473
|
-
state: stateResult.state,
|
|
474
|
-
lane,
|
|
475
|
-
status: "failed",
|
|
476
|
-
credentialRevision: group.record.revision,
|
|
477
|
-
error: result.message,
|
|
478
|
-
attempts: pingAttemptCount(result),
|
|
479
|
-
});
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
firstFailure ??= failedPingResult(agentName, group.lanes[0], group.provider, group.model, result);
|
|
483
|
-
continue;
|
|
484
|
-
}
|
|
485
|
-
if (shouldRecordReadiness) {
|
|
486
377
|
for (const lane of group.lanes) {
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
state: stateResult.state,
|
|
378
|
+
(0, provider_readiness_cache_1.recordProviderLaneReadiness)({
|
|
379
|
+
agentName,
|
|
490
380
|
lane,
|
|
491
|
-
|
|
381
|
+
provider: group.provider,
|
|
382
|
+
model: group.model,
|
|
492
383
|
credentialRevision: group.record.revision,
|
|
384
|
+
status: "failed",
|
|
385
|
+
checkedAt: new Date().toISOString(),
|
|
386
|
+
error: result.message,
|
|
493
387
|
attempts: pingAttemptCount(result),
|
|
494
388
|
});
|
|
495
389
|
}
|
|
390
|
+
firstFailure ??= failedPingResult(agentName, group.lanes[0], group.provider, group.model, result);
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
for (const lane of group.lanes) {
|
|
394
|
+
(0, provider_readiness_cache_1.recordProviderLaneReadiness)({
|
|
395
|
+
agentName,
|
|
396
|
+
lane,
|
|
397
|
+
provider: group.provider,
|
|
398
|
+
model: group.model,
|
|
399
|
+
credentialRevision: group.record.revision,
|
|
400
|
+
status: "ready",
|
|
401
|
+
checkedAt: new Date().toISOString(),
|
|
402
|
+
attempts: pingAttemptCount(result),
|
|
403
|
+
});
|
|
496
404
|
}
|
|
497
405
|
}
|
|
498
406
|
if (firstFailure)
|
|
499
|
-
return
|
|
407
|
+
return firstFailure;
|
|
500
408
|
(0, runtime_1.emitNervesEvent)({
|
|
501
409
|
component: "daemon",
|
|
502
410
|
event: "daemon.agent_config_valid",
|
|
@@ -505,8 +413,7 @@ async function checkAgentConfigWithProviderHealth(agentName, bundlesRoot, deps =
|
|
|
505
413
|
agent: agentName,
|
|
506
414
|
providers: [...new Set([...pingGroups.values()].map((group) => group.provider))],
|
|
507
415
|
liveProviderCheck: true,
|
|
508
|
-
driftCount: driftFindings.length,
|
|
509
416
|
},
|
|
510
417
|
});
|
|
511
|
-
return { ok: true
|
|
418
|
+
return { ok: true };
|
|
512
419
|
}
|
|
@@ -68,7 +68,7 @@ function buildSystemPrompt(degraded) {
|
|
|
68
68
|
"and the simplest fix the user can apply.",
|
|
69
69
|
].join("\n");
|
|
70
70
|
}
|
|
71
|
-
function buildUserMessage(degraded, logsTail,
|
|
71
|
+
function buildUserMessage(degraded, logsTail, syncFindings = []) {
|
|
72
72
|
const agentDetails = degraded
|
|
73
73
|
.map((d) => `Agent: ${d.agent}\n Error: ${d.errorReason}\n Fix hint: ${d.fixHint}`)
|
|
74
74
|
.join("\n\n");
|
|
@@ -80,13 +80,6 @@ function buildUserMessage(degraded, logsTail, driftFindings = [], syncFindings =
|
|
|
80
80
|
"Recent daemon logs:",
|
|
81
81
|
logsTail,
|
|
82
82
|
];
|
|
83
|
-
// Layer 3: thread Layer 4's structured drift findings into the prompt as
|
|
84
|
-
// a JSON block. The `diagnose-bootstrap-drift` skill (loaded into the
|
|
85
|
-
// system prompt by `buildSystemPromptWithRepairGuide`) instructs the LLM
|
|
86
|
-
// how to read this shape and what `ouro use` repair to propose.
|
|
87
|
-
if (driftFindings.length > 0) {
|
|
88
|
-
sections.push("", "driftFindings (DriftFinding[]):", "```json", JSON.stringify(driftFindings, null, 2), "```");
|
|
89
|
-
}
|
|
90
83
|
// Layer 3: thread Layer 2's structured sync-probe findings into the
|
|
91
84
|
// prompt as a JSON block. `diagnose-broken-remote` (auth/404/network/
|
|
92
85
|
// timeout-hard) and `diagnose-sync-blocked` (dirty/non-fast-forward/
|
|
@@ -158,7 +151,7 @@ async function tryAgenticDiagnosis(degraded, provider, deps) {
|
|
|
158
151
|
const repoRoot = deps.repoRootOverride ?? (0, identity_1.getRepoRoot)();
|
|
159
152
|
const repairGuide = loadRepairGuideContent(repoRoot);
|
|
160
153
|
const systemPrompt = buildSystemPromptWithRepairGuide(degraded, repairGuide);
|
|
161
|
-
const userMessage = buildUserMessage(degraded, logsTail, deps.
|
|
154
|
+
const userMessage = buildUserMessage(degraded, logsTail, deps.syncFindings);
|
|
162
155
|
const messages = [
|
|
163
156
|
{ role: "system", content: systemPrompt },
|
|
164
157
|
{ role: "user", content: userMessage },
|