Implement src/serialize.ts with unit tests (EJSON + truncation) #138
Labels
No labels
bug
chore
documentation
enhancement
feature
ready
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
david/pi-extensions-and-skills#138
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement
extensions/mongodb/src/serialize.ts—ejsonSerializeWithTruncation(docs), which serializes query results as Extended JSON with a byte cap that truncates only at document boundaries — with unit tests.Background
Depends on: #133
mongo_find(a later step) returns query documents through this module. Two concerns are solved here: (1) BSON types (ObjectId, Date, Binary, Decimal128, Long) have no plain-JSON equivalent — plainJSON.stringifyflattens ObjectId to a bare hex string and mangles Binary/Long — so results must be serialized with MongoDB's Extended JSON (EJSON), which renders them losslessly ({"$oid": ...},{"$date": ...},{"$binary": ...},{"$numberDecimal": ...}); (2) the LLM's context window must be protected from unbounded output, so output is byte-capped and, when truncated, a visible marker tells the agent to narrow the filter/projection rather than silently missing data. UsesOUTPUT_BYTE_CAPfromsrc/defaults.ts(sibling step in this milestone — do it first).Documentation Required
A separate process downloads these into the listed folder before this issue is implemented. Check the folder for the actual reference material before starting.
docs/reference/mongodb-driver/— for theEJSONAPI (re-exported from thebsonpackage via themongodbdriver):EJSON.stringify()(relaxed mode is the default;{ relaxed: false }for canonical),EJSON.parse()(accepts both relaxed and canonical), worked examples for ObjectId/Date/Code/Binary.EJSONconst:stringify,parse,serialize,deserializesignatures.Implementation Details
ejsonSerializeWithTruncation(docs: Document[]): { text: string; truncated: boolean; docCount: number }EJSON.stringify(doc, null, 2)(relaxed — the default;EJSONis available asimport { EJSON } from "mongodb"orBSON.EJSON) and accumulate into an array of strings, tracking a running byte length (Buffer.byteLength(str)ornew TextEncoder().encode(str).length— both work under bun).OUTPUT_BYTE_CAP(100 000), stop — the array is never cut mid-document, so the output stays valid JSON.\n… (truncated: <returned> of <total> docs, <bytes>/<cap> bytes)where<returned>= number of docs actually serialized,<total>=docs.length,<bytes>= the byte length of the accumulated text before the marker,<cap>=OUTPUT_BYTE_CAP.{ text, truncated, docCount }—truncatedtrue iff at least one doc was dropped;docCount= number of docs serialized.Write co-located tests in
src/serialize.test.ts(bun test):EJSON.parse(EJSON.stringify(doc))preserves ObjectId/Date/Binary/Decimal128 (assert the BSON types survive the round-trip).truncated: false, no marker.<returned>/<total>; the JSON before the marker parses cleanly (JSON.parse/EJSON.parse).truncatedflag anddocCountcorrect in both cases.Acceptance Criteria
truncated: false, no marker.… (truncated: <returned> of <total> docs, <bytes>/<cap> bytes)is present and correct when truncated.truncatedflag anddocCountare correct in both cases.bun testinextensions/mongodb/is green forsrc/serialize.ts.Test Plan
pi-loop opened and merged a pull request for this issue: #155