refactor(deadcode): trim mid-size src exports (#105888)

* refactor(deadcode): trim auto-reply and CLI exports

* refactor(deadcode): trim cron and task exports

* refactor(deadcode): trim fleet and process exports

* test(deadcode): exercise live task and process seams

* test(fleet): cover stream redaction through owner module

* refactor(security): trim dead internal exports

* refactor(secrets): trim dead internal exports

* refactor(deadcode): trim remaining src exports

* refactor(deadcode): remove test-only runtime exports

* refactor(deadcode): trim pairing test exports

* refactor(deadcode): reconcile refreshed baseline

* test(auto-reply): deduplicate queue state imports
This commit is contained in:
Peter Steinberger
2026-07-13 00:42:56 -07:00
committed by GitHub
parent 0ab7e2569b
commit e2ec8283c4
406 changed files with 798 additions and 2360 deletions
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -6,7 +6,7 @@ import { expect } from "vitest";
import { toAcpRuntimeError } from "./errors.js";
/** Inputs and optional assertions for the shared ACP runtime adapter contract. */
export type AcpRuntimeAdapterContractParams = {
type AcpRuntimeAdapterContractParams = {
createRuntime: () => Promise<AcpRuntime> | AcpRuntime;
agentId?: string;
successPrompt?: string;
+1 -1
View File
@@ -73,7 +73,7 @@ function resolveStoreSessionKey(
}
/** Resolves the session store path that owns an ACP session key. */
export function resolveSessionStorePathForAcp(params: {
function resolveSessionStorePathForAcp(params: {
sessionKey: string;
cfg?: OpenClawConfig;
env?: NodeJS.ProcessEnv;
@@ -9,11 +9,9 @@ import os from "node:os";
import path from "node:path";
import { completeSimple, type Model } from "openclaw/plugin-sdk/llm";
import { describe, expect, it } from "vitest";
import {
ANTHROPIC_SETUP_TOKEN_PREFIX,
validateAnthropicSetupToken,
} from "../commands/auth-token.js";
import { validateAnthropicSetupToken } from "../commands/auth-token.js";
import { getRuntimeConfig } from "../config/config.js";
import { ANTHROPIC_SETUP_TOKEN_PREFIX } from "../plugins/provider-auth-token.js";
import { discoverAuthStorage, discoverModels } from "./agent-model-discovery.js";
import { resolveDefaultAgentDir } from "./agent-scope.js";
import {
@@ -8,7 +8,8 @@ import os from "node:os";
import path from "node:path";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { createTempDirTracker } from "../../test/helpers/temp-dir.js";
import type { ProcessSupervisor, SpawnInput } from "../process/supervisor/index.js";
import type { ProcessSupervisor } from "../process/supervisor/index.js";
import type { SpawnInput } from "../process/supervisor/types.js";
import { captureEnv } from "../test-utils/env.js";
import { resetProcessRegistryForTests } from "./bash-process-registry.js";
import { createExecTool } from "./bash-tools.exec.js";
@@ -10,7 +10,8 @@ import {
type DiagnosticExecProcessCompletedEvent,
type DiagnosticEventPayload,
} from "../infra/diagnostic-events.js";
import type { ManagedRun, SpawnInput } from "../process/supervisor/index.js";
import type { ManagedRun } from "../process/supervisor/index.js";
import type { SpawnInput } from "../process/supervisor/types.js";
let listRunningSessions: typeof import("./bash-process-registry.js").listRunningSessions;
let resetProcessRegistryForTests: typeof import("./bash-process-registry.js").resetProcessRegistryForTests;
@@ -6,7 +6,7 @@ import {
createMoonshotThinkingWrapper,
resolveMoonshotThinkingKeep,
resolveMoonshotThinkingType,
} from "../llm/providers/stream-wrappers/moonshot.js";
} from "../llm/providers/stream-wrappers/moonshot-thinking.js";
import { runExtraParamsPayloadCase } from "./embedded-agent-runner-extraparams.test-support.js";
import { testing as extraParamsTesting } from "./embedded-agent-runner/extra-params.js";
@@ -11,10 +11,8 @@ import { createMockPluginRegistry } from "openclaw/plugin-sdk/plugin-test-runtim
import { afterEach, describe, expect, it } from "vitest";
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import {
attachRuntimeUserTurnTranscriptContext,
createUserTurnTranscriptRecorder,
} from "../sessions/user-turn-transcript.js";
import { attachRuntimeUserTurnTranscriptContext } from "../sessions/user-turn-transcript-runtime-context.js";
import { createUserTurnTranscriptRecorder } from "../sessions/user-turn-transcript.js";
import { createTestUserTurnTranscriptTarget } from "../sessions/user-turn-transcript.test-support.js";
import { guardSessionManager } from "./session-tool-result-guard-wrapper.js";
import { sanitizeToolUseResultPairing } from "./session-transcript-repair.js";
@@ -4,7 +4,8 @@ import {
completeTaskRunByRunId,
createRunningTaskRun,
} from "../../../tasks/detached-task-runtime.js";
import { resetTaskRegistryForTests, type TaskRecord } from "../../../tasks/runtime-internal.js";
import type { TaskRecord } from "../../../tasks/runtime-internal.js";
import { resetTaskRegistryForTests } from "../../../tasks/task-registry.js";
import {
requiresCompletionRequiredAsyncTaskWait,
shouldWaitForCompletionRequiredAsyncTasks,
+2 -1
View File
@@ -4,7 +4,8 @@ import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { AVATAR_MAX_BYTES, AVATAR_MAX_DATA_URL_CHARS } from "../shared/avatar-policy.js";
import { AVATAR_MAX_DATA_URL_CHARS } from "../shared/avatar-limits.js";
import { AVATAR_MAX_BYTES } from "../shared/avatar-policy.js";
import {
openLocalAgentAvatarFile,
readOpenedLocalAgentAvatarDataUrl,
+2 -1
View File
@@ -4,7 +4,8 @@ import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import { AVATAR_MAX_BYTES, AVATAR_MAX_DATA_URL_CHARS } from "../shared/avatar-policy.js";
import { AVATAR_MAX_DATA_URL_CHARS } from "../shared/avatar-limits.js";
import { AVATAR_MAX_BYTES } from "../shared/avatar-policy.js";
import { resolveAgentAvatar, resolvePublicAgentAvatarSource } from "./identity-avatar.js";
async function writeFile(filePath: string, contents = "avatar") {
+2 -4
View File
@@ -4,10 +4,7 @@ import { createAssistantMessageEventStream, type AssistantMessage } from "opencl
import { Type } from "typebox";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { Model, SimpleStreamOptions } from "../../llm/types.js";
import {
createUserTurnTranscriptRecorder,
takeRuntimeUserTurnTranscriptContext,
} from "../../sessions/user-turn-transcript.js";
import { createUserTurnTranscriptRecorder } from "../../sessions/user-turn-transcript.js";
import { createTestUserTurnTranscriptTarget } from "../../sessions/user-turn-transcript.test-support.js";
const thinkingMocks = vi.hoisted(() => ({
@@ -23,6 +20,7 @@ vi.mock("../../auto-reply/thinking.js", () => ({
vi.mock("../../llm/stream.js", () => ({
streamSimple: streamMocks.streamSimple,
}));
import { takeRuntimeUserTurnTranscriptContext } from "../../sessions/user-turn-transcript-runtime-context.js";
import { AuthStorage } from "./auth-storage.js";
import { createExtensionRuntime } from "./extensions/loader.js";
import type { LoadExtensionsResult, ToolDefinition } from "./extensions/types.js";
+5 -5
View File
@@ -2,9 +2,9 @@
export const AUDIT_EVENT_SCHEMA_VERSION = 1 as const;
export type AuditEventKind = "agent_run" | "tool_action" | "message";
type AuditEventKind = "agent_run" | "tool_action" | "message";
export type AuditEventStatus =
type AuditEventStatus =
| "started"
| "succeeded"
| "failed"
@@ -13,7 +13,7 @@ export type AuditEventStatus =
| "blocked"
| "unknown";
export type AuditMessageDirection = "inbound" | "outbound";
type AuditMessageDirection = "inbound" | "outbound";
export type AuditMessageConversationKind = "direct" | "group" | "channel" | "unknown";
export type AuditMessageDeliveryKind = "text" | "media" | "other";
export type AuditMessageFailureStage = "platform_send" | "queue" | "unknown";
@@ -41,7 +41,7 @@ export const AUDIT_INBOUND_MESSAGE_SKIPPED_REASONS = [
export type AuditInboundMessageSkippedReasonCode =
(typeof AUDIT_INBOUND_MESSAGE_SKIPPED_REASONS)[number];
export type AuditInboundMessageFailureReasonCode = "acp_dispatch_failed" | "plugin_bound_error";
type AuditInboundMessageFailureReasonCode = "acp_dispatch_failed" | "plugin_bound_error";
export const AUDIT_OUTBOUND_MESSAGE_SUPPRESSED_REASONS = [
"cancelled_by_message_sending_hook",
@@ -85,7 +85,7 @@ export type AgentRunAuditEventInput = AuditEventInputBase &
AgentAuditAttribution &
AgentRunAuditLifecycle & { kind: "agent_run" };
export type ToolActionFinishedAuditTerminal =
type ToolActionFinishedAuditTerminal =
| { status: "succeeded"; errorCode?: never }
| { status: "failed"; errorCode: "tool_failed" }
| { status: "cancelled"; errorCode: "tool_cancelled" }
+2 -2
View File
@@ -29,12 +29,12 @@ const AUDIT_IDENTITY_DOMAIN = "openclaw.audit.identity.v1";
// around a nested creation would leave a cached key that was never persisted.
const identityByDatabase = new WeakMap<DatabaseSync, AuditIdentityKey>();
export type AuditIdentityKey = {
type AuditIdentityKey = {
keyId: string;
key: Uint8Array;
};
export type AuditIdentityKind = "account" | "actor" | "conversation" | "message" | "target";
type AuditIdentityKind = "account" | "actor" | "conversation" | "message" | "target";
function registerAuditIdentityKeyForRedaction(key: Uint8Array): void {
const bytes = Buffer.from(key);
+1 -1
View File
@@ -12,7 +12,7 @@ import type { TrustedMessageAuditEvent } from "./message-audit-events.js";
const log = createSubsystemLogger("audit/events");
let persistenceFailureWarned = false;
export type AuditEventRecorder = AgentEventAuditRecorder & {
type AuditEventRecorder = AgentEventAuditRecorder & {
recordMessage: (event: TrustedMessageAuditEvent) => void;
};
+2 -1
View File
@@ -4,7 +4,8 @@ import type { OpenClawConfig } from "../config/config.js";
import { onDiagnosticEvent, resetDiagnosticEventsForTest } from "../infra/diagnostic-events.js";
import { registerReplyDispatcherSettledTask } from "./dispatch-dispatcher.js";
import { getReplyPayloadMetadata, setReplyPayloadMetadata } from "./reply-payload.js";
import type { ReplyDispatchBeforeDeliver, ReplyDispatcher } from "./reply/reply-dispatcher.js";
import type { ReplyDispatchBeforeDeliver } from "./reply/reply-dispatcher.js";
import type { ReplyDispatcher } from "./reply/reply-dispatcher.types.js";
import { buildTestCtx } from "./reply/test-ctx.js";
type DispatchReplyFromConfigFn =
+1 -1
View File
@@ -467,7 +467,7 @@ function buildDispatchTimelineAttributes(ctx: MsgContext | FinalizedMsgContext)
};
}
export type DispatchInboundResult = DispatchFromConfigResult;
type DispatchInboundResult = DispatchFromConfigResult;
export { settleReplyDispatcher, withReplyDispatcher } from "./dispatch-dispatcher.js";
function finalizeDispatchResult(
+2 -3
View File
@@ -2,11 +2,10 @@
import { afterEach, describe, expect, it } from "vitest";
import { testing as cliBackendsTesting } from "../agents/cli-backends.js";
import {
buildFallbackNotice,
resolveActiveFallbackState,
resolveFallbackTransition,
type FallbackNoticeState,
} from "./fallback-state.js";
} from "../status/fallback-notice-state.js";
import { buildFallbackNotice, resolveFallbackTransition } from "./fallback-state.js";
const baseAttempt = {
provider: "demo-primary",
-5
View File
@@ -8,11 +8,6 @@ import type { FallbackNoticeState } from "../status/fallback-notice-state.js";
import { formatProviderModelRef } from "./model-runtime.js";
import type { RuntimeFallbackAttempt } from "./reply/agent-runner-execution.js";
export {
resolveActiveFallbackState,
type FallbackNoticeState,
} from "../status/fallback-notice-state.js";
const FALLBACK_REASON_PART_MAX = 80;
const TRANSIENT_FALLBACK_REASONS = new Set([
"rate_limit",
+1 -1
View File
@@ -73,7 +73,7 @@ export type ReplyPayload = {
// through Plugin SDK; this is not a third-party plugin contract.
const PAIRING_QR_REPLY_CHANNEL_DATA_KEY = "openclawPairingQr";
export type PairingQrReplyChannelData = {
type PairingQrReplyChannelData = {
setupCode: string;
expiresAtMs: number;
};
-11
View File
@@ -1,13 +1,2 @@
// Public auto-reply API barrel for directives and reply execution.
export {
extractElevatedDirective,
extractReasoningDirective,
extractTraceDirective,
extractThinkDirective,
extractVerboseDirective,
} from "./reply/directives.js";
export { getReplyFromConfig } from "./reply/get-reply.js";
export { extractExecDirective } from "./reply/exec.js";
export { extractQueueDirective } from "./reply/queue.js";
export { extractReplyToTag } from "./reply/reply-tags.js";
export type { GetReplyOptions, ReplyPayload } from "./types.js";
+1 -2
View File
@@ -10,6 +10,7 @@ import {
type SessionAbortTargetResult,
} from "../../config/sessions/session-accessor.js";
import { createSuiteTempRootTracker } from "../../test-helpers/temp-dir.js";
import { resolveAbortCutoffFromContext, shouldSkipMessageByAbortCutoff } from "./abort-cutoff.js";
import {
testing as abortTesting,
formatAbortReplyText,
@@ -18,10 +19,8 @@ import {
isAbortRequestText,
isAbortTrigger,
resetAbortMemoryForTest,
resolveAbortCutoffFromContext,
setAbortMemory,
stopSubagentsForRequester,
shouldSkipMessageByAbortCutoff,
tryFastAbortFromMessage,
} from "./abort.js";
import { testing as acpResetTargetTesting } from "./acp-reset-target.js";
-2
View File
@@ -53,7 +53,6 @@ import { stripMentions, stripStructuralPrefixes } from "./mentions.js";
import { clearSessionQueues } from "./queue.js";
import { replyRunRegistry } from "./reply-run-registry.js";
export { resolveAbortCutoffFromContext, shouldSkipMessageByAbortCutoff } from "./abort-cutoff.js";
export {
getAbortMemory,
getAbortMemorySizeForTest,
@@ -521,4 +520,3 @@ export async function tryFastAbortFromMessage(params: {
const { stopped } = stopSubagentsForRequester({ cfg, requesterSessionKey });
return { handled: true, aborted: false, stoppedSubagents: stopped };
}
export { testing as __testing };
+1 -1
View File
@@ -366,7 +366,7 @@ function truncateMemoryFlushErrorMessage(err: unknown): string {
}
/** Usage snapshot read from a session transcript before compaction. */
export type SessionTranscriptUsageSnapshot = {
type SessionTranscriptUsageSnapshot = {
promptTokens?: number;
outputTokens?: number;
trailingBytesTokens?: number;
+4 -4
View File
@@ -56,7 +56,7 @@ export type AcpAction =
export type AcpSpawnThreadMode = "auto" | "here" | "off";
export type AcpSpawnBindMode = "here" | "off";
export type ParsedSpawnInput = {
type ParsedSpawnInput = {
agentId: string;
mode: AcpRuntimeSessionMode;
thread: AcpSpawnThreadMode;
@@ -65,17 +65,17 @@ export type ParsedSpawnInput = {
label?: string;
};
export type ParsedSteerInput = {
type ParsedSteerInput = {
sessionToken?: string;
instruction: string;
};
export type ParsedSingleValueCommandInput = {
type ParsedSingleValueCommandInput = {
value: string;
sessionToken?: string;
};
export type ParsedSetCommandInput = {
type ParsedSetCommandInput = {
key: string;
value: string;
sessionToken?: string;
-2
View File
@@ -22,8 +22,6 @@ import { buildStatusPluginsReply, buildStatusReply } from "./commands-status.js"
import type { CommandHandler, HandleCommandsParams } from "./commands-types.js";
import { extractExplicitGroupId } from "./group-id.js";
import { resolveReplyToMode } from "./reply-threading.js";
export { handleContextCommand } from "./commands-context-command.js";
export { handleWhoamiCommand } from "./commands-whoami.js";
async function resolveSkillCommands(
params: HandleCommandsParams,
+1 -1
View File
@@ -9,7 +9,7 @@ type SlashCommandParseResult =
| { kind: "parsed"; action: string; args: string };
/** Public slash-command parse result returned to command handlers. */
export type ParsedSlashCommand =
type ParsedSlashCommand =
| { ok: true; action: string; args: string }
| { ok: false; message: string };
@@ -2,7 +2,6 @@
export {
formatEmbeddedAgentQueueFailureSummary,
isEmbeddedAgentRunActive,
queueEmbeddedAgentMessage,
queueEmbeddedAgentMessageWithOutcomeAsync,
resolveActiveEmbeddedRunSessionId,
resolveActiveEmbeddedRunSessionIdBySessionFile,
@@ -3,7 +3,6 @@ import type { SubagentRunRecord } from "../../agents/subagent-registry.types.js"
import type { HandleCommandsParams } from "./commands-types.js";
export {
COMMAND,
resolveHandledPrefix,
resolveRequesterSessionKey,
resolveSubagentsAction,
@@ -10,13 +10,13 @@ import { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/c
import { resolveCommandAuthorization } from "../command-auth.js";
import type { MsgContext } from "../templating.js";
import {
COMMAND,
resolveHandledPrefix,
resolveRequesterSessionKey,
resolveSubagentsAction,
stopWithText,
} from "./commands-subagents-dispatch.js";
import { handleSubagentsCommand } from "./commands-subagents.js";
import { COMMAND } from "./commands-subagents/shared.js";
import type { HandleCommandsParams } from "./commands-types.js";
const listControlledSubagentRunsMock = vi.hoisted(() => vi.fn(() => []));
@@ -11,7 +11,7 @@ import {
import type { SessionEntry } from "../../config/sessions/types.js";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
export type ModelRuntimeDirectiveResolution =
type ModelRuntimeDirectiveResolution =
| { kind: "unchanged" }
| { kind: "clear" }
| { kind: "set"; runtime: string }
@@ -305,15 +305,16 @@ import type { ElevatedLevel } from "../thinking.js";
let handleDirectiveOnly: typeof import("./directive-handling.impl.js").handleDirectiveOnly;
let cliBackendsTesting: typeof import("../../agents/cli-backends.js").testing;
let maybeHandleModelDirectiveInfo: typeof import("./directive-handling.model.js").maybeHandleModelDirectiveInfo;
let resolveModelSelectionFromDirective: typeof import("./directive-handling.model.js").resolveModelSelectionFromDirective;
let resolveModelSelectionFromDirective: typeof import("./directive-handling.model-selection.js").resolveModelSelectionFromDirective;
let parseInlineDirectives: typeof import("./directive-handling.parse.js").parseInlineDirectives;
let persistInlineDirectives: typeof import("./directive-handling.persist.js").persistInlineDirectives;
beforeAll(async () => {
({ testing: cliBackendsTesting } = await import("../../agents/cli-backends.js"));
({ handleDirectiveOnly } = await import("./directive-handling.impl.js"));
({ maybeHandleModelDirectiveInfo, resolveModelSelectionFromDirective } =
await import("./directive-handling.model.js"));
({ maybeHandleModelDirectiveInfo } = await import("./directive-handling.model.js"));
({ resolveModelSelectionFromDirective } =
await import("./directive-handling.model-selection.js"));
({ parseInlineDirectives } = await import("./directive-handling.parse.js"));
({ persistInlineDirectives } = await import("./directive-handling.persist.js"));
});
@@ -32,7 +32,6 @@ import {
type ModelPickerCatalogEntry,
resolveProviderEndpointLabel,
} from "./directive-handling.model-picker.js";
export { resolveModelSelectionFromDirective } from "./directive-handling.model-selection.js";
import type { InlineDirectives } from "./directive-handling.parse.js";
function isMissingAuthLabel(auth: { label: string; source: string }): boolean {
@@ -9,7 +9,7 @@ import type { InlineDirectives } from "./directive-handling.parse.js";
import type { ElevatedLevel, ReasoningLevel, ThinkLevel, VerboseLevel } from "./directives.js";
/** Core directive handler inputs that do not depend on the inbound message shape. */
export type HandleDirectiveOnlyCoreParams = {
type HandleDirectiveOnlyCoreParams = {
cfg: OpenClawConfig;
directives: InlineDirectives;
sessionEntry: SessionEntry;
@@ -41,7 +41,7 @@ import { resolveContextTokens } from "./model-selection.js";
import { refreshQueuedFollowupSession } from "./queue.js";
import { persistReplySessionEntry } from "./session-entry-persistence.js";
export type PersistedThinkingLevelRemap = {
type PersistedThinkingLevelRemap = {
from: ThinkLevel;
to: ThinkLevel;
provider: string;
+2 -2
View File
@@ -1,7 +1,7 @@
// Defines reply directive parsing constants and text-matching helpers.
import type { FastMode } from "@openclaw/normalization-core/string-coerce";
import { escapeRegExp } from "../../utils.js";
import type { NoticeLevel, ReasoningLevel, TraceLevel } from "../thinking.js";
import type { ReasoningLevel, TraceLevel } from "../thinking.js";
import {
type ElevatedLevel,
normalizeFastMode,
@@ -228,5 +228,5 @@ export function extractStatusDirective(body?: string): {
return extractSimpleDirective(body, STATUS_DIRECTIVE_PATTERN);
}
export type { ElevatedLevel, NoticeLevel, ReasoningLevel, ThinkLevel, TraceLevel, VerboseLevel };
export type { ElevatedLevel, ReasoningLevel, ThinkLevel, TraceLevel, VerboseLevel };
export { extractExecDirective } from "./exec/directive.js";
@@ -3,7 +3,8 @@ import { expectDefined } from "@openclaw/normalization-core";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../config/config.js";
import { createAcpDispatchDeliveryCoordinator } from "./dispatch-acp-delivery.js";
import { createReplyDispatcher, type ReplyDispatcher } from "./reply-dispatcher.js";
import { createReplyDispatcher } from "./reply-dispatcher.js";
import type { ReplyDispatcher } from "./reply-dispatcher.types.js";
import { buildTestCtx } from "./test-ctx.js";
import { createAcpTestConfig } from "./test-fixtures/acp-runtime.js";
@@ -53,7 +53,7 @@ function loadMessageActionRuntime() {
return messageActionRuntimeLoader.load();
}
export type AcpDispatchDeliveryMeta = {
type AcpDispatchDeliveryMeta = {
toolCallId?: string;
allowEdit?: boolean;
skipTts?: boolean;
+1 -1
View File
@@ -19,7 +19,7 @@ import {
appendRecentHistoryImageContext,
resolveRecentInboundHistoryImages,
} from "./history-media.js";
import type { ReplyDispatcher } from "./reply-dispatcher.js";
import type { ReplyDispatcher } from "./reply-dispatcher.types.js";
import { buildTestCtx } from "./test-ctx.js";
import { createAcpSessionMeta, createAcpTestConfig } from "./test-fixtures/acp-runtime.js";
@@ -4,7 +4,8 @@ import { clearAgentHarnesses } from "../../agents/harness/registry.js";
import type { PluginHookReplyDispatchResult } from "../../plugins/hooks.js";
import { createInternalHookEventPayload } from "../../test-utils/internal-hook-event-payload.js";
import { withReplyDispatcher } from "../dispatch-dispatcher.js";
import { setReplyPayloadMetadata, type ReplyPayload } from "../types.js";
import { setReplyPayloadMetadata } from "../reply-payload.js";
import type { ReplyPayload } from "../types.js";
import {
acpManagerRuntimeMocks,
acpMocks,
@@ -1,5 +1,6 @@
/** Runtime-only dispatch dependencies shared by config-driven reply delivery. */
import { loadSessionEntry, updateSessionEntry } from "../../config/sessions/session-accessor.js";
/** Runtime-only dispatch dependencies shared by config-driven reply delivery. */
import { loadSessionEntry } from "../../config/sessions/session-accessor.js";
import type { SessionEntry } from "../../config/sessions/types.js";
export { resolveStorePath } from "../../config/sessions/paths.js";
@@ -14,25 +15,3 @@ export function loadSessionStoreEntry(params: {
}): SessionEntry | undefined {
return loadSessionEntry(params);
}
export async function updateSessionStoreEntry(params: {
storePath: string;
sessionKey: string;
skipMaintenance?: boolean;
takeCacheOwnership?: boolean;
update: (
entry: SessionEntry,
) => Promise<Partial<SessionEntry> | null> | Partial<SessionEntry> | null;
}): Promise<SessionEntry | null> {
return await updateSessionEntry(
{
storePath: params.storePath,
sessionKey: params.sessionKey,
},
params.update,
{
skipMaintenance: params.skipMaintenance,
takeCacheOwnership: params.takeCacheOwnership,
},
);
}
@@ -15,7 +15,8 @@ import {
} from "../../test-utils/channel-plugins.js";
import { copyReplyPayloadMetadata } from "../reply-payload.js";
import type { ReplyPayload } from "../types.js";
import type { ReplyDispatchBeforeDeliver, ReplyDispatcher } from "./reply-dispatcher.js";
import type { ReplyDispatchBeforeDeliver } from "./reply-dispatcher.js";
import type { ReplyDispatcher } from "./reply-dispatcher.types.js";
import { buildTestCtx } from "./test-ctx.js";
type AbortResult = {
@@ -36,9 +36,9 @@ import {
} from "../../test-utils/channel-plugins.js";
import { createInternalHookEventPayload } from "../../test-utils/internal-hook-event-payload.js";
import { settleReplyDispatcher } from "../dispatch-dispatcher.js";
import { getReplyPayloadMetadata } from "../reply-payload.js";
import { getReplyPayloadMetadata, setReplyPayloadMetadata } from "../reply-payload.js";
import type { MsgContext } from "../templating.js";
import { setReplyPayloadMetadata, type GetReplyOptions, type ReplyPayload } from "../types.js";
import type { GetReplyOptions, ReplyPayload } from "../types.js";
import { markCommandSessionMetadataChanged } from "./command-session-metadata.js";
import {
acpManagerRuntimeMocks,
@@ -65,7 +65,8 @@ import {
ttsMocks,
} from "./dispatch-from-config.shared.test-harness.js";
import { PROVIDER_CONVERSATION_STATE_ERROR_USER_MESSAGE } from "./provider-request-error-classifier.js";
import { createReplyDispatcher, type ReplyDispatcher } from "./reply-dispatcher.js";
import { createReplyDispatcher } from "./reply-dispatcher.js";
import type { ReplyDispatcher } from "./reply-dispatcher.types.js";
import { resolveRoutedDeliveryThreadId } from "./routed-delivery-thread.js";
import { buildTestCtx } from "./test-ctx.js";
@@ -9752,12 +9753,11 @@ describe("dispatchReplyFromConfig", () => {
const dispatcher = createDispatcher();
const ctx = buildTestCtx({ Provider: "whatsapp" });
const onBlockReplyQueued = vi.fn();
const { setReplyPayloadMetadata: setReplyPayloadMetadataLocal } = await import("../types.js");
const replyResolver = async (
_ctx: MsgContext,
opts?: GetReplyOptions,
): Promise<ReplyPayload | undefined> => {
const payload = setReplyPayloadMetadataLocal({ text: "Alpha" }, { assistantMessageIndex: 7 });
const payload = setReplyPayloadMetadata({ text: "Alpha" }, { assistantMessageIndex: 7 });
await opts?.onBlockReply?.(payload);
return undefined;
};
+1 -4
View File
@@ -1597,10 +1597,7 @@ function createReplyHotPathTimingTracker(options: { profilerEnabled?: boolean }
};
}
export type {
DispatchFromConfigParams,
DispatchFromConfigResult,
} from "./dispatch-from-config.types.js";
export type { DispatchFromConfigResult } from "./dispatch-from-config.types.js";
/** Dispatches a reply from config, context, command handling, agent run, and delivery policy. */
export async function dispatchReplyFromConfig(
-2
View File
@@ -1,2 +0,0 @@
/** Public exec directive parser barrel for reply command handling. */
export { extractExecDirective } from "./exec/directive.js";
+3 -2
View File
@@ -38,7 +38,7 @@ let loadSessionStore: typeof import("../../config/sessions/store.js").loadSessio
let saveSessionStore: typeof import("../../config/sessions/store.js").saveSessionStore;
let replaceSessionEntrySync: typeof import("../../config/sessions/session-accessor.js").replaceSessionEntrySync;
let clearSessionStoreCacheForTest: typeof import("../../config/sessions/store.js").clearSessionStoreCacheForTest;
let clearFollowupQueue: typeof import("./queue.js").clearFollowupQueue;
let clearFollowupQueue: typeof import("./queue/state.js").clearFollowupQueue;
let enqueueFollowupRun: typeof import("./queue.js").enqueueFollowupRun;
let sessionRunAccounting: typeof import("./session-run-accounting.js");
let setRuntimeConfigSnapshot: typeof import("../../config/config.js").setRuntimeConfigSnapshot;
@@ -504,7 +504,8 @@ async function loadFreshFollowupRunnerModuleForTest() {
({ clearSessionStoreCacheForTest, loadSessionStore, saveSessionStore } =
await import("../../config/sessions/store.js"));
({ replaceSessionEntrySync } = await import("../../config/sessions/session-accessor.js"));
({ clearFollowupQueue, enqueueFollowupRun } = await import("./queue.js"));
({ clearFollowupQueue } = await import("./queue/state.js"));
({ enqueueFollowupRun } = await import("./queue.js"));
sessionRunAccounting = await import("./session-run-accounting.js");
({ createMockFollowupRun, createMockTypingController } = await import("./test-helpers.js"));
({
+1 -1
View File
@@ -29,7 +29,7 @@ export function evictOldHistoryKeys<T>(
}
}
export type { HistoryEntry, HistoryMediaEntry } from "./history.types.js";
export type { HistoryEntry } from "./history.types.js";
/** Wraps previous chat history and the current message in the prompt context marker format. */
export function buildHistoryContext(params: {
+1 -1
View File
@@ -2,7 +2,7 @@
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
/** Minimal inbound media fields used by media/audio detection. */
export type InboundMediaContext = {
type InboundMediaContext = {
Body?: unknown;
BodyForCommands?: unknown;
CommandBody?: unknown;
+1 -1
View File
@@ -16,7 +16,7 @@ import { compileConfigRegexes, type ConfigRegexRejectReason } from "../../securi
import { escapeRegExp } from "../../utils.js";
import type { MsgContext } from "../templating.js";
import type { BuildMentionRegexesOptions, ExplicitMentionSignal } from "./mentions.types.js";
export type { BuildMentionRegexesOptions, ExplicitMentionSignal } from "./mentions.types.js";
export type { BuildMentionRegexesOptions } from "./mentions.types.js";
function deriveMentionPatterns(identity?: { name?: string; emoji?: string }) {
const patterns: string[] = [];
+2 -2
View File
@@ -81,7 +81,7 @@ export function buildReplyPromptBodies(params: {
type ReplyPromptEnvelopeStartupAction = "new" | "reset";
/** Full prompt envelope passed into reply run preparation. */
export type ReplyPromptEnvelope = ReturnType<typeof buildReplyPromptBodies> & {
type ReplyPromptEnvelope = ReturnType<typeof buildReplyPromptBodies> & {
/** Model-visible body before media, thread context, and inter-session annotation are applied. */
effectiveBaseBody: string;
/** User-visible body persisted to transcript before media/inter-session annotation. */
@@ -91,7 +91,7 @@ export type ReplyPromptEnvelope = ReturnType<typeof buildReplyPromptBodies> & {
};
/** Base prompt envelope fields before body variants are added. */
export type ReplyPromptEnvelopeBase = {
type ReplyPromptEnvelopeBase = {
/** Model-visible body before media, thread context, and inter-session annotation are applied. */
effectiveBaseBody: string;
/** User-visible body persisted to transcript before media/inter-session annotation. */
@@ -8,7 +8,7 @@ import { isFailoverError } from "../../agents/failover-error.js";
import { formatErrorMessage } from "../../infra/errors.js";
/** Provider request error classes that get a specialized user-facing reply. */
export type ProviderRequestErrorCode =
type ProviderRequestErrorCode =
| "provider_authentication_error"
| "provider_conversation_state_error"
| "provider_internal_error"
@@ -16,7 +16,7 @@ export type ProviderRequestErrorCode =
| "provider_rate_limit_or_quota_error";
/** Structured provider error classification for reply failure handling. */
export type ProviderRequestErrorClassification = {
type ProviderRequestErrorClassification = {
code: ProviderRequestErrorCode;
userMessage: string;
technicalMessage: string;
+1 -2
View File
@@ -13,7 +13,6 @@ import { createTestUserTurnTranscriptTarget } from "../../sessions/user-turn-tra
import type { FollowupRun, QueueSettings } from "./queue.js";
import {
admitFollowupRunLifecycle,
clearFollowupQueue,
completeFollowupRunLifecycle,
enqueueFollowupRun,
FollowupRunDeferredError,
@@ -26,7 +25,7 @@ import {
installQueueRuntimeErrorSilencer,
} from "./queue.test-helpers.js";
import { resolveFollowupAuthorizationKey } from "./queue/drain.js";
import { getExistingFollowupQueue } from "./queue/state.js";
import { clearFollowupQueue, getExistingFollowupQueue } from "./queue/state.js";
installQueueRuntimeErrorSilencer();
+2 -5
View File
@@ -2,16 +2,13 @@
import { importFreshModule } from "openclaw/plugin-sdk/test-fixtures";
import { beforeEach, describe, expect, it } from "vitest";
import type { FollowupRun, QueueSettings } from "./queue.js";
import {
enqueueFollowupRun,
resetRecentQueuedMessageIdDedupe,
scheduleFollowupDrain,
} from "./queue.js";
import { enqueueFollowupRun, scheduleFollowupDrain } from "./queue.js";
import {
createDeferred,
createQueueTestRun as createRun,
installQueueRuntimeErrorSilencer,
} from "./queue.test-helpers.js";
import { resetRecentQueuedMessageIdDedupe } from "./queue/enqueue.js";
installQueueRuntimeErrorSilencer();
@@ -11,7 +11,6 @@ import {
import { captureEnv, setTestEnvValue } from "../../test-utils/env.js";
import type { FollowupRun, QueueSettings } from "./queue.js";
import {
clearFollowupQueue,
clearSessionQueues,
enqueueFollowupRun,
FollowupRunDeferredError,
@@ -22,7 +21,7 @@ import {
createQueueTestRun as createRun,
installQueueRuntimeErrorSilencer,
} from "./queue.test-helpers.js";
import { getExistingFollowupQueue } from "./queue/state.js";
import { clearFollowupQueue, getExistingFollowupQueue } from "./queue/state.js";
installQueueRuntimeErrorSilencer();
+1 -2
View File
@@ -1,14 +1,13 @@
// Proves queue caps and depth describe pending work while active identities remain in shared state.
import { afterEach, describe, expect, it, vi } from "vitest";
import {
clearFollowupQueue,
completeFollowupRunLifecycle,
enqueueFollowupRun,
getFollowupQueueDepth,
scheduleFollowupDrain,
} from "./queue.js";
import { createDeferred, createQueueTestRun as createRun } from "./queue.test-helpers.js";
import { getExistingFollowupQueue } from "./queue/state.js";
import { clearFollowupQueue, getExistingFollowupQueue } from "./queue/state.js";
import type { FollowupRun, QueueDropPolicy, QueueSettings } from "./queue/types.js";
describe("followup queue in-flight ownership", () => {
+4 -12
View File
@@ -1,5 +1,5 @@
/** Public queue API for deferred auto-reply follow-up runs. */
export { extractQueueDirective } from "./queue/directive.js";
export { clearSessionQueues } from "./queue/cleanup.js";
export type { ClearSessionQueueResult } from "./queue/cleanup.js";
export { scheduleFollowupDrain } from "./queue/drain.js";
@@ -9,16 +9,8 @@ export {
resetRecentQueuedMessageIdDedupe,
} from "./queue/enqueue.js";
export { resolveQueueSettings } from "./queue/settings-runtime.js";
export { clearFollowupQueue, refreshQueuedFollowupSession } from "./queue/state.js";
export type {
EnqueueFollowupRunOptions,
FollowupRun,
QueueDedupeMode,
QueueInsertPosition,
QueueDropPolicy,
QueueMode,
QueueSettings,
} from "./queue/types.js";
export { refreshQueuedFollowupSession } from "./queue/state.js";
export type { FollowupRun, QueueSettings } from "./queue/types.js";
export { isFollowupRunAborted } from "./queue/types.js";
export { admitFollowupRunLifecycle, completeFollowupRunLifecycle } from "./queue/types.js";
export { FollowupRunDeferredError, isFollowupRunDeferredError } from "./queue/types.js";
export { FollowupRunDeferredError } from "./queue/types.js";
+1 -1
View File
@@ -16,7 +16,7 @@ import {
type QueueSettings,
} from "./types.js";
export type FollowupQueueState = {
type FollowupQueueState = {
abortController: AbortController;
items: FollowupRun[];
draining: boolean;
+1 -1
View File
@@ -37,7 +37,7 @@ export type QueueSettings = {
export type QueueDedupeMode = "message-id" | "prompt" | "none";
export type QueueInsertPosition = "tail" | "front";
type QueueInsertPosition = "tail" | "front";
export type EnqueueFollowupRunOptions = {
position?: QueueInsertPosition;
-2
View File
@@ -22,8 +22,6 @@ import type {
import type { ResponsePrefixContext } from "./response-prefix-template.js";
import type { TypingController } from "./typing.js";
export type { ReplyDispatchKind, ReplyDispatcher } from "./reply-dispatcher.types.js";
type ReplyDispatchErrorHandler = (
err: unknown,
info: ReplyDispatchRuntimeInfo,
@@ -1,4 +1,4 @@
export type ReplyOperationAdmissionSnapshot =
type ReplyOperationAdmissionSnapshot =
| { status: "owned" }
| { status: "skipped"; reason: "active-run" | "aborted" | "lifecycle-invalidated" };
+1 -1
View File
@@ -4,10 +4,10 @@ import { describe, expect, it, vi } from "vitest";
import { resetPluginRuntimeStateForTest, setActivePluginRegistry } from "../../plugins/runtime.js";
import { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js";
import { getReplyPayloadMetadata, setReplyPayloadMetadata } from "../reply-payload.js";
import { shouldDedupeMessagingToolRepliesForRoute } from "./reply-payloads-dedupe.js";
import {
filterMessagingToolMediaDuplicates,
resolveMessagingToolPayloadDedupe,
shouldDedupeMessagingToolRepliesForRoute,
} from "./reply-payloads.js";
function targetsMatchTelegramReplySuppression(params: {
-1
View File
@@ -10,5 +10,4 @@ export {
filterMessagingToolDuplicates,
filterMessagingToolMediaDuplicates,
resolveMessagingToolPayloadDedupe,
shouldDedupeMessagingToolRepliesForRoute,
} from "./reply-payloads-dedupe.js";
+9 -9
View File
@@ -20,11 +20,11 @@ import type {
} from "../get-reply-options.types.js";
import type { ReplyFollowupAdmissionBarrierTimeoutPolicy } from "./reply-dispatcher.types.js";
export type ReplyRunKey = string;
type ReplyRunKey = string;
export type ReplyBackendKind = "embedded" | "cli";
type ReplyBackendKind = "embedded" | "cli";
export type ReplyBackendCancelReason = "user_abort" | "restart" | "superseded";
type ReplyBackendCancelReason = "user_abort" | "restart" | "superseded";
export type ReplyBackendQueueMessageOptions = {
steeringMode?: "all";
@@ -53,7 +53,7 @@ export type ReplyBackendHandle = {
isCompacting?: () => boolean;
};
export type ReplyBackendQueueMessageMismatch =
type ReplyBackendQueueMessageMismatch =
| "source_reply_delivery_mode_mismatch"
| "task_suggestion_delivery_mode_mismatch";
@@ -90,7 +90,7 @@ export type ReplyOperationPhase =
| "failed"
| "aborted";
export type ReplyOperationFailureCode =
type ReplyOperationFailureCode =
| "gateway_draining"
| "command_lane_cleared"
| "aborted_by_user"
@@ -98,9 +98,9 @@ export type ReplyOperationFailureCode =
| "run_stalled"
| "run_failed";
export type ReplyOperationAbortCode = "aborted_by_user" | "aborted_for_restart";
type ReplyOperationAbortCode = "aborted_by_user" | "aborted_for_restart";
export type ReplyOperationResult =
type ReplyOperationResult =
| { kind: "completed" }
| { kind: "failed"; code: ReplyOperationFailureCode; cause?: unknown }
| { kind: "aborted"; code: ReplyOperationAbortCode };
@@ -182,7 +182,7 @@ export type ReplyOperation = {
abortForRestart(): boolean;
};
export type ReplyRunRegistry = {
type ReplyRunRegistry = {
begin(params: {
sessionKey: string;
sessionId: string;
@@ -238,7 +238,7 @@ export const REPLY_RUN_IDLE_SETTLE_TIMEOUT_MS = 15_000;
// Without this, abort/failure can leave the session wedged until process restart.
export const REPLY_RUN_TERMINAL_SETTLE_TIMEOUT_MS = 60_000;
export type ReplyOperationStaleReason = "terminal_unreleased" | "no_activity" | "stuck_recovery";
type ReplyOperationStaleReason = "terminal_unreleased" | "no_activity" | "stuck_recovery";
export class ReplyRunAlreadyActiveError extends Error {
constructor(sessionKey: string) {
+2 -2
View File
@@ -26,10 +26,10 @@ import {
} from "./reply-run-registry.js";
/** Kinds of turns that compete for one reply run slot per session. */
export type ReplyTurnKind = "visible" | "heartbeat" | "queued_followup";
type ReplyTurnKind = "visible" | "heartbeat" | "queued_followup";
/** Admission result for a reply turn attempting to own the session run slot. */
export type ReplyTurnAdmission =
type ReplyTurnAdmission =
| { status: "owned"; operation: ReplyOperation; sessionEntry?: SessionEntry }
| {
status: "skipped";
+1 -1
View File
@@ -19,7 +19,7 @@ import {
} from "../../utils/message-channel.js";
import type { MsgContext } from "../templating.js";
export type LegacyMainDeliveryRetirement = {
type LegacyMainDeliveryRetirement = {
key: string;
entry: SessionEntry;
};
+1 -1
View File
@@ -45,7 +45,7 @@ type ForkSessionFromParentParams = {
targetStorePath?: string;
};
export type ForkedParentSessionEntry = ParentForkedSessionTranscript;
type ForkedParentSessionEntry = ParentForkedSessionTranscript;
export type ForkSessionEntryFromParentResult =
| {
-2
View File
@@ -22,8 +22,6 @@ import { getRemoteSkillEligibility } from "../../skills/runtime/remote.js";
import { resolveReusableWorkspaceSkillSnapshot } from "../../skills/runtime/session-snapshot.js";
import type { ReplySessionEntryHandle } from "./session-entry-handle.js";
import { buildSessionEndHookPayload, buildSessionStartHookPayload } from "./session-hooks.js";
export { drainFormattedSystemEvents } from "./session-system-events.js";
export { resetResolvedSkillsCacheForTests } from "../../skills/runtime/session-snapshot.js";
async function persistSessionEntryUpdate(params: {
expectedSessionId: string | undefined;
+1 -1
View File
@@ -45,7 +45,7 @@ import {
import { withEnvAsync } from "../../test-utils/env.js";
import { createSessionConversationTestRegistry } from "../../test-utils/session-conversation-registry.js";
import { replyRunRegistry } from "./reply-run-registry.js";
import { drainFormattedSystemEvents } from "./session-updates.js";
import { drainFormattedSystemEvents } from "./session-system-events.js";
import { persistSessionUsageUpdate } from "./session-usage.js";
import { initSessionState, resolveReplySessionPreprocessingState } from "./session.js";
+2 -2
View File
@@ -198,7 +198,7 @@ export type SessionInitResult = {
triggerBodyNormalized: string;
};
export type InitSessionStateParams = {
type InitSessionStateParams = {
abortSignal?: AbortSignal;
cfg: OpenClawConfig;
commandAuthorized: boolean;
@@ -322,7 +322,7 @@ function resolveInitSessionStateAttemptContext(
};
}
export type ReplySessionPreprocessingState = {
type ReplySessionPreprocessingState = {
sessionEntry?: SessionEntry;
sessionKey: string;
storePath: string;
+1 -1
View File
@@ -7,7 +7,7 @@ import type { TypingPolicy } from "../types.js";
import type { TypingController } from "./typing.js";
/** Inputs that decide when a channel typing indicator should be shown. */
export type TypingModeContext = {
type TypingModeContext = {
configured?: TypingMode;
isGroupChat: boolean;
wasMentioned: boolean;
+4 -6
View File
@@ -11,14 +11,12 @@ import {
} from "../agents/context-cache.js";
import type { OpenClawConfig } from "../config/config.js";
import { applyModelOverrideToSessionEntry } from "../sessions/model-overrides.js";
import { createSuccessfulImageMediaDecision } from "./media-understanding.test-fixtures.js";
import {
buildCommandsMessage,
buildCommandsMessagePaginated,
buildHelpMessage,
buildStatusMessage as buildStatusMessageRaw,
} from "./status.js";
import type { buildStatusMessage as BuildStatusMessage } from "./status.js";
type buildStatusMessage as BuildStatusMessage,
} from "../status/status-message.js";
import { createSuccessfulImageMediaDecision } from "./media-understanding.test-fixtures.js";
import { buildCommandsMessage, buildCommandsMessagePaginated, buildHelpMessage } from "./status.js";
const buildStatusMessage: typeof BuildStatusMessage = (args) =>
buildStatusMessageRaw({
+1 -7
View File
@@ -7,14 +7,8 @@ export {
buildCommandsMessage,
buildCommandsMessagePaginated,
buildHelpMessage,
type CommandsMessageOptions,
type CommandsMessageResult,
} from "./command-status-builders.js";
export {
buildStatusMessage,
formatContextUsageShort,
type StatusArgs,
} from "../status/status-message.js";
export { formatContextUsageShort } from "../status/status-message.js";
export { formatTokenCount } from "../utils/usage-format.js";
type ToolsMessageItem = {
+4 -5
View File
@@ -22,7 +22,6 @@ export type ThinkLevel =
| "ultra";
export type VerboseLevel = "off" | "on" | "full";
export type TraceLevel = "off" | "on" | "raw";
export type NoticeLevel = "off" | "on" | "full";
export type ElevatedLevel = "off" | "on" | "ask" | "full";
export type ReasoningLevel = "off" | "on" | "stream";
type UsageDisplayLevel = "off" | "tokens" | "full";
@@ -40,7 +39,7 @@ export type ThinkingCatalogEntry = {
};
/** Complete canonical level set accepted by user-facing thinking controls. */
export const ALL_THINKING_LEVELS: readonly ThinkLevel[] = [
const ALL_THINKING_LEVELS: readonly ThinkLevel[] = [
"off",
"minimal",
"low",
@@ -200,12 +199,12 @@ export function resolveResponseUsageMode(raw?: string | null): UsageDisplayLevel
return normalizeUsageDisplay(raw) ?? "off";
}
export type ResponseUsageInput = "on" | "off" | "tokens" | "full";
export type ResponseUsageDefaultConfig =
type ResponseUsageInput = "on" | "off" | "tokens" | "full";
type ResponseUsageDefaultConfig =
| ResponseUsageInput
| { default?: ResponseUsageInput; [channel: string]: ResponseUsageInput | undefined };
export function resolveMessagesResponseUsageDefault(
function resolveMessagesResponseUsageDefault(
configured: ResponseUsageDefaultConfig | undefined,
channel?: string,
): ResponseUsageInput | undefined {
-28
View File
@@ -25,7 +25,6 @@ const {
formatThinkingLevels,
resolveSupportedThinkingLevel,
resolveThinkingDefaultForModel,
resolveMessagesResponseUsageDefault,
resolveEffectiveResponseUsage,
} = await import("./thinking.js");
@@ -847,33 +846,6 @@ describe("normalizeReasoningLevel", () => {
});
});
describe("resolveMessagesResponseUsageDefault", () => {
it("returns undefined when unset (preserves off-by-default behavior)", () => {
expect(resolveMessagesResponseUsageDefault(undefined)).toBeUndefined();
expect(resolveMessagesResponseUsageDefault(undefined, "discord")).toBeUndefined();
});
it("returns a bare string default for any channel", () => {
expect(resolveMessagesResponseUsageDefault("full")).toBe("full");
expect(resolveMessagesResponseUsageDefault("full", "telegram")).toBe("full");
});
it("resolves the channel entry from a map", () => {
const cfg = { default: "off", discord: "full", telegram: "tokens" } as const;
expect(resolveMessagesResponseUsageDefault(cfg, "discord")).toBe("full");
expect(resolveMessagesResponseUsageDefault(cfg, "telegram")).toBe("tokens");
});
it("falls back to default for an unmapped channel", () => {
const cfg = { default: "tokens", discord: "full" } as const;
expect(resolveMessagesResponseUsageDefault(cfg, "whatsapp")).toBe("tokens");
});
it("returns undefined for a map with neither the channel nor a default", () => {
expect(resolveMessagesResponseUsageDefault({ discord: "full" }, "telegram")).toBeUndefined();
});
});
describe("resolveEffectiveResponseUsage", () => {
it("returns off when session is unset and no config is provided", () => {
expect(resolveEffectiveResponseUsage(undefined, undefined)).toBe("off");
+1 -5
View File
@@ -18,16 +18,12 @@ export {
normalizeUsageDisplay,
normalizeVerboseLevel,
resolveEffectiveResponseUsage,
resolveMessagesResponseUsageDefault,
resolveResponseUsageMode,
} from "./thinking.shared.js";
export type {
ElevatedLevel,
FastMode,
NoticeLevel,
ReasoningLevel,
ResponseUsageDefaultConfig,
ResponseUsageInput,
TraceLevel,
ThinkLevel,
ThinkingCatalogEntry,
@@ -46,7 +42,7 @@ import {
import type { ProviderThinkingProfile } from "../plugins/provider-thinking.types.js";
/** UI-facing thinking level option. */
export type ThinkingLevelOption = {
type ThinkingLevelOption = {
id: ThinkLevel;
label: string;
};
-7
View File
@@ -2,14 +2,7 @@
export type {
BlockReplyContext,
GetReplyOptions,
PartialReplyPayload,
ReplyThreadingPolicy,
TypingPolicy,
} from "./get-reply-options.types.js";
export {
copyReplyPayloadMetadata,
markCommandReplyForDelivery,
markReplyPayloadForSourceSuppressionDelivery,
setReplyPayloadMetadata,
} from "./reply-payload.js";
export type { ReplyPayload } from "./reply-payload.js";
+1 -1
View File
@@ -6,7 +6,7 @@ import { createSubsystemLogger } from "../../logging/subsystem.js";
import { DEFAULT_USAGE_BAR_TEMPLATE } from "./default-template.js";
import type { UsageBarTemplate } from "./translator.js";
export type UsageTemplateConfig = string | Record<string, unknown> | undefined;
type UsageTemplateConfig = string | Record<string, unknown> | undefined;
type CacheEntry = { template: UsageBarTemplate | undefined; watcher?: FSWatcher };
const fileCache = new Map<string, CacheEntry>();
-51
View File
@@ -8,7 +8,6 @@ import {
getPrimaryCommand,
getPositiveIntFlagValue,
getVerboseFlag,
hasHelpOrVersion,
hasFlag,
isHelpOrVersionInvocation,
isRootHelpInvocation,
@@ -21,56 +20,6 @@ import {
} from "./argv.js";
describe("argv helpers", () => {
it.each([
{
name: "help flag",
argv: ["node", "openclaw", "--help"],
expected: true,
},
{
name: "version flag",
argv: ["node", "openclaw", "-V"],
expected: true,
},
{
name: "normal command",
argv: ["node", "openclaw", "status"],
expected: false,
},
{
name: "root -v alias",
argv: ["node", "openclaw", "-v"],
expected: true,
},
{
name: "root -v alias with profile",
argv: ["node", "openclaw", "--profile", "work", "-v"],
expected: true,
},
{
name: "root -v alias with log-level",
argv: ["node", "openclaw", "--log-level", "debug", "-v"],
expected: true,
},
{
name: "subcommand -v should not be treated as version",
argv: ["node", "openclaw", "acp", "-v"],
expected: false,
},
{
name: "root -v alias with equals profile",
argv: ["node", "openclaw", "--profile=work", "-v"],
expected: true,
},
{
name: "subcommand path after global root flags should not be treated as version",
argv: ["node", "openclaw", "--dev", "skills", "list", "-v"],
expected: false,
},
])("detects help/version flags: $name", ({ argv, expected }) => {
expect(hasHelpOrVersion(argv)).toBe(expected);
});
it.each([
{
name: "known command group help command help flag",
+2 -8
View File
@@ -22,12 +22,6 @@ const ROOT_COMMANDS_WITH_SUBCOMMANDS: ReadonlySet<string> = new Set(
),
);
export function hasHelpOrVersion(argv: string[]): boolean {
return (
argv.some((arg) => HELP_FLAGS.has(arg) || VERSION_FLAGS.has(arg)) || hasRootVersionAlias(argv)
);
}
export function isHelpOrVersionInvocation(argv: string[]): boolean {
if (hasRootVersionAlias(argv)) {
return true;
@@ -265,14 +259,14 @@ export function normalizeRootHelpTargetArgv(argv: string[]): string[] {
return [runtimePath, entryPath, ...rootOptions, ...targetPath, "--help"];
}
export type NormalizeRootNoColorArgvOptions = {
type NormalizeRootNoColorArgvOptions = {
shouldPreserveNoColor?: (params: {
remainingArgs: readonly string[];
noColorIndex: number;
}) => boolean;
};
export type NormalizeRootLogLevelArgvOptions = {
type NormalizeRootLogLevelArgvOptions = {
shouldPreserveLogLevel?: (params: {
remainingArgs: readonly string[];
logLevelIndex: number;
+1 -1
View File
@@ -2,7 +2,7 @@ import { sanitizeTerminalText } from "../../packages/terminal-core/src/safe-text
import type { ClawHubRiskAcknowledgementRequest } from "../infra/clawhub-install-trust.js";
import { promptText, promptYesNo } from "./prompt.js";
export type ClawHubRiskAcknowledgementCliOptions = {
type ClawHubRiskAcknowledgementCliOptions = {
acknowledgeClawHubRisk?: boolean;
};
+1 -1
View File
@@ -29,7 +29,7 @@ type NormalizedScheduleOptions = {
};
/** Normalized schedule edit request, including patch-only updates for cron metadata. */
export type CronEditScheduleRequest =
type CronEditScheduleRequest =
| { kind: "direct"; schedule: CronSchedule }
| { kind: "patch-existing-cron"; staggerMs: number | undefined; tz: string | undefined }
| { kind: "none" };
+3 -3
View File
@@ -10,10 +10,10 @@ import { isWSL } from "../../infra/wsl.js";
import { defaultRuntime } from "../../runtime.js";
/** Gateway service action emitted by lifecycle commands. */
export type DaemonAction = "install" | "uninstall" | "start" | "stop" | "restart";
type DaemonAction = "install" | "uninstall" | "start" | "stop" | "restart";
/** Stable hint category for machine-readable daemon command output. */
export type DaemonHintKind =
type DaemonHintKind =
| "install"
| "container-restart"
| "container-foreground"
@@ -23,7 +23,7 @@ export type DaemonHintKind =
| "generic";
/** Classified daemon recovery hint item. */
export type DaemonHintItem = {
type DaemonHintItem = {
kind: DaemonHintKind;
text: string;
};
+1 -1
View File
@@ -31,7 +31,7 @@ type QaParentWatchdogDeps = {
setInterval?: (callback: () => void, ms: number) => QaParentWatchdogTimer;
};
export type QaParentWatchdogHandle = {
type QaParentWatchdogHandle = {
parentPid: number;
stop: () => void;
};
-1
View File
@@ -1098,4 +1098,3 @@ export const testing = {
resolveGatewayStartupFailureExitCode,
runGatewayLoopWithSupervisedLockRecovery,
};
export { testing as __testing };
+1 -1
View File
@@ -2,7 +2,7 @@
import { theme } from "../../packages/terminal-core/src/theme.js";
/** Command plus short description tuple used in help epilogues. */
export type HelpExample = readonly [command: string, description: string];
type HelpExample = readonly [command: string, description: string];
function formatHelpExample(command: string, description: string): string {
return ` ${theme.command(command)}\n ${theme.muted(description)}`;
+2 -2
View File
@@ -24,7 +24,7 @@ const CAMERA_URL_DOWNLOAD_TIMEOUT_MS = 15 * 60_000;
export type CameraFacing = "front" | "back";
/** Validated still-image payload from `nodes camera snap`. */
export type CameraSnapPayload = {
type CameraSnapPayload = {
format: string;
base64?: string;
url?: string;
@@ -33,7 +33,7 @@ export type CameraSnapPayload = {
};
/** Validated video payload from `nodes camera clip`. */
export type CameraClipPayload = {
type CameraClipPayload = {
format: string;
base64?: string;
url?: string;
+2 -2
View File
@@ -4,7 +4,7 @@ import { writeBase64ToFile } from "./nodes-camera.js";
import { asRecord, asString, resolveTempPathParts } from "./nodes-media-utils.js";
/** Validated payload returned by `nodes screen record` RPC calls. */
export type ScreenRecordPayload = {
type ScreenRecordPayload = {
format: string;
base64: string;
durationMs?: number;
@@ -47,7 +47,7 @@ export async function writeScreenRecordToFile(
}
/** Validated payload returned by `nodes screen snapshot` RPC calls. */
export type ScreenSnapshotPayload = {
type ScreenSnapshotPayload = {
format: string;
base64: string;
/** Node-issued token binding this image to one physical display geometry. */
+1 -1
View File
@@ -45,7 +45,7 @@ type PluginSearchOptions = {
limit?: number;
};
export type PluginUninstallOptions = {
type PluginUninstallOptions = {
keepFiles?: boolean;
/** @deprecated Use keepFiles. */
keepConfig?: boolean;
+1 -1
View File
@@ -12,7 +12,7 @@ import {
resolveOfficialExternalPluginInstall,
} from "../plugins/official-external-plugin-catalog.js";
export type PersistedBundledPluginRecoveryLocation = {
type PersistedBundledPluginRecoveryLocation = {
pluginId: string;
loadPaths: readonly string[];
};
+1 -1
View File
@@ -7,7 +7,7 @@ import { searchInstallablePluginPackages } from "../plugins/catalog-search.js";
import { defaultRuntime, writeRuntimeJson, type RuntimeEnv } from "../runtime.js";
/** Options accepted by `openclaw plugins search`. */
export type PluginsSearchOptions = {
type PluginsSearchOptions = {
json?: boolean;
limit?: number;
};
+1 -1
View File
@@ -12,7 +12,7 @@ import { sleep } from "../utils.js";
export type PortProcess = { pid: number; command?: string };
export type ForceFreePortResult = {
type ForceFreePortResult = {
killed: PortProcess[];
waitedMs: number;
escalatedToSigkill: boolean;
+1 -1
View File
@@ -2,7 +2,7 @@ import { consumeRootOptionToken } from "../infra/cli-root-options.js";
import { getCommandPathWithRootOptions, hasFlag } from "./argv.js";
import type { RootHelpRenderOptions } from "./program/root-help.js";
export type PrecomputedSubcommandHelpName =
type PrecomputedSubcommandHelpName =
| "doctor"
| "gateway"
| "models"
+2 -2
View File
@@ -4,12 +4,12 @@ import { sanitizeForLog } from "../../../packages/terminal-core/src/ansi.js";
import type { NamedCommandDescriptor } from "./command-group-descriptors.js";
/** Minimal descriptor shape used before a command is fully registered. */
export type CommandDescriptorLike = Pick<NamedCommandDescriptor, "name" | "description">;
type CommandDescriptorLike = Pick<NamedCommandDescriptor, "name" | "description">;
const SAFE_COMMAND_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
/** Descriptor catalog plus derived name lists used by lazy command registration. */
export type CommandDescriptorCatalog<TDescriptor extends NamedCommandDescriptor> = {
type CommandDescriptorCatalog<TDescriptor extends NamedCommandDescriptor> = {
descriptors: readonly TDescriptor[];
getDescriptors: () => readonly TDescriptor[];
getNames: () => string[];
+1 -1
View File
@@ -16,7 +16,7 @@ export type CommandGroupDescriptorSpec<TRegister> = {
};
/** Resolved group entry after descriptor lookup. */
export type ResolvedCommandGroupEntry<TDescriptor extends NamedCommandDescriptor, TRegister> = {
type ResolvedCommandGroupEntry<TDescriptor extends NamedCommandDescriptor, TRegister> = {
placeholders: TDescriptor[];
register: TRegister;
};
+1 -6
View File
@@ -20,7 +20,7 @@ import {
type CommandGroupEntry,
} from "./register-command-groups.js";
export { getCoreCliCommandDescriptors, getCoreCliCommandsWithSubcommands };
export { getCoreCliCommandsWithSubcommands };
type CommandRegisterParams = {
program: Command;
@@ -28,11 +28,6 @@ type CommandRegisterParams = {
argv: string[];
};
export type CommandRegistration = {
id: string;
register: (params: CommandRegisterParams) => void;
};
function withProgramOnlySpecs(
specs: readonly CommandGroupDescriptorSpec<(program: Command) => Promise<void> | void>[],
): CommandGroupDescriptorSpec<(params: CommandRegisterParams) => Promise<void>>[] {
-6
View File
@@ -1,10 +1,8 @@
// Program command registry facade: exports core descriptors and registers core plus sub-CLIs.
import type { Command } from "commander";
import {
getCoreCliCommandDescriptors,
getCoreCliCommandNames,
getCoreCliCommandsWithSubcommands,
type CommandRegistration,
registerCoreCliByName,
registerCoreCliCommands,
} from "./command-registry-core.js";
@@ -12,16 +10,12 @@ import type { ProgramContext } from "./context.js";
import { registerSubCliCommands } from "./register.subclis.js";
export {
getCoreCliCommandDescriptors,
getCoreCliCommandNames,
getCoreCliCommandsWithSubcommands,
registerCoreCliByName,
registerCoreCliCommands,
};
/** Core command registration contract re-exported for program builders and tests. */
export type { CommandRegistration };
/** Register all root-program commands for the current argv shape. */
export function registerProgramCommands(
program: Command,
+1 -1
View File
@@ -3,7 +3,7 @@ import { defineCommandDescriptorCatalog } from "./command-descriptor-utils.js";
import type { NamedCommandDescriptor } from "./command-group-descriptors.js";
/** Descriptor shape for root commands owned by the core CLI. */
export type CoreCliCommandDescriptor = NamedCommandDescriptor;
type CoreCliCommandDescriptor = NamedCommandDescriptor;
const coreCliCommandCatalog = defineCommandDescriptorCatalog([
{
+1 -1
View File
@@ -12,7 +12,7 @@ export type CommandGroupPlaceholder = {
};
/** Commander option metadata attached to a lazy placeholder. */
export type CommandGroupPlaceholderOption = {
type CommandGroupPlaceholderOption = {
flags: string;
description: string;
};
-3
View File
@@ -20,13 +20,10 @@ import {
type CommandGroupEntry,
} from "./register-command-groups.js";
import {
getSubCliCommandsWithSubcommands,
getSubCliEntries as getSubCliEntryDescriptors,
type SubCliDescriptor,
} from "./subcli-descriptors.js";
export { getSubCliCommandsWithSubcommands };
export type SubCliRegistrationContext = {
purpose?: "runtime" | "completion";
};
-3
View File
@@ -21,13 +21,10 @@ import {
type SubCliRegistrationContext,
} from "./register.subclis-core.js";
import {
getSubCliCommandsWithSubcommands,
getSubCliEntries as getSubCliEntryDescriptors,
type SubCliDescriptor,
} from "./subcli-descriptors.js";
export { getSubCliCommandsWithSubcommands };
type SubCliRegistrar = (
program: Command,
argv: string[],

Some files were not shown because too many files have changed in this diff Show More