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
This commit is contained in:
Saket Aryan
2026-09-15 00:42:44 +05:30
parent 5104cc3276
commit e9cbc626c0
2 changed files with 27 additions and 5 deletions
@@ -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):
+6 -1
View File
@@ -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 ?? [];
};