惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - 聂微东
F
Fortinet All Blogs
H
Help Net Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
D
DataBreaches.Net
MyScale Blog
MyScale Blog
B
Blog
I
InfoQ
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
GbyAI
GbyAI
Google DeepMind News
Google DeepMind News
IT之家
IT之家
The GitHub Blog
The GitHub Blog
有赞技术团队
有赞技术团队
博客园_首页
L
LangChain Blog
V
V2EX
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
T
The Blog of Author Tim Ferriss
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - Franky

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
feat(hooks): per-turn usageState (with provider limits + ...
Peetiegonzal · 2026-06-13 · via Recent Commits to openclaw:main

@@ -15,6 +15,7 @@ import {

1515

formatEmbeddedAgentQueueFailureSummary,

1616

queueEmbeddedAgentMessageWithOutcomeAsync,

1717

} from "../../agents/embedded-agent-runner/runs.js";

18+

import { resolveFastModeState } from "../../agents/fast-mode.js";

1819

import { resolveModelAuthMode } from "../../agents/model-auth.js";

1920

import { isCliProvider } from "../../agents/model-selection.js";

2021

import { deriveContextPromptTokens, hasNonzeroUsage, normalizeUsage } from "../../agents/usage.js";

@@ -39,6 +40,8 @@ import {

3940

freezeDiagnosticTraceContext,

4041

} from "../../infra/diagnostic-trace-context.js";

4142

import { measureDiagnosticsTimelineSpan } from "../../infra/diagnostics-timeline.js";

43+

import { getProviderUsageLimitsCached } from "../../infra/provider-usage.limits.js";

44+

import { resolveAgentIdentity } from "../../agents/identity.js";

4245

import { enqueueSystemEvent } from "../../infra/system-events.js";

4346

import { CommandLaneClearedError, GatewayDrainingError } from "../../process/command-queue.js";

4447

import { shouldPreserveUserFacingSessionStateForInputProvenance } from "../../sessions/input-provenance.js";

@@ -117,6 +120,7 @@ import { createReplyMediaContext } from "./reply-media-paths.js";

117120

import { replyRunRegistry, type ReplyOperation } from "./reply-run-registry.js";

118121

import { createReplyToModeFilterForChannel, resolveReplyToMode } from "./reply-threading.js";

119122

import { admitReplyTurn, resolveReplyTurnKind } from "./reply-turn-admission.js";

123+

import { recordReplyUsageState } from "./reply-usage-state.js";

120124

import { resolveRoutedDeliveryThreadId } from "./routed-delivery-thread.js";

121125

import { incrementRunCompactionCount, persistRunSessionUsage } from "./session-run-accounting.js";

122126

import { resolveSourceReplyVisibilityPolicy } from "./source-reply-delivery-mode.js";

@@ -1735,6 +1739,74 @@ export async function runReplyAgent(params: {

17351739

const modelUsed = runResult.meta?.agentMeta?.model ?? fallbackModel ?? defaultModel;

17361740

const providerUsed =

17371741

runResult.meta?.agentMeta?.provider ?? fallbackProvider ?? followupRun.run.provider;

1742+1743+

// Hand the turn's execution state to the reply_payload_sending hook (harness-

1744+

// agnostic: every harness produces runResult.meta). A footer/readout plugin

1745+

// reads it at deliver time, correlated by runId/sessionKey.

1746+

{

1747+

const winnerProvider = runResult.meta?.executionTrace?.winnerProvider ?? providerUsed;

1748+

const winnerModel = runResult.meta?.executionTrace?.winnerModel ?? modelUsed;

1749+

const ctxTokens = runResult.meta?.agentMeta?.contextTokens;

1750+

const compactions = runResult.meta?.agentMeta?.compactionCount;

1751+

recordReplyUsageState(

1752+

{ runId, sessionKey },

1753+

{

1754+

provider: providerUsed,

1755+

model: modelUsed,

1756+

resolvedRef:

1757+

winnerProvider && winnerModel ? `${winnerProvider}/${winnerModel}` : undefined,

1758+

reasoningEffort:

1759+

typeof followupRun.run.thinkLevel === "string" ? followupRun.run.thinkLevel : undefined,

1760+

fastMode: resolveFastModeState({

1761+

cfg,

1762+

provider: providerUsed ?? "",

1763+

model: modelUsed ?? "",

1764+

agentId: followupRun.run.agentId,

1765+

sessionEntry: activeSessionEntry,

1766+

}).enabled,

1767+

fallbackUsed: runResult.meta?.executionTrace?.fallbackUsed === true,

1768+

// Richer per-turn atoms for usage rendering (/usage + plugins).

1769+

agentId: followupRun.run.agentId,

1770+

sessionId: followupRun.run.sessionId,

1771+

chatType: typeof sessionCtx.ChatType === "string" ? sessionCtx.ChatType : undefined,

1772+

authMode: runResult.meta?.requestShaping?.authMode ?? undefined,

1773+

overrideSource: activeSessionEntry?.modelOverrideSource ?? undefined,

1774+

requested:

1775+

followupRun.run.provider && followupRun.run.model

1776+

? `${followupRun.run.provider}/${followupRun.run.model}`

1777+

: undefined,

1778+

turnUsd: usage

1779+

? estimateUsageCost({

1780+

usage,

1781+

cost: resolveModelCostConfig({

1782+

provider: providerUsed,

1783+

model: modelUsed,

1784+

config: cfg,

1785+

}),

1786+

})

1787+

: undefined,

1788+

durationMs: Date.now() - runStartedAt,

1789+

identity: resolveAgentIdentity(cfg, followupRun.run.agentId),

1790+

compactionCount: typeof compactions === "number" ? compactions : undefined,

1791+

contextTokenBudget:

1792+

typeof ctxTokens === "number" && Number.isFinite(ctxTokens) ? ctxTokens : undefined,

1793+

usage: usage

1794+

? {

1795+

input: usage.input,

1796+

output: usage.output,

1797+

cacheRead: usage.cacheRead,

1798+

cacheWrite: usage.cacheWrite,

1799+

total: usage.total,

1800+

}

1801+

: undefined,

1802+

// Provider subscription/limit windows for the 📊 readout. Non-blocking

1803+

// (stale-while-revalidate): returns cached windows or undefined on a

1804+

// cold cache and refreshes in the background, so it never delays the

1805+

// reply. Undefined for api-key / unmapped providers.

1806+

limits: getProviderUsageLimitsCached(providerUsed),

1807+

},

1808+

);

1809+

}

17381810

const verboseEnabled = resolvedVerboseLevel !== "off";

17391811

const preserveUserFacingSessionState = shouldPreserveUserFacingSessionStateForInputProvenance(

17401812

followupRun.run.inputProvenance,