Skip to content

feat(api): local HTTP/REST API for memory (#85) - #122

Merged
jaylfc merged 1 commit into
masterfrom
feat/http-api
Jun 7, 2026
Merged

feat(api): local HTTP/REST API for memory (#85)#122
jaylfc merged 1 commit into
masterfrom
feat/http-api

Conversation

@jaylfc

@jaylfc jaylfc commented Jun 7, 2026

Copy link
Copy Markdown
Owner

Adds a local HTTP/REST activation surface for taOSmd memory, plus a small shared service layer the upcoming MCP server (#84) reuses. This addresses the "API/HTTP is WIP" gap noted in memory-landscape comparisons.

Endpoints

  • GET /health -> {"status":"ok","version"}
  • POST /ingest {text, agent} -> ingest result ({archived, agent, data_dir})
  • POST /search {query, agent, limit?} -> {"hits":[...]}
  • GET /search?q=&agent=&limit= -> {"hits":[...]}
  • GET /pending?agent= -> {"pending":[...]}
  • POST /pending/resolve {id, decision, note?} -> resolve result

Errors return JSON with the right status: 400 (bad input / malformed JSON), 404 (unknown route), 500 (unhandled, with message).

Design

  • stdlib only, zero new depshttp.server.ThreadingHTTPServer + BaseHTTPRequestHandler, json, threading. Nothing added to requirements.
  • Local-first — binds 127.0.0.1 by default (localhost only). Pass --host 0.0.0.0 to expose on the LAN. No auth: fine on localhost (any local process already has the Python API); gate it yourself if you bind to a routable address. The startup banner says which mode is active.
  • Additive + opt-in — the server only runs when started via taosmd serve. Python API, CLI, and standalone use are unchanged.
  • Per-agent scoping — every endpoint takes an agent and forwards it to the service layer, honouring the same isolation as the Python API.
  • Shared service layer — new taosmd/service.py wraps taosmd.api into adapter-agnostic functions (ingest, search, pending_list, pending_resolve, stats). It reuses _ensure_stores / the stores cache / TAOSMD_DATA_DIR handling so behaviour matches the Python API exactly. The MCP server (Add MCP server interface for memory (retrieve / ingest / review) #84) sits on the same core.
  • Concurrency — DB stores hold thread-affine SQLite connections, so instead of asyncio.run per request, all async service calls are dispatched onto one long-lived background event-loop thread. Every DB op runs in a single context, sequentially, like the single-threaded Python API.

CLI

taosmd serve --host 127.0.0.1 --port 7833 [--serve-data-dir ...]

Tests

tests/test_http_server.py (8 tests): boots the server on an ephemeral port in a thread with an isolated tmp data dir and a patched embedder (offline, no model). Covers health, ingest->search round-trip, GET-style search, 400 on bad JSON, 400 on missing field, 404 on unknown route, empty pending, and bad pending-resolve input. Full suite: 319 passed.

Closes #85

Summary by CodeRabbit

  • New Features
    • Added a local HTTP/REST API for memory operations including ingestion, search, and pending item resolution
    • Added a new CLI command to run the API server locally with customizable host and port settings

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0b896438-cd62-495b-adcb-d690eaa805de

📥 Commits

Reviewing files that changed from the base of the PR and between 0f2ac97 and 71e45fa.

📒 Files selected for processing (5)
  • taosmd/__init__.py
  • taosmd/cli.py
  • taosmd/http_server.py
  • taosmd/service.py
  • tests/test_http_server.py

📝 Walkthrough

Walkthrough

This PR introduces a complete local HTTP/REST API for taOSmd memory operations. It adds a reusable async service layer that wraps the underlying API, a stdlib-only HTTP server with background asyncio concurrency, CLI integration via a serve subcommand, and comprehensive integration tests validating all endpoints and error handling.

Changes

Local HTTP/REST API

Layer / File(s) Summary
Service layer async wrappers
taosmd/service.py
Defines thin async wrappers (ingest, search, pending_list, pending_resolve, stats) that standardize signatures around agent and optional data_dir, forwarding to taosmd.api. The stats function handles unknown agents gracefully by returning registered=False instead of raising.
HTTP server core with concurrency
taosmd/http_server.py
Implements a stdlib-only HTTP server with a background asyncio event loop (_ServiceLoop) that isolates thread-affine SQLite work. Routes GET/HEAD/POST to /health, /ingest, /search, /pending, /pending/resolve; validates request bodies and query parameters; enforces a decision whitelist; maps validation errors to 400 and unexpected exceptions to 500 with logging.
CLI serve subcommand and package exports
taosmd/cli.py, taosmd/__init__.py
Registers a serve subcommand with --host, --port, and --serve-data-dir options that dispatch to http_server.serve() before AgentRegistry initialization. Exports service module and serve function from the package namespace.
HTTP server integration tests
tests/test_http_server.py
Boots the server on an ephemeral port with isolated temporary data; patches the vector embedder with deterministic hash-based vectors for reproducible search; validates /health status, ingest/search roundtrips with query parameters, JSON and field validation (returning 400), unknown routes (404), empty pending lists, and invalid decision values.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • jaylfc/taosmd#85: The PR implements the requested local HTTP/REST API and shared service layer (taosmd/service.py, taosmd/http_server.py) with endpoints /health, /ingest, /search, /pending, /pending/resolve directly addressing the functionality described in the issue.

Possibly related PRs

  • jaylfc/taosmd#60: The new HTTP endpoints (/ingest, /search) directly forward to taosmd.api.ingest() and taosmd.api.search(), which were added in that PR and form the underlying foundation for this HTTP API.

Poem

🐰 A REST-ful rabbit hops with glee,
Through /health and /search so free,
Async loops in daemon threads they run,
SQLite stays safe—no race, all fun!
The service layer speaks in gentle ways,
HTTP blooms bright through all its days. ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/http-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jaylfc
jaylfc merged commit 18daec8 into master Jun 7, 2026
1 of 2 checks passed
@jaylfc
jaylfc deleted the feat/http-api branch June 7, 2026 11:28
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.

Add local HTTP/REST API server for memory (ingest / retrieve / review)

1 participant