fix: restore status usage summary output

This commit is contained in:
Peter Steinberger
2026-01-16 02:49:10 +00:00
parent e7c16cc0e6
commit 29476b222d
6 changed files with 37 additions and 24 deletions

View File

@@ -15,6 +15,7 @@
- Docs: clarify multi-gateway rescue bot guidance. (#969) — thanks @bjesuiter. - Docs: clarify multi-gateway rescue bot guidance. (#969) — thanks @bjesuiter.
- Agents: add Current Date & Time system prompt section with configurable time format (auto/12/24). - Agents: add Current Date & Time system prompt section with configurable time format (auto/12/24).
- Agents: avoid false positives when logging unsupported Google tool schema keywords. - Agents: avoid false positives when logging unsupported Google tool schema keywords.
- Status: restore usage summary line for current provider when no OAuth profiles exist.
- Tools: normalize Slack/Discord message timestamps with `timestampMs`/`timestampUtc` while keeping raw provider fields. - Tools: normalize Slack/Discord message timestamps with `timestampMs`/`timestampUtc` while keeping raw provider fields.
- Docs: add Date & Time guide and update prompt/timezone configuration docs. - Docs: add Date & Time guide and update prompt/timezone configuration docs.
- Messages: debounce rapid inbound messages across channels with per-connector overrides. (#971) — thanks @juanpablodlc. - Messages: debounce rapid inbound messages across channels with per-connector overrides. (#971) — thanks @juanpablodlc.

View File

@@ -56,6 +56,7 @@ vi.mock("../skills.js", async (importOriginal) => {
describe("Agent-specific sandbox config", () => { describe("Agent-specific sandbox config", () => {
beforeEach(() => { beforeEach(() => {
spawnCalls.length = 0; spawnCalls.length = 0;
vi.resetModules();
}); });
it("should use agent-specific workspaceRoot", async () => { it("should use agent-specific workspaceRoot", async () => {

View File

@@ -15,6 +15,7 @@ import type { ClawdbotConfig } from "../../config/config.js";
import type { SessionEntry, SessionScope } from "../../config/sessions.js"; import type { SessionEntry, SessionScope } from "../../config/sessions.js";
import { logVerbose } from "../../globals.js"; import { logVerbose } from "../../globals.js";
import { import {
formatUsageSummaryLine,
formatUsageWindowSummary, formatUsageWindowSummary,
loadProviderUsageSummary, loadProviderUsageSummary,
resolveUsageProviderId, resolveUsageProviderId,
@@ -139,22 +140,34 @@ export async function buildStatusReply(params: {
(profile) => profile.type === "oauth" || profile.type === "token", (profile) => profile.type === "oauth" || profile.type === "token",
); );
const usageProviders = Array.from( const usageProviders = new Set<UsageProviderId>();
new Set( for (const profile of oauthProfiles) {
oauthProfiles const entry = resolveUsageProviderId(profile.provider);
.map((profile) => resolveUsageProviderId(profile.provider)) if (entry) usageProviders.add(entry);
.filter((entry): entry is UsageProviderId => Boolean(entry)), }
), const currentUsageProvider = (() => {
);
const usageByProvider = new Map<string, string>();
if (usageProviders.length > 0) {
try { try {
const usageSummary = await loadProviderUsageSummary({ return resolveUsageProviderId(provider);
} catch {
return undefined;
}
})();
if (usageProviders.size === 0 && currentUsageProvider) {
usageProviders.add(currentUsageProvider);
}
const usageByProvider = new Map<string, string>();
let usageSummaryCache:
| Awaited<ReturnType<typeof loadProviderUsageSummary>>
| null
| undefined;
if (usageProviders.size > 0) {
try {
usageSummaryCache = await loadProviderUsageSummary({
timeoutMs: 3500, timeoutMs: 3500,
providers: usageProviders, providers: Array.from(usageProviders),
agentDir: statusAgentDir, agentDir: statusAgentDir,
}); });
for (const snapshot of usageSummary.providers) { for (const snapshot of usageSummaryCache.providers) {
const formatted = formatUsageWindowSummary(snapshot, { const formatted = formatUsageWindowSummary(snapshot, {
now: Date.now(), now: Date.now(),
maxWindows: 2, maxWindows: 2,
@@ -168,10 +181,16 @@ export async function buildStatusReply(params: {
let usageLine: string | null = null; let usageLine: string | null = null;
try { try {
const usageProvider = resolveUsageProviderId(provider); if (oauthProfiles.length === 0 && currentUsageProvider) {
if (oauthProfiles.length === 0 && usageProvider) { const summaryLine = usageSummaryCache
const usage = usageByProvider.get(usageProvider); ? formatUsageSummaryLine(usageSummaryCache, { now: Date.now(), maxProviders: 1 })
if (usage) usageLine = `📊 Usage: ${usage}`; : null;
if (summaryLine) {
usageLine = summaryLine;
} else {
const usage = usageByProvider.get(currentUsageProvider);
if (usage) usageLine = `📊 Usage: ${usage}`;
}
} }
} catch { } catch {
usageLine = null; usageLine = null;

View File

@@ -6,7 +6,6 @@ export const createTestRegistry = (overrides: Partial<PluginRegistry> = {}): Plu
tools: [], tools: [],
providers: [], providers: [],
channels: [], channels: [],
providers: [],
gatewayHandlers: {}, gatewayHandlers: {},
httpHandlers: [], httpHandlers: [],
cliRegistrars: [], cliRegistrars: [],

View File

@@ -191,7 +191,6 @@ function createPluginRecord(params: {
toolNames: [], toolNames: [],
providerIds: [], providerIds: [],
channelIds: [], channelIds: [],
providerIds: [],
gatewayMethods: [], gatewayMethods: [],
cliCommands: [], cliCommands: [],
services: [], services: [],

View File

@@ -138,11 +138,6 @@ export type ClawdbotPluginChannelRegistration = {
dock?: ChannelDock; dock?: ChannelDock;
}; };
export type ClawdbotPluginProviderRegistration = {
id: string;
[key: string]: unknown;
};
export type ClawdbotPluginDefinition = { export type ClawdbotPluginDefinition = {
id?: string; id?: string;
name?: string; name?: string;
@@ -170,7 +165,6 @@ export type ClawdbotPluginApi = {
tool: AnyAgentTool | ClawdbotPluginToolFactory, tool: AnyAgentTool | ClawdbotPluginToolFactory,
opts?: { name?: string; names?: string[] }, opts?: { name?: string; names?: string[] },
) => void; ) => void;
registerProvider: (provider: ClawdbotPluginProviderRegistration) => void;
registerHttpHandler: (handler: ClawdbotPluginHttpHandler) => void; registerHttpHandler: (handler: ClawdbotPluginHttpHandler) => void;
registerChannel: (registration: ClawdbotPluginChannelRegistration | ChannelPlugin) => void; registerChannel: (registration: ClawdbotPluginChannelRegistration | ChannelPlugin) => void;
registerGatewayMethod: (method: string, handler: GatewayRequestHandler) => void; registerGatewayMethod: (method: string, handler: GatewayRequestHandler) => void;