@memberjunction/ai-agents 2.107.0 → 2.109.0
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 +450 -0
- package/dist/AgentDataPreloader.d.ts +25 -0
- package/dist/AgentDataPreloader.d.ts.map +1 -0
- package/dist/AgentDataPreloader.js +264 -0
- package/dist/AgentDataPreloader.js.map +1 -0
- package/dist/agent-types/loop-agent-response-type.d.ts +2 -1
- package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.js +4 -2
- package/dist/agent-types/loop-agent-type.js.map +1 -1
- package/dist/base-agent.d.ts +33 -4
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +673 -36
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -268,6 +268,302 @@ The callback is invoked:
|
|
|
268
268
|
|
|
269
269
|
## Advanced Features
|
|
270
270
|
|
|
271
|
+
### Agent Data Preloading
|
|
272
|
+
|
|
273
|
+
Agents can declaratively preload reference data without requiring custom application code or action calls. Data sources are configured through the `AIAgentDataSource` entity and automatically loaded before agent execution.
|
|
274
|
+
|
|
275
|
+
#### Overview
|
|
276
|
+
|
|
277
|
+
Data preloading solves the common problem of agents needing access to reference data (like entity lists, configuration values, or initial state) that doesn't change during execution. Instead of:
|
|
278
|
+
- Writing custom application code to load data
|
|
279
|
+
- Having agents call actions to fetch data (which bloats conversation context)
|
|
280
|
+
- Manually passing the same data to every agent invocation
|
|
281
|
+
|
|
282
|
+
Agents can now specify data sources that are automatically loaded and injected into the appropriate destination (`data`, `context`, or `payload`).
|
|
283
|
+
|
|
284
|
+
#### Three Destination Types
|
|
285
|
+
|
|
286
|
+
**1. Data Destination** - For Nunjucks templates in prompts (visible to LLMs)
|
|
287
|
+
```typescript
|
|
288
|
+
// Configuration
|
|
289
|
+
{
|
|
290
|
+
"Name": "ALL_ENTITIES",
|
|
291
|
+
"SourceType": "RunView",
|
|
292
|
+
"EntityName": "Entities",
|
|
293
|
+
"OrderBy": "Name ASC",
|
|
294
|
+
"DestinationType": "Data",
|
|
295
|
+
"DestinationPath": null // Uses "ALL_ENTITIES" at root level
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Result in agent prompt:
|
|
299
|
+
// params.data.ALL_ENTITIES = [{ Name: "Users", ... }, { Name: "Entities", ... }]
|
|
300
|
+
|
|
301
|
+
// Prompt can use Nunjucks:
|
|
302
|
+
// You have access to {{ALL_ENTITIES.length}} entities:
|
|
303
|
+
// {% for entity in ALL_ENTITIES %}
|
|
304
|
+
// - {{entity.Name}}: {{entity.Description}}
|
|
305
|
+
// {% endfor %}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
**2. Context Destination** - For actions only (NOT visible to LLMs)
|
|
309
|
+
```typescript
|
|
310
|
+
// Configuration
|
|
311
|
+
{
|
|
312
|
+
"Name": "ORG_SETTINGS",
|
|
313
|
+
"SourceType": "RunView",
|
|
314
|
+
"EntityName": "Organization Settings",
|
|
315
|
+
"ExtraFilter": "OrgID='${context.organizationId}'",
|
|
316
|
+
"DestinationType": "Context",
|
|
317
|
+
"DestinationPath": "organization.settings"
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Result:
|
|
321
|
+
// params.context.organization.settings = { apiEndpoint: "...", features: [...] }
|
|
322
|
+
|
|
323
|
+
// Actions can access context, but prompts/LLMs cannot
|
|
324
|
+
// This keeps API keys and sensitive configuration away from LLMs
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**3. Payload Destination** - For agent state initialization
|
|
328
|
+
```typescript
|
|
329
|
+
// Configuration
|
|
330
|
+
{
|
|
331
|
+
"Name": "CustomerOrders",
|
|
332
|
+
"SourceType": "RunQuery",
|
|
333
|
+
"QueryName": "Recent Orders by Customer",
|
|
334
|
+
"Parameters": JSON.stringify({ customerId: "{{context.customerId}}" }),
|
|
335
|
+
"DestinationType": "Payload",
|
|
336
|
+
"DestinationPath": "analysis.orders.recent"
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Result:
|
|
340
|
+
// params.payload.analysis.orders.recent = [{ OrderID: "123", ... }]
|
|
341
|
+
|
|
342
|
+
// Agent starts with rich initial state without caller manually loading it
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
#### Data Source Types
|
|
346
|
+
|
|
347
|
+
**RunView Data Sources** - Query entities with filters
|
|
348
|
+
```typescript
|
|
349
|
+
{
|
|
350
|
+
"Name": "ACTIVE_MODELS",
|
|
351
|
+
"SourceType": "RunView",
|
|
352
|
+
"EntityName": "AI Models",
|
|
353
|
+
"ExtraFilter": "IsActive=1 AND Vendor='OpenAI'",
|
|
354
|
+
"OrderBy": "Priority DESC",
|
|
355
|
+
"FieldsToRetrieve": JSON.stringify(["ID", "Name", "Vendor", "MaxInputTokens"]),
|
|
356
|
+
"ResultType": "simple", // or "entity_object"
|
|
357
|
+
"MaxRows": 100,
|
|
358
|
+
"DestinationType": "Data"
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**RunQuery Data Sources** - Execute stored queries
|
|
363
|
+
```typescript
|
|
364
|
+
{
|
|
365
|
+
"Name": "MONTHLY_STATS",
|
|
366
|
+
"SourceType": "RunQuery",
|
|
367
|
+
"QueryName": "Monthly Analytics",
|
|
368
|
+
"CategoryPath": "/Reports/Analytics",
|
|
369
|
+
"Parameters": JSON.stringify({
|
|
370
|
+
month: "{{context.currentMonth}}",
|
|
371
|
+
year: "{{context.currentYear}}"
|
|
372
|
+
}),
|
|
373
|
+
"DestinationType": "Payload",
|
|
374
|
+
"DestinationPath": "stats.monthly"
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### Path Support
|
|
379
|
+
|
|
380
|
+
The `DestinationPath` field supports nested paths using dot notation:
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
// Simple root-level
|
|
384
|
+
{
|
|
385
|
+
"Name": "ENTITIES",
|
|
386
|
+
"DestinationPath": null // Uses "ENTITIES" at root
|
|
387
|
+
}
|
|
388
|
+
// Result: data.ENTITIES
|
|
389
|
+
|
|
390
|
+
// Nested paths
|
|
391
|
+
{
|
|
392
|
+
"Name": "ModelList",
|
|
393
|
+
"DestinationPath": "config.ai.models"
|
|
394
|
+
}
|
|
395
|
+
// Result: data.config.ai.models
|
|
396
|
+
|
|
397
|
+
// Deep nesting
|
|
398
|
+
{
|
|
399
|
+
"Name": "CustomerData",
|
|
400
|
+
"DestinationPath": "analysis.customer.profile.orders"
|
|
401
|
+
}
|
|
402
|
+
// Result: payload.analysis.customer.profile.orders
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
#### Caching Policies
|
|
406
|
+
|
|
407
|
+
Data sources support three caching strategies:
|
|
408
|
+
|
|
409
|
+
**1. None** - No caching (default)
|
|
410
|
+
```typescript
|
|
411
|
+
{
|
|
412
|
+
"CachePolicy": "None"
|
|
413
|
+
// Data is loaded fresh every time
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**2. PerRun** - Cache for duration of a single agent run
|
|
418
|
+
```typescript
|
|
419
|
+
{
|
|
420
|
+
"CachePolicy": "PerRun"
|
|
421
|
+
// Multiple data sources with same AgentID+Name share cached data within one run
|
|
422
|
+
// Cache is cleared when agent run completes
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
**3. PerAgent** - Global cache with TTL
|
|
427
|
+
```typescript
|
|
428
|
+
{
|
|
429
|
+
"CachePolicy": "PerAgent",
|
|
430
|
+
"CacheTimeoutSeconds": 3600 // 1 hour
|
|
431
|
+
// Cached across all runs for this agent until TTL expires
|
|
432
|
+
// Good for rarely-changing reference data like entity lists
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
#### Execution Control
|
|
437
|
+
|
|
438
|
+
**Disable data preloading** for specific executions:
|
|
439
|
+
```typescript
|
|
440
|
+
const result = await runner.RunAgent({
|
|
441
|
+
agent: myAgent,
|
|
442
|
+
conversationMessages: messages,
|
|
443
|
+
contextUser: user,
|
|
444
|
+
disableDataPreloading: true // Skip automatic data preloading
|
|
445
|
+
});
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
**Caller precedence**: Caller-provided data always takes precedence over preloaded data:
|
|
449
|
+
```typescript
|
|
450
|
+
const result = await runner.RunAgent({
|
|
451
|
+
agent: myAgent,
|
|
452
|
+
conversationMessages: messages,
|
|
453
|
+
contextUser: user,
|
|
454
|
+
data: {
|
|
455
|
+
CUSTOM_ENTITIES: myEntities // Overrides preloaded CUSTOM_ENTITIES
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
#### Configuration Examples
|
|
461
|
+
|
|
462
|
+
**Database Research Agent** - Preload entity metadata
|
|
463
|
+
```typescript
|
|
464
|
+
// Data source 1: All entities for reference
|
|
465
|
+
{
|
|
466
|
+
"AgentID": "database-research-agent-id",
|
|
467
|
+
"Name": "ALL_ENTITIES",
|
|
468
|
+
"SourceType": "RunView",
|
|
469
|
+
"EntityName": "Entities",
|
|
470
|
+
"OrderBy": "Name ASC",
|
|
471
|
+
"FieldsToRetrieve": JSON.stringify(["ID", "Name", "SchemaName", "Description", "BaseView"]),
|
|
472
|
+
"DestinationType": "Data",
|
|
473
|
+
"ExecutionOrder": 1,
|
|
474
|
+
"Status": "Active",
|
|
475
|
+
"CachePolicy": "PerAgent",
|
|
476
|
+
"CacheTimeoutSeconds": 3600
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Data source 2: Schema information
|
|
480
|
+
{
|
|
481
|
+
"AgentID": "database-research-agent-id",
|
|
482
|
+
"Name": "SCHEMA_INFO",
|
|
483
|
+
"SourceType": "RunView",
|
|
484
|
+
"EntityName": "Entity Fields",
|
|
485
|
+
"DestinationType": "Data",
|
|
486
|
+
"DestinationPath": "schema.fields",
|
|
487
|
+
"ExecutionOrder": 2,
|
|
488
|
+
"Status": "Active",
|
|
489
|
+
"CachePolicy": "PerAgent",
|
|
490
|
+
"CacheTimeoutSeconds": 3600
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
**Customer Service Agent** - Preload customer context
|
|
495
|
+
```typescript
|
|
496
|
+
// Preload customer data into payload
|
|
497
|
+
{
|
|
498
|
+
"AgentID": "customer-service-agent-id",
|
|
499
|
+
"Name": "CUSTOMER_PROFILE",
|
|
500
|
+
"SourceType": "RunView",
|
|
501
|
+
"EntityName": "Customers",
|
|
502
|
+
"ExtraFilter": "ID='{{context.customerId}}'",
|
|
503
|
+
"DestinationType": "Payload",
|
|
504
|
+
"DestinationPath": "customer.profile",
|
|
505
|
+
"Status": "Active",
|
|
506
|
+
"CachePolicy": "PerRun"
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// Preload recent orders
|
|
510
|
+
{
|
|
511
|
+
"AgentID": "customer-service-agent-id",
|
|
512
|
+
"Name": "RECENT_ORDERS",
|
|
513
|
+
"SourceType": "RunQuery",
|
|
514
|
+
"QueryName": "Recent Orders by Customer",
|
|
515
|
+
"Parameters": JSON.stringify({ customerId: "{{context.customerId}}", days: 30 }),
|
|
516
|
+
"DestinationType": "Payload",
|
|
517
|
+
"DestinationPath": "customer.orders",
|
|
518
|
+
"Status": "Active",
|
|
519
|
+
"CachePolicy": "PerRun"
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Preload organization settings (for actions)
|
|
523
|
+
{
|
|
524
|
+
"AgentID": "customer-service-agent-id",
|
|
525
|
+
"Name": "ORG_CONFIG",
|
|
526
|
+
"SourceType": "RunView",
|
|
527
|
+
"EntityName": "Organization Settings",
|
|
528
|
+
"ExtraFilter": "OrgID='{{context.organizationId}}'",
|
|
529
|
+
"DestinationType": "Context",
|
|
530
|
+
"DestinationPath": "organization.config",
|
|
531
|
+
"Status": "Active",
|
|
532
|
+
"CachePolicy": "PerAgent",
|
|
533
|
+
"CacheTimeoutSeconds": 1800
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
#### Benefits
|
|
538
|
+
|
|
539
|
+
- **Declarative**: Configure data preloading through metadata, not code
|
|
540
|
+
- **Reusable**: Same agent works across different environments
|
|
541
|
+
- **Efficient**: Caching reduces redundant database queries
|
|
542
|
+
- **Clean Separation**: Keeps data in appropriate destinations (data/context/payload)
|
|
543
|
+
- **Flexible**: Supports both RunView and RunQuery with full parameter control
|
|
544
|
+
- **Secure**: Context destination keeps sensitive data away from LLMs
|
|
545
|
+
- **Performance**: Multiple caching strategies for different use cases
|
|
546
|
+
|
|
547
|
+
#### Database Schema
|
|
548
|
+
|
|
549
|
+
The `AIAgentDataSource` table includes:
|
|
550
|
+
- **AgentID**: The agent using this data source
|
|
551
|
+
- **Name**: Variable name (used as fallback if DestinationPath is null)
|
|
552
|
+
- **SourceType**: RunView or RunQuery
|
|
553
|
+
- **EntityName**, **ExtraFilter**, **OrderBy**, **FieldsToRetrieve**, **ResultType**: RunView parameters
|
|
554
|
+
- **QueryName**, **CategoryPath**, **Parameters**: RunQuery parameters
|
|
555
|
+
- **MaxRows**: Limit results (applies to both source types)
|
|
556
|
+
- **DestinationType**: Data, Context, or Payload
|
|
557
|
+
- **DestinationPath**: Nested path using dot notation (optional)
|
|
558
|
+
- **ExecutionOrder**: Order to execute when multiple sources exist
|
|
559
|
+
- **Status**: Active or Disabled
|
|
560
|
+
- **CachePolicy**: None, PerRun, or PerAgent
|
|
561
|
+
- **CacheTimeoutSeconds**: TTL for PerAgent cache
|
|
562
|
+
|
|
563
|
+
**Unique Constraint**: `AgentID + Name + DestinationType + DestinationPath`
|
|
564
|
+
- Allows same Name across different destinations/paths
|
|
565
|
+
- Example: "ENTITIES" can exist in both Data and Payload destinations
|
|
566
|
+
|
|
271
567
|
### Payload Scoping for Sub-Agents
|
|
272
568
|
|
|
273
569
|
The framework now supports narrowing the payload that sub-agents work with through the `PayloadScope` field:
|
|
@@ -498,10 +794,164 @@ const result = await agent.ExecutePrompt({
|
|
|
498
794
|
### Context Management
|
|
499
795
|
Agents automatically manage conversation context:
|
|
500
796
|
- Maintains message history across steps
|
|
797
|
+
- **Intelligent message expiration** - Automatically compacts or removes old action results
|
|
501
798
|
- Compresses context when approaching token limits
|
|
502
799
|
- Handles placeholder replacement in prompts
|
|
503
800
|
- Preserves important context during compression
|
|
504
801
|
|
|
802
|
+
### Message Expiration and Compaction
|
|
803
|
+
|
|
804
|
+
The framework provides sophisticated message lifecycle management to prevent context bloat from large action results:
|
|
805
|
+
|
|
806
|
+
**Per-Action Configuration** (in `AIAgentAction` table):
|
|
807
|
+
- `ResultExpirationTurns`: Number of turns before message expires (e.g., 2)
|
|
808
|
+
- `ResultExpirationMode`: 'None' | 'Remove' | 'Compact'
|
|
809
|
+
- `CompactMode`: 'First N Chars' | 'AI Summary'
|
|
810
|
+
- `CompactLength`: Character limit for 'First N Chars' mode
|
|
811
|
+
- `CompactPromptID`: Custom AI prompt for 'AI Summary' mode
|
|
812
|
+
|
|
813
|
+
**How It Works**:
|
|
814
|
+
```typescript
|
|
815
|
+
// Configure a Google Search action to compact results after 2 turns
|
|
816
|
+
await agentAction.Save({
|
|
817
|
+
ResultExpirationTurns: 2,
|
|
818
|
+
ResultExpirationMode: 'Compact',
|
|
819
|
+
CompactMode: 'First N Chars',
|
|
820
|
+
CompactLength: 500
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
// Turn 1: Action returns 10,000 char search results
|
|
824
|
+
// Turn 2: Results still in conversation (turn 1, limit 2)
|
|
825
|
+
// Turn 3: Results still in conversation (turn 2, limit 2)
|
|
826
|
+
// Turn 4: Results compacted to 500 chars (turn 3 > limit 2)
|
|
827
|
+
// Original content preserved in metadata for expansion
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
**Compaction Modes**:
|
|
831
|
+
1. **First N Chars**: Fast truncation with annotation
|
|
832
|
+
```
|
|
833
|
+
First 500 chars of result...
|
|
834
|
+
|
|
835
|
+
[Compacted: showing first 500 of 10000 characters. Agent can request expansion if needed.]
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
2. **AI Summary**: Intelligent LLM-based summarization
|
|
839
|
+
```
|
|
840
|
+
[AI Summary of 10000 chars. Agent can request full expansion if needed.]
|
|
841
|
+
|
|
842
|
+
Search found 47 results for "MemberJunction". Top results include...
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
**Message Expansion**:
|
|
846
|
+
Agents can restore compacted messages when needed:
|
|
847
|
+
```typescript
|
|
848
|
+
// In agent's JSON response
|
|
849
|
+
{
|
|
850
|
+
"taskComplete": false,
|
|
851
|
+
"nextStep": {
|
|
852
|
+
"type": "Retry",
|
|
853
|
+
"messageIndex": 5, // Index of compacted message
|
|
854
|
+
"reason": "Need full search results to answer user's question about item #47"
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
**Runtime Override**:
|
|
860
|
+
Test different expiration strategies without modifying database:
|
|
861
|
+
```typescript
|
|
862
|
+
const result = await runner.RunAgent({
|
|
863
|
+
agent: myAgent,
|
|
864
|
+
conversationMessages: messages,
|
|
865
|
+
contextUser: user,
|
|
866
|
+
messageExpirationOverride: {
|
|
867
|
+
expirationTurns: 1,
|
|
868
|
+
expirationMode: 'Compact',
|
|
869
|
+
compactMode: 'First N Chars',
|
|
870
|
+
compactLength: 200,
|
|
871
|
+
preserveOriginalContent: true
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
**Lifecycle Monitoring**:
|
|
877
|
+
Track message compaction for debugging and token savings analysis:
|
|
878
|
+
```typescript
|
|
879
|
+
const result = await runner.RunAgent({
|
|
880
|
+
agent: myAgent,
|
|
881
|
+
conversationMessages: messages,
|
|
882
|
+
contextUser: user,
|
|
883
|
+
onMessageLifecycle: (event) => {
|
|
884
|
+
console.log(`[Turn ${event.turn}] ${event.type}: ${event.reason}`);
|
|
885
|
+
if (event.tokensSaved) {
|
|
886
|
+
console.log(` Tokens saved: ${event.tokensSaved}`);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
// Output:
|
|
891
|
+
// [Turn 3] message-compacted: Compacted using First N Chars (saved 2375 tokens)
|
|
892
|
+
// [Turn 5] message-removed: Removed due to expiration
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
**Prompt Lookup Hierarchy**:
|
|
896
|
+
For AI Summary mode, prompts are resolved in this order:
|
|
897
|
+
1. Runtime override (`messageExpirationOverride.compactPromptId`)
|
|
898
|
+
2. Agent action configuration (`AIAgentAction.CompactPromptID`)
|
|
899
|
+
3. Action default (`Action.DefaultCompactPromptID`)
|
|
900
|
+
4. System default ("Compact Agent Message" prompt)
|
|
901
|
+
|
|
902
|
+
**Benefits**:
|
|
903
|
+
- **Addresses Large Action Results**: Automatically handles the most common cause of context bloat
|
|
904
|
+
- **Configurable Per-Action**: Different expiration strategies for different action types
|
|
905
|
+
- **Non-Destructive**: Original content preserved in metadata for on-demand expansion
|
|
906
|
+
- **Token Savings**: Reduces context window usage by 70-95% for large results
|
|
907
|
+
- **Agent-Aware**: Agents can detect compacted messages and request full expansion when needed
|
|
908
|
+
|
|
909
|
+
### Context Length Recovery
|
|
910
|
+
|
|
911
|
+
When a prompt execution fails due to context length overflow (even after model failover), BaseAgent provides **one-time automatic recovery** instead of immediately terminating. This gives the agent an opportunity to adapt its approach.
|
|
912
|
+
|
|
913
|
+
**How It Works**:
|
|
914
|
+
1. **Prompt fails with ContextLengthExceeded** → Detected as fatal error
|
|
915
|
+
2. **First occurrence**: Recovery is attempted automatically (once per run)
|
|
916
|
+
3. **Last user message is trimmed** using smart strategies:
|
|
917
|
+
- JSON arrays: Keeps first 10 items with truncation notice
|
|
918
|
+
- CSV data: Keeps header + first 10 rows
|
|
919
|
+
- Plain text: Keeps first 1000 characters
|
|
920
|
+
4. **Agent receives clear guidance** explaining what happened and recommended actions
|
|
921
|
+
5. **Agent gets Retry step** to choose alternative approach (e.g., more specific filters, batch requests)
|
|
922
|
+
6. **If recovery fails again**: Normal fatal error handling (agent terminates)
|
|
923
|
+
|
|
924
|
+
**Example Recovery Message**:
|
|
925
|
+
```
|
|
926
|
+
⚠️ CONTEXT OVERFLOW RECOVERY ⚠️
|
|
927
|
+
|
|
928
|
+
The previous step returned a result that exceeded the context window (147,532 characters truncated).
|
|
929
|
+
|
|
930
|
+
Here is a PARTIAL result from the previous action:
|
|
931
|
+
---
|
|
932
|
+
[First 10 items from JSON array...]
|
|
933
|
+
... (487 more items truncated due to context length)
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
❗ THE ABOVE IS INCOMPLETE - the full result was too large for the context window.
|
|
937
|
+
|
|
938
|
+
RECOMMENDED ACTIONS:
|
|
939
|
+
1. Use a different action with more specific filters to get smaller result sets
|
|
940
|
+
2. Request data in batches or pages instead of all at once
|
|
941
|
+
3. Ask the user to clarify scope to narrow the query
|
|
942
|
+
4. If you need the full data, acknowledge the limitation and ask the user how to proceed
|
|
943
|
+
|
|
944
|
+
Please choose an alternative approach to complete your task.
|
|
945
|
+
```
|
|
946
|
+
|
|
947
|
+
**Benefits**:
|
|
948
|
+
- **Resilient**: Agents can adapt instead of failing immediately
|
|
949
|
+
- **Informative**: Clear explanation of what went wrong and how to recover
|
|
950
|
+
- **Safe**: ONE-TIME recovery prevents infinite loops
|
|
951
|
+
- **Smart**: Preserves data structure when possible (JSON, CSV)
|
|
952
|
+
|
|
953
|
+
This feature is particularly useful when agents call actions that can return very large datasets (e.g., "Get Entity List" without filters).
|
|
954
|
+
|
|
505
955
|
### Action Integration
|
|
506
956
|
```typescript
|
|
507
957
|
// In agent type's DetermineNextStep
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { UserInfo } from '@memberjunction/core';
|
|
2
|
+
export interface PreloadedDataResult {
|
|
3
|
+
data: Record<string, unknown>;
|
|
4
|
+
context: Record<string, unknown>;
|
|
5
|
+
payload: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export declare class AgentDataPreloader {
|
|
8
|
+
private static _instance;
|
|
9
|
+
private _perAgentCache;
|
|
10
|
+
private _perRunCache;
|
|
11
|
+
private constructor();
|
|
12
|
+
static get Instance(): AgentDataPreloader;
|
|
13
|
+
PreloadAgentData(agentId: string, contextUser: UserInfo, runId?: string): Promise<PreloadedDataResult>;
|
|
14
|
+
clearRunCache(runId: string): void;
|
|
15
|
+
clearAgentCache(): void;
|
|
16
|
+
private loadDataSourcesForAgent;
|
|
17
|
+
private executeDataSource;
|
|
18
|
+
private executeRunView;
|
|
19
|
+
private executeRunQuery;
|
|
20
|
+
private getCachedData;
|
|
21
|
+
private cacheData;
|
|
22
|
+
private getPerAgentCacheKey;
|
|
23
|
+
}
|
|
24
|
+
export declare function LoadAgentDataPreloader(): AgentDataPreloader;
|
|
25
|
+
//# sourceMappingURL=AgentDataPreloader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentDataPreloader.d.ts","sourceRoot":"","sources":["../src/AgentDataPreloader.ts"],"names":[],"mappings":"AAcA,OAAO,EAAqE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAQnH,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AA4BD,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAmC;IAK3D,OAAO,CAAC,cAAc,CAAsC;IAK5D,OAAO,CAAC,YAAY,CAAgD;IAKpE,OAAO;IAOP,WAAkB,QAAQ,IAAI,kBAAkB,CAK/C;IA4BY,gBAAgB,CACzB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,QAAQ,EACrB,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,mBAAmB,CAAC;IA8ExB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAalC,eAAe,IAAI,IAAI;YAchB,uBAAuB;YAuBvB,iBAAiB;YAsCjB,cAAc;YAwCd,eAAe;IAuC7B,OAAO,CAAC,aAAa;IA2CrB,OAAO,CAAC,SAAS;IAwCjB,OAAO,CAAC,mBAAmB;CAG9B;AAKD,wBAAgB,sBAAsB,uBAGrC"}
|