Adds the SDK-facing tools.invoke Gateway RPC for #74705.
Reuses the /tools/invoke policy path for tool policy, deny-list, owner filtering, before-tool-call hooks, session/agent scoping, and plugin approval handling. Returns typed SDK approval/refusal/success results while preserving HTTP compatibility and uses idempotencyKey as the stable tool-call id.
Includes protocol schema exports, method scope/list registration, SDK helper/types, docs, generated Swift models, tests, and changelog credit.
Harden gateway recovery diagnostics and media delivery.\n\n- Accept gateway send asVoice and map it to outbound audioAsVoice.\n- Preserve generated Swift protocol models for the gateway send schema.\n- Keep the broader recovery hardening for install/update/status/vector/TTS paths in one reviewed PR.\n\nProof:\n- Focused local gateway/outbound/update/status/doctor/sqlite-vec tests passed.\n- oxfmt --check and git diff --check passed.\n- Testbox OPENCLAW_TESTBOX=1 pnpm check:changed passed at 2f5ef650e97763a61ff43c28e61707db84c50060.\n- GitHub required checks are green at the merge SHA; the qa-lab parity gate is optional/surface-only and was still pending.
* Manage Codex app-server binary
* Use plugin deps for Codex app-server binary
* Stabilize media model registry test
* Exclude checkpoint transcripts from memory ingestion
* fix(memory-host-sdk): use TRUSTED_ENV_PROXY mode in withRemoteHttpResponse
When a HTTP/HTTPS proxy is configured via environment variables
(HTTPS_PROXY, HTTP_PROXY, ALL_PROXY), the withRemoteHttpResponse
function now passes mode=TRUSTED_ENV_PROXY to fetchWithSsrFGuard.
This causes DNS resolution to skip the local resolver and route
through the configured proxy, fixing 'fetch failed' errors for
remote memory embeddings (including GitHub Copilot embeddings) in
proxy environments (e.g. Clash TUN, corporate proxies).
Previously, without an explicit mode, fetchWithSsrFGuard defaulted
to STRICT mode which performs local DNS pre-resolution via
resolvePinnedHostnameWithPolicy(), failing in proxy environments
where DNS must go through the proxy.
Fixes: openclaw/openclaw#52162
* fix: harden memory env proxy guard (#71506) (thanks @DhtIsCoding)
---------
Co-authored-by: Dht <dht@openclaw.ai>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Expose raw `vectorScore` and `textScore` alongside the combined hybrid memory search `score`.
- Preserve vector/text component scores from `mergeHybridResults` output.
- Add optional component-score fields to both memory host SDK type surfaces.
- Extend hybrid merge tests for vector-only, text-only, and overlapping result cases.
- Document that component scores remain raw retrieval diagnostics while temporal decay/MMR only adjust or reorder the combined ranking `score`.
Closes#68166.
Maintainer verification:
- `pnpm test extensions/memory-core/src/memory/hybrid.test.ts`
- `pnpm check:changed`
- Fresh GitHub checks passed.
Co-authored-by: Alex Fries <alex@engramlabs.io>
* [EV-001] memory-core: filter memory_search session hits by visibility
- Move session visibility + listSpawnedSessionKeys to plugin-sdk; sync test
hook with sessions-resolution __testing.setDepsForTest
- Extract loadCombinedSessionStoreForGateway to config/sessions; re-export
from gateway session-utils
- Add session-transcript-hit stem resolver for builtin + QMD paths
- Post-filter memory_search results before citations/recall; fail closed when
requester session key missing; optional corpus=sessions
- Tests: stem extraction, visibility filter smoke, existing suites green
* chore: sync plugin-sdk exports for session-transcript-hit and session-visibility
Run pnpm plugin-sdk:sync-exports so package.json exports match
scripts/lib/plugin-sdk-entrypoints.json. Fixes contract tests and
lint:plugins:plugin-sdk-subpaths-exported for memory-core imports.
* fix(EV-001): cross-agent session memory hits + hoist combined store load
- resolveTranscriptStemToSessionKeys: stop filtering by requester agentId so
keys from other agents reach createSessionVisibilityGuard (a2a + visibility=all).
- Re-export loadCombinedSessionStoreForGateway from session-transcript-hit;
filterMemorySearchHitsBySessionVisibility loads the combined store once per pass.
- Drop unused agentId from filter params; extend tests (Greptile/Codex review).
* fix(memory_search): honor corpus=sessions before maxResults cap
Pass sources into MemoryIndexManager.search so FTS/vector queries add
source IN (...) before ranking and top-N slice (Codex: non-session hits
could fill the window).
QMD path: oversample fetch limit for single-source recall, filter by
source, then diversify/clamp to the requested maxResults.
Wire corpus=sessions from tools; extend MemorySearchManager opts and
wrappers.
* fix(memory_search): apply corpus=memory source filter like sessions
Pass sources: ["memory"] into manager.search so maxResults applies only
within the memory index; post-filter for defense in depth. Document
corpus=memory in the tool description.
* fix: scope qmd session memory search
* fix: enforce memory search session visibility (#70761) (thanks @nefainl)
---------
Co-authored-by: NefAI <info@nefai.nl>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>