@framers/agentos 0.1.6 → 0.1.7
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 +96 -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 +198 -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.map +1 -1
- package/dist/extensions/ExtensionManager.js +6 -1
- 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/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 +11 -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 +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -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/package.json +22 -6
|
@@ -11,9 +11,56 @@ import { AgentOSResponseChunkType, } from './types/AgentOSResponse.js';
|
|
|
11
11
|
import { GMIInteractionType, // Added for GMITurnInput
|
|
12
12
|
GMIOutputChunkType, // Added for comparisons
|
|
13
13
|
} from '../cognitive_substrate/IGMI.js';
|
|
14
|
+
import { MessageRole } from '../core/conversation/ConversationMessage.js';
|
|
14
15
|
import { uuidv4 } from '../utils/uuid.js';
|
|
15
16
|
import { GMIError, GMIErrorCode } from '../utils/errors.js';
|
|
16
17
|
import { normalizeUsage, snapshotPersonaDetails } from '../core/orchestration/helpers.js';
|
|
18
|
+
import { DEFAULT_PROMPT_PROFILE_CONFIG, selectPromptProfile, } from '../core/prompting/PromptProfileRouter.js';
|
|
19
|
+
import { DEFAULT_ROLLING_SUMMARY_COMPACTION_CONFIG, maybeCompactConversationMessages, } from '../core/conversation/RollingSummaryCompactor.js';
|
|
20
|
+
import { DEFAULT_LONG_TERM_MEMORY_POLICY, hasAnyLongTermMemoryScope, LONG_TERM_MEMORY_POLICY_METADATA_KEY, resolveLongTermMemoryPolicy, } from '../core/conversation/LongTermMemoryPolicy.js';
|
|
21
|
+
function normalizeMode(value) {
|
|
22
|
+
return (value || '').trim().toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
function pickByMode(map, mode) {
|
|
25
|
+
if (!map || Object.keys(map).length === 0)
|
|
26
|
+
return null;
|
|
27
|
+
const modeNorm = normalizeMode(mode);
|
|
28
|
+
const exact = map[modeNorm];
|
|
29
|
+
if (exact)
|
|
30
|
+
return exact;
|
|
31
|
+
const patternMatch = Object.entries(map)
|
|
32
|
+
.map(([key, value]) => ({ key: normalizeMode(key), value }))
|
|
33
|
+
.filter(({ key }) => key && (modeNorm === key || modeNorm.startsWith(key) || modeNorm.includes(key)))
|
|
34
|
+
.sort((a, b) => b.key.length - a.key.length)[0];
|
|
35
|
+
return patternMatch?.value ?? null;
|
|
36
|
+
}
|
|
37
|
+
function renderPlainText(markdown) {
|
|
38
|
+
let text = String(markdown ?? '');
|
|
39
|
+
if (!text.trim())
|
|
40
|
+
return '';
|
|
41
|
+
text = text.replace(/\r\n/g, '\n');
|
|
42
|
+
// Fenced code blocks: keep inner content, drop fences.
|
|
43
|
+
text = text.replace(/```[a-zA-Z0-9_-]*\n([\s\S]*?)```/g, '$1');
|
|
44
|
+
// Inline code.
|
|
45
|
+
text = text.replace(/`([^`]+)`/g, '$1');
|
|
46
|
+
// Images + links.
|
|
47
|
+
text = text.replace(/!\[([^\]]*)\]\([^)]+\)/g, '$1');
|
|
48
|
+
text = text.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1');
|
|
49
|
+
// Headings + blockquotes.
|
|
50
|
+
text = text.replace(/^\s{0,3}#{1,6}\s+/gm, '');
|
|
51
|
+
text = text.replace(/^\s{0,3}>\s?/gm, '');
|
|
52
|
+
// Emphasis / strike-through.
|
|
53
|
+
text = text.replace(/(\*\*|__)(.*?)\1/g, '$2');
|
|
54
|
+
text = text.replace(/(\*|_)(.*?)\1/g, '$2');
|
|
55
|
+
text = text.replace(/~~(.*?)~~/g, '$1');
|
|
56
|
+
// Horizontal rules.
|
|
57
|
+
text = text.replace(/^\s*(?:-{3,}|\*{3,}|_{3,})\s*$/gm, '');
|
|
58
|
+
// Basic HTML tags.
|
|
59
|
+
text = text.replace(/<\/?[^>]+>/g, '');
|
|
60
|
+
text = text.replace(/ /g, ' ');
|
|
61
|
+
text = text.replace(/\n{3,}/g, '\n\n');
|
|
62
|
+
return text.trim();
|
|
63
|
+
}
|
|
17
64
|
/**
|
|
18
65
|
* @class AgentOSOrchestrator
|
|
19
66
|
* @description
|
|
@@ -50,13 +97,22 @@ export class AgentOSOrchestrator {
|
|
|
50
97
|
console.warn('AgentOSOrchestrator already initialized. Skipping re-initialization.');
|
|
51
98
|
return;
|
|
52
99
|
}
|
|
53
|
-
if (!dependencies.gmiManager || !dependencies.toolOrchestrator || !dependencies.conversationManager || !dependencies.streamingManager) {
|
|
54
|
-
throw new GMIError('AgentOSOrchestrator: Missing essential dependencies (gmiManager, toolOrchestrator, conversationManager, streamingManager).', GMIErrorCode.CONFIGURATION_ERROR);
|
|
100
|
+
if (!dependencies.gmiManager || !dependencies.toolOrchestrator || !dependencies.conversationManager || !dependencies.streamingManager || !dependencies.modelProviderManager) {
|
|
101
|
+
throw new GMIError('AgentOSOrchestrator: Missing essential dependencies (gmiManager, toolOrchestrator, conversationManager, streamingManager, modelProviderManager).', GMIErrorCode.CONFIGURATION_ERROR);
|
|
55
102
|
}
|
|
56
103
|
this.config = {
|
|
57
104
|
maxToolCallIterations: config.maxToolCallIterations ?? 5,
|
|
58
105
|
defaultAgentTurnTimeoutMs: config.defaultAgentTurnTimeoutMs ?? 120000,
|
|
59
106
|
enableConversationalPersistence: config.enableConversationalPersistence ?? true,
|
|
107
|
+
promptProfileConfig: config.promptProfileConfig === null
|
|
108
|
+
? null
|
|
109
|
+
: (config.promptProfileConfig ?? DEFAULT_PROMPT_PROFILE_CONFIG),
|
|
110
|
+
rollingSummaryCompactionConfig: config.rollingSummaryCompactionConfig === null
|
|
111
|
+
? null
|
|
112
|
+
: { ...DEFAULT_ROLLING_SUMMARY_COMPACTION_CONFIG, ...(config.rollingSummaryCompactionConfig ?? {}) },
|
|
113
|
+
rollingSummaryCompactionProfilesConfig: config.rollingSummaryCompactionProfilesConfig ?? null,
|
|
114
|
+
rollingSummarySystemPrompt: config.rollingSummarySystemPrompt ?? '',
|
|
115
|
+
rollingSummaryStateKey: config.rollingSummaryStateKey ?? 'rollingSummaryState',
|
|
60
116
|
};
|
|
61
117
|
this.dependencies = dependencies;
|
|
62
118
|
this.initialized = true;
|
|
@@ -156,6 +212,12 @@ export class AgentOSOrchestrator {
|
|
|
156
212
|
workflow: data.workflow,
|
|
157
213
|
};
|
|
158
214
|
break;
|
|
215
|
+
case AgentOSResponseChunkType.METADATA_UPDATE:
|
|
216
|
+
chunk = {
|
|
217
|
+
...baseChunk,
|
|
218
|
+
updates: data.updates,
|
|
219
|
+
};
|
|
220
|
+
break;
|
|
159
221
|
default:
|
|
160
222
|
console.error(`AgentOSOrchestrator: Unknown chunk type encountered in pushChunkToStream: ${type}`);
|
|
161
223
|
chunk = {
|
|
@@ -255,6 +317,8 @@ export class AgentOSOrchestrator {
|
|
|
255
317
|
let conversationContext;
|
|
256
318
|
let currentPersonaId = input.selectedPersonaId;
|
|
257
319
|
let gmiInstanceIdForChunks = 'gmi_pending_init';
|
|
320
|
+
let organizationIdForMemory;
|
|
321
|
+
let longTermMemoryPolicy = null;
|
|
258
322
|
try {
|
|
259
323
|
const gmiResult = await this.dependencies.gmiManager.getOrCreateGMIForSession(input.userId, input.sessionId, // This is AgentOS's session ID, GMI might have its own.
|
|
260
324
|
input.selectedPersonaId, // Can be undefined, GMIManager handles default.
|
|
@@ -272,6 +336,346 @@ export class AgentOSOrchestrator {
|
|
|
272
336
|
this.activeStreamContexts.set(agentOSStreamId, streamContext);
|
|
273
337
|
await this.pushChunkToStream(agentOSStreamId, AgentOSResponseChunkType.SYSTEM_PROGRESS, gmiInstanceIdForChunks, currentPersonaId, false, { message: `Initializing persona ${currentPersonaId}... GMI: ${gmiInstanceIdForChunks}`, progressPercentage: 10 });
|
|
274
338
|
const gmiInput = this.constructGMITurnInput(agentOSStreamId, input, streamContext);
|
|
339
|
+
// --- Org context + long-term memory policy (persisted per conversation) ---
|
|
340
|
+
if (conversationContext) {
|
|
341
|
+
const inboundOrg = typeof input.organizationId === 'string' ? input.organizationId.trim() : '';
|
|
342
|
+
// SECURITY NOTE: do not persist organizationId in conversation metadata. The org context
|
|
343
|
+
// should be asserted by the trusted caller each request (after membership checks).
|
|
344
|
+
organizationIdForMemory = inboundOrg || undefined;
|
|
345
|
+
const rawPrevPolicy = conversationContext.getMetadata(LONG_TERM_MEMORY_POLICY_METADATA_KEY);
|
|
346
|
+
const prevPolicy = rawPrevPolicy && typeof rawPrevPolicy === 'object'
|
|
347
|
+
? rawPrevPolicy
|
|
348
|
+
: null;
|
|
349
|
+
const inputPolicy = input.memoryControl?.longTermMemory ?? null;
|
|
350
|
+
longTermMemoryPolicy = resolveLongTermMemoryPolicy({
|
|
351
|
+
previous: prevPolicy,
|
|
352
|
+
input: inputPolicy,
|
|
353
|
+
defaults: DEFAULT_LONG_TERM_MEMORY_POLICY,
|
|
354
|
+
});
|
|
355
|
+
// Only write back when the client supplies overrides or no prior policy exists.
|
|
356
|
+
if (inputPolicy || !prevPolicy) {
|
|
357
|
+
conversationContext.setMetadata(LONG_TERM_MEMORY_POLICY_METADATA_KEY, longTermMemoryPolicy);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
organizationIdForMemory =
|
|
362
|
+
typeof input.organizationId === 'string' ? input.organizationId.trim() : undefined;
|
|
363
|
+
longTermMemoryPolicy = resolveLongTermMemoryPolicy({
|
|
364
|
+
defaults: DEFAULT_LONG_TERM_MEMORY_POLICY,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
(gmiInput.metadata ?? (gmiInput.metadata = {})).organizationId = organizationIdForMemory ?? null;
|
|
368
|
+
gmiInput.metadata.longTermMemoryPolicy = longTermMemoryPolicy;
|
|
369
|
+
// Persist inbound user/system message to ConversationContext BEFORE any LLM call so persona switches
|
|
370
|
+
// and restarts preserve memory, even if the LLM fails.
|
|
371
|
+
if (this.config.enableConversationalPersistence && conversationContext) {
|
|
372
|
+
try {
|
|
373
|
+
if (gmiInput.type === GMIInteractionType.TEXT && typeof gmiInput.content === 'string') {
|
|
374
|
+
conversationContext.addMessage({
|
|
375
|
+
role: MessageRole.USER,
|
|
376
|
+
content: gmiInput.content,
|
|
377
|
+
name: input.userId,
|
|
378
|
+
metadata: { agentPersonaId: currentPersonaId, source: 'agentos_input' },
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
else if (gmiInput.type === GMIInteractionType.MULTIMODAL_CONTENT) {
|
|
382
|
+
conversationContext.addMessage({
|
|
383
|
+
role: MessageRole.USER,
|
|
384
|
+
content: JSON.stringify(gmiInput.content),
|
|
385
|
+
name: input.userId,
|
|
386
|
+
metadata: { agentPersonaId: currentPersonaId, source: 'agentos_input_multimodal' },
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
else if (gmiInput.type === GMIInteractionType.SYSTEM_MESSAGE) {
|
|
390
|
+
conversationContext.addMessage({
|
|
391
|
+
role: MessageRole.SYSTEM,
|
|
392
|
+
content: typeof gmiInput.content === 'string' ? gmiInput.content : JSON.stringify(gmiInput.content),
|
|
393
|
+
metadata: { agentPersonaId: currentPersonaId, source: 'agentos_input_system' },
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
await this.dependencies.conversationManager.saveConversation(conversationContext);
|
|
397
|
+
}
|
|
398
|
+
catch (persistError) {
|
|
399
|
+
console.warn(`AgentOSOrchestrator: Failed to persist inbound message to ConversationContext for stream ${agentOSStreamId}.`, persistError);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
// Build conversationHistoryForPrompt after compaction/routing so it can reflect rolling-summary trimming.
|
|
403
|
+
const modeForRouting = typeof input.options?.customFlags?.mode === 'string' && input.options.customFlags.mode.trim()
|
|
404
|
+
? input.options.customFlags.mode.trim()
|
|
405
|
+
: currentPersonaId;
|
|
406
|
+
// --- Rolling summary compaction (text + JSON metadata) ---
|
|
407
|
+
let rollingSummaryResult = null;
|
|
408
|
+
let rollingSummaryProfileId = null;
|
|
409
|
+
let rollingSummaryConfigForTurn = this.config.rollingSummaryCompactionConfig;
|
|
410
|
+
let rollingSummarySystemPromptForTurn = this.config.rollingSummarySystemPrompt;
|
|
411
|
+
if (this.config.rollingSummaryCompactionProfilesConfig) {
|
|
412
|
+
const profilesConfig = this.config.rollingSummaryCompactionProfilesConfig;
|
|
413
|
+
const picked = pickByMode(profilesConfig.defaultProfileByMode, modeForRouting) ??
|
|
414
|
+
profilesConfig.defaultProfileId;
|
|
415
|
+
rollingSummaryProfileId = picked;
|
|
416
|
+
const profile = profilesConfig.profiles?.[picked];
|
|
417
|
+
if (profile?.config) {
|
|
418
|
+
rollingSummaryConfigForTurn = profile.config;
|
|
419
|
+
}
|
|
420
|
+
if (profile?.systemPrompt) {
|
|
421
|
+
rollingSummarySystemPromptForTurn = profile.systemPrompt;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (conversationContext && rollingSummaryConfigForTurn) {
|
|
425
|
+
try {
|
|
426
|
+
const llmCaller = async (call) => {
|
|
427
|
+
const providerIdResolved = call.providerId ||
|
|
428
|
+
this.dependencies.modelProviderManager.getProviderForModel(call.modelId)?.providerId ||
|
|
429
|
+
this.dependencies.modelProviderManager.getDefaultProvider()?.providerId;
|
|
430
|
+
if (!providerIdResolved) {
|
|
431
|
+
throw new Error(`No provider resolved for rolling-summary model '${call.modelId}'.`);
|
|
432
|
+
}
|
|
433
|
+
const provider = this.dependencies.modelProviderManager.getProvider(providerIdResolved);
|
|
434
|
+
if (!provider) {
|
|
435
|
+
throw new Error(`Provider '${providerIdResolved}' not found for rolling-summary compaction.`);
|
|
436
|
+
}
|
|
437
|
+
const response = await provider.generateCompletion(call.modelId, call.messages, call.options);
|
|
438
|
+
const choice = response?.choices?.[0];
|
|
439
|
+
const responseContent = choice?.message?.content ?? choice?.text ?? '';
|
|
440
|
+
if (typeof responseContent === 'string')
|
|
441
|
+
return responseContent.trim();
|
|
442
|
+
if (Array.isArray(responseContent)) {
|
|
443
|
+
return responseContent
|
|
444
|
+
.map((part) => (typeof part?.text === 'string' ? part.text : ''))
|
|
445
|
+
.filter(Boolean)
|
|
446
|
+
.join('\n')
|
|
447
|
+
.trim();
|
|
448
|
+
}
|
|
449
|
+
return String(responseContent ?? '').trim();
|
|
450
|
+
};
|
|
451
|
+
const stateKey = this.config.rollingSummaryStateKey;
|
|
452
|
+
const compaction = await maybeCompactConversationMessages({
|
|
453
|
+
messages: conversationContext.getAllMessages(),
|
|
454
|
+
sessionMetadata: conversationContext.getAllMetadata(),
|
|
455
|
+
config: rollingSummaryConfigForTurn,
|
|
456
|
+
llmCaller: ({ providerId, modelId, messages, options }) => llmCaller({ providerId, modelId, messages, options }),
|
|
457
|
+
systemPrompt: rollingSummarySystemPromptForTurn,
|
|
458
|
+
stateKey,
|
|
459
|
+
});
|
|
460
|
+
rollingSummaryResult = compaction;
|
|
461
|
+
if (compaction.updatedSessionMetadata && Object.prototype.hasOwnProperty.call(compaction.updatedSessionMetadata, stateKey)) {
|
|
462
|
+
conversationContext.setMetadata(stateKey, compaction.updatedSessionMetadata[stateKey]);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
catch (compactionError) {
|
|
466
|
+
console.warn(`AgentOSOrchestrator: Rolling summary compaction failed for stream ${agentOSStreamId} (continuing without it).`, compactionError);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
if (!gmiInput.metadata) {
|
|
470
|
+
gmiInput.metadata = {};
|
|
471
|
+
}
|
|
472
|
+
const rollingSummaryEnabled = Boolean(rollingSummaryConfigForTurn?.enabled);
|
|
473
|
+
const rollingSummaryText = rollingSummaryEnabled && typeof rollingSummaryResult?.summaryText === 'string'
|
|
474
|
+
? rollingSummaryResult.summaryText.trim()
|
|
475
|
+
: '';
|
|
476
|
+
gmiInput.metadata.rollingSummary =
|
|
477
|
+
rollingSummaryEnabled && rollingSummaryText
|
|
478
|
+
? { text: rollingSummaryText, json: rollingSummaryResult?.summaryJson ?? undefined }
|
|
479
|
+
: null;
|
|
480
|
+
// --- Prompt-profile routing (concise/deep/planner/reviewer) ---
|
|
481
|
+
let promptProfileSelection = null;
|
|
482
|
+
if (conversationContext && this.config.promptProfileConfig) {
|
|
483
|
+
try {
|
|
484
|
+
const rawPrev = conversationContext.getMetadata('promptProfileState');
|
|
485
|
+
const previousState = rawPrev && typeof rawPrev === 'object' && typeof rawPrev.presetId === 'string'
|
|
486
|
+
? rawPrev
|
|
487
|
+
: null;
|
|
488
|
+
const userMessageForRouting = gmiInput.type === GMIInteractionType.TEXT && typeof gmiInput.content === 'string'
|
|
489
|
+
? gmiInput.content
|
|
490
|
+
: gmiInput.type === GMIInteractionType.MULTIMODAL_CONTENT
|
|
491
|
+
? JSON.stringify(gmiInput.content)
|
|
492
|
+
: '';
|
|
493
|
+
const selection = selectPromptProfile(this.config.promptProfileConfig, {
|
|
494
|
+
conversationId: conversationContext.sessionId,
|
|
495
|
+
mode: modeForRouting,
|
|
496
|
+
userMessage: userMessageForRouting,
|
|
497
|
+
didCompact: Boolean(rollingSummaryResult?.didCompact),
|
|
498
|
+
}, previousState);
|
|
499
|
+
promptProfileSelection = selection.result;
|
|
500
|
+
conversationContext.setMetadata('promptProfileState', selection.nextState);
|
|
501
|
+
}
|
|
502
|
+
catch (routerError) {
|
|
503
|
+
console.warn(`AgentOSOrchestrator: Prompt-profile routing failed for stream ${agentOSStreamId} (continuing without it).`, routerError);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
gmiInput.metadata.promptProfile = promptProfileSelection
|
|
507
|
+
? {
|
|
508
|
+
id: promptProfileSelection.presetId,
|
|
509
|
+
systemInstructions: promptProfileSelection.systemInstructions,
|
|
510
|
+
reason: promptProfileSelection.reason,
|
|
511
|
+
}
|
|
512
|
+
: null;
|
|
513
|
+
// --- Long-term memory retrieval (user/persona/org) ---
|
|
514
|
+
let longTermMemoryContextText = null;
|
|
515
|
+
let longTermMemoryRetrievalDiagnostics;
|
|
516
|
+
if (conversationContext &&
|
|
517
|
+
this.dependencies.longTermMemoryRetriever &&
|
|
518
|
+
Boolean(longTermMemoryPolicy?.enabled) &&
|
|
519
|
+
(Boolean(longTermMemoryPolicy?.scopes?.user) ||
|
|
520
|
+
Boolean(longTermMemoryPolicy?.scopes?.persona) ||
|
|
521
|
+
Boolean(longTermMemoryPolicy?.scopes?.organization))) {
|
|
522
|
+
try {
|
|
523
|
+
const queryText = gmiInput.type === GMIInteractionType.TEXT && typeof gmiInput.content === 'string'
|
|
524
|
+
? gmiInput.content.trim()
|
|
525
|
+
: gmiInput.type === GMIInteractionType.MULTIMODAL_CONTENT
|
|
526
|
+
? JSON.stringify(gmiInput.content).trim()
|
|
527
|
+
: '';
|
|
528
|
+
const userTurnCount = conversationContext.getAllMessages().filter((m) => m?.role === MessageRole.USER).length;
|
|
529
|
+
const cadenceTurns = typeof this.config.promptProfileConfig?.routing?.reviewEveryNTurns === 'number'
|
|
530
|
+
? Number(this.config.promptProfileConfig.routing.reviewEveryNTurns)
|
|
531
|
+
: 6;
|
|
532
|
+
const forceOnCompaction = typeof this.config.promptProfileConfig?.routing?.forceReviewOnCompaction === 'boolean'
|
|
533
|
+
? Boolean(this.config.promptProfileConfig.routing.forceReviewOnCompaction)
|
|
534
|
+
: true;
|
|
535
|
+
const rawState = conversationContext.getMetadata('longTermMemoryRetrievalState');
|
|
536
|
+
const prevState = rawState &&
|
|
537
|
+
typeof rawState === 'object' &&
|
|
538
|
+
typeof rawState.lastReviewedUserTurn === 'number'
|
|
539
|
+
? rawState
|
|
540
|
+
: null;
|
|
541
|
+
const shouldReview = !prevState ||
|
|
542
|
+
(cadenceTurns > 0 && userTurnCount - prevState.lastReviewedUserTurn >= cadenceTurns) ||
|
|
543
|
+
(forceOnCompaction && Boolean(rollingSummaryResult?.didCompact));
|
|
544
|
+
if (shouldReview && queryText.length > 0) {
|
|
545
|
+
const retrievalResult = await this.dependencies.longTermMemoryRetriever.retrieveLongTermMemory({
|
|
546
|
+
userId: streamContext.userId,
|
|
547
|
+
organizationId: organizationIdForMemory,
|
|
548
|
+
conversationId: streamContext.conversationId,
|
|
549
|
+
personaId: currentPersonaId,
|
|
550
|
+
mode: modeForRouting,
|
|
551
|
+
queryText,
|
|
552
|
+
memoryPolicy: longTermMemoryPolicy ?? DEFAULT_LONG_TERM_MEMORY_POLICY,
|
|
553
|
+
maxContextChars: 2800,
|
|
554
|
+
topKByScope: { user: 6, persona: 6, organization: 6 },
|
|
555
|
+
});
|
|
556
|
+
if (retrievalResult?.contextText && retrievalResult.contextText.trim()) {
|
|
557
|
+
longTermMemoryContextText = retrievalResult.contextText.trim();
|
|
558
|
+
longTermMemoryRetrievalDiagnostics = retrievalResult.diagnostics;
|
|
559
|
+
}
|
|
560
|
+
conversationContext.setMetadata('longTermMemoryRetrievalState', {
|
|
561
|
+
lastReviewedUserTurn: userTurnCount,
|
|
562
|
+
lastReviewedAt: Date.now(),
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
catch (retrievalError) {
|
|
567
|
+
console.warn(`AgentOSOrchestrator: Long-term memory retrieval failed for stream ${agentOSStreamId} (continuing without it).`, retrievalError);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
gmiInput.metadata.longTermMemoryContext =
|
|
571
|
+
typeof longTermMemoryContextText === 'string' && longTermMemoryContextText.length > 0
|
|
572
|
+
? longTermMemoryContextText
|
|
573
|
+
: null;
|
|
574
|
+
// Provide a durable history snapshot for prompt construction so persona switches share memory.
|
|
575
|
+
// When rolling-summary compaction is enabled and a summary exists, trim history to:
|
|
576
|
+
// - keep the configured head messages verbatim
|
|
577
|
+
// - keep only messages after `summaryUptoTimestamp` (unsummarized tail)
|
|
578
|
+
if (conversationContext) {
|
|
579
|
+
const excludeRoles = new Set([MessageRole.ERROR, MessageRole.THOUGHT]);
|
|
580
|
+
const useTrimmedHistory = rollingSummaryEnabled &&
|
|
581
|
+
typeof rollingSummaryResult?.summaryUptoTimestamp === 'number' &&
|
|
582
|
+
rollingSummaryText.length > 0;
|
|
583
|
+
const rawHistory = useTrimmedHistory
|
|
584
|
+
? conversationContext.getAllMessages()
|
|
585
|
+
: conversationContext.getHistory(undefined, [MessageRole.ERROR, MessageRole.THOUGHT]);
|
|
586
|
+
let historyForPrompt = rawHistory.filter((m) => m && !excludeRoles.has(m.role));
|
|
587
|
+
const last = historyForPrompt[historyForPrompt.length - 1];
|
|
588
|
+
if (last?.role === MessageRole.USER) {
|
|
589
|
+
const content = typeof last.content === 'string' ? last.content.trim() : '';
|
|
590
|
+
const inbound = gmiInput.type === GMIInteractionType.TEXT && typeof gmiInput.content === 'string'
|
|
591
|
+
? gmiInput.content.trim()
|
|
592
|
+
: gmiInput.type === GMIInteractionType.MULTIMODAL_CONTENT
|
|
593
|
+
? JSON.stringify(gmiInput.content).trim()
|
|
594
|
+
: '';
|
|
595
|
+
if (content && inbound && content === inbound) {
|
|
596
|
+
historyForPrompt = historyForPrompt.slice(0, -1);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
if (useTrimmedHistory) {
|
|
600
|
+
const headCount = Math.max(0, rollingSummaryConfigForTurn?.headMessagesToKeep ?? 0);
|
|
601
|
+
const head = historyForPrompt.slice(0, Math.min(headCount, historyForPrompt.length));
|
|
602
|
+
const afterSummary = historyForPrompt.filter((m) => m && m.timestamp > rollingSummaryResult.summaryUptoTimestamp);
|
|
603
|
+
const merged = [];
|
|
604
|
+
const seen = new Set();
|
|
605
|
+
for (const msg of [...head, ...afterSummary]) {
|
|
606
|
+
const id = typeof msg?.id === 'string' ? msg.id : '';
|
|
607
|
+
if (!id || seen.has(id))
|
|
608
|
+
continue;
|
|
609
|
+
seen.add(id);
|
|
610
|
+
merged.push(msg);
|
|
611
|
+
}
|
|
612
|
+
historyForPrompt = merged;
|
|
613
|
+
}
|
|
614
|
+
gmiInput.metadata.conversationHistoryForPrompt = historyForPrompt;
|
|
615
|
+
}
|
|
616
|
+
// Persist any compaction/router metadata updates prior to the main LLM call.
|
|
617
|
+
if (this.config.enableConversationalPersistence && conversationContext) {
|
|
618
|
+
try {
|
|
619
|
+
await this.dependencies.conversationManager.saveConversation(conversationContext);
|
|
620
|
+
}
|
|
621
|
+
catch (metadataPersistError) {
|
|
622
|
+
console.warn(`AgentOSOrchestrator: Failed to persist conversation metadata updates for stream ${agentOSStreamId}.`, metadataPersistError);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
// Best-effort: persist structured rolling memory (`memory_json`) to an external store for retrieval.
|
|
626
|
+
if (rollingSummaryEnabled &&
|
|
627
|
+
rollingSummaryResult?.didCompact &&
|
|
628
|
+
typeof rollingSummaryResult.summaryText === 'string' &&
|
|
629
|
+
this.dependencies.rollingSummaryMemorySink &&
|
|
630
|
+
Boolean(longTermMemoryPolicy?.enabled) &&
|
|
631
|
+
hasAnyLongTermMemoryScope(longTermMemoryPolicy ?? DEFAULT_LONG_TERM_MEMORY_POLICY)) {
|
|
632
|
+
const update = {
|
|
633
|
+
userId: streamContext.userId,
|
|
634
|
+
organizationId: organizationIdForMemory,
|
|
635
|
+
sessionId: streamContext.sessionId,
|
|
636
|
+
conversationId: streamContext.conversationId,
|
|
637
|
+
personaId: currentPersonaId,
|
|
638
|
+
mode: modeForRouting,
|
|
639
|
+
profileId: rollingSummaryProfileId,
|
|
640
|
+
memoryPolicy: longTermMemoryPolicy ?? undefined,
|
|
641
|
+
summaryText: rollingSummaryResult.summaryText,
|
|
642
|
+
summaryJson: rollingSummaryResult.summaryJson ?? null,
|
|
643
|
+
summaryUptoTimestamp: rollingSummaryResult.summaryUptoTimestamp ?? null,
|
|
644
|
+
summaryUpdatedAt: rollingSummaryResult.summaryUpdatedAt ?? null,
|
|
645
|
+
};
|
|
646
|
+
void this.dependencies.rollingSummaryMemorySink
|
|
647
|
+
.upsertRollingSummaryMemory(update)
|
|
648
|
+
.catch((error) => {
|
|
649
|
+
console.warn(`AgentOSOrchestrator: Rolling summary sink failed for stream ${agentOSStreamId} (continuing).`, error);
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
// Emit routing + memory metadata as a first-class chunk for clients.
|
|
653
|
+
await this.pushChunkToStream(agentOSStreamId, AgentOSResponseChunkType.METADATA_UPDATE, gmiInstanceIdForChunks, currentPersonaId, false, {
|
|
654
|
+
updates: {
|
|
655
|
+
promptProfile: promptProfileSelection,
|
|
656
|
+
organizationId: organizationIdForMemory ?? null,
|
|
657
|
+
longTermMemoryPolicy,
|
|
658
|
+
longTermMemoryRetrieval: longTermMemoryContextText
|
|
659
|
+
? {
|
|
660
|
+
didRetrieve: true,
|
|
661
|
+
contextChars: longTermMemoryContextText.length,
|
|
662
|
+
diagnostics: longTermMemoryRetrievalDiagnostics,
|
|
663
|
+
}
|
|
664
|
+
: { didRetrieve: false },
|
|
665
|
+
rollingSummary: rollingSummaryResult
|
|
666
|
+
? {
|
|
667
|
+
profileId: rollingSummaryProfileId,
|
|
668
|
+
enabled: rollingSummaryResult.enabled,
|
|
669
|
+
didCompact: rollingSummaryResult.didCompact,
|
|
670
|
+
summaryText: rollingSummaryResult.summaryText,
|
|
671
|
+
summaryJson: rollingSummaryResult.summaryJson,
|
|
672
|
+
summaryUptoTimestamp: rollingSummaryResult.summaryUptoTimestamp,
|
|
673
|
+
summaryUpdatedAt: rollingSummaryResult.summaryUpdatedAt,
|
|
674
|
+
reason: rollingSummaryResult.reason,
|
|
675
|
+
}
|
|
676
|
+
: null,
|
|
677
|
+
},
|
|
678
|
+
});
|
|
275
679
|
let currentToolCallIteration = 0;
|
|
276
680
|
let continueProcessing = true;
|
|
277
681
|
let lastGMIOutput; // To store the result from handleToolResult or final processTurnStream result
|
|
@@ -338,9 +742,6 @@ export class AgentOSOrchestrator {
|
|
|
338
742
|
// This should use the true GMIOutput returned by GMI (either initial or after tool handling)
|
|
339
743
|
// For now, this relies on the fact that the last interaction with GMI (processTurnStream or handleToolResult)
|
|
340
744
|
// updated the conversation context, and we generate a final response summary.
|
|
341
|
-
if (this.config.enableConversationalPersistence && conversationContext) {
|
|
342
|
-
await this.dependencies.conversationManager.saveConversation(conversationContext);
|
|
343
|
-
}
|
|
344
745
|
// Send a final response chunk if not already implicitly sent by an error or final GMI chunk transform.
|
|
345
746
|
// This part needs careful consideration of what `lastGMIOutput` represents here.
|
|
346
747
|
// It should represent the *actual* TReturn from the GMI's processing.
|
|
@@ -349,8 +750,35 @@ export class AgentOSOrchestrator {
|
|
|
349
750
|
isFinal: true,
|
|
350
751
|
responseText: gmi ? 'Processing complete.' : 'Processing ended.',
|
|
351
752
|
};
|
|
753
|
+
// Persist assistant output into ConversationContext for durable memory / prompt reconstruction.
|
|
754
|
+
if (this.config.enableConversationalPersistence && conversationContext) {
|
|
755
|
+
try {
|
|
756
|
+
if (typeof finalGMIStateForResponse.responseText === 'string' && finalGMIStateForResponse.responseText.trim()) {
|
|
757
|
+
conversationContext.addMessage({
|
|
758
|
+
role: MessageRole.ASSISTANT,
|
|
759
|
+
content: finalGMIStateForResponse.responseText,
|
|
760
|
+
metadata: { agentPersonaId: currentPersonaId, source: 'agentos_output' },
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
else if (finalGMIStateForResponse.toolCalls && finalGMIStateForResponse.toolCalls.length > 0) {
|
|
764
|
+
conversationContext.addMessage({
|
|
765
|
+
role: MessageRole.ASSISTANT,
|
|
766
|
+
content: null,
|
|
767
|
+
tool_calls: finalGMIStateForResponse.toolCalls,
|
|
768
|
+
metadata: { agentPersonaId: currentPersonaId, source: 'agentos_output_tool_calls' },
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
await this.dependencies.conversationManager.saveConversation(conversationContext);
|
|
772
|
+
}
|
|
773
|
+
catch (persistError) {
|
|
774
|
+
console.warn(`AgentOSOrchestrator: Failed to persist assistant output to ConversationContext for stream ${agentOSStreamId}.`, persistError);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
352
777
|
await this.pushChunkToStream(agentOSStreamId, AgentOSResponseChunkType.FINAL_RESPONSE, gmiInstanceIdForChunks, currentPersonaId, true, {
|
|
353
778
|
finalResponseText: finalGMIStateForResponse.responseText ?? null,
|
|
779
|
+
finalResponseTextPlain: typeof finalGMIStateForResponse.responseText === 'string'
|
|
780
|
+
? renderPlainText(finalGMIStateForResponse.responseText)
|
|
781
|
+
: null,
|
|
354
782
|
finalToolCalls: finalGMIStateForResponse.toolCalls,
|
|
355
783
|
finalUiCommands: finalGMIStateForResponse.uiCommands,
|
|
356
784
|
audioOutput: finalGMIStateForResponse.audioOutput,
|
|
@@ -411,6 +839,22 @@ export class AgentOSOrchestrator {
|
|
|
411
839
|
try {
|
|
412
840
|
// Emit the tool result itself as a chunk
|
|
413
841
|
await this.pushChunkToStream(agentOSStreamId, AgentOSResponseChunkType.TOOL_RESULT_EMISSION, gmiInstanceIdForChunks, personaId, false, { toolCallId, toolName, toolResult: toolOutput, isSuccess, errorMessage });
|
|
842
|
+
// Persist tool result into ConversationContext for durable memory / prompt reconstruction.
|
|
843
|
+
if (this.config.enableConversationalPersistence && conversationContext) {
|
|
844
|
+
try {
|
|
845
|
+
conversationContext.addMessage({
|
|
846
|
+
role: MessageRole.TOOL,
|
|
847
|
+
content: typeof toolOutput === 'string' ? toolOutput : JSON.stringify(toolOutput),
|
|
848
|
+
tool_call_id: toolCallId,
|
|
849
|
+
name: toolName,
|
|
850
|
+
metadata: { agentPersonaId: personaId, source: 'agentos_tool_result', isSuccess },
|
|
851
|
+
});
|
|
852
|
+
await this.dependencies.conversationManager.saveConversation(conversationContext);
|
|
853
|
+
}
|
|
854
|
+
catch (persistError) {
|
|
855
|
+
console.warn(`AgentOSOrchestrator: Failed to persist tool result to ConversationContext for stream ${agentOSStreamId}.`, persistError);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
414
858
|
// GMI processes the tool result and gives a *final output for that step*
|
|
415
859
|
const gmiOutputAfterTool = await gmi.handleToolResult(toolCallId, toolName, toolResultPayload, userId, userApiKeys || {});
|
|
416
860
|
// Process the GMIOutput (which is not a stream of chunks)
|
|
@@ -423,7 +867,27 @@ export class AgentOSOrchestrator {
|
|
|
423
867
|
}
|
|
424
868
|
else if (gmiOutputAfterTool.isFinal) {
|
|
425
869
|
if (this.config.enableConversationalPersistence && conversationContext) {
|
|
426
|
-
|
|
870
|
+
try {
|
|
871
|
+
if (typeof gmiOutputAfterTool.responseText === 'string' && gmiOutputAfterTool.responseText.trim()) {
|
|
872
|
+
conversationContext.addMessage({
|
|
873
|
+
role: MessageRole.ASSISTANT,
|
|
874
|
+
content: gmiOutputAfterTool.responseText,
|
|
875
|
+
metadata: { agentPersonaId: personaId, source: 'agentos_output' },
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
else if (gmiOutputAfterTool.toolCalls && gmiOutputAfterTool.toolCalls.length > 0) {
|
|
879
|
+
conversationContext.addMessage({
|
|
880
|
+
role: MessageRole.ASSISTANT,
|
|
881
|
+
content: null,
|
|
882
|
+
tool_calls: gmiOutputAfterTool.toolCalls,
|
|
883
|
+
metadata: { agentPersonaId: personaId, source: 'agentos_output_tool_calls' },
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
await this.dependencies.conversationManager.saveConversation(conversationContext);
|
|
887
|
+
}
|
|
888
|
+
catch (persistError) {
|
|
889
|
+
console.warn(`AgentOSOrchestrator: Failed to persist assistant output after tool result for stream ${agentOSStreamId}.`, persistError);
|
|
890
|
+
}
|
|
427
891
|
}
|
|
428
892
|
// If it's final and no more tool calls, the interaction for this GMI processing cycle might be done.
|
|
429
893
|
// Push a final response marker or the already pushed final data from processGMIOutput takes precedence.
|