A question about how a run went should arrive with the run attached, not with directions to the log panel
This commit is contained in:
@@ -67,6 +67,8 @@
|
||||
// 3 history JSON array of {role, content}, already trimmed by the endpoint
|
||||
// 4 kind optional retrieval filter (header|readme|manual|template|doc)
|
||||
// 5 think "1" to allow the model's reasoning, "0" to suppress it
|
||||
// 6 profile varaverk|chat|code|troubleshoot — decides the contract and the inputs
|
||||
// 7 scope what the operator has open, e.g. Orchestrators/daily_sync_maintenance
|
||||
//
|
||||
// JOB FILE STATES
|
||||
// {"status":"retrieving"}
|
||||
@@ -154,7 +156,17 @@ if ($profile === 'varaverk' || $profile === 'troubleshoot') {
|
||||
// The troubleshooting profile is diagnostic by definition — the operator opened a log and asked
|
||||
// about it, which is a clearer signal than any phrasing test. For the assistant it stays a
|
||||
// keyword gate, since most of its questions are not about failures.
|
||||
$diagnostic = $profile === 'troubleshoot' || ($profile === 'varaverk' && (bool)preg_match(
|
||||
// "How did the daily orch go last night" is diagnostic too, and matched none of the words below
|
||||
// — nothing had failed, so nothing in the question said failure. It retrieved the documentation
|
||||
// on where logs live and answered with directions to a page the operator already had open. The
|
||||
// question is about a run that happened, so the run itself has to be in context.
|
||||
$runOutcome = (bool)preg_match(
|
||||
'/\b(how did|how.d|did .{0,24}\b(run|go|finish|complete)|last run|latest run|last night|'
|
||||
. 'go last|went last|how long did|run record|rundown|summar(y|ise|ize)|recap)\b/i',
|
||||
$question
|
||||
);
|
||||
|
||||
$diagnostic = $profile === 'troubleshoot' || $runOutcome || ($profile === 'varaverk' && (bool)preg_match(
|
||||
'/\b(why|fail(ed|ing|ure)?|error|broken?|not work|isn.t work|wrong|stuck|hang|'
|
||||
. 'never runs?|didn.t|won.t|debug|troubleshoot|diagnos)/i',
|
||||
$question
|
||||
@@ -185,15 +197,39 @@ if ($diagnostic) {
|
||||
// The troubleshooting profile gets the actual tail of the one log the operator is looking at,
|
||||
// warnings and ordinary lines alike. The fleet-wide WARN/ERROR sweep above cannot answer "why
|
||||
// did this one stop" — the last line a script printed before dying is usually not labelled.
|
||||
// The target is whatever the operator has open, and failing that whatever they named in the
|
||||
// question. The second half is what makes a run-outcome question work from any view: asking how
|
||||
// the daily orchestrator went while looking at the suggestions list is the ordinary case, not an
|
||||
// edge one, and requiring them to open the log first is asking them to do the lookup themselves.
|
||||
$runTarget = ($profile === 'troubleshoot' && $scope !== '') ? $scope : '';
|
||||
if ($runTarget === '' && $runOutcome) $runTarget = vv_ai_resolve_run_target($question);
|
||||
|
||||
$scopedLog = null;
|
||||
if ($profile === 'troubleshoot' && $scope !== '') {
|
||||
$scopedLog = vv_ai_scoped_log($scope, 120);
|
||||
if ($runTarget !== '' && vv_ai_scope_ok($runTarget)) {
|
||||
// The record first: it states the outcome, where the tail only implies it. A log that ends
|
||||
// on a tidy summary block looks identical whether the script exited 0 or was killed on the
|
||||
// next line, and the difference is the whole answer.
|
||||
$rec = vv_ai_run_record($runTarget);
|
||||
if ($rec['ok']) {
|
||||
$diagBlock .= 'RUN RECORD for ' . $runTarget . " (authoritative — how the last run ended)\n"
|
||||
. '- status: ' . $rec['status']
|
||||
. ($rec['exit'] !== null ? ' (exit ' . $rec['exit'] . ')' : '') . "\n"
|
||||
. '- started: ' . date('Y-m-d H:i:s', $rec['start']) . "\n"
|
||||
. '- ended: ' . ($rec['end'] ? date('Y-m-d H:i:s', $rec['end']) : 'no end recorded — '
|
||||
. 'it did not finish, or is still running') . "\n"
|
||||
. ($rec['duration'] !== null
|
||||
? '- duration: ' . floor($rec['duration'] / 60) . 'm' . ($rec['duration'] % 60) . "s\n"
|
||||
: '')
|
||||
. "\n";
|
||||
}
|
||||
|
||||
$scopedLog = vv_ai_scoped_log($runTarget, 120);
|
||||
if ($scopedLog['ok']) {
|
||||
$diagBlock .= 'LOG: ' . $scopedLog['path']
|
||||
. ' (' . $scopedLog['total'] . " lines total, newest last)\n"
|
||||
. implode("\n", $scopedLog['tail']) . "\n\n";
|
||||
} else {
|
||||
$diagBlock .= "LOG: none found for " . $scope . " — it may never have run.\n\n";
|
||||
$diagBlock .= "LOG: none found for " . $runTarget . " — it may never have run.\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,6 +376,29 @@ if ($profile === 'chat') {
|
||||
. "gap from general knowledge. Prefer the user's own terminology.\n\n";
|
||||
}
|
||||
|
||||
// A run-outcome question arrives with the run attached, and the assistant's standing contract —
|
||||
// answer only from the retrieved passages — is wrong for it: the run record and the log are not
|
||||
// in the index and never will be. Without this the honest reading of its own rules is to fall
|
||||
// back on the documentation, which is how "how did the daily orch go" got answered with
|
||||
// directions to the Recent Activity panel instead of the run it was asked about.
|
||||
if ($runTarget !== '' && $runOutcome) {
|
||||
$system .= "THIS IS A QUESTION ABOUT A RUN THAT ALREADY HAPPENED\n"
|
||||
. "You have been given the run record and the tail of the log for " . $runTarget
|
||||
. ". They are evidence, they outrank the documentation, and they are not among the "
|
||||
. "numbered passages — use them directly and do not cite them.\n\n"
|
||||
. "Answer it as a rundown of that run, in this order: whether it succeeded, when it "
|
||||
. "ran and how long it took, what it actually did, and anything that failed, was "
|
||||
. "skipped or looks off. Use the real figures — counts, durations, script names — "
|
||||
. "rather than describing them in general terms. Summary blocks near the end of the "
|
||||
. "log usually hold the totals worth leading with.\n\n"
|
||||
. "Do NOT explain how to find the log, which panel shows recent runs, or how to read "
|
||||
. "it in the WebGUI. They asked you to read it and you have it in front of you; "
|
||||
. "telling them where to click is answering a question they did not ask.\n\n"
|
||||
. "If the record and the log disagree — a clean summary under a non-zero exit, or a "
|
||||
. "record with no end time — say so and lead with it. That contradiction is the most "
|
||||
. "useful thing on the page.\n\n";
|
||||
}
|
||||
|
||||
// Memory first, before the passages. It is the standing context — who the operator is and what
|
||||
// has already been decided — so it should frame everything that follows rather than read as one
|
||||
// more retrieved document. Marked as operator-authored so the model treats it as fact about the
|
||||
|
||||
Reference in New Issue
Block a user