v0.2.7

tinyauthapp/tinyauthv0.2.7Jul 14, 2026by het0814

AI Summary

This release adds first-class TypeScript SDK integrations for Vercel AI SDK, Mastra, and OpenAI, closes security gaps including agent lifecycle management auth and recall filter injection, and fixes event-loop-blocking bugs in on-prem restart and session end.

Key Highlights

  • New TypeScript SDK integrations for Vercel AI SDK, Mastra, and OpenAI
  • Security improvements: agent lifecycle auth, recall filter injection guard, unique upload staging paths
  • Event-loop blocking fixes in on-prem restart and session end processes
  • Hardened memory-update/export edge cases in on-prem data migration

New Features

  • TypeScript SDK framework integrations with ai-sdk.ts, mastra.ts, and openai.ts modules
  • Management auth required for agent lifecycle endpoints
  • Recall filter-token injection guard preventing query-syntax injection
  • Unique on-prem upload staging paths using UUID-suffixed filenames
  • Batch upload status normalization counting 'ok' as success
  • OpenAPI/CI sync to prevent spec drift

Full Release Notes

# Release Notes for v0.2.7

This release adds first-class **TypeScript SDK integrations** for the Vercel AI SDK, Mastra, and OpenAI; closes another set of **security gaps** (agent lifecycle management auth, recall filter injection, unique on-prem upload staging paths); fixes **event-loop-blocking bugs** in on-prem restart and session end; and hardens memory-update/export edge cases uncovered in on-prem data migration.

## New Features

- **TypeScript SDK framework integrations** (`sdks/typescript/src/integrations/`)
  - New `ai-sdk.ts`: Vercel AI SDK integration exposing Memanto memories as
    AI SDK-compatible tools/context.
  - New `mastra.ts`: Mastra framework integration.
  - New `openai.ts`: OpenAI SDK integration for wiring Memanto recall/remember
    into OpenAI-based agents.
  - Shared `memory-types.ts` module for consistent memory typing across
    integrations; new peer dependencies (`ai`, `zod`, `@ai-sdk/openai`,
    `@mastra/core`, `openai`); Node engine bumped to `>=20`.
  - Full test coverage: `test/integrations/{ai-sdk,mastra,openai}.test.ts`.
  - README updated with on-prem (no-API-key) usage instructions.

## Security

- **Management auth required for agent lifecycle endpoints** (`memanto/app/routes/auth_deps.py`)
  - Agent create/list/delete/activate and `/api/v2/status` previously only
    checked that the *server* had a configured `MOORCHEH_API_KEY`, not that the
    *caller* was authorized — with the default `HOST=0.0.0.0` bind, any network
    peer could create agents, activate sessions, and obtain session tokens.
    These endpoints now require either a matching management credential
    (`Authorization: Bearer` / `X-Api-Key`) or a loopback client origin.

- **Recall filter-token injection guard** (`memanto/app/services/memory_read_service.py`)
  - `memory_type`, `tag`, `status`, and metadata key/value filters passed to
    Moorcheh's keyword query syntax are now validated against a strict
    `[A-Za-z0-9_.-]+` token pattern before being interpolated, preventing
    query-syntax injection via crafted filter values.

- **Unique on-prem upload staging paths** (`memanto/app/clients/onprem.py`)
  - Uploaded files are now staged under a UUID-suffixed filename
    (`{stem}-{uuid4}{suffix}`) instead of the original name, preventing
    same-named concurrent uploads from colliding/overwriting each other's
    staged file.

## Improvements

- **Event-loop blocking fixes** (`memanto/app/ui/routes/ui_router.py`,
  `memanto/app/services/session_service.py`)
  - `restart_onprem_backend` previously ran two blocking `subprocess.run()`
    calls (up to 360s combined) plus synchronous `httpx.get()` / `time.sleep()`
    directly inside an `async def`, freezing the entire FastAPI event loop for
    the whole restart window. Now wrapped in `asyncio.to_thread` /
    `httpx.AsyncClient` / `await asyncio.sleep`.
  - The restart lock is now cancellation-safe: the actual restart runs as an
    independent task guarded by `asyncio.shield()`, so a cancelled HTTP handler
    (e.g. client timeout) can no longer release the lock while `moorcheh
    down/up` is still running, which previously let concurrent restarts
    interleave subprocess calls against the same stack.
  - `end_session` always returned `memories_created=0` due to an unresolved
    TODO; it now snapshots the live Moorcheh namespace document count
    before/after ending the session and reports the delta (best-effort — falls
    back to 0 if Moorcheh is unreachable).

- **Batch upload status normalization** (`memanto/app/services/memory_write_service.py`)
  - Batch memory writes now count `"ok"` (in addition to `"queued"`/`"success"`)
    as a successful per-item status, and count `"failed"` case-insensitively —
    on-prem batch uploads were previously miscounted as failed despite
    succeeding.

- **On-prem answer model omission** (`memanto/app/services/conversation_memory_extraction_service.py`)
  - Conversation extraction now omits `ai_model` when no on-prem LLM is
    configured (falls back to `get_active_llm_model`), letting the server pick
    its own default instead of erroring, matching the existing `answer`
    endpoint behavior.

- **`memanto export` refuses to overwrite a good cache on backend outage**
  (`memanto/cli/client/{direct_client,sdk_client}.py`)
  - `export_memory_md` previously swallowed every per-type recall failure into
    an empty list and wrote it unconditionally — during a full backend outage
    this silently wiped the cached export (and, via `sync_memory_to_project`,
    the project's `MEMORY.md`) even though nothing was actually forgotten. Now
    raises `ConnectionError` when *every* memory type fails to recall (a
    genuine "no memories of this type" still exports fine); `sync_memory_to_project`
    falls back to the previous export (`"stale-cache"`) when a refresh fails
    and a prior export exists.

- **Memory-update metadata handling** (`memanto/app/services/memory_write_service.py`)
  - `update_memory` now preserves extra metadata fields from the existing
    record (e.g. on-prem `original_id`) that aren't part of the `MemoryRecord`
    schema — but explicitly excludes the trust fields removed on 2026-06-29
    (`superseded_by`, `supersedes`, `validated_at`, `validation_count`,
    `contradiction_detected`) so old on-prem records don't resurrect dead
    schema on update.

- **OpenAPI/CI sync** (`scripts/generate_openapi.py`, `.github/workflows/sdk-typescript.yml`)
  - `generate_openapi.py` now pins a fallback version before importing the app
    so the spec doesn't drift on every commit from the hatch-vcs-derived
    version; CI updated to catch TypeScript `openapi.json` drift.

## Tests

- New `tests/test_memory_read_filter_sanitization.py`, `tests/test_export_resilience.py`,
  and expanded `tests/test_backend.py` / `tests/test_unit.py` / `tests/test_api.py`
  covering the filter-injection guard, stale-cache export fallback, batch
  upload status normalization, and trust-field exclusion on update.
- New `sdks/typescript/test/integrations/*.test.ts` for the three new SDK
  integrations.

## Full Changelog

Full Changelog: https://github.com/moorcheh-ai/memanto/compare/v0.2.6...v0.2.7