@pdpp/read-core 0.0.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +44 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdpp/read-core",
3
- "version": "0.0.0",
3
+ "version": "0.15.1",
4
4
  "type": "module",
5
5
  "description": "Pure, adapter-agnostic primitives for shaping PDPP read results into bounded previews, continuation descriptors, handle metadata, and escalation paths.",
6
6
  "repository": {
package/src/index.js CHANGED
@@ -7,6 +7,8 @@ const DEFAULT_RECORD_PREVIEW_TRUNCATED_MARKER =
7
7
  const DEFAULT_FIELD_WINDOW_LIMIT_CHARS = 2048;
8
8
  const DEFAULT_FIELD_WINDOW_LIMIT = 8;
9
9
  const DEFAULT_BINARY_FIELD_LIMIT = 8;
10
+ const DEFAULT_JSON_FIELD_LIMIT = 8;
11
+ const DEFAULT_JSON_PREVIEW_CHAR_LIMIT = 512;
10
12
 
11
13
  const OMIT_FIELD_KEYS = new Set([
12
14
  'id',
@@ -138,18 +140,24 @@ export function buildRecordContentLadder(record, options = {}) {
138
140
  const binaryFields = recordContentBinaryFields(record, {
139
141
  binaryLimit: options.binaryLimit ?? DEFAULT_BINARY_FIELD_LIMIT,
140
142
  });
143
+ const jsonFields = recordContentJsonFields(record, identity, {
144
+ jsonLimit: options.jsonLimit ?? DEFAULT_JSON_FIELD_LIMIT,
145
+ jsonPreviewChars: options.jsonPreviewChars ?? DEFAULT_JSON_PREVIEW_CHAR_LIMIT,
146
+ });
141
147
 
142
148
  return {
143
149
  id: identity.id,
144
150
  connection_id: identity.connectionId,
145
151
  stream: identity.stream,
146
152
  record_id: identity.recordId,
153
+ handle_semantics: 'live_lookup',
147
154
  record_uri: encodeResourceUri('record', {
148
155
  connection_id: identity.connectionId,
149
156
  stream: identity.stream,
150
157
  record_id: identity.recordId,
151
158
  }),
152
159
  field_windows: fieldWindows,
160
+ ...(jsonFields.length > 0 ? { json_fields: jsonFields } : {}),
153
161
  ...(binaryFields.length > 0 ? { binary_fields: binaryFields } : {}),
154
162
  };
155
163
  }
@@ -214,6 +222,7 @@ export function binaryFieldMetadata(fieldPath, value) {
214
222
  field_path: fieldPath,
215
223
  binary_field: true,
216
224
  text_like: false,
225
+ handle_semantics: 'live_lookup',
217
226
  preview_status: 'binary-only',
218
227
  ...blob,
219
228
  };
@@ -224,6 +233,7 @@ export function binaryFieldMetadata(fieldPath, value) {
224
233
  field_path: fieldPath,
225
234
  binary_field: true,
226
235
  text_like: false,
236
+ handle_semantics: 'live_lookup',
227
237
  preview_status: 'binary-only',
228
238
  encoding: 'base64',
229
239
  size_chars: value.length,
@@ -275,6 +285,7 @@ function recordContentFields(record, identity, options) {
275
285
  .map(([fieldPath, value]) => ({
276
286
  field_path: fieldPath,
277
287
  text_like: true,
288
+ handle_semantics: 'live_lookup',
278
289
  preview_status: value.length > options.windowLimitChars ? 'truncated' : 'complete',
279
290
  size_chars: value.length,
280
291
  read: {
@@ -305,6 +316,39 @@ function recordContentBinaryFields(record, options) {
305
316
  .slice(0, options.binaryLimit);
306
317
  }
307
318
 
319
+ function recordContentJsonFields(record, identity, options) {
320
+ const payload = objectValue(record?.data) || objectValue(record?.record) || objectValue(record);
321
+ return Object.entries(payload)
322
+ .filter(([fieldPath, value]) => isJsonEvidenceField(fieldPath, value))
323
+ .slice(0, options.jsonLimit)
324
+ .map(([fieldPath, value]) => {
325
+ const rendered = stableInlineJson(value);
326
+ return {
327
+ field_path: fieldPath,
328
+ json_field: true,
329
+ text_like: false,
330
+ handle_semantics: 'live_lookup',
331
+ preview_status: rendered.length > options.jsonPreviewChars ? 'truncated' : 'complete',
332
+ size_chars: rendered.length,
333
+ preview_text: truncateText(rendered, options.jsonPreviewChars),
334
+ read: {
335
+ tool: 'fetch',
336
+ args: {
337
+ id: identity.id,
338
+ fields: [fieldPath],
339
+ },
340
+ },
341
+ };
342
+ });
343
+ }
344
+
345
+ function isJsonEvidenceField(fieldPath, value) {
346
+ if (typeof fieldPath !== 'string' || fieldPath.length === 0 || OMIT_FIELD_KEYS.has(fieldPath)) return false;
347
+ if (!value || typeof value !== 'object') return false;
348
+ if (blobRefMetadata(value)) return false;
349
+ return true;
350
+ }
351
+
308
352
  function sanitizePayloadObject(payload) {
309
353
  const out = {};
310
354
  for (const [key, value] of Object.entries(payload)) {