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", () => {
|
describe("redactSensitiveStatusSummary", () => {
|
||||||
it("removes sensitive session and path details while preserving summary structure", () => {
|
it("removes sensitive session and path details while preserving summary structure", () => {
|
||||||
const input: StatusSummary = {
|
const input: StatusSummary = {
|
||||||
|
runtimeVersion: "2026.3.8",
|
||||||
heartbeat: {
|
heartbeat: {
|
||||||
defaultAgentId: "main",
|
defaultAgentId: "main",
|
||||||
agents: [{ agentId: "main", enabled: true, every: "5m", everyMs: 300_000 }],
|
agents: [{ agentId: "main", enabled: true, every: "5m", everyMs: 300_000 }],
|
||||||
@@ -50,6 +51,7 @@ describe("redactSensitiveStatusSummary", () => {
|
|||||||
expect(redacted.sessions.recent).toEqual([]);
|
expect(redacted.sessions.recent).toEqual([]);
|
||||||
expect(redacted.sessions.byAgent[0]?.path).toBe("[redacted]");
|
expect(redacted.sessions.byAgent[0]?.path).toBe("[redacted]");
|
||||||
expect(redacted.sessions.byAgent[0]?.recent).toEqual([]);
|
expect(redacted.sessions.byAgent[0]?.recent).toEqual([]);
|
||||||
|
expect(redacted.runtimeVersion).toBe("2026.3.8");
|
||||||
expect(redacted.heartbeat).toEqual(input.heartbeat);
|
expect(redacted.heartbeat).toEqual(input.heartbeat);
|
||||||
expect(redacted.channelSummary).toEqual(input.channelSummary);
|
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 { resolveHeartbeatSummaryForAgent } from "../infra/heartbeat-runner.js";
|
||||||
import { peekSystemEvents } from "../infra/system-events.js";
|
import { peekSystemEvents } from "../infra/system-events.js";
|
||||||
import { parseAgentSessionKey } from "../routing/session-key.js";
|
import { parseAgentSessionKey } from "../routing/session-key.js";
|
||||||
|
import { resolveRuntimeServiceVersion } from "../version.js";
|
||||||
import { resolveLinkChannelContext } from "./status.link-channel.js";
|
import { resolveLinkChannelContext } from "./status.link-channel.js";
|
||||||
import type { HeartbeatStatus, SessionStatus, StatusSummary } from "./status.types.js";
|
import type { HeartbeatStatus, SessionStatus, StatusSummary } from "./status.types.js";
|
||||||
|
|
||||||
@@ -210,6 +211,7 @@ export async function getStatusSummary(
|
|||||||
const totalSessions = allSessions.length;
|
const totalSessions = allSessions.length;
|
||||||
|
|
||||||
const summary: StatusSummary = {
|
const summary: StatusSummary = {
|
||||||
|
runtimeVersion: resolveRuntimeServiceVersion(process.env),
|
||||||
linkChannel: linkContext
|
linkChannel: linkContext
|
||||||
? {
|
? {
|
||||||
id: linkContext.plugin.id,
|
id: linkContext.plugin.id,
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ export type HeartbeatStatus = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type StatusSummary = {
|
export type StatusSummary = {
|
||||||
|
runtimeVersion?: string | null;
|
||||||
linkChannel?: {
|
linkChannel?: {
|
||||||
id: ChannelId;
|
id: ChannelId;
|
||||||
label: string;
|
label: string;
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import type { GatewayStatusSummary } from "./tui-types.js";
|
|||||||
export function formatStatusSummary(summary: GatewayStatusSummary) {
|
export function formatStatusSummary(summary: GatewayStatusSummary) {
|
||||||
const lines: string[] = [];
|
const lines: string[] = [];
|
||||||
lines.push("Gateway status");
|
lines.push("Gateway status");
|
||||||
|
if (summary.runtimeVersion) {
|
||||||
|
lines.push(`Version: ${summary.runtimeVersion}`);
|
||||||
|
}
|
||||||
|
|
||||||
if (!summary.linkChannel) {
|
if (!summary.linkChannel) {
|
||||||
lines.push("Link channel: unknown");
|
lines.push("Link channel: unknown");
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ export type AgentSummary = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type GatewayStatusSummary = {
|
export type GatewayStatusSummary = {
|
||||||
|
runtimeVersion?: string | null;
|
||||||
linkChannel?: {
|
linkChannel?: {
|
||||||
id?: string;
|
id?: string;
|
||||||
label?: string;
|
label?: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user