From e9cbc626c039abf4f10699a9498a0c0be3cf0a54 Mon Sep 17 00:00:00 2001 From: Saket Aryan Date: Tue, 15 Sep 2026 00:42:44 +0530 Subject: [PATCH] fix(pi-agent): widen the search options by one property instead of to never CI caught what I could not check locally: `pnpm exec tsc --noEmit` fails with error TS2353: Object literal may only specify known properties, and 'source' does not exist in type 'SearchMemoryOptions'. Adding `source` to SearchMemoryOptions in mem0-ts does not help here. pi-agent resolves `mem0ai` from npm, so it typechecks against the published 3.1.8 types, not this repo's source. The declaration still belongs in mem0-ts for the next release; this call site needs to compile today. Widened by exactly that one property rather than restoring `as never`, which was the original objection: a blanket cast also disabled checking of filters, threshold, topK and rerank on the same literal. `source` reaches the wire through the SDK's camelToSnakeKeys spread either way. Verified by installing the package deps and running the real gates: tsc clean, build clean. vercel-ai-sdk typechecks clean too. Also carries the spool-test environment fix that had not been committed in this worktree. Claude-Session: https://claude.ai/code/session_01C7tEmH86HAr7GoAAKCEHZb --- .../tests/test_spool_delivery.py | 25 ++++++++++++++++--- integrations/pi-agent-plugin/src/commands.ts | 7 +++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/integrations/agent-plugin-core/tests/test_spool_delivery.py b/integrations/agent-plugin-core/tests/test_spool_delivery.py index 08266cc98..a51027904 100644 --- a/integrations/agent-plugin-core/tests/test_spool_delivery.py +++ b/integrations/agent-plugin-core/tests/test_spool_delivery.py @@ -25,15 +25,32 @@ pytestmark = pytest.mark.skipif(not HOST_CORE.exists(), reason="claude-code-plug @pytest.fixture() def telemetry(tmp_path, monkeypatch): + # CI runs this directory and claude-code-plugin/tests in ONE pytest process, + # and that suite's conftest sets MEM0_TELEMETRY=false at import, process-wide. + # Without this the whole file silently no-ops: record() returns early and + # every assertion sees an empty spool. Do not rely on ambient env. + monkeypatch.setenv("MEM0_TELEMETRY", "true") monkeypatch.setenv("MEM0_CODE_DATA_DIR", str(tmp_path / "data")) monkeypatch.syspath_prepend(str(HOST_CORE)) - for name in ("telemetry", "memory_core", "_harness_id"): + + # Save and RESTORE rather than delete. claude-code-plugin/tests/conftest.py + # imports memory_core once at collection and calls configure_harness() on it; + # dropping the module left a later re-import with default harness config, so + # tests in that suite failed depending on collection order. + names = ("telemetry", "memory_core", "_harness_id") + saved = {name: sys.modules.get(name) for name in names} + for name in names: sys.modules.pop(name, None) + module = importlib.import_module("telemetry") monkeypatch.setattr(module, "resolve_distinct_id", lambda: ("tester@example.com", "")) - yield module - for name in ("telemetry", "memory_core", "_harness_id"): - sys.modules.pop(name, None) + try: + yield module + finally: + for name in names: + sys.modules.pop(name, None) + if saved[name] is not None: + sys.modules[name] = saved[name] def _delivered(payloads): diff --git a/integrations/pi-agent-plugin/src/commands.ts b/integrations/pi-agent-plugin/src/commands.ts index f50194ed6..a733aea0a 100644 --- a/integrations/pi-agent-plugin/src/commands.ts +++ b/integrations/pi-agent-plugin/src/commands.ts @@ -1,3 +1,4 @@ +import type { SearchMemoryOptions } from "mem0ai"; import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import type MemoryClient from "mem0ai"; import type { Mem0Config, ScopeContext, Scope } from "./types.ts"; @@ -34,7 +35,11 @@ export function registerCommands( topK: SEARCH_TOP_K, rerank: true, source: PLATFORM_SOURCE, - }); + // Widened by exactly this one property. `source` reaches the wire via the + // SDK's camelToSnakeKeys spread, but it is absent from SearchMemoryOptions + // in the published mem0ai types. A blanket `as never` would also disable + // checking of filters, threshold, topK and rerank above. + } as SearchMemoryOptions & { source: string }); return result.results ?? []; };