@gitsense/gsc-utils 0.2.0 → 0.2.2
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/gsc-utils.cjs.js +352 -37
- package/dist/gsc-utils.esm.js +352 -37
- package/package.json +1 -1
- package/src/AnalyzerUtils/constants.js +17 -0
- package/src/AnalyzerUtils/contextMapper.js +51 -0
- package/src/AnalyzerUtils/dataValidator.js +81 -0
- package/src/AnalyzerUtils/index.js +21 -0
- package/src/AnalyzerUtils/responseProcessor.js +131 -0
- package/src/ChatUtils.js +11 -2
- package/src/GitSenseChatUtils.js +6 -0
package/dist/gsc-utils.esm.js
CHANGED
|
@@ -450,7 +450,7 @@ function parseAnalyzeMessage(messageContent) {
|
|
|
450
450
|
return { id: uniqueAnalyzerId, analyzer, content, instructions };
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
-
var MessageUtils$
|
|
453
|
+
var MessageUtils$3 = {
|
|
454
454
|
deleteMessagesByIds: deleteMessagesByIds$1,
|
|
455
455
|
getChatTemplateMessages: getChatTemplateMessages$1,
|
|
456
456
|
getMessagesBeforeId: getMessagesBeforeId$2,
|
|
@@ -476,7 +476,7 @@ var MessageUtils$2 = {
|
|
|
476
476
|
* Authors: Gemini 2.5 Pro (v1.0.0), Gemini 2.5 Pro (v1.1.0), Gemini 2.5 Flash Thinking (v1.2.0), Gemini 2.5 Flash Thinking (v1.2.1), Gemini 2.5 Flash Thinking (v1.3.0)
|
|
477
477
|
*/
|
|
478
478
|
|
|
479
|
-
const { getMessagesBeforeId: getMessagesBeforeId$1 } = MessageUtils$
|
|
479
|
+
const { getMessagesBeforeId: getMessagesBeforeId$1 } = MessageUtils$3;
|
|
480
480
|
|
|
481
481
|
/**
|
|
482
482
|
* Internal helper function to determine if a chat session matches a specific pattern.
|
|
@@ -528,13 +528,21 @@ function isNewAnalyzerChat(chat, model) {
|
|
|
528
528
|
/**
|
|
529
529
|
* Determines if the current chat session appears to be an "Analyze" session.
|
|
530
530
|
* @param {object} chat - The chat object.
|
|
531
|
-
* @param {string} model - Optional model.
|
|
532
531
|
* @returns {boolean} True if the chat matches the Overview Builder pattern, false otherwise.
|
|
533
532
|
*/
|
|
534
|
-
function isAnalyzeChat(chat
|
|
533
|
+
function isAnalyzeChat(chat) {
|
|
535
534
|
return chat.type === 'analyze';
|
|
536
535
|
}
|
|
537
536
|
|
|
537
|
+
/**
|
|
538
|
+
* Determines if the current chat session appears to be an "Analyze Builder" session.
|
|
539
|
+
* @param {object} chat - The chat object.
|
|
540
|
+
* @returns {boolean} True if the chat matches the Overview Builder pattern, false otherwise.
|
|
541
|
+
*/
|
|
542
|
+
function isAnalyzeBuilderChat(chat) {
|
|
543
|
+
return chat.type === 'analyze-builder';
|
|
544
|
+
}
|
|
545
|
+
|
|
538
546
|
/**
|
|
539
547
|
* Determines if the current chat session appears to be an "Ask" session.
|
|
540
548
|
* @param {object} chat - The chat object.
|
|
@@ -586,6 +594,7 @@ var ChatUtils$1 = {
|
|
|
586
594
|
isAskChat,
|
|
587
595
|
isNewAnalyzerChat,
|
|
588
596
|
isAnalyzeChat,
|
|
597
|
+
isAnalyzeBuilderChat,
|
|
589
598
|
isPlanChat,
|
|
590
599
|
isCodeChat,
|
|
591
600
|
getChatMessages: getChatMessages$1
|
|
@@ -647,7 +656,7 @@ const COMMENT_STYLES$3 = {
|
|
|
647
656
|
'vbscript': { type: 'apostrophe' }
|
|
648
657
|
};
|
|
649
658
|
|
|
650
|
-
var constants$
|
|
659
|
+
var constants$2 = {
|
|
651
660
|
COMMENT_STYLES: COMMENT_STYLES$3
|
|
652
661
|
};
|
|
653
662
|
|
|
@@ -827,7 +836,7 @@ var lineNumberFormatter = {
|
|
|
827
836
|
*/
|
|
828
837
|
|
|
829
838
|
// Dependencies from other modules within CodeBlockUtils
|
|
830
|
-
const { COMMENT_STYLES: COMMENT_STYLES$2 } = constants$
|
|
839
|
+
const { COMMENT_STYLES: COMMENT_STYLES$2 } = constants$2;
|
|
831
840
|
const { removeLineNumbers: removeLineNumbers$9 } = lineNumberFormatter; // Assuming this utility exists
|
|
832
841
|
const { validateUUID: validateUUID$3 } = uuidUtils; // Assuming uuidUtils.js is in the same directory
|
|
833
842
|
|
|
@@ -1449,7 +1458,7 @@ function validateAnalysisMetadata(metadata) {
|
|
|
1449
1458
|
}
|
|
1450
1459
|
|
|
1451
1460
|
|
|
1452
|
-
var AnalysisBlockUtils$
|
|
1461
|
+
var AnalysisBlockUtils$3 = {
|
|
1453
1462
|
isAnalysisBlock,
|
|
1454
1463
|
getAnalysisBlockType,
|
|
1455
1464
|
parseOverviewMetadata: parseOverviewMetadata$1,
|
|
@@ -1782,7 +1791,7 @@ const CONTENT_LINE_REGEX$5 = /^([ +-])\s*[-+]*(\d+):\s?(.*)$/;
|
|
|
1782
1791
|
// Captures: 1: old_start, 2: old_count (optional), 3: new_start, 4: new_count (optional)
|
|
1783
1792
|
const HUNK_HEADER_REGEX$4 = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
|
|
1784
1793
|
|
|
1785
|
-
var constants = {
|
|
1794
|
+
var constants$1 = {
|
|
1786
1795
|
CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$5,
|
|
1787
1796
|
HUNK_HEADER_REGEX: HUNK_HEADER_REGEX$4,
|
|
1788
1797
|
};
|
|
@@ -1799,7 +1808,7 @@ var constants = {
|
|
|
1799
1808
|
*/
|
|
1800
1809
|
|
|
1801
1810
|
const { removeLineNumbers: removeLineNumbers$8 } = lineNumberFormatter; // Assuming this utility exists
|
|
1802
|
-
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$4, HUNK_HEADER_REGEX: HUNK_HEADER_REGEX$3 } = constants;
|
|
1811
|
+
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$4, HUNK_HEADER_REGEX: HUNK_HEADER_REGEX$3 } = constants$1;
|
|
1803
1812
|
|
|
1804
1813
|
|
|
1805
1814
|
/**
|
|
@@ -1964,7 +1973,7 @@ var formatAndAddLineNumbers_1 = {
|
|
|
1964
1973
|
*/
|
|
1965
1974
|
|
|
1966
1975
|
const { removeLineNumbers: removeLineNumbers$7 } = lineNumberFormatter; // Assuming this utility exists
|
|
1967
|
-
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$3 } = constants;
|
|
1976
|
+
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$3 } = constants$1;
|
|
1968
1977
|
const { formatAndAddLineNumbers: formatAndAddLineNumbers$1 } = formatAndAddLineNumbers_1; // Import the helper
|
|
1969
1978
|
|
|
1970
1979
|
|
|
@@ -2217,7 +2226,7 @@ var verifyAndCorrectLineNumbers_1 = {
|
|
|
2217
2226
|
* Authors: Gemini 2.5 Flash Thinking (v1.0.0)
|
|
2218
2227
|
*/
|
|
2219
2228
|
|
|
2220
|
-
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$2, HUNK_HEADER_REGEX: HUNK_HEADER_REGEX$2 } = constants;
|
|
2229
|
+
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$2, HUNK_HEADER_REGEX: HUNK_HEADER_REGEX$2 } = constants$1;
|
|
2221
2230
|
|
|
2222
2231
|
|
|
2223
2232
|
/**
|
|
@@ -2416,7 +2425,7 @@ var verifyAndCorrectHunkHeaders_1 = {
|
|
|
2416
2425
|
* Authors: Gemini 2.5 Flash Thinking (v1.0.0)
|
|
2417
2426
|
*/
|
|
2418
2427
|
|
|
2419
|
-
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$1, HUNK_HEADER_REGEX: HUNK_HEADER_REGEX$1 } = constants;
|
|
2428
|
+
const { CONTENT_LINE_REGEX: CONTENT_LINE_REGEX$1, HUNK_HEADER_REGEX: HUNK_HEADER_REGEX$1 } = constants$1;
|
|
2420
2429
|
|
|
2421
2430
|
|
|
2422
2431
|
/**
|
|
@@ -2819,7 +2828,7 @@ var detectAndFixRedundantChanges_1 = {
|
|
|
2819
2828
|
* Authors: Gemini 2.5 Flash Thinking (v1.0.0)
|
|
2820
2829
|
*/
|
|
2821
2830
|
|
|
2822
|
-
const { CONTENT_LINE_REGEX, HUNK_HEADER_REGEX } = constants;
|
|
2831
|
+
const { CONTENT_LINE_REGEX, HUNK_HEADER_REGEX } = constants$1;
|
|
2823
2832
|
|
|
2824
2833
|
|
|
2825
2834
|
/**
|
|
@@ -8773,7 +8782,7 @@ function formatToolBlock(toolData) {
|
|
|
8773
8782
|
return `# GitSense Chat Tool\n\n${JSON.stringify(toolData, null, 2)}`;
|
|
8774
8783
|
}
|
|
8775
8784
|
|
|
8776
|
-
var GSToolBlockUtils$
|
|
8785
|
+
var GSToolBlockUtils$3 = {
|
|
8777
8786
|
isToolBlock: isToolBlock$1,
|
|
8778
8787
|
parseToolBlock: parseToolBlock$1,
|
|
8779
8788
|
formatToolBlock
|
|
@@ -9067,7 +9076,7 @@ function detectJsonComments$2(jsonString) {
|
|
|
9067
9076
|
return comments;
|
|
9068
9077
|
}
|
|
9069
9078
|
|
|
9070
|
-
var JsonUtils$
|
|
9079
|
+
var JsonUtils$2 = {
|
|
9071
9080
|
detectJsonComments: detectJsonComments$2
|
|
9072
9081
|
};
|
|
9073
9082
|
|
|
@@ -9085,12 +9094,12 @@ var JsonUtils$1 = {
|
|
|
9085
9094
|
const { findAllCodeFences: findAllCodeFences$3, matchFencesAndExtractBlocks: matchFencesAndExtractBlocks$3 } = blockExtractor;
|
|
9086
9095
|
const { parseHeader: parseHeader$2 } = headerUtils;
|
|
9087
9096
|
const { validateUUID: validateUUID$2, generateUUID: generateUUID$2 } = uuidUtils;
|
|
9088
|
-
const AnalysisBlockUtils$
|
|
9097
|
+
const AnalysisBlockUtils$2 = AnalysisBlockUtils$3;
|
|
9089
9098
|
const PatchUtils$1 = PatchUtils$2;
|
|
9090
|
-
const GSToolBlockUtils$
|
|
9099
|
+
const GSToolBlockUtils$2 = GSToolBlockUtils$3;
|
|
9091
9100
|
const { extractContinuationInfo: extractContinuationInfo$2 } = continuationUtils;
|
|
9092
9101
|
const { removeLineNumbers: removeLineNumbers$2 } = lineNumberFormatter;
|
|
9093
|
-
const { detectJsonComments: detectJsonComments$1 } = JsonUtils$
|
|
9102
|
+
const { detectJsonComments: detectJsonComments$1 } = JsonUtils$2;
|
|
9094
9103
|
|
|
9095
9104
|
/**
|
|
9096
9105
|
* Processes a single block's content (internal helper)
|
|
@@ -9111,12 +9120,12 @@ function processBlockContent(content, language, position, incomplete, options =
|
|
|
9111
9120
|
let codeText = content; // Default to all content being code
|
|
9112
9121
|
|
|
9113
9122
|
// Check if this is a GitSense Tool Block *first*
|
|
9114
|
-
if (GSToolBlockUtils$
|
|
9123
|
+
if (GSToolBlockUtils$2.isToolBlock(content)) {
|
|
9115
9124
|
let ignoreDueToComments = false;
|
|
9116
9125
|
let toolData = null;
|
|
9117
9126
|
let toolParseError = null;
|
|
9118
9127
|
try {
|
|
9119
|
-
toolData = GSToolBlockUtils$
|
|
9128
|
+
toolData = GSToolBlockUtils$2.parseToolBlock(content);
|
|
9120
9129
|
} catch (error) {
|
|
9121
9130
|
// When chatting about the tool block, the LLM may add
|
|
9122
9131
|
// add comments in it so let's test for this
|
|
@@ -9150,14 +9159,14 @@ function processBlockContent(content, language, position, incomplete, options =
|
|
|
9150
9159
|
}
|
|
9151
9160
|
|
|
9152
9161
|
// Check if this is an analysis block *next*
|
|
9153
|
-
if (AnalysisBlockUtils$
|
|
9154
|
-
const analysisType = AnalysisBlockUtils$
|
|
9155
|
-
const analysisMetadata = AnalysisBlockUtils$
|
|
9162
|
+
if (AnalysisBlockUtils$2.isAnalysisBlock(content)) {
|
|
9163
|
+
const analysisType = AnalysisBlockUtils$2.getAnalysisBlockType(content);
|
|
9164
|
+
const analysisMetadata = AnalysisBlockUtils$2.parseOverviewMetadata(content);
|
|
9156
9165
|
|
|
9157
9166
|
// Validate the metadata if it was successfully parsed
|
|
9158
9167
|
let validationResult = { isValid: false, errors: ['Failed to parse analysis metadata'] };
|
|
9159
9168
|
if (analysisMetadata) {
|
|
9160
|
-
validationResult = AnalysisBlockUtils$
|
|
9169
|
+
validationResult = AnalysisBlockUtils$2.validateAnalysisMetadata(analysisMetadata);
|
|
9161
9170
|
|
|
9162
9171
|
if (!validationResult.isValid) {
|
|
9163
9172
|
warnings.push({
|
|
@@ -10374,7 +10383,7 @@ var updateCodeBlock_1 = {
|
|
|
10374
10383
|
*/
|
|
10375
10384
|
|
|
10376
10385
|
// Import from individual utility files
|
|
10377
|
-
const { COMMENT_STYLES: COMMENT_STYLES$1 } = constants$
|
|
10386
|
+
const { COMMENT_STYLES: COMMENT_STYLES$1 } = constants$2;
|
|
10378
10387
|
const { generateUUID: generateUUID$1, validateUUID: validateUUID$1 } = uuidUtils;
|
|
10379
10388
|
const { isValidISOTimestamp: isValidISOTimestamp$1, parseHeader: parseHeader$1, getHeaderLineCount } = headerUtils;
|
|
10380
10389
|
const { findAllCodeFences: findAllCodeFences$1, matchFencesAndExtractBlocks: matchFencesAndExtractBlocks$1, extractCodeBlocksWithUUIDs, findCodeBlockByUUID } = blockExtractor;
|
|
@@ -10388,7 +10397,7 @@ const { updateCodeBlockByIndex: updateCodeBlockByIndex$1, updateCodeBlockByUUID,
|
|
|
10388
10397
|
const { formatWithLineNumbers: formatWithLineNumbers$1, formatBlockWithLineNumbers: formatBlockWithLineNumbers$1, formatBlocksWithLineNumbers: formatBlocksWithLineNumbers$1, removeLineNumbers: removeLineNumbers$1 } = lineNumberFormatter;
|
|
10389
10398
|
|
|
10390
10399
|
// Export all imported items
|
|
10391
|
-
var CodeBlockUtils$
|
|
10400
|
+
var CodeBlockUtils$3 = {
|
|
10392
10401
|
// Constants
|
|
10393
10402
|
COMMENT_STYLES: COMMENT_STYLES$1,
|
|
10394
10403
|
|
|
@@ -10455,8 +10464,8 @@ var CodeBlockUtils$2 = {
|
|
|
10455
10464
|
* Authors: Gemini 2.5 Flash Thinking (v1.0.0)
|
|
10456
10465
|
*/
|
|
10457
10466
|
|
|
10458
|
-
const CodeBlockUtils$
|
|
10459
|
-
const MessageUtils$
|
|
10467
|
+
const CodeBlockUtils$2 = CodeBlockUtils$3;
|
|
10468
|
+
const MessageUtils$2 = MessageUtils$3;
|
|
10460
10469
|
|
|
10461
10470
|
/**
|
|
10462
10471
|
* Parses context details from a context message section.
|
|
@@ -10512,7 +10521,7 @@ function parseContextSection(sectionText) {
|
|
|
10512
10521
|
}
|
|
10513
10522
|
});
|
|
10514
10523
|
|
|
10515
|
-
const { blocks, warnings } = CodeBlockUtils$
|
|
10524
|
+
const { blocks, warnings } = CodeBlockUtils$2.extractCodeBlocks(sectionText, { silent: true });
|
|
10516
10525
|
const codeBlocks = blocks.filter(block => block.type === 'code');
|
|
10517
10526
|
|
|
10518
10527
|
if (codeBlocks.length === 0) {
|
|
@@ -10541,7 +10550,7 @@ function parseContextSection(sectionText) {
|
|
|
10541
10550
|
*/
|
|
10542
10551
|
function extractContextSections(messageContent) {
|
|
10543
10552
|
// Use the utility function to validate the message type
|
|
10544
|
-
if (!MessageUtils$
|
|
10553
|
+
if (!MessageUtils$2.isContextMessage(messageContent)) {
|
|
10545
10554
|
throw new Error("Invalid message type: Content is not a context message.");
|
|
10546
10555
|
}
|
|
10547
10556
|
|
|
@@ -10618,12 +10627,312 @@ function extractContextItemsOverviewTableRows(messageContent) {
|
|
|
10618
10627
|
return rows;
|
|
10619
10628
|
}
|
|
10620
10629
|
|
|
10621
|
-
var ContextUtils$
|
|
10630
|
+
var ContextUtils$2 = {
|
|
10622
10631
|
parseContextSection,
|
|
10623
10632
|
extractContextSections,
|
|
10624
10633
|
extractContextItemsOverviewTableRows
|
|
10625
10634
|
};
|
|
10626
10635
|
|
|
10636
|
+
/*
|
|
10637
|
+
* Component: AnalyzerUtils Context Mapper
|
|
10638
|
+
* Block-UUID: 1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d
|
|
10639
|
+
* Parent-UUID: N/A
|
|
10640
|
+
* Version: 1.0.0
|
|
10641
|
+
* Description: Provides utility functions for building a map of chat IDs to file paths from chat context messages.
|
|
10642
|
+
* Language: JavaScript
|
|
10643
|
+
* Created-at: 2025-08-28T15:56:40.319Z
|
|
10644
|
+
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
10645
|
+
*/
|
|
10646
|
+
|
|
10647
|
+
const MessageUtils$1 = MessageUtils$3;
|
|
10648
|
+
const ContextUtils$1 = ContextUtils$2;
|
|
10649
|
+
|
|
10650
|
+
/**
|
|
10651
|
+
* Builds a map of chat IDs to file paths from the context messages within a chat.
|
|
10652
|
+
* This is crucial for validating that the LLM-generated analysis metadata refers to actual files in context.
|
|
10653
|
+
*
|
|
10654
|
+
* @param {Array<Object>} allMessages - An array of all message objects in the chat.
|
|
10655
|
+
* @returns {Map<number, string>} A Map where keys are chat IDs (numbers) and values are file paths (strings).
|
|
10656
|
+
*/
|
|
10657
|
+
function buildChatIdToPathMap$1(allMessages) {
|
|
10658
|
+
const chatIdToPathMap = new Map();
|
|
10659
|
+
|
|
10660
|
+
for (const msg of allMessages) {
|
|
10661
|
+
const content = msg.message;
|
|
10662
|
+
if (MessageUtils$1.isContextMessage(content)) {
|
|
10663
|
+
try {
|
|
10664
|
+
const contextSections = ContextUtils$1.extractContextSections(content);
|
|
10665
|
+
|
|
10666
|
+
for (const section of contextSections) {
|
|
10667
|
+
const chatId = section['chat id'];
|
|
10668
|
+
const path = section.path;
|
|
10669
|
+
|
|
10670
|
+
if (chatId && path) {
|
|
10671
|
+
chatIdToPathMap.set(chatId, path);
|
|
10672
|
+
}
|
|
10673
|
+
}
|
|
10674
|
+
} catch (error) {
|
|
10675
|
+
console.warn("AnalyzerUtils/contextMapper: Error parsing context message for map building:", error);
|
|
10676
|
+
// Continue processing other messages
|
|
10677
|
+
}
|
|
10678
|
+
}
|
|
10679
|
+
}
|
|
10680
|
+
return chatIdToPathMap;
|
|
10681
|
+
}
|
|
10682
|
+
|
|
10683
|
+
var contextMapper = {
|
|
10684
|
+
buildChatIdToPathMap: buildChatIdToPathMap$1
|
|
10685
|
+
};
|
|
10686
|
+
|
|
10687
|
+
/*
|
|
10688
|
+
* Component: AnalyzerUtils Constants
|
|
10689
|
+
* Block-UUID: 01b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d
|
|
10690
|
+
* Parent-UUID: N/A
|
|
10691
|
+
* Version: 1.0.0
|
|
10692
|
+
* Description: Defines constants specific to the AnalyzerUtils module.
|
|
10693
|
+
* Language: JavaScript
|
|
10694
|
+
* Created-at: 2025-08-28T15:56:40.319Z
|
|
10695
|
+
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
10696
|
+
*/
|
|
10697
|
+
|
|
10698
|
+
const ANALYZE_HEADER_PREFIX$1 = '# GitSense Chat Analysis';
|
|
10699
|
+
|
|
10700
|
+
var constants = {
|
|
10701
|
+
ANALYZE_HEADER_PREFIX: ANALYZE_HEADER_PREFIX$1
|
|
10702
|
+
};
|
|
10703
|
+
|
|
10704
|
+
/*
|
|
10705
|
+
* Component: AnalyzerUtils Response Processor
|
|
10706
|
+
* Block-UUID: 2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d
|
|
10707
|
+
* Parent-UUID: N/A
|
|
10708
|
+
* Version: 1.0.0
|
|
10709
|
+
* Description: Extracts and performs initial validation of analysis and metadata code blocks from raw LLM message content.
|
|
10710
|
+
* Language: JavaScript
|
|
10711
|
+
* Created-at: 2025-08-28T15:56:40.319Z
|
|
10712
|
+
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
10713
|
+
*/
|
|
10714
|
+
|
|
10715
|
+
const CodeBlockUtils$1 = CodeBlockUtils$3;
|
|
10716
|
+
const GSToolBlockUtils$1 = GSToolBlockUtils$3;
|
|
10717
|
+
const JsonUtils$1 = JsonUtils$2;
|
|
10718
|
+
const { ANALYZE_HEADER_PREFIX } = constants;
|
|
10719
|
+
|
|
10720
|
+
/**
|
|
10721
|
+
* Extracts code blocks from the message content, identifies analysis and metadata blocks,
|
|
10722
|
+
* and performs initial validation (block type, metadata presence, JSON format).
|
|
10723
|
+
* This function is adapted from the original `blockProcessing.js` in `gsc-conversation-view`.
|
|
10724
|
+
*
|
|
10725
|
+
* @param {string} messageContent - The full content of the message.
|
|
10726
|
+
* @param {boolean} stoppedStreaming - Flag indicating if the message streaming has stopped.
|
|
10727
|
+
* @returns {{analysisBlocks: Array<Object>, analysisMetadataBlocks: Array<Object|null>, error: string|null}}
|
|
10728
|
+
* An object containing the extracted blocks and any processing error.
|
|
10729
|
+
*/
|
|
10730
|
+
function processLLMAnalysisResponse$1(messageContent, stoppedStreaming) {
|
|
10731
|
+
const silent = { silent: true };
|
|
10732
|
+
const { blocks, warnings } = CodeBlockUtils$1.extractCodeBlocks(messageContent, silent);
|
|
10733
|
+
|
|
10734
|
+
const analysisBlocks = [];
|
|
10735
|
+
const analysisMetadataBlocks = [];
|
|
10736
|
+
let error = null;
|
|
10737
|
+
|
|
10738
|
+
for (let i = 0; i < blocks.length; i += 2) {
|
|
10739
|
+
const analysisBlock = blocks[i];
|
|
10740
|
+
|
|
10741
|
+
// Make sure this is an analysis block by checking its content
|
|
10742
|
+
if (!analysisBlock.content.trimStart().startsWith(ANALYZE_HEADER_PREFIX)) {
|
|
10743
|
+
// Also check if it's a GitSense Tool Block, which should be ignored by this analyzer
|
|
10744
|
+
if (GSToolBlockUtils$1.isToolBlock(analysisBlock.content)) {
|
|
10745
|
+
// If it's a tool block, it's not an analysis block, so skip it and don't treat as error
|
|
10746
|
+
// Adjust index to skip this block and its potential "metadata" if it was paired
|
|
10747
|
+
if (blocks[i+1] && blocks[i+1].language === 'json') {
|
|
10748
|
+
i += 1; // Skip the next block too if it's a JSON block (likely tool config)
|
|
10749
|
+
}
|
|
10750
|
+
continue;
|
|
10751
|
+
}
|
|
10752
|
+
|
|
10753
|
+
if (stoppedStreaming) {
|
|
10754
|
+
error = `Analysis block #${i} does not start with the "${ANALYZE_HEADER_PREFIX}" header.`;
|
|
10755
|
+
}
|
|
10756
|
+
// If we are still streaming, we may not have enough information to tell what type
|
|
10757
|
+
// of block this is, so stop looking
|
|
10758
|
+
break;
|
|
10759
|
+
}
|
|
10760
|
+
|
|
10761
|
+
// Add the analysis block (Markdown overview)
|
|
10762
|
+
analysisBlocks.push(analysisBlock);
|
|
10763
|
+
|
|
10764
|
+
// Make sure there is an analysis metadata block (JSON)
|
|
10765
|
+
const analysisMetadataBlock = blocks[i + 1];
|
|
10766
|
+
|
|
10767
|
+
if (!analysisMetadataBlock) {
|
|
10768
|
+
if (stoppedStreaming) {
|
|
10769
|
+
error = `No analysis metadata found for analysis block (index ${i}).`;
|
|
10770
|
+
} else {
|
|
10771
|
+
// Add a null metadata block to let use know we are still streaming
|
|
10772
|
+
analysisMetadataBlocks.push(null);
|
|
10773
|
+
}
|
|
10774
|
+
break;
|
|
10775
|
+
}
|
|
10776
|
+
|
|
10777
|
+
// We found a code block but we don't know if it is valid or not
|
|
10778
|
+
// 1. First make sure the code block is a JSON type
|
|
10779
|
+
// 2. Try to parse the JSON
|
|
10780
|
+
if (analysisMetadataBlock.language !== 'json') {
|
|
10781
|
+
if (stoppedStreaming) {
|
|
10782
|
+
error = `Analysis metadata block for "${analysisBlock.overviewMetadata?.Path || 'Unknown Path'}" has invalid language "${analysisMetadataBlock.language}". Expected "json".`;
|
|
10783
|
+
} else {
|
|
10784
|
+
// Add a null metadata block to let use know we are still streaming
|
|
10785
|
+
analysisMetadataBlocks.push(null);
|
|
10786
|
+
}
|
|
10787
|
+
break;
|
|
10788
|
+
}
|
|
10789
|
+
|
|
10790
|
+
try {
|
|
10791
|
+
// Check for comments within JSON, which would make it invalid for direct parsing
|
|
10792
|
+
const comments = JsonUtils$1.detectJsonComments(analysisMetadataBlock.content);
|
|
10793
|
+
if (comments.length > 0) {
|
|
10794
|
+
error = `The analysis metadata block for "${analysisBlock.overviewMetadata?.Path || 'Unknown Path'}" contains comments, which makes it invalid JSON.`;
|
|
10795
|
+
if (stoppedStreaming || blocks[i + 2]) { // If streaming stopped or not the last block
|
|
10796
|
+
break;
|
|
10797
|
+
} else {
|
|
10798
|
+
analysisMetadataBlocks.push(null); // Add null to keep arrays aligned
|
|
10799
|
+
return { analysisBlocks, analysisMetadataBlocks, error: null };
|
|
10800
|
+
}
|
|
10801
|
+
}
|
|
10802
|
+
|
|
10803
|
+
JSON.parse(analysisMetadataBlock.content.trim());
|
|
10804
|
+
analysisMetadataBlocks.push(analysisMetadataBlock);
|
|
10805
|
+
} catch (err) {
|
|
10806
|
+
const path = analysisBlock.overviewMetadata?.Path || 'Unknown Path';
|
|
10807
|
+
error = `The analysis metadata block for "${path}" contains an invalid JSON: ${err.message}`;
|
|
10808
|
+
|
|
10809
|
+
// If streaming has stopped or if this is not the last block, set error and break.
|
|
10810
|
+
// Remember to increment by two since every second block is the meta block.
|
|
10811
|
+
if (stoppedStreaming || blocks[i + 2]) {
|
|
10812
|
+
break;
|
|
10813
|
+
} else {
|
|
10814
|
+
// Do nothing since the error is most certaintly due to the fact that we are still
|
|
10815
|
+
// streaming the JSON
|
|
10816
|
+
analysisMetadataBlocks.push(null); // Add null to keep arrays aligned
|
|
10817
|
+
return { analysisBlocks, analysisMetadataBlocks, error: null };
|
|
10818
|
+
}
|
|
10819
|
+
}
|
|
10820
|
+
}
|
|
10821
|
+
|
|
10822
|
+
// If streaming stopped and no overview blocks were found, set an error
|
|
10823
|
+
if (stoppedStreaming && analysisBlocks.length === 0) {
|
|
10824
|
+
error = 'Analysis stopped without producing any data.';
|
|
10825
|
+
}
|
|
10826
|
+
|
|
10827
|
+
return { analysisBlocks, analysisMetadataBlocks, error };
|
|
10828
|
+
}
|
|
10829
|
+
|
|
10830
|
+
var responseProcessor = {
|
|
10831
|
+
processLLMAnalysisResponse: processLLMAnalysisResponse$1
|
|
10832
|
+
};
|
|
10833
|
+
|
|
10834
|
+
/*
|
|
10835
|
+
* Component: AnalyzerUtils Data Validator
|
|
10836
|
+
* Block-UUID: 1317cc51-fca0-49b7-9e4b-b3e1a06ab93f
|
|
10837
|
+
* Parent-UUID: N/A
|
|
10838
|
+
* Version: 1.0.0
|
|
10839
|
+
* Description: Validates extracted analysis data against chat context and expected schema.
|
|
10840
|
+
* Language: JavaScript
|
|
10841
|
+
* Created-at: 2025-08-28T15:56:40.319Z
|
|
10842
|
+
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
10843
|
+
*/
|
|
10844
|
+
|
|
10845
|
+
const AnalysisBlockUtils$1 = AnalysisBlockUtils$3;
|
|
10846
|
+
|
|
10847
|
+
/**
|
|
10848
|
+
* Validates the extracted analysis blocks and their metadata.
|
|
10849
|
+
* Checks for valid chat IDs/paths and uses AnalysisBlockUtils for further metadata validation.
|
|
10850
|
+
* This function is adapted from the original `analysisValidation.js` in `gsc-conversation-view`.
|
|
10851
|
+
*
|
|
10852
|
+
* @param {Array<Object>} analysisBlocks - Array of extracted analysis code blocks (Markdown overviews).
|
|
10853
|
+
* @param {Array<Object|null>} analysisMetadataBlocks - Array of extracted analysis metadata blocks (JSON).
|
|
10854
|
+
* @param {Map<number, string>} chatIdToPathMap - Map of chat IDs to file paths from context messages.
|
|
10855
|
+
* @returns {{validAnalysisData: Array<Object>, invalidAnalysisBlocks: Array<string|Object>}}
|
|
10856
|
+
* An object containing arrays of valid analysis data and invalid analysis blocks.
|
|
10857
|
+
*/
|
|
10858
|
+
function validateLLMAnalysisData$1(analysisBlocks, analysisMetadataBlocks, chatIdToPathMap) {
|
|
10859
|
+
const validAnalysisData = []; // Store data for the "Save All" button
|
|
10860
|
+
const invalidAnalysisBlocks = []; // Store invalid analysis blocks
|
|
10861
|
+
|
|
10862
|
+
analysisBlocks.forEach((block, index) => {
|
|
10863
|
+
// Ensure metadata is parsed from the block's content for initial checks
|
|
10864
|
+
const overviewMetadata = AnalysisBlockUtils$1.parseOverviewMetadata(block.content);
|
|
10865
|
+
const metadataBlock = analysisMetadataBlocks[index];
|
|
10866
|
+
const isDone = metadataBlock ? true : false; // Check if metadata block was successfully processed
|
|
10867
|
+
|
|
10868
|
+
// Skip if metadata block is missing (still streaming or error)
|
|
10869
|
+
if (!overviewMetadata || !isDone) {
|
|
10870
|
+
// If metadata block is missing but streaming stopped, it's an error handled in responseProcessor
|
|
10871
|
+
// If overviewMetadata is missing, it's an error handled in responseProcessor
|
|
10872
|
+
return;
|
|
10873
|
+
}
|
|
10874
|
+
|
|
10875
|
+
const chatId = overviewMetadata['Chat ID'];
|
|
10876
|
+
const path = overviewMetadata['Path'];
|
|
10877
|
+
|
|
10878
|
+
// Is this a valid chat id and path id? Some LLMs will actually hallucinate this
|
|
10879
|
+
if (!chatId || !path || !chatIdToPathMap.has(chatId)) {
|
|
10880
|
+
invalidAnalysisBlocks.push(`<li>#${chatId || 'N/A'} => ${path || 'N/A'} (Invalid Chat ID or Path)</li>`);
|
|
10881
|
+
return;
|
|
10882
|
+
}
|
|
10883
|
+
|
|
10884
|
+
// Perform detailed metadata validation using AnalysisBlockUtils
|
|
10885
|
+
const validation = AnalysisBlockUtils$1.validateAnalysisMetadata(overviewMetadata);
|
|
10886
|
+
|
|
10887
|
+
if (validation.isValid) {
|
|
10888
|
+
// Prepare data for API call (map keys if necessary)
|
|
10889
|
+
const analysisData = {
|
|
10890
|
+
chatId: overviewMetadata['Chat ID'],
|
|
10891
|
+
// The original analyzeHandler used 'Message ID', 'Repository', 'Summarized At', 'Analyze At',
|
|
10892
|
+
// 'Summary', 'Key Functionality', 'Keywords' from overviewMetadata.
|
|
10893
|
+
// For batch processing, we primarily need chatId, content, and the full JSON metadata.
|
|
10894
|
+
// The other fields can be derived from the full JSON metadata if needed.
|
|
10895
|
+
path: overviewMetadata['Path'],
|
|
10896
|
+
content: block.content, // The full Markdown overview
|
|
10897
|
+
type: AnalysisBlockUtils$1.getAnalysisBlockType(block.content), // e.g., 'tiny-overview::file-content::default'
|
|
10898
|
+
// We know metadataBlock.content is a valid JSON from responseProcessor
|
|
10899
|
+
metadata: JSON.parse(metadataBlock.content) // The full JSON metadata object
|
|
10900
|
+
};
|
|
10901
|
+
validAnalysisData.push(analysisData); // Add to list for saving
|
|
10902
|
+
} else {
|
|
10903
|
+
// Add invalid analysis block with validation details
|
|
10904
|
+
invalidAnalysisBlocks.push({ block, validation });
|
|
10905
|
+
}
|
|
10906
|
+
});
|
|
10907
|
+
|
|
10908
|
+
return { validAnalysisData, invalidAnalysisBlocks };
|
|
10909
|
+
}
|
|
10910
|
+
|
|
10911
|
+
var dataValidator = {
|
|
10912
|
+
validateLLMAnalysisData: validateLLMAnalysisData$1
|
|
10913
|
+
};
|
|
10914
|
+
|
|
10915
|
+
/*
|
|
10916
|
+
* Component: AnalyzerUtils Index
|
|
10917
|
+
* Block-UUID: b403b6a1-230b-4247-8cd6-2a3d068f4bbf
|
|
10918
|
+
* Parent-UUID: N/A
|
|
10919
|
+
* Version: 1.0.0
|
|
10920
|
+
* Description: Aggregates and exports all utility functions from the AnalyzerUtils module.
|
|
10921
|
+
* Language: JavaScript
|
|
10922
|
+
* Created-at: 2025-08-28T15:56:40.319Z
|
|
10923
|
+
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
10924
|
+
*/
|
|
10925
|
+
|
|
10926
|
+
const { buildChatIdToPathMap } = contextMapper;
|
|
10927
|
+
const { processLLMAnalysisResponse } = responseProcessor;
|
|
10928
|
+
const { validateLLMAnalysisData } = dataValidator;
|
|
10929
|
+
|
|
10930
|
+
var AnalyzerUtils$1 = {
|
|
10931
|
+
buildChatIdToPathMap,
|
|
10932
|
+
processLLMAnalysisResponse,
|
|
10933
|
+
validateLLMAnalysisData
|
|
10934
|
+
};
|
|
10935
|
+
|
|
10627
10936
|
/**
|
|
10628
10937
|
* Component: LLMUtils
|
|
10629
10938
|
* Block-UUID: a3106054-42f1-474f-96f3-182d66eb19a0
|
|
@@ -10667,14 +10976,15 @@ var LLMUtils$1 = {
|
|
|
10667
10976
|
*/
|
|
10668
10977
|
|
|
10669
10978
|
const ChatUtils = ChatUtils$1;
|
|
10670
|
-
const CodeBlockUtils = CodeBlockUtils$
|
|
10671
|
-
const ContextUtils = ContextUtils$
|
|
10672
|
-
const MessageUtils = MessageUtils$
|
|
10673
|
-
const AnalysisBlockUtils = AnalysisBlockUtils$
|
|
10979
|
+
const CodeBlockUtils = CodeBlockUtils$3;
|
|
10980
|
+
const ContextUtils = ContextUtils$2;
|
|
10981
|
+
const MessageUtils = MessageUtils$3;
|
|
10982
|
+
const AnalysisBlockUtils = AnalysisBlockUtils$3;
|
|
10983
|
+
const AnalyzerUtils = AnalyzerUtils$1;
|
|
10674
10984
|
const PatchUtils = PatchUtils$2;
|
|
10675
|
-
const GSToolBlockUtils = GSToolBlockUtils$
|
|
10985
|
+
const GSToolBlockUtils = GSToolBlockUtils$3;
|
|
10676
10986
|
const LLMUtils = LLMUtils$1;
|
|
10677
|
-
const JsonUtils = JsonUtils$
|
|
10987
|
+
const JsonUtils = JsonUtils$2;
|
|
10678
10988
|
|
|
10679
10989
|
const {
|
|
10680
10990
|
estimateTokens
|
|
@@ -11016,6 +11326,11 @@ var GitSenseChatUtils_1 = {
|
|
|
11016
11326
|
parseOverviewMetadata,
|
|
11017
11327
|
validateOverviewMetadata,
|
|
11018
11328
|
|
|
11329
|
+
// Analyzer Utilities
|
|
11330
|
+
buildChatIdToPathMap: AnalyzerUtils.buildChatIdToPathMap,
|
|
11331
|
+
processLLMAnalysisResponse: AnalyzerUtils.processLLMAnalysisResponse,
|
|
11332
|
+
validateLLMAnalysisData: AnalyzerUtils.validateLLMAnalysisData,
|
|
11333
|
+
|
|
11019
11334
|
// ChatUtils
|
|
11020
11335
|
getChatMessages,
|
|
11021
11336
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Component: AnalyzerUtils Constants
|
|
3
|
+
* Block-UUID: 01b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d
|
|
4
|
+
* Parent-UUID: N/A
|
|
5
|
+
* Version: 1.0.0
|
|
6
|
+
* Description: Defines constants specific to the AnalyzerUtils module.
|
|
7
|
+
* Language: JavaScript
|
|
8
|
+
* Created-at: 2025-08-28T15:56:40.319Z
|
|
9
|
+
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const ANALYZE_HEADER_PREFIX = '# GitSense Chat Analysis';
|
|
14
|
+
|
|
15
|
+
module.exports = {
|
|
16
|
+
ANALYZE_HEADER_PREFIX
|
|
17
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Component: AnalyzerUtils Context Mapper
|
|
3
|
+
* Block-UUID: 1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d
|
|
4
|
+
* Parent-UUID: N/A
|
|
5
|
+
* Version: 1.0.0
|
|
6
|
+
* Description: Provides utility functions for building a map of chat IDs to file paths from chat context messages.
|
|
7
|
+
* Language: JavaScript
|
|
8
|
+
* Created-at: 2025-08-28T15:56:40.319Z
|
|
9
|
+
* Authors: Gemini 2.5 Flash (v1.0.0)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const MessageUtils = require('../MessageUtils');
|
|
14
|
+
const ContextUtils = require('../ContextUtils');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Builds a map of chat IDs to file paths from the context messages within a chat.
|
|
18
|
+
* This is crucial for validating that the LLM-generated analysis metadata refers to actual files in context.
|
|
19
|
+
*
|
|
20
|
+
* @param {Array<Object>} allMessages - An array of all message objects in the chat.
|
|
21
|
+
* @returns {Map<number, string>} A Map where keys are chat IDs (numbers) and values are file paths (strings).
|
|
22
|
+
*/
|
|
23
|
+
function buildChatIdToPathMap(allMessages) {
|
|
24
|
+
const chatIdToPathMap = new Map();
|
|
25
|
+
|
|
26
|
+
for (const msg of allMessages) {
|
|
27
|
+
const content = msg.message;
|
|
28
|
+
if (MessageUtils.isContextMessage(content)) {
|
|
29
|
+
try {
|
|
30
|
+
const contextSections = ContextUtils.extractContextSections(content);
|
|
31
|
+
|
|
32
|
+
for (const section of contextSections) {
|
|
33
|
+
const chatId = section['chat id'];
|
|
34
|
+
const path = section.path;
|
|
35
|
+
|
|
36
|
+
if (chatId && path) {
|
|
37
|
+
chatIdToPathMap.set(chatId, path);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.warn("AnalyzerUtils/contextMapper: Error parsing context message for map building:", error);
|
|
42
|
+
// Continue processing other messages
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return chatIdToPathMap;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
module.exports = {
|
|
50
|
+
buildChatIdToPathMap
|
|
51
|
+
};
|