copilot-chat-analyzer 0.0.1 → 0.0.3
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/AI_USAGE.md +93 -0
- package/README.md +94 -14
- package/dist/index.cjs +224 -0
- package/dist/index.d.cts +47 -1
- package/dist/index.d.ts +47 -1
- package/dist/index.mjs +126 -4
- package/package.json +45 -6
- package/dist/index.js +0 -102
package/AI_USAGE.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# AI Usage Guide for copilot-chat-analyzer
|
|
2
|
+
|
|
3
|
+
This is a TypeScript/JavaScript library for analyzing GitHub Copilot chat exports.
|
|
4
|
+
|
|
5
|
+
## Quick Start for AI Assistants
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import CopilotChatAnalyzer, { DialogStatus } from "copilot-chat-analyzer";
|
|
9
|
+
import { readFileSync } from "fs";
|
|
10
|
+
|
|
11
|
+
// Load chat data from JSON export
|
|
12
|
+
const chatData = JSON.parse(readFileSync("chat.json", "utf8"));
|
|
13
|
+
const analyzer = new CopilotChatAnalyzer();
|
|
14
|
+
|
|
15
|
+
// Basic analysis
|
|
16
|
+
const status = analyzer.getDialogStatus(chatData);
|
|
17
|
+
const requestCount = analyzer.getRequestsCount(chatData);
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Core Methods
|
|
21
|
+
|
|
22
|
+
### getDialogStatus(chatData)
|
|
23
|
+
|
|
24
|
+
Returns one of four status strings:
|
|
25
|
+
|
|
26
|
+
- `"pending"` - Chat created but no requests made (empty requests array)
|
|
27
|
+
- `"in_progress"` - Chat has requests but not completed
|
|
28
|
+
- `"completed"` - Chat finished successfully (has followups: [])
|
|
29
|
+
- `"canceled"` - Chat was canceled (isCanceled: true)
|
|
30
|
+
|
|
31
|
+
### getRequestsCount(chatData)
|
|
32
|
+
|
|
33
|
+
Returns number of requests in the chat.
|
|
34
|
+
|
|
35
|
+
### getDialogStatusDetails(chatData)
|
|
36
|
+
|
|
37
|
+
Returns detailed object:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
{
|
|
41
|
+
status: DialogStatusType,
|
|
42
|
+
statusText: string, // Human readable status
|
|
43
|
+
hasResult: boolean, // Has result data
|
|
44
|
+
hasFollowups: boolean, // Has followups property
|
|
45
|
+
isCanceled: boolean, // Was canceled
|
|
46
|
+
lastRequestId?: string // ID of last request
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### getMcpToolMonitoring(chatData, toolName?)
|
|
51
|
+
|
|
52
|
+
Monitor MCP (Model Context Protocol) tool usage:
|
|
53
|
+
|
|
54
|
+
- Without toolName: Returns summary of all tools
|
|
55
|
+
- With toolName: Returns detailed stats for specific tool
|
|
56
|
+
|
|
57
|
+
## Chat Data Structure
|
|
58
|
+
|
|
59
|
+
Expected JSON structure from GitHub Copilot export:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
{
|
|
63
|
+
requesterUsername: string,
|
|
64
|
+
responderUsername: string,
|
|
65
|
+
requests: Array<{
|
|
66
|
+
requestId: string,
|
|
67
|
+
isCanceled?: boolean,
|
|
68
|
+
followups?: any[],
|
|
69
|
+
result?: any,
|
|
70
|
+
response?: any[]
|
|
71
|
+
}>
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Status Detection Logic
|
|
76
|
+
|
|
77
|
+
1. No requests or empty array → `"pending"`
|
|
78
|
+
2. Last request has `isCanceled: true` → `"canceled"`
|
|
79
|
+
3. Last request has `followups: []` (empty array) → `"completed"`
|
|
80
|
+
4. Otherwise → `"in_progress"`
|
|
81
|
+
|
|
82
|
+
## MCP Tool Analysis
|
|
83
|
+
|
|
84
|
+
The library can extract and analyze Model Context Protocol tool calls from chat responses, providing:
|
|
85
|
+
|
|
86
|
+
- Tool success rates
|
|
87
|
+
- Call counts
|
|
88
|
+
- Input/output data
|
|
89
|
+
- Error tracking
|
|
90
|
+
|
|
91
|
+
## Examples Directory
|
|
92
|
+
|
|
93
|
+
Check `/examples` folder for complete usage examples with sample data.
|
package/README.md
CHANGED
|
@@ -4,14 +4,39 @@
|
|
|
4
4
|
[](https://github.com/dealenx/copilot-chat-analyzer/actions/workflows/quality.yml)
|
|
5
5
|
[](https://badge.fury.io/js/copilot-chat-analyzer)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
TypeScript библиотека для анализа экспортированных чатов GitHub Copilot с поддержкой мониторинга MCP инструментов.
|
|
8
|
+
|
|
9
|
+
## 🤖 AI Assistant Quick Reference
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// Basic import and usage
|
|
13
|
+
import CopilotChatAnalyzer, { DialogStatus } from "copilot-chat-analyzer";
|
|
14
|
+
|
|
15
|
+
const analyzer = new CopilotChatAnalyzer();
|
|
16
|
+
const chatData = JSON.parse(fs.readFileSync("chat.json", "utf8"));
|
|
17
|
+
|
|
18
|
+
// Core methods:
|
|
19
|
+
analyzer.getDialogStatus(chatData); // Returns: 'pending' | 'in_progress' | 'completed' | 'canceled'
|
|
20
|
+
analyzer.getRequestsCount(chatData); // Returns: number
|
|
21
|
+
analyzer.getDialogStatusDetails(chatData); // Returns: { status, statusText, hasResult, hasFollowups, isCanceled, lastRequestId }
|
|
22
|
+
analyzer.getMcpToolMonitoring(chatData); // Returns: MCP tool usage statistics
|
|
23
|
+
|
|
24
|
+
// Dialog statuses:
|
|
25
|
+
// - 'pending': Empty requests array, chat not started
|
|
26
|
+
// - 'in_progress': Has requests but not finished
|
|
27
|
+
// - 'completed': Has followups:[] and not canceled
|
|
28
|
+
// - 'canceled': isCanceled:true in last request
|
|
29
|
+
```
|
|
8
30
|
|
|
9
31
|
## Особенности
|
|
10
32
|
|
|
11
|
-
- 📊
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
33
|
+
- 📊 **Анализ статусов диалога** - автоматическое определение состояния чата
|
|
34
|
+
- 🔢 **Подсчет запросов** - точный подсчет количества запросов в диалоге
|
|
35
|
+
- 🔍 **Детальная диагностика** - получение развернутой информации о статусе
|
|
36
|
+
- �️ **MCP мониторинг** - отслеживание использования Model Context Protocol инструментов
|
|
37
|
+
- 📈 **Статистика успешности** - анализ успешности выполнения MCP вызовов
|
|
38
|
+
- 🚀 **Простой API** - интуитивно понятный интерфейс
|
|
39
|
+
- 💪 **TypeScript** - полная поддержка типов
|
|
15
40
|
|
|
16
41
|
## Установка
|
|
17
42
|
|
|
@@ -31,6 +56,17 @@ yarn add copilot-chat-analyzer
|
|
|
31
56
|
pnpm add copilot-chat-analyzer
|
|
32
57
|
```
|
|
33
58
|
|
|
59
|
+
## Как экспортировать чат
|
|
60
|
+
|
|
61
|
+
Для получения данных чата из GitHub Copilot Chat:
|
|
62
|
+
|
|
63
|
+
1. **Откройте VS Code** с установленным GitHub Copilot Chat
|
|
64
|
+
2. **Откройте панель чата** (обычно справа или через `Ctrl+Shift+I`)
|
|
65
|
+
3. **Ведите диалог** с Copilot
|
|
66
|
+
4. **Нажмите `F1`** для открытия Command Palette
|
|
67
|
+
5. **Введите и выберите** `"Export Chat"`
|
|
68
|
+
6. **Сохраните файл** в формате JSON
|
|
69
|
+
|
|
34
70
|
## 🚀 Использование
|
|
35
71
|
|
|
36
72
|
### Основной API
|
|
@@ -48,7 +84,7 @@ console.log(`Количество запросов: ${requestsCount}`);
|
|
|
48
84
|
|
|
49
85
|
// Определение статуса диалога
|
|
50
86
|
const status = analyzer.getDialogStatus(chatData);
|
|
51
|
-
console.log(`Статус: ${status}`); // 'completed', 'canceled', 'in_progress'
|
|
87
|
+
console.log(`Статус: ${status}`); // 'pending', 'completed', 'canceled', 'in_progress'
|
|
52
88
|
|
|
53
89
|
// Получение детальной информации о статусе
|
|
54
90
|
const details = analyzer.getDialogStatusDetails(chatData);
|
|
@@ -62,8 +98,43 @@ console.log({
|
|
|
62
98
|
});
|
|
63
99
|
```
|
|
64
100
|
|
|
101
|
+
### Мониторинг MCP инструментов
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
// Получить список всех MCP инструментов в чате
|
|
105
|
+
const toolNames = analyzer.getMcpToolNames(chatData);
|
|
106
|
+
console.log("Инструменты:", toolNames);
|
|
107
|
+
|
|
108
|
+
// Получить все вызовы конкретного инструмента
|
|
109
|
+
const calls = analyzer.getMcpToolCalls(chatData, "update_entry_fields");
|
|
110
|
+
calls.forEach((call, i) => {
|
|
111
|
+
console.log(
|
|
112
|
+
`${i + 1}. ${call.isError ? "❌ Ошибка" : "✅ Успех"}: ${JSON.stringify(
|
|
113
|
+
call.input
|
|
114
|
+
)}`
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// Получить только успешные или только ошибочные вызовы
|
|
119
|
+
const successCalls = analyzer.getMcpToolSuccessfulCalls(
|
|
120
|
+
chatData,
|
|
121
|
+
"update_entry_fields"
|
|
122
|
+
);
|
|
123
|
+
const errorCalls = analyzer.getMcpToolErrorCalls(
|
|
124
|
+
chatData,
|
|
125
|
+
"update_entry_fields"
|
|
126
|
+
);
|
|
127
|
+
```
|
|
128
|
+
|
|
65
129
|
## Статусы диалога
|
|
66
130
|
|
|
131
|
+
Библиотека автоматически определяет текущий статус чата при экспорте:
|
|
132
|
+
|
|
133
|
+
- **`DialogStatus.PENDING`** (`"pending"`) - Диалог еще не начат
|
|
134
|
+
|
|
135
|
+
- Массив `requests` пустой или отсутствует
|
|
136
|
+
- Еще не было сделано ни одного запроса к Copilot
|
|
137
|
+
|
|
67
138
|
- **`DialogStatus.COMPLETED`** (`"completed"`) - Диалог завершен успешно
|
|
68
139
|
|
|
69
140
|
- Есть поле `followups: []` (пустой массив)
|
|
@@ -78,6 +149,7 @@ console.log({
|
|
|
78
149
|
- **`DialogStatus.IN_PROGRESS`** (`"in_progress"`) - Диалог в процессе
|
|
79
150
|
- Отсутствует поле `followups`
|
|
80
151
|
- `isCanceled: false`
|
|
152
|
+
- **Такой статус получается при экспорте во время диалога**
|
|
81
153
|
|
|
82
154
|
## Примеры использования
|
|
83
155
|
|
|
@@ -111,18 +183,26 @@ pnpm test:coverage
|
|
|
111
183
|
|
|
112
184
|
## Структура экспорта чата
|
|
113
185
|
|
|
114
|
-
Библиотека работает с JSON файлами, экспортированными из GitHub Copilot Chat
|
|
186
|
+
Библиотека работает с JSON файлами, экспортированными из GitHub Copilot Chat через команду **`F1 > Export Chat`**.
|
|
187
|
+
|
|
188
|
+
### Формат файла
|
|
189
|
+
|
|
190
|
+
Экспортированный файл содержит следующую структуру:
|
|
115
191
|
|
|
116
192
|
```json
|
|
117
193
|
{
|
|
194
|
+
"requesterUsername": "your-username",
|
|
195
|
+
"responderUsername": "GitHub Copilot",
|
|
118
196
|
"requests": [
|
|
119
197
|
{
|
|
120
|
-
"requestId": "...",
|
|
121
|
-
"message": {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"
|
|
125
|
-
"
|
|
198
|
+
"requestId": "request_abc123...",
|
|
199
|
+
"message": {
|
|
200
|
+
"text": "Ваш вопрос к Copilot"
|
|
201
|
+
},
|
|
202
|
+
"response": [...], // массив частей ответа
|
|
203
|
+
"followups": [], // только в завершенных диалогах (пустой массив)
|
|
204
|
+
"result": {...}, // метаданные результата
|
|
205
|
+
"isCanceled": false // true если диалог был отменен
|
|
126
206
|
}
|
|
127
207
|
]
|
|
128
208
|
}
|
|
@@ -136,7 +216,7 @@ interface CopilotChatData {
|
|
|
136
216
|
[key: string]: any;
|
|
137
217
|
}
|
|
138
218
|
|
|
139
|
-
type DialogStatusType = "completed" | "canceled" | "in_progress";
|
|
219
|
+
type DialogStatusType = "pending" | "completed" | "canceled" | "in_progress";
|
|
140
220
|
|
|
141
221
|
interface DialogStatusDetails {
|
|
142
222
|
status: DialogStatusType;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
CopilotChatAnalyzer: () => CopilotChatAnalyzer,
|
|
24
|
+
DialogStatus: () => DialogStatus,
|
|
25
|
+
default: () => index_default
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
var DialogStatus = {
|
|
29
|
+
PENDING: "pending",
|
|
30
|
+
COMPLETED: "completed",
|
|
31
|
+
CANCELED: "canceled",
|
|
32
|
+
IN_PROGRESS: "in_progress"
|
|
33
|
+
};
|
|
34
|
+
var CopilotChatAnalyzer = class {
|
|
35
|
+
getRequestsCount(chatData) {
|
|
36
|
+
if (!chatData || !Array.isArray(chatData.requests)) {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
return chatData.requests.length;
|
|
40
|
+
}
|
|
41
|
+
hasRequests(chatData) {
|
|
42
|
+
return Array.isArray(chatData.requests) && chatData.requests.length > 0;
|
|
43
|
+
}
|
|
44
|
+
getLastRequest(chatData) {
|
|
45
|
+
if (!this.hasRequests(chatData)) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return chatData.requests[chatData.requests.length - 1];
|
|
49
|
+
}
|
|
50
|
+
getDialogStatus(chatData) {
|
|
51
|
+
if (!this.hasRequests(chatData)) {
|
|
52
|
+
return DialogStatus.PENDING;
|
|
53
|
+
}
|
|
54
|
+
const lastRequest = this.getLastRequest(chatData);
|
|
55
|
+
if (!lastRequest) {
|
|
56
|
+
return DialogStatus.PENDING;
|
|
57
|
+
}
|
|
58
|
+
if (lastRequest.isCanceled === true) {
|
|
59
|
+
return DialogStatus.CANCELED;
|
|
60
|
+
}
|
|
61
|
+
if ("followups" in lastRequest && Array.isArray(lastRequest.followups)) {
|
|
62
|
+
if (lastRequest.followups.length === 0) {
|
|
63
|
+
return DialogStatus.COMPLETED;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (!("followups" in lastRequest)) {
|
|
67
|
+
return DialogStatus.IN_PROGRESS;
|
|
68
|
+
}
|
|
69
|
+
return DialogStatus.IN_PROGRESS;
|
|
70
|
+
}
|
|
71
|
+
getDialogStatusDetails(chatData) {
|
|
72
|
+
const status = this.getDialogStatus(chatData);
|
|
73
|
+
if (!this.hasRequests(chatData)) {
|
|
74
|
+
return {
|
|
75
|
+
status: DialogStatus.PENDING,
|
|
76
|
+
statusText: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0435\u0449\u0435 \u043D\u0435 \u043D\u0430\u0447\u0430\u0442",
|
|
77
|
+
hasResult: false,
|
|
78
|
+
hasFollowups: false,
|
|
79
|
+
isCanceled: false
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const lastRequest = this.getLastRequest(chatData);
|
|
83
|
+
const statusTexts = {
|
|
84
|
+
[DialogStatus.PENDING]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0435\u0449\u0435 \u043D\u0435 \u043D\u0430\u0447\u0430\u0442",
|
|
85
|
+
[DialogStatus.COMPLETED]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D \u0443\u0441\u043F\u0435\u0448\u043D\u043E",
|
|
86
|
+
[DialogStatus.CANCELED]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0431\u044B\u043B \u043E\u0442\u043C\u0435\u043D\u0435\u043D",
|
|
87
|
+
[DialogStatus.IN_PROGRESS]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0432 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F"
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
status,
|
|
91
|
+
statusText: statusTexts[status],
|
|
92
|
+
hasResult: lastRequest && "result" in lastRequest && lastRequest.result !== null,
|
|
93
|
+
hasFollowups: lastRequest && "followups" in lastRequest,
|
|
94
|
+
isCanceled: lastRequest && lastRequest.isCanceled === true,
|
|
95
|
+
lastRequestId: lastRequest?.requestId
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
extractMcpToolCalls(chatData) {
|
|
99
|
+
if (!this.hasRequests(chatData)) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
const toolCalls = [];
|
|
103
|
+
chatData.requests.forEach((request) => {
|
|
104
|
+
if (!request.response || !Array.isArray(request.response)) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
request.response.forEach((responseItem) => {
|
|
108
|
+
if (responseItem.kind === "toolInvocationSerialized" && responseItem.source?.type === "mcp") {
|
|
109
|
+
const toolCall = {
|
|
110
|
+
toolId: responseItem.toolId || responseItem.toolName || "unknown",
|
|
111
|
+
toolName: responseItem.toolName || responseItem.toolId || "unknown",
|
|
112
|
+
requestId: request.requestId,
|
|
113
|
+
input: responseItem.resultDetails?.input || responseItem.toolSpecificData?.rawInput || null,
|
|
114
|
+
output: responseItem.resultDetails?.output || null,
|
|
115
|
+
isError: responseItem.resultDetails?.isError || false,
|
|
116
|
+
timestamp: request.timestamp,
|
|
117
|
+
source: responseItem.source
|
|
118
|
+
};
|
|
119
|
+
toolCalls.push(toolCall);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
return toolCalls;
|
|
124
|
+
}
|
|
125
|
+
getMcpToolMonitoring(chatData, toolName) {
|
|
126
|
+
const allToolCalls = this.extractMcpToolCalls(chatData);
|
|
127
|
+
if (toolName) {
|
|
128
|
+
const toolCalls = allToolCalls.filter(
|
|
129
|
+
(call) => call.toolName.includes(toolName) || call.toolId.includes(toolName)
|
|
130
|
+
);
|
|
131
|
+
const successfulCalls = toolCalls.filter((call) => !call.isError).length;
|
|
132
|
+
const errorCalls = toolCalls.filter((call) => call.isError).length;
|
|
133
|
+
const successRate = toolCalls.length > 0 ? successfulCalls / toolCalls.length * 100 : 0;
|
|
134
|
+
return {
|
|
135
|
+
toolName,
|
|
136
|
+
totalCalls: toolCalls.length,
|
|
137
|
+
successfulCalls,
|
|
138
|
+
errorCalls,
|
|
139
|
+
successRate: Math.round(successRate * 100) / 100,
|
|
140
|
+
calls: toolCalls
|
|
141
|
+
};
|
|
142
|
+
} else {
|
|
143
|
+
const toolsMap = /* @__PURE__ */ new Map();
|
|
144
|
+
allToolCalls.forEach((call) => {
|
|
145
|
+
const key = call.toolName || call.toolId;
|
|
146
|
+
if (!toolsMap.has(key)) {
|
|
147
|
+
toolsMap.set(key, []);
|
|
148
|
+
}
|
|
149
|
+
toolsMap.get(key).push(call);
|
|
150
|
+
});
|
|
151
|
+
const tools = Array.from(toolsMap.entries()).map(
|
|
152
|
+
([toolName2, calls]) => {
|
|
153
|
+
const successfulCalls = calls.filter((call) => !call.isError).length;
|
|
154
|
+
const errorCalls = calls.filter((call) => call.isError).length;
|
|
155
|
+
const successRate = calls.length > 0 ? successfulCalls / calls.length * 100 : 0;
|
|
156
|
+
return {
|
|
157
|
+
toolName: toolName2,
|
|
158
|
+
totalCalls: calls.length,
|
|
159
|
+
successfulCalls,
|
|
160
|
+
errorCalls,
|
|
161
|
+
successRate: Math.round(successRate * 100) / 100,
|
|
162
|
+
calls
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
const totalCalls = allToolCalls.length;
|
|
167
|
+
const totalSuccessful = allToolCalls.filter(
|
|
168
|
+
(call) => !call.isError
|
|
169
|
+
).length;
|
|
170
|
+
const overallSuccessRate = totalCalls > 0 ? totalSuccessful / totalCalls * 100 : 0;
|
|
171
|
+
return {
|
|
172
|
+
totalTools: tools.length,
|
|
173
|
+
totalCalls,
|
|
174
|
+
overallSuccessRate: Math.round(overallSuccessRate * 100) / 100,
|
|
175
|
+
tools
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
getMcpToolSuccessfulCalls(chatData, toolName) {
|
|
180
|
+
const monitoring = this.getMcpToolMonitoring(
|
|
181
|
+
chatData,
|
|
182
|
+
toolName
|
|
183
|
+
);
|
|
184
|
+
return monitoring.calls.filter((call) => !call.isError);
|
|
185
|
+
}
|
|
186
|
+
getMcpToolErrorCalls(chatData, toolName) {
|
|
187
|
+
const monitoring = this.getMcpToolMonitoring(
|
|
188
|
+
chatData,
|
|
189
|
+
toolName
|
|
190
|
+
);
|
|
191
|
+
return monitoring.calls.filter((call) => call.isError);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Простой метод для получения всех вызовов конкретного MCP инструмента
|
|
195
|
+
* @param chatData - данные чата
|
|
196
|
+
* @param toolName - название инструмента (например, 'update_entry_fields')
|
|
197
|
+
* @returns массив всех вызовов инструмента
|
|
198
|
+
*/
|
|
199
|
+
getMcpToolCalls(chatData, toolName) {
|
|
200
|
+
const allToolCalls = this.extractMcpToolCalls(chatData);
|
|
201
|
+
return allToolCalls.filter(
|
|
202
|
+
(call) => call.toolName.includes(toolName) || call.toolId.includes(toolName)
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Получить список всех уникальных MCP инструментов, использованных в чате
|
|
207
|
+
* @param chatData - данные чата
|
|
208
|
+
* @returns массив названий инструментов
|
|
209
|
+
*/
|
|
210
|
+
getMcpToolNames(chatData) {
|
|
211
|
+
const allToolCalls = this.extractMcpToolCalls(chatData);
|
|
212
|
+
const uniqueNames = /* @__PURE__ */ new Set();
|
|
213
|
+
allToolCalls.forEach((call) => {
|
|
214
|
+
uniqueNames.add(call.toolName || call.toolId);
|
|
215
|
+
});
|
|
216
|
+
return Array.from(uniqueNames);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
var index_default = CopilotChatAnalyzer;
|
|
220
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
221
|
+
0 && (module.exports = {
|
|
222
|
+
CopilotChatAnalyzer,
|
|
223
|
+
DialogStatus
|
|
224
|
+
});
|
package/dist/index.d.cts
CHANGED
|
@@ -10,7 +10,36 @@ interface DialogStatusDetails {
|
|
|
10
10
|
isCanceled: boolean;
|
|
11
11
|
lastRequestId?: string;
|
|
12
12
|
}
|
|
13
|
+
interface McpToolCall {
|
|
14
|
+
toolId: string;
|
|
15
|
+
toolName: string;
|
|
16
|
+
requestId: string;
|
|
17
|
+
input: any;
|
|
18
|
+
output: any;
|
|
19
|
+
isError: boolean;
|
|
20
|
+
timestamp?: number;
|
|
21
|
+
source?: {
|
|
22
|
+
type: string;
|
|
23
|
+
serverLabel: string;
|
|
24
|
+
label: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
interface McpToolMonitoring {
|
|
28
|
+
toolName: string;
|
|
29
|
+
totalCalls: number;
|
|
30
|
+
successfulCalls: number;
|
|
31
|
+
errorCalls: number;
|
|
32
|
+
successRate: number;
|
|
33
|
+
calls: McpToolCall[];
|
|
34
|
+
}
|
|
35
|
+
interface McpMonitoringSummary {
|
|
36
|
+
totalTools: number;
|
|
37
|
+
totalCalls: number;
|
|
38
|
+
overallSuccessRate: number;
|
|
39
|
+
tools: McpToolMonitoring[];
|
|
40
|
+
}
|
|
13
41
|
declare const DialogStatus: {
|
|
42
|
+
readonly PENDING: "pending";
|
|
14
43
|
readonly COMPLETED: "completed";
|
|
15
44
|
readonly CANCELED: "canceled";
|
|
16
45
|
readonly IN_PROGRESS: "in_progress";
|
|
@@ -22,6 +51,23 @@ declare class CopilotChatAnalyzer {
|
|
|
22
51
|
private getLastRequest;
|
|
23
52
|
getDialogStatus(chatData: CopilotChatData): DialogStatusType;
|
|
24
53
|
getDialogStatusDetails(chatData: CopilotChatData): DialogStatusDetails;
|
|
54
|
+
private extractMcpToolCalls;
|
|
55
|
+
getMcpToolMonitoring(chatData: CopilotChatData, toolName?: string): McpToolMonitoring | McpMonitoringSummary;
|
|
56
|
+
getMcpToolSuccessfulCalls(chatData: CopilotChatData, toolName: string): McpToolCall[];
|
|
57
|
+
getMcpToolErrorCalls(chatData: CopilotChatData, toolName: string): McpToolCall[];
|
|
58
|
+
/**
|
|
59
|
+
* Простой метод для получения всех вызовов конкретного MCP инструмента
|
|
60
|
+
* @param chatData - данные чата
|
|
61
|
+
* @param toolName - название инструмента (например, 'update_entry_fields')
|
|
62
|
+
* @returns массив всех вызовов инструмента
|
|
63
|
+
*/
|
|
64
|
+
getMcpToolCalls(chatData: CopilotChatData, toolName: string): McpToolCall[];
|
|
65
|
+
/**
|
|
66
|
+
* Получить список всех уникальных MCP инструментов, использованных в чате
|
|
67
|
+
* @param chatData - данные чата
|
|
68
|
+
* @returns массив названий инструментов
|
|
69
|
+
*/
|
|
70
|
+
getMcpToolNames(chatData: CopilotChatData): string[];
|
|
25
71
|
}
|
|
26
72
|
|
|
27
|
-
export { CopilotChatAnalyzer, DialogStatus, type DialogStatusType, CopilotChatAnalyzer as default };
|
|
73
|
+
export { CopilotChatAnalyzer, DialogStatus, type DialogStatusType, type McpMonitoringSummary, type McpToolCall, type McpToolMonitoring, CopilotChatAnalyzer as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,36 @@ interface DialogStatusDetails {
|
|
|
10
10
|
isCanceled: boolean;
|
|
11
11
|
lastRequestId?: string;
|
|
12
12
|
}
|
|
13
|
+
interface McpToolCall {
|
|
14
|
+
toolId: string;
|
|
15
|
+
toolName: string;
|
|
16
|
+
requestId: string;
|
|
17
|
+
input: any;
|
|
18
|
+
output: any;
|
|
19
|
+
isError: boolean;
|
|
20
|
+
timestamp?: number;
|
|
21
|
+
source?: {
|
|
22
|
+
type: string;
|
|
23
|
+
serverLabel: string;
|
|
24
|
+
label: string;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
interface McpToolMonitoring {
|
|
28
|
+
toolName: string;
|
|
29
|
+
totalCalls: number;
|
|
30
|
+
successfulCalls: number;
|
|
31
|
+
errorCalls: number;
|
|
32
|
+
successRate: number;
|
|
33
|
+
calls: McpToolCall[];
|
|
34
|
+
}
|
|
35
|
+
interface McpMonitoringSummary {
|
|
36
|
+
totalTools: number;
|
|
37
|
+
totalCalls: number;
|
|
38
|
+
overallSuccessRate: number;
|
|
39
|
+
tools: McpToolMonitoring[];
|
|
40
|
+
}
|
|
13
41
|
declare const DialogStatus: {
|
|
42
|
+
readonly PENDING: "pending";
|
|
14
43
|
readonly COMPLETED: "completed";
|
|
15
44
|
readonly CANCELED: "canceled";
|
|
16
45
|
readonly IN_PROGRESS: "in_progress";
|
|
@@ -22,6 +51,23 @@ declare class CopilotChatAnalyzer {
|
|
|
22
51
|
private getLastRequest;
|
|
23
52
|
getDialogStatus(chatData: CopilotChatData): DialogStatusType;
|
|
24
53
|
getDialogStatusDetails(chatData: CopilotChatData): DialogStatusDetails;
|
|
54
|
+
private extractMcpToolCalls;
|
|
55
|
+
getMcpToolMonitoring(chatData: CopilotChatData, toolName?: string): McpToolMonitoring | McpMonitoringSummary;
|
|
56
|
+
getMcpToolSuccessfulCalls(chatData: CopilotChatData, toolName: string): McpToolCall[];
|
|
57
|
+
getMcpToolErrorCalls(chatData: CopilotChatData, toolName: string): McpToolCall[];
|
|
58
|
+
/**
|
|
59
|
+
* Простой метод для получения всех вызовов конкретного MCP инструмента
|
|
60
|
+
* @param chatData - данные чата
|
|
61
|
+
* @param toolName - название инструмента (например, 'update_entry_fields')
|
|
62
|
+
* @returns массив всех вызовов инструмента
|
|
63
|
+
*/
|
|
64
|
+
getMcpToolCalls(chatData: CopilotChatData, toolName: string): McpToolCall[];
|
|
65
|
+
/**
|
|
66
|
+
* Получить список всех уникальных MCP инструментов, использованных в чате
|
|
67
|
+
* @param chatData - данные чата
|
|
68
|
+
* @returns массив названий инструментов
|
|
69
|
+
*/
|
|
70
|
+
getMcpToolNames(chatData: CopilotChatData): string[];
|
|
25
71
|
}
|
|
26
72
|
|
|
27
|
-
export { CopilotChatAnalyzer, DialogStatus, type DialogStatusType, CopilotChatAnalyzer as default };
|
|
73
|
+
export { CopilotChatAnalyzer, DialogStatus, type DialogStatusType, type McpMonitoringSummary, type McpToolCall, type McpToolMonitoring, CopilotChatAnalyzer as default };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
var DialogStatus = {
|
|
3
|
+
PENDING: "pending",
|
|
3
4
|
COMPLETED: "completed",
|
|
4
5
|
CANCELED: "canceled",
|
|
5
6
|
IN_PROGRESS: "in_progress"
|
|
@@ -22,11 +23,11 @@ var CopilotChatAnalyzer = class {
|
|
|
22
23
|
}
|
|
23
24
|
getDialogStatus(chatData) {
|
|
24
25
|
if (!this.hasRequests(chatData)) {
|
|
25
|
-
return DialogStatus.
|
|
26
|
+
return DialogStatus.PENDING;
|
|
26
27
|
}
|
|
27
28
|
const lastRequest = this.getLastRequest(chatData);
|
|
28
29
|
if (!lastRequest) {
|
|
29
|
-
return DialogStatus.
|
|
30
|
+
return DialogStatus.PENDING;
|
|
30
31
|
}
|
|
31
32
|
if (lastRequest.isCanceled === true) {
|
|
32
33
|
return DialogStatus.CANCELED;
|
|
@@ -45,8 +46,8 @@ var CopilotChatAnalyzer = class {
|
|
|
45
46
|
const status = this.getDialogStatus(chatData);
|
|
46
47
|
if (!this.hasRequests(chatData)) {
|
|
47
48
|
return {
|
|
48
|
-
status: DialogStatus.
|
|
49
|
-
statusText: "\
|
|
49
|
+
status: DialogStatus.PENDING,
|
|
50
|
+
statusText: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0435\u0449\u0435 \u043D\u0435 \u043D\u0430\u0447\u0430\u0442",
|
|
50
51
|
hasResult: false,
|
|
51
52
|
hasFollowups: false,
|
|
52
53
|
isCanceled: false
|
|
@@ -54,6 +55,7 @@ var CopilotChatAnalyzer = class {
|
|
|
54
55
|
}
|
|
55
56
|
const lastRequest = this.getLastRequest(chatData);
|
|
56
57
|
const statusTexts = {
|
|
58
|
+
[DialogStatus.PENDING]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0435\u0449\u0435 \u043D\u0435 \u043D\u0430\u0447\u0430\u0442",
|
|
57
59
|
[DialogStatus.COMPLETED]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D \u0443\u0441\u043F\u0435\u0448\u043D\u043E",
|
|
58
60
|
[DialogStatus.CANCELED]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0431\u044B\u043B \u043E\u0442\u043C\u0435\u043D\u0435\u043D",
|
|
59
61
|
[DialogStatus.IN_PROGRESS]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0432 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F"
|
|
@@ -67,6 +69,126 @@ var CopilotChatAnalyzer = class {
|
|
|
67
69
|
lastRequestId: lastRequest?.requestId
|
|
68
70
|
};
|
|
69
71
|
}
|
|
72
|
+
extractMcpToolCalls(chatData) {
|
|
73
|
+
if (!this.hasRequests(chatData)) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const toolCalls = [];
|
|
77
|
+
chatData.requests.forEach((request) => {
|
|
78
|
+
if (!request.response || !Array.isArray(request.response)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
request.response.forEach((responseItem) => {
|
|
82
|
+
if (responseItem.kind === "toolInvocationSerialized" && responseItem.source?.type === "mcp") {
|
|
83
|
+
const toolCall = {
|
|
84
|
+
toolId: responseItem.toolId || responseItem.toolName || "unknown",
|
|
85
|
+
toolName: responseItem.toolName || responseItem.toolId || "unknown",
|
|
86
|
+
requestId: request.requestId,
|
|
87
|
+
input: responseItem.resultDetails?.input || responseItem.toolSpecificData?.rawInput || null,
|
|
88
|
+
output: responseItem.resultDetails?.output || null,
|
|
89
|
+
isError: responseItem.resultDetails?.isError || false,
|
|
90
|
+
timestamp: request.timestamp,
|
|
91
|
+
source: responseItem.source
|
|
92
|
+
};
|
|
93
|
+
toolCalls.push(toolCall);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
return toolCalls;
|
|
98
|
+
}
|
|
99
|
+
getMcpToolMonitoring(chatData, toolName) {
|
|
100
|
+
const allToolCalls = this.extractMcpToolCalls(chatData);
|
|
101
|
+
if (toolName) {
|
|
102
|
+
const toolCalls = allToolCalls.filter(
|
|
103
|
+
(call) => call.toolName.includes(toolName) || call.toolId.includes(toolName)
|
|
104
|
+
);
|
|
105
|
+
const successfulCalls = toolCalls.filter((call) => !call.isError).length;
|
|
106
|
+
const errorCalls = toolCalls.filter((call) => call.isError).length;
|
|
107
|
+
const successRate = toolCalls.length > 0 ? successfulCalls / toolCalls.length * 100 : 0;
|
|
108
|
+
return {
|
|
109
|
+
toolName,
|
|
110
|
+
totalCalls: toolCalls.length,
|
|
111
|
+
successfulCalls,
|
|
112
|
+
errorCalls,
|
|
113
|
+
successRate: Math.round(successRate * 100) / 100,
|
|
114
|
+
calls: toolCalls
|
|
115
|
+
};
|
|
116
|
+
} else {
|
|
117
|
+
const toolsMap = /* @__PURE__ */ new Map();
|
|
118
|
+
allToolCalls.forEach((call) => {
|
|
119
|
+
const key = call.toolName || call.toolId;
|
|
120
|
+
if (!toolsMap.has(key)) {
|
|
121
|
+
toolsMap.set(key, []);
|
|
122
|
+
}
|
|
123
|
+
toolsMap.get(key).push(call);
|
|
124
|
+
});
|
|
125
|
+
const tools = Array.from(toolsMap.entries()).map(
|
|
126
|
+
([toolName2, calls]) => {
|
|
127
|
+
const successfulCalls = calls.filter((call) => !call.isError).length;
|
|
128
|
+
const errorCalls = calls.filter((call) => call.isError).length;
|
|
129
|
+
const successRate = calls.length > 0 ? successfulCalls / calls.length * 100 : 0;
|
|
130
|
+
return {
|
|
131
|
+
toolName: toolName2,
|
|
132
|
+
totalCalls: calls.length,
|
|
133
|
+
successfulCalls,
|
|
134
|
+
errorCalls,
|
|
135
|
+
successRate: Math.round(successRate * 100) / 100,
|
|
136
|
+
calls
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
const totalCalls = allToolCalls.length;
|
|
141
|
+
const totalSuccessful = allToolCalls.filter(
|
|
142
|
+
(call) => !call.isError
|
|
143
|
+
).length;
|
|
144
|
+
const overallSuccessRate = totalCalls > 0 ? totalSuccessful / totalCalls * 100 : 0;
|
|
145
|
+
return {
|
|
146
|
+
totalTools: tools.length,
|
|
147
|
+
totalCalls,
|
|
148
|
+
overallSuccessRate: Math.round(overallSuccessRate * 100) / 100,
|
|
149
|
+
tools
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
getMcpToolSuccessfulCalls(chatData, toolName) {
|
|
154
|
+
const monitoring = this.getMcpToolMonitoring(
|
|
155
|
+
chatData,
|
|
156
|
+
toolName
|
|
157
|
+
);
|
|
158
|
+
return monitoring.calls.filter((call) => !call.isError);
|
|
159
|
+
}
|
|
160
|
+
getMcpToolErrorCalls(chatData, toolName) {
|
|
161
|
+
const monitoring = this.getMcpToolMonitoring(
|
|
162
|
+
chatData,
|
|
163
|
+
toolName
|
|
164
|
+
);
|
|
165
|
+
return monitoring.calls.filter((call) => call.isError);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Простой метод для получения всех вызовов конкретного MCP инструмента
|
|
169
|
+
* @param chatData - данные чата
|
|
170
|
+
* @param toolName - название инструмента (например, 'update_entry_fields')
|
|
171
|
+
* @returns массив всех вызовов инструмента
|
|
172
|
+
*/
|
|
173
|
+
getMcpToolCalls(chatData, toolName) {
|
|
174
|
+
const allToolCalls = this.extractMcpToolCalls(chatData);
|
|
175
|
+
return allToolCalls.filter(
|
|
176
|
+
(call) => call.toolName.includes(toolName) || call.toolId.includes(toolName)
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Получить список всех уникальных MCP инструментов, использованных в чате
|
|
181
|
+
* @param chatData - данные чата
|
|
182
|
+
* @returns массив названий инструментов
|
|
183
|
+
*/
|
|
184
|
+
getMcpToolNames(chatData) {
|
|
185
|
+
const allToolCalls = this.extractMcpToolCalls(chatData);
|
|
186
|
+
const uniqueNames = /* @__PURE__ */ new Set();
|
|
187
|
+
allToolCalls.forEach((call) => {
|
|
188
|
+
uniqueNames.add(call.toolName || call.toolId);
|
|
189
|
+
});
|
|
190
|
+
return Array.from(uniqueNames);
|
|
191
|
+
}
|
|
70
192
|
};
|
|
71
193
|
var index_default = CopilotChatAnalyzer;
|
|
72
194
|
export {
|
package/package.json
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "copilot-chat-analyzer",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
5
|
-
"description": "
|
|
4
|
+
"version": "0.0.3",
|
|
5
|
+
"description": "TypeScript library for analyzing and monitoring GitHub Copilot chat exports with status detection, request counting, and MCP tool tracking",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"copilot",
|
|
8
8
|
"chat",
|
|
9
9
|
"analyzer",
|
|
10
10
|
"github",
|
|
11
|
-
"typescript"
|
|
11
|
+
"typescript",
|
|
12
|
+
"mcp",
|
|
13
|
+
"model-context-protocol",
|
|
14
|
+
"monitoring",
|
|
15
|
+
"status-detection",
|
|
16
|
+
"dialog-analysis",
|
|
17
|
+
"ai-tools",
|
|
18
|
+
"export-analysis"
|
|
12
19
|
],
|
|
13
20
|
"author": "dealenx",
|
|
14
21
|
"license": "MIT",
|
|
@@ -20,20 +27,52 @@
|
|
|
20
27
|
"url": "https://github.com/dealenx/copilot-chat-analyzer/issues"
|
|
21
28
|
},
|
|
22
29
|
"homepage": "https://github.com/dealenx/copilot-chat-analyzer#readme",
|
|
30
|
+
"funding": {
|
|
31
|
+
"type": "github",
|
|
32
|
+
"url": "https://github.com/sponsors/dealenx"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=16.0.0"
|
|
36
|
+
},
|
|
37
|
+
"ai-usage": {
|
|
38
|
+
"purpose": "Analyze GitHub Copilot chat exports for dialog status, request counting, and MCP tool monitoring",
|
|
39
|
+
"quick-start": "import CopilotChatAnalyzer, { DialogStatus } from 'copilot-chat-analyzer'; const analyzer = new CopilotChatAnalyzer(); const status = analyzer.getDialogStatus(chatData);",
|
|
40
|
+
"main-features": [
|
|
41
|
+
"Dialog status detection (pending, in_progress, completed, canceled)",
|
|
42
|
+
"Request counting and analysis",
|
|
43
|
+
"MCP (Model Context Protocol) tool monitoring",
|
|
44
|
+
"Chat export validation and parsing"
|
|
45
|
+
],
|
|
46
|
+
"common-methods": {
|
|
47
|
+
"getDialogStatus": "Returns dialog status: 'pending' | 'completed' | 'canceled' | 'in_progress'",
|
|
48
|
+
"getRequestsCount": "Returns number of requests in chat",
|
|
49
|
+
"getDialogStatusDetails": "Returns detailed status information with flags",
|
|
50
|
+
"getMcpToolMonitoring": "Returns MCP tool usage statistics and monitoring data"
|
|
51
|
+
},
|
|
52
|
+
"status-meanings": {
|
|
53
|
+
"pending": "Chat created but no requests made yet (requests: [])",
|
|
54
|
+
"in_progress": "Chat has requests but not completed",
|
|
55
|
+
"completed": "Chat finished successfully (has followups: [])",
|
|
56
|
+
"canceled": "Chat was canceled (isCanceled: true)"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
23
59
|
"type": "module",
|
|
24
|
-
"main": "dist/index.
|
|
60
|
+
"main": "dist/index.cjs",
|
|
25
61
|
"module": "dist/index.mjs",
|
|
26
62
|
"types": "dist/index.d.ts",
|
|
27
63
|
"exports": {
|
|
28
64
|
".": {
|
|
29
65
|
"types": "./dist/index.d.ts",
|
|
30
66
|
"import": "./dist/index.mjs",
|
|
31
|
-
"require": "./dist/index.
|
|
67
|
+
"require": "./dist/index.cjs",
|
|
32
68
|
"default": "./dist/index.mjs"
|
|
33
69
|
}
|
|
34
70
|
},
|
|
35
71
|
"files": [
|
|
36
|
-
"dist"
|
|
72
|
+
"dist",
|
|
73
|
+
"README.md",
|
|
74
|
+
"AI_USAGE.md",
|
|
75
|
+
"LICENSE"
|
|
37
76
|
],
|
|
38
77
|
"devDependencies": {
|
|
39
78
|
"@types/jest": "^30.0.0",
|
package/dist/index.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
CopilotChatAnalyzer: () => CopilotChatAnalyzer,
|
|
24
|
-
DialogStatus: () => DialogStatus,
|
|
25
|
-
default: () => index_default
|
|
26
|
-
});
|
|
27
|
-
module.exports = __toCommonJS(index_exports);
|
|
28
|
-
var DialogStatus = {
|
|
29
|
-
COMPLETED: "completed",
|
|
30
|
-
CANCELED: "canceled",
|
|
31
|
-
IN_PROGRESS: "in_progress"
|
|
32
|
-
};
|
|
33
|
-
var CopilotChatAnalyzer = class {
|
|
34
|
-
getRequestsCount(chatData) {
|
|
35
|
-
if (!chatData || !Array.isArray(chatData.requests)) {
|
|
36
|
-
return 0;
|
|
37
|
-
}
|
|
38
|
-
return chatData.requests.length;
|
|
39
|
-
}
|
|
40
|
-
hasRequests(chatData) {
|
|
41
|
-
return Array.isArray(chatData.requests) && chatData.requests.length > 0;
|
|
42
|
-
}
|
|
43
|
-
getLastRequest(chatData) {
|
|
44
|
-
if (!this.hasRequests(chatData)) {
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
return chatData.requests[chatData.requests.length - 1];
|
|
48
|
-
}
|
|
49
|
-
getDialogStatus(chatData) {
|
|
50
|
-
if (!this.hasRequests(chatData)) {
|
|
51
|
-
return DialogStatus.IN_PROGRESS;
|
|
52
|
-
}
|
|
53
|
-
const lastRequest = this.getLastRequest(chatData);
|
|
54
|
-
if (!lastRequest) {
|
|
55
|
-
return DialogStatus.IN_PROGRESS;
|
|
56
|
-
}
|
|
57
|
-
if (lastRequest.isCanceled === true) {
|
|
58
|
-
return DialogStatus.CANCELED;
|
|
59
|
-
}
|
|
60
|
-
if ("followups" in lastRequest && Array.isArray(lastRequest.followups)) {
|
|
61
|
-
if (lastRequest.followups.length === 0) {
|
|
62
|
-
return DialogStatus.COMPLETED;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (!("followups" in lastRequest)) {
|
|
66
|
-
return DialogStatus.IN_PROGRESS;
|
|
67
|
-
}
|
|
68
|
-
return DialogStatus.IN_PROGRESS;
|
|
69
|
-
}
|
|
70
|
-
getDialogStatusDetails(chatData) {
|
|
71
|
-
const status = this.getDialogStatus(chatData);
|
|
72
|
-
if (!this.hasRequests(chatData)) {
|
|
73
|
-
return {
|
|
74
|
-
status: DialogStatus.IN_PROGRESS,
|
|
75
|
-
statusText: "\u041D\u0435\u0442 \u0437\u0430\u043F\u0440\u043E\u0441\u043E\u0432",
|
|
76
|
-
hasResult: false,
|
|
77
|
-
hasFollowups: false,
|
|
78
|
-
isCanceled: false
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
const lastRequest = this.getLastRequest(chatData);
|
|
82
|
-
const statusTexts = {
|
|
83
|
-
[DialogStatus.COMPLETED]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D \u0443\u0441\u043F\u0435\u0448\u043D\u043E",
|
|
84
|
-
[DialogStatus.CANCELED]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0431\u044B\u043B \u043E\u0442\u043C\u0435\u043D\u0435\u043D",
|
|
85
|
-
[DialogStatus.IN_PROGRESS]: "\u0414\u0438\u0430\u043B\u043E\u0433 \u0432 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F"
|
|
86
|
-
};
|
|
87
|
-
return {
|
|
88
|
-
status,
|
|
89
|
-
statusText: statusTexts[status],
|
|
90
|
-
hasResult: lastRequest && "result" in lastRequest && lastRequest.result !== null,
|
|
91
|
-
hasFollowups: lastRequest && "followups" in lastRequest,
|
|
92
|
-
isCanceled: lastRequest && lastRequest.isCanceled === true,
|
|
93
|
-
lastRequestId: lastRequest?.requestId
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
var index_default = CopilotChatAnalyzer;
|
|
98
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
99
|
-
0 && (module.exports = {
|
|
100
|
-
CopilotChatAnalyzer,
|
|
101
|
-
DialogStatus
|
|
102
|
-
});
|