dialog-survey 1.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.
Files changed (233) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/README.md +242 -0
  3. package/VERSION +1 -0
  4. package/dist/api/admin-templates.d.ts +15 -0
  5. package/dist/api/admin-templates.d.ts.map +1 -0
  6. package/dist/api/admin-templates.js +611 -0
  7. package/dist/api/admin-templates.js.map +1 -0
  8. package/dist/api/analysis.d.ts +8 -0
  9. package/dist/api/analysis.d.ts.map +1 -0
  10. package/dist/api/analysis.js +106 -0
  11. package/dist/api/analysis.js.map +1 -0
  12. package/dist/api/health.d.ts +6 -0
  13. package/dist/api/health.d.ts.map +1 -0
  14. package/dist/api/health.js +116 -0
  15. package/dist/api/health.js.map +1 -0
  16. package/dist/api/plans.d.ts +3 -0
  17. package/dist/api/plans.d.ts.map +1 -0
  18. package/dist/api/plans.js +184 -0
  19. package/dist/api/plans.js.map +1 -0
  20. package/dist/api/templates.d.ts +9 -0
  21. package/dist/api/templates.d.ts.map +1 -0
  22. package/dist/api/templates.js +211 -0
  23. package/dist/api/templates.js.map +1 -0
  24. package/dist/core/graph.d.ts +7 -0
  25. package/dist/core/graph.d.ts.map +1 -0
  26. package/dist/core/graph.js +31 -0
  27. package/dist/core/graph.js.map +1 -0
  28. package/dist/core/nodes/analyzing.d.ts +3 -0
  29. package/dist/core/nodes/analyzing.d.ts.map +1 -0
  30. package/dist/core/nodes/analyzing.js +38 -0
  31. package/dist/core/nodes/analyzing.js.map +1 -0
  32. package/dist/core/nodes/completed.d.ts +3 -0
  33. package/dist/core/nodes/completed.d.ts.map +1 -0
  34. package/dist/core/nodes/completed.js +8 -0
  35. package/dist/core/nodes/completed.js.map +1 -0
  36. package/dist/core/nodes/interviewing.d.ts +13 -0
  37. package/dist/core/nodes/interviewing.d.ts.map +1 -0
  38. package/dist/core/nodes/interviewing.js +130 -0
  39. package/dist/core/nodes/interviewing.js.map +1 -0
  40. package/dist/core/nodes/planning.d.ts +15 -0
  41. package/dist/core/nodes/planning.d.ts.map +1 -0
  42. package/dist/core/nodes/planning.js +40 -0
  43. package/dist/core/nodes/planning.js.map +1 -0
  44. package/dist/core/types/index.d.ts +69 -0
  45. package/dist/core/types/index.d.ts.map +1 -0
  46. package/dist/core/types/index.js +49 -0
  47. package/dist/core/types/index.js.map +1 -0
  48. package/dist/domains/interview/entities/interview.entity.d.ts +21 -0
  49. package/dist/domains/interview/entities/interview.entity.d.ts.map +1 -0
  50. package/dist/domains/interview/entities/interview.entity.js +20 -0
  51. package/dist/domains/interview/entities/interview.entity.js.map +1 -0
  52. package/dist/domains/interview/entities/message.entity.d.ts +15 -0
  53. package/dist/domains/interview/entities/message.entity.d.ts.map +1 -0
  54. package/dist/domains/interview/entities/message.entity.js +11 -0
  55. package/dist/domains/interview/entities/message.entity.js.map +1 -0
  56. package/dist/domains/interview/entities/response.entity.d.ts +17 -0
  57. package/dist/domains/interview/entities/response.entity.d.ts.map +1 -0
  58. package/dist/domains/interview/entities/response.entity.js +12 -0
  59. package/dist/domains/interview/entities/response.entity.js.map +1 -0
  60. package/dist/domains/interview/services/interview.domain.d.ts +8 -0
  61. package/dist/domains/interview/services/interview.domain.d.ts.map +1 -0
  62. package/dist/domains/interview/services/interview.domain.js +30 -0
  63. package/dist/domains/interview/services/interview.domain.js.map +1 -0
  64. package/dist/integrations/dingtalk/client.d.ts +32 -0
  65. package/dist/integrations/dingtalk/client.d.ts.map +1 -0
  66. package/dist/integrations/dingtalk/client.js +89 -0
  67. package/dist/integrations/dingtalk/client.js.map +1 -0
  68. package/dist/integrations/dingtalk/message-sender.d.ts +24 -0
  69. package/dist/integrations/dingtalk/message-sender.d.ts.map +1 -0
  70. package/dist/integrations/dingtalk/message-sender.js +81 -0
  71. package/dist/integrations/dingtalk/message-sender.js.map +1 -0
  72. package/dist/integrations/dingtalk/middleware.d.ts +4 -0
  73. package/dist/integrations/dingtalk/middleware.d.ts.map +1 -0
  74. package/dist/integrations/dingtalk/middleware.js +29 -0
  75. package/dist/integrations/dingtalk/middleware.js.map +1 -0
  76. package/dist/integrations/dingtalk/stream-client.d.ts +112 -0
  77. package/dist/integrations/dingtalk/stream-client.d.ts.map +1 -0
  78. package/dist/integrations/dingtalk/stream-client.js +305 -0
  79. package/dist/integrations/dingtalk/stream-client.js.map +1 -0
  80. package/dist/integrations/dingtalk/token-manager.d.ts +22 -0
  81. package/dist/integrations/dingtalk/token-manager.d.ts.map +1 -0
  82. package/dist/integrations/dingtalk/token-manager.js +109 -0
  83. package/dist/integrations/dingtalk/token-manager.js.map +1 -0
  84. package/dist/integrations/llm/alibaba.d.ts +10 -0
  85. package/dist/integrations/llm/alibaba.d.ts.map +1 -0
  86. package/dist/integrations/llm/alibaba.js +60 -0
  87. package/dist/integrations/llm/alibaba.js.map +1 -0
  88. package/dist/integrations/llm/base.d.ts +28 -0
  89. package/dist/integrations/llm/base.d.ts.map +1 -0
  90. package/dist/integrations/llm/base.js +2 -0
  91. package/dist/integrations/llm/base.js.map +1 -0
  92. package/dist/integrations/llm/volcengine.d.ts +12 -0
  93. package/dist/integrations/llm/volcengine.d.ts.map +1 -0
  94. package/dist/integrations/llm/volcengine.js +80 -0
  95. package/dist/integrations/llm/volcengine.js.map +1 -0
  96. package/dist/middleware/admin-auth.d.ts +3 -0
  97. package/dist/middleware/admin-auth.d.ts.map +1 -0
  98. package/dist/middleware/admin-auth.js +37 -0
  99. package/dist/middleware/admin-auth.js.map +1 -0
  100. package/dist/middleware/api-auth.d.ts +10 -0
  101. package/dist/middleware/api-auth.d.ts.map +1 -0
  102. package/dist/middleware/api-auth.js +30 -0
  103. package/dist/middleware/api-auth.js.map +1 -0
  104. package/dist/repositories/interview-state-mapper.d.ts +28 -0
  105. package/dist/repositories/interview-state-mapper.d.ts.map +1 -0
  106. package/dist/repositories/interview-state-mapper.js +32 -0
  107. package/dist/repositories/interview-state-mapper.js.map +1 -0
  108. package/dist/repositories/interview-state.repository.d.ts +34 -0
  109. package/dist/repositories/interview-state.repository.d.ts.map +1 -0
  110. package/dist/repositories/interview-state.repository.js +220 -0
  111. package/dist/repositories/interview-state.repository.js.map +1 -0
  112. package/dist/repositories/interview.repository.d.ts +29 -0
  113. package/dist/repositories/interview.repository.d.ts.map +1 -0
  114. package/dist/repositories/interview.repository.js +36 -0
  115. package/dist/repositories/interview.repository.js.map +1 -0
  116. package/dist/repositories/message.repository.d.ts +17 -0
  117. package/dist/repositories/message.repository.d.ts.map +1 -0
  118. package/dist/repositories/message.repository.js +37 -0
  119. package/dist/repositories/message.repository.js.map +1 -0
  120. package/dist/repositories/template.repository.d.ts +117 -0
  121. package/dist/repositories/template.repository.d.ts.map +1 -0
  122. package/dist/repositories/template.repository.js +280 -0
  123. package/dist/repositories/template.repository.js.map +1 -0
  124. package/dist/schemas/dimensions.d.ts +61 -0
  125. package/dist/schemas/dimensions.d.ts.map +1 -0
  126. package/dist/schemas/dimensions.js +44 -0
  127. package/dist/schemas/dimensions.js.map +1 -0
  128. package/dist/server.d.ts +10 -0
  129. package/dist/server.d.ts.map +1 -0
  130. package/dist/server.js +217 -0
  131. package/dist/server.js.map +1 -0
  132. package/dist/services/analysis.service.d.ts +81 -0
  133. package/dist/services/analysis.service.d.ts.map +1 -0
  134. package/dist/services/analysis.service.js +229 -0
  135. package/dist/services/analysis.service.js.map +1 -0
  136. package/dist/services/analytics.service.d.ts +44 -0
  137. package/dist/services/analytics.service.d.ts.map +1 -0
  138. package/dist/services/analytics.service.js +222 -0
  139. package/dist/services/analytics.service.js.map +1 -0
  140. package/dist/services/asr.service.d.ts +9 -0
  141. package/dist/services/asr.service.d.ts.map +1 -0
  142. package/dist/services/asr.service.js +41 -0
  143. package/dist/services/asr.service.js.map +1 -0
  144. package/dist/services/audit-cleanup.service.d.ts +9 -0
  145. package/dist/services/audit-cleanup.service.d.ts.map +1 -0
  146. package/dist/services/audit-cleanup.service.js +27 -0
  147. package/dist/services/audit-cleanup.service.js.map +1 -0
  148. package/dist/services/batch-aggregation.service.d.ts +34 -0
  149. package/dist/services/batch-aggregation.service.d.ts.map +1 -0
  150. package/dist/services/batch-aggregation.service.js +91 -0
  151. package/dist/services/batch-aggregation.service.js.map +1 -0
  152. package/dist/services/conversation-engine.d.ts +16 -0
  153. package/dist/services/conversation-engine.d.ts.map +1 -0
  154. package/dist/services/conversation-engine.js +49 -0
  155. package/dist/services/conversation-engine.js.map +1 -0
  156. package/dist/services/dead-letter.service.d.ts +12 -0
  157. package/dist/services/dead-letter.service.d.ts.map +1 -0
  158. package/dist/services/dead-letter.service.js +24 -0
  159. package/dist/services/dead-letter.service.js.map +1 -0
  160. package/dist/services/followup.service.d.ts +18 -0
  161. package/dist/services/followup.service.d.ts.map +1 -0
  162. package/dist/services/followup.service.js +146 -0
  163. package/dist/services/followup.service.js.map +1 -0
  164. package/dist/services/interview-plan-base.service.d.ts +226 -0
  165. package/dist/services/interview-plan-base.service.d.ts.map +1 -0
  166. package/dist/services/interview-plan-base.service.js +217 -0
  167. package/dist/services/interview-plan-base.service.js.map +1 -0
  168. package/dist/services/interview-plan-members.service.d.ts +45 -0
  169. package/dist/services/interview-plan-members.service.d.ts.map +1 -0
  170. package/dist/services/interview-plan-members.service.js +237 -0
  171. package/dist/services/interview-plan-members.service.js.map +1 -0
  172. package/dist/services/interview-plan-send.service.d.ts +27 -0
  173. package/dist/services/interview-plan-send.service.d.ts.map +1 -0
  174. package/dist/services/interview-plan-send.service.js +250 -0
  175. package/dist/services/interview-plan-send.service.js.map +1 -0
  176. package/dist/services/interview-plan.service.d.ts +8 -0
  177. package/dist/services/interview-plan.service.d.ts.map +1 -0
  178. package/dist/services/interview-plan.service.js +8 -0
  179. package/dist/services/interview-plan.service.js.map +1 -0
  180. package/dist/services/llm-clustering.d.ts +16 -0
  181. package/dist/services/llm-clustering.d.ts.map +1 -0
  182. package/dist/services/llm-clustering.js +91 -0
  183. package/dist/services/llm-clustering.js.map +1 -0
  184. package/dist/services/prompt.service.d.ts +13 -0
  185. package/dist/services/prompt.service.d.ts.map +1 -0
  186. package/dist/services/prompt.service.js +151 -0
  187. package/dist/services/prompt.service.js.map +1 -0
  188. package/dist/services/report.service.d.ts +28 -0
  189. package/dist/services/report.service.d.ts.map +1 -0
  190. package/dist/services/report.service.js +169 -0
  191. package/dist/services/report.service.js.map +1 -0
  192. package/dist/services/stream-message-utils.d.ts +31 -0
  193. package/dist/services/stream-message-utils.d.ts.map +1 -0
  194. package/dist/services/stream-message-utils.js +80 -0
  195. package/dist/services/stream-message-utils.js.map +1 -0
  196. package/dist/services/stream-message.service.d.ts +29 -0
  197. package/dist/services/stream-message.service.d.ts.map +1 -0
  198. package/dist/services/stream-message.service.js +184 -0
  199. package/dist/services/stream-message.service.js.map +1 -0
  200. package/dist/services/template-dimension.service.d.ts +21 -0
  201. package/dist/services/template-dimension.service.d.ts.map +1 -0
  202. package/dist/services/template-dimension.service.js +9 -0
  203. package/dist/services/template-dimension.service.js.map +1 -0
  204. package/dist/utils/db.d.ts +10 -0
  205. package/dist/utils/db.d.ts.map +1 -0
  206. package/dist/utils/db.js +21 -0
  207. package/dist/utils/db.js.map +1 -0
  208. package/dist/utils/logger.d.ts +8 -0
  209. package/dist/utils/logger.d.ts.map +1 -0
  210. package/dist/utils/logger.js +21 -0
  211. package/dist/utils/logger.js.map +1 -0
  212. package/dist/utils/markdown.d.ts +2 -0
  213. package/dist/utils/markdown.d.ts.map +1 -0
  214. package/dist/utils/markdown.js +39 -0
  215. package/dist/utils/markdown.js.map +1 -0
  216. package/dist/utils/pii-anonymizer.d.ts +2 -0
  217. package/dist/utils/pii-anonymizer.d.ts.map +1 -0
  218. package/dist/utils/pii-anonymizer.js +13 -0
  219. package/dist/utils/pii-anonymizer.js.map +1 -0
  220. package/dist/utils/retry.d.ts +8 -0
  221. package/dist/utils/retry.d.ts.map +1 -0
  222. package/dist/utils/retry.js +28 -0
  223. package/dist/utils/retry.js.map +1 -0
  224. package/dist/utils/security.d.ts +26 -0
  225. package/dist/utils/security.d.ts.map +1 -0
  226. package/dist/utils/security.js +99 -0
  227. package/dist/utils/security.js.map +1 -0
  228. package/package.json +80 -0
  229. package/prisma/schema.prisma +228 -0
  230. package/public/css/admin.css +73 -0
  231. package/public/js/alpine.min.js +2670 -0
  232. package/public/js/htmx.min.js +3422 -0
  233. package/scripts/cli.mjs +794 -0
@@ -0,0 +1,305 @@
1
+ import { WebSocket } from 'ws';
2
+ import { debug, error, info } from '../../utils/logger.js';
3
+ const CIRCUIT_COOLDOWN_MS = 30000;
4
+ const FAILURE_THRESHOLD = 3;
5
+ export class DingTalkStreamClient {
6
+ config;
7
+ options;
8
+ ws = null;
9
+ connected = false;
10
+ reconnectAttempts = 0;
11
+ eventHandlers = new Map();
12
+ circuitState = 'CLOSED';
13
+ circuitOpenedAt = null;
14
+ failureCount = 0;
15
+ constructor(config, options = {}) {
16
+ if (!config.clientId) {
17
+ throw new Error('clientId is required');
18
+ }
19
+ if (!config.clientSecret) {
20
+ throw new Error('clientSecret is required');
21
+ }
22
+ this.config = config;
23
+ this.options = {
24
+ maxReconnectAttempts: options.maxReconnectAttempts ?? 3,
25
+ };
26
+ }
27
+ /**
28
+ * Create client from environment variables
29
+ */
30
+ static fromEnv() {
31
+ const clientId = process.env.DINGTALK_CLIENT_ID || '';
32
+ const clientSecret = process.env.DINGTALK_CLIENT_SECRET || '';
33
+ const agentId = process.env.DINGTALK_AGENT_ID;
34
+ return new DingTalkStreamClient({ clientId, clientSecret, agentId });
35
+ }
36
+ /**
37
+ * Get connection token from DingTalk API
38
+ */
39
+ async getConnectionToken() {
40
+ const url = 'https://api.dingtalk.com/v1.0/gateway/connections/open';
41
+ const body = {
42
+ clientId: this.config.clientId,
43
+ clientSecret: this.config.clientSecret,
44
+ subscriptions: [
45
+ {
46
+ topic: '/v1.0/im/bot/messages/get',
47
+ type: 'CALLBACK',
48
+ },
49
+ ],
50
+ ua: 'bot',
51
+ };
52
+ try {
53
+ const response = await fetch(url, {
54
+ method: 'POST',
55
+ headers: {
56
+ 'Content-Type': 'application/json',
57
+ },
58
+ body: JSON.stringify(body),
59
+ });
60
+ if (!response.ok) {
61
+ throw new Error(`Failed to get connection token: ${response.status} ${response.statusText}`);
62
+ }
63
+ const data = (await response.json());
64
+ if (!data.endpoint || !data.ticket) {
65
+ throw new Error('endpoint or ticket missing in response');
66
+ }
67
+ debug('Got connection token', { endpoint: data.endpoint });
68
+ return data;
69
+ }
70
+ catch (err) {
71
+ const errMsg = err instanceof Error ? err.message : 'Unknown error';
72
+ error('Failed to get connection token', { error: errMsg });
73
+ throw err;
74
+ }
75
+ }
76
+ /**
77
+ * Build WebSocket URL from connection token
78
+ */
79
+ buildWebSocketUrl(token) {
80
+ return `${token.endpoint}?ticket=${token.ticket}`;
81
+ }
82
+ /**
83
+ * Connect to DingTalk Stream
84
+ */
85
+ async connect() {
86
+ if (this.connected && this.ws) {
87
+ info('Already connected');
88
+ return;
89
+ }
90
+ const token = await this.getConnectionToken();
91
+ const wsUrl = this.buildWebSocketUrl(token);
92
+ info('Connecting to DingTalk Stream', { endpoint: token.endpoint });
93
+ this.ws = new WebSocket(wsUrl);
94
+ this.ws.on('open', () => {
95
+ this.connected = true;
96
+ this.reconnectAttempts = 0;
97
+ info('Connected to DingTalk Stream');
98
+ this.emit('connected', {});
99
+ });
100
+ this.ws.on('message', (data) => {
101
+ this.handleMessage(data);
102
+ });
103
+ this.ws.on('error', (err) => {
104
+ error('WebSocket error', { error: err.message });
105
+ this.emit('error', err);
106
+ });
107
+ this.ws.on('close', (code, reason) => {
108
+ this.connected = false;
109
+ this.failureCount++;
110
+ info('WebSocket connection closed', {
111
+ code,
112
+ reason: reason.toString(),
113
+ failureCount: this.failureCount,
114
+ });
115
+ this.emit('disconnected', { code, reason: reason.toString() });
116
+ if (this.circuitState === 'CLOSED' && this.failureCount >= FAILURE_THRESHOLD) {
117
+ this.circuitState = 'OPEN';
118
+ this.circuitOpenedAt = Date.now();
119
+ info('Circuit breaker OPEN', { cooldownMs: CIRCUIT_COOLDOWN_MS });
120
+ return;
121
+ }
122
+ if (this.circuitState === 'HALF_OPEN') {
123
+ this.circuitState = 'OPEN';
124
+ this.circuitOpenedAt = Date.now();
125
+ return;
126
+ }
127
+ const maxAttempts = this.options.maxReconnectAttempts ?? 3;
128
+ if (this.reconnectAttempts < maxAttempts) {
129
+ this.reconnect();
130
+ }
131
+ });
132
+ }
133
+ /**
134
+ * Handle incoming WebSocket message
135
+ */
136
+ handleMessage(data) {
137
+ try {
138
+ const message = this.parseMessage(data.toString());
139
+ info('Received message', {
140
+ topic: message.headers.topic,
141
+ messageId: message.headers.messageId,
142
+ });
143
+ this.emit('message', message);
144
+ this.sendAck(message.headers.messageId);
145
+ }
146
+ catch (err) {
147
+ const errMsg = err instanceof Error ? err.message : 'Unknown error';
148
+ error('Failed to handle message', { error: errMsg });
149
+ this.emit('error', err);
150
+ }
151
+ }
152
+ /**
153
+ * Parse incoming message
154
+ */
155
+ parseMessage(data) {
156
+ return JSON.parse(data);
157
+ }
158
+ /**
159
+ * Build ACK response
160
+ */
161
+ buildAck(messageId) {
162
+ return {
163
+ code: 200,
164
+ headers: {
165
+ messageId,
166
+ },
167
+ message: 'OK',
168
+ data: '{}',
169
+ };
170
+ }
171
+ /**
172
+ * Send ACK response
173
+ */
174
+ sendAck(messageId) {
175
+ if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
176
+ return;
177
+ }
178
+ const ack = this.buildAck(messageId);
179
+ this.ws.send(JSON.stringify(ack));
180
+ debug('Sent ACK', { messageId });
181
+ }
182
+ /**
183
+ * Send text message via session webhook
184
+ */
185
+ async sendText(sessionWebhook, content) {
186
+ if (!sessionWebhook) {
187
+ throw new Error('sessionWebhook is required');
188
+ }
189
+ if (!content) {
190
+ throw new Error('content is required');
191
+ }
192
+ const body = {
193
+ msgtype: 'text',
194
+ text: { content },
195
+ };
196
+ const response = await fetch(sessionWebhook, {
197
+ method: 'POST',
198
+ headers: {
199
+ 'Content-Type': 'application/json',
200
+ },
201
+ body: JSON.stringify(body),
202
+ });
203
+ if (!response.ok) {
204
+ throw new Error(`Failed to send message: ${response.status} ${response.statusText}`);
205
+ }
206
+ debug('Sent text message', {
207
+ sessionWebhook,
208
+ contentLength: content.length,
209
+ });
210
+ }
211
+ /**
212
+ * Reconnect to DingTalk Stream
213
+ */
214
+ reconnect() {
215
+ if (this.circuitState === 'OPEN' && this.circuitOpenedAt) {
216
+ const elapsed = Date.now() - this.circuitOpenedAt;
217
+ if (elapsed < CIRCUIT_COOLDOWN_MS) {
218
+ debug('Circuit open, skipping reconnect', { remainingMs: CIRCUIT_COOLDOWN_MS - elapsed });
219
+ return;
220
+ }
221
+ this.circuitState = 'HALF_OPEN';
222
+ this.failureCount = 0;
223
+ }
224
+ this.reconnectAttempts++;
225
+ info('Reconnecting', { attempt: this.reconnectAttempts });
226
+ setTimeout(() => {
227
+ this.connect().catch((err) => {
228
+ const errMsg = err instanceof Error ? err.message : 'Unknown error';
229
+ error('Reconnection failed', { error: errMsg });
230
+ });
231
+ }, 1000 * this.reconnectAttempts);
232
+ }
233
+ /**
234
+ * Disconnect from DingTalk Stream
235
+ */
236
+ disconnect() {
237
+ if (this.ws) {
238
+ this.ws.close();
239
+ this.ws = null;
240
+ this.connected = false;
241
+ this.reconnectAttempts = 0;
242
+ info('Disconnected from DingTalk Stream');
243
+ }
244
+ }
245
+ /**
246
+ * Check if connected
247
+ */
248
+ isConnected() {
249
+ return this.connected;
250
+ }
251
+ /**
252
+ * Get current reconnect attempts
253
+ */
254
+ getReconnectAttempts() {
255
+ return this.reconnectAttempts;
256
+ }
257
+ /**
258
+ * Get max reconnect attempts
259
+ */
260
+ getMaxReconnectAttempts() {
261
+ return this.options.maxReconnectAttempts ?? 3;
262
+ }
263
+ /**
264
+ * Register event handler
265
+ */
266
+ on(event, handler) {
267
+ if (!this.eventHandlers.has(event)) {
268
+ this.eventHandlers.set(event, []);
269
+ }
270
+ const handlersForEvent = this.eventHandlers.get(event);
271
+ if (handlersForEvent) {
272
+ handlersForEvent.push(handler);
273
+ }
274
+ }
275
+ /**
276
+ * Unregister event handler
277
+ */
278
+ off(event, handler) {
279
+ const handlers = this.eventHandlers.get(event);
280
+ if (handlers) {
281
+ const index = handlers.indexOf(handler);
282
+ if (index > -1) {
283
+ handlers.splice(index, 1);
284
+ }
285
+ }
286
+ }
287
+ /**
288
+ * Emit event
289
+ */
290
+ emit(event, data) {
291
+ const handlers = this.eventHandlers.get(event);
292
+ if (handlers) {
293
+ for (const handler of handlers) {
294
+ try {
295
+ handler(data);
296
+ }
297
+ catch (err) {
298
+ const errMsg = err instanceof Error ? err.message : 'Unknown error';
299
+ error('Event handler error', { event, error: errMsg });
300
+ }
301
+ }
302
+ }
303
+ }
304
+ }
305
+ //# sourceMappingURL=stream-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-client.js","sourceRoot":"","sources":["../../../src/integrations/dingtalk/stream-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface TokenManager {
2
+ getAccessToken(): Promise<string>;
3
+ invalidateToken(): void;
4
+ }
5
+ export declare class DingTalkTokenManager implements TokenManager {
6
+ private cachedToken;
7
+ private tokenExpiryTime;
8
+ private isRefreshing;
9
+ private refreshPromise;
10
+ getAccessToken(): Promise<string>;
11
+ private validateCredentials;
12
+ private getValidCachedToken;
13
+ private refreshToken;
14
+ private fetchWithRetry;
15
+ private tryFetch;
16
+ private validateTokenResponse;
17
+ private doFetch;
18
+ private delay;
19
+ invalidateToken(): void;
20
+ }
21
+ export declare const tokenManager: DingTalkTokenManager;
22
+ //# sourceMappingURL=token-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-manager.d.ts","sourceRoot":"","sources":["../../../src/integrations/dingtalk/token-manager.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,eAAe,IAAI,IAAI,CAAC;CACzB;AAKD,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAAgC;IAEhD,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAUvC,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,mBAAmB;YAMb,YAAY;YAoBZ,cAAc;YAWd,QAAQ;IAiBtB,OAAO,CAAC,qBAAqB;YAUf,OAAO;IAWrB,OAAO,CAAC,KAAK;IAIb,eAAe,IAAI,IAAI;CAKxB;AAED,eAAO,MAAM,YAAY,sBAA6B,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { error, info, warn } from '../../utils/logger.js';
2
+ const TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1000;
3
+ const TOKEN_MAX_RETRIES = 2;
4
+ export class DingTalkTokenManager {
5
+ cachedToken = null;
6
+ tokenExpiryTime = null;
7
+ isRefreshing = false;
8
+ refreshPromise = null;
9
+ async getAccessToken() {
10
+ this.validateCredentials();
11
+ const cached = this.getValidCachedToken();
12
+ if (cached)
13
+ return cached;
14
+ if (this.isRefreshing && this.refreshPromise) {
15
+ return this.refreshPromise;
16
+ }
17
+ return this.refreshToken();
18
+ }
19
+ validateCredentials() {
20
+ const id = process.env.DINGTALK_CLIENT_ID;
21
+ const secret = process.env.DINGTALK_CLIENT_SECRET;
22
+ if (!id || !secret) {
23
+ throw new Error('DINGTALK_CLIENT_ID and DINGTALK_CLIENT_SECRET must be set in environment variables');
24
+ }
25
+ }
26
+ getValidCachedToken() {
27
+ if (!this.cachedToken || !this.tokenExpiryTime)
28
+ return null;
29
+ if (Date.now() >= this.tokenExpiryTime - TOKEN_REFRESH_BUFFER_MS)
30
+ return null;
31
+ return this.cachedToken;
32
+ }
33
+ async refreshToken() {
34
+ this.isRefreshing = true;
35
+ try {
36
+ this.refreshPromise = this.fetchWithRetry().then((token) => {
37
+ this.cachedToken = token.access_token;
38
+ this.tokenExpiryTime = Date.now() + token.expires_in * 1000;
39
+ info('Successfully refreshed access token');
40
+ return token.access_token;
41
+ });
42
+ return await this.refreshPromise;
43
+ }
44
+ catch (err) {
45
+ const errMsg = err instanceof Error ? err.message : String(err);
46
+ error('Failed to refresh access token', { error: errMsg });
47
+ throw new Error(`Failed to get DingTalk access token: ${errMsg}`);
48
+ }
49
+ finally {
50
+ this.isRefreshing = false;
51
+ this.refreshPromise = null;
52
+ }
53
+ }
54
+ async fetchWithRetry() {
55
+ let attempt = 0;
56
+ while (true) {
57
+ const result = await this.tryFetch();
58
+ if (result.ok)
59
+ return result.token;
60
+ attempt++;
61
+ if (attempt > TOKEN_MAX_RETRIES)
62
+ throw result.error;
63
+ await this.delay(2 ** attempt * 1000);
64
+ }
65
+ }
66
+ async tryFetch() {
67
+ try {
68
+ const token = await this.doFetch();
69
+ const validationError = this.validateTokenResponse(token);
70
+ if (validationError)
71
+ return { ok: false, token, error: validationError };
72
+ return { ok: true, token, error: new Error('unreachable') };
73
+ }
74
+ catch (err) {
75
+ const e = err instanceof Error ? err : new Error(String(err));
76
+ warn('Fetch attempt failed', { error: e.message });
77
+ return { ok: false, token: {}, error: e };
78
+ }
79
+ }
80
+ validateTokenResponse(token) {
81
+ if (token.errcode !== 0) {
82
+ return new Error(`DingTalk API error: ${token.errmsg} (code: ${token.errcode})`);
83
+ }
84
+ if (!token.access_token) {
85
+ return new Error('Access token not found in response');
86
+ }
87
+ return null;
88
+ }
89
+ async doFetch() {
90
+ const id = process.env.DINGTALK_CLIENT_ID ?? '';
91
+ const secret = process.env.DINGTALK_CLIENT_SECRET ?? '';
92
+ const url = `https://oapi.dingtalk.com/gettoken?appkey=${encodeURIComponent(id)}&appsecret=${encodeURIComponent(secret)}`;
93
+ const response = await fetch(url);
94
+ if (!response.ok) {
95
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
96
+ }
97
+ return (await response.json());
98
+ }
99
+ delay(ms) {
100
+ return new Promise((resolve) => setTimeout(resolve, ms));
101
+ }
102
+ invalidateToken() {
103
+ info('Invalidating cached access token');
104
+ this.cachedToken = null;
105
+ this.tokenExpiryTime = null;
106
+ }
107
+ }
108
+ export const tokenManager = new DingTalkTokenManager();
109
+ //# sourceMappingURL=token-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-manager.js","sourceRoot":"","sources":["../../../src/integrations/dingtalk/token-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { LLMOptions, LLMRequest, LLMResponse, LLMService } from './base.js';
2
+ export declare class AlibabaLLM implements LLMService {
3
+ private apiKey;
4
+ private model;
5
+ constructor(options: LLMOptions);
6
+ chat(request: LLMRequest): Promise<LLMResponse>;
7
+ embeddings(text: string): Promise<number[]>;
8
+ static fromEnv(): AlibabaLLM;
9
+ }
10
+ //# sourceMappingURL=alibaba.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alibaba.d.ts","sourceRoot":"","sources":["../../../src/integrations/llm/alibaba.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAO5E,qBAAa,UAAW,YAAW,UAAU;IAC3C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,EAAE,UAAU;IAKzB,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IA8B/C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAuBjD,MAAM,CAAC,OAAO,IAAI,UAAU;CAM7B"}
@@ -0,0 +1,60 @@
1
+ const CHAT_API_URL = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation';
2
+ const EMBEDDINGS_URL = 'https://dashscope.aliyuncs.com/api/v1/services/embeddings/text-embedding/text-embedding';
3
+ export class AlibabaLLM {
4
+ apiKey;
5
+ model;
6
+ constructor(options) {
7
+ this.apiKey = options.apiKey;
8
+ this.model = options.model || 'qwen-turbo';
9
+ }
10
+ async chat(request) {
11
+ const response = await fetch(CHAT_API_URL, {
12
+ method: 'POST',
13
+ headers: {
14
+ Authorization: `Bearer ${this.apiKey}`,
15
+ 'Content-Type': 'application/json',
16
+ },
17
+ body: JSON.stringify({
18
+ model: request.model || this.model,
19
+ input: { messages: request.messages },
20
+ parameters: {
21
+ temperature: request.temperature || 0.7,
22
+ max_tokens: request.max_tokens || 2000,
23
+ },
24
+ }),
25
+ });
26
+ if (!response.ok) {
27
+ throw new Error(`LLM API error: ${response.status}`);
28
+ }
29
+ const data = (await response.json());
30
+ return {
31
+ content: data.output?.text || '',
32
+ finishReason: data.output?.finish_reason || 'stop',
33
+ };
34
+ }
35
+ async embeddings(text) {
36
+ const response = await fetch(EMBEDDINGS_URL, {
37
+ method: 'POST',
38
+ headers: {
39
+ Authorization: `Bearer ${this.apiKey}`,
40
+ 'Content-Type': 'application/json',
41
+ },
42
+ body: JSON.stringify({
43
+ model: 'text-embedding-v3',
44
+ input: text,
45
+ }),
46
+ });
47
+ if (!response.ok) {
48
+ throw new Error(`Embeddings API error: ${response.status}`);
49
+ }
50
+ const data = (await response.json());
51
+ return data.output?.embeddings?.[0]?.embedding || [];
52
+ }
53
+ static fromEnv() {
54
+ return new AlibabaLLM({
55
+ apiKey: process.env.DASHSCOPE_API_KEY || '',
56
+ model: 'qwen-turbo',
57
+ });
58
+ }
59
+ }
60
+ //# sourceMappingURL=alibaba.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alibaba.js","sourceRoot":"","sources":["../../../src/integrations/llm/alibaba.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAChB,gFAAgF,CAAC;AACnF,MAAM,cAAc,GAClB,yFAAyF,CAAC;AAE5F,MAAM,OAAO,UAAU;IACb,MAAM,CAAS;IACf,KAAK,CAAS;IAEtB,YAAY,OAAmB;QAC7B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAmB;QAC5B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;gBACtC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK;gBAClC,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE;gBACrC,UAAU,EAAE;oBACV,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,GAAG;oBACvC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;iBACvC;aACF,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,kBAAkB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAElC,CAAC;QACF,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE;YAChC,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,aAAa,IAAI,MAAM;SACnD,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAY;QAC3B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,cAAc,EAAE;YAC3C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;gBACtC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,mBAAmB;gBAC1B,KAAK,EAAE,IAAI;aACZ,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAElC,CAAC;QACF,OAAO,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,OAAO;QACZ,OAAO,IAAI,UAAU,CAAC;YACpB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE;YAC3C,KAAK,EAAE,YAAY;SACpB,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,28 @@
1
+ export interface LLMMessage {
2
+ role: 'system' | 'user' | 'assistant';
3
+ content: string;
4
+ }
5
+ export interface LLMRequest {
6
+ model?: string;
7
+ messages: LLMMessage[];
8
+ temperature?: number;
9
+ max_tokens?: number;
10
+ }
11
+ export interface LLMResponse {
12
+ content: string;
13
+ finishReason: string;
14
+ usage?: {
15
+ promptTokens: number;
16
+ completionTokens: number;
17
+ };
18
+ }
19
+ export interface LLMService {
20
+ chat(request: LLMRequest): Promise<LLMResponse>;
21
+ embeddings(text: string): Promise<number[]>;
22
+ }
23
+ export interface LLMOptions {
24
+ apiKey: string;
25
+ baseUrl?: string;
26
+ model?: string;
27
+ }
28
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/integrations/llm/base.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/integrations/llm/base.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { LLMOptions, LLMRequest, LLMResponse, LLMService } from './base.js';
2
+ export declare const DEFAULT_MODEL = "deepseek-v3.2";
3
+ export declare class VolcengineLLM implements LLMService {
4
+ private apiKey;
5
+ private baseUrl;
6
+ private model;
7
+ constructor(options: LLMOptions);
8
+ chat(request: LLMRequest): Promise<LLMResponse>;
9
+ embeddings(_text: string): Promise<number[]>;
10
+ static fromEnv(): VolcengineLLM;
11
+ }
12
+ //# sourceMappingURL=volcengine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"volcengine.d.ts","sourceRoot":"","sources":["../../../src/integrations/llm/volcengine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAM5E,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,qBAAa,aAAc,YAAW,UAAU;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,EAAE,UAAU;IAMzB,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IA2D/C,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKlD,MAAM,CAAC,OAAO,IAAI,aAAa;CAsBhC"}