@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/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
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src/**/*"],
8
+ "exclude": ["node_modules", "dist"]
9
+ }
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'tsdown';
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['esm'],
6
+ dts: true,
7
+ clean: true,
8
+ sourcemap: true,
9
+ outExtensions: () => ({ js: '.js', dts: '.d.ts' }),
10
+ });