mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 02:50:23 +00:00
fix(status): align session_status with /status
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { normalizeGroupActivation } from "../../auto-reply/group-activation.js";
|
||||
import { getFollowupQueueDepth, resolveQueueSettings } from "../../auto-reply/reply/queue.js";
|
||||
import { buildStatusMessage } from "../../auto-reply/status.js";
|
||||
import { buildStatusText } from "../../auto-reply/reply/commands-status.js";
|
||||
import type {
|
||||
ElevatedLevel,
|
||||
ReasoningLevel,
|
||||
ThinkLevel,
|
||||
VerboseLevel,
|
||||
} from "../../auto-reply/thinking.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { loadConfig } from "../../config/config.js";
|
||||
import {
|
||||
@@ -11,11 +15,6 @@ import {
|
||||
updateSessionStore,
|
||||
} from "../../config/sessions.js";
|
||||
import { resolveSessionModelIdentityRef } from "../../gateway/session-utils.js";
|
||||
import {
|
||||
formatUsageWindowSummary,
|
||||
loadProviderUsageSummary,
|
||||
resolveUsageProviderId,
|
||||
} from "../../infra/provider-usage.js";
|
||||
import {
|
||||
buildAgentMainSessionKey,
|
||||
DEFAULT_AGENT_ID,
|
||||
@@ -24,9 +23,6 @@ import {
|
||||
} from "../../routing/session-key.js";
|
||||
import { applyModelOverrideToSessionEntry } from "../../sessions/model-overrides.js";
|
||||
import { listTasksForRelatedSessionKeyForOwner } from "../../tasks/task-owner-access.js";
|
||||
import { resolveAgentConfig, resolveAgentDir } from "../agent-scope.js";
|
||||
import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "../date-time.js";
|
||||
import { resolveModelAuthLabel } from "../model-auth-label.js";
|
||||
import { loadModelCatalog } from "../model-catalog.js";
|
||||
import {
|
||||
buildAllowedModelSet,
|
||||
@@ -449,7 +445,6 @@ export function createSessionStatusTool(opts?: {
|
||||
}
|
||||
}
|
||||
|
||||
const agentDir = resolveAgentDir(cfg, agentId);
|
||||
const runtimeModelIdentity = resolveSessionModelIdentityRef(
|
||||
cfg,
|
||||
resolved.entry,
|
||||
@@ -467,118 +462,54 @@ export function createSessionStatusTool(opts?: {
|
||||
const defaultModelForCard = hasExplicitModelOverride
|
||||
? configured.model
|
||||
: runtimeModelForCard || configured.model;
|
||||
// Preserve the "provider unknown" case for legacy runtime-only sessions so the
|
||||
// status card does not synthesize a configured provider/model pair that never ran.
|
||||
const statusSessionEntry =
|
||||
!hasExplicitModelOverride && !runtimeProviderForCard && runtimeModelForCard
|
||||
? { ...resolved.entry, providerOverride: "" }
|
||||
: resolved.entry;
|
||||
const providerOverrideForCard = statusSessionEntry.providerOverride?.trim();
|
||||
const providerForCard = providerOverrideForCard ?? defaultProviderForCard;
|
||||
const usageProvider = resolveUsageProviderId(providerForCard);
|
||||
let usageLine: string | undefined;
|
||||
if (usageProvider) {
|
||||
try {
|
||||
const usageSummary = await loadProviderUsageSummary({
|
||||
timeoutMs: 3500,
|
||||
providers: [usageProvider],
|
||||
agentDir,
|
||||
});
|
||||
const snapshot = usageSummary.providers.find((entry) => entry.provider === usageProvider);
|
||||
if (snapshot) {
|
||||
const formatted = formatUsageWindowSummary(snapshot, {
|
||||
now: Date.now(),
|
||||
maxWindows: 2,
|
||||
includeResets: true,
|
||||
});
|
||||
if (formatted && !formatted.startsWith("error:")) {
|
||||
usageLine = `📊 Usage: ${formatted}`;
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
const primaryModelLabel =
|
||||
providerForCard && defaultModelForCard
|
||||
? `${providerForCard}/${defaultModelForCard}`
|
||||
: defaultModelForCard;
|
||||
const isGroup =
|
||||
resolved.entry.chatType === "group" ||
|
||||
resolved.entry.chatType === "channel" ||
|
||||
statusSessionEntry.chatType === "group" ||
|
||||
statusSessionEntry.chatType === "channel" ||
|
||||
resolved.key.includes(":group:") ||
|
||||
resolved.key.includes(":channel:");
|
||||
const groupActivation = isGroup
|
||||
? (normalizeGroupActivation(resolved.entry.groupActivation) ?? "mention")
|
||||
: undefined;
|
||||
|
||||
const queueSettings = resolveQueueSettings({
|
||||
cfg,
|
||||
channel:
|
||||
resolved.entry.channel ??
|
||||
resolved.entry.lastChannel ??
|
||||
resolved.entry.origin?.provider ??
|
||||
"unknown",
|
||||
sessionEntry: resolved.entry,
|
||||
});
|
||||
const queueKey = resolved.key ?? resolved.entry.sessionId;
|
||||
const queueDepth = queueKey ? getFollowupQueueDepth(queueKey) : 0;
|
||||
const queueOverrides = Boolean(
|
||||
resolved.entry.queueDebounceMs ?? resolved.entry.queueCap ?? resolved.entry.queueDrop,
|
||||
);
|
||||
|
||||
const userTimezone = resolveUserTimezone(cfg.agents?.defaults?.userTimezone);
|
||||
const userTimeFormat = resolveUserTimeFormat(cfg.agents?.defaults?.timeFormat);
|
||||
const userTime = formatUserTime(new Date(), userTimezone, userTimeFormat);
|
||||
const timeLine = userTime
|
||||
? `🕒 Time: ${userTime} (${userTimezone})`
|
||||
: `🕒 Time zone: ${userTimezone}`;
|
||||
|
||||
const agentDefaults = cfg.agents?.defaults ?? {};
|
||||
const agentConfig = resolveAgentConfig(cfg, agentId);
|
||||
const defaultLabel = defaultProviderForCard
|
||||
? `${defaultProviderForCard}/${defaultModelForCard}`
|
||||
: defaultModelForCard;
|
||||
const agentModel =
|
||||
typeof agentDefaults.model === "object" && agentDefaults.model
|
||||
? { ...agentDefaults.model, primary: defaultLabel }
|
||||
: { primary: defaultLabel };
|
||||
const statusText = buildStatusMessage({
|
||||
config: cfg,
|
||||
agent: {
|
||||
...agentDefaults,
|
||||
model: agentModel,
|
||||
thinkingDefault: agentConfig?.thinkingDefault ?? agentDefaults.thinkingDefault,
|
||||
},
|
||||
agentId,
|
||||
explicitConfiguredContextTokens:
|
||||
typeof agentDefaults.contextTokens === "number" && agentDefaults.contextTokens > 0
|
||||
? agentDefaults.contextTokens
|
||||
: undefined,
|
||||
sessionEntry: statusSessionEntry,
|
||||
sessionKey: resolved.key,
|
||||
sessionStorePath: storePath,
|
||||
groupActivation,
|
||||
modelAuth: resolveModelAuthLabel({
|
||||
provider: providerForCard,
|
||||
cfg,
|
||||
sessionEntry: statusSessionEntry,
|
||||
agentDir,
|
||||
}),
|
||||
usageLine,
|
||||
timeLine,
|
||||
queue: {
|
||||
mode: queueSettings.mode,
|
||||
depth: queueDepth,
|
||||
debounceMs: queueSettings.debounceMs,
|
||||
cap: queueSettings.cap,
|
||||
dropPolicy: queueSettings.dropPolicy,
|
||||
showDetails: queueOverrides,
|
||||
},
|
||||
includeTranscriptUsage: true,
|
||||
});
|
||||
const taskLine = formatSessionTaskLine({
|
||||
relatedSessionKey: resolved.key,
|
||||
callerOwnerKey: visibilityRequesterKey,
|
||||
});
|
||||
const fullStatusText = taskLine ? `${statusText}\n${taskLine}` : statusText;
|
||||
const statusText = await buildStatusText({
|
||||
cfg,
|
||||
sessionEntry: statusSessionEntry,
|
||||
sessionKey: resolved.key,
|
||||
parentSessionKey: statusSessionEntry.parentSessionKey,
|
||||
sessionScope: cfg.session?.scope,
|
||||
storePath,
|
||||
statusChannel:
|
||||
statusSessionEntry.channel ??
|
||||
statusSessionEntry.lastChannel ??
|
||||
statusSessionEntry.origin?.provider ??
|
||||
"unknown",
|
||||
provider: providerForCard,
|
||||
model: defaultModelForCard,
|
||||
resolvedThinkLevel: statusSessionEntry.thinkingLevel as ThinkLevel | undefined,
|
||||
resolvedFastMode: statusSessionEntry.fastMode,
|
||||
resolvedVerboseLevel: (statusSessionEntry.verboseLevel ?? "off") as VerboseLevel,
|
||||
resolvedReasoningLevel: (statusSessionEntry.reasoningLevel ?? "off") as ReasoningLevel,
|
||||
resolvedElevatedLevel: statusSessionEntry.elevatedLevel as ElevatedLevel | undefined,
|
||||
resolveDefaultThinkingLevel: async () => cfg.agents?.defaults?.thinkingDefault,
|
||||
isGroup,
|
||||
defaultGroupActivation: () => "mention",
|
||||
taskLineOverride: taskLine,
|
||||
skipDefaultTaskLookup: true,
|
||||
primaryModelLabelOverride: primaryModelLabel,
|
||||
...(providerForCard ? {} : { modelAuthOverride: undefined }),
|
||||
});
|
||||
const fullStatusText =
|
||||
taskLine && !statusText.includes(taskLine) ? `${statusText}\n${taskLine}` : statusText;
|
||||
|
||||
return {
|
||||
content: [{ type: "text", text: fullStatusText }],
|
||||
|
||||
Reference in New Issue
Block a user