mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
feat: expose runtime version in gateway status
This commit is contained in:
@@ -22,6 +22,7 @@ function createRecentSessionRow() {
|
||||
describe("redactSensitiveStatusSummary", () => {
|
||||
it("removes sensitive session and path details while preserving summary structure", () => {
|
||||
const input: StatusSummary = {
|
||||
runtimeVersion: "2026.3.8",
|
||||
heartbeat: {
|
||||
defaultAgentId: "main",
|
||||
agents: [{ agentId: "main", enabled: true, every: "5m", everyMs: 300_000 }],
|
||||
@@ -50,6 +51,7 @@ describe("redactSensitiveStatusSummary", () => {
|
||||
expect(redacted.sessions.recent).toEqual([]);
|
||||
expect(redacted.sessions.byAgent[0]?.path).toBe("[redacted]");
|
||||
expect(redacted.sessions.byAgent[0]?.recent).toEqual([]);
|
||||
expect(redacted.runtimeVersion).toBe("2026.3.8");
|
||||
expect(redacted.heartbeat).toEqual(input.heartbeat);
|
||||
expect(redacted.channelSummary).toEqual(input.channelSummary);
|
||||
});
|
||||
|
||||
85
src/commands/status.summary.test.ts
Normal file
85
src/commands/status.summary.test.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("../agents/context.js", () => ({
|
||||
resolveContextTokensForModel: vi.fn(() => 200_000),
|
||||
}));
|
||||
|
||||
vi.mock("../agents/defaults.js", () => ({
|
||||
DEFAULT_CONTEXT_TOKENS: 200_000,
|
||||
DEFAULT_MODEL: "gpt-5.2",
|
||||
DEFAULT_PROVIDER: "openai",
|
||||
}));
|
||||
|
||||
vi.mock("../agents/model-selection.js", () => ({
|
||||
resolveConfiguredModelRef: vi.fn(() => ({
|
||||
provider: "openai",
|
||||
model: "gpt-5.2",
|
||||
})),
|
||||
}));
|
||||
|
||||
vi.mock("../config/config.js", () => ({
|
||||
loadConfig: vi.fn(() => ({})),
|
||||
}));
|
||||
|
||||
vi.mock("../config/sessions.js", () => ({
|
||||
loadSessionStore: vi.fn(() => ({})),
|
||||
resolveFreshSessionTotalTokens: vi.fn(() => undefined),
|
||||
resolveMainSessionKey: vi.fn(() => "main"),
|
||||
resolveStorePath: vi.fn(() => "/tmp/sessions.json"),
|
||||
}));
|
||||
|
||||
vi.mock("../gateway/session-utils.js", () => ({
|
||||
classifySessionKey: vi.fn(() => "direct"),
|
||||
listAgentsForGateway: vi.fn(() => ({
|
||||
defaultId: "main",
|
||||
agents: [{ id: "main" }],
|
||||
})),
|
||||
resolveSessionModelRef: vi.fn(() => ({
|
||||
provider: "openai",
|
||||
model: "gpt-5.2",
|
||||
})),
|
||||
}));
|
||||
|
||||
vi.mock("../infra/channel-summary.js", () => ({
|
||||
buildChannelSummary: vi.fn(async () => ["ok"]),
|
||||
}));
|
||||
|
||||
vi.mock("../infra/heartbeat-runner.js", () => ({
|
||||
resolveHeartbeatSummaryForAgent: vi.fn(() => ({
|
||||
enabled: true,
|
||||
every: "5m",
|
||||
everyMs: 300_000,
|
||||
})),
|
||||
}));
|
||||
|
||||
vi.mock("../infra/system-events.js", () => ({
|
||||
peekSystemEvents: vi.fn(() => []),
|
||||
}));
|
||||
|
||||
vi.mock("../routing/session-key.js", () => ({
|
||||
parseAgentSessionKey: vi.fn(() => null),
|
||||
}));
|
||||
|
||||
vi.mock("../version.js", () => ({
|
||||
resolveRuntimeServiceVersion: vi.fn(() => "2026.3.8"),
|
||||
}));
|
||||
|
||||
vi.mock("./status.link-channel.js", () => ({
|
||||
resolveLinkChannelContext: vi.fn(async () => undefined),
|
||||
}));
|
||||
|
||||
describe("getStatusSummary", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("includes runtimeVersion in the status payload", async () => {
|
||||
const { getStatusSummary } = await import("./status.summary.js");
|
||||
|
||||
const summary = await getStatusSummary();
|
||||
|
||||
expect(summary.runtimeVersion).toBe("2026.3.8");
|
||||
expect(summary.heartbeat.defaultAgentId).toBe("main");
|
||||
expect(summary.channelSummary).toEqual(["ok"]);
|
||||
});
|
||||
});
|
||||
@@ -19,6 +19,7 @@ import { buildChannelSummary } from "../infra/channel-summary.js";
|
||||
import { resolveHeartbeatSummaryForAgent } from "../infra/heartbeat-runner.js";
|
||||
import { peekSystemEvents } from "../infra/system-events.js";
|
||||
import { parseAgentSessionKey } from "../routing/session-key.js";
|
||||
import { resolveRuntimeServiceVersion } from "../version.js";
|
||||
import { resolveLinkChannelContext } from "./status.link-channel.js";
|
||||
import type { HeartbeatStatus, SessionStatus, StatusSummary } from "./status.types.js";
|
||||
|
||||
@@ -210,6 +211,7 @@ export async function getStatusSummary(
|
||||
const totalSessions = allSessions.length;
|
||||
|
||||
const summary: StatusSummary = {
|
||||
runtimeVersion: resolveRuntimeServiceVersion(process.env),
|
||||
linkChannel: linkContext
|
||||
? {
|
||||
id: linkContext.plugin.id,
|
||||
|
||||
@@ -34,6 +34,7 @@ export type HeartbeatStatus = {
|
||||
};
|
||||
|
||||
export type StatusSummary = {
|
||||
runtimeVersion?: string | null;
|
||||
linkChannel?: {
|
||||
id: ChannelId;
|
||||
label: string;
|
||||
|
||||
@@ -6,6 +6,9 @@ import type { GatewayStatusSummary } from "./tui-types.js";
|
||||
export function formatStatusSummary(summary: GatewayStatusSummary) {
|
||||
const lines: string[] = [];
|
||||
lines.push("Gateway status");
|
||||
if (summary.runtimeVersion) {
|
||||
lines.push(`Version: ${summary.runtimeVersion}`);
|
||||
}
|
||||
|
||||
if (!summary.linkChannel) {
|
||||
lines.push("Link channel: unknown");
|
||||
|
||||
@@ -49,6 +49,7 @@ export type AgentSummary = {
|
||||
};
|
||||
|
||||
export type GatewayStatusSummary = {
|
||||
runtimeVersion?: string | null;
|
||||
linkChannel?: {
|
||||
id?: string;
|
||||
label?: string;
|
||||
|
||||
Reference in New Issue
Block a user