@personize/sdk 0.6.4 → 0.6.6

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.
package/README.md CHANGED
@@ -38,6 +38,7 @@ console.log(me.data.plan.limits);
38
38
  | **AI** | | |
39
39
  | POST | `/api/v1/ai/smart-guidelines` | `client.ai.smartGuidelines(opts)` |
40
40
  | POST | `/api/v1/prompt` | `client.ai.prompt(opts)` |
41
+ | POST | `/api/v1/prompt` (stream) | `client.ai.promptStream(opts)` |
41
42
  | **Memory** | | |
42
43
  | POST | `/api/v1/memorize` | `client.memory.memorize(opts)` |
43
44
  | POST | `/api/v1/smart-recall` | `client.memory.smartRecall(opts)` |
@@ -45,6 +46,7 @@ console.log(me.data.plan.limits);
45
46
  | POST | `/api/v1/search` | `client.memory.search(opts)` |
46
47
  | POST | `/api/v1/batch-memorize` | `client.memory.memorizeBatch(opts)` |
47
48
  | POST | `/api/v1/smart-memory-digest` | `client.memory.smartDigest(opts)` |
49
+ | POST | `/api/v1/memory/properties` | `client.memory.properties(opts)` |
48
50
  | **Guidelines** | | |
49
51
  | GET | `/api/v1/guidelines` | `client.guidelines.list()` |
50
52
  | POST | `/api/v1/guidelines` | `client.guidelines.create(payload)` |
@@ -107,6 +109,27 @@ const ctx = await client.ai.smartGuidelines({
107
109
  console.log(ctx.data.compiledContext);
108
110
  ```
109
111
 
112
+ #### Content Budget
113
+
114
+ Control how much guideline content is delivered:
115
+
116
+ ```typescript
117
+ const result = await client.ai.smartGuidelines({
118
+ message: "write a cold email",
119
+ maxContentTokens: 5000, // deliver ~2-3 full guidelines, rest as summaries
120
+ });
121
+
122
+ // Demoted guidelines (over budget) returned with id + description for follow-up
123
+ if (result.data.budgetMetadata?.demotedGuidelines) {
124
+ for (const g of result.data.budgetMetadata.demotedGuidelines) {
125
+ // Fetch specific section: client.guidelines.getSection(g.id, { header: "Cold Email" })
126
+ console.log(`${g.name}: ${g.description} — sections: ${g.sections.join(', ')}`);
127
+ }
128
+ }
129
+ ```
130
+
131
+ Default: 10,000 tokens. Guidelines too large for the budget are automatically trimmed to relevant sections. Remaining guidelines are returned as summaries with `id`, `description`, and `sections[]` for follow-up via `client.guidelines.getSection()`.
132
+
110
133
  ### Prompt Execution
111
134
 
112
135
  ```typescript
@@ -185,6 +208,97 @@ console.log(research.data?.outputs?.company_profile);
185
208
  console.log(research.data?.evaluation?.finalScore);
186
209
  ```
187
210
 
211
+ ### Streaming Prompt Execution
212
+
213
+ `promptStream()` returns an async generator that yields Server-Sent Events as they arrive. Use this for real-time UI updates, progressive output delivery, or when you need structured outputs as soon as each one finishes generating.
214
+
215
+ ```typescript
216
+ import type { PromptSSEEvent } from '@personize/sdk';
217
+
218
+ // Stream with structured outputs — events arrive as each output closes
219
+ for await (const event of client.ai.promptStream({
220
+ prompt: 'Generate a hero section and social proof for our landing page',
221
+ outputs: [
222
+ { name: 'hero' },
223
+ { name: 'social_proof' },
224
+ ],
225
+ })) {
226
+ switch (event.type) {
227
+ case 'text':
228
+ // Raw LLM text chunks (everything outside <output> markers)
229
+ process.stdout.write(event.chunk);
230
+ break;
231
+
232
+ case 'output':
233
+ // A named output extracted — fired once per output as soon as </output> closes
234
+ // event.data is already parsed (JSON object or plain string)
235
+ console.log(`Output "${event.name}":`, event.data);
236
+ break;
237
+
238
+ case 'done':
239
+ // Final event — includes all outputs, evaluation, and metadata
240
+ console.log('All outputs:', event.outputs);
241
+ console.log('Metadata:', event.metadata);
242
+ break;
243
+
244
+ case 'error':
245
+ // Non-fatal error during streaming
246
+ console.error('Stream error:', event.message);
247
+ break;
248
+ }
249
+ }
250
+ ```
251
+
252
+ **SSE Event Types:**
253
+
254
+ | Event | Frequency | Description |
255
+ | :--- | :--- | :--- |
256
+ | `text` | Many per response | Plain text chunks from the LLM |
257
+ | `output` | Once per named output | Extracted output (JSON or string) — fired as soon as `</output>` closes |
258
+ | `step_complete` | Once per instruction step | Multi-step mode: step metadata |
259
+ | `done` | Once at end | Final reconciliation with all outputs + metadata |
260
+ | `error` | 0 or more | Non-fatal streaming errors |
261
+
262
+ **Options:**
263
+
264
+ | Option | Type | Default | Description |
265
+ | :--- | :--- | :--- | :--- |
266
+ | `streamTimeout` | number | `120000` | Overall stream timeout in ms |
267
+ | `signal` | AbortSignal | — | External abort signal for cancellation |
268
+
269
+ All other `PromptOptions` parameters (`outputs`, `context`, `instructions`, `tier`, `memorize`, `evaluate`, etc.) are supported.
270
+
271
+ **Cancellation:**
272
+
273
+ ```typescript
274
+ const controller = new AbortController();
275
+ setTimeout(() => controller.abort(), 5000); // cancel after 5s
276
+
277
+ for await (const event of client.ai.promptStream({
278
+ prompt: '...',
279
+ signal: controller.signal,
280
+ })) {
281
+ // ...
282
+ }
283
+ ```
284
+
285
+ #### Entity Identifiers
286
+
287
+ All memory endpoints support multiple CRM key types for entity scoping:
288
+
289
+ | Key | Use case |
290
+ |-----|----------|
291
+ | `email` | Contact lookup |
292
+ | `websiteUrl` | Company lookup |
293
+ | `recordId` | Direct record ID |
294
+ | `customKeyName` + `customKeyValue` | Custom CRM field (e.g. `hubspot_id`) |
295
+ | `phoneNumber` | Phone-based lookup |
296
+ | `postalCode` | Location-based lookup |
297
+ | `deviceId` | Device-based lookup |
298
+ | `contentId` | Content-based lookup |
299
+
300
+ You can pass multiple keys simultaneously for better matching.
301
+
188
302
  ### Memory (RAG)
189
303
 
190
304
  ```typescript
@@ -199,21 +313,20 @@ const memorized = await client.memory.memorize({
199
313
  });
200
314
  console.log(memorized.data?.recordId); // REC#<hex> — deterministic, use for recall/digest
201
315
 
202
- // Smart recall — advanced recall with reflection
316
+ // Smart recall — deep mode (default): reflection + answer generation, ~10-20s, 2 credits
203
317
  const results = await client.memory.smartRecall({
204
318
  query: 'What does John prefer?',
205
319
  limit: 5,
206
320
  minScore: 0.7,
207
- enable_reflection: true,
208
- generate_answer: true,
321
+ mode: 'deep',
209
322
  });
210
323
 
211
- // Fast recall — low-latency mode (~500ms), guaranteed min 10 results
324
+ // Smart recall — fast mode: skips reflection, ~500ms, 1 credit
212
325
  const fast = await client.memory.smartRecall({
213
326
  query: 'contact info for John',
214
327
  email: 'john@example.com',
215
- fast_mode: true,
216
- // min_results: 10 (default in fast_mode — always returns top N even below score threshold)
328
+ mode: 'fast',
329
+ // min_results: 10 (default in fast mode — always returns top N even below score threshold)
217
330
  });
218
331
 
219
332
  // Custom keys — bring your own identifier for any entity type
@@ -239,7 +352,7 @@ const student = await client.memory.smartRecall({
239
352
  type: 'Student',
240
353
  customKeyName: 'studentNumber',
241
354
  customKeyValue: 'S-2024-1234',
242
- fast_mode: true,
355
+ mode: 'fast',
243
356
  });
244
357
 
245
358
  // Direct recall — DynamoDB lookup: properties + freeform memories (no AI, type required)
@@ -377,6 +490,38 @@ console.log(digest.data?.compiledContext); // ready-to-use markdown for LLM prom
377
490
 
378
491
  ```
379
492
 
493
+ ### Get Record Properties
494
+
495
+ Fetch current property values for a record, joined with collection schema descriptions and the `update` flag.
496
+
497
+ ```typescript
498
+ // Get specific properties with schema info
499
+ const result = await client.memory.properties({
500
+ email: 'john@acme.com',
501
+ propertyNames: ['Tasks', 'Lifecycle Stage'],
502
+ nonEmpty: true,
503
+ });
504
+
505
+ for (const prop of result.data.properties) {
506
+ console.log(`${prop.name}: ${JSON.stringify(prop.value)}`);
507
+ console.log(` Type: ${prop.type}, Update: ${prop.update}`);
508
+ console.log(` Description: ${prop.description}`);
509
+ }
510
+ ```
511
+
512
+ Each property includes:
513
+ - `value` — current value
514
+ - `description` — from the collection schema, tells AI how to interpret/update
515
+ - `update` — `true` means replaceable (use `memory.update()` with `propertyValue`), `false` means append-only (use `arrayPush`)
516
+ - `type` — property type (`text`, `number`, `boolean`, `array`, `date`, `options`)
517
+ - `collectionName` — which collection this property belongs to
518
+
519
+ Options:
520
+ - `propertyNames` — filter to specific properties (recommended to save tokens)
521
+ - `includeDescriptions` — join with collection schema (default: `true`)
522
+ - `nonEmpty` — exclude null/empty values (default: `false`)
523
+ - Identifiers: `email`, `websiteUrl`, `recordId`, `customKeyName`+`customKeyValue`
524
+
380
525
  ### Agents
381
526
 
382
527
  ```typescript
@@ -456,12 +601,12 @@ console.log(evaluation.data.summary.propertiesOptimized);
456
601
 
457
602
  | Operation | Mode | Credits/Call |
458
603
  | :--- | :--- | :--- |
459
- | Smart Recall | `fast_mode: true` | 1 |
460
- | Smart Recall | `fast_mode: false` (deep) | 1 |
604
+ | Smart Recall | `mode: 'fast'` | 1 |
605
+ | Smart Recall | `mode: 'deep'` | 2 |
461
606
  | Smart Guidelines | `mode: 'fast'` | 1 |
462
607
  | Smart Guidelines | `mode: 'deep'` | 1 |
463
608
 
464
- All read operations (recall, smart recall, smart guidelines, smart context) charge a flat **1 credit per call** regardless of mode. Mode choice affects latency and depth, not cost.
609
+ Smart Recall cost depends on mode: fast = 1 credit, deep = 2 credits. All other read operations (recall, smart guidelines, smart context) charge a flat **1 credit per call**.
465
610
 
466
611
  1 credit = $0.01.
467
612
 
@@ -496,6 +641,33 @@ await client.ai.prompt({
496
641
 
497
642
  Response metadata includes `byok: true` and `creditsCharged` reflecting the flat 5-credit charge.
498
643
 
644
+ ## Smart Recall Modes
645
+
646
+ The `mode` parameter controls smart recall behavior:
647
+
648
+ | Mode | Latency | Credits | Description |
649
+ | :--- | :--- | :--- | :--- |
650
+ | `"fast"` | ~500ms | 1 | Skips reflection and answer generation. Returns raw vector results with guaranteed minimum count. |
651
+ | `"deep"` | ~10-20s | 2 | Enables reflection + answer generation for higher-quality, synthesized responses. |
652
+
653
+ Default is `"deep"`. The `mode` parameter takes precedence over the individual `enable_reflection`, `generate_answer`, and `fast_mode` flags. If `mode` is set, those flags are ignored.
654
+
655
+ #### Recency Bias
656
+
657
+ Use `prefer_recent` to boost recent memories with exponential decay:
658
+
659
+ ```typescript
660
+ const result = await client.memory.smartRecall({
661
+ query: "what changed on this contact recently?",
662
+ email: "john@acme.com",
663
+ mode: "deep",
664
+ prefer_recent: true,
665
+ recency_half_life_days: 30, // aggressive: 30-day half-life
666
+ });
667
+ ```
668
+
669
+ Default half-life is 90 days. A memory 90 days old scores ~37% of its original relevance. Set to 7-30 for "what happened this week/month" queries.
670
+
499
671
  ## Best Practices: Query Crafting for smartRecall
500
672
 
501
673
  The `smartRecall` endpoint uses vector similarity search. Query quality directly impacts result relevance. When building AI pipelines that call `smartRecall`, the **AI agent is responsible for crafting embedding-friendly queries**.
@@ -518,11 +690,11 @@ const bad = await client.memory.smartRecall({ query: 'Tell me about this contact
518
690
  const good = await client.memory.smartRecall({
519
691
  query: `${contactName} role company background interests preferences`,
520
692
  email,
521
- fast_mode: true,
693
+ mode: 'fast',
522
694
  });
523
695
  ```
524
696
 
525
- **Guaranteed minimum results:** In `fast_mode`, `smartRecall` guarantees at least 10 results (configurable via `min_results`) even when scores fall below the threshold. This ensures your AI workflow always has context to reason about — it can then decide whether the data is sufficient or not.
697
+ **Guaranteed minimum results:** In `mode: 'fast'`, `smartRecall` guarantees at least 10 results (configurable via `min_results`) even when scores fall below the threshold. This ensures your AI workflow always has context to reason about — it can then decide whether the data is sufficient or not.
526
698
 
527
699
  ## Configuration
528
700
 
@@ -543,23 +715,23 @@ const client = new Personize({
543
715
  });
544
716
  ```
545
717
 
546
- ## Migration from 0.6.2
547
-
548
- **New in 0.6.3:**
549
-
550
- | Feature | Details |
551
- | :--- | :--- |
552
- | `evaluationCriteria` on `PromptOptions` | Compatibility alias for `evaluate: { criteria, serverSide: true }` |
553
- | `message` on `RecallOptions` / `SmartRecallOptions` | Compatibility alias for `query` |
554
- | Legacy `memory.recall()` routing | If you call `recall()` with legacy advanced-recall-style inputs (`message`, `limit`, omitted `type`, collection-name scoping), the SDK routes to `/smart-recall` automatically |
555
- | Shorthand semantic `memory.search()` | `search({ query, limit, collectionName })` is accepted and routed to `/smart-recall` when no filter groups are provided |
556
- | `collectionName` / `collectionNames` on `memorize()` | Collection names are resolved client-side into `collectionIds` |
557
- | Legacy collection payload aliases | `collections.create()` now accepts `name`, `slug`, `description`, array `options`, and `updateSemantics` |
558
- | `records` shorthand on `memorizeBatch()` | Accepts record-style input and normalizes it client-side into `memorize()` + `/batch-memorize` calls |
559
-
560
- See [SDK_0_6_3_COMPATIBILITY_CHANGES.md](SDK_0_6_3_COMPATIBILITY_CHANGES.md) for the full design notes and tradeoffs.
561
-
562
- ## Migration from 0.5.x
718
+ ## Migration from 0.6.2
719
+
720
+ **New in 0.6.3:**
721
+
722
+ | Feature | Details |
723
+ | :--- | :--- |
724
+ | `evaluationCriteria` on `PromptOptions` | Compatibility alias for `evaluate: { criteria, serverSide: true }` |
725
+ | `message` on `RecallOptions` / `SmartRecallOptions` | Compatibility alias for `query` |
726
+ | Legacy `memory.recall()` routing | If you call `recall()` with legacy advanced-recall-style inputs (`message`, `limit`, omitted `type`, collection-name scoping), the SDK routes to `/smart-recall` automatically |
727
+ | Shorthand semantic `memory.search()` | `search({ query, limit, collectionName })` is accepted and routed to `/smart-recall` when no filter groups are provided |
728
+ | `collectionName` / `collectionNames` on `memorize()` | Collection names are resolved client-side into `collectionIds` |
729
+ | Legacy collection payload aliases | `collections.create()` now accepts `name`, `slug`, `description`, array `options`, and `updateSemantics` |
730
+ | `records` shorthand on `memorizeBatch()` | Accepts record-style input and normalizes it client-side into `memorize()` + `/batch-memorize` calls |
731
+
732
+ See [SDK_0_6_3_COMPATIBILITY_CHANGES.md](SDK_0_6_3_COMPATIBILITY_CHANGES.md) for the full design notes and tradeoffs.
733
+
734
+ ## Migration from 0.5.x
563
735
 
564
736
  **New in 0.6.0:**
565
737
 
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { PersonizeConfig, ApiResponse, MeResponse, TestResponse, ListOptions, GuidelinesResponse, GuidelineSectionOptions, GuidelineUpdatePayload, GuidelineCreatePayload, GuidelineHistoryResponse, GuidelineHistoryOptions, CollectionsResponse, CollectionCreatePayload, CollectionUpdatePayload, CollectionHistoryOptions, CollectionHistoryResponse, SmartGuidelinesOptions, SmartGuidelinesResponse, PromptOptions, PromptResponse, AgentRunOptions, AgentResponse, MemorizeOptions, SmartRecallOptions, RecallOptions, RecallResponse, SearchOptions, SearchResponse, BatchMemorizeOptions, SmartDigestOptions, SmartDigestResponse, EvaluateMemorizationOptions, EvaluateMemorizationResponse } from './types';
1
+ import { PersonizeConfig, ApiResponse, MeResponse, TestResponse, ListOptions, GuidelinesResponse, GuidelineSectionOptions, GuidelineUpdatePayload, GuidelineCreatePayload, GuidelineHistoryResponse, GuidelineHistoryOptions, CollectionsResponse, CollectionCreatePayload, CollectionUpdatePayload, CollectionHistoryOptions, CollectionHistoryResponse, SmartGuidelinesOptions, SmartGuidelinesResponse, PromptOptions, PromptResponse, PromptStreamOptions, PromptSSEEvent, AgentRunOptions, AgentResponse, MemorizeOptions, SmartRecallOptions, RecallOptions, RecallResponse, SearchOptions, SearchResponse, BatchMemorizeOptions, SmartDigestOptions, SmartDigestResponse, EvaluateMemorizationOptions, EvaluateMemorizationResponse, UpdatePropertyOptions, UpdateResult, BulkUpdateOptions, BulkUpdateResult, PropertyHistoryOptions, PropertyHistoryResult, QueryPropertiesOptions, QueryPropertiesResult, DeleteMemoriesOptions, DeleteRecordOptions, DeletionResult, CancelDeletionOptions, CancelDeletionResult, FilterByPropertyOptions, FilterByPropertyResult, GetPropertiesOptions, GetPropertiesResponse } from './types';
2
2
  export declare class Personize {
3
3
  private client;
4
4
  private _organizationId?;
@@ -105,6 +105,28 @@ export declare class Personize {
105
105
  * Use `memorize` to auto-save outputs and tool results to memory.
106
106
  */
107
107
  prompt: (options: PromptOptions) => Promise<ApiResponse<PromptResponse>>;
108
+ /**
109
+ * POST /api/v1/prompt (stream: true) — Stream prompt execution as Server-Sent Events.
110
+ *
111
+ * Returns an async generator that yields SSE events as they arrive:
112
+ * - `text`: plain text chunks from the LLM
113
+ * - `output`: a named output extracted when its </output> marker closes
114
+ * - `step_complete`: fired after each instruction step (multi-step mode)
115
+ * - `done`: final event with all outputs, evaluation, and metadata
116
+ * - `error`: non-fatal error during streaming
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * for await (const event of personize.ai.promptStream({
121
+ * prompt: 'Write a hero section',
122
+ * outputs: [{ name: 'headline' }, { name: 'subtitle' }],
123
+ * })) {
124
+ * if (event.type === 'output') console.log(event.name, event.data);
125
+ * if (event.type === 'done') console.log('Finished:', event.metadata);
126
+ * }
127
+ * ```
128
+ */
129
+ promptStream: (options: PromptStreamOptions) => AsyncGenerator<PromptSSEEvent>;
108
130
  };
109
131
  agents: {
110
132
  /**
@@ -152,6 +174,61 @@ export declare class Personize {
152
174
  * Combines DynamoDB properties + LanceDB memories into a token-budgeted markdown block.
153
175
  */
154
176
  smartDigest: (data: SmartDigestOptions) => Promise<ApiResponse<SmartDigestResponse>>;
177
+ /**
178
+ * POST /api/v1/memory/update — Update a single property or freeform memory.
179
+ *
180
+ * For property updates: pass `propertyName` + `propertyValue` (or array operations).
181
+ * For freeform edits: pass `memoryId` + `text`.
182
+ * Use `expectedVersion` for optimistic concurrency (409 on mismatch).
183
+ */
184
+ update: (data: UpdatePropertyOptions) => Promise<ApiResponse<UpdateResult>>;
185
+ /**
186
+ * POST /api/v1/memory/bulk-update — Update multiple properties on a record in one request.
187
+ * Use `expectedVersion` for optimistic concurrency (checked before any writes).
188
+ */
189
+ bulkUpdate: (data: BulkUpdateOptions) => Promise<ApiResponse<BulkUpdateResult>>;
190
+ /**
191
+ * POST /api/v1/memory/delete — Soft-delete memories (30-day recovery window).
192
+ * Deleted items are excluded from all reads. Use `cancelDeletion` to restore.
193
+ */
194
+ delete: (data: DeleteMemoriesOptions) => Promise<ApiResponse<DeletionResult>>;
195
+ /**
196
+ * POST /api/v1/memory/delete-record — Soft-delete all memories for a record (30-day recovery).
197
+ */
198
+ deleteRecord: (data: DeleteRecordOptions) => Promise<ApiResponse<DeletionResult>>;
199
+ /**
200
+ * POST /api/v1/memory/cancel-deletion — Cancel a pending soft-delete within the 30-day window.
201
+ * Returns 409 DELETION_FINALIZED if the window has expired.
202
+ */
203
+ cancelDeletion: (data: CancelDeletionOptions) => Promise<ApiResponse<CancelDeletionResult>>;
204
+ /**
205
+ * POST /api/v1/memory/property-history — Query property change history for a record.
206
+ * Supports filtering by property name, time range, and cursor-based pagination.
207
+ */
208
+ propertyHistory: (data: PropertyHistoryOptions) => Promise<ApiResponse<PropertyHistoryResult>>;
209
+ /**
210
+ * POST /api/v1/memory/query-properties — LLM-powered search across property values.
211
+ * Finds records where a property value matches a natural-language query.
212
+ */
213
+ queryProperties: (data: QueryPropertiesOptions) => Promise<ApiResponse<QueryPropertiesResult>>;
214
+ /**
215
+ * POST /api/v1/memory/filter-by-property — Deterministic property filter (no LLM, no token cost).
216
+ * Finds records where property values match structured conditions.
217
+ *
218
+ * @example
219
+ * ```ts
220
+ * const result = await client.memory.filterByProperty({
221
+ * conditions: [{ propertyName: 'deal_stage', operator: 'equals', value: 'closed_won' }],
222
+ * type: 'Company',
223
+ * limit: 100,
224
+ * });
225
+ * ```
226
+ */
227
+ filterByProperty: (data: FilterByPropertyOptions) => Promise<ApiResponse<FilterByPropertyResult>>;
228
+ /**
229
+ * POST /api/v1/properties — Get record properties with schema descriptions.
230
+ */
231
+ properties: (data: GetPropertiesOptions) => Promise<ApiResponse<GetPropertiesResponse>>;
155
232
  };
156
233
  evaluate: {
157
234
  /**
package/dist/client.js CHANGED
@@ -153,7 +153,13 @@ class Personize {
153
153
  * POST /api/v1/ai/smart-guidelines — Smart guidelines routing. Selects relevant organizational guidelines for a task.
154
154
  */
155
155
  smartGuidelines: async (options) => {
156
- const response = await this.client.post('/api/v1/ai/smart-guidelines', options);
156
+ // Normalize snake_case alias camelCase
157
+ const { max_content_tokens, ...rest } = options;
158
+ const normalized = {
159
+ ...rest,
160
+ maxContentTokens: rest.maxContentTokens ?? max_content_tokens,
161
+ };
162
+ const response = await this.client.post('/api/v1/ai/smart-guidelines', normalized);
157
163
  return response.data;
158
164
  },
159
165
  /**
@@ -169,6 +175,34 @@ class Personize {
169
175
  const response = await this.client.post('/api/v1/prompt', normalizedOptions);
170
176
  return response.data;
171
177
  },
178
+ /**
179
+ * POST /api/v1/prompt (stream: true) — Stream prompt execution as Server-Sent Events.
180
+ *
181
+ * Returns an async generator that yields SSE events as they arrive:
182
+ * - `text`: plain text chunks from the LLM
183
+ * - `output`: a named output extracted when its </output> marker closes
184
+ * - `step_complete`: fired after each instruction step (multi-step mode)
185
+ * - `done`: final event with all outputs, evaluation, and metadata
186
+ * - `error`: non-fatal error during streaming
187
+ *
188
+ * @example
189
+ * ```ts
190
+ * for await (const event of personize.ai.promptStream({
191
+ * prompt: 'Write a hero section',
192
+ * outputs: [{ name: 'headline' }, { name: 'subtitle' }],
193
+ * })) {
194
+ * if (event.type === 'output') console.log(event.name, event.data);
195
+ * if (event.type === 'done') console.log('Finished:', event.metadata);
196
+ * }
197
+ * ```
198
+ */
199
+ promptStream: (options) => {
200
+ const normalizedOptions = this.normalizePromptOptions({ ...options, stream: true });
201
+ const baseURL = this.client.defaults.baseURL || 'https://agent.personize.ai';
202
+ const authHeader = this.client.defaults.headers?.['Authorization'];
203
+ const streamTimeout = options.streamTimeout ?? 120000;
204
+ return streamPromptSSE(baseURL, authHeader, normalizedOptions, streamTimeout, options.signal);
205
+ },
172
206
  };
173
207
  this.agents = {
174
208
  /**
@@ -330,6 +364,98 @@ class Personize {
330
364
  const response = await this.client.post('/api/v1/smart-memory-digest', data);
331
365
  return response.data;
332
366
  },
367
+ /**
368
+ * POST /api/v1/memory/update — Update a single property or freeform memory.
369
+ *
370
+ * For property updates: pass `propertyName` + `propertyValue` (or array operations).
371
+ * For freeform edits: pass `memoryId` + `text`.
372
+ * Use `expectedVersion` for optimistic concurrency (409 on mismatch).
373
+ */
374
+ update: async (data) => {
375
+ const response = await this.client.post('/api/v1/memory/update', data);
376
+ return response.data;
377
+ },
378
+ /**
379
+ * POST /api/v1/memory/bulk-update — Update multiple properties on a record in one request.
380
+ * Use `expectedVersion` for optimistic concurrency (checked before any writes).
381
+ */
382
+ bulkUpdate: async (data) => {
383
+ const response = await this.client.post('/api/v1/memory/bulk-update', data);
384
+ return response.data;
385
+ },
386
+ /**
387
+ * POST /api/v1/memory/delete — Soft-delete memories (30-day recovery window).
388
+ * Deleted items are excluded from all reads. Use `cancelDeletion` to restore.
389
+ */
390
+ delete: async (data) => {
391
+ const response = await this.client.post('/api/v1/memory/delete', data);
392
+ return response.data;
393
+ },
394
+ /**
395
+ * POST /api/v1/memory/delete-record — Soft-delete all memories for a record (30-day recovery).
396
+ */
397
+ deleteRecord: async (data) => {
398
+ const response = await this.client.post('/api/v1/memory/delete-record', data);
399
+ return response.data;
400
+ },
401
+ /**
402
+ * POST /api/v1/memory/cancel-deletion — Cancel a pending soft-delete within the 30-day window.
403
+ * Returns 409 DELETION_FINALIZED if the window has expired.
404
+ */
405
+ cancelDeletion: async (data) => {
406
+ const response = await this.client.post('/api/v1/memory/cancel-deletion', data);
407
+ return response.data;
408
+ },
409
+ /**
410
+ * POST /api/v1/memory/property-history — Query property change history for a record.
411
+ * Supports filtering by property name, time range, and cursor-based pagination.
412
+ */
413
+ propertyHistory: async (data) => {
414
+ const response = await this.client.post('/api/v1/memory/property-history', data);
415
+ return response.data;
416
+ },
417
+ /**
418
+ * POST /api/v1/memory/query-properties — LLM-powered search across property values.
419
+ * Finds records where a property value matches a natural-language query.
420
+ */
421
+ queryProperties: async (data) => {
422
+ const response = await this.client.post('/api/v1/memory/query-properties', data);
423
+ return response.data;
424
+ },
425
+ /**
426
+ * POST /api/v1/memory/filter-by-property — Deterministic property filter (no LLM, no token cost).
427
+ * Finds records where property values match structured conditions.
428
+ *
429
+ * @example
430
+ * ```ts
431
+ * const result = await client.memory.filterByProperty({
432
+ * conditions: [{ propertyName: 'deal_stage', operator: 'equals', value: 'closed_won' }],
433
+ * type: 'Company',
434
+ * limit: 100,
435
+ * });
436
+ * ```
437
+ */
438
+ filterByProperty: async (data) => {
439
+ const response = await this.client.post('/api/v1/memory/filter-by-property', data);
440
+ return response.data;
441
+ },
442
+ /**
443
+ * POST /api/v1/properties — Get record properties with schema descriptions.
444
+ */
445
+ properties: async (data) => {
446
+ const response = await this.client.post('/api/v1/properties', {
447
+ email: data.email,
448
+ websiteUrl: data.websiteUrl || data.website_url,
449
+ recordId: data.recordId || data.record_id,
450
+ type: data.type,
451
+ customKeyName: data.customKeyName,
452
+ customKeyValue: data.customKeyValue,
453
+ propertyNames: data.propertyNames,
454
+ includeDescriptions: data.includeDescriptions,
455
+ nonEmpty: data.nonEmpty,
456
+ });
457
+ return response.data;
458
+ },
333
459
  };
334
460
  this.evaluate = {
335
461
  /**
@@ -487,7 +613,7 @@ class Personize {
487
613
  }
488
614
  normalizePromptOptions(options) {
489
615
  if (!options.evaluationCriteria || options.evaluate) {
490
- const { evaluationCriteria, ...rest } = options;
616
+ const { evaluationCriteria: _ec, ...rest } = options;
491
617
  return rest;
492
618
  }
493
619
  const { evaluationCriteria, ...rest } = options;
@@ -550,7 +676,7 @@ class Personize {
550
676
  };
551
677
  }
552
678
  normalizeRecallOptions(data) {
553
- const { message, limit, collectionName, collectionNames, ...rest } = data;
679
+ const { message, limit: _limit, collectionName: _collectionName, collectionNames: _collectionNames, ...rest } = data;
554
680
  return {
555
681
  ...rest,
556
682
  query: data.query || message || '',
@@ -790,3 +916,124 @@ class Personize {
790
916
  }
791
917
  }
792
918
  exports.Personize = Personize;
919
+ // ────────────────────────────── SSE Stream Parser ──────────────────────────────
920
+ /**
921
+ * Initiates a streaming prompt request and yields SSE events.
922
+ * Extracted as a standalone function to avoid `this` binding issues with async generators.
923
+ */
924
+ async function* streamPromptSSE(baseURL, authHeader, options, streamTimeout, signal) {
925
+ const controller = new AbortController();
926
+ const timeoutId = setTimeout(() => controller.abort(), streamTimeout);
927
+ // Link external signal if provided
928
+ if (signal) {
929
+ if (signal.aborted) {
930
+ clearTimeout(timeoutId);
931
+ controller.abort();
932
+ }
933
+ else {
934
+ signal.addEventListener('abort', () => controller.abort(), { once: true });
935
+ }
936
+ }
937
+ let response;
938
+ try {
939
+ response = await fetch(`${baseURL}/api/v1/prompt`, {
940
+ method: 'POST',
941
+ headers: {
942
+ 'Authorization': authHeader,
943
+ 'Content-Type': 'application/json',
944
+ },
945
+ body: JSON.stringify(options),
946
+ signal: controller.signal,
947
+ });
948
+ }
949
+ catch (err) {
950
+ clearTimeout(timeoutId);
951
+ throw new Error(`Prompt stream connection failed: ${err instanceof Error ? err.message : err}`);
952
+ }
953
+ if (!response.ok) {
954
+ clearTimeout(timeoutId);
955
+ const errorBody = await response.text().catch(() => '');
956
+ throw new Error(`Prompt stream failed (${response.status}): ${errorBody}`);
957
+ }
958
+ if (!response.body) {
959
+ clearTimeout(timeoutId);
960
+ throw new Error('Prompt stream: response body is null');
961
+ }
962
+ try {
963
+ yield* parseSSEStream(response.body);
964
+ }
965
+ finally {
966
+ clearTimeout(timeoutId);
967
+ }
968
+ }
969
+ /**
970
+ * Parses a ReadableStream of SSE bytes into typed PromptSSEEvent objects.
971
+ *
972
+ * Handles:
973
+ * - Partial chunks split across reads
974
+ * - Multi-line `data:` fields (accumulated per event)
975
+ * - Empty lines as event separators
976
+ * - Graceful end-of-stream
977
+ */
978
+ async function* parseSSEStream(body) {
979
+ const reader = body.getReader();
980
+ const decoder = new TextDecoder();
981
+ let buffer = '';
982
+ try {
983
+ while (true) {
984
+ const { done, value } = await reader.read();
985
+ if (done)
986
+ break;
987
+ buffer += decoder.decode(value, { stream: true });
988
+ // Process complete events (separated by double newline)
989
+ const parts = buffer.split('\n\n');
990
+ // Last part may be incomplete — keep it in buffer
991
+ buffer = parts.pop() || '';
992
+ for (const part of parts) {
993
+ const dataLines = [];
994
+ for (const line of part.split('\n')) {
995
+ if (line.startsWith('data: ')) {
996
+ dataLines.push(line.slice(6));
997
+ }
998
+ else if (line.startsWith('data:')) {
999
+ dataLines.push(line.slice(5));
1000
+ }
1001
+ // Ignore lines starting with ':' (comments/keepalive)
1002
+ // Ignore 'event:', 'id:', 'retry:' — we only use unnamed data events
1003
+ }
1004
+ if (dataLines.length === 0)
1005
+ continue;
1006
+ const jsonStr = dataLines.join('\n');
1007
+ try {
1008
+ const event = JSON.parse(jsonStr);
1009
+ yield event;
1010
+ }
1011
+ catch {
1012
+ // Non-JSON data line — skip (could be a keepalive or malformed chunk)
1013
+ }
1014
+ }
1015
+ }
1016
+ // Flush remaining buffer
1017
+ if (buffer.trim()) {
1018
+ const dataLines = [];
1019
+ for (const line of buffer.split('\n')) {
1020
+ if (line.startsWith('data: '))
1021
+ dataLines.push(line.slice(6));
1022
+ else if (line.startsWith('data:'))
1023
+ dataLines.push(line.slice(5));
1024
+ }
1025
+ if (dataLines.length > 0) {
1026
+ try {
1027
+ const event = JSON.parse(dataLines.join('\n'));
1028
+ yield event;
1029
+ }
1030
+ catch {
1031
+ // Ignore incomplete final chunk
1032
+ }
1033
+ }
1034
+ }
1035
+ }
1036
+ finally {
1037
+ reader.releaseLock();
1038
+ }
1039
+ }
package/dist/types.d.ts CHANGED
@@ -292,6 +292,10 @@ export interface SmartGuidelinesOptions {
292
292
  minScore?: number;
293
293
  /** Session ID for conversation continuity. */
294
294
  sessionId?: string;
295
+ /** Maximum tokens of guideline content to deliver. The system selects the most relevant guidelines and trims to fit. Default: 10000. */
296
+ maxContentTokens?: number;
297
+ /** @deprecated Use maxContentTokens instead. */
298
+ max_content_tokens?: number;
295
299
  }
296
300
  /** @deprecated Use SmartGuidelinesOptions instead. */
297
301
  export type SmartContextOptions = SmartGuidelinesOptions;
@@ -537,6 +541,48 @@ export interface PromptResponse {
537
541
  stepsExecuted: number;
538
542
  }>;
539
543
  }
544
+ /** Text chunk from the LLM stream. Many of these per response. */
545
+ export interface SSETextEvent {
546
+ type: 'text';
547
+ chunk: string;
548
+ }
549
+ /** A named output extracted from the stream when its </output> tag closes. One per output. */
550
+ export interface SSEOutputEvent {
551
+ type: 'output';
552
+ name: string;
553
+ data: unknown;
554
+ }
555
+ /** Fired after each instruction step completes (multi-step mode). */
556
+ export interface SSEStepCompleteEvent {
557
+ type: 'step_complete';
558
+ instructionIndex: number;
559
+ text: string;
560
+ toolCalls: Array<{
561
+ toolName: string;
562
+ }>;
563
+ }
564
+ /** Final event — includes all outputs, evaluation, and metadata. */
565
+ export interface SSEDoneEvent {
566
+ type: 'done';
567
+ outputs?: Record<string, unknown>;
568
+ toolOutputs?: Record<string, unknown>;
569
+ evaluation?: unknown;
570
+ metadata?: unknown;
571
+ }
572
+ /** Non-fatal error during streaming. */
573
+ export interface SSEErrorEvent {
574
+ type: 'error';
575
+ message: string;
576
+ }
577
+ /** Union of all SSE event types emitted by the /prompt streaming endpoint. */
578
+ export type PromptSSEEvent = SSETextEvent | SSEOutputEvent | SSEStepCompleteEvent | SSEDoneEvent | SSEErrorEvent;
579
+ /** Options for promptStream(). Extends PromptOptions but forces stream: true. */
580
+ export interface PromptStreamOptions extends Omit<PromptOptions, 'stream'> {
581
+ /** Timeout in milliseconds for the overall stream (default: 120000). */
582
+ streamTimeout?: number;
583
+ /** Abort signal for cancellation. */
584
+ signal?: AbortSignal;
585
+ }
540
586
  export interface TestResponse {
541
587
  timestamp: string;
542
588
  ip: string;
@@ -624,6 +670,14 @@ export interface MemorizeOptions {
624
670
  skipDualWrite?: boolean;
625
671
  /** If true, skip property selection step. */
626
672
  skipPropertySelection?: boolean;
673
+ /** Phone number for entity scoping. */
674
+ phoneNumber?: string;
675
+ /** Postal code for entity scoping. */
676
+ postalCode?: string;
677
+ /** Device ID for entity scoping. */
678
+ deviceId?: string;
679
+ /** Content ID for entity scoping. */
680
+ contentId?: string;
627
681
  }
628
682
  /** @deprecated Use MemorizeOptions instead. */
629
683
  export type MemorizeProOptions = MemorizeOptions;
@@ -632,6 +686,8 @@ export interface SmartRecallOptions {
632
686
  query: string;
633
687
  /** Compatibility alias for query. */
634
688
  message?: string;
689
+ /** Retrieval mode. "fast" skips reflection (~500ms, 1 credit). "deep" enables reflection + answer (~10-20s, 2 credits). Default: "deep". */
690
+ mode?: 'fast' | 'deep';
635
691
  /** Max results to return (default: 10). */
636
692
  limit?: number;
637
693
  /** Minimum similarity score threshold. */
@@ -648,6 +704,22 @@ export interface SmartRecallOptions {
648
704
  websiteUrl?: string;
649
705
  /** Entity type filter (e.g. 'Contact', 'Company'). */
650
706
  type?: string;
707
+ /** Phone number for entity scoping. */
708
+ phoneNumber?: string;
709
+ /** Phone number (snake_case alias). */
710
+ phone_number?: string;
711
+ /** Postal code for entity scoping. */
712
+ postalCode?: string;
713
+ /** Postal code (snake_case alias). */
714
+ postal_code?: string;
715
+ /** Device ID for entity scoping. */
716
+ deviceId?: string;
717
+ /** Device ID (snake_case alias). */
718
+ device_id?: string;
719
+ /** Content ID for entity scoping. */
720
+ contentId?: string;
721
+ /** Content ID (snake_case alias). */
722
+ content_id?: string;
651
723
  /** Custom key name — for entity types with domain-specific unique IDs. */
652
724
  customKeyName?: string;
653
725
  /** Custom key value — the unique identifier value. */
@@ -682,6 +754,10 @@ export interface SmartRecallOptions {
682
754
  * In fast_mode, defaults to 10. Set to 0 to disable (strict score cutoff).
683
755
  */
684
756
  min_results?: number;
757
+ /** Apply exponential recency decay to scores. Recent memories rank higher. */
758
+ prefer_recent?: boolean;
759
+ /** Half-life in days for recency decay (default: 90). A memory this many days old has its score multiplied by ~0.37. */
760
+ recency_half_life_days?: number;
685
761
  /** Metadata filters for narrowing results. */
686
762
  filters?: Record<string, unknown>;
687
763
  }
@@ -710,8 +786,18 @@ export interface RecallOptions {
710
786
  customKeyName?: string;
711
787
  /** Custom key value — the unique identifier value. */
712
788
  customKeyValue?: string;
789
+ /** Phone number for entity scoping. */
790
+ phoneNumber?: string;
791
+ /** Postal code for entity scoping. */
792
+ postalCode?: string;
793
+ /** Device ID for entity scoping. */
794
+ deviceId?: string;
795
+ /** Content ID for entity scoping. */
796
+ contentId?: string;
713
797
  /** Additional filters. */
714
798
  filters?: Record<string, unknown>;
799
+ /** Scope results to specific collections by ID. */
800
+ collectionIds?: string[];
715
801
  /** Compatibility alias for a single collection name. */
716
802
  collectionName?: string;
717
803
  /** Compatibility alias for collection scoping by name. */
@@ -811,6 +897,45 @@ export interface BatchMemorizeRecord {
811
897
  timestamp?: string;
812
898
  speaker?: string;
813
899
  }
900
+ export interface GetPropertiesOptions {
901
+ /** Contact email. */
902
+ email?: string;
903
+ /** Company website URL. */
904
+ websiteUrl?: string;
905
+ /** Website URL (snake_case alias). */
906
+ website_url?: string;
907
+ /** CRM record ID. */
908
+ recordId?: string;
909
+ /** CRM record ID (snake_case alias). */
910
+ record_id?: string;
911
+ /** Entity type. */
912
+ type?: string;
913
+ /** Custom CRM key field name. */
914
+ customKeyName?: string;
915
+ /** Custom CRM key field value. */
916
+ customKeyValue?: string;
917
+ /** Filter to specific properties by name. */
918
+ propertyNames?: string[];
919
+ /** Include collection schema descriptions (default: true). */
920
+ includeDescriptions?: boolean;
921
+ /** Only return non-empty properties (default: false). */
922
+ nonEmpty?: boolean;
923
+ }
924
+ export interface PropertyItem {
925
+ name: string;
926
+ value: unknown;
927
+ type?: string;
928
+ description?: string;
929
+ /** true = replaceable (set), false = append-only (push only). */
930
+ update?: boolean;
931
+ collectionId?: string;
932
+ collectionName?: string;
933
+ }
934
+ export interface GetPropertiesResponse {
935
+ recordId: string;
936
+ type: string;
937
+ properties: PropertyItem[];
938
+ }
814
939
  export interface SmartDigestOptions {
815
940
  /** CRM record ID */
816
941
  record_id?: string;
@@ -840,6 +965,14 @@ export interface SmartDigestOptions {
840
965
  include_memories?: boolean;
841
966
  /** Include memories (camelCase alias). */
842
967
  includeMemories?: boolean;
968
+ /** Phone number for entity scoping. */
969
+ phoneNumber?: string;
970
+ /** Postal code for entity scoping. */
971
+ postalCode?: string;
972
+ /** Device ID for entity scoping. */
973
+ deviceId?: string;
974
+ /** Content ID for entity scoping. */
975
+ contentId?: string;
843
976
  }
844
977
  export interface SmartDigestResponse {
845
978
  success: boolean;
@@ -961,6 +1094,223 @@ export interface SearchResponse extends Array<SearchResultItem> {
961
1094
  }
962
1095
  /** @deprecated Use SearchResponse instead. */
963
1096
  export type ExportResponse = SearchResponse;
1097
+ export interface UpdatePropertyOptions {
1098
+ /** Target record ID. */
1099
+ recordId: string;
1100
+ /** Entity type (default: 'contact'). */
1101
+ type?: string;
1102
+ /** Property to update. Required for property updates (mutually exclusive with memoryId+text). */
1103
+ propertyName?: string;
1104
+ /** New property value. Required unless using array operations. */
1105
+ propertyValue?: any;
1106
+ /** Collection ID for the property. */
1107
+ collectionId?: string;
1108
+ /** Confidence score for this value. */
1109
+ confidence?: number;
1110
+ /** Reason for the change (logged in property history). */
1111
+ reason?: string;
1112
+ /** Who made the change (auto-set from API key if omitted). */
1113
+ updatedBy?: string;
1114
+ /** Idempotency key to prevent duplicate writes. */
1115
+ idempotencyKey?: string;
1116
+ /** Optimistic concurrency guard. If set, returns 409 if the record's current version differs. */
1117
+ expectedVersion?: number;
1118
+ /** Append items to an array property. With `unique: true`, skips duplicates. */
1119
+ arrayPush?: {
1120
+ items: any[];
1121
+ unique?: boolean;
1122
+ };
1123
+ /** Remove items from an array property by value or index. */
1124
+ arrayRemove?: {
1125
+ items?: any[];
1126
+ indices?: number[];
1127
+ };
1128
+ /** Update matching objects inside an array property. */
1129
+ arrayPatch?: {
1130
+ match: Record<string, any>;
1131
+ set: Record<string, any>;
1132
+ };
1133
+ /** Freeform memory UUID to edit. */
1134
+ memoryId?: string;
1135
+ /** New text for the freeform memory. */
1136
+ text?: string;
1137
+ }
1138
+ export interface UpdateResult {
1139
+ success: boolean;
1140
+ previousValue?: any;
1141
+ newValue: any;
1142
+ version?: number;
1143
+ stores: {
1144
+ snapshot: 'updated' | 'skipped';
1145
+ lancedb: 'updated' | 'skipped';
1146
+ freeform: 'updated' | 'skipped';
1147
+ };
1148
+ }
1149
+ export interface BulkUpdateOptions {
1150
+ /** Target record ID. */
1151
+ recordId: string;
1152
+ /** Entity type (default: 'contact'). */
1153
+ type?: string;
1154
+ /** Array of property updates. */
1155
+ updates: Array<{
1156
+ propertyName: string;
1157
+ propertyValue: any;
1158
+ collectionId?: string;
1159
+ confidence?: number;
1160
+ }>;
1161
+ /** Who made the changes. */
1162
+ updatedBy?: string;
1163
+ /** Idempotency key to prevent duplicate writes. */
1164
+ idempotencyKey?: string;
1165
+ /** Optimistic concurrency guard. Checked before any writes; 409 if mismatch. */
1166
+ expectedVersion?: number;
1167
+ }
1168
+ export interface BulkUpdateResult {
1169
+ success: boolean;
1170
+ results: Array<{
1171
+ propertyName: string;
1172
+ previousValue?: any;
1173
+ newValue: any;
1174
+ status: 'updated' | 'failed';
1175
+ error?: string;
1176
+ }>;
1177
+ version?: number;
1178
+ }
1179
+ export interface PropertyHistoryOptions {
1180
+ /** Target record ID. */
1181
+ recordId: string;
1182
+ /** Filter to a specific property. */
1183
+ propertyName?: string;
1184
+ /** ISO-8601 lower bound. */
1185
+ from?: string;
1186
+ /** ISO-8601 upper bound. */
1187
+ to?: string;
1188
+ /** Max entries to return (default: 50, max: 200). */
1189
+ limit?: number;
1190
+ /** Pagination cursor from previous response. */
1191
+ nextToken?: string;
1192
+ }
1193
+ export interface PropertyHistoryEntry {
1194
+ entryId: string;
1195
+ propertyName: string;
1196
+ propertyValue: any;
1197
+ collectionId: string;
1198
+ collectionName?: string;
1199
+ updatedBy: string;
1200
+ createdAt: string;
1201
+ source?: string;
1202
+ }
1203
+ export interface PropertyHistoryResult {
1204
+ entries: PropertyHistoryEntry[];
1205
+ nextToken?: string;
1206
+ }
1207
+ export interface QueryPropertiesOptions {
1208
+ /** Which property to search across. */
1209
+ propertyName: string;
1210
+ /** Natural language query. */
1211
+ query: string;
1212
+ /** Limit to single record. */
1213
+ recordId?: string;
1214
+ /** Entity type filter (default: 'contact'). */
1215
+ type?: string;
1216
+ /** Max results (default: 100, max: 200). */
1217
+ limit?: number;
1218
+ }
1219
+ export interface QueryPropertiesResult {
1220
+ matches: Array<{
1221
+ recordId: string;
1222
+ propertyValue: any;
1223
+ matchReason: string;
1224
+ }>;
1225
+ processedCount: number;
1226
+ totalAvailable: number;
1227
+ truncated: boolean;
1228
+ capMessage?: string;
1229
+ }
1230
+ export interface DeleteMemoriesOptions {
1231
+ /** Memory UUIDs to delete. */
1232
+ ids?: string[];
1233
+ /** CRM identifiers for scoping. */
1234
+ crmKeys?: {
1235
+ recordId?: string;
1236
+ email?: string;
1237
+ websiteUrl?: string;
1238
+ };
1239
+ /** ISO date — delete memories older than this. */
1240
+ olderThan?: string;
1241
+ }
1242
+ export interface DeleteRecordOptions {
1243
+ /** Record ID to delete. */
1244
+ recordId: string;
1245
+ /** Entity type (required). */
1246
+ type: string;
1247
+ /** CRM identifiers for additional LanceDB filtering. */
1248
+ crmKeys?: {
1249
+ recordId?: string;
1250
+ email?: string;
1251
+ websiteUrl?: string;
1252
+ };
1253
+ /** Reason for deletion. */
1254
+ reason?: string;
1255
+ /** Who performed the deletion. */
1256
+ performedBy?: string;
1257
+ }
1258
+ export interface DeletionResult {
1259
+ success: boolean;
1260
+ deletedCount?: number;
1261
+ hardDeleteAt?: string;
1262
+ }
1263
+ export interface CancelDeletionOptions {
1264
+ /** Record ID to restore. */
1265
+ recordId: string;
1266
+ /** Entity type (default: 'contact'). */
1267
+ type?: string;
1268
+ /** Who performed the restoration. */
1269
+ performedBy?: string;
1270
+ }
1271
+ export interface CancelDeletionResult {
1272
+ success: boolean;
1273
+ restoredCounts: {
1274
+ snapshot: 'restored' | 'already_gone';
1275
+ freeform: 'restored' | 'already_gone';
1276
+ lancedb: 'restored' | 'already_gone';
1277
+ };
1278
+ warning?: string;
1279
+ }
1280
+ /** Comparison operators for deterministic property filters. */
1281
+ export type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'gt' | 'lt' | 'gte' | 'lte' | 'exists' | 'isEmpty';
1282
+ export interface PropertyFilterCondition {
1283
+ /** Property to filter on. */
1284
+ propertyName: string;
1285
+ /** Comparison operator. */
1286
+ operator: FilterOperator;
1287
+ /** Value to compare against. Not needed for 'exists'/'isEmpty'. */
1288
+ value?: any;
1289
+ }
1290
+ export interface FilterByPropertyOptions {
1291
+ /** Entity type (default: 'contact'). */
1292
+ type?: string;
1293
+ /** Filter conditions. */
1294
+ conditions: PropertyFilterCondition[];
1295
+ /** Combine conditions with AND (default) or OR. */
1296
+ logic?: 'AND' | 'OR';
1297
+ /** Max results (default: 50, max: 200). */
1298
+ limit?: number;
1299
+ /** Pagination cursor. */
1300
+ nextToken?: string;
1301
+ }
1302
+ export interface FilterByPropertyResult {
1303
+ records: Array<{
1304
+ recordId: string;
1305
+ type: string;
1306
+ matchedProperties: Record<string, any>;
1307
+ lastUpdatedAt?: number;
1308
+ }>;
1309
+ totalMatched: number;
1310
+ nextToken?: string;
1311
+ }
1312
+ /** Webhook event types fired by memory CRUD operations. */
1313
+ export type MemoryWebhookEvent = 'memory.property.updated' | 'memory.properties.bulk_updated' | 'memory.updated' | 'memory.deleted' | 'memory.record.deleted' | 'memory.record.deletion_cancelled';
964
1314
  export interface EvaluateMemorizationOptions {
965
1315
  /** Collection to evaluate against. */
966
1316
  collectionId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@personize/sdk",
3
- "version": "0.6.4",
3
+ "version": "0.6.6",
4
4
  "description": "Official Personize SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",