Skip to content

tests: stabilize sessions_spawn mock/import ordering#1

Merged
dkdimou merged 3909 commits intomainfrom
pr/sessions-spawn-stabilization
Mar 15, 2026
Merged

tests: stabilize sessions_spawn mock/import ordering#1
dkdimou merged 3909 commits intomainfrom
pr/sessions-spawn-stabilization

Conversation

@dkdimou
Copy link
Copy Markdown
Owner

@dkdimou dkdimou commented Mar 15, 2026

Summary

  • stabilize sessions_spawn tests by avoiding eager import/cycle hazards
  • make accepted-note assertions version-safe via runtime constant import
  • align depth-limit test formatting and deterministic setup behavior

Validation

  • local focused suites pass
  • CI checks green on the branch before handoff

steipete and others added 30 commits March 14, 2026 00:33
…3912) (openclaw#34262)

* fix(feishu): preserve non-ASCII filenames in file uploads (openclaw#33912)

* style(feishu): format media test file

* fix(feishu): preserve UTF-8 filenames in file uploads (openclaw#34262) thanks @fabiaodemianyang

---------

Co-authored-by: Robin Waslander <[email protected]>
…claw#13707)

Fix macOS gateway exec approvals to respect exec-approvals.json.

This updates the macOS gateway prompter to resolve per-agent exec approval policy before deciding whether to show UI, use agentId for policy lookup, honor askFallback when prompts cannot be presented, and resolve no-prompt decisions from the configured security policy instead of hardcoded allow-once behavior. It also adds regression coverage for ask-policy and allowlist-fallback behavior, plus a changelog entry for the fix.

Co-authored-by: ImLukeF <[email protected]>
vincentkoc and others added 26 commits March 14, 2026 23:06
…runtime capability detection (openclaw#45824)

* fix: fetch OpenRouter model capabilities at runtime for unknown models

When an OpenRouter model is not in the built-in static snapshot from
pi-ai, the fallback hardcodes input: ["text"], silently dropping images.

Query the OpenRouter API at runtime to detect actual capabilities
(image support, reasoning, context window) for models not in the
built-in list. Results are cached in memory for 1 hour. On API
failure/timeout, falls back to text-only (no regression).

* feat(openrouter): add disk cache for OpenRouter model capabilities

Persist the OpenRouter model catalog to ~/.openclaw/cache/openrouter-models.json
so it survives process restarts. Cache lookup order:

1. In-memory Map (instant)
2. On-disk JSON file (avoids network on restart)
3. OpenRouter API fetch (populates both layers)

Also triggers a background refresh when a model is not found in the cache,
in case it was newly added to OpenRouter.

* refactor(openrouter): remove pre-warm, use pure lazy-load with disk cache

- Remove eager ensureOpenRouterModelCache() from run.ts
- Remove TTL — model capabilities are stable, no periodic re-fetching
- Cache lookup: in-memory → disk → API fetch (only when needed)
- API is only called when no cache exists or a model is not found
- Disk cache persists across gateway restarts

* fix(openrouter): address review feedback

- Fix timer leak: move clearTimeout to finally block
- Fix modality check: only check input side of "->" separator to avoid
  matching image-generation models (text->image)
- Use resolveStateDir() instead of hardcoded homedir()/.openclaw
- Separate cache dir and filename constants
- Add utf-8 encoding to writeFileSync for consistency
- Add data validation when reading disk cache

* ci: retrigger checks

* fix: preload unknown OpenRouter model capabilities before resolve

* fix: accept top-level OpenRouter max token metadata

* fix: update changelog for OpenRouter runtime capability lookup (openclaw#45824) (thanks @DJjjjhao)

* fix: avoid redundant OpenRouter refetches and preserve suppression guards

---------

Co-authored-by: Ayaan Zaidi <[email protected]>
…law#46788)

* Tlon: fail closed on explicit empty allowlists

* Tlon: preserve cited content for owner DMs
)

* macOS: restrict canvas agent actions to trusted surfaces

* Changelog: note trusted macOS canvas actions

* macOS: encode allowed canvas schemes as JSON
…tion.timeoutSeconds (openclaw#46889)

* feat: make compaction timeout configurable via agents.defaults.compaction.timeoutSeconds

The hardcoded 5-minute (300s) compaction timeout causes large sessions
to enter a death spiral where compaction repeatedly fails and the
session grows indefinitely. This adds agents.defaults.compaction.timeoutSeconds
to allow operators to override the compaction safety timeout.

Default raised to 900s (15min) which is sufficient for sessions up to
~400k tokens. The resolved timeout is also used for the session write
lock duration so locks don't expire before compaction completes.

Fixes openclaw#38233

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* test: add resolveCompactionTimeoutMs tests

Cover config resolution edge cases: undefined config, missing
compaction section, valid seconds, fractional values, zero,
negative, NaN, and Infinity.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: add timeoutSeconds to compaction Zod schema

The compaction object schema uses .strict(), so setting the new
timeoutSeconds config option would fail validation at startup.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: enforce integer constraint on compaction timeoutSeconds schema

Prevents sub-second values like 0.5 which would floor to 0ms and
cause immediate compaction timeout. Matches pattern of other
integer timeout fields in the schema.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: clamp compaction timeout to Node timer-safe maximum

Values above ~2.1B ms overflow Node's setTimeout to 1ms, causing
immediate timeout. Clamp to MAX_SAFE_TIMEOUT_MS matching the
pattern in agents/timeout.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: add FIELD_LABELS entry for compaction timeoutSeconds

Maintains label/help parity invariant enforced by
schema.help.quality.test.ts.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: align compaction timeouts with abort handling

* fix: land compaction timeout handling (openclaw#46889) (thanks @asyncjason)

---------

Co-authored-by: Jason Separovic <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
openclaw#41563)

Update 5 references to the old "Clawdbot" name in
skills/apple-reminders/SKILL.md and skills/imsg/SKILL.md.

Co-authored-by: imanisynapse <[email protected]>
…atible APIs (openclaw#45497)

Merged via squash.

Prepared head SHA: 20fe05f
Co-authored-by: sahancava <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
* fix(android): support android node  `calllog.search`

* fix(android): support android node calllog.search

* fix(android): wire callLog through shared surfaces

* fix: land Android callLog support (openclaw#44073) (thanks @lxk7280)

---------

Co-authored-by: lixuankai <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
…tor, handle Long timestamps (openclaw#42588)

Merged via squash.

Prepared head SHA: 8ce59bb
Co-authored-by: MonkeyLeeT <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Reviewed-by: @scoootscooob
…w#27910)

* fix(web): handle 515 Stream Error during WhatsApp QR pairing

getStatusCode() never unwrapped the lastDisconnect wrapper object,
so login.errorStatus was always undefined and the 515 restart path
in restartLoginSocket was dead code.

- Add err.error?.output?.statusCode fallback to getStatusCode()
- Export waitForCredsSaveQueue() so callers can await pending creds
- Await creds flush in restartLoginSocket before creating new socket

Fixes openclaw#3942

* test: update session mock for getStatusCode unwrap + waitForCredsSaveQueue

Mirror the getStatusCode fix (err.error?.output?.statusCode fallback)
in the test mock and export waitForCredsSaveQueue so restartLoginSocket
tests work correctly.

* fix(web): scope creds save queue per-authDir to avoid cross-account blocking

The credential save queue was a single global promise chain shared by all
WhatsApp accounts. In multi-account setups, a slow save on one account
blocked credential writes and 515 restart recovery for unrelated accounts.

Replace the global queue with a per-authDir Map so each account's creds
serialize independently. waitForCredsSaveQueue() now accepts an optional
authDir to wait on a single account's queue, or waits on all when omitted.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* test: use real Baileys v7 error shape in 515 restart test

The test was using { output: { statusCode: 515 } } which was already
handled before the fix. Updated to use the actual Baileys v7 shape
{ error: { output: { statusCode: 515 } } } to cover the new fallback
path in getStatusCode.

Co-Authored-By: Claude Code (Opus 4.6) <[email protected]>

* fix(web): bound credential-queue wait during 515 restart

Prevents restartLoginSocket from blocking indefinitely if a queued
saveCreds() promise stalls (e.g. hung filesystem write).

Co-Authored-By: Claude <[email protected]>

* fix: clear flush timeout handle and assert creds queue in test

Co-Authored-By: Claude <[email protected]>

* fix: evict settled credsSaveQueues entries to prevent unbounded growth

Co-Authored-By: Claude <[email protected]>

* fix: share WhatsApp 515 creds flush handling (openclaw#27910) (thanks @asyncjason)

---------

Co-authored-by: Jason Separovic <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
…aw#40996)

Merged via squash.

Prepared head SHA: 38d8048
Co-authored-by: xaeon2026 <[email protected]>
Co-authored-by: frankekn <[email protected]>
Reviewed-by: @frankekn
…nclaw#42931) (openclaw#47148)

When auth is completely disabled (mode=none), requiring device pairing
for Control UI operator sessions adds friction without security value
since any client can already connect without credentials.

Add authMode parameter to shouldSkipControlUiPairing so the bypass
fires only for Control UI + operator role + auth.mode=none. This avoids
the openclaw#43478 regression where a top-level OR disabled pairing for ALL
websocket clients.
…#47274)

* fix: preserve Telegram chunk word boundaries

* fix: address Telegram chunking review feedback

* fix: preserve Telegram retry separators

* fix: preserve Telegram chunking boundaries (openclaw#47274)
Copilot AI review requested due to automatic review settings March 15, 2026 15:54
@dkdimou dkdimou merged commit 52fb86e into main Mar 15, 2026
3 of 11 checks passed
@dkdimou dkdimou deleted the pr/sessions-spawn-stabilization branch March 15, 2026 15:54
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR performs a broad Android + tooling refactor (package rename to ai.openclaw.app, new node capability/command registry, new camera/notifications/call-log handlers), plus CI/workflow and repo-maintenance updates (new CodeQL workflow, action version bumps, linting, Docker build optimizations, and docs/policy updates).

Changes:

  • Android: rename packages/namespaces, add new node capability/command registry, and add/replace handlers for notifications, camera, and call log.
  • CI/automation: introduce new workflows (CodeQL, npm release) and update multiple workflow/action versions + caching behavior.
  • Docs/policies: expand SECURITY/CONTRIBUTING/AGENTS guidance and update Android docs + permissions.

Reviewed changes

Copilot reviewed 111 out of 5630 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
apps/android/app/src/main/java/ai/openclaw/app/node/InvokeCommandRegistry.kt Adds centralized registry for commands/capabilities and runtime flag gating.
apps/android/app/src/main/java/ai/openclaw/app/node/GatewayEventHandler.kt Renames package/imports to ai.openclaw.app.*.
apps/android/app/src/main/java/ai/openclaw/app/node/DeviceNotificationListenerService.kt Reworks notification listener to emit change events + add action execution.
apps/android/app/src/main/java/ai/openclaw/app/node/DebugHandler.kt Renames package/imports and fixes JSON escaping via JsonPrimitive.
apps/android/app/src/main/java/ai/openclaw/app/node/ConnectionManager.kt Uses NodeRuntimeFlags and registry-driven advertised commands/capabilities.
apps/android/app/src/main/java/ai/openclaw/app/node/CanvasController.kt Adds “home canvas state” JS bridge + factors bitmap scaling helper.
apps/android/app/src/main/java/ai/openclaw/app/node/CameraHandler.kt Adds camera list/snap/clip invoke handlers with debug logging + payload limit checks.
apps/android/app/src/main/java/ai/openclaw/app/node/CameraCaptureManager.kt Adds camera device listing + deviceId selection + switches param parsing to JSON objects.
apps/android/app/src/main/java/ai/openclaw/app/node/CallLogHandler.kt Adds call log search handler + permission checks and JSON request parsing.
apps/android/app/src/main/java/ai/openclaw/app/node/A2UIHandler.kt Renames package/imports to new ai.openclaw.app.* path.
apps/android/app/src/main/java/ai/openclaw/app/gateway/InvokeErrorParser.kt Renames gateway package to ai.openclaw.app.gateway.
apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayTls.kt Renames gateway package to ai.openclaw.app.gateway.
apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayProtocol.kt Adds gateway protocol constant under new package.
apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayEndpoint.kt Renames gateway package to ai.openclaw.app.gateway.
apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayDiscovery.kt Renames gateway package to ai.openclaw.app.gateway.
apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceIdentityStore.kt Renames gateway package to ai.openclaw.app.gateway.
apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceAuthStore.kt Adds clearToken to interface and overrides implementation.
apps/android/app/src/main/java/ai/openclaw/app/gateway/DeviceAuthPayload.kt Renames gateway package to ai.openclaw.app.gateway.
apps/android/app/src/main/java/ai/openclaw/app/gateway/BonjourEscapes.kt Renames gateway package to ai.openclaw.app.gateway.
apps/android/app/src/main/java/ai/openclaw/app/chat/ChatModels.kt Renames chat package to ai.openclaw.app.chat.
apps/android/app/src/main/java/ai/openclaw/app/chat/ChatController.kt Tweaks streaming delta handling to only show for initiated runs.
apps/android/app/src/main/java/ai/openclaw/app/WakeWords.kt Renames package to ai.openclaw.app.
apps/android/app/src/main/java/ai/openclaw/app/VoiceWakeMode.kt Renames package to ai.openclaw.app.
apps/android/app/src/main/java/ai/openclaw/app/SessionKey.kt Renames package to ai.openclaw.app.
apps/android/app/src/main/java/ai/openclaw/app/SecurePrefs.kt Renames package + adds override injection + new bootstrap token and speaker prefs.
apps/android/app/src/main/java/ai/openclaw/app/PermissionRequester.kt Renames package to ai.openclaw.app.
apps/android/app/src/main/java/ai/openclaw/app/NodeForegroundService.kt Simplifies foreground type usage and updates stop action namespace.
apps/android/app/src/main/java/ai/openclaw/app/NodeApp.kt Renames package to ai.openclaw.app.
apps/android/app/src/main/java/ai/openclaw/app/MainViewModel.kt Removes screen recorder bindings and adds new runtime flows/methods (speaker/mic cooldown, etc.).
apps/android/app/src/main/java/ai/openclaw/app/MainActivity.kt Removes screen capture wiring; updates UI imports to ai.openclaw.app.ui.
apps/android/app/src/main/java/ai/openclaw/app/LocationMode.kt Removes Always mode; maps legacy “always” to WhileUsing.
apps/android/app/src/main/java/ai/openclaw/app/DeviceNames.kt Renames package to ai.openclaw.app.
apps/android/app/src/main/java/ai/openclaw/app/CameraHudState.kt Renames package to ai.openclaw.app.
apps/android/app/src/main/AndroidManifest.xml Adds new runtime permissions, updates foreground service type, removes update receiver.
apps/android/app/proguard-rules.pro Removes many keep rules; retains dontwarn rules.
apps/android/app/build.gradle.kts Renames namespace/applicationId, adds release signing gating, ktlint, packaging excludes, and DNSJava resource stripping task.
apps/android/README.md Updates Android status checklist and adds integration test instructions.
Swabble/Tests/SwabbleKitTests/WakeWordGateTests.swift Adds regression test for foreign range indices in segments.
Swabble/Sources/SwabbleKit/WakeWordGate.swift Avoids slicing transcript using segment ranges; builds command words from segments.
SECURITY.md Expands security triage guidance and clarifies trust boundaries and out-of-scope classes.
Dockerfile.sandbox-common Enables BuildKit syntax and uses cached apt mounts + adds apt-get upgrade.
Dockerfile.sandbox-browser Enables BuildKit syntax, cached apt mounts, apt-get upgrade, and COPY --chmod.
Dockerfile.sandbox Enables BuildKit syntax, cached apt mounts, and apt-get upgrade.
CONTRIBUTING.md Updates contributor list and adds AI/bot-conversation expectations.
AGENTS.md Adds new PR/bot handling, dynamic import rules, release notes, and extensive platform smoke guidance.
.swiftlint.yml Updates generated-file exclusions.
.swiftformat Updates exclusions to new protocol paths and generated file.
.pre-commit-config.yaml Tightens detect-secrets exclude-files and adds multiple exclude-lines and file exclusions.
.pi/prompts/reviewpr.md Adds “truthfulness gate” and formal claim verification matrix to review prompt.
.pi/prompts/landpr.md Switches merge preference to squash; clarifies strategy.
.pi/extensions/ui/paged-select.ts Adds reusable paged select list UI component.
.pi/extensions/prompt-url-widget.ts Refactors repeated widget rendering into a helper function.
.pi/extensions/files.ts Uses new paged select list helper instead of inlined UI picker.
.pi/extensions/diff.ts Uses new paged select list helper instead of inlined UI picker.
.npmignore Adds ignore for nested node_modules in npm publish.
.jscpd.json Adds duplication checker config with ignore globs.
.github/workflows/workflow-sanity.yml Adds workflow_dispatch job, updates checkout version, and adds Node24 forcing env.
.github/workflows/stale.yml Adds Node24 forcing env, adds token fallback logic, bumps stale action version, adds issue locking job.
.github/workflows/sandbox-common-smoke.yml Updates checkout version, adds Node24 forcing env, and sets up buildx.
.github/workflows/openclaw-npm-release.yml Adds tag-based + manual npm publish workflow with release checks.
.github/workflows/install-smoke.yml Updates checkout version, adds base-commit fetch helper, rewires docker smoke builds.
.github/workflows/codeql.yml Adds on-demand CodeQL workflow across multiple languages with explicit builds.
.github/workflows/auto-response.yml Adds Node24 forcing env, token fallback, spam handling, bug subtype label syncing, and PR limit logic.
.github/pull_request_template.md Adds checklist for resolving bot review conversations.
.github/labeler.yml Removes src-based channel globs (keeps extensions/docs).
.github/dependabot.yml Adds npm registry token and increases update cadence with shorter cooldown.
.github/codeql/codeql-javascript-typescript.yml Adds CodeQL config restricting scan paths/ignores.
.github/actions/setup-pnpm-store-cache/action.yml Updates default cache suffix and adds sticky-disk + configurable restore behavior; bumps cache action version.
.github/actions/setup-node-env/action.yml Defaults to Node24; adds cache suffix + deps-install toggle; bumps action versions.
.github/actions/ensure-base-commit/action.yml Adds composite action to deepen/fetch base commit for shallow checkouts.
.github/actionlint.yaml Adds a new runner label to allowed self-hosted list.
.github/ISSUE_TEMPLATE/bug_report.yml Adds “Bug type” dropdown and more provider/model routing fields.
.github/CODEOWNERS Adds CODEOWNERS rules (secops + release-manager ownership).
.dockerignore Excludes .env* from build context and fine-tunes inclusion of shared resources.
.detect-secrets.cfg Moves exclude patterns into .pre-commit and adds extensive exclude-line patterns.
.agent/workflows/update_clawdbot.md Renames doc to OpenClaw and updates app naming paths.

android {
namespace = "ai.openclaw.android"
compileSdk = 36
namespace = "ai.openclaw.app"
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")

defaultConfig {
applicationId = "ai.openclaw.app"
Comment on lines +123 to +130
// Skip offset rows
if (request.offset > 0 && cursor.moveToPosition(request.offset - 1)) {
// Successfully moved to offset position
}

val out = mutableListOf<CallLogRecord>()
var count = 0
while (cursor.moveToNext() && count < request.limit) {
exit 0
fi

echo "Base commit still unavailable after fetch attempts: $BASE_SHA"
Comment on lines +27 to 29
&& apt-get upgrade -y --no-install-recommends \
&& apt-get install -y --no-install-recommends ${PACKAGES}

Comment on lines +103 to +106
const items = files.map((file) => ({
value: file,
label: `${file.status} ${file.file}`,
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.