SmartMemory
ExamplesClinical trials

Ingest a monitoring visit report

Add a new CRA monitoring visit report (MVR) to the workspace, with the visit date as its valid time so that date-aware questions find it.

Set SMARTMEMORY_API_KEY, SMARTMEMORY_WORKSPACE_ID and optionally SMARTMEMORY_BASE_URL (default https://api.smartmemory.ai). See the overview for setup.

What it uses

  • client.add (Python) and client.memories.create (JavaScript) store the report. Both return a save receipt, not a bare id.
  • await_receipt and awaitReceipt wait until the save has a final outcome.
  • metadata.record_id is how this dataset identifies a record, so the script looks it up first and a second run adds nothing.
  • metadata.valid_start_time is the day the visit happened. Without it the service picks a date it finds in the text, which can be off by a day.

Python

"""Ingest a new monitoring visit report (MVR) into the "Clinical trial demo" workspace."""

import os

from smartmemory_client import SmartMemoryClient

client = SmartMemoryClient(
    base_url=os.environ.get("SMARTMEMORY_BASE_URL", "https://api.smartmemory.ai"),
    api_key=os.environ["SMARTMEMORY_API_KEY"],
    workspace_id=os.environ["SMARTMEMORY_WORKSPACE_ID"],
)

RECORD_ID = "EX-MVR-S01-20260714"
REPORT = (
    "Monitoring visit report: site 01, interim visit, 2026-07-14. "
    "CRA Nadia Kerr made an on-site interim monitoring visit to site 01 (Halvard) on 2026-07-14. "
    "Findings: (1) 100 percent source data verification of consent and eligibility for the 11 participants "
    "randomized since the last visit, no findings, (2) the week 6 liver test tracker added after DEV-05 is in use "
    "and every due test in the period was drawn inside its window, (3) the deviation log matches the visit "
    "findings under procedure v1.1, no new deviations, (4) enrolment under the raised cap of 40 is on track, "
    "(5) 7 open queries, none older than 8 business days. "
    "Action items: send the follow-up letter (Nadia Kerr, 2026-07-21), confirm the cap tracker with the "
    "sponsor (Daniel Okoro, 2026-07-24). Report finalized on 2026-07-21."
)

# Re-running must not add a second copy: records are identified by metadata.record_id.
existing = client.list_memories(metadata_key="record_id", metadata_value=RECORD_ID)
if existing["total"]:
    print(f"{RECORD_ID} is already in the workspace, nothing to do")
    raise SystemExit(0)

receipt = client.add(
    REPORT,
    memory_type="episodic",
    metadata={
        "record_id": RECORD_ID,
        "record_type": "monitoring_report",
        "study": "KVR-417-201",
        "site": "01",
        "event_date": "2026-07-14",
        # Valid time: the day the visit happened. As-of questions filter on this field.
        "valid_start_time": "2026-07-14T00:00:00+00:00",
    },
    # Leave extraction on against a real deployment. CT_EXAMPLES_PIPELINE=0 stores the text as written,
    # for a stack whose language model provider is not reachable.
    use_pipeline=os.environ.get("CT_EXAMPLES_PIPELINE", "1") != "0",
)
receipt = client.await_receipt(receipt)
print("item_id:", receipt.item_id)
print("stage:", receipt.processing_stage, "| outcome:", receipt.outcome, "| terminal:", receipt.terminal)

stored = client.get(receipt.item_id)
print("record_id:", stored.metadata["record_id"])
print("valid_start_time:", stored.valid_start_time)

Output:

item_id: 1c943109-f2d0-427a-bd0e-b40030de14ae
stage: stored | outcome: skipped | terminal: True
record_id: EX-MVR-S01-20260714
valid_start_time: 2026-07-14T00:00:00+00:00

JavaScript

// Ingest a new monitoring visit report (MVR) into the "Clinical trial demo" workspace.
import { SmartMemoryClient } from "@smartmemory/sdk-js";

const client = new SmartMemoryClient({
  apiBaseUrl: process.env.SMARTMEMORY_BASE_URL ?? "https://api.smartmemory.ai",
  apiKey: process.env.SMARTMEMORY_API_KEY,
  storage: "memory", // a script has no browser storage
});
client.setWorkspaceId(process.env.SMARTMEMORY_WORKSPACE_ID);

const RECORD_ID = "EX-MVR-S01-20260714";
const REPORT =
  "Monitoring visit report: site 01, interim visit, 2026-07-14. " +
  "CRA Nadia Kerr made an on-site interim monitoring visit to site 01 (Halvard) on 2026-07-14. " +
  "Findings: (1) 100 percent source data verification of consent and eligibility for the 11 participants " +
  "randomized since the last visit, no findings, (2) the week 6 liver test tracker added after DEV-05 is in use " +
  "and every due test in the period was drawn inside its window, (3) the deviation log matches the visit " +
  "findings under procedure v1.1, no new deviations, (4) enrolment under the raised cap of 40 is on track, " +
  "(5) 7 open queries, none older than 8 business days. " +
  "Action items: send the follow-up letter (Nadia Kerr, 2026-07-21), confirm the cap tracker with the " +
  "sponsor (Daniel Okoro, 2026-07-24). Report finalized on 2026-07-21.";

// Re-running must not add a second copy: records are identified by metadata.record_id.
const existing = await client.memories.list({ metadataKey: "record_id", metadataValue: RECORD_ID });
if (existing.total) {
  console.log(`${RECORD_ID} is already in the workspace, nothing to do`);
  process.exit(0);
}

let receipt = await client.memories.create({
  content: REPORT,
  memoryType: "episodic",
  metadata: {
    record_id: RECORD_ID,
    record_type: "monitoring_report",
    study: "KVR-417-201",
    site: "01",
    event_date: "2026-07-14",
    // Valid time: the day the visit happened. As-of questions filter on this field.
    valid_start_time: "2026-07-14T00:00:00+00:00",
  },
  // Leave extraction on against a real deployment. CT_EXAMPLES_PIPELINE=0 stores the text as written,
  // for a stack whose language model provider is not reachable.
  usePipeline: process.env.CT_EXAMPLES_PIPELINE !== "0",
});
receipt = await client.memories.awaitReceipt(receipt);
console.log("item_id:", receipt.item_id);
console.log("stage:", receipt.processing_stage, "| outcome:", receipt.outcome, "| terminal:", receipt.terminal);

const stored = await client.memories.get(receipt.item_id);
console.log("record_id:", stored.metadata.record_id);
console.log("valid_start_time:", stored.valid_start_time);

Output:

item_id: 303c4645-b4fb-4fb7-afd0-fbef797f6551
stage: stored | outcome: skipped | terminal: true
record_id: EX-MVR-S01-20260714
valid_start_time: 2026-07-14T00:00:00+00:00

Notes

The report is fictional and new, it does not copy any record in the dataset. Against a deployment with a working language model leave extraction on (the default). The local run set CT_EXAMPLES_PIPELINE=0 because the local stack's language model provider is unavailable, so the receipt shows outcome: skipped for the extraction step. The text and metadata are stored as written either way.

The output below is from a real run against a local test stack seeded with the demo dataset. It shows record ids and dates only.

On this page