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) andclient.memories.create(JavaScript) store the report. Both return a save receipt, not a bare id.await_receiptandawaitReceiptwait until the save has a final outcome.metadata.record_idis how this dataset identifies a record, so the script looks it up first and a second run adds nothing.metadata.valid_start_timeis 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:00JavaScript
// 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:00Notes
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.