@framers/agentos 0.1.6 → 0.1.8
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 +19 -0
- package/dist/api/AgentOS.d.ts +12 -0
- package/dist/api/AgentOS.d.ts.map +1 -1
- package/dist/api/AgentOS.js +100 -2
- package/dist/api/AgentOS.js.map +1 -1
- package/dist/api/AgentOSOrchestrator.d.ts +45 -0
- package/dist/api/AgentOSOrchestrator.d.ts.map +1 -1
- package/dist/api/AgentOSOrchestrator.js +470 -6
- package/dist/api/AgentOSOrchestrator.js.map +1 -1
- package/dist/api/types/AgentOSInput.d.ts +8 -0
- package/dist/api/types/AgentOSInput.d.ts.map +1 -1
- package/dist/api/types/AgentOSResponse.d.ts +22 -2
- package/dist/api/types/AgentOSResponse.d.ts.map +1 -1
- package/dist/api/types/AgentOSResponse.js +1 -0
- package/dist/api/types/AgentOSResponse.js.map +1 -1
- package/dist/channels/ChannelRouter.d.ts +150 -0
- package/dist/channels/ChannelRouter.d.ts.map +1 -0
- package/dist/channels/ChannelRouter.js +309 -0
- package/dist/channels/ChannelRouter.js.map +1 -0
- package/dist/channels/IChannelAdapter.d.ts +113 -0
- package/dist/channels/IChannelAdapter.d.ts.map +1 -0
- package/dist/channels/IChannelAdapter.js +17 -0
- package/dist/channels/IChannelAdapter.js.map +1 -0
- package/dist/channels/index.d.ts +9 -0
- package/dist/channels/index.d.ts.map +1 -0
- package/dist/channels/index.js +7 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/types.d.ts +257 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +12 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/cognitive_substrate/GMI.d.ts +139 -0
- package/dist/cognitive_substrate/GMI.d.ts.map +1 -1
- package/dist/cognitive_substrate/GMI.js +680 -14
- package/dist/cognitive_substrate/GMI.js.map +1 -1
- package/dist/cognitive_substrate/GMIEvent.d.ts +151 -0
- package/dist/cognitive_substrate/GMIEvent.d.ts.map +1 -0
- package/dist/cognitive_substrate/GMIEvent.js +79 -0
- package/dist/cognitive_substrate/GMIEvent.js.map +1 -0
- package/dist/cognitive_substrate/IGMI.d.ts +22 -0
- package/dist/cognitive_substrate/IGMI.d.ts.map +1 -1
- package/dist/cognitive_substrate/IGMI.js.map +1 -1
- package/dist/cognitive_substrate/personas/IPersonaDefinition.d.ts +92 -0
- package/dist/cognitive_substrate/personas/IPersonaDefinition.d.ts.map +1 -1
- package/dist/cognitive_substrate/personas/PersonaLoader.d.ts.map +1 -1
- package/dist/cognitive_substrate/personas/PersonaLoader.js +21 -0
- package/dist/cognitive_substrate/personas/PersonaLoader.js.map +1 -1
- package/dist/cognitive_substrate/personas/metaprompt_presets.d.ts +86 -0
- package/dist/cognitive_substrate/personas/metaprompt_presets.d.ts.map +1 -0
- package/dist/cognitive_substrate/personas/metaprompt_presets.js +457 -0
- package/dist/cognitive_substrate/personas/metaprompt_presets.js.map +1 -0
- package/dist/config/RetrievalAugmentorConfiguration.d.ts +21 -0
- package/dist/config/RetrievalAugmentorConfiguration.d.ts.map +1 -1
- package/dist/config/RetrievalAugmentorConfiguration.js.map +1 -1
- package/dist/config/VectorStoreConfiguration.d.ts +2 -1
- package/dist/config/VectorStoreConfiguration.d.ts.map +1 -1
- package/dist/config/VectorStoreConfiguration.js.map +1 -1
- package/dist/config/extension-secrets.json +360 -0
- package/dist/core/agents/AgentCore.d.ts +8 -0
- package/dist/core/agents/AgentCore.d.ts.map +1 -1
- package/dist/core/agents/AgentCore.js.map +1 -1
- package/dist/core/conversation/ConversationManager.d.ts.map +1 -1
- package/dist/core/conversation/ConversationManager.js +2 -4
- package/dist/core/conversation/ConversationManager.js.map +1 -1
- package/dist/core/conversation/ILongTermMemoryRetriever.d.ts +30 -0
- package/dist/core/conversation/ILongTermMemoryRetriever.d.ts.map +1 -0
- package/dist/core/conversation/ILongTermMemoryRetriever.js +2 -0
- package/dist/core/conversation/ILongTermMemoryRetriever.js.map +1 -0
- package/dist/core/conversation/IRollingSummaryMemorySink.d.ts +44 -0
- package/dist/core/conversation/IRollingSummaryMemorySink.d.ts.map +1 -0
- package/dist/core/conversation/IRollingSummaryMemorySink.js +9 -0
- package/dist/core/conversation/IRollingSummaryMemorySink.js.map +1 -0
- package/dist/core/conversation/LongTermMemoryPolicy.d.ts +53 -0
- package/dist/core/conversation/LongTermMemoryPolicy.d.ts.map +1 -0
- package/dist/core/conversation/LongTermMemoryPolicy.js +84 -0
- package/dist/core/conversation/LongTermMemoryPolicy.js.map +1 -0
- package/dist/core/conversation/RollingSummaryCompactor.d.ts +61 -0
- package/dist/core/conversation/RollingSummaryCompactor.d.ts.map +1 -0
- package/dist/core/conversation/RollingSummaryCompactor.js +255 -0
- package/dist/core/conversation/RollingSummaryCompactor.js.map +1 -0
- package/dist/core/llm/PromptEngine.d.ts.map +1 -1
- package/dist/core/llm/PromptEngine.js +10 -1
- package/dist/core/llm/PromptEngine.js.map +1 -1
- package/dist/core/orchestration/AgentOrchestrator.d.ts +40 -0
- package/dist/core/orchestration/AgentOrchestrator.d.ts.map +1 -1
- package/dist/core/orchestration/AgentOrchestrator.js +324 -2
- package/dist/core/orchestration/AgentOrchestrator.js.map +1 -1
- package/dist/core/prompting/PromptProfileRouter.d.ts +74 -0
- package/dist/core/prompting/PromptProfileRouter.d.ts.map +1 -0
- package/dist/core/prompting/PromptProfileRouter.js +270 -0
- package/dist/core/prompting/PromptProfileRouter.js.map +1 -0
- package/dist/core/provenance/anchoring/AnchorManager.d.ts +86 -0
- package/dist/core/provenance/anchoring/AnchorManager.d.ts.map +1 -0
- package/dist/core/provenance/anchoring/AnchorManager.js +244 -0
- package/dist/core/provenance/anchoring/AnchorManager.js.map +1 -0
- package/dist/core/provenance/anchoring/providers/CompositeAnchorProvider.d.ts +20 -0
- package/dist/core/provenance/anchoring/providers/CompositeAnchorProvider.d.ts.map +1 -0
- package/dist/core/provenance/anchoring/providers/CompositeAnchorProvider.js +62 -0
- package/dist/core/provenance/anchoring/providers/CompositeAnchorProvider.js.map +1 -0
- package/dist/core/provenance/anchoring/providers/NoneProvider.d.ts +15 -0
- package/dist/core/provenance/anchoring/providers/NoneProvider.d.ts.map +1 -0
- package/dist/core/provenance/anchoring/providers/NoneProvider.js +21 -0
- package/dist/core/provenance/anchoring/providers/NoneProvider.js.map +1 -0
- package/dist/core/provenance/anchoring/providers/createAnchorProvider.d.ts +38 -0
- package/dist/core/provenance/anchoring/providers/createAnchorProvider.d.ts.map +1 -0
- package/dist/core/provenance/anchoring/providers/createAnchorProvider.js +67 -0
- package/dist/core/provenance/anchoring/providers/createAnchorProvider.js.map +1 -0
- package/dist/core/provenance/anchoring/providers/index.d.ts +12 -0
- package/dist/core/provenance/anchoring/providers/index.d.ts.map +1 -0
- package/dist/core/provenance/anchoring/providers/index.js +12 -0
- package/dist/core/provenance/anchoring/providers/index.js.map +1 -0
- package/dist/core/provenance/config/PolicyProfiles.d.ts +60 -0
- package/dist/core/provenance/config/PolicyProfiles.d.ts.map +1 -0
- package/dist/core/provenance/config/PolicyProfiles.js +144 -0
- package/dist/core/provenance/config/PolicyProfiles.js.map +1 -0
- package/dist/core/provenance/crypto/AgentKeyManager.d.ts +48 -0
- package/dist/core/provenance/crypto/AgentKeyManager.d.ts.map +1 -0
- package/dist/core/provenance/crypto/AgentKeyManager.js +162 -0
- package/dist/core/provenance/crypto/AgentKeyManager.js.map +1 -0
- package/dist/core/provenance/crypto/HashChain.d.ts +58 -0
- package/dist/core/provenance/crypto/HashChain.d.ts.map +1 -0
- package/dist/core/provenance/crypto/HashChain.js +86 -0
- package/dist/core/provenance/crypto/HashChain.js.map +1 -0
- package/dist/core/provenance/crypto/MerkleTree.d.ts +41 -0
- package/dist/core/provenance/crypto/MerkleTree.d.ts.map +1 -0
- package/dist/core/provenance/crypto/MerkleTree.js +86 -0
- package/dist/core/provenance/crypto/MerkleTree.js.map +1 -0
- package/dist/core/provenance/enforcement/AutonomyGuard.d.ts +37 -0
- package/dist/core/provenance/enforcement/AutonomyGuard.d.ts.map +1 -0
- package/dist/core/provenance/enforcement/AutonomyGuard.js +120 -0
- package/dist/core/provenance/enforcement/AutonomyGuard.js.map +1 -0
- package/dist/core/provenance/enforcement/ProvenanceStorageHooks.d.ts +43 -0
- package/dist/core/provenance/enforcement/ProvenanceStorageHooks.d.ts.map +1 -0
- package/dist/core/provenance/enforcement/ProvenanceStorageHooks.js +193 -0
- package/dist/core/provenance/enforcement/ProvenanceStorageHooks.js.map +1 -0
- package/dist/core/provenance/enforcement/RevisionManager.d.ts +41 -0
- package/dist/core/provenance/enforcement/RevisionManager.d.ts.map +1 -0
- package/dist/core/provenance/enforcement/RevisionManager.js +105 -0
- package/dist/core/provenance/enforcement/RevisionManager.js.map +1 -0
- package/dist/core/provenance/enforcement/TombstoneManager.d.ts +47 -0
- package/dist/core/provenance/enforcement/TombstoneManager.d.ts.map +1 -0
- package/dist/core/provenance/enforcement/TombstoneManager.js +121 -0
- package/dist/core/provenance/enforcement/TombstoneManager.js.map +1 -0
- package/dist/core/provenance/index.d.ts +34 -0
- package/dist/core/provenance/index.d.ts.map +1 -0
- package/dist/core/provenance/index.js +39 -0
- package/dist/core/provenance/index.js.map +1 -0
- package/dist/core/provenance/ledger/EventTypes.d.ts +123 -0
- package/dist/core/provenance/ledger/EventTypes.d.ts.map +1 -0
- package/dist/core/provenance/ledger/EventTypes.js +9 -0
- package/dist/core/provenance/ledger/EventTypes.js.map +1 -0
- package/dist/core/provenance/ledger/SignedEventLedger.d.ts +75 -0
- package/dist/core/provenance/ledger/SignedEventLedger.d.ts.map +1 -0
- package/dist/core/provenance/ledger/SignedEventLedger.js +210 -0
- package/dist/core/provenance/ledger/SignedEventLedger.js.map +1 -0
- package/dist/core/provenance/schema/provenance-schema.d.ts +17 -0
- package/dist/core/provenance/schema/provenance-schema.d.ts.map +1 -0
- package/dist/core/provenance/schema/provenance-schema.js +104 -0
- package/dist/core/provenance/schema/provenance-schema.js.map +1 -0
- package/dist/core/provenance/types.d.ts +261 -0
- package/dist/core/provenance/types.d.ts.map +1 -0
- package/dist/core/provenance/types.js +21 -0
- package/dist/core/provenance/types.js.map +1 -0
- package/dist/core/provenance/verification/BundleExporter.d.ts +50 -0
- package/dist/core/provenance/verification/BundleExporter.d.ts.map +1 -0
- package/dist/core/provenance/verification/BundleExporter.js +240 -0
- package/dist/core/provenance/verification/BundleExporter.js.map +1 -0
- package/dist/core/provenance/verification/ChainVerifier.d.ts +39 -0
- package/dist/core/provenance/verification/ChainVerifier.d.ts.map +1 -0
- package/dist/core/provenance/verification/ChainVerifier.js +204 -0
- package/dist/core/provenance/verification/ChainVerifier.js.map +1 -0
- package/dist/core/provenance/verification/ConversationVerifier.d.ts +56 -0
- package/dist/core/provenance/verification/ConversationVerifier.d.ts.map +1 -0
- package/dist/core/provenance/verification/ConversationVerifier.js +109 -0
- package/dist/core/provenance/verification/ConversationVerifier.js.map +1 -0
- package/dist/extensions/ExtensionManager.d.ts +8 -0
- package/dist/extensions/ExtensionManager.d.ts.map +1 -1
- package/dist/extensions/ExtensionManager.js +58 -3
- package/dist/extensions/ExtensionManager.js.map +1 -1
- package/dist/extensions/MessagingChannelPayload.d.ts +39 -0
- package/dist/extensions/MessagingChannelPayload.d.ts.map +1 -0
- package/dist/extensions/MessagingChannelPayload.js +12 -0
- package/dist/extensions/MessagingChannelPayload.js.map +1 -0
- package/dist/extensions/manifest.d.ts +3 -1
- package/dist/extensions/manifest.d.ts.map +1 -1
- package/dist/extensions/packs/provenance-pack.d.ts +66 -0
- package/dist/extensions/packs/provenance-pack.d.ts.map +1 -0
- package/dist/extensions/packs/provenance-pack.js +162 -0
- package/dist/extensions/packs/provenance-pack.js.map +1 -0
- package/dist/extensions/types.d.ts +23 -0
- package/dist/extensions/types.d.ts.map +1 -1
- package/dist/extensions/types.js +4 -0
- package/dist/extensions/types.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/rag/IRetrievalAugmentor.d.ts +22 -1
- package/dist/rag/IRetrievalAugmentor.d.ts.map +1 -1
- package/dist/rag/RetrievalAugmentor.d.ts +37 -0
- package/dist/rag/RetrievalAugmentor.d.ts.map +1 -1
- package/dist/rag/RetrievalAugmentor.js +82 -6
- package/dist/rag/RetrievalAugmentor.js.map +1 -1
- package/dist/rag/VectorStoreManager.d.ts.map +1 -1
- package/dist/rag/VectorStoreManager.js +5 -0
- package/dist/rag/VectorStoreManager.js.map +1 -1
- package/dist/rag/graphrag/GraphRAGEngine.d.ts +100 -0
- package/dist/rag/graphrag/GraphRAGEngine.d.ts.map +1 -0
- package/dist/rag/graphrag/GraphRAGEngine.js +1146 -0
- package/dist/rag/graphrag/GraphRAGEngine.js.map +1 -0
- package/dist/rag/graphrag/IGraphRAG.d.ts +198 -0
- package/dist/rag/graphrag/IGraphRAG.d.ts.map +1 -0
- package/dist/rag/graphrag/IGraphRAG.js +11 -0
- package/dist/rag/graphrag/IGraphRAG.js.map +1 -0
- package/dist/rag/graphrag/index.d.ts +12 -0
- package/dist/rag/graphrag/index.d.ts.map +1 -0
- package/dist/rag/graphrag/index.js +11 -0
- package/dist/rag/graphrag/index.js.map +1 -0
- package/dist/rag/implementations/vector_stores/HnswlibVectorStore.d.ts +72 -0
- package/dist/rag/implementations/vector_stores/HnswlibVectorStore.d.ts.map +1 -0
- package/dist/rag/implementations/vector_stores/HnswlibVectorStore.js +463 -0
- package/dist/rag/implementations/vector_stores/HnswlibVectorStore.js.map +1 -0
- package/dist/rag/implementations/vector_stores/index.d.ts +1 -0
- package/dist/rag/implementations/vector_stores/index.d.ts.map +1 -1
- package/dist/rag/implementations/vector_stores/index.js +2 -0
- package/dist/rag/implementations/vector_stores/index.js.map +1 -1
- package/dist/rag/index.d.ts +3 -0
- package/dist/rag/index.d.ts.map +1 -1
- package/dist/rag/index.js +5 -0
- package/dist/rag/index.js.map +1 -1
- package/dist/rag/reranking/IRerankerService.d.ts +163 -0
- package/dist/rag/reranking/IRerankerService.d.ts.map +1 -0
- package/dist/rag/reranking/IRerankerService.js +9 -0
- package/dist/rag/reranking/IRerankerService.js.map +1 -0
- package/dist/rag/reranking/RerankerService.d.ts +107 -0
- package/dist/rag/reranking/RerankerService.d.ts.map +1 -0
- package/dist/rag/reranking/RerankerService.js +194 -0
- package/dist/rag/reranking/RerankerService.js.map +1 -0
- package/dist/rag/reranking/index.d.ts +55 -0
- package/dist/rag/reranking/index.d.ts.map +1 -0
- package/dist/rag/reranking/index.js +56 -0
- package/dist/rag/reranking/index.js.map +1 -0
- package/dist/rag/reranking/providers/CohereReranker.d.ts +66 -0
- package/dist/rag/reranking/providers/CohereReranker.d.ts.map +1 -0
- package/dist/rag/reranking/providers/CohereReranker.js +141 -0
- package/dist/rag/reranking/providers/CohereReranker.js.map +1 -0
- package/dist/rag/reranking/providers/LocalCrossEncoderReranker.d.ts +105 -0
- package/dist/rag/reranking/providers/LocalCrossEncoderReranker.d.ts.map +1 -0
- package/dist/rag/reranking/providers/LocalCrossEncoderReranker.js +214 -0
- package/dist/rag/reranking/providers/LocalCrossEncoderReranker.js.map +1 -0
- package/dist/rag/reranking/providers/index.d.ts +7 -0
- package/dist/rag/reranking/providers/index.d.ts.map +1 -0
- package/dist/rag/reranking/providers/index.js +7 -0
- package/dist/rag/reranking/providers/index.js.map +1 -0
- package/dist/rag/reranking/tests/index.d.ts +6 -0
- package/dist/rag/reranking/tests/index.d.ts.map +1 -0
- package/dist/rag/reranking/tests/index.js +11 -0
- package/dist/rag/reranking/tests/index.js.map +1 -0
- package/dist/types/optionalDependencies.d.ts +5 -0
- package/dist/types/optionalDependencies.d.ts.map +1 -0
- package/dist/types/optionalDependencies.js +4 -0
- package/dist/types/optionalDependencies.js.map +1 -0
- package/dist/voice/CallManager.d.ts +116 -0
- package/dist/voice/CallManager.d.ts.map +1 -0
- package/dist/voice/CallManager.js +426 -0
- package/dist/voice/CallManager.js.map +1 -0
- package/dist/voice/IVoiceCallProvider.d.ts +137 -0
- package/dist/voice/IVoiceCallProvider.d.ts.map +1 -0
- package/dist/voice/IVoiceCallProvider.js +11 -0
- package/dist/voice/IVoiceCallProvider.js.map +1 -0
- package/dist/voice/index.d.ts +10 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +8 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/providers/mock.d.ts +74 -0
- package/dist/voice/providers/mock.d.ts.map +1 -0
- package/dist/voice/providers/mock.js +199 -0
- package/dist/voice/providers/mock.js.map +1 -0
- package/dist/voice/telephony-audio.d.ts +42 -0
- package/dist/voice/telephony-audio.d.ts.map +1 -0
- package/dist/voice/telephony-audio.js +150 -0
- package/dist/voice/telephony-audio.js.map +1 -0
- package/dist/voice/types.d.ts +260 -0
- package/dist/voice/types.d.ts.map +1 -0
- package/dist/voice/types.js +36 -0
- package/dist/voice/types.js.map +1 -0
- package/package.json +22 -6
|
@@ -18,6 +18,7 @@ import { GMIOutputChunkType, GMIPrimeState, GMIMood, ReasoningEntryType, GMIInte
|
|
|
18
18
|
import { RagMemoryCategory } from '../rag/IRetrievalAugmentor.js';
|
|
19
19
|
import { createConversationMessage, MessageRole } from '../core/conversation/ConversationMessage.js';
|
|
20
20
|
import { GMIError, GMIErrorCode, createGMIErrorFromError } from '../utils/errors.js';
|
|
21
|
+
import { GMIEventType, createGMIEvent } from './GMIEvent.js';
|
|
21
22
|
const DEFAULT_MAX_CONVERSATION_HISTORY_TURNS = 20;
|
|
22
23
|
const DEFAULT_SELF_REFLECTION_INTERVAL_TURNS = 5;
|
|
23
24
|
const MAX_REASONING_TRACE_ENTRIES = 500; // Limit trace size in memory
|
|
@@ -35,6 +36,10 @@ export class GMI {
|
|
|
35
36
|
*/
|
|
36
37
|
constructor(gmiId) {
|
|
37
38
|
this.isInitialized = false; // Maintained as per user-provided GMI.ts
|
|
39
|
+
// Sentiment & Event Tracking
|
|
40
|
+
this.pendingGMIEvents = new Set();
|
|
41
|
+
this.eventHistory = []; // Last 20 events for debugging
|
|
42
|
+
this.metaPromptTriggerCounters = new Map();
|
|
38
43
|
this.gmiId = gmiId || `gmi-${uuidv4()}`;
|
|
39
44
|
this.creationTimestamp = new Date();
|
|
40
45
|
this.state = GMIPrimeState.IDLE;
|
|
@@ -401,10 +406,25 @@ export class GMI {
|
|
|
401
406
|
await this.workingMemory.set('currentUserContext', this.currentUserContext);
|
|
402
407
|
}
|
|
403
408
|
this.updateConversationHistory(turnInput);
|
|
409
|
+
// Analyze sentiment of user input only when sentiment tracking is enabled
|
|
410
|
+
if (this.activePersona.sentimentTracking?.enabled) {
|
|
411
|
+
const lastMsg = this.conversationHistory.length > 0
|
|
412
|
+
? this.conversationHistory[this.conversationHistory.length - 1]
|
|
413
|
+
: null;
|
|
414
|
+
if (lastMsg?.role === 'user' && lastMsg?.content) {
|
|
415
|
+
const userInputText = typeof lastMsg.content === 'string'
|
|
416
|
+
? lastMsg.content
|
|
417
|
+
: JSON.stringify(lastMsg.content);
|
|
418
|
+
await this.analyzeTurnSentiment(turnId, userInputText);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
404
421
|
let safetyBreak = 0;
|
|
405
422
|
main_processing_loop: while (safetyBreak < 5) {
|
|
406
423
|
safetyBreak++;
|
|
407
424
|
let augmentedContextFromRAG = "";
|
|
425
|
+
const injectedLongTermMemoryContext = typeof turnInput.metadata?.longTermMemoryContext === 'string'
|
|
426
|
+
? turnInput.metadata.longTermMemoryContext.trim()
|
|
427
|
+
: "";
|
|
408
428
|
const lastMessage = this.conversationHistory.length > 0 ? this.conversationHistory[this.conversationHistory.length - 1] : null;
|
|
409
429
|
const isUserInitiatedTurn = lastMessage?.role === 'user';
|
|
410
430
|
if (this.retrievalAugmentor && this.activePersona.memoryConfig?.ragConfig?.enabled && isUserInitiatedTurn && lastMessage?.content) {
|
|
@@ -429,11 +449,33 @@ export class GMI {
|
|
|
429
449
|
: typeof this.activePersona.baseSystemPrompt === 'string'
|
|
430
450
|
? [{ content: this.activePersona.baseSystemPrompt, priority: 1 }]
|
|
431
451
|
: [];
|
|
452
|
+
const systemPrompts = [...baseSystemPrompts];
|
|
453
|
+
const rollingSummaryText = typeof turnInput.metadata?.rollingSummary?.text === 'string'
|
|
454
|
+
? turnInput.metadata.rollingSummary.text.trim()
|
|
455
|
+
: '';
|
|
456
|
+
if (rollingSummaryText) {
|
|
457
|
+
systemPrompts.push({
|
|
458
|
+
content: `Rolling Memory Summary (compressed)\n${rollingSummaryText}`,
|
|
459
|
+
priority: 50,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
const promptProfileInstructions = typeof turnInput.metadata?.promptProfile?.systemInstructions === 'string'
|
|
463
|
+
? turnInput.metadata.promptProfile.systemInstructions.trim()
|
|
464
|
+
: '';
|
|
465
|
+
if (promptProfileInstructions) {
|
|
466
|
+
systemPrompts.push({
|
|
467
|
+
content: promptProfileInstructions,
|
|
468
|
+
priority: 60,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
const durableHistoryForPrompt = Array.isArray(turnInput.metadata?.conversationHistoryForPrompt) && turnInput.metadata?.conversationHistoryForPrompt.length > 0
|
|
472
|
+
? turnInput.metadata?.conversationHistoryForPrompt
|
|
473
|
+
: null;
|
|
432
474
|
const promptComponents = {
|
|
433
|
-
systemPrompts
|
|
434
|
-
conversationHistory: this.buildConversationHistoryForPrompt(),
|
|
475
|
+
systemPrompts,
|
|
476
|
+
conversationHistory: durableHistoryForPrompt ?? this.buildConversationHistoryForPrompt(),
|
|
435
477
|
userInput: isUserInitiatedTurn && typeof lastMessage?.content === 'string' ? lastMessage.content : null,
|
|
436
|
-
retrievedContext: augmentedContextFromRAG,
|
|
478
|
+
retrievedContext: [augmentedContextFromRAG, injectedLongTermMemoryContext].filter(Boolean).join("\n\n---\n\n"),
|
|
437
479
|
// tools: this.activePersona.embeddedTools, // If ITool[] and PromptComponents.tools takes ITool[]
|
|
438
480
|
};
|
|
439
481
|
const preferredModelIdFromInput = turnInput.metadata?.options?.preferredModelId;
|
|
@@ -552,17 +594,8 @@ export class GMI {
|
|
|
552
594
|
break main_processing_loop; // Break if no tool calls
|
|
553
595
|
}
|
|
554
596
|
await this.performPostTurnIngestion(typeof turnInput.content === 'string' ? turnInput.content : JSON.stringify(turnInput.content), aggregatedResponseText);
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
if (reflectionMetaPrompt?.trigger?.type === 'turn_interval' &&
|
|
558
|
-
this.turnsSinceLastReflection >= (reflectionMetaPrompt.trigger.intervalTurns || this.selfReflectionIntervalTurns)) {
|
|
559
|
-
this.addTraceEntry(ReasoningEntryType.SELF_REFLECTION_TRIGGERED, `Interval reached.`);
|
|
560
|
-
this._triggerAndProcessSelfReflection().catch(err => {
|
|
561
|
-
console.error(`GMI (ID: ${this.gmiId}): Background self-reflection error:`, err);
|
|
562
|
-
this.addTraceEntry(ReasoningEntryType.ERROR, "Self-reflection background process failed.", { error: err.message });
|
|
563
|
-
});
|
|
564
|
-
this.turnsSinceLastReflection = 0;
|
|
565
|
-
}
|
|
597
|
+
// Check and trigger all metaprompts (turn_interval, event_based, manual)
|
|
598
|
+
await this.checkAndTriggerMetaprompts(turnId);
|
|
566
599
|
// Prepare the final GMIOutput for the generator's return value
|
|
567
600
|
const finalTurnOutput = {
|
|
568
601
|
isFinal: true,
|
|
@@ -735,6 +768,639 @@ export class GMI {
|
|
|
735
768
|
console.error(`GMI (ID: ${this.gmiId}): RAG Ingestion Error - ${gmiError.message}`, gmiError.details);
|
|
736
769
|
}
|
|
737
770
|
}
|
|
771
|
+
/**
|
|
772
|
+
* Analyzes sentiment of user input and updates sentiment history.
|
|
773
|
+
* Triggers event detection based on sentiment patterns.
|
|
774
|
+
*
|
|
775
|
+
* @param turnId - Current turn identifier
|
|
776
|
+
* @param userInput - User's input text
|
|
777
|
+
* @private
|
|
778
|
+
*/
|
|
779
|
+
async analyzeTurnSentiment(turnId, userInput) {
|
|
780
|
+
// Skip if input is not a string or is empty
|
|
781
|
+
if (!userInput || typeof userInput !== 'string') {
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
try {
|
|
785
|
+
// Analyze sentiment using configurable method from sentimentTracking config
|
|
786
|
+
const stConfig = this.activePersona.sentimentTracking;
|
|
787
|
+
const sentimentResult = await this.utilityAI.analyzeSentiment(userInput, {
|
|
788
|
+
method: stConfig?.method || 'lexicon_based',
|
|
789
|
+
modelId: stConfig?.modelId || this.activePersona.defaultModelId,
|
|
790
|
+
providerId: stConfig?.providerId || this.activePersona.defaultProviderId,
|
|
791
|
+
language: this.currentUserContext.language || 'en',
|
|
792
|
+
});
|
|
793
|
+
// Update UserContext with current sentiment
|
|
794
|
+
this.currentUserContext.currentSentiment = sentimentResult.polarity;
|
|
795
|
+
await this.workingMemory.set('currentUserContext', this.currentUserContext);
|
|
796
|
+
// Get or initialize sentiment history
|
|
797
|
+
let sentimentHistory = await this.workingMemory.get('gmi_sentiment_history');
|
|
798
|
+
if (!sentimentHistory) {
|
|
799
|
+
sentimentHistory = {
|
|
800
|
+
trends: [],
|
|
801
|
+
consecutiveFrustration: 0,
|
|
802
|
+
consecutiveConfusion: 0,
|
|
803
|
+
consecutiveSatisfaction: 0,
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
// Add to sentiment trends
|
|
807
|
+
const trend = {
|
|
808
|
+
turnId,
|
|
809
|
+
timestamp: new Date(),
|
|
810
|
+
score: sentimentResult.score,
|
|
811
|
+
polarity: sentimentResult.polarity,
|
|
812
|
+
intensity: sentimentResult.intensity || 0,
|
|
813
|
+
context: userInput.substring(0, 100), // First 100 chars
|
|
814
|
+
};
|
|
815
|
+
sentimentHistory.trends.push(trend);
|
|
816
|
+
// Keep only last N trends (configurable sliding window)
|
|
817
|
+
const historyWindow = stConfig?.historyWindow || 10;
|
|
818
|
+
if (sentimentHistory.trends.length > historyWindow) {
|
|
819
|
+
sentimentHistory.trends.shift();
|
|
820
|
+
}
|
|
821
|
+
// Update consecutive counters based on configurable thresholds
|
|
822
|
+
const frustrationThreshold = stConfig?.frustrationThreshold ?? -0.3;
|
|
823
|
+
const satisfactionThreshold = stConfig?.satisfactionThreshold ?? 0.3;
|
|
824
|
+
if (sentimentResult.score < frustrationThreshold) {
|
|
825
|
+
// Negative sentiment
|
|
826
|
+
sentimentHistory.consecutiveFrustration++;
|
|
827
|
+
sentimentHistory.consecutiveConfusion = 0;
|
|
828
|
+
sentimentHistory.consecutiveSatisfaction = 0;
|
|
829
|
+
}
|
|
830
|
+
else if (sentimentResult.score > satisfactionThreshold) {
|
|
831
|
+
// Positive sentiment
|
|
832
|
+
sentimentHistory.consecutiveSatisfaction++;
|
|
833
|
+
sentimentHistory.consecutiveFrustration = 0;
|
|
834
|
+
sentimentHistory.consecutiveConfusion = 0;
|
|
835
|
+
}
|
|
836
|
+
else {
|
|
837
|
+
// Neutral sentiment (or close to it)
|
|
838
|
+
sentimentHistory.consecutiveConfusion++;
|
|
839
|
+
sentimentHistory.consecutiveFrustration = 0;
|
|
840
|
+
sentimentHistory.consecutiveSatisfaction = 0;
|
|
841
|
+
}
|
|
842
|
+
sentimentHistory.lastAnalyzedTurnId = turnId;
|
|
843
|
+
// Store updated sentiment history
|
|
844
|
+
await this.workingMemory.set('gmi_sentiment_history', sentimentHistory);
|
|
845
|
+
this.addTraceEntry(ReasoningEntryType.DEBUG, 'Turn sentiment analyzed', {
|
|
846
|
+
sentiment: {
|
|
847
|
+
score: sentimentResult.score,
|
|
848
|
+
polarity: sentimentResult.polarity,
|
|
849
|
+
intensity: sentimentResult.intensity,
|
|
850
|
+
},
|
|
851
|
+
consecutiveCounters: {
|
|
852
|
+
frustration: sentimentHistory.consecutiveFrustration,
|
|
853
|
+
confusion: sentimentHistory.consecutiveConfusion,
|
|
854
|
+
satisfaction: sentimentHistory.consecutiveSatisfaction,
|
|
855
|
+
},
|
|
856
|
+
});
|
|
857
|
+
// Detect and emit events based on sentiment patterns
|
|
858
|
+
await this.detectAndEmitEvents(turnId, userInput, sentimentResult, sentimentHistory);
|
|
859
|
+
}
|
|
860
|
+
catch (error) {
|
|
861
|
+
// Don't fail the turn if sentiment analysis fails - log and continue
|
|
862
|
+
console.error(`GMI (ID: ${this.gmiId}): Sentiment analysis error:`, error);
|
|
863
|
+
this.addTraceEntry(ReasoningEntryType.WARNING, 'Sentiment analysis failed', { error: error.message });
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Detects emotional patterns and emits appropriate GMI events.
|
|
868
|
+
*
|
|
869
|
+
* @param turnId - Current turn identifier
|
|
870
|
+
* @param userInput - User's input text
|
|
871
|
+
* @param sentimentResult - Sentiment analysis result
|
|
872
|
+
* @param sentimentHistory - Historical sentiment data
|
|
873
|
+
* @private
|
|
874
|
+
*/
|
|
875
|
+
async detectAndEmitEvents(turnId, userInput, sentimentResult, sentimentHistory) {
|
|
876
|
+
// Read configurable thresholds
|
|
877
|
+
const stConfig = this.activePersona.sentimentTracking;
|
|
878
|
+
const frustThreshold = stConfig?.frustrationThreshold ?? -0.3;
|
|
879
|
+
const satisThreshold = stConfig?.satisfactionThreshold ?? 0.3;
|
|
880
|
+
const consecutiveRequired = stConfig?.consecutiveTurnsForTrigger ?? 2;
|
|
881
|
+
// Frustration detection
|
|
882
|
+
if ((sentimentResult.score < frustThreshold && (sentimentResult.intensity || 0) > 0.6) ||
|
|
883
|
+
sentimentHistory.consecutiveFrustration >= consecutiveRequired) {
|
|
884
|
+
this.emitEvent(createGMIEvent(GMIEventType.USER_FRUSTRATED, turnId, sentimentHistory.consecutiveFrustration >= 2 ? 'high' : 'medium', {
|
|
885
|
+
sentimentScore: sentimentResult.score,
|
|
886
|
+
sentimentPolarity: sentimentResult.polarity,
|
|
887
|
+
sentimentIntensity: sentimentResult.intensity,
|
|
888
|
+
consecutiveTurns: sentimentHistory.consecutiveFrustration,
|
|
889
|
+
triggeredBy: 'sentiment',
|
|
890
|
+
}));
|
|
891
|
+
}
|
|
892
|
+
// Confusion detection (keyword-based + sentiment)
|
|
893
|
+
const confusionKeywords = [
|
|
894
|
+
'confused',
|
|
895
|
+
"don't understand",
|
|
896
|
+
"dont understand",
|
|
897
|
+
'unclear',
|
|
898
|
+
'what do you mean',
|
|
899
|
+
'explain',
|
|
900
|
+
'clarify',
|
|
901
|
+
'huh',
|
|
902
|
+
'??',
|
|
903
|
+
"doesn't make sense",
|
|
904
|
+
"doesnt make sense",
|
|
905
|
+
'not sure',
|
|
906
|
+
];
|
|
907
|
+
const lowerInput = userInput.toLowerCase();
|
|
908
|
+
const hasConfusionKeyword = confusionKeywords.some((keyword) => lowerInput.includes(keyword));
|
|
909
|
+
const triggerKeywords = hasConfusionKeyword
|
|
910
|
+
? confusionKeywords.filter((keyword) => lowerInput.includes(keyword))
|
|
911
|
+
: [];
|
|
912
|
+
if (hasConfusionKeyword ||
|
|
913
|
+
(sentimentResult.polarity === 'neutral' &&
|
|
914
|
+
sentimentResult.negativeTokens &&
|
|
915
|
+
sentimentResult.negativeTokens.length > 2)) {
|
|
916
|
+
this.emitEvent(createGMIEvent(GMIEventType.USER_CONFUSED, turnId, sentimentHistory.consecutiveConfusion >= 2 ? 'high' : 'medium', {
|
|
917
|
+
triggeredBy: hasConfusionKeyword ? 'keyword' : 'sentiment',
|
|
918
|
+
consecutiveTurns: sentimentHistory.consecutiveConfusion,
|
|
919
|
+
evidencePreview: userInput.substring(0, 100),
|
|
920
|
+
triggerKeywords: hasConfusionKeyword ? triggerKeywords : undefined,
|
|
921
|
+
}));
|
|
922
|
+
}
|
|
923
|
+
// Satisfaction detection
|
|
924
|
+
if ((sentimentResult.score > satisThreshold && (sentimentResult.intensity || 0) > 0.5) ||
|
|
925
|
+
sentimentHistory.consecutiveSatisfaction >= (consecutiveRequired + 1)) {
|
|
926
|
+
this.emitEvent(createGMIEvent(GMIEventType.USER_SATISFIED, turnId, 'low', {
|
|
927
|
+
sentimentScore: sentimentResult.score,
|
|
928
|
+
sentimentPolarity: sentimentResult.polarity,
|
|
929
|
+
sentimentIntensity: sentimentResult.intensity,
|
|
930
|
+
consecutiveTurns: sentimentHistory.consecutiveSatisfaction,
|
|
931
|
+
triggeredBy: 'sentiment',
|
|
932
|
+
}));
|
|
933
|
+
}
|
|
934
|
+
// Error threshold detection (check reasoning trace for recent errors)
|
|
935
|
+
const recentErrors = this.reasoningTrace.entries
|
|
936
|
+
.slice(-10)
|
|
937
|
+
.filter((entry) => entry.type === ReasoningEntryType.ERROR);
|
|
938
|
+
if (recentErrors.length >= 2) {
|
|
939
|
+
this.emitEvent(createGMIEvent(GMIEventType.ERROR_THRESHOLD_EXCEEDED, turnId, 'high', {
|
|
940
|
+
triggeredBy: 'error',
|
|
941
|
+
errorCount: recentErrors.length,
|
|
942
|
+
consecutiveTurns: recentErrors.length,
|
|
943
|
+
}));
|
|
944
|
+
}
|
|
945
|
+
// Low engagement detection (consecutive neutral with short responses)
|
|
946
|
+
const recentUserMessages = this.conversationHistory
|
|
947
|
+
.slice(-5)
|
|
948
|
+
.filter((msg) => msg.role === 'user');
|
|
949
|
+
const avgLength = recentUserMessages.length > 0
|
|
950
|
+
? recentUserMessages.reduce((sum, msg) => sum + String(msg.content).length, 0) / recentUserMessages.length
|
|
951
|
+
: 0;
|
|
952
|
+
if (sentimentHistory.consecutiveConfusion >= 4 && avgLength < 50) {
|
|
953
|
+
this.emitEvent(createGMIEvent(GMIEventType.LOW_ENGAGEMENT, turnId, 'medium', {
|
|
954
|
+
triggeredBy: 'pattern',
|
|
955
|
+
consecutiveTurns: sentimentHistory.consecutiveConfusion,
|
|
956
|
+
evidencePreview: `Avg response length: ${avgLength.toFixed(0)} chars`,
|
|
957
|
+
}));
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* Emits a GMI event and stores it in event history.
|
|
962
|
+
*
|
|
963
|
+
* @param event - The event to emit
|
|
964
|
+
* @private
|
|
965
|
+
*/
|
|
966
|
+
emitEvent(event) {
|
|
967
|
+
// Add to pending events (will be consumed by trigger checking)
|
|
968
|
+
this.pendingGMIEvents.add(event.eventType);
|
|
969
|
+
// Add to event history for debugging (circular buffer, max 20)
|
|
970
|
+
this.eventHistory.push(event);
|
|
971
|
+
if (this.eventHistory.length > 20) {
|
|
972
|
+
this.eventHistory.shift();
|
|
973
|
+
}
|
|
974
|
+
this.addTraceEntry(ReasoningEntryType.DEBUG, `GMI Event Emitted: ${event.eventType}`, {
|
|
975
|
+
event: {
|
|
976
|
+
eventType: event.eventType,
|
|
977
|
+
turnId: event.turnId,
|
|
978
|
+
severity: event.severity,
|
|
979
|
+
metadata: event.metadata,
|
|
980
|
+
},
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Checks all metaprompt triggers (turn_interval, event_based, manual) and executes triggered ones.
|
|
985
|
+
*
|
|
986
|
+
* @param turnId - Current turn identifier
|
|
987
|
+
* @private
|
|
988
|
+
*/
|
|
989
|
+
async checkAndTriggerMetaprompts(turnId) {
|
|
990
|
+
if (!this.activePersona.metaPrompts || this.activePersona.metaPrompts.length === 0) {
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
const triggeredMetaPrompts = [];
|
|
994
|
+
for (const metaPrompt of this.activePersona.metaPrompts) {
|
|
995
|
+
if (!metaPrompt.trigger)
|
|
996
|
+
continue;
|
|
997
|
+
if (metaPrompt.trigger.type === 'turn_interval') {
|
|
998
|
+
// Existing turn_interval logic
|
|
999
|
+
const counter = await this.getMetapromptTurnCounter(metaPrompt.id);
|
|
1000
|
+
if (counter >= metaPrompt.trigger.intervalTurns) {
|
|
1001
|
+
triggeredMetaPrompts.push(metaPrompt);
|
|
1002
|
+
await this.resetMetapromptTurnCounter(metaPrompt.id);
|
|
1003
|
+
}
|
|
1004
|
+
else {
|
|
1005
|
+
await this.incrementMetapromptTurnCounter(metaPrompt.id);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
else if (metaPrompt.trigger.type === 'event_based') {
|
|
1009
|
+
// NEW: Event-based trigger checking
|
|
1010
|
+
const eventName = metaPrompt.trigger.eventName;
|
|
1011
|
+
if (this.pendingGMIEvents.has(eventName)) {
|
|
1012
|
+
triggeredMetaPrompts.push(metaPrompt);
|
|
1013
|
+
// Consume the event (remove from pending)
|
|
1014
|
+
this.pendingGMIEvents.delete(eventName);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
else if (metaPrompt.trigger.type === 'manual') {
|
|
1018
|
+
// NEW: Manual trigger checking
|
|
1019
|
+
// Check for manual trigger flag in working memory
|
|
1020
|
+
const manualFlag = await this.workingMemory.get(`manual_trigger_${metaPrompt.id}`);
|
|
1021
|
+
if (manualFlag) {
|
|
1022
|
+
triggeredMetaPrompts.push(metaPrompt);
|
|
1023
|
+
// Clear the flag
|
|
1024
|
+
await this.workingMemory.delete(`manual_trigger_${metaPrompt.id}`);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
if (triggeredMetaPrompts.length > 0) {
|
|
1029
|
+
this.addTraceEntry(ReasoningEntryType.SELF_REFLECTION_TRIGGERED, `${triggeredMetaPrompts.length} metaprompt(s) triggered`, { ids: triggeredMetaPrompts.map((m) => m.id), turnId });
|
|
1030
|
+
// Execute metaprompts (background task, don't block turn)
|
|
1031
|
+
this.executeMetaprompts(triggeredMetaPrompts).catch((err) => {
|
|
1032
|
+
console.error(`GMI (ID: ${this.gmiId}): Metaprompt execution error:`, err);
|
|
1033
|
+
this.addTraceEntry(ReasoningEntryType.ERROR, 'Metaprompt execution failed', { error: err.message });
|
|
1034
|
+
});
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Gets the turn counter for a specific metaprompt.
|
|
1039
|
+
*
|
|
1040
|
+
* @param metapromptId - Metaprompt identifier
|
|
1041
|
+
* @returns Current counter value
|
|
1042
|
+
* @private
|
|
1043
|
+
*/
|
|
1044
|
+
async getMetapromptTurnCounter(metapromptId) {
|
|
1045
|
+
const counter = this.metaPromptTriggerCounters.get(metapromptId);
|
|
1046
|
+
if (counter !== undefined) {
|
|
1047
|
+
return counter;
|
|
1048
|
+
}
|
|
1049
|
+
// Try loading from working memory (for persistence across GMI instances)
|
|
1050
|
+
const storedCounter = await this.workingMemory.get(`metaprompt_turn_counter_${metapromptId}`);
|
|
1051
|
+
return storedCounter || 0;
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Increments the turn counter for a specific metaprompt.
|
|
1055
|
+
*
|
|
1056
|
+
* @param metapromptId - Metaprompt identifier
|
|
1057
|
+
* @private
|
|
1058
|
+
*/
|
|
1059
|
+
async incrementMetapromptTurnCounter(metapromptId) {
|
|
1060
|
+
const current = await this.getMetapromptTurnCounter(metapromptId);
|
|
1061
|
+
const newValue = current + 1;
|
|
1062
|
+
this.metaPromptTriggerCounters.set(metapromptId, newValue);
|
|
1063
|
+
await this.workingMemory.set(`metaprompt_turn_counter_${metapromptId}`, newValue);
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Resets the turn counter for a specific metaprompt to zero.
|
|
1067
|
+
*
|
|
1068
|
+
* @param metapromptId - Metaprompt identifier
|
|
1069
|
+
* @private
|
|
1070
|
+
*/
|
|
1071
|
+
async resetMetapromptTurnCounter(metapromptId) {
|
|
1072
|
+
this.metaPromptTriggerCounters.set(metapromptId, 0);
|
|
1073
|
+
await this.workingMemory.set(`metaprompt_turn_counter_${metapromptId}`, 0);
|
|
1074
|
+
}
|
|
1075
|
+
/**
|
|
1076
|
+
* Executes multiple metaprompts in parallel or sequence.
|
|
1077
|
+
* Replaces the single-metaprompt _triggerAndProcessSelfReflection().
|
|
1078
|
+
*
|
|
1079
|
+
* @param metaPrompts - Array of metaprompts to execute
|
|
1080
|
+
* @private
|
|
1081
|
+
*/
|
|
1082
|
+
async executeMetaprompts(metaPrompts) {
|
|
1083
|
+
if (metaPrompts.length === 0)
|
|
1084
|
+
return;
|
|
1085
|
+
const previousState = this.state;
|
|
1086
|
+
this.state = GMIPrimeState.REFLECTING;
|
|
1087
|
+
this.addTraceEntry(ReasoningEntryType.SELF_REFLECTION_START, `Executing ${metaPrompts.length} metaprompt(s)`, { ids: metaPrompts.map((m) => m.id) });
|
|
1088
|
+
try {
|
|
1089
|
+
// Execute metaprompts in parallel using Promise.allSettled
|
|
1090
|
+
// This allows all to run even if some fail
|
|
1091
|
+
const results = await Promise.allSettled(metaPrompts.map((mp) => this.executeMetapromptHandler(mp)));
|
|
1092
|
+
// Log any failures
|
|
1093
|
+
results.forEach((result, idx) => {
|
|
1094
|
+
if (result.status === 'rejected') {
|
|
1095
|
+
this.addTraceEntry(ReasoningEntryType.ERROR, `Metaprompt '${metaPrompts[idx].id}' failed: ${result.reason}`, { error: result.reason });
|
|
1096
|
+
}
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
catch (error) {
|
|
1100
|
+
const gmiError = createGMIErrorFromError(error, GMIErrorCode.GMI_PROCESSING_ERROR, undefined, 'Error during metaprompt execution');
|
|
1101
|
+
this.addTraceEntry(ReasoningEntryType.ERROR, gmiError.message, gmiError.toPlainObject());
|
|
1102
|
+
}
|
|
1103
|
+
finally {
|
|
1104
|
+
// Restore state
|
|
1105
|
+
const disallowedStates = new Set([
|
|
1106
|
+
GMIPrimeState.IDLE,
|
|
1107
|
+
GMIPrimeState.INITIALIZING,
|
|
1108
|
+
]);
|
|
1109
|
+
this.state = disallowedStates.has(previousState)
|
|
1110
|
+
? GMIPrimeState.READY
|
|
1111
|
+
: previousState;
|
|
1112
|
+
this.addTraceEntry(ReasoningEntryType.SELF_REFLECTION_COMPLETE, 'Metaprompt execution cycle complete');
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
/**
|
|
1116
|
+
* Routes a metaprompt to its appropriate handler based on ID.
|
|
1117
|
+
*
|
|
1118
|
+
* @param metaPrompt - Metaprompt definition to execute
|
|
1119
|
+
* @private
|
|
1120
|
+
*/
|
|
1121
|
+
async executeMetapromptHandler(metaPrompt) {
|
|
1122
|
+
// Handler routing map
|
|
1123
|
+
switch (metaPrompt.id) {
|
|
1124
|
+
case 'gmi_self_trait_adjustment':
|
|
1125
|
+
return this.handleTraitAdjustment(metaPrompt);
|
|
1126
|
+
case 'gmi_frustration_recovery':
|
|
1127
|
+
return this.handleFrustrationRecovery(metaPrompt);
|
|
1128
|
+
case 'gmi_confusion_clarification':
|
|
1129
|
+
return this.handleConfusionClarification(metaPrompt);
|
|
1130
|
+
case 'gmi_satisfaction_reinforcement':
|
|
1131
|
+
return this.handleSatisfactionReinforcement(metaPrompt);
|
|
1132
|
+
case 'gmi_error_recovery':
|
|
1133
|
+
return this.handleErrorRecovery(metaPrompt);
|
|
1134
|
+
case 'gmi_engagement_boost':
|
|
1135
|
+
return this.handleEngagementBoost(metaPrompt);
|
|
1136
|
+
default:
|
|
1137
|
+
// Generic handler for custom metaprompts
|
|
1138
|
+
return this.handleGenericMetaprompt(metaPrompt);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Handler for trait adjustment metaprompt (existing self-reflection logic).
|
|
1143
|
+
*
|
|
1144
|
+
* @param metaPrompt - Metaprompt definition
|
|
1145
|
+
* @private
|
|
1146
|
+
*/
|
|
1147
|
+
async handleTraitAdjustment(metaPrompt) {
|
|
1148
|
+
// Gather evidence for self-reflection
|
|
1149
|
+
const evidenceHistory = this.conversationHistory.slice(-10);
|
|
1150
|
+
const evidenceTrace = this.reasoningTrace.entries.slice(-20);
|
|
1151
|
+
const evidence = {
|
|
1152
|
+
recentHistory: evidenceHistory,
|
|
1153
|
+
recentReasoning: evidenceTrace,
|
|
1154
|
+
currentMood: this.currentGmiMood,
|
|
1155
|
+
userContext: this.currentUserContext,
|
|
1156
|
+
taskContext: this.currentTaskContext,
|
|
1157
|
+
};
|
|
1158
|
+
const variables = {
|
|
1159
|
+
evidence: JSON.stringify(evidence).substring(0, 4000), // Limit size
|
|
1160
|
+
current_mood: this.currentGmiMood,
|
|
1161
|
+
user_skill: this.currentUserContext.skillLevel || 'unknown',
|
|
1162
|
+
task_complexity: this.currentTaskContext.complexity || 'unknown',
|
|
1163
|
+
};
|
|
1164
|
+
const response = await this.executeMetapromptWithVariables(metaPrompt, variables);
|
|
1165
|
+
await this.applyMetapromptUpdates(response, metaPrompt.id);
|
|
1166
|
+
}
|
|
1167
|
+
/**
|
|
1168
|
+
* Handler for frustration recovery metaprompt.
|
|
1169
|
+
*
|
|
1170
|
+
* @param metaPrompt - Metaprompt definition
|
|
1171
|
+
* @private
|
|
1172
|
+
*/
|
|
1173
|
+
async handleFrustrationRecovery(metaPrompt) {
|
|
1174
|
+
const sentimentHistory = await this.workingMemory.get('gmi_sentiment_history');
|
|
1175
|
+
const recentErrors = this.reasoningTrace.entries
|
|
1176
|
+
.slice(-10)
|
|
1177
|
+
.filter((e) => e.type === ReasoningEntryType.ERROR);
|
|
1178
|
+
const variables = {
|
|
1179
|
+
current_sentiment: this.currentUserContext.currentSentiment || 'negative',
|
|
1180
|
+
sentiment_score: (sentimentHistory?.trends[sentimentHistory.trends.length - 1]?.score || -0.5).toString(),
|
|
1181
|
+
consecutive_frustration: (sentimentHistory?.consecutiveFrustration || 1).toString(),
|
|
1182
|
+
recent_conversation: JSON.stringify(this.conversationHistory.slice(-5)),
|
|
1183
|
+
recent_errors: JSON.stringify(recentErrors.map((e) => e.message)),
|
|
1184
|
+
current_mood: this.currentGmiMood,
|
|
1185
|
+
user_skill: this.currentUserContext.skillLevel || 'unknown',
|
|
1186
|
+
task_complexity: this.currentTaskContext.complexity || 'unknown',
|
|
1187
|
+
};
|
|
1188
|
+
const response = await this.executeMetapromptWithVariables(metaPrompt, variables);
|
|
1189
|
+
await this.applyMetapromptUpdates(response, metaPrompt.id);
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Handler for confusion clarification metaprompt.
|
|
1193
|
+
*
|
|
1194
|
+
* @param metaPrompt - Metaprompt definition
|
|
1195
|
+
* @private
|
|
1196
|
+
*/
|
|
1197
|
+
async handleConfusionClarification(metaPrompt) {
|
|
1198
|
+
const sentimentHistory = await this.workingMemory.get('gmi_sentiment_history');
|
|
1199
|
+
// Get the last event for confusion keywords
|
|
1200
|
+
const lastConfusionEvent = this.eventHistory
|
|
1201
|
+
.slice()
|
|
1202
|
+
.reverse()
|
|
1203
|
+
.find((e) => e.eventType === GMIEventType.USER_CONFUSED);
|
|
1204
|
+
const variables = {
|
|
1205
|
+
current_sentiment: this.currentUserContext.currentSentiment || 'neutral',
|
|
1206
|
+
consecutive_confusion: (sentimentHistory?.consecutiveConfusion || 1).toString(),
|
|
1207
|
+
recent_conversation: JSON.stringify(this.conversationHistory.slice(-5)),
|
|
1208
|
+
confusion_keywords: lastConfusionEvent?.metadata.triggerKeywords
|
|
1209
|
+
? JSON.stringify(lastConfusionEvent.metadata.triggerKeywords)
|
|
1210
|
+
: '[]',
|
|
1211
|
+
current_mood: this.currentGmiMood,
|
|
1212
|
+
user_skill: this.currentUserContext.skillLevel || 'unknown',
|
|
1213
|
+
task_complexity: this.currentTaskContext.complexity || 'unknown',
|
|
1214
|
+
};
|
|
1215
|
+
const response = await this.executeMetapromptWithVariables(metaPrompt, variables);
|
|
1216
|
+
await this.applyMetapromptUpdates(response, metaPrompt.id);
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* Handler for satisfaction reinforcement metaprompt.
|
|
1220
|
+
*
|
|
1221
|
+
* @param metaPrompt - Metaprompt definition
|
|
1222
|
+
* @private
|
|
1223
|
+
*/
|
|
1224
|
+
async handleSatisfactionReinforcement(metaPrompt) {
|
|
1225
|
+
const sentimentHistory = await this.workingMemory.get('gmi_sentiment_history');
|
|
1226
|
+
const variables = {
|
|
1227
|
+
current_sentiment: this.currentUserContext.currentSentiment || 'positive',
|
|
1228
|
+
sentiment_score: (sentimentHistory?.trends[sentimentHistory.trends.length - 1]?.score || 0.5).toString(),
|
|
1229
|
+
consecutive_satisfaction: (sentimentHistory?.consecutiveSatisfaction || 1).toString(),
|
|
1230
|
+
recent_conversation: JSON.stringify(this.conversationHistory.slice(-5)),
|
|
1231
|
+
current_mood: this.currentGmiMood,
|
|
1232
|
+
user_skill: this.currentUserContext.skillLevel || 'unknown',
|
|
1233
|
+
task_complexity: this.currentTaskContext.complexity || 'unknown',
|
|
1234
|
+
};
|
|
1235
|
+
const response = await this.executeMetapromptWithVariables(metaPrompt, variables);
|
|
1236
|
+
await this.applyMetapromptUpdates(response, metaPrompt.id);
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* Handler for error recovery metaprompt.
|
|
1240
|
+
*
|
|
1241
|
+
* @param metaPrompt - Metaprompt definition
|
|
1242
|
+
* @private
|
|
1243
|
+
*/
|
|
1244
|
+
async handleErrorRecovery(metaPrompt) {
|
|
1245
|
+
const recentErrors = this.reasoningTrace.entries
|
|
1246
|
+
.slice(-10)
|
|
1247
|
+
.filter((e) => e.type === ReasoningEntryType.ERROR);
|
|
1248
|
+
const variables = {
|
|
1249
|
+
recent_errors: JSON.stringify(recentErrors.map((e) => ({ message: e.message, details: e.details }))),
|
|
1250
|
+
recent_conversation: JSON.stringify(this.conversationHistory.slice(-5)),
|
|
1251
|
+
current_mood: this.currentGmiMood,
|
|
1252
|
+
user_skill: this.currentUserContext.skillLevel || 'unknown',
|
|
1253
|
+
task_complexity: this.currentTaskContext.complexity || 'unknown',
|
|
1254
|
+
};
|
|
1255
|
+
const response = await this.executeMetapromptWithVariables(metaPrompt, variables);
|
|
1256
|
+
await this.applyMetapromptUpdates(response, metaPrompt.id);
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* Handler for engagement boost metaprompt.
|
|
1260
|
+
*
|
|
1261
|
+
* @param metaPrompt - Metaprompt definition
|
|
1262
|
+
* @private
|
|
1263
|
+
*/
|
|
1264
|
+
async handleEngagementBoost(metaPrompt) {
|
|
1265
|
+
const sentimentHistory = await this.workingMemory.get('gmi_sentiment_history');
|
|
1266
|
+
const variables = {
|
|
1267
|
+
consecutive_neutral: (sentimentHistory?.consecutiveConfusion || 4).toString(),
|
|
1268
|
+
recent_conversation: JSON.stringify(this.conversationHistory.slice(-5)),
|
|
1269
|
+
current_mood: this.currentGmiMood,
|
|
1270
|
+
user_skill: this.currentUserContext.skillLevel || 'unknown',
|
|
1271
|
+
task_complexity: this.currentTaskContext.complexity || 'unknown',
|
|
1272
|
+
};
|
|
1273
|
+
const response = await this.executeMetapromptWithVariables(metaPrompt, variables);
|
|
1274
|
+
await this.applyMetapromptUpdates(response, metaPrompt.id);
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* Generic handler for custom metaprompts not in the preset list.
|
|
1278
|
+
*
|
|
1279
|
+
* @param metaPrompt - Metaprompt definition
|
|
1280
|
+
* @private
|
|
1281
|
+
*/
|
|
1282
|
+
async handleGenericMetaprompt(metaPrompt) {
|
|
1283
|
+
// Generic handler that provides all available context
|
|
1284
|
+
const variables = {
|
|
1285
|
+
recent_conversation: JSON.stringify(this.conversationHistory.slice(-5)),
|
|
1286
|
+
recent_reasoning: JSON.stringify(this.reasoningTrace.entries.slice(-10)),
|
|
1287
|
+
current_mood: this.currentGmiMood,
|
|
1288
|
+
user_skill: this.currentUserContext.skillLevel || 'unknown',
|
|
1289
|
+
task_complexity: this.currentTaskContext.complexity || 'unknown',
|
|
1290
|
+
current_sentiment: this.currentUserContext.currentSentiment || 'neutral',
|
|
1291
|
+
};
|
|
1292
|
+
const response = await this.executeMetapromptWithVariables(metaPrompt, variables);
|
|
1293
|
+
await this.applyMetapromptUpdates(response, metaPrompt.id);
|
|
1294
|
+
}
|
|
1295
|
+
/**
|
|
1296
|
+
* Executes a metaprompt with variable substitution.
|
|
1297
|
+
*
|
|
1298
|
+
* @param metaPrompt - Metaprompt definition
|
|
1299
|
+
* @param variables - Variables to substitute in the template
|
|
1300
|
+
* @returns Parsed JSON response from LLM
|
|
1301
|
+
* @private
|
|
1302
|
+
*/
|
|
1303
|
+
async executeMetapromptWithVariables(metaPrompt, variables) {
|
|
1304
|
+
// Extract template
|
|
1305
|
+
let template;
|
|
1306
|
+
if (typeof metaPrompt.promptTemplate === 'string') {
|
|
1307
|
+
template = metaPrompt.promptTemplate;
|
|
1308
|
+
}
|
|
1309
|
+
else {
|
|
1310
|
+
template = metaPrompt.promptTemplate.template;
|
|
1311
|
+
}
|
|
1312
|
+
// Substitute variables
|
|
1313
|
+
let finalPrompt = template;
|
|
1314
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
1315
|
+
finalPrompt = finalPrompt.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), value);
|
|
1316
|
+
}
|
|
1317
|
+
// Get model and provider info
|
|
1318
|
+
const modelId = metaPrompt.modelId || this.activePersona.defaultModelId;
|
|
1319
|
+
const providerId = metaPrompt.providerId || this.activePersona.defaultProviderId;
|
|
1320
|
+
if (!modelId || !providerId) {
|
|
1321
|
+
throw new GMIError('No model or provider specified for metaprompt', GMIErrorCode.CONFIGURATION_ERROR);
|
|
1322
|
+
}
|
|
1323
|
+
// Call LLM
|
|
1324
|
+
this.addTraceEntry(ReasoningEntryType.DEBUG, `Executing metaprompt '${metaPrompt.id}'`, { modelId, providerId });
|
|
1325
|
+
const completionOptions = {
|
|
1326
|
+
temperature: metaPrompt.temperature ?? 0.3,
|
|
1327
|
+
maxTokens: metaPrompt.maxOutputTokens ?? 512,
|
|
1328
|
+
responseFormat: { type: 'json_object' },
|
|
1329
|
+
};
|
|
1330
|
+
const provider = this.llmProviderManager.getProvider(providerId);
|
|
1331
|
+
if (!provider) {
|
|
1332
|
+
throw new GMIError(`Provider '${providerId}' not found for metaprompt '${metaPrompt.id}'.`, GMIErrorCode.LLM_PROVIDER_UNAVAILABLE);
|
|
1333
|
+
}
|
|
1334
|
+
const result = await provider.generateCompletion(modelId, [{ role: 'user', content: finalPrompt }], completionOptions);
|
|
1335
|
+
const responseContent = result.choices?.[0]?.message?.content;
|
|
1336
|
+
if (!responseContent || typeof responseContent !== 'string') {
|
|
1337
|
+
throw new GMIError(`Metaprompt '${metaPrompt.id}' returned no valid content.`, GMIErrorCode.LLM_PROVIDER_ERROR, { response: result });
|
|
1338
|
+
}
|
|
1339
|
+
// Parse JSON with LLM-based recovery
|
|
1340
|
+
const parseOptions = {
|
|
1341
|
+
attemptFixWithLLM: true,
|
|
1342
|
+
llmModelIdForFix: modelId,
|
|
1343
|
+
llmProviderIdForFix: providerId,
|
|
1344
|
+
};
|
|
1345
|
+
const parsedResponse = await this.utilityAI.parseJsonSafe(responseContent, parseOptions);
|
|
1346
|
+
return parsedResponse;
|
|
1347
|
+
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Applies metaprompt updates to GMI state (mood, user skill, task complexity, memory).
|
|
1350
|
+
*
|
|
1351
|
+
* @param updates - Parsed updates from metaprompt response
|
|
1352
|
+
* @param metapromptId - ID of the metaprompt that generated these updates
|
|
1353
|
+
* @private
|
|
1354
|
+
*/
|
|
1355
|
+
async applyMetapromptUpdates(updates, metapromptId) {
|
|
1356
|
+
if (!updates)
|
|
1357
|
+
return;
|
|
1358
|
+
let stateChanged = false;
|
|
1359
|
+
// Mood update
|
|
1360
|
+
if (updates.updatedGmiMood && this.currentGmiMood !== updates.updatedGmiMood) {
|
|
1361
|
+
// Validate that the mood is a valid GMIMood value
|
|
1362
|
+
const validMoods = Object.values(GMIMood);
|
|
1363
|
+
if (validMoods.includes(updates.updatedGmiMood.toUpperCase())) {
|
|
1364
|
+
this.currentGmiMood = updates.updatedGmiMood.toUpperCase();
|
|
1365
|
+
await this.workingMemory.set('currentGmiMood', this.currentGmiMood);
|
|
1366
|
+
stateChanged = true;
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
// User skill level update
|
|
1370
|
+
if (updates.updatedUserSkillLevel &&
|
|
1371
|
+
this.currentUserContext.skillLevel !== updates.updatedUserSkillLevel) {
|
|
1372
|
+
this.currentUserContext.skillLevel = updates.updatedUserSkillLevel;
|
|
1373
|
+
await this.workingMemory.set('currentUserContext', this.currentUserContext);
|
|
1374
|
+
stateChanged = true;
|
|
1375
|
+
}
|
|
1376
|
+
// Task complexity update
|
|
1377
|
+
if (updates.updatedTaskComplexity &&
|
|
1378
|
+
this.currentTaskContext.complexity !== updates.updatedTaskComplexity) {
|
|
1379
|
+
this.currentTaskContext.complexity = updates.updatedTaskComplexity;
|
|
1380
|
+
await this.workingMemory.set('currentTaskContext', this.currentTaskContext);
|
|
1381
|
+
stateChanged = true;
|
|
1382
|
+
}
|
|
1383
|
+
// Memory imprints
|
|
1384
|
+
if (updates.newMemoryImprints && Array.isArray(updates.newMemoryImprints)) {
|
|
1385
|
+
for (const imprint of updates.newMemoryImprints) {
|
|
1386
|
+
if (imprint.key) {
|
|
1387
|
+
await this.workingMemory.set(imprint.key, imprint.value);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
if (updates.newMemoryImprints.length > 0) {
|
|
1391
|
+
stateChanged = true;
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
// Log state change
|
|
1395
|
+
if (stateChanged) {
|
|
1396
|
+
this.addTraceEntry(ReasoningEntryType.STATE_CHANGE, `GMI state updated by metaprompt '${metapromptId}'`, {
|
|
1397
|
+
newMood: this.currentGmiMood,
|
|
1398
|
+
newUserSkill: this.currentUserContext.skillLevel,
|
|
1399
|
+
newTaskComplexity: this.currentTaskContext.complexity,
|
|
1400
|
+
rationale: updates.adjustmentRationale || updates.recoveryStrategy || updates.clarificationStrategy || updates.engagementStrategy || updates.mitigationStrategy,
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
738
1404
|
/** @inheritdoc */
|
|
739
1405
|
async _triggerAndProcessSelfReflection() {
|
|
740
1406
|
// ... (GMI.ts code for _triggerAndProcessSelfReflection provided by user, with my error fixes)
|