@operor/copilot 0.1.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/index.d.ts +282 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +708 -0
- package/dist/index.js.map +1 -0
- package/package.json +32 -0
- package/src/CopilotCommandHandler.ts +263 -0
- package/src/DigestScheduler.ts +76 -0
- package/src/InMemoryCopilotStore.ts +90 -0
- package/src/QueryClusterer.ts +84 -0
- package/src/SQLiteCopilotStore.ts +300 -0
- package/src/SuggestionEngine.ts +44 -0
- package/src/UnansweredQueryTracker.ts +83 -0
- package/src/__tests__/copilot.test.ts +1007 -0
- package/src/index.ts +8 -0
- package/src/types.ts +131 -0
- package/tsconfig.json +9 -0
- package/tsdown.config.ts +10 -0
package/src/index.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export { SQLiteCopilotStore } from './SQLiteCopilotStore.js';
|
|
3
|
+
export { InMemoryCopilotStore } from './InMemoryCopilotStore.js';
|
|
4
|
+
export { UnansweredQueryTracker } from './UnansweredQueryTracker.js';
|
|
5
|
+
export { QueryClusterer } from './QueryClusterer.js';
|
|
6
|
+
export { SuggestionEngine } from './SuggestionEngine.js';
|
|
7
|
+
export { CopilotCommandHandler } from './CopilotCommandHandler.js';
|
|
8
|
+
export { DigestScheduler } from './DigestScheduler.js';
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Training Copilot types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/** Status of an unanswered query through the review lifecycle */
|
|
6
|
+
export type QueryStatus = 'pending' | 'taught' | 'dismissed';
|
|
7
|
+
|
|
8
|
+
/** A customer query that the KB couldn't confidently answer */
|
|
9
|
+
export interface UnansweredQuery {
|
|
10
|
+
id: string;
|
|
11
|
+
query: string;
|
|
12
|
+
normalizedQuery: string;
|
|
13
|
+
channel: string;
|
|
14
|
+
customerPhone: string;
|
|
15
|
+
kbTopScore: number;
|
|
16
|
+
kbIsFaqMatch: boolean;
|
|
17
|
+
kbTopChunkContent?: string;
|
|
18
|
+
kbResultCount: number;
|
|
19
|
+
status: QueryStatus;
|
|
20
|
+
clusterId?: string;
|
|
21
|
+
timesAsked: number;
|
|
22
|
+
uniqueCustomers: string[];
|
|
23
|
+
embedding?: number[];
|
|
24
|
+
suggestedAnswer?: string;
|
|
25
|
+
taughtAnswer?: string;
|
|
26
|
+
createdAt: number;
|
|
27
|
+
updatedAt: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** A cluster of semantically similar unanswered queries */
|
|
31
|
+
export interface QueryCluster {
|
|
32
|
+
id: string;
|
|
33
|
+
label?: string;
|
|
34
|
+
representativeQuery: string;
|
|
35
|
+
centroid?: number[];
|
|
36
|
+
queryCount: number;
|
|
37
|
+
uniqueCustomers: string[];
|
|
38
|
+
status: QueryStatus;
|
|
39
|
+
createdAt: number;
|
|
40
|
+
updatedAt: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Aggregate metrics for the copilot dashboard / digest */
|
|
44
|
+
export interface ImpactMetrics {
|
|
45
|
+
pendingCount: number;
|
|
46
|
+
taughtCount: number;
|
|
47
|
+
dismissedCount: number;
|
|
48
|
+
totalCustomersAffected: number;
|
|
49
|
+
totalTimesAsked: number;
|
|
50
|
+
topPendingQueries: UnansweredQuery[];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Configuration for the copilot subsystem */
|
|
54
|
+
export interface CopilotConfig {
|
|
55
|
+
enabled: boolean;
|
|
56
|
+
trackingThreshold: number;
|
|
57
|
+
clusterThreshold: number;
|
|
58
|
+
digestIntervalMs: number;
|
|
59
|
+
digestMaxItems: number;
|
|
60
|
+
autoSuggest: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Default copilot configuration values */
|
|
64
|
+
export const DEFAULT_COPILOT_CONFIG: CopilotConfig = {
|
|
65
|
+
enabled: false,
|
|
66
|
+
trackingThreshold: 0.70,
|
|
67
|
+
clusterThreshold: 0.87,
|
|
68
|
+
digestIntervalMs: 86_400_000, // 24h
|
|
69
|
+
digestMaxItems: 10,
|
|
70
|
+
autoSuggest: true,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/** Embedding service interface — decouples copilot from specific embedding providers */
|
|
74
|
+
export interface EmbeddingService {
|
|
75
|
+
embed(text: string): Promise<number[]>;
|
|
76
|
+
dimensions: number;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** AI provider interface for suggestion generation */
|
|
80
|
+
export interface AIProviderLike {
|
|
81
|
+
generateText(options: {
|
|
82
|
+
model?: string;
|
|
83
|
+
system?: string;
|
|
84
|
+
prompt: string;
|
|
85
|
+
maxTokens?: number;
|
|
86
|
+
temperature?: number;
|
|
87
|
+
}): Promise<{ text: string }>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Store interface for copilot persistence */
|
|
91
|
+
export interface CopilotStore {
|
|
92
|
+
initialize(): Promise<void>;
|
|
93
|
+
close(): Promise<void>;
|
|
94
|
+
|
|
95
|
+
// Queries
|
|
96
|
+
addQuery(query: UnansweredQuery): Promise<void>;
|
|
97
|
+
getQuery(id: string): Promise<UnansweredQuery | null>;
|
|
98
|
+
updateQuery(id: string, updates: Partial<UnansweredQuery>): Promise<void>;
|
|
99
|
+
getPendingQueries(limit?: number): Promise<UnansweredQuery[]>;
|
|
100
|
+
findSimilarQuery(normalizedQuery: string): Promise<UnansweredQuery | null>;
|
|
101
|
+
getQueriesByCluster(clusterId: string): Promise<UnansweredQuery[]>;
|
|
102
|
+
|
|
103
|
+
// Clusters
|
|
104
|
+
addCluster(cluster: QueryCluster): Promise<void>;
|
|
105
|
+
getCluster(id: string): Promise<QueryCluster | null>;
|
|
106
|
+
updateCluster(id: string, updates: Partial<QueryCluster>): Promise<void>;
|
|
107
|
+
getOpenClusters(): Promise<QueryCluster[]>;
|
|
108
|
+
|
|
109
|
+
// Metrics
|
|
110
|
+
getImpactMetrics(topN?: number): Promise<ImpactMetrics>;
|
|
111
|
+
|
|
112
|
+
// Digest tracking
|
|
113
|
+
getLastDigestTime(): Promise<number>;
|
|
114
|
+
setLastDigestTime(time: number): Promise<void>;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Event emitted after a message is processed by the agent pipeline */
|
|
118
|
+
export interface MessageProcessedEvent {
|
|
119
|
+
query: string;
|
|
120
|
+
channel: string;
|
|
121
|
+
customerPhone: string;
|
|
122
|
+
response: {
|
|
123
|
+
text: string;
|
|
124
|
+
metadata?: {
|
|
125
|
+
kbTopScore?: number;
|
|
126
|
+
kbIsFaqMatch?: boolean;
|
|
127
|
+
kbTopChunkContent?: string;
|
|
128
|
+
kbResultCount?: number;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
}
|
package/tsconfig.json
ADDED