From 41475454696316cdf3d2dbeca24e451402a35742 Mon Sep 17 00:00:00 2001 From: Sebastian <19554889+sebslight@users.noreply.github.com> Date: Mon, 16 Feb 2026 21:04:06 -0500 Subject: [PATCH] Revert "feat: show transcript file size in session status" This reverts commit 15dd2cda209ccabc9febc25e16eec620137ae744. --- src/agents/tools/session-status-tool.ts | 13 +-- src/auto-reply/reply/commands-status.ts | 21 ++--- src/auto-reply/status.transcript.test.ts | 112 ----------------------- src/auto-reply/status.ts | 90 +----------------- 4 files changed, 15 insertions(+), 221 deletions(-) delete mode 100644 src/auto-reply/status.transcript.test.ts diff --git a/src/agents/tools/session-status-tool.ts b/src/agents/tools/session-status-tool.ts index dc7fc3148b2..b67de007f7a 100644 --- a/src/agents/tools/session-status-tool.ts +++ b/src/agents/tools/session-status-tool.ts @@ -1,8 +1,9 @@ import { Type } from "@sinclair/typebox"; +import type { OpenClawConfig } from "../../config/config.js"; +import type { AnyAgentTool } from "./common.js"; import { normalizeGroupActivation } from "../../auto-reply/group-activation.js"; import { getFollowupQueueDepth, resolveQueueSettings } from "../../auto-reply/reply/queue.js"; -import { buildStatusMessage, getTranscriptInfo } from "../../auto-reply/status.js"; -import type { OpenClawConfig } from "../../config/config.js"; +import { buildStatusMessage } from "../../auto-reply/status.js"; import { loadConfig } from "../../config/config.js"; import { loadSessionStore, @@ -33,7 +34,6 @@ import { resolveDefaultModelForAgent, resolveModelRefFromString, } from "../model-selection.js"; -import type { AnyAgentTool } from "./common.js"; import { readStringParam } from "./common.js"; import { shouldResolveSessionIdInput, @@ -382,13 +382,6 @@ export function createSessionStatusTool(opts?: { showDetails: queueOverrides, }, includeTranscriptUsage: false, - transcriptInfo: getTranscriptInfo({ - sessionId: resolved.entry?.sessionId, - sessionEntry: resolved.entry, - agentId, - sessionKey: resolved.key, - storePath, - }), }); return { diff --git a/src/auto-reply/reply/commands-status.ts b/src/auto-reply/reply/commands-status.ts index 41a35ad269e..9d416d3f291 100644 --- a/src/auto-reply/reply/commands-status.ts +++ b/src/auto-reply/reply/commands-status.ts @@ -1,3 +1,9 @@ +import type { OpenClawConfig } from "../../config/config.js"; +import type { SessionEntry, SessionScope } from "../../config/sessions.js"; +import type { MediaUnderstandingDecision } from "../../media-understanding/types.js"; +import type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel } from "../thinking.js"; +import type { ReplyPayload } from "../types.js"; +import type { CommandContext } from "./commands-types.js"; import { resolveAgentDir, resolveDefaultAgentId, @@ -9,20 +15,14 @@ import { resolveInternalSessionKey, resolveMainSessionAlias, } from "../../agents/tools/sessions-helpers.js"; -import type { OpenClawConfig } from "../../config/config.js"; -import type { SessionEntry, SessionScope } from "../../config/sessions.js"; import { logVerbose } from "../../globals.js"; import { formatUsageWindowSummary, loadProviderUsageSummary, resolveUsageProviderId, } from "../../infra/provider-usage.js"; -import type { MediaUnderstandingDecision } from "../../media-understanding/types.js"; import { normalizeGroupActivation } from "../group-activation.js"; -import { buildStatusMessage, getTranscriptInfo } from "../status.js"; -import type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel } from "../thinking.js"; -import type { ReplyPayload } from "../types.js"; -import type { CommandContext } from "./commands-types.js"; +import { buildStatusMessage } from "../status.js"; import { getFollowupQueueDepth, resolveQueueSettings } from "./queue.js"; import { resolveSubagentLabel } from "./subagents-utils.js"; @@ -178,13 +178,6 @@ export async function buildStatusReply(params: { subagentsLine, mediaDecisions: params.mediaDecisions, includeTranscriptUsage: false, - transcriptInfo: getTranscriptInfo({ - sessionId: sessionEntry?.sessionId, - sessionEntry, - agentId: statusAgentId, - sessionKey, - storePath, - }), }); return { text: statusText }; diff --git a/src/auto-reply/status.transcript.test.ts b/src/auto-reply/status.transcript.test.ts deleted file mode 100644 index d49578d94fb..00000000000 --- a/src/auto-reply/status.transcript.test.ts +++ /dev/null @@ -1,112 +0,0 @@ -import fs from "node:fs"; -import os from "node:os"; -import path from "node:path"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; - -vi.mock("../config/sessions.js", () => ({ - resolveSessionFilePath: vi.fn((_sessionId: string) => ""), - resolveSessionFilePathOptions: vi.fn(() => ({})), - resolveMainSessionKey: vi.fn(() => "main"), -})); - -const sessions = await import("../config/sessions.js"); -const resolveSessionFilePathMock = vi.mocked(sessions.resolveSessionFilePath); - -const { getTranscriptInfo, buildStatusMessage } = await import("./status.js"); - -describe("getTranscriptInfo", () => { - let tmpDir: string; - let testFilePath: string; - - beforeEach(() => { - tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "transcript-test-")); - testFilePath = path.join(tmpDir, "test-session.jsonl"); - resolveSessionFilePathMock.mockReturnValue(testFilePath); - }); - - afterEach(() => { - fs.rmSync(tmpDir, { recursive: true, force: true }); - }); - - it("returns undefined when sessionId is missing", () => { - expect(getTranscriptInfo({})).toBeUndefined(); - }); - - it("returns undefined when file does not exist", () => { - resolveSessionFilePathMock.mockReturnValue(path.join(tmpDir, "nonexistent.jsonl")); - expect(getTranscriptInfo({ sessionId: "abc" })).toBeUndefined(); - }); - - it("returns size and message count for a transcript file", () => { - const lines = [ - JSON.stringify({ message: { role: "user", content: "hello" } }), - JSON.stringify({ message: { role: "assistant", content: "hi" } }), - "", - ]; - fs.writeFileSync(testFilePath, lines.join("\n")); - const info = getTranscriptInfo({ sessionId: "abc" }); - expect(info).toBeDefined(); - expect(info!.messageCount).toBe(2); - expect(info!.sizeBytes).toBeGreaterThan(0); - expect(info!.filePath).toBe(testFilePath); - }); - - it("counts only non-empty lines", () => { - const content = '{"a":1}\n\n\n{"b":2}\n{"c":3}\n\n'; - fs.writeFileSync(testFilePath, content); - const info = getTranscriptInfo({ sessionId: "abc" }); - expect(info!.messageCount).toBe(3); - }); -}); - -describe("transcript line in buildStatusMessage", () => { - it("includes transcript line when transcriptInfo is provided", () => { - const info = { - sizeBytes: 512_000, - messageCount: 42, - filePath: "/tmp/test.jsonl", - }; - const result = buildStatusMessage({ - agent: {}, - transcriptInfo: info, - }); - expect(result).toContain("๐Ÿ“„ Transcript:"); - expect(result).toContain("500.0 KB"); - expect(result).toContain("42 messages"); - }); - - it("shows warning emoji for large transcripts", () => { - const info = { - sizeBytes: 2 * 1024 * 1024, - messageCount: 600, - filePath: "/tmp/test.jsonl", - }; - const result = buildStatusMessage({ - agent: {}, - transcriptInfo: info, - }); - expect(result).toContain("โš ๏ธ"); - expect(result).toContain("2.0 MB"); - }); - - it("omits transcript line when transcriptInfo is undefined", () => { - const result = buildStatusMessage({ - agent: {}, - }); - expect(result).not.toContain("๐Ÿ“„ Transcript:"); - }); - - it("handles singular message count", () => { - const info = { - sizeBytes: 100, - messageCount: 1, - filePath: "/tmp/test.jsonl", - }; - const result = buildStatusMessage({ - agent: {}, - transcriptInfo: info, - }); - expect(result).toContain("1 message"); - expect(result).not.toContain("1 messages"); - }); -}); diff --git a/src/auto-reply/status.ts b/src/auto-reply/status.ts index ba75545c363..7b147053a69 100644 --- a/src/auto-reply/status.ts +++ b/src/auto-reply/status.ts @@ -1,12 +1,15 @@ import fs from "node:fs"; +import type { SkillCommandSpec } from "../agents/skills.js"; +import type { OpenClawConfig } from "../config/config.js"; +import type { MediaUnderstandingDecision } from "../media-understanding/types.js"; +import type { CommandCategory } from "./commands-registry.types.js"; +import type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel } from "./thinking.js"; import { lookupContextTokens } from "../agents/context.js"; import { DEFAULT_CONTEXT_TOKENS, DEFAULT_MODEL, DEFAULT_PROVIDER } from "../agents/defaults.js"; import { resolveModelAuthMode } from "../agents/model-auth.js"; import { resolveConfiguredModelRef } from "../agents/model-selection.js"; import { resolveSandboxRuntimeStatus } from "../agents/sandbox.js"; -import type { SkillCommandSpec } from "../agents/skills.js"; import { derivePromptTokens, normalizeUsage, type UsageLike } from "../agents/usage.js"; -import type { OpenClawConfig } from "../config/config.js"; import { resolveMainSessionKey, resolveSessionFilePath, @@ -16,7 +19,6 @@ import { } from "../config/sessions.js"; import { formatTimeAgo } from "../infra/format-time/format-relative.ts"; import { resolveCommitHash } from "../infra/git-commit.js"; -import type { MediaUnderstandingDecision } from "../media-understanding/types.js"; import { listPluginCommands } from "../plugins/commands.js"; import { resolveAgentIdFromSessionKey } from "../routing/session-key.js"; import { @@ -39,8 +41,6 @@ import { listChatCommandsForConfig, type ChatCommandDefinition, } from "./commands-registry.js"; -import type { CommandCategory } from "./commands-registry.types.js"; -import type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel } from "./thinking.js"; type AgentConfig = Partial["defaults"]>>; @@ -55,15 +55,6 @@ type QueueStatus = { showDetails?: boolean; }; -export type TranscriptInfo = { - /** File size in bytes. */ - sizeBytes: number; - /** Number of non-empty lines (messages) in the transcript. */ - messageCount: number; - /** Absolute path to the transcript file. */ - filePath: string; -}; - type StatusArgs = { config?: OpenClawConfig; agent: AgentConfig; @@ -84,7 +75,6 @@ type StatusArgs = { mediaDecisions?: MediaUnderstandingDecision[]; subagentsLine?: string; includeTranscriptUsage?: boolean; - transcriptInfo?: TranscriptInfo; now?: number; }; @@ -334,74 +324,6 @@ const formatVoiceModeLine = ( return `๐Ÿ”Š Voice: ${autoMode} ยท provider=${provider} ยท limit=${maxLength} ยท summary=${summarize}`; }; -/** - * Read transcript file metadata (size + line count) for a session. - * Returns `undefined` when the file does not exist or cannot be read. - */ -export function getTranscriptInfo(params: { - sessionId?: string; - sessionEntry?: SessionEntry; - agentId?: string; - sessionKey?: string; - storePath?: string; -}): TranscriptInfo | undefined { - if (!params.sessionId) { - return undefined; - } - let logPath: string; - try { - const resolvedAgentId = - params.agentId ?? - (params.sessionKey ? resolveAgentIdFromSessionKey(params.sessionKey) : undefined); - logPath = resolveSessionFilePath( - params.sessionId, - params.sessionEntry, - resolveSessionFilePathOptions({ agentId: resolvedAgentId, storePath: params.storePath }), - ); - } catch { - return undefined; - } - try { - const stat = fs.statSync(logPath); - if (!stat.isFile()) { - return undefined; - } - // Count non-empty lines for message count. - const content = fs.readFileSync(logPath, "utf-8"); - let messageCount = 0; - for (const line of content.split("\n")) { - if (line.trim()) { - messageCount += 1; - } - } - return { sizeBytes: stat.size, messageCount, filePath: logPath }; - } catch { - return undefined; - } -} - -function formatFileSize(bytes: number): string { - if (bytes < 1024) { - return `${bytes} B`; - } - if (bytes < 1024 * 1024) { - return `${(bytes / 1024).toFixed(1)} KB`; - } - return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; -} - -/** Size threshold (bytes) above which a warning emoji is shown. Default: 1 MB. */ -const TRANSCRIPT_SIZE_WARNING_BYTES = 1024 * 1024; - -function formatTranscriptLine(info: TranscriptInfo | undefined): string | null { - if (!info) { - return null; - } - const sizeLabel = formatFileSize(info.sizeBytes); - const warning = info.sizeBytes >= TRANSCRIPT_SIZE_WARNING_BYTES ? " โš ๏ธ" : ""; - return `๐Ÿ“„ Transcript: ${sizeLabel}, ${info.messageCount} message${info.messageCount === 1 ? "" : "s"}${warning}`; -} - export function buildStatusMessage(args: StatusArgs): string { const now = args.now ?? Date.now(); const entry = args.sessionEntry; @@ -550,7 +472,6 @@ export function buildStatusMessage(args: StatusArgs): string { usagePair && costLine ? `${usagePair} ยท ${costLine}` : (usagePair ?? costLine); const mediaLine = formatMediaUnderstandingLine(args.mediaDecisions); const voiceLine = formatVoiceModeLine(args.config, args.sessionEntry); - const transcriptLine = formatTranscriptLine(args.transcriptInfo); return [ versionLine, @@ -558,7 +479,6 @@ export function buildStatusMessage(args: StatusArgs): string { modelLine, usageCostLine, `๐Ÿ“š ${contextLine}`, - transcriptLine, mediaLine, args.usageLine, `๐Ÿงต ${sessionLine}`,