From f523d803548bf3a17aa4b2a3a0c03e11148c0d08 Mon Sep 17 00:00:00 2001 From: Agent 0 Date: Mon, 23 Mar 2026 14:50:19 -0400 Subject: [PATCH 1/2] status: derive status fields from daemon summaries --- src/mirror/status/status.ts | 21 ++++++++++----------- src/mirror/status/tests/status.test.ts | 3 +++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/mirror/status/status.ts b/src/mirror/status/status.ts index 7487c58af0..fc2792df90 100644 --- a/src/mirror/status/status.ts +++ b/src/mirror/status/status.ts @@ -50,7 +50,6 @@ export type GetMirrorStatusOptions = { export async function getMirrorStatus(opts: GetMirrorStatusOptions): Promise { const daemon = opts.runtimeHost.daemon; - const boot = daemon.getBootSnapshot(); const peers = opts.runtimeHost.syncManager.listPeers(); const baseUrl = opts.runtimeHost.syncManager.getLocalBaseUrl(); const runtime = getMirrordaemonRuntimeState(daemon, { @@ -66,10 +65,10 @@ export async function getMirrorStatus(opts: GetMirrorStatusOptions): Promise { expect(status.runtime.node_id).toBe("status-node"); expect(status.runtime.sessions.total).toBe(0); expect(status.service.lore_dir).toBe(path.resolve(loreDir)); + expect(status.lore.dir).toBe(status.service.lore_dir); + expect(status.service.workspace_users_root).toBe(status.workspace.users_root); expect(status.provider.configured).toBe(false); expect(status.provider.active_provider_id).toBe("primary"); expect(status.provider.total).toBe(1); @@ -71,6 +73,7 @@ describe("mirror status", () => { expect(status.runtime.sessions.total).toBe(1); expect(status.runtime.sessions.open).toBe(1); + expect(status.sync.node_id).toBe(status.runtime.node_id); expect(status.provider.providers[0]?.provider_id).toBe("primary"); const json = JSON.stringify(status); From b48f3985fdd4b2030dd8f12b8cb925cbceda45e6 Mon Sep 17 00:00:00 2001 From: Agent 0 Date: Mon, 23 Mar 2026 15:17:16 -0400 Subject: [PATCH 2/2] status: derive provider list from daemon provider summary --- src/mirror/status/status.ts | 14 +++--- src/mirrordaemon/daemon_types.ts | 2 + src/mirrordaemon/runtime_state.test.ts | 62 ++++++++++++++++++++++++++ src/mirrordaemon/runtime_state.ts | 2 + 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/src/mirror/status/status.ts b/src/mirror/status/status.ts index fc2792df90..c5aabddfd1 100644 --- a/src/mirror/status/status.ts +++ b/src/mirror/status/status.ts @@ -1,6 +1,7 @@ import type { MirrorRuntimeHost } from "../../mirror-service/index.js"; import { getMirrordaemonHealthState, + getMirrordaemonProvidersState, getMirrordaemonRuntimeState, } from "../../mirrordaemon/index.js"; @@ -61,6 +62,9 @@ export async function getMirrorStatus(opts: GetMirrorStatusOptions): Promise ({ + active_provider_id: providers.active_provider_id, + total: providers.total, + available: providers.available, + fallback_available: providers.fallback_available, + providers: providers.providers.map((provider) => ({ provider_id: provider.provider_id, label: provider.label, url: provider.url, diff --git a/src/mirrordaemon/daemon_types.ts b/src/mirrordaemon/daemon_types.ts index d0e35c3130..9bf7c781f0 100644 --- a/src/mirrordaemon/daemon_types.ts +++ b/src/mirrordaemon/daemon_types.ts @@ -194,9 +194,11 @@ export type MirrordaemonProvidersSummary = { provider_id: string; label: string; kind: string; + url: string; ready: boolean; configured: boolean; selected: boolean; + last_error?: string; }>; }; diff --git a/src/mirrordaemon/runtime_state.test.ts b/src/mirrordaemon/runtime_state.test.ts index 197783eb98..16ea7aab51 100644 --- a/src/mirrordaemon/runtime_state.test.ts +++ b/src/mirrordaemon/runtime_state.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; import { + buildProvidersSummary, buildDebugSnapshot, buildHealthSummary, buildRuntimeSummary, @@ -227,4 +228,65 @@ describe("mirrordaemon runtime state", () => { expect(health.event_stream.recent_events).toBe(daemon.getRecentEvents().length); expect(health.sync.peers_known).toBe(2); }); + + it("includes provider url and last_error in the daemon provider summary", () => { + const daemon = createMirrordaemon({ + config: baseConfig, + lifecycle: { + discoveredLoreFiles: 2, + shutdown: async () => undefined, + }, + runtimeStartedAt: "2026-03-13T00:00:00.000Z", + }); + + const providers = buildProvidersSummary(daemon, { + providerPlane: { + listProviders: () => [ + { + provider_id: "primary", + label: "Primary", + kind: "openai-compatible", + url: "http://brain.local/v1/chat/completions", + ready: true, + configured: true, + selected: true, + last_error: undefined, + }, + { + provider_id: "fallback", + label: "Fallback", + kind: "openai-compatible", + url: "http://brain.local/v1/fallback", + ready: false, + configured: false, + selected: false, + last_error: "provider unavailable", + }, + ], + } as never, + }); + + expect(providers.providers).toEqual([ + { + provider_id: "primary", + label: "Primary", + kind: "openai-compatible", + url: "http://brain.local/v1/chat/completions", + ready: true, + configured: true, + selected: true, + last_error: undefined, + }, + { + provider_id: "fallback", + label: "Fallback", + kind: "openai-compatible", + url: "http://brain.local/v1/fallback", + ready: false, + configured: false, + selected: false, + last_error: "provider unavailable", + }, + ]); + }); }); diff --git a/src/mirrordaemon/runtime_state.ts b/src/mirrordaemon/runtime_state.ts index 260905be59..f4e0575dfb 100644 --- a/src/mirrordaemon/runtime_state.ts +++ b/src/mirrordaemon/runtime_state.ts @@ -95,9 +95,11 @@ export function buildProvidersSummary( provider_id: provider.provider_id, label: provider.label, kind: provider.kind, + url: provider.url, ready: provider.ready, configured: provider.configured, selected: provider.selected, + last_error: provider.last_error, })) ?? []; return {