-
Notifications
You must be signed in to change notification settings - Fork 0
chore(overseer): structured log on soft brain-unavailable converse #111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/overseer-inbox-turn-supersede
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -205,7 +205,7 @@ export function createOverseerRoutes(getSyncEngine: () => SyncEngine | null): Ho | |
| // Converse — the modality-agnostic conversation core. Runs the brain LLM | ||
| // with the read-only tools and returns a human-facing reply + tool trace. | ||
| // Text is the first transport (debug settings); voice/XR reuse this. When | ||
| // the brain is offline (GPU pulled for VR), returns brainOnline:false with a | ||
| // the brain is offline, returns brainOnline:false with a | ||
| // friendly message rather than an error. | ||
| // | ||
| // Continuity: hub assembles prior `convo_turn`s (budgeted) + latest operator | ||
|
|
@@ -244,6 +244,14 @@ export function createOverseerRoutes(getSyncEngine: () => SyncEngine | null): Ho | |
| model: parsed.data.model | ||
| })) | ||
| if (!config) { | ||
| // Soft 200 for clients — journal still needs a greppable line (access log is 200). | ||
| console.warn('[Overseer][Converse] brain unavailable', { | ||
| reason: 'not_configured', | ||
| kind: 'not_configured', | ||
| reachable: false, | ||
| model: null, | ||
| profile: parsed.data.profile ?? null | ||
| }) | ||
| const reply = 'The Overseer brain is not configured on this hub (set OVERSEER_BRAIN_URL). I can still show raw events and inbox items, but I cannot answer in conversation yet.' | ||
| persistOverseerConvoExchange(overseer, assembled, { | ||
| operatorText: lastOperator, | ||
|
|
@@ -289,9 +297,19 @@ export function createOverseerRoutes(getSyncEngine: () => SyncEngine | null): Ho | |
| if (error instanceof BrainUnavailableError) { | ||
| // Reachable-but-failed (http 4xx/5xx, malformed body) is a converse | ||
| // bug, not an offline brain — do not mislabel it as GPU/VR downtime. | ||
| // Soft 200 for clients — structured warn so journalctl can find it. | ||
| console.warn('[Overseer][Converse] brain unavailable', { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a follow-up brain call fails after Useful? React with 👍 / 👎. |
||
| reason: error.reachable ? 'request_error' : 'unreachable', | ||
| kind: error.kind, | ||
| reachable: error.reachable, | ||
| status: error.status ?? null, | ||
| model: config.model, | ||
| profile: parsed.data.profile ?? null, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a valid caller omits Useful? React with 👍 / 👎. |
||
| message: error.message.slice(0, 200) | ||
| }) | ||
| const reply = error.reachable | ||
| ? 'I reached the Overseer brain but could not complete the tool conversation (request error). This is a converse-loop issue, not the brain being offline — please retry, and flag it if it persists.' | ||
| : 'The Overseer brain is offline right now (the GPU may be in use for VR). Try again shortly — your events and inbox are still being captured.' | ||
| : 'The Overseer brain is offline right now. Try again shortly — your events and inbox are still being captured.' | ||
| persistOverseerConvoExchange(overseer, assembled, { | ||
| operatorText: lastOperator, | ||
| overseerText: reply, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,7 +40,15 @@ export function OverseerChatDebugControls() { | |
| useEffect(() => { | ||
| if (!open || !api || profiles.length > 0) return | ||
| void api.fetchOverseerBrains() | ||
| .then((res) => setProfiles(res.profiles)) | ||
| .then((res) => { | ||
| setProfiles(res.profiles) | ||
| // Prefer hub active brain — do not stick on hard-coded "default" when | ||
| // the operator saved a working profile (e.g. local loopback). | ||
| if (res.active?.profile) { | ||
| setSelectedProfile(res.active.profile) | ||
| setSelectedModel(res.active.model ?? '') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the persisted active profile differs from the initial Useful? React with 👍 / 👎. |
||
| } | ||
| }) | ||
| .catch(() => { /* brains list is optional chrome */ }) | ||
| }, [open, api, profiles.length]) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Under Bun, passing this object as a second
console.warnargument renders the warning across multiple lines: the prefixed line contains only[Overseer][Converse] brain unavailable {, whilereason,kind,reachable, and the other fields appear on separate unprefixed lines. Consequently, grepping the journal for the advertised prefix returns none of the diagnostic fields, defeating the purpose of this structured warning; serialize the payload onto the prefixed line or use a logger that emits a single structured record.Useful? React with 👍 / 👎.