Skip to content

Commit 0d0632d

Browse files
committed
docs: document agent runtime utility helpers
1 parent 2e89655 commit 0d0632d

5 files changed

Lines changed: 28 additions & 8 deletions

src/agents/content-blocks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Collects text block payloads from provider-style structured content arrays. */
12
export function collectTextContentBlocks(content: unknown): string[] {
23
if (!Array.isArray(content)) {
34
return [];

src/agents/embedded-agent-subscribe.handlers.compaction.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ type CompactionEndEvent =
2525
aborted?: unknown;
2626
};
2727

28+
// Unknown reasons come from external runtimes or older sessions. Treat them as
29+
// threshold compaction so logs and event payloads stay on the closed reason set.
2830
function normalizeCompactionReason(reason: unknown): CompactionReason {
2931
return reason === "manual" || reason === "threshold" || reason === "overflow"
3032
? reason
@@ -35,6 +37,7 @@ function compactionLogKind(reason: CompactionReason): string {
3537
return reason === "manual" ? "manual compaction" : "auto-compaction";
3638
}
3739

40+
/** Handles compaction start events from an embedded agent session. */
3841
export function handleCompactionStart(
3942
ctx: EmbeddedAgentSubscribeContext,
4043
evt: CompactionStartEvent,
@@ -60,7 +63,8 @@ export function handleCompactionStart(
6063
data: { phase: "start" },
6164
});
6265

63-
// Run before_compaction plugin hook (fire-and-forget)
66+
// Hooks are fire-and-forget so compaction state updates and liveness pauses
67+
// cannot be delayed by plugin work.
6468
const hookRunner = getGlobalHookRunner();
6569
if (hookRunner?.hasHooks("before_compaction")) {
6670
void hookRunner
@@ -80,15 +84,15 @@ export function handleCompactionStart(
8084
}
8185
}
8286

87+
/** Handles compaction completion, retry, and incomplete events. */
8388
export function handleCompactionEnd(ctx: EmbeddedAgentSubscribeContext, evt: CompactionEndEvent) {
8489
const reason = normalizeCompactionReason(evt.reason);
8590
const kind = compactionLogKind(reason);
8691
ctx.state.compactionInFlight = false;
8792
const willRetry = Boolean(evt.willRetry);
88-
// Increment counter whenever compaction actually produced a result,
89-
// regardless of willRetry. Overflow-triggered compaction sets willRetry=true
90-
// (the framework retries the LLM request), but the compaction itself succeeded
91-
// and context was trimmed — the counter must reflect that. (#38905)
93+
// Increment counter whenever compaction actually produced a result, regardless
94+
// of willRetry. Overflow-triggered compaction retries the LLM request after
95+
// trimming context, and the persisted count must reflect that successful trim.
9296
const hasResult = evt.result != null;
9397
const wasAborted = Boolean(evt.aborted);
9498
if (hasResult && !wasAborted) {
@@ -149,7 +153,8 @@ export function handleCompactionEnd(ctx: EmbeddedAgentSubscribeContext, evt: Com
149153
data: { phase: "end", willRetry, completed: hasResult && !wasAborted },
150154
});
151155

152-
// Run after_compaction plugin hook (fire-and-forget)
156+
// after_compaction runs only once the run will not retry, matching the visible
157+
// post-compaction session state plugin authors observe.
153158
if (!willRetry) {
154159
const hookRunnerEnd = getGlobalHookRunner();
155160
if (hookRunnerEnd?.hasHooks("after_compaction")) {
@@ -169,6 +174,7 @@ export function handleCompactionEnd(ctx: EmbeddedAgentSubscribeContext, evt: Com
169174
}
170175
}
171176

177+
/** Lazily reconciles persisted compaction count after a successful compaction. */
172178
export async function reconcileSessionStoreCompactionCountAfterSuccess(params: {
173179
sessionKey?: string;
174180
agentId?: string;
@@ -181,6 +187,8 @@ export async function reconcileSessionStoreCompactionCountAfterSuccess(params: {
181187
return reconcile(params);
182188
}
183189

190+
// Compaction rewrites history, so assistant usage snapshots can refer to the
191+
// old context. Keep the usage field shape but zero it for fresh accounting.
184192
function clearStaleAssistantUsageOnSessionMessages(ctx: EmbeddedAgentSubscribeContext): void {
185193
const messages = ctx.params.session.messages;
186194
if (!Array.isArray(messages)) {
@@ -194,8 +202,6 @@ function clearStaleAssistantUsageOnSessionMessages(ctx: EmbeddedAgentSubscribeCo
194202
if (candidate.role !== "assistant") {
195203
continue;
196204
}
197-
// session runtime expects assistant usage to exist when computing context usage.
198-
// Reset stale snapshots to zeros instead of deleting the field.
199205
candidate.usage = makeZeroUsageSnapshot();
200206
}
201207
}

src/agents/local-model-lean.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import { resolveAgentConfig, resolveDefaultAgentId } from "./agent-scope-config.
44
import type { AnyAgentTool } from "./agent-tools.types.js";
55
import { expandToolGroups, normalizeToolName } from "./tool-policy.js";
66

7+
// Local-model lean mode removes high-latency or channel-dependent tools unless
8+
// the caller explicitly preserves them for the current delivery path.
79
const LOCAL_MODEL_LEAN_DENY_TOOL_NAMES = new Set(["browser", "cron", "message"]);
810

11+
// Preserve lists accept tool groups; normalize them to concrete tool names so
12+
// filtering stays aligned with the normal tool-policy path.
913
function resolvePreservedLocalModelLeanToolNames(names?: Iterable<string>): Set<string> {
1014
if (!names) {
1115
return new Set();
@@ -17,6 +21,7 @@ function resolvePreservedLocalModelLeanToolNames(names?: Iterable<string>): Set<
1721
);
1822
}
1923

24+
/** Resolves tool names that must survive local-model lean filtering. */
2025
export function resolveLocalModelLeanPreserveToolNames(params?: {
2126
toolNames?: Iterable<string>;
2227
forceMessageTool?: boolean;
@@ -29,6 +34,8 @@ export function resolveLocalModelLeanPreserveToolNames(params?: {
2934
return [...new Set(names)];
3035
}
3136

37+
// Agent id may arrive explicitly, through the session key, or via config default.
38+
// Resolve once so default/agent experimental flags use the same scope.
3239
function resolveLocalModelLeanAgentId(params: {
3340
config?: OpenClawConfig;
3441
agentId?: string;
@@ -48,6 +55,7 @@ function resolveLocalModelLeanAgentId(params: {
4855
return params.config ? resolveDefaultAgentId(params.config) : undefined;
4956
}
5057

58+
/** Returns true when local-model lean mode is enabled for the selected agent. */
5159
export function isLocalModelLeanEnabled(params: {
5260
config?: OpenClawConfig;
5361
agentId?: string;
@@ -62,6 +70,7 @@ export function isLocalModelLeanEnabled(params: {
6270
return resolvedExperimental?.localModelLean ?? false;
6371
}
6472

73+
/** Filters tools for local-model lean mode while preserving required delivery tools. */
6574
export function filterLocalModelLeanTools(params: {
6675
tools: AnyAgentTool[];
6776
config?: OpenClawConfig;

src/agents/provider-model-normalization.runtime.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ type ProviderRuntimeModule = Pick<
66
>;
77

88
const require = createRequire(import.meta.url);
9+
// Built code loads .js while source/test paths may still resolve .ts. Try both
10+
// once, then cache the absence to avoid repeated require work on hot paths.
911
const PROVIDER_RUNTIME_CANDIDATES = [
1012
"../plugins/provider-runtime.js",
1113
"../plugins/provider-runtime.ts",
@@ -33,6 +35,7 @@ function loadProviderRuntime(): ProviderRuntimeModule | null {
3335
return null;
3436
}
3537

38+
/** Normalizes provider model ids through plugin runtime hooks when available. */
3639
export function normalizeProviderModelIdWithRuntime(params: {
3740
provider: string;
3841
context: {

src/agents/subagent-session-cleanup.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { SpawnSubagentMode } from "./subagent-spawn.types.js";
33

44
type CallGateway = typeof defaultCallGateway;
55

6+
/** Deletes a child subagent session and optionally emits session-mode lifecycle hooks. */
67
export async function deleteSubagentSessionForCleanup(params: {
78
callGateway: CallGateway;
89
childSessionKey: string;

0 commit comments

Comments
 (0)