@memberjunction/ng-conversations 6.1.0-edge.2 → 6.1.0-edge.4

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.
Files changed (43) hide show
  1. package/LICENSE +180 -4
  2. package/README.md +32 -1
  3. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +159 -9
  4. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  5. package/dist/lib/components/conversation/conversation-chat-area.component.js +497 -106
  6. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  7. package/dist/lib/components/conversation/pinned-messages-panel.component.d.ts +14 -2
  8. package/dist/lib/components/conversation/pinned-messages-panel.component.d.ts.map +1 -1
  9. package/dist/lib/components/conversation/pinned-messages-panel.component.js +37 -19
  10. package/dist/lib/components/conversation/pinned-messages-panel.component.js.map +1 -1
  11. package/dist/lib/components/message/message-input.component.d.ts +7 -3
  12. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  13. package/dist/lib/components/message/message-input.component.js +78 -159
  14. package/dist/lib/components/message/message-input.component.js.map +1 -1
  15. package/dist/lib/components/message/message-list.component.d.ts +287 -7
  16. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  17. package/dist/lib/components/message/message-list.component.js +850 -56
  18. package/dist/lib/components/message/message-list.component.js.map +1 -1
  19. package/dist/lib/services/conversation-agent.service.d.ts +98 -16
  20. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  21. package/dist/lib/services/conversation-agent.service.js +218 -69
  22. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  23. package/dist/lib/services/conversation-detail-window.store.d.ts +206 -0
  24. package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -0
  25. package/dist/lib/services/conversation-detail-window.store.js +503 -0
  26. package/dist/lib/services/conversation-detail-window.store.js.map +1 -0
  27. package/dist/lib/services/search.service.d.ts +10 -4
  28. package/dist/lib/services/search.service.d.ts.map +1 -1
  29. package/dist/lib/services/search.service.js +16 -11
  30. package/dist/lib/services/search.service.js.map +1 -1
  31. package/dist/lib/utils/agent-artifact-summary.d.ts +54 -0
  32. package/dist/lib/utils/agent-artifact-summary.d.ts.map +1 -0
  33. package/dist/lib/utils/agent-artifact-summary.js +49 -0
  34. package/dist/lib/utils/agent-artifact-summary.js.map +1 -0
  35. package/dist/lib/utils/conversation-detail-window.d.ts +49 -0
  36. package/dist/lib/utils/conversation-detail-window.d.ts.map +1 -0
  37. package/dist/lib/utils/conversation-detail-window.js +86 -0
  38. package/dist/lib/utils/conversation-detail-window.js.map +1 -0
  39. package/dist/lib/utils/date-jump.d.ts +65 -0
  40. package/dist/lib/utils/date-jump.d.ts.map +1 -0
  41. package/dist/lib/utils/date-jump.js +106 -0
  42. package/dist/lib/utils/date-jump.js.map +1 -0
  43. package/package.json +32 -32
@@ -1160,7 +1160,9 @@ export class MessageInputComponent extends BaseAngularComponent {
1160
1160
  // Priority 5: Check if Sage was explicitly @mentioned with a config preset
1161
1161
  // If so, treat it like agent continuity so the config preset is preserved
1162
1162
  if (this.converationManagerAgent?.ID) {
1163
- const sageConfigPreset = this.agentService.findConfigurationPresetFromHistory(this.converationManagerAgent.ID, this.conversationHistory);
1163
+ const sageConfigPreset = this.conversationId
1164
+ ? await this.agentService.FindConfigurationPresetForAgent(this.conversationId, this.converationManagerAgent.ID)
1165
+ : undefined;
1164
1166
  if (sageConfigPreset) {
1165
1167
  // User explicitly @mentioned Sage with a config - use the shared execution helper directly
1166
1168
  // Pass the already-found config preset to avoid redundant history search
@@ -1273,15 +1275,15 @@ export class MessageInputComponent extends BaseAngularComponent {
1273
1275
  // Emit event to show temporary "Analyzing intent..." message in conversation
1274
1276
  this.intentCheckStarted.emit({ conversationId: this.conversationId });
1275
1277
  try {
1276
- // Build context from pre-loaded maps (if available)
1277
- if (!this.artifactsByDetailId || !this.agentRunsByDetailId) {
1278
- console.warn('⚠️ Artifact/agent run context not available for intent check');
1279
- return { decision: 'UNSURE', reasoning: 'Context not available' };
1280
- }
1281
- const intent = await this.agentService.checkAgentContinuityIntent(agentId, message, this.conversationHistory, {
1282
- artifactsByDetailId: this.artifactsByDetailId,
1283
- agentRunsByDetailId: this.agentRunsByDetailId
1284
- });
1278
+ // The pre-loaded artifact/agent-run maps are no longer passed: they are scoped to the
1279
+ // loaded transcript window, and the service now queries for this agent's artifacts so
1280
+ // the classifier reasons over the whole conversation. A conversation id is what it
1281
+ // needs instead, and without one there is nothing to query.
1282
+ if (!this.conversationId) {
1283
+ console.warn('⚠️ No conversation id available for intent check');
1284
+ return { decision: 'UNSURE', reasoning: 'Conversation not available' };
1285
+ }
1286
+ const intent = await this.agentService.checkAgentContinuityIntent(this.conversationId, agentId, message, this.conversationHistory);
1285
1287
  return intent;
1286
1288
  }
1287
1289
  catch (error) {
@@ -1701,52 +1703,32 @@ export class MessageInputComponent extends BaseAngularComponent {
1701
1703
  }
1702
1704
  /**
1703
1705
  * Load previous payload for an agent from its most recent OUTPUT artifact.
1704
- * Searches backwards through all messages from this agent until an artifact is found.
1705
- * This ensures payload continuity even after clarifying exchanges without artifacts.
1706
- * Checks both user-visible and system artifacts to support agents like Agent Manager.
1706
+ *
1707
+ * Resolved by QUERY rather than by scanning `conversationHistory`. That array is now the
1708
+ * loaded transcript WINDOW, not the full conversation, so a scan silently misses any
1709
+ * artifact below the window's oldest row — and a null payload is a legal agent input, so
1710
+ * the miss surfaces as the agent regenerating from scratch instead of modifying. Covers
1711
+ * system-visibility artifacts (Agent Manager and friends) for free: the query filters on
1712
+ * Direction, not on Visibility.
1707
1713
  */
1708
1714
  async loadPreviousPayloadForAgent(agentId) {
1709
- // Get all messages from this agent in reverse order (most recent first)
1710
- const agentMessages = this.conversationHistory
1711
- .slice()
1712
- .reverse()
1713
- .filter(msg => msg.Role === 'AI' && UUIDsEqual(msg.AgentID, agentId));
1714
- if (agentMessages.length === 0) {
1715
+ if (!this.conversationId) {
1715
1716
  return { payload: null, artifactInfo: null };
1716
1717
  }
1717
- // Search through all agent messages until we find one with an artifact
1718
- for (const message of agentMessages) {
1719
- // Check user-visible artifacts first
1720
- let artifacts = this.artifactsByDetailId?.get(message.ID);
1721
- // If not found, check system artifacts (Agent Manager, etc.)
1722
- if (!artifacts || artifacts.length === 0) {
1723
- artifacts = this.systemArtifactsByDetailId?.get(message.ID);
1724
- }
1725
- // Try to load artifact content as payload
1726
- if (artifacts && artifacts.length > 0) {
1727
- const artifact = artifacts[0];
1728
- try {
1729
- const version = await artifact.getVersion();
1730
- if (version.Content) {
1731
- console.log(`📦 Loaded previous payload for agent ${agentId} from artifact (message: ${message.ID})`);
1732
- return {
1733
- payload: JSON.parse(version.Content),
1734
- artifactInfo: {
1735
- artifactId: artifact.artifactId,
1736
- versionId: artifact.artifactVersionId,
1737
- versionNumber: artifact.versionNumber
1738
- }
1739
- };
1740
- }
1741
- }
1742
- catch (error) {
1743
- console.error('Error loading payload from artifact:', error);
1744
- // Continue to next message
1745
- }
1746
- }
1718
+ const source = await this.agentService.FindLatestAgentOutputVersion(this.conversationId, agentId);
1719
+ if (!source || source.payload == null) {
1720
+ console.log(`📦 No previous payload found for agent ${agentId}`);
1721
+ return { payload: null, artifactInfo: null };
1747
1722
  }
1748
- console.log(`📦 No previous payload found for agent ${agentId} after searching ${agentMessages.length} messages`);
1749
- return { payload: null, artifactInfo: null };
1723
+ console.log(`📦 Loaded previous payload for agent ${agentId} from artifact version ${source.versionId}`);
1724
+ return {
1725
+ payload: source.payload,
1726
+ artifactInfo: {
1727
+ artifactId: source.artifactId,
1728
+ versionId: source.versionId,
1729
+ versionNumber: source.versionNumber
1730
+ }
1731
+ };
1750
1732
  }
1751
1733
  /**
1752
1734
  * Handle sub-agent invocation based on Sage's payload
@@ -1790,7 +1772,7 @@ export class MessageInputComponent extends BaseAngularComponent {
1790
1772
  : { payload: null, artifactInfo: null };
1791
1773
  // Find configuration preset from previous @mention in conversation history
1792
1774
  const configurationPresetId = agent?.ID
1793
- ? this.agentService.findConfigurationPresetFromHistory(agent.ID, this.conversationHistory)
1775
+ ? await this.agentService.FindConfigurationPresetForAgent(conversationId, agent.ID)
1794
1776
  : undefined;
1795
1777
  // Invoke the sub-agent with progress callback
1796
1778
  const subResult = await this.agentService.invokeSubAgent(agentName, conversationId, userMessage, this.conversationHistory, reasoning, agentResponseMessage.ID, previousPayload, // Pass previous payload for continuity
@@ -1881,30 +1863,18 @@ export class MessageInputComponent extends BaseAngularComponent {
1881
1863
  const agentName = previousAgent.Name || 'Agent';
1882
1864
  let previousPayload = null;
1883
1865
  let previousArtifactInfo = null;
1884
- // Use pre-loaded artifact data (no DB queries!)
1885
- // Check both user-visible and system artifacts
1886
- let artifacts = this.artifactsByDetailId?.get(lastAIMessage.ID);
1887
- if (!artifacts || artifacts.length === 0) {
1888
- artifacts = this.systemArtifactsByDetailId?.get(lastAIMessage.ID);
1889
- }
1890
- if (artifacts && artifacts.length > 0) {
1891
- try {
1892
- // Use the first artifact (should only be one OUTPUT per message)
1893
- const artifact = artifacts[0];
1894
- const version = await artifact.getVersion();
1895
- if (version.Content) {
1896
- previousPayload = JSON.parse(version.Content);
1897
- previousArtifactInfo = {
1898
- artifactId: artifact.artifactId,
1899
- versionId: artifact.artifactVersionId,
1900
- versionNumber: artifact.versionNumber
1901
- };
1902
- console.log('📦 Loaded previous OUTPUT artifact as payload for continuity', previousArtifactInfo);
1903
- }
1904
- }
1905
- catch (error) {
1906
- console.warn('⚠️ Could not parse previous artifact content:', error);
1907
- }
1866
+ // Resolved by QUERY, not from the window's artifact maps: `lastAIMessage` can sit inside
1867
+ // the loaded window while its artifact does not, and this path silently degrades to a
1868
+ // null payload when the lookup misses.
1869
+ const source = await this.agentService.FindLatestAgentOutputVersion(conversationId, lastAIMessage.AgentID);
1870
+ if (source && source.payload != null) {
1871
+ previousPayload = source.payload;
1872
+ previousArtifactInfo = {
1873
+ artifactId: source.artifactId,
1874
+ versionId: source.versionId,
1875
+ versionNumber: source.versionNumber
1876
+ };
1877
+ console.log('📦 Loaded previous OUTPUT artifact as payload for continuity', previousArtifactInfo);
1908
1878
  }
1909
1879
  // Create status message showing agent continuity
1910
1880
  const statusMessage = await this.dataCache.createConversationDetail(this.currentUser);
@@ -2085,64 +2055,28 @@ export class MessageInputComponent extends BaseAngularComponent {
2085
2055
  let previousPayload = null;
2086
2056
  let previousArtifactInfo = null;
2087
2057
  let previousConfigurationId = undefined;
2088
- // Use targetArtifactVersionId if specified (from intent check)
2058
+ // Use targetArtifactVersionId if specified (from intent check).
2059
+ // Resolved by ID against the database, not against artifactsByDetailId: the intent check
2060
+ // may well have named a version attached to a message BELOW the loaded window, which is
2061
+ // precisely when continuity matters and precisely what the window's maps cannot see.
2089
2062
  if (targetArtifactVersionId) {
2090
- // Find the artifact in pre-loaded data (check both user-visible and system artifacts)
2091
- for (const [detailId, artifacts] of (this.artifactsByDetailId?.entries() || [])) {
2092
- const targetArtifact = artifacts.find(a => a.artifactVersionId === targetArtifactVersionId);
2093
- if (targetArtifact) {
2094
- try {
2095
- // Lazy load the full version entity to get Content
2096
- const version = await targetArtifact.getVersion();
2097
- if (version.Content) {
2098
- previousPayload = JSON.parse(version.Content);
2099
- previousArtifactInfo = {
2100
- artifactId: targetArtifact.artifactId,
2101
- versionId: targetArtifact.artifactVersionId,
2102
- versionNumber: targetArtifact.versionNumber
2103
- };
2104
- console.log('📦 Loaded target artifact version as payload', previousArtifactInfo);
2105
- }
2106
- }
2107
- catch (error) {
2108
- console.warn('⚠️ Could not load target artifact version:', error);
2109
- }
2110
- break;
2111
- }
2063
+ const target = await this.agentService.FindArtifactVersionById(targetArtifactVersionId);
2064
+ if (target && target.payload != null) {
2065
+ previousPayload = target.payload;
2066
+ previousArtifactInfo = {
2067
+ artifactId: target.artifactId,
2068
+ versionId: target.versionId,
2069
+ versionNumber: target.versionNumber
2070
+ };
2071
+ console.log('📦 Loaded target artifact version as payload', previousArtifactInfo);
2112
2072
  }
2113
- // If not found in user-visible artifacts, check system artifacts
2114
- if (!previousPayload && this.systemArtifactsByDetailId) {
2115
- for (const [detailId, artifacts] of this.systemArtifactsByDetailId.entries()) {
2116
- const targetArtifact = artifacts.find(a => a.artifactVersionId === targetArtifactVersionId);
2117
- if (targetArtifact) {
2118
- try {
2119
- const version = await targetArtifact.getVersion();
2120
- if (version.Content) {
2121
- previousPayload = JSON.parse(version.Content);
2122
- previousArtifactInfo = {
2123
- artifactId: targetArtifact.artifactId,
2124
- versionId: targetArtifact.artifactVersionId,
2125
- versionNumber: targetArtifact.versionNumber
2126
- };
2127
- console.log('📦 Loaded target artifact version as payload (from system artifacts)', previousArtifactInfo);
2128
- }
2129
- }
2130
- catch (error) {
2131
- console.warn('⚠️ Could not load target artifact version:', error);
2132
- }
2133
- break;
2134
- }
2135
- }
2073
+ else {
2074
+ console.warn('⚠️ Could not load target artifact version:', targetArtifactVersionId);
2136
2075
  }
2137
2076
  }
2138
- // Get all messages from this agent in reverse order (most recent first)
2139
- const agentMessages = this.conversationHistory
2140
- .slice()
2141
- .reverse()
2142
- .filter(msg => msg.Role === 'AI' && UUIDsEqual(msg.AgentID, agentId));
2143
2077
  // Extract configuration preset from the User message that @mentioned this agent
2144
2078
  // Uses the shared helper method in the agent service
2145
- previousConfigurationId = this.agentService.findConfigurationPresetFromHistory(agentId, this.conversationHistory);
2079
+ previousConfigurationId = await this.agentService.FindConfigurationPresetForAgent(conversationId, agentId);
2146
2080
  // Fall back to the chat header's mode-picker selection when nothing
2147
2081
  // in the message history pinned a preset. The picker reflects the
2148
2082
  // user's persistent per-agent mode preference (Draft / Standard /
@@ -2154,38 +2088,23 @@ export class MessageInputComponent extends BaseAngularComponent {
2154
2088
  }
2155
2089
  // Fall back to searching through all agent messages for an artifact
2156
2090
  // This ensures payload continuity even after clarifying exchanges without artifacts
2157
- if (!previousPayload && agentMessages.length > 0) {
2158
- console.log('📦 Searching through agent messages for most recent artifact...');
2159
- for (const message of agentMessages) {
2160
- // Get artifacts from pre-loaded data (check both user-visible and system artifacts)
2161
- let artifacts = this.artifactsByDetailId?.get(message.ID);
2162
- if (!artifacts || artifacts.length === 0) {
2163
- artifacts = this.systemArtifactsByDetailId?.get(message.ID);
2164
- }
2165
- if (artifacts && artifacts.length > 0) {
2166
- try {
2167
- // Use the first artifact (should only be one OUTPUT per message)
2168
- const artifact = artifacts[0];
2169
- const version = await artifact.getVersion();
2170
- if (version.Content) {
2171
- previousPayload = JSON.parse(version.Content);
2172
- previousArtifactInfo = {
2173
- artifactId: artifact.artifactId,
2174
- versionId: artifact.artifactVersionId,
2175
- versionNumber: artifact.versionNumber
2176
- };
2177
- console.log(`📦 Loaded artifact as payload from message ${message.ID}`, previousArtifactInfo);
2178
- break; // Found an artifact, stop searching
2179
- }
2180
- }
2181
- catch (error) {
2182
- console.warn('⚠️ Could not parse artifact content:', error);
2183
- // Continue to next message
2184
- }
2185
- }
2091
+ // Fall back to this agent's newest OUTPUT artifact when the intent check named no
2092
+ // version (or named one that no longer resolves). Queried, not scanned: the array this
2093
+ // used to walk is the loaded window, so the artifact it is looking for is exactly the
2094
+ // one most likely to be missing from it.
2095
+ if (!previousPayload) {
2096
+ const source = await this.agentService.FindLatestAgentOutputVersion(conversationId, agentId);
2097
+ if (source && source.payload != null) {
2098
+ previousPayload = source.payload;
2099
+ previousArtifactInfo = {
2100
+ artifactId: source.artifactId,
2101
+ versionId: source.versionId,
2102
+ versionNumber: source.versionNumber
2103
+ };
2104
+ console.log('📦 Loaded artifact as payload for continuation', previousArtifactInfo);
2186
2105
  }
2187
- if (!previousPayload) {
2188
- console.log(`📦 No artifact found after searching ${agentMessages.length} messages from agent`);
2106
+ else {
2107
+ console.log(`📦 No artifact found for agent ${agentId} in this conversation`);
2189
2108
  }
2190
2109
  }
2191
2110
  // Execute the agent with the gathered context