@memberjunction/ng-ai-test-harness 2.112.0 → 2.113.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/ai-test-harness-dialog.component.d.ts.map +1 -1
- package/dist/lib/ai-test-harness-dialog.component.js +12 -16
- package/dist/lib/ai-test-harness-dialog.component.js.map +1 -1
- package/dist/lib/ai-test-harness-window.component.d.ts.map +1 -1
- package/dist/lib/ai-test-harness-window.component.js +2 -2
- package/dist/lib/ai-test-harness-window.component.js.map +1 -1
- package/dist/lib/ai-test-harness.component.d.ts.map +1 -1
- package/dist/lib/ai-test-harness.component.js +135 -126
- package/dist/lib/ai-test-harness.component.js.map +1 -1
- package/dist/lib/test-harness-custom-window.component.d.ts.map +1 -1
- package/dist/lib/test-harness-custom-window.component.js +5 -4
- package/dist/lib/test-harness-custom-window.component.js.map +1 -1
- package/package.json +8 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Component, Input, Output, EventEmitter, ViewChild, SecurityContext
|
|
2
|
-
import { Metadata, RunView, CompositeKey } from '@memberjunction/
|
|
1
|
+
import { Component, Input, Output, EventEmitter, ViewChild, SecurityContext } from '@angular/core';
|
|
2
|
+
import { Metadata, RunView, CompositeKey } from '@memberjunction/core';
|
|
3
3
|
import { MJNotificationService } from '@memberjunction/ng-notifications';
|
|
4
4
|
import { SharedService } from '@memberjunction/ng-shared';
|
|
5
5
|
import { Subject } from 'rxjs';
|
|
@@ -1277,7 +1277,7 @@ export class AITestHarnessComponent {
|
|
|
1277
1277
|
seed: null,
|
|
1278
1278
|
stopSequences: [],
|
|
1279
1279
|
includeLogProbs: false,
|
|
1280
|
-
topLogProbs: 2
|
|
1280
|
+
topLogProbs: 2
|
|
1281
1281
|
};
|
|
1282
1282
|
/** Raw stop sequences input for textarea */
|
|
1283
1283
|
this.stopSequencesText = '';
|
|
@@ -1291,7 +1291,7 @@ export class AITestHarnessComponent {
|
|
|
1291
1291
|
{ text: 'Text', value: 'Text' },
|
|
1292
1292
|
{ text: 'Markdown', value: 'Markdown' },
|
|
1293
1293
|
{ text: 'JSON', value: 'JSON' },
|
|
1294
|
-
{ text: 'Model Specific', value: 'ModelSpecific' }
|
|
1294
|
+
{ text: 'Model Specific', value: 'ModelSpecific' }
|
|
1295
1295
|
];
|
|
1296
1296
|
/** Selected response format for prompt execution */
|
|
1297
1297
|
this.selectedResponseFormat = this.responseFormatOptions[0];
|
|
@@ -1477,7 +1477,7 @@ export class AITestHarnessComponent {
|
|
|
1477
1477
|
const serializedAgentRun = message.data.agentRun;
|
|
1478
1478
|
// Update streaming message content if available
|
|
1479
1479
|
if (message.data.progress?.message) {
|
|
1480
|
-
const streamingMessage = this.conversationMessages.find(
|
|
1480
|
+
const streamingMessage = this.conversationMessages.find(m => m.isStreaming);
|
|
1481
1481
|
if (streamingMessage) {
|
|
1482
1482
|
// Clear any typing animation interval
|
|
1483
1483
|
const typingInterval = streamingMessage._typingInterval;
|
|
@@ -1499,7 +1499,7 @@ export class AITestHarnessComponent {
|
|
|
1499
1499
|
// Load the serialized data into our entity
|
|
1500
1500
|
await this.currentAgentRun.LoadFromData(serializedAgentRun);
|
|
1501
1501
|
// Update assistant message with agent run ID if available
|
|
1502
|
-
const streamingMessage = this.conversationMessages.find(
|
|
1502
|
+
const streamingMessage = this.conversationMessages.find(m => m.isStreaming);
|
|
1503
1503
|
if (streamingMessage && this.currentAgentRun.ID) {
|
|
1504
1504
|
streamingMessage.agentRunId = this.currentAgentRun.ID;
|
|
1505
1505
|
}
|
|
@@ -1512,19 +1512,19 @@ export class AITestHarnessComponent {
|
|
|
1512
1512
|
status: this.currentAgentRun.Status,
|
|
1513
1513
|
stepCount: this.currentAgentRun.Steps?.length || 0,
|
|
1514
1514
|
executionMonitorMode: this.executionMonitorMode,
|
|
1515
|
-
steps: this.currentAgentRun.Steps?.map(
|
|
1515
|
+
steps: this.currentAgentRun.Steps?.map(s => ({
|
|
1516
1516
|
id: s.ID,
|
|
1517
1517
|
type: s.StepType,
|
|
1518
1518
|
status: s.Status,
|
|
1519
1519
|
hasSubAgentRun: !!s.SubAgentRun,
|
|
1520
|
-
subStepCount: s.SubAgentRun?.Steps?.length || 0
|
|
1521
|
-
}))
|
|
1520
|
+
subStepCount: s.SubAgentRun?.Steps?.length || 0
|
|
1521
|
+
}))
|
|
1522
1522
|
});
|
|
1523
1523
|
// Force change detection
|
|
1524
1524
|
this.cdr.detectChanges();
|
|
1525
1525
|
}
|
|
1526
1526
|
else if (message?.type === 'StreamingContent' && message.data?.streaming) {
|
|
1527
|
-
const streamingMessage = this.conversationMessages.find(
|
|
1527
|
+
const streamingMessage = this.conversationMessages.find(m => m.isStreaming);
|
|
1528
1528
|
if (streamingMessage) {
|
|
1529
1529
|
// Append streaming content
|
|
1530
1530
|
if (!streamingMessage.streamingContent) {
|
|
@@ -1555,15 +1555,15 @@ export class AITestHarnessComponent {
|
|
|
1555
1555
|
if (this.entity && 'AIModelTypeID' in this.entity) {
|
|
1556
1556
|
const prompt = this.entity;
|
|
1557
1557
|
if (prompt.AIModelTypeID) {
|
|
1558
|
-
filteredModels = AIEngineBase.Instance.Models.filter(
|
|
1558
|
+
filteredModels = AIEngineBase.Instance.Models.filter(model => model.AIModelTypeID === prompt.AIModelTypeID && model.IsActive);
|
|
1559
1559
|
}
|
|
1560
1560
|
else {
|
|
1561
1561
|
// No model type restriction, show all active models
|
|
1562
|
-
filteredModels = AIEngineBase.Instance.Models.filter(
|
|
1562
|
+
filteredModels = AIEngineBase.Instance.Models.filter(model => model.IsActive);
|
|
1563
1563
|
}
|
|
1564
1564
|
// Set default response format from prompt with slight delay for Kendo dropdown
|
|
1565
1565
|
setTimeout(() => {
|
|
1566
|
-
const format = this.responseFormatOptions.find(
|
|
1566
|
+
const format = this.responseFormatOptions.find(f => f.value.trim().toLowerCase() === prompt.ResponseFormat.trim().toLowerCase());
|
|
1567
1567
|
if (format) {
|
|
1568
1568
|
this.selectedResponseFormat = format;
|
|
1569
1569
|
}
|
|
@@ -1574,7 +1574,7 @@ export class AITestHarnessComponent {
|
|
|
1574
1574
|
}
|
|
1575
1575
|
else {
|
|
1576
1576
|
// Not a prompt entity, show all active models
|
|
1577
|
-
filteredModels = AIEngineBase.Instance.Models.filter(
|
|
1577
|
+
filteredModels = AIEngineBase.Instance.Models.filter(model => model.IsActive);
|
|
1578
1578
|
}
|
|
1579
1579
|
// Sort models by name
|
|
1580
1580
|
filteredModels.sort((a, b) => a.Name.localeCompare(b.Name));
|
|
@@ -1586,7 +1586,7 @@ export class AITestHarnessComponent {
|
|
|
1586
1586
|
// Add a blank option at the beginning with the default model name
|
|
1587
1587
|
this.availableModels = [
|
|
1588
1588
|
{ ID: '', Name: this.defaultModelName ? `-- Default: ${this.defaultModelName} --` : '-- Use Default Model --' },
|
|
1589
|
-
...filteredModels
|
|
1589
|
+
...filteredModels
|
|
1590
1590
|
];
|
|
1591
1591
|
// Don't auto-select a model - let the dropdown show the blank option
|
|
1592
1592
|
this.selectedModelId = '';
|
|
@@ -1605,14 +1605,15 @@ export class AITestHarnessComponent {
|
|
|
1605
1605
|
async getDefaultModelName(prompt) {
|
|
1606
1606
|
try {
|
|
1607
1607
|
// Get prompt-specific model associations
|
|
1608
|
-
const promptModels = AIEngineBase.Instance.PromptModels.filter(
|
|
1608
|
+
const promptModels = AIEngineBase.Instance.PromptModels.filter(pm => pm.PromptID === prompt.ID &&
|
|
1609
|
+
(pm.Status === 'Active' || pm.Status === 'Preview'));
|
|
1609
1610
|
let defaultModel = null;
|
|
1610
1611
|
if (promptModels.length > 0) {
|
|
1611
1612
|
// Sort by priority (higher priority first)
|
|
1612
1613
|
promptModels.sort((a, b) => (b.Priority || 0) - (a.Priority || 0));
|
|
1613
1614
|
// Find the first active model
|
|
1614
1615
|
for (const pm of promptModels) {
|
|
1615
|
-
const model = AIEngineBase.Instance.Models.find(
|
|
1616
|
+
const model = AIEngineBase.Instance.Models.find(m => m.ID === pm.ModelID && m.IsActive);
|
|
1616
1617
|
if (model) {
|
|
1617
1618
|
defaultModel = model;
|
|
1618
1619
|
break;
|
|
@@ -1621,7 +1622,8 @@ export class AITestHarnessComponent {
|
|
|
1621
1622
|
}
|
|
1622
1623
|
// If no prompt-specific model, use selection strategy
|
|
1623
1624
|
if (!defaultModel) {
|
|
1624
|
-
const candidates = AIEngineBase.Instance.Models.filter(
|
|
1625
|
+
const candidates = AIEngineBase.Instance.Models.filter(m => m.IsActive &&
|
|
1626
|
+
(!prompt.AIModelTypeID || m.AIModelTypeID === prompt.AIModelTypeID));
|
|
1625
1627
|
if (candidates.length > 0) {
|
|
1626
1628
|
// Apply selection strategy
|
|
1627
1629
|
if (prompt.SelectionStrategy === 'ByPower') {
|
|
@@ -1658,16 +1660,18 @@ export class AITestHarnessComponent {
|
|
|
1658
1660
|
return;
|
|
1659
1661
|
}
|
|
1660
1662
|
// Get vendors that offer this model - same logic as loadVendorsForModel
|
|
1661
|
-
const modelVendors = AIEngineBase.Instance.ModelVendors.filter(
|
|
1663
|
+
const modelVendors = AIEngineBase.Instance.ModelVendors.filter(mv => mv.ModelID === this.defaultModel.ID &&
|
|
1664
|
+
mv.Status === 'Active' &&
|
|
1665
|
+
mv.Type?.trim().toLowerCase() === 'inference provider');
|
|
1662
1666
|
// Map to vendor objects with priority from ModelVendor
|
|
1663
1667
|
const vendorObjects = [];
|
|
1664
1668
|
for (const mv of modelVendors) {
|
|
1665
|
-
const vendor = AIEngineBase.Instance.Vendors.find(
|
|
1669
|
+
const vendor = AIEngineBase.Instance.Vendors.find(v => v.ID === mv.VendorID);
|
|
1666
1670
|
if (vendor) {
|
|
1667
1671
|
vendorObjects.push({
|
|
1668
1672
|
ID: vendor.ID,
|
|
1669
1673
|
Name: vendor.Name,
|
|
1670
|
-
Priority: mv.Priority || 999
|
|
1674
|
+
Priority: mv.Priority || 999 // Use ModelVendor priority
|
|
1671
1675
|
});
|
|
1672
1676
|
}
|
|
1673
1677
|
}
|
|
@@ -1695,12 +1699,12 @@ export class AITestHarnessComponent {
|
|
|
1695
1699
|
EntityName: 'MJ: AI Configurations',
|
|
1696
1700
|
ExtraFilter: `Status IN ('Active', 'Preview')`,
|
|
1697
1701
|
OrderBy: 'IsDefault DESC, Name',
|
|
1698
|
-
ResultType: 'entity_object'
|
|
1702
|
+
ResultType: 'entity_object'
|
|
1699
1703
|
});
|
|
1700
1704
|
if (result.Success && result.Results) {
|
|
1701
1705
|
this.availableConfigurations = result.Results;
|
|
1702
1706
|
// Auto-select the default configuration if one exists
|
|
1703
|
-
const defaultConfig = this.availableConfigurations.find(
|
|
1707
|
+
const defaultConfig = this.availableConfigurations.find(c => c.IsDefault);
|
|
1704
1708
|
if (defaultConfig) {
|
|
1705
1709
|
this.selectedConfigurationId = defaultConfig.ID;
|
|
1706
1710
|
}
|
|
@@ -1746,17 +1750,19 @@ export class AITestHarnessComponent {
|
|
|
1746
1750
|
return;
|
|
1747
1751
|
}
|
|
1748
1752
|
// Get model-specific vendors
|
|
1749
|
-
const modelVendors = AIEngineBase.Instance.ModelVendors.filter(
|
|
1753
|
+
const modelVendors = AIEngineBase.Instance.ModelVendors.filter(mv => mv.ModelID === this.selectedModelId &&
|
|
1754
|
+
mv.Status === 'Active' &&
|
|
1755
|
+
mv.Type?.trim().toLowerCase() === 'inference provider');
|
|
1750
1756
|
// Map to vendor objects with priority from ModelVendor
|
|
1751
1757
|
const vendorObjects = [];
|
|
1752
1758
|
for (const mv of modelVendors) {
|
|
1753
|
-
const vendor = AIEngineBase.Instance.Vendors.find(
|
|
1759
|
+
const vendor = AIEngineBase.Instance.Vendors.find(v => v.ID === mv.VendorID);
|
|
1754
1760
|
if (vendor) {
|
|
1755
1761
|
// For now, include all vendors. TODO: Filter by vendor type when available
|
|
1756
1762
|
vendorObjects.push({
|
|
1757
1763
|
ID: vendor.ID,
|
|
1758
1764
|
Name: vendor.Name,
|
|
1759
|
-
Priority: mv.Priority || 999
|
|
1765
|
+
Priority: mv.Priority || 999 // Use ModelVendor priority
|
|
1760
1766
|
});
|
|
1761
1767
|
}
|
|
1762
1768
|
}
|
|
@@ -1795,9 +1801,7 @@ export class AITestHarnessComponent {
|
|
|
1795
1801
|
this.advancedParams.seed = prompt.Seed;
|
|
1796
1802
|
if (prompt.StopSequences) {
|
|
1797
1803
|
this.stopSequencesText = prompt.StopSequences;
|
|
1798
|
-
this.advancedParams.stopSequences = prompt.StopSequences.split(',')
|
|
1799
|
-
.map((s) => s.trim())
|
|
1800
|
-
.filter((s) => s.length > 0);
|
|
1804
|
+
this.advancedParams.stopSequences = prompt.StopSequences.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
|
|
1801
1805
|
}
|
|
1802
1806
|
if (prompt.IncludeLogProbs != null)
|
|
1803
1807
|
this.advancedParams.includeLogProbs = prompt.IncludeLogProbs;
|
|
@@ -1821,7 +1825,7 @@ export class AITestHarnessComponent {
|
|
|
1821
1825
|
EntityName: 'Template Params',
|
|
1822
1826
|
ExtraFilter: `TemplateID='${prompt.TemplateID}'`,
|
|
1823
1827
|
OrderBy: 'Name ASC',
|
|
1824
|
-
ResultType: 'entity_object'
|
|
1828
|
+
ResultType: 'entity_object'
|
|
1825
1829
|
});
|
|
1826
1830
|
if (result.Success && result.Results && result.Results.length > 0) {
|
|
1827
1831
|
// Clear existing template variables
|
|
@@ -1831,7 +1835,7 @@ export class AITestHarnessComponent {
|
|
|
1831
1835
|
this.templateVariables.push({
|
|
1832
1836
|
name: param.Name,
|
|
1833
1837
|
value: param.DefaultValue || '',
|
|
1834
|
-
type: this.getVariableTypeFromParamType(param.Type)
|
|
1838
|
+
type: this.getVariableTypeFromParamType(param.Type)
|
|
1835
1839
|
});
|
|
1836
1840
|
}
|
|
1837
1841
|
// If no parameters found, add one empty variable to start
|
|
@@ -1879,14 +1883,14 @@ export class AITestHarnessComponent {
|
|
|
1879
1883
|
// Reset vendor - will be loaded by loadDefaultVendor
|
|
1880
1884
|
this.selectedVendorId = '';
|
|
1881
1885
|
// Reset response format to prompt's setting
|
|
1882
|
-
const format = this.responseFormatOptions.find(
|
|
1886
|
+
const format = this.responseFormatOptions.find(f => f.value.trim().toLowerCase() === prompt.ResponseFormat.trim().toLowerCase());
|
|
1883
1887
|
this.selectedResponseFormat = format || this.responseFormatOptions[0];
|
|
1884
1888
|
// Reset max tokens
|
|
1885
1889
|
this.maxTokens = null;
|
|
1886
1890
|
// Reset skip validation
|
|
1887
1891
|
this.skipValidation = false;
|
|
1888
1892
|
// Reset configuration to default
|
|
1889
|
-
const defaultConfig = this.availableConfigurations.find(
|
|
1893
|
+
const defaultConfig = this.availableConfigurations.find(c => c.IsDefault);
|
|
1890
1894
|
if (defaultConfig) {
|
|
1891
1895
|
this.selectedConfigurationId = defaultConfig.ID;
|
|
1892
1896
|
}
|
|
@@ -1904,7 +1908,7 @@ export class AITestHarnessComponent {
|
|
|
1904
1908
|
seed: null,
|
|
1905
1909
|
stopSequences: [],
|
|
1906
1910
|
includeLogProbs: false,
|
|
1907
|
-
topLogProbs: 2
|
|
1911
|
+
topLogProbs: 2
|
|
1908
1912
|
};
|
|
1909
1913
|
this.stopSequencesText = '';
|
|
1910
1914
|
// Reload prompt defaults for advanced params
|
|
@@ -1949,14 +1953,14 @@ export class AITestHarnessComponent {
|
|
|
1949
1953
|
seed: null,
|
|
1950
1954
|
stopSequences: [],
|
|
1951
1955
|
includeLogProbs: false,
|
|
1952
|
-
topLogProbs: 2
|
|
1956
|
+
topLogProbs: 2
|
|
1953
1957
|
};
|
|
1954
1958
|
this.stopSequencesText = '';
|
|
1955
1959
|
this.advancedParamsExpanded = false;
|
|
1956
1960
|
this.skipValidation = false;
|
|
1957
1961
|
// Reset agent configuration to default
|
|
1958
1962
|
if (this.mode === 'agent') {
|
|
1959
|
-
const defaultConfig = this.availableConfigurations.find(
|
|
1963
|
+
const defaultConfig = this.availableConfigurations.find(c => c.IsDefault);
|
|
1960
1964
|
this.agentConfigurationId = defaultConfig?.ID || '';
|
|
1961
1965
|
}
|
|
1962
1966
|
}
|
|
@@ -2002,7 +2006,7 @@ export class AITestHarnessComponent {
|
|
|
2002
2006
|
currentAgentRun: !!this.currentAgentRun,
|
|
2003
2007
|
agentRunStatus: this.currentAgentRun?.Status || 'none',
|
|
2004
2008
|
conversationMessages: this.conversationMessages.length,
|
|
2005
|
-
executionMonitorMode: this.executionMonitorMode
|
|
2009
|
+
executionMonitorMode: this.executionMonitorMode
|
|
2006
2010
|
});
|
|
2007
2011
|
this.activeTab = tab;
|
|
2008
2012
|
// If switching to execution monitor tab, ensure it has the latest data
|
|
@@ -2010,11 +2014,13 @@ export class AITestHarnessComponent {
|
|
|
2010
2014
|
console.log('📊 Switching to execution monitor tab');
|
|
2011
2015
|
// Always ensure we have the latest execution data when switching to monitor
|
|
2012
2016
|
if (this.conversationMessages.length > 0) {
|
|
2013
|
-
const lastAssistantMessage = this.conversationMessages
|
|
2017
|
+
const lastAssistantMessage = this.conversationMessages
|
|
2018
|
+
.filter(m => m.role === 'assistant' && m.agentRunId)
|
|
2019
|
+
.pop();
|
|
2014
2020
|
console.log('🔍 Last assistant message with agent run:', {
|
|
2015
2021
|
found: !!lastAssistantMessage,
|
|
2016
2022
|
hasAgentRunId: !!lastAssistantMessage?.agentRunId,
|
|
2017
|
-
agentRunId: lastAssistantMessage?.agentRunId
|
|
2023
|
+
agentRunId: lastAssistantMessage?.agentRunId
|
|
2018
2024
|
});
|
|
2019
2025
|
if (lastAssistantMessage && lastAssistantMessage.agentRunId) {
|
|
2020
2026
|
// Always update agent run to ensure it's fresh
|
|
@@ -2025,7 +2031,7 @@ export class AITestHarnessComponent {
|
|
|
2025
2031
|
this.lastProcessedRunId = messageRunId;
|
|
2026
2032
|
console.log('✅ Loading agent run:', {
|
|
2027
2033
|
mode: this.executionMonitorMode,
|
|
2028
|
-
runId: this.lastProcessedRunId
|
|
2034
|
+
runId: this.lastProcessedRunId
|
|
2029
2035
|
});
|
|
2030
2036
|
// Trigger change detection to ensure the execution monitor updates
|
|
2031
2037
|
setTimeout(() => {
|
|
@@ -2042,7 +2048,7 @@ export class AITestHarnessComponent {
|
|
|
2042
2048
|
}
|
|
2043
2049
|
else {
|
|
2044
2050
|
console.log('📄 Switching away from execution monitor, preserving data:', {
|
|
2045
|
-
currentAgentRunExists: !!this.currentAgentRun
|
|
2051
|
+
currentAgentRunExists: !!this.currentAgentRun
|
|
2046
2052
|
});
|
|
2047
2053
|
// Don't clear currentAgentRun when switching away from execution monitor
|
|
2048
2054
|
// This preserves the state for when the user switches back
|
|
@@ -2088,7 +2094,7 @@ export class AITestHarnessComponent {
|
|
|
2088
2094
|
this.executionMonitorMode = 'historical';
|
|
2089
2095
|
console.log('✅ Loaded agent run:', {
|
|
2090
2096
|
id: agentRunEntity.ID,
|
|
2091
|
-
stepCount: this.currentAgentRun.Steps?.length || 0
|
|
2097
|
+
stepCount: this.currentAgentRun.Steps?.length || 0
|
|
2092
2098
|
});
|
|
2093
2099
|
// Force change detection to update the execution monitor
|
|
2094
2100
|
this.cdr.detectChanges();
|
|
@@ -2145,7 +2151,7 @@ export class AITestHarnessComponent {
|
|
|
2145
2151
|
id: this.generateMessageId(),
|
|
2146
2152
|
role: 'user',
|
|
2147
2153
|
content: this.currentUserMessage.trim(),
|
|
2148
|
-
timestamp: new Date()
|
|
2154
|
+
timestamp: new Date()
|
|
2149
2155
|
};
|
|
2150
2156
|
this.conversationMessages.push(userMessage);
|
|
2151
2157
|
// Clear input and update change detection
|
|
@@ -2197,7 +2203,7 @@ export class AITestHarnessComponent {
|
|
|
2197
2203
|
streamingContent: this.mode === 'agent' ? 'Running agent...' : 'Running prompt...',
|
|
2198
2204
|
agentRunId: '',
|
|
2199
2205
|
streamingStartTime: Date.now(),
|
|
2200
|
-
elapsedTime: 0
|
|
2206
|
+
elapsedTime: 0
|
|
2201
2207
|
};
|
|
2202
2208
|
this.conversationMessages.push(assistantMessage);
|
|
2203
2209
|
this.scrollNeeded = true;
|
|
@@ -2229,7 +2235,7 @@ export class AITestHarnessComponent {
|
|
|
2229
2235
|
data: Object.keys(dataContext).length > 0 ? dataContext : undefined,
|
|
2230
2236
|
lastRunId: this.lastAgentRunId || undefined,
|
|
2231
2237
|
autoPopulateLastRunPayload: this.lastAgentRunId ? true : false,
|
|
2232
|
-
configurationId: this.agentConfigurationId || undefined
|
|
2238
|
+
configurationId: this.agentConfigurationId || undefined
|
|
2233
2239
|
});
|
|
2234
2240
|
// Stop elapsed time counter
|
|
2235
2241
|
if (this.elapsedTimeInterval) {
|
|
@@ -2244,7 +2250,7 @@ export class AITestHarnessComponent {
|
|
|
2244
2250
|
const parseOptions = {
|
|
2245
2251
|
extractInlineJson: true,
|
|
2246
2252
|
maxDepth: 100,
|
|
2247
|
-
debug: false
|
|
2253
|
+
debug: false
|
|
2248
2254
|
};
|
|
2249
2255
|
// Apply recursive JSON parsing to extract any nested JSON strings
|
|
2250
2256
|
const fullResult = ParseJSONRecursive(executionResult, parseOptions);
|
|
@@ -2286,7 +2292,7 @@ export class AITestHarnessComponent {
|
|
|
2286
2292
|
assistantMessage.payload = payloadData; // Store the payload if present
|
|
2287
2293
|
const startedAt = executionResult.agentRun?.StartedAt ? new Date(executionResult.agentRun.StartedAt).getTime() : 0;
|
|
2288
2294
|
const completedAt = executionResult.agentRun?.CompletedAt ? new Date(executionResult.agentRun.CompletedAt).getTime() : 0;
|
|
2289
|
-
const executionTime = startedAt && completedAt ? completedAt - startedAt : 0;
|
|
2295
|
+
const executionTime = (startedAt && completedAt) ? (completedAt - startedAt) : 0;
|
|
2290
2296
|
assistantMessage.executionTime = executionTime;
|
|
2291
2297
|
assistantMessage.agentRunId = fullResult.agentRun?.ID || assistantMessage.agentRunId;
|
|
2292
2298
|
// Update the tracking ID when we set new execution data
|
|
@@ -2304,7 +2310,7 @@ export class AITestHarnessComponent {
|
|
|
2304
2310
|
console.error('❌ AI Test Harness: Execution failed', {
|
|
2305
2311
|
success: executionResult?.success,
|
|
2306
2312
|
errorMessage: executionResult?.agentRun?.ErrorMessage,
|
|
2307
|
-
hasPayload: !!executionResult?.payload
|
|
2313
|
+
hasPayload: !!executionResult?.payload
|
|
2308
2314
|
});
|
|
2309
2315
|
assistantMessage.content = 'I encountered an error processing your request.';
|
|
2310
2316
|
assistantMessage.error = executionResult?.agentRun?.ErrorMessage || 'Unknown error occurred';
|
|
@@ -2334,7 +2340,7 @@ export class AITestHarnessComponent {
|
|
|
2334
2340
|
error: error,
|
|
2335
2341
|
message: error?.message,
|
|
2336
2342
|
stack: error?.stack,
|
|
2337
|
-
type: error?.constructor?.name
|
|
2343
|
+
type: error?.constructor?.name
|
|
2338
2344
|
});
|
|
2339
2345
|
// Update assistant message with error
|
|
2340
2346
|
const lastMessage = this.conversationMessages[this.conversationMessages.length - 1];
|
|
@@ -2375,7 +2381,7 @@ export class AITestHarnessComponent {
|
|
|
2375
2381
|
streamingContent: this.mode === 'agent' ? 'Running agent...' : 'Running prompt...',
|
|
2376
2382
|
agentRunId: '',
|
|
2377
2383
|
streamingStartTime: Date.now(),
|
|
2378
|
-
elapsedTime: 0
|
|
2384
|
+
elapsedTime: 0
|
|
2379
2385
|
};
|
|
2380
2386
|
this.conversationMessages.push(assistantMessage);
|
|
2381
2387
|
this.scrollNeeded = true;
|
|
@@ -2389,14 +2395,14 @@ export class AITestHarnessComponent {
|
|
|
2389
2395
|
// Prepare data context (template variables + user message)
|
|
2390
2396
|
const dataContext = {
|
|
2391
2397
|
...templateVariables,
|
|
2392
|
-
userMessage: userMessage
|
|
2398
|
+
userMessage: userMessage
|
|
2393
2399
|
};
|
|
2394
2400
|
// Build conversation messages
|
|
2395
2401
|
const messages = this.conversationMessages
|
|
2396
|
-
.filter(
|
|
2397
|
-
.map(
|
|
2402
|
+
.filter(m => !m.isStreaming && m.content) // Only include non-streaming messages with content
|
|
2403
|
+
.map(m => ({
|
|
2398
2404
|
role: m.role,
|
|
2399
|
-
content: m.content
|
|
2405
|
+
content: m.content
|
|
2400
2406
|
}));
|
|
2401
2407
|
// Execute the prompt using the new AI client
|
|
2402
2408
|
const executionResult = await dataProvider.AI.RunAIPrompt({
|
|
@@ -2420,7 +2426,7 @@ export class AITestHarnessComponent {
|
|
|
2420
2426
|
topLogProbs: this.advancedParams.includeLogProbs ? this.advancedParams.topLogProbs : undefined,
|
|
2421
2427
|
messages: messages.length > 0 ? messages : undefined,
|
|
2422
2428
|
rerunFromPromptRunID: this.originalPromptRunId || undefined,
|
|
2423
|
-
systemPromptOverride: this.systemPromptOverride || undefined
|
|
2429
|
+
systemPromptOverride: this.systemPromptOverride || undefined
|
|
2424
2430
|
});
|
|
2425
2431
|
// Stop elapsed time counter
|
|
2426
2432
|
if (this.elapsedTimeInterval) {
|
|
@@ -2433,16 +2439,16 @@ export class AITestHarnessComponent {
|
|
|
2433
2439
|
const parseOptions = {
|
|
2434
2440
|
extractInlineJson: true,
|
|
2435
2441
|
maxDepth: 100,
|
|
2436
|
-
debug: false
|
|
2442
|
+
debug: false
|
|
2437
2443
|
};
|
|
2438
2444
|
if (executionResult?.success) {
|
|
2439
2445
|
// Use parsedResult if available, otherwise fall back to output
|
|
2440
2446
|
// Handle case where parsedResult is already an object (from GraphQL client)
|
|
2441
2447
|
const contentToDisplay = executionResult.parsedResult
|
|
2442
|
-
? typeof executionResult.parsedResult === 'object'
|
|
2448
|
+
? (typeof executionResult.parsedResult === 'object'
|
|
2443
2449
|
? JSON.stringify(executionResult.parsedResult, null, 2)
|
|
2444
|
-
: executionResult.parsedResult
|
|
2445
|
-
: executionResult.output || 'No response generated';
|
|
2450
|
+
: executionResult.parsedResult)
|
|
2451
|
+
: (executionResult.output || 'No response generated');
|
|
2446
2452
|
assistantMessage.content = contentToDisplay;
|
|
2447
2453
|
assistantMessage.executionTime = executionResult.executionTimeMs;
|
|
2448
2454
|
// Store the complete execution result for JSON display
|
|
@@ -2516,10 +2522,10 @@ export class AITestHarnessComponent {
|
|
|
2516
2522
|
startTypingAnimation(message) {
|
|
2517
2523
|
const initialMessages = [
|
|
2518
2524
|
"I'm processing your request...",
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2525
|
+
"Let me think about that...",
|
|
2526
|
+
"Working on your request...",
|
|
2527
|
+
"Analyzing your question...",
|
|
2528
|
+
"Processing..."
|
|
2523
2529
|
];
|
|
2524
2530
|
const selectedMessage = initialMessages[Math.floor(Math.random() * initialMessages.length)];
|
|
2525
2531
|
let index = 0;
|
|
@@ -2586,7 +2592,7 @@ export class AITestHarnessComponent {
|
|
|
2586
2592
|
this.agentVariables.push({
|
|
2587
2593
|
name: '',
|
|
2588
2594
|
value: '',
|
|
2589
|
-
type: 'string'
|
|
2595
|
+
type: 'string'
|
|
2590
2596
|
});
|
|
2591
2597
|
}
|
|
2592
2598
|
/**
|
|
@@ -2604,7 +2610,7 @@ export class AITestHarnessComponent {
|
|
|
2604
2610
|
this.templateVariables.push({
|
|
2605
2611
|
name: '',
|
|
2606
2612
|
value: '',
|
|
2607
|
-
type: 'string'
|
|
2613
|
+
type: 'string'
|
|
2608
2614
|
});
|
|
2609
2615
|
}
|
|
2610
2616
|
/**
|
|
@@ -2648,10 +2654,10 @@ export class AITestHarnessComponent {
|
|
|
2648
2654
|
const parsedData = JSON.parse(saved);
|
|
2649
2655
|
this.savedConversations = parsedData || [];
|
|
2650
2656
|
// Convert date strings back to Date objects
|
|
2651
|
-
this.savedConversations.forEach(
|
|
2657
|
+
this.savedConversations.forEach(conv => {
|
|
2652
2658
|
conv.createdAt = new Date(conv.createdAt);
|
|
2653
2659
|
conv.updatedAt = new Date(conv.updatedAt);
|
|
2654
|
-
conv.messages.forEach(
|
|
2660
|
+
conv.messages.forEach(msg => {
|
|
2655
2661
|
msg.timestamp = new Date(msg.timestamp);
|
|
2656
2662
|
});
|
|
2657
2663
|
});
|
|
@@ -2694,7 +2700,7 @@ export class AITestHarnessComponent {
|
|
|
2694
2700
|
}
|
|
2695
2701
|
// If updating existing conversation, pre-fill the name
|
|
2696
2702
|
if (this.currentConversationId) {
|
|
2697
|
-
const currentConv = this.savedConversations.find(
|
|
2703
|
+
const currentConv = this.savedConversations.find(c => c.id === this.currentConversationId);
|
|
2698
2704
|
this.tempConversationName = currentConv ? currentConv.name : '';
|
|
2699
2705
|
}
|
|
2700
2706
|
else {
|
|
@@ -2740,11 +2746,11 @@ export class AITestHarnessComponent {
|
|
|
2740
2746
|
skipValidation: this.mode === 'prompt' ? this.skipValidation : undefined,
|
|
2741
2747
|
agentConfigurationId: this.mode === 'agent' ? this.agentConfigurationId : undefined,
|
|
2742
2748
|
createdAt: new Date(),
|
|
2743
|
-
updatedAt: new Date()
|
|
2749
|
+
updatedAt: new Date()
|
|
2744
2750
|
};
|
|
2745
2751
|
if (this.currentConversationId) {
|
|
2746
2752
|
// Update existing conversation
|
|
2747
|
-
const index = this.savedConversations.findIndex(
|
|
2753
|
+
const index = this.savedConversations.findIndex(c => c.id === this.currentConversationId);
|
|
2748
2754
|
if (index >= 0) {
|
|
2749
2755
|
conversation.id = this.currentConversationId;
|
|
2750
2756
|
conversation.createdAt = this.savedConversations[index].createdAt;
|
|
@@ -2797,7 +2803,7 @@ export class AITestHarnessComponent {
|
|
|
2797
2803
|
}
|
|
2798
2804
|
autoSaveConversation() {
|
|
2799
2805
|
if (this.currentConversationId && this.conversationMessages.length > 0) {
|
|
2800
|
-
const index = this.savedConversations.findIndex(
|
|
2806
|
+
const index = this.savedConversations.findIndex(c => c.id === this.currentConversationId);
|
|
2801
2807
|
if (index >= 0) {
|
|
2802
2808
|
this.savedConversations[index].messages = [...this.conversationMessages];
|
|
2803
2809
|
this.savedConversations[index].dataContext = this.buildDataContext();
|
|
@@ -2862,7 +2868,9 @@ export class AITestHarnessComponent {
|
|
|
2862
2868
|
this.agentVariables.push({
|
|
2863
2869
|
name: key,
|
|
2864
2870
|
value: typeof value === 'object' ? JSON.stringify(value) : String(value),
|
|
2865
|
-
type: typeof value === 'boolean' ? 'boolean' :
|
|
2871
|
+
type: typeof value === 'boolean' ? 'boolean' :
|
|
2872
|
+
typeof value === 'number' ? 'number' :
|
|
2873
|
+
typeof value === 'object' ? 'object' : 'string'
|
|
2866
2874
|
});
|
|
2867
2875
|
}
|
|
2868
2876
|
// Restore configuration for agent mode
|
|
@@ -2878,7 +2886,9 @@ export class AITestHarnessComponent {
|
|
|
2878
2886
|
this.templateVariables.push({
|
|
2879
2887
|
name: key,
|
|
2880
2888
|
value: typeof value === 'object' ? JSON.stringify(value) : String(value),
|
|
2881
|
-
type: typeof value === 'boolean' ? 'boolean' :
|
|
2889
|
+
type: typeof value === 'boolean' ? 'boolean' :
|
|
2890
|
+
typeof value === 'number' ? 'number' :
|
|
2891
|
+
typeof value === 'object' ? 'object' : 'string'
|
|
2882
2892
|
});
|
|
2883
2893
|
}
|
|
2884
2894
|
// Restore advanced parameters
|
|
@@ -2914,7 +2924,9 @@ export class AITestHarnessComponent {
|
|
|
2914
2924
|
}
|
|
2915
2925
|
}
|
|
2916
2926
|
// Load agent run from the last assistant message if available
|
|
2917
|
-
const lastAssistantMessage = this.conversationMessages
|
|
2927
|
+
const lastAssistantMessage = this.conversationMessages
|
|
2928
|
+
.filter(m => m.role === 'assistant' && m.agentRunId)
|
|
2929
|
+
.pop();
|
|
2918
2930
|
if (lastAssistantMessage && lastAssistantMessage.agentRunId) {
|
|
2919
2931
|
this.loadAgentRun(lastAssistantMessage.agentRunId);
|
|
2920
2932
|
this.executionMonitorMode = 'historical';
|
|
@@ -2932,7 +2944,7 @@ export class AITestHarnessComponent {
|
|
|
2932
2944
|
async deleteConversation(conversation, event) {
|
|
2933
2945
|
event.stopPropagation();
|
|
2934
2946
|
if (confirm(`Delete conversation "${conversation.name}"?`)) {
|
|
2935
|
-
const index = this.savedConversations.findIndex(
|
|
2947
|
+
const index = this.savedConversations.findIndex(c => c.id === conversation.id);
|
|
2936
2948
|
if (index >= 0) {
|
|
2937
2949
|
this.savedConversations.splice(index, 1);
|
|
2938
2950
|
// Save to localStorage
|
|
@@ -2953,17 +2965,17 @@ export class AITestHarnessComponent {
|
|
|
2953
2965
|
entity: {
|
|
2954
2966
|
id: this.entity?.ID,
|
|
2955
2967
|
name: this.getEntityName(),
|
|
2956
|
-
type: this.mode
|
|
2968
|
+
type: this.mode
|
|
2957
2969
|
},
|
|
2958
2970
|
messages: this.conversationMessages,
|
|
2959
2971
|
dataContext: this.buildDataContext(),
|
|
2960
|
-
exportedAt: new Date().toISOString()
|
|
2972
|
+
exportedAt: new Date().toISOString()
|
|
2961
2973
|
};
|
|
2962
2974
|
// Add mode-specific data
|
|
2963
2975
|
if (this.mode === 'agent') {
|
|
2964
2976
|
exportData.templateData = this.buildTemplateData();
|
|
2965
2977
|
exportData.agentSettings = {
|
|
2966
|
-
configurationId: this.agentConfigurationId
|
|
2978
|
+
configurationId: this.agentConfigurationId
|
|
2967
2979
|
};
|
|
2968
2980
|
}
|
|
2969
2981
|
else {
|
|
@@ -2973,7 +2985,7 @@ export class AITestHarnessComponent {
|
|
|
2973
2985
|
vendorId: this.selectedVendorId,
|
|
2974
2986
|
configurationId: this.selectedConfigurationId,
|
|
2975
2987
|
maxTokens: this.maxTokens,
|
|
2976
|
-
skipValidation: this.skipValidation
|
|
2988
|
+
skipValidation: this.skipValidation
|
|
2977
2989
|
};
|
|
2978
2990
|
exportData.advancedParams = this.advancedParams;
|
|
2979
2991
|
}
|
|
@@ -3006,7 +3018,7 @@ export class AITestHarnessComponent {
|
|
|
3006
3018
|
}
|
|
3007
3019
|
this.conversationMessages = data.messages.map((msg) => ({
|
|
3008
3020
|
...msg,
|
|
3009
|
-
timestamp: new Date(msg.timestamp)
|
|
3021
|
+
timestamp: new Date(msg.timestamp)
|
|
3010
3022
|
}));
|
|
3011
3023
|
// Import agent variables (unified from dataContext and templateData)
|
|
3012
3024
|
this.agentVariables = [];
|
|
@@ -3015,13 +3027,9 @@ export class AITestHarnessComponent {
|
|
|
3015
3027
|
this.agentVariables.push({
|
|
3016
3028
|
name: key,
|
|
3017
3029
|
value: typeof value === 'object' ? JSON.stringify(value) : String(value),
|
|
3018
|
-
type: typeof value === 'boolean'
|
|
3019
|
-
? '
|
|
3020
|
-
|
|
3021
|
-
? 'number'
|
|
3022
|
-
: typeof value === 'object'
|
|
3023
|
-
? 'object'
|
|
3024
|
-
: 'string',
|
|
3030
|
+
type: typeof value === 'boolean' ? 'boolean' :
|
|
3031
|
+
typeof value === 'number' ? 'number' :
|
|
3032
|
+
typeof value === 'object' ? 'object' : 'string'
|
|
3025
3033
|
});
|
|
3026
3034
|
}
|
|
3027
3035
|
// Template data is already imported into agentVariables above
|
|
@@ -3108,7 +3116,7 @@ export class AITestHarnessComponent {
|
|
|
3108
3116
|
formatTimestamp(date) {
|
|
3109
3117
|
return date.toLocaleTimeString('en-US', {
|
|
3110
3118
|
hour: '2-digit',
|
|
3111
|
-
minute: '2-digit'
|
|
3119
|
+
minute: '2-digit'
|
|
3112
3120
|
});
|
|
3113
3121
|
}
|
|
3114
3122
|
/**
|
|
@@ -3172,7 +3180,7 @@ export class AITestHarnessComponent {
|
|
|
3172
3180
|
// Add agent run ID for reference
|
|
3173
3181
|
const enhancedParsed = {
|
|
3174
3182
|
...parsed,
|
|
3175
|
-
_agentRunID: parsed.agentRunID
|
|
3183
|
+
_agentRunID: parsed.agentRunID
|
|
3176
3184
|
};
|
|
3177
3185
|
this.currentJsonContent = this.formatJson(enhancedParsed);
|
|
3178
3186
|
}
|
|
@@ -3203,7 +3211,7 @@ export class AITestHarnessComponent {
|
|
|
3203
3211
|
resizable: true,
|
|
3204
3212
|
draggable: true,
|
|
3205
3213
|
top: centerTop,
|
|
3206
|
-
left: centerLeft
|
|
3214
|
+
left: centerLeft
|
|
3207
3215
|
});
|
|
3208
3216
|
// Pass the JSON content to the component
|
|
3209
3217
|
const windowContent = this.jsonWindowRef.content.instance;
|
|
@@ -3220,7 +3228,9 @@ export class AITestHarnessComponent {
|
|
|
3220
3228
|
* Get the last run ID from conversation messages
|
|
3221
3229
|
*/
|
|
3222
3230
|
getLastRunId() {
|
|
3223
|
-
const lastAssistantMessage = this.conversationMessages
|
|
3231
|
+
const lastAssistantMessage = this.conversationMessages
|
|
3232
|
+
.filter(m => m.role === 'assistant' && m.agentRunId)
|
|
3233
|
+
.pop();
|
|
3224
3234
|
return lastAssistantMessage?.agentRunId || null;
|
|
3225
3235
|
}
|
|
3226
3236
|
/**
|
|
@@ -3254,7 +3264,9 @@ export class AITestHarnessComponent {
|
|
|
3254
3264
|
async copyMessage(message) {
|
|
3255
3265
|
try {
|
|
3256
3266
|
// Convert content to string if needed
|
|
3257
|
-
const content = typeof message.content === 'string'
|
|
3267
|
+
const content = typeof message.content === 'string'
|
|
3268
|
+
? message.content
|
|
3269
|
+
: JSON.stringify(message.content);
|
|
3258
3270
|
await navigator.clipboard.writeText(content);
|
|
3259
3271
|
MJNotificationService.Instance.CreateSimpleNotification('Message copied to clipboard', 'success', 2000);
|
|
3260
3272
|
}
|
|
@@ -3298,7 +3310,7 @@ export class AITestHarnessComponent {
|
|
|
3298
3310
|
const parseOptions = {
|
|
3299
3311
|
extractInlineJson: true,
|
|
3300
3312
|
maxDepth: 100,
|
|
3301
|
-
debug: false
|
|
3313
|
+
debug: false
|
|
3302
3314
|
};
|
|
3303
3315
|
try {
|
|
3304
3316
|
let parsed;
|
|
@@ -3380,9 +3392,9 @@ export class AITestHarnessComponent {
|
|
|
3380
3392
|
/```[\s\S]*?```/, // Code blocks
|
|
3381
3393
|
/`[^`]+`/, // Inline code
|
|
3382
3394
|
/^[-*+]\s/m, // Lists
|
|
3383
|
-
/^\d+\.\s/m
|
|
3395
|
+
/^\d+\.\s/m // Numbered lists
|
|
3384
3396
|
];
|
|
3385
|
-
if (markdownPatterns.some(
|
|
3397
|
+
if (markdownPatterns.some(pattern => pattern.test(content))) {
|
|
3386
3398
|
return 'markdown';
|
|
3387
3399
|
}
|
|
3388
3400
|
return 'text';
|
|
@@ -3391,7 +3403,9 @@ export class AITestHarnessComponent {
|
|
|
3391
3403
|
// Basic markdown to HTML conversion with improved formatting
|
|
3392
3404
|
let html = content;
|
|
3393
3405
|
// Escape HTML first
|
|
3394
|
-
html = html.replace(/&/g, '&')
|
|
3406
|
+
html = html.replace(/&/g, '&')
|
|
3407
|
+
.replace(/</g, '<')
|
|
3408
|
+
.replace(/>/g, '>');
|
|
3395
3409
|
// Code blocks with language support
|
|
3396
3410
|
html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
|
|
3397
3411
|
const language = lang || '';
|
|
@@ -3481,7 +3495,12 @@ export class AITestHarnessComponent {
|
|
|
3481
3495
|
* Escapes HTML content for use in attributes
|
|
3482
3496
|
*/
|
|
3483
3497
|
escapeHtmlAttribute(text) {
|
|
3484
|
-
return text
|
|
3498
|
+
return text
|
|
3499
|
+
.replace(/&/g, '&')
|
|
3500
|
+
.replace(/"/g, '"')
|
|
3501
|
+
.replace(/'/g, ''')
|
|
3502
|
+
.replace(/</g, '<')
|
|
3503
|
+
.replace(/>/g, '>');
|
|
3485
3504
|
}
|
|
3486
3505
|
/**
|
|
3487
3506
|
* Renders JSON content with human-readable content prominently displayed
|
|
@@ -3522,12 +3541,9 @@ export class AITestHarnessComponent {
|
|
|
3522
3541
|
*/
|
|
3523
3542
|
copyJsonContent() {
|
|
3524
3543
|
if (this.currentJsonContent) {
|
|
3525
|
-
navigator.clipboard
|
|
3526
|
-
.writeText(this.currentJsonContent)
|
|
3527
|
-
.then(() => {
|
|
3544
|
+
navigator.clipboard.writeText(this.currentJsonContent).then(() => {
|
|
3528
3545
|
// Success - JSON copied
|
|
3529
|
-
})
|
|
3530
|
-
.catch((err) => {
|
|
3546
|
+
}).catch((err) => {
|
|
3531
3547
|
// Error copying
|
|
3532
3548
|
});
|
|
3533
3549
|
}
|
|
@@ -3546,14 +3562,15 @@ export class AITestHarnessComponent {
|
|
|
3546
3562
|
return parsed.userMessage;
|
|
3547
3563
|
}
|
|
3548
3564
|
// Priority 2: Check for nested userMessage in nextStep or other objects
|
|
3549
|
-
if (parsed.nextStep &&
|
|
3550
|
-
parsed.nextStep.userMessage &&
|
|
3551
|
-
typeof parsed.nextStep.userMessage === 'string' &&
|
|
3552
|
-
parsed.nextStep.userMessage.trim()) {
|
|
3565
|
+
if (parsed.nextStep && parsed.nextStep.userMessage &&
|
|
3566
|
+
typeof parsed.nextStep.userMessage === 'string' && parsed.nextStep.userMessage.trim()) {
|
|
3553
3567
|
return parsed.nextStep.userMessage;
|
|
3554
3568
|
}
|
|
3555
3569
|
// Priority 3: Other common human-readable fields
|
|
3556
|
-
const contentFields = [
|
|
3570
|
+
const contentFields = [
|
|
3571
|
+
'message', 'content', 'response', 'text', 'output',
|
|
3572
|
+
'result', 'answer', 'reply', 'description', 'summary'
|
|
3573
|
+
];
|
|
3557
3574
|
for (const field of contentFields) {
|
|
3558
3575
|
if (parsed[field] && typeof parsed[field] === 'string' && parsed[field].trim()) {
|
|
3559
3576
|
return parsed[field];
|
|
@@ -3648,22 +3665,18 @@ export class AITestHarnessComponent {
|
|
|
3648
3665
|
if (Array.isArray(obj)) {
|
|
3649
3666
|
if (obj.length === 0)
|
|
3650
3667
|
return '<span class="json-bracket">[]</span>';
|
|
3651
|
-
const items = obj
|
|
3652
|
-
.map((item) => `<div class="json-array-item">${nextIndent}${this.createJsonDisplayHtml(item, depth + 1)}</div>`)
|
|
3653
|
-
.join(',\n');
|
|
3668
|
+
const items = obj.map(item => `<div class="json-array-item">${nextIndent}${this.createJsonDisplayHtml(item, depth + 1)}</div>`).join(',\n');
|
|
3654
3669
|
return `<span class="json-bracket">[</span>\n${items}\n<div class="json-indent">${indent}</div><span class="json-bracket">]</span>`;
|
|
3655
3670
|
}
|
|
3656
3671
|
if (typeof obj === 'object') {
|
|
3657
3672
|
const keys = Object.keys(obj);
|
|
3658
3673
|
if (keys.length === 0)
|
|
3659
3674
|
return '<span class="json-bracket">{}</span>';
|
|
3660
|
-
const properties = keys
|
|
3661
|
-
.map((key) => {
|
|
3675
|
+
const properties = keys.map(key => {
|
|
3662
3676
|
const escapedKey = this.escapeHtml(key);
|
|
3663
3677
|
const value = this.createJsonDisplayHtml(obj[key], depth + 1);
|
|
3664
3678
|
return `<div class="json-property">${nextIndent}<span class="json-key">"${escapedKey}"</span><span class="json-colon">:</span> ${value}</div>`;
|
|
3665
|
-
})
|
|
3666
|
-
.join(',\n');
|
|
3679
|
+
}).join(',\n');
|
|
3667
3680
|
return `<span class="json-bracket">{</span>\n${properties}\n<div class="json-indent">${indent}</div><span class="json-bracket">}</span>`;
|
|
3668
3681
|
}
|
|
3669
3682
|
return String(obj);
|
|
@@ -3734,8 +3747,8 @@ export class AITestHarnessComponent {
|
|
|
3734
3747
|
// Split by comma and trim each sequence
|
|
3735
3748
|
this.advancedParams.stopSequences = this.stopSequencesText
|
|
3736
3749
|
.split(',')
|
|
3737
|
-
.map(
|
|
3738
|
-
.filter(
|
|
3750
|
+
.map(s => s.trim())
|
|
3751
|
+
.filter(s => s.length > 0);
|
|
3739
3752
|
}
|
|
3740
3753
|
}
|
|
3741
3754
|
/**
|
|
@@ -3808,16 +3821,12 @@ export class AITestHarnessComponent {
|
|
|
3808
3821
|
const convertedMessages = chatMessages.map((msg, index) => ({
|
|
3809
3822
|
id: `msg-${Date.now()}-${index}`,
|
|
3810
3823
|
role: msg.role,
|
|
3811
|
-
content: typeof msg.content === 'string'
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
.filter((block) => block.type === 'text')
|
|
3816
|
-
.map((block) => block.content)
|
|
3817
|
-
.join('\n')
|
|
3818
|
-
: '',
|
|
3824
|
+
content: typeof msg.content === 'string' ? msg.content :
|
|
3825
|
+
Array.isArray(msg.content) ?
|
|
3826
|
+
msg.content.filter(block => block.type === 'text').map(block => block.content).join('\n') :
|
|
3827
|
+
'',
|
|
3819
3828
|
timestamp: new Date(),
|
|
3820
|
-
isStreaming: false
|
|
3829
|
+
isStreaming: false
|
|
3821
3830
|
}));
|
|
3822
3831
|
console.log('🎯 Converted messages for test harness:', convertedMessages);
|
|
3823
3832
|
this.conversationMessages = convertedMessages;
|
|
@@ -3903,5 +3912,5 @@ export class AITestHarnessComponent {
|
|
|
3903
3912
|
type: ViewChild,
|
|
3904
3913
|
args: ['saveDialogInput']
|
|
3905
3914
|
}] }); })();
|
|
3906
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AITestHarnessComponent, { className: "AITestHarnessComponent", filePath: "lib/ai-test-harness.component.ts", lineNumber:
|
|
3915
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AITestHarnessComponent, { className: "AITestHarnessComponent", filePath: "lib/ai-test-harness.component.ts", lineNumber: 155 }); })();
|
|
3907
3916
|
//# sourceMappingURL=ai-test-harness.component.js.map
|