@hashgraphonline/conversational-agent 0.2.1 → 0.2.103
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 +3 -3
- package/bin/conversational-agent-cli.js +0 -1
- package/dist/cjs/conversational-agent.d.ts +11 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/memory/smart-memory-manager.d.ts +7 -1
- package/dist/cjs/services/attachment-processor.d.ts +41 -0
- package/dist/cjs/services/index.d.ts +2 -0
- package/dist/cjs/services/parameter-service.d.ts +43 -0
- package/dist/cjs/tools/entity-resolver-tool.d.ts +5 -3
- package/dist/esm/index.js +9 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index10.js +2 -2
- package/dist/esm/index18.js +64 -17
- package/dist/esm/index18.js.map +1 -1
- package/dist/esm/index21.js +1 -1
- package/dist/esm/index23.js +3 -3
- package/dist/esm/index24.js +20 -4
- package/dist/esm/index24.js.map +1 -1
- package/dist/esm/index29.js +248 -903
- package/dist/esm/index29.js.map +1 -1
- package/dist/esm/index30.js +98 -219
- package/dist/esm/index30.js.map +1 -1
- package/dist/esm/index31.js +833 -1085
- package/dist/esm/index31.js.map +1 -1
- package/dist/esm/index32.js +228 -115
- package/dist/esm/index32.js.map +1 -1
- package/dist/esm/index33.js +1197 -79
- package/dist/esm/index33.js.map +1 -1
- package/dist/esm/index34.js +119 -39
- package/dist/esm/index34.js.map +1 -1
- package/dist/esm/index35.js +103 -96
- package/dist/esm/index35.js.map +1 -1
- package/dist/esm/index36.js +46 -21
- package/dist/esm/index36.js.map +1 -1
- package/dist/esm/index37.js +107 -12
- package/dist/esm/index37.js.map +1 -1
- package/dist/esm/index38.js +21 -7
- package/dist/esm/index38.js.map +1 -1
- package/dist/esm/index39.js +11 -26
- package/dist/esm/index39.js.map +1 -1
- package/dist/esm/index40.js +6 -4
- package/dist/esm/index40.js.map +1 -1
- package/dist/esm/index41.js +5 -255
- package/dist/esm/index41.js.map +1 -1
- package/dist/esm/index42.js +213 -142
- package/dist/esm/index42.js.map +1 -1
- package/dist/esm/index43.js +174 -82
- package/dist/esm/index43.js.map +1 -1
- package/dist/esm/index44.js +95 -0
- package/dist/esm/index44.js.map +1 -0
- package/dist/esm/index45.js +30 -0
- package/dist/esm/index45.js.map +1 -0
- package/dist/esm/index5.js +2 -2
- package/dist/esm/index6.js +76 -6
- package/dist/esm/index6.js.map +1 -1
- package/dist/esm/index8.js +1 -1
- package/dist/types/conversational-agent.d.ts +11 -1
- package/dist/types/memory/smart-memory-manager.d.ts +7 -1
- package/dist/types/services/attachment-processor.d.ts +41 -0
- package/dist/types/services/index.d.ts +2 -0
- package/dist/types/services/parameter-service.d.ts +43 -0
- package/dist/types/tools/entity-resolver-tool.d.ts +5 -3
- package/package.json +2 -1
- package/src/conversational-agent.ts +97 -5
- package/src/langchain/form-aware-agent-executor.ts +1 -1
- package/src/langchain/langchain-agent.ts +36 -18
- package/src/memory/smart-memory-manager.ts +80 -27
- package/src/scripts/test-inscribe-form-generation.ts +3 -3
- package/src/scripts/test-inscribe-wrapper-verification.ts +3 -3
- package/src/services/attachment-processor.ts +163 -0
- package/src/services/content-store-manager.ts +32 -4
- package/src/services/index.ts +2 -0
- package/src/services/parameter-service.ts +430 -0
- package/src/tools/entity-resolver-tool.ts +12 -18
|
@@ -19,6 +19,8 @@ export interface EntityAssociation {
|
|
|
19
19
|
createdAt: Date;
|
|
20
20
|
/** Transaction ID that created this entity */
|
|
21
21
|
transactionId?: string;
|
|
22
|
+
/** Optional session identifier to scope associations */
|
|
23
|
+
sessionId?: string;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
/**
|
|
@@ -381,7 +383,8 @@ export class SmartMemoryManager {
|
|
|
381
383
|
entityId: string,
|
|
382
384
|
entityName: string,
|
|
383
385
|
entityType: string,
|
|
384
|
-
transactionId?: string
|
|
386
|
+
transactionId?: string,
|
|
387
|
+
sessionId?: string
|
|
385
388
|
): void {
|
|
386
389
|
try {
|
|
387
390
|
if (
|
|
@@ -410,7 +413,7 @@ export class SmartMemoryManager {
|
|
|
410
413
|
|
|
411
414
|
const sanitizedEntityId = entityId.trim();
|
|
412
415
|
const sanitizedEntityName = entityName.trim().substring(0, 100);
|
|
413
|
-
const sanitizedEntityType =
|
|
416
|
+
const sanitizedEntityType = this.normalizeEntityType(entityType);
|
|
414
417
|
|
|
415
418
|
let usageHint = '';
|
|
416
419
|
if (sanitizedEntityType === 'tokenid') {
|
|
@@ -433,7 +436,7 @@ export class SmartMemoryManager {
|
|
|
433
436
|
createdAt: new Date(),
|
|
434
437
|
isEntityAssociation: true,
|
|
435
438
|
...(usageHint ? { usage: usageHint } : {}),
|
|
436
|
-
...(sanitizedEntityType === '
|
|
439
|
+
...(sanitizedEntityType === 'topicId'
|
|
437
440
|
? { hrl: `hcs://1/${sanitizedEntityId}` }
|
|
438
441
|
: {}),
|
|
439
442
|
...(transactionId !== undefined &&
|
|
@@ -441,6 +444,7 @@ export class SmartMemoryManager {
|
|
|
441
444
|
transactionId.trim() !== ''
|
|
442
445
|
? { transactionId: transactionId.trim() }
|
|
443
446
|
: {}),
|
|
447
|
+
...(sessionId && sessionId.trim() !== '' ? { sessionId: sessionId.trim() } : {}),
|
|
444
448
|
};
|
|
445
449
|
|
|
446
450
|
const content = JSON.stringify(association);
|
|
@@ -462,6 +466,7 @@ export class SmartMemoryManager {
|
|
|
462
466
|
entityName: sanitizedEntityName,
|
|
463
467
|
entityType: sanitizedEntityType,
|
|
464
468
|
isEntityAssociation: true,
|
|
469
|
+
...(sessionId && sessionId.trim() !== '' ? { sessionId: sessionId.trim() } : {}),
|
|
465
470
|
},
|
|
466
471
|
};
|
|
467
472
|
|
|
@@ -480,6 +485,43 @@ export class SmartMemoryManager {
|
|
|
480
485
|
}
|
|
481
486
|
}
|
|
482
487
|
|
|
488
|
+
/**
|
|
489
|
+
* Normalize various type aliases to canonical EntityFormat strings using a registry.
|
|
490
|
+
*/
|
|
491
|
+
private normalizeEntityType(input: string): string {
|
|
492
|
+
const raw = (input || '').trim();
|
|
493
|
+
if (raw.length === 0) {
|
|
494
|
+
return '';
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
const key = raw.replace(/[^a-z]/gi, '').toLowerCase();
|
|
498
|
+
|
|
499
|
+
const REGISTRY: Record<string, string> = {
|
|
500
|
+
topic: 'topicId',
|
|
501
|
+
topicid: 'topicId',
|
|
502
|
+
token: 'tokenId',
|
|
503
|
+
tokenid: 'tokenId',
|
|
504
|
+
account: 'accountId',
|
|
505
|
+
accountid: 'accountId',
|
|
506
|
+
contract: 'contractId',
|
|
507
|
+
contractid: 'contractId',
|
|
508
|
+
file: 'fileId',
|
|
509
|
+
fileid: 'fileId',
|
|
510
|
+
schedule: 'scheduleId',
|
|
511
|
+
scheduleid: 'scheduleId',
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
if (Object.prototype.hasOwnProperty.call(REGISTRY, key)) {
|
|
515
|
+
return REGISTRY[key];
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
if (/^[a-z]+Id$/.test(raw)) {
|
|
519
|
+
return raw;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
return raw;
|
|
523
|
+
}
|
|
524
|
+
|
|
483
525
|
/**
|
|
484
526
|
* Resolve entity references from natural language queries
|
|
485
527
|
* @param query - Search query (entity name or natural language reference)
|
|
@@ -611,19 +653,15 @@ export class SmartMemoryManager {
|
|
|
611
653
|
*/
|
|
612
654
|
getEntityAssociations(entityType?: string): EntityAssociation[] {
|
|
613
655
|
try {
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
: undefined;
|
|
656
|
+
const rawFilter = entityType ? entityType.trim() : undefined;
|
|
657
|
+
const filterCanonical = rawFilter ? this.normalizeEntityType(rawFilter) : undefined;
|
|
617
658
|
|
|
618
|
-
if (
|
|
619
|
-
entityType &&
|
|
620
|
-
(!sanitizedEntityType || sanitizedEntityType.length === 0)
|
|
621
|
-
) {
|
|
659
|
+
if (entityType && (!rawFilter || rawFilter.length === 0)) {
|
|
622
660
|
return [];
|
|
623
661
|
}
|
|
624
662
|
|
|
625
663
|
const SEARCH_ANY_ENTITY = 'entityId';
|
|
626
|
-
const searchQuery =
|
|
664
|
+
const searchQuery = filterCanonical || SEARCH_ANY_ENTITY;
|
|
627
665
|
const searchResults = this._contentStorage.searchMessages(searchQuery, {
|
|
628
666
|
caseSensitive: false,
|
|
629
667
|
limit: 100,
|
|
@@ -638,10 +676,7 @@ export class SmartMemoryManager {
|
|
|
638
676
|
const parsed = JSON.parse(content);
|
|
639
677
|
|
|
640
678
|
if (parsed.entityId && parsed.entityName && parsed.entityType) {
|
|
641
|
-
if (
|
|
642
|
-
sanitizedEntityType &&
|
|
643
|
-
parsed.entityType !== sanitizedEntityType
|
|
644
|
-
) {
|
|
679
|
+
if (filterCanonical && parsed.entityType !== filterCanonical) {
|
|
645
680
|
continue;
|
|
646
681
|
}
|
|
647
682
|
|
|
@@ -667,18 +702,36 @@ export class SmartMemoryManager {
|
|
|
667
702
|
}
|
|
668
703
|
}
|
|
669
704
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
705
|
+
// Merge duplicates by entityId, preferring the newest and one that carries transactionId
|
|
706
|
+
const mergedById = new Map<string, EntityAssociation>();
|
|
707
|
+
const getTime = (d: Date | string): number =>
|
|
708
|
+
d instanceof Date ? d.getTime() : new Date(d).getTime();
|
|
709
|
+
|
|
710
|
+
for (const assoc of associations) {
|
|
711
|
+
const existing = mergedById.get(assoc.entityId);
|
|
712
|
+
if (!existing) {
|
|
713
|
+
mergedById.set(assoc.entityId, assoc);
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
const existingTime = getTime(existing.createdAt);
|
|
718
|
+
const currentTime = getTime(assoc.createdAt);
|
|
719
|
+
|
|
720
|
+
const preferCurrent =
|
|
721
|
+
currentTime > existingTime ||
|
|
722
|
+
(!!assoc.transactionId && !existing.transactionId);
|
|
723
|
+
|
|
724
|
+
if (preferCurrent) {
|
|
725
|
+
mergedById.set(assoc.entityId, {
|
|
726
|
+
...existing,
|
|
727
|
+
...assoc,
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
const results = Array.from(mergedById.values()).sort((a, b) =>
|
|
733
|
+
getTime(b.createdAt) - getTime(a.createdAt)
|
|
734
|
+
);
|
|
682
735
|
|
|
683
736
|
return results;
|
|
684
737
|
} catch (error) {
|
|
@@ -69,9 +69,9 @@ async function createTestAgent(): Promise<ConversationalAgent> {
|
|
|
69
69
|
network: (process.env.HEDERA_NETWORK as 'testnet' | 'mainnet') || 'testnet',
|
|
70
70
|
openAIApiKey: process.env.OPENAI_API_KEY!,
|
|
71
71
|
openAIModelName: 'gpt-4o-mini',
|
|
72
|
-
verbose: true,
|
|
73
|
-
disableLogging: false,
|
|
74
|
-
entityMemoryEnabled: false,
|
|
72
|
+
verbose: true,
|
|
73
|
+
disableLogging: false,
|
|
74
|
+
entityMemoryEnabled: false,
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
const agent = new ConversationalAgent(options);
|
|
@@ -64,9 +64,9 @@ async function createTestAgent(): Promise<ConversationalAgent> {
|
|
|
64
64
|
network: (process.env.HEDERA_NETWORK as 'testnet' | 'mainnet') || 'testnet',
|
|
65
65
|
openAIApiKey: process.env.OPENAI_API_KEY!,
|
|
66
66
|
openAIModelName: 'gpt-4o-mini',
|
|
67
|
-
verbose: false,
|
|
68
|
-
disableLogging: true,
|
|
69
|
-
entityMemoryEnabled: false,
|
|
67
|
+
verbose: false,
|
|
68
|
+
disableLogging: true,
|
|
69
|
+
entityMemoryEnabled: false,
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
const agent = new ConversationalAgent(options);
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { Logger } from '@hashgraphonline/standards-sdk';
|
|
2
|
+
import type { ContentStoreManager as PackageContentStoreManager } from './content-store-manager';
|
|
3
|
+
|
|
4
|
+
export interface AttachmentData {
|
|
5
|
+
name: string;
|
|
6
|
+
data: string;
|
|
7
|
+
type: string;
|
|
8
|
+
size: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type ContentStoreManager = PackageContentStoreManager;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Utility for processing file attachments and content references
|
|
15
|
+
*/
|
|
16
|
+
export class AttachmentProcessor {
|
|
17
|
+
private logger: Logger;
|
|
18
|
+
|
|
19
|
+
constructor() {
|
|
20
|
+
this.logger = new Logger({ module: 'AttachmentProcessor' });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Process attachments and create content references
|
|
25
|
+
*/
|
|
26
|
+
async processAttachments(
|
|
27
|
+
content: string,
|
|
28
|
+
attachments: AttachmentData[],
|
|
29
|
+
contentStoreManager?: ContentStoreManager
|
|
30
|
+
): Promise<string> {
|
|
31
|
+
if (attachments.length === 0) {
|
|
32
|
+
return content;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
this.logger.info('Processing attachments with content reference system:', {
|
|
36
|
+
attachmentCount: attachments.length,
|
|
37
|
+
totalSize: attachments.reduce((sum, att) => sum + att.size, 0),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (contentStoreManager && contentStoreManager.isInitialized()) {
|
|
41
|
+
return this.processWithContentStore(content, attachments, contentStoreManager);
|
|
42
|
+
} else {
|
|
43
|
+
this.logger.warn('Content storage not available, creating simple file references');
|
|
44
|
+
return this.processWithSimpleReferences(content, attachments);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Process attachments using content store manager
|
|
50
|
+
*/
|
|
51
|
+
private async processWithContentStore(
|
|
52
|
+
content: string,
|
|
53
|
+
attachments: AttachmentData[],
|
|
54
|
+
contentStoreManager: ContentStoreManager
|
|
55
|
+
): Promise<string> {
|
|
56
|
+
const contentReferences: string[] = [];
|
|
57
|
+
|
|
58
|
+
for (const attachment of attachments) {
|
|
59
|
+
try {
|
|
60
|
+
const base64Data = attachment.data.includes('base64,')
|
|
61
|
+
? attachment.data.split('base64,')[1]
|
|
62
|
+
: attachment.data;
|
|
63
|
+
const buffer = Buffer.from(base64Data, 'base64');
|
|
64
|
+
|
|
65
|
+
const contentRef = await contentStoreManager.storeContentIfLarge(
|
|
66
|
+
buffer,
|
|
67
|
+
{
|
|
68
|
+
mimeType: attachment.type,
|
|
69
|
+
source: 'user_upload',
|
|
70
|
+
fileName: attachment.name,
|
|
71
|
+
tags: ['attachment', 'user_file'],
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
if (contentRef) {
|
|
76
|
+
if (attachment.type.startsWith('image/')) {
|
|
77
|
+
contentReferences.push(
|
|
78
|
+
`[Image File: ${attachment.name}] (content-ref:${contentRef.referenceId})`
|
|
79
|
+
);
|
|
80
|
+
} else {
|
|
81
|
+
contentReferences.push(
|
|
82
|
+
`[File: ${attachment.name}] (content-ref:${contentRef.referenceId})`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
contentReferences.push(
|
|
87
|
+
this.createInlineReference(attachment, base64Data)
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
} catch (error) {
|
|
91
|
+
this.logger.error('Failed to process attachment:', {
|
|
92
|
+
fileName: attachment.name,
|
|
93
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
94
|
+
});
|
|
95
|
+
contentReferences.push(
|
|
96
|
+
`[File: ${attachment.name} - Error processing file: ${
|
|
97
|
+
error instanceof Error ? error.message : 'Unknown error'
|
|
98
|
+
}]`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const fileList = this.createFileList(attachments);
|
|
104
|
+
return content
|
|
105
|
+
? `${content}\n\nAttached files:\n${fileList}\n\n${contentReferences.join('\n')}`
|
|
106
|
+
: `Attached files:\n${fileList}\n\n${contentReferences.join('\n')}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Process attachments with simple file references
|
|
111
|
+
*/
|
|
112
|
+
private processWithSimpleReferences(content: string, attachments: AttachmentData[]): string {
|
|
113
|
+
const fileReferences = attachments.map((attachment) => {
|
|
114
|
+
const sizeStr = this.formatFileSize(attachment.size);
|
|
115
|
+
|
|
116
|
+
if (attachment.type.startsWith('image/')) {
|
|
117
|
+
return `📎 Image: ${attachment.name} (${sizeStr}, ${attachment.type})`;
|
|
118
|
+
} else {
|
|
119
|
+
return `📎 File: ${attachment.name} (${sizeStr}, ${attachment.type})`;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
return content
|
|
124
|
+
? `${content}\n\nAttached files:\n${fileReferences.join('\n')}`
|
|
125
|
+
: `Attached files:\n${fileReferences.join('\n')}`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Create inline reference for small files
|
|
130
|
+
*/
|
|
131
|
+
private createInlineReference(attachment: AttachmentData, base64Data: string): string {
|
|
132
|
+
if (attachment.size < 50000) {
|
|
133
|
+
if (attachment.type.startsWith('image/')) {
|
|
134
|
+
return ``;
|
|
135
|
+
} else {
|
|
136
|
+
return `[File: ${attachment.name} (${this.formatFileSize(attachment.size)})]\nContent: ${base64Data}`;
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
return `[File: ${attachment.name} (${this.formatFileSize(attachment.size)}) - Content too large to include inline]`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Create formatted file list
|
|
145
|
+
*/
|
|
146
|
+
private createFileList(attachments: AttachmentData[]): string {
|
|
147
|
+
return attachments
|
|
148
|
+
.map((file) => {
|
|
149
|
+
const sizeStr = this.formatFileSize(file.size);
|
|
150
|
+
return `📎 ${file.name} (${sizeStr})`;
|
|
151
|
+
})
|
|
152
|
+
.join('\n');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Format file size for display
|
|
157
|
+
*/
|
|
158
|
+
private formatFileSize(size: number): string {
|
|
159
|
+
return size >= 1024 * 1024
|
|
160
|
+
? `${(size / (1024 * 1024)).toFixed(1)}MB`
|
|
161
|
+
: `${(size / 1024).toFixed(1)}KB`;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -165,8 +165,26 @@ export class ContentStoreManager {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
try {
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
if (
|
|
169
|
+
ContentStoreService &&
|
|
170
|
+
typeof (ContentStoreService as unknown as { setInstance?: Function }).setInstance === 'function'
|
|
171
|
+
) {
|
|
172
|
+
await (ContentStoreService as unknown as { setInstance: (adapter: unknown) => Promise<void> }).setInstance(
|
|
173
|
+
this.adapter
|
|
174
|
+
);
|
|
175
|
+
} else {
|
|
176
|
+
this.logger.warn('ContentStoreService.setInstance is unavailable; skipping registration');
|
|
177
|
+
}
|
|
178
|
+
if (
|
|
179
|
+
ContentResolverRegistry &&
|
|
180
|
+
typeof (ContentResolverRegistry as unknown as { register?: Function }).register === 'function'
|
|
181
|
+
) {
|
|
182
|
+
(ContentResolverRegistry as unknown as { register: (resolver: unknown) => void }).register(
|
|
183
|
+
this.resolver
|
|
184
|
+
);
|
|
185
|
+
} else {
|
|
186
|
+
this.logger.warn('ContentResolverRegistry.register is unavailable; skipping registration');
|
|
187
|
+
}
|
|
170
188
|
this.isRegistered = true;
|
|
171
189
|
this.logger.info(
|
|
172
190
|
'ContentStoreManager initialized and registered for cross-package access'
|
|
@@ -236,8 +254,18 @@ export class ContentStoreManager {
|
|
|
236
254
|
async dispose(): Promise<void> {
|
|
237
255
|
if (this.isRegistered) {
|
|
238
256
|
this.contentStorage.dispose();
|
|
239
|
-
|
|
240
|
-
|
|
257
|
+
if (
|
|
258
|
+
ContentStoreService &&
|
|
259
|
+
typeof (ContentStoreService as unknown as { dispose?: Function }).dispose === 'function'
|
|
260
|
+
) {
|
|
261
|
+
(ContentStoreService as unknown as { dispose: () => void }).dispose();
|
|
262
|
+
}
|
|
263
|
+
if (
|
|
264
|
+
ContentResolverRegistry &&
|
|
265
|
+
typeof (ContentResolverRegistry as unknown as { unregister?: Function }).unregister === 'function'
|
|
266
|
+
) {
|
|
267
|
+
(ContentResolverRegistry as unknown as { unregister: () => void }).unregister();
|
|
268
|
+
}
|
|
241
269
|
this.isRegistered = false;
|
|
242
270
|
this.logger.info('ContentStoreManager disposed and unregistered');
|
|
243
271
|
}
|