Merge d9907fb15ede84e8093d053807f5adddc5073a31 into 8a05c05596ca9ba0735dafd8e359885de4c2c969
This commit is contained in:
commit
4331b68430
@ -68,10 +68,17 @@ export async function updateSessionStoreAfterAgentRun(params: {
|
||||
updatedAt: Date.now(),
|
||||
contextTokens,
|
||||
};
|
||||
const modelChanged =
|
||||
(entry.model !== undefined && entry.model !== modelUsed) ||
|
||||
(entry.modelProvider !== undefined && entry.modelProvider !== providerUsed);
|
||||
setSessionRuntimeModel(next, {
|
||||
provider: providerUsed,
|
||||
model: modelUsed,
|
||||
});
|
||||
if (modelChanged) {
|
||||
next.totalTokens = undefined;
|
||||
next.totalTokensFresh = false;
|
||||
}
|
||||
if (isCliProvider(providerUsed, cfg)) {
|
||||
const cliSessionId = result.meta.agentMeta?.sessionId?.trim();
|
||||
if (cliSessionId) {
|
||||
@ -105,9 +112,13 @@ export async function updateSessionStoreAfterAgentRun(params: {
|
||||
if (typeof totalTokens === "number" && Number.isFinite(totalTokens) && totalTokens > 0) {
|
||||
next.totalTokens = totalTokens;
|
||||
next.totalTokensFresh = true;
|
||||
next.totalTokensEstimate = totalTokens;
|
||||
} else {
|
||||
next.totalTokens = undefined;
|
||||
next.totalTokensFresh = false;
|
||||
if (typeof totalTokens === "number" && Number.isFinite(totalTokens)) {
|
||||
next.totalTokensEstimate = totalTokens;
|
||||
}
|
||||
}
|
||||
next.cacheRead = usage.cacheRead ?? 0;
|
||||
next.cacheWrite = usage.cacheWrite ?? 0;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { resolveTotalTokens } from "../shared/subagents-format.js";
|
||||
import { resolveQueueSettings } from "../auto-reply/reply/queue.js";
|
||||
import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../auto-reply/tokens.js";
|
||||
import { DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH } from "../config/agent-limits.js";
|
||||
@ -550,7 +551,7 @@ async function buildCompactAnnounceStatsLine(params: {
|
||||
const input = typeof entry?.inputTokens === "number" ? entry.inputTokens : 0;
|
||||
const output = typeof entry?.outputTokens === "number" ? entry.outputTokens : 0;
|
||||
const ioTotal = input + output;
|
||||
const promptCache = typeof entry?.totalTokens === "number" ? entry.totalTokens : undefined;
|
||||
const promptCache = resolveTotalTokens(entry as any);
|
||||
const runtimeMs =
|
||||
typeof params.startedAt === "number" && typeof params.endedAt === "number"
|
||||
? Math.max(0, params.endedAt - params.startedAt)
|
||||
|
||||
@ -4,7 +4,10 @@ import {
|
||||
resolveBootstrapTotalMaxChars,
|
||||
} from "../../agents/pi-embedded-helpers.js";
|
||||
import { buildSystemPromptReport } from "../../agents/system-prompt-report.js";
|
||||
import type { SessionSystemPromptReport } from "../../config/sessions/types.js";
|
||||
import {
|
||||
resolveFreshSessionTotalTokens,
|
||||
type SessionSystemPromptReport,
|
||||
} from "../../config/sessions/types.js";
|
||||
import type { ReplyPayload } from "../types.js";
|
||||
import { resolveCommandsSystemPromptBundle } from "./commands-system-prompt.js";
|
||||
import type { HandleCommandsParams } from "./commands-types.js";
|
||||
@ -96,8 +99,10 @@ export async function buildContextReply(params: HandleCommandsParams): Promise<R
|
||||
}
|
||||
|
||||
const report = await resolveContextReport(params);
|
||||
const totalTokens = resolveFreshSessionTotalTokens(params.sessionEntry);
|
||||
const session = {
|
||||
totalTokens: params.sessionEntry?.totalTokens ?? null,
|
||||
totalTokens: totalTokens ?? null,
|
||||
totalTokensFresh: params.sessionEntry?.totalTokensFresh ?? false,
|
||||
inputTokens: params.sessionEntry?.inputTokens ?? null,
|
||||
outputTokens: params.sessionEntry?.outputTokens ?? null,
|
||||
contextTokens: params.contextTokens ?? null,
|
||||
|
||||
@ -20,6 +20,7 @@ import {
|
||||
resolveThreadFlag,
|
||||
resolveSessionResetPolicy,
|
||||
resolveSessionResetType,
|
||||
resolveFreshSessionTotalTokens,
|
||||
resolveGroupSessionKey,
|
||||
resolveSessionKey,
|
||||
resolveSessionTranscriptPath,
|
||||
@ -478,7 +479,7 @@ export async function initSessionState(params: {
|
||||
sessionStore[parentSessionKey] &&
|
||||
!alreadyForked
|
||||
) {
|
||||
const parentTokens = sessionStore[parentSessionKey].totalTokens ?? 0;
|
||||
const parentTokens = resolveFreshSessionTotalTokens(sessionStore[parentSessionKey]) ?? 0;
|
||||
if (parentForkMaxTokens > 0 && parentTokens > parentForkMaxTokens) {
|
||||
// Parent context is too large — forking would create a thread session
|
||||
// that immediately overflows the model's context window. Start fresh
|
||||
|
||||
@ -14,6 +14,7 @@ import { resolveChannelModelOverride } from "../channels/model-overrides.js";
|
||||
import { isCommandFlagEnabled } from "../config/commands.js";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
resolveFreshSessionTotalTokens,
|
||||
resolveMainSessionKey,
|
||||
resolveSessionFilePath,
|
||||
resolveSessionFilePathOptions,
|
||||
@ -460,7 +461,7 @@ export function buildStatusMessage(args: StatusArgs): string {
|
||||
let outputTokens = entry?.outputTokens;
|
||||
let cacheRead = entry?.cacheRead;
|
||||
let cacheWrite = entry?.cacheWrite;
|
||||
let totalTokens = entry?.totalTokens ?? (entry?.inputTokens ?? 0) + (entry?.outputTokens ?? 0);
|
||||
let totalTokens = resolveFreshSessionTotalTokens(entry) ?? (entry?.inputTokens ?? 0) + (entry?.outputTokens ?? 0);
|
||||
|
||||
// Prefer prompt-size tokens from the session transcript when it looks larger
|
||||
// (cached prompt tokens are often missing from agent meta/store).
|
||||
|
||||
@ -142,6 +142,11 @@ export type SessionEntry = {
|
||||
inputTokens?: number;
|
||||
outputTokens?: number;
|
||||
totalTokens?: number;
|
||||
/**
|
||||
* Last known total tokens (including summaries), used for display when
|
||||
* a fresh model-reported count is unavailable.
|
||||
*/
|
||||
totalTokensEstimate?: number;
|
||||
/**
|
||||
* Whether totalTokens reflects a fresh context snapshot for the latest run.
|
||||
* Undefined means legacy/unknown freshness; false forces consumers to treat
|
||||
|
||||
@ -752,10 +752,19 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
lookupContextTokens(modelUsed, { allowAsyncLoad: false }) ??
|
||||
DEFAULT_CONTEXT_TOKENS;
|
||||
|
||||
const modelChanged =
|
||||
(cronSession.sessionEntry.model !== undefined &&
|
||||
cronSession.sessionEntry.model !== modelUsed) ||
|
||||
(cronSession.sessionEntry.modelProvider !== undefined &&
|
||||
cronSession.sessionEntry.modelProvider !== providerUsed);
|
||||
setSessionRuntimeModel(cronSession.sessionEntry, {
|
||||
provider: providerUsed,
|
||||
model: modelUsed,
|
||||
});
|
||||
if (modelChanged) {
|
||||
cronSession.sessionEntry.totalTokens = undefined;
|
||||
cronSession.sessionEntry.totalTokensFresh = false;
|
||||
}
|
||||
cronSession.sessionEntry.contextTokens = contextTokens;
|
||||
if (isCliProvider(providerUsed, cfgWithAgentDefaults)) {
|
||||
const cliSessionId = finalRunResult.meta?.agentMeta?.sessionId?.trim();
|
||||
@ -790,10 +799,14 @@ export async function runCronIsolatedAgentTurn(params: {
|
||||
if (typeof totalTokens === "number" && Number.isFinite(totalTokens) && totalTokens > 0) {
|
||||
cronSession.sessionEntry.totalTokens = totalTokens;
|
||||
cronSession.sessionEntry.totalTokensFresh = true;
|
||||
cronSession.sessionEntry.totalTokensEstimate = totalTokens;
|
||||
telemetryUsage.total_tokens = totalTokens;
|
||||
} else {
|
||||
cronSession.sessionEntry.totalTokens = undefined;
|
||||
cronSession.sessionEntry.totalTokensFresh = false;
|
||||
if (typeof totalTokens === "number" && Number.isFinite(totalTokens)) {
|
||||
cronSession.sessionEntry.totalTokensEstimate = totalTokens;
|
||||
}
|
||||
}
|
||||
cronSession.sessionEntry.cacheRead = usage.cacheRead ?? 0;
|
||||
cronSession.sessionEntry.cacheWrite = usage.cacheWrite ?? 0;
|
||||
|
||||
@ -42,6 +42,7 @@ export function truncateLine(value: string, maxLength: number) {
|
||||
|
||||
export type TokenUsageLike = {
|
||||
totalTokens?: unknown;
|
||||
totalTokensFresh?: unknown;
|
||||
inputTokens?: unknown;
|
||||
outputTokens?: unknown;
|
||||
};
|
||||
@ -50,7 +51,11 @@ export function resolveTotalTokens(entry?: TokenUsageLike) {
|
||||
if (!entry || typeof entry !== "object") {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof entry.totalTokens === "number" && Number.isFinite(entry.totalTokens)) {
|
||||
if (
|
||||
entry.totalTokensFresh !== false &&
|
||||
typeof entry.totalTokens === "number" &&
|
||||
Number.isFinite(entry.totalTokens)
|
||||
) {
|
||||
return entry.totalTokens;
|
||||
}
|
||||
const input = typeof entry.inputTokens === "number" ? entry.inputTokens : 0;
|
||||
|
||||
@ -48,6 +48,7 @@ export type SessionInfo = {
|
||||
inputTokens?: number | null;
|
||||
outputTokens?: number | null;
|
||||
totalTokens?: number | null;
|
||||
totalTokensEstimate?: number | null;
|
||||
responseUsage?: ResponseUsageMode;
|
||||
updatedAt?: number | null;
|
||||
displayName?: string;
|
||||
@ -91,6 +92,7 @@ export type GatewayStatusSummary = {
|
||||
age?: number | null;
|
||||
model?: string | null;
|
||||
totalTokens?: number | null;
|
||||
totalTokensEstimate?: number | null;
|
||||
contextTokens?: number | null;
|
||||
remainingTokens?: number | null;
|
||||
percentUsed?: number | null;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user