@clowder-ai/connector-dingtalk 0.0.0-stage → 0.1.0-alpha.5

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 (62) hide show
  1. package/README.en.md +54 -0
  2. package/README.md +24 -2
  3. package/assets/icon.svg +4 -0
  4. package/dist/DingTalkAdapter.d.ts +251 -0
  5. package/dist/DingTalkAdapter.d.ts.map +1 -0
  6. package/dist/DingTalkAdapter.js +821 -0
  7. package/dist/DingTalkAdapter.js.map +1 -0
  8. package/dist/command-ingress.d.ts +10 -0
  9. package/dist/command-ingress.d.ts.map +1 -0
  10. package/dist/command-ingress.js +15 -0
  11. package/dist/command-ingress.js.map +1 -0
  12. package/dist/execution-status.d.ts +27 -0
  13. package/dist/execution-status.d.ts.map +1 -0
  14. package/dist/execution-status.js +48 -0
  15. package/dist/execution-status.js.map +1 -0
  16. package/dist/inbound-download.d.ts +13 -0
  17. package/dist/inbound-download.d.ts.map +1 -0
  18. package/dist/inbound-download.js +70 -0
  19. package/dist/inbound-download.js.map +1 -0
  20. package/dist/inbound-media-source.d.ts +25 -0
  21. package/dist/inbound-media-source.d.ts.map +1 -0
  22. package/dist/inbound-media-source.js +115 -0
  23. package/dist/inbound-media-source.js.map +1 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +3 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/lifecycle-action.d.ts +30 -0
  29. package/dist/lifecycle-action.d.ts.map +1 -0
  30. package/dist/lifecycle-action.js +457 -0
  31. package/dist/lifecycle-action.js.map +1 -0
  32. package/dist/materialize-media.d.ts +7 -0
  33. package/dist/materialize-media.d.ts.map +1 -0
  34. package/dist/materialize-media.js +35 -0
  35. package/dist/materialize-media.js.map +1 -0
  36. package/dist/media-notice.d.ts +6 -0
  37. package/dist/media-notice.d.ts.map +1 -0
  38. package/dist/media-notice.js +50 -0
  39. package/dist/media-notice.js.map +1 -0
  40. package/dist/plugin-entrypoint.d.ts +7 -0
  41. package/dist/plugin-entrypoint.d.ts.map +1 -0
  42. package/dist/plugin-entrypoint.js +282 -0
  43. package/dist/plugin-entrypoint.js.map +1 -0
  44. package/dist/reply-sender-map.d.ts +10 -0
  45. package/dist/reply-sender-map.d.ts.map +1 -0
  46. package/dist/reply-sender-map.js +123 -0
  47. package/dist/reply-sender-map.js.map +1 -0
  48. package/dist/runtime.d.ts +68 -0
  49. package/dist/runtime.d.ts.map +1 -0
  50. package/dist/runtime.js +167 -0
  51. package/dist/runtime.js.map +1 -0
  52. package/dist/thread-mappings.d.ts +46 -0
  53. package/dist/thread-mappings.d.ts.map +1 -0
  54. package/dist/thread-mappings.js +62 -0
  55. package/dist/thread-mappings.js.map +1 -0
  56. package/dist/types.d.ts +16 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +2 -0
  59. package/dist/types.js.map +1 -0
  60. package/npm-shrinkwrap.json +485 -0
  61. package/package.json +55 -4
  62. package/plugin.yaml +63 -0
@@ -0,0 +1,167 @@
1
+ import { DingTalkAdapter, } from './DingTalkAdapter.js';
2
+ function required(value, key) {
3
+ const normalized = value.trim();
4
+ if (normalized.length === 0)
5
+ throw new TypeError(`${key} must be a non-empty declared value`);
6
+ return normalized;
7
+ }
8
+ function hostMessage(adapter, message) {
9
+ const attachments = message.attachments
10
+ ?.filter(attachment => attachment.downloadCode !== undefined)
11
+ .map(attachment => ({
12
+ type: attachment.type,
13
+ platformKey: attachment.downloadCode,
14
+ ...(attachment.fileName === undefined ? {} : { fileName: attachment.fileName }),
15
+ ...(attachment.duration === undefined ? {} : { duration: attachment.duration }),
16
+ }));
17
+ const senderName = message.senderNick ?? adapter.resolveSenderName(message.senderId);
18
+ const chatName = message.conversationTitle ?? adapter.resolveConversationTitle(message.chatId);
19
+ const sender = message.chatType === 'group' && message.senderId !== 'unknown'
20
+ ? { id: message.senderId, ...(senderName === undefined ? {} : { name: senderName }) }
21
+ : undefined;
22
+ return {
23
+ externalConversationId: message.chatId,
24
+ providerConversationId: message.conversationId,
25
+ providerMessageId: message.messageId,
26
+ ...(message.senderId === 'unknown' || message.senderId.trim() === '' ? {} : { externalSenderId: message.senderId }),
27
+ text: message.text,
28
+ chatType: message.chatType,
29
+ ...(attachments === undefined ? {} : { attachments }),
30
+ ...(sender === undefined ? {} : { sender }),
31
+ ...(chatName === undefined ? {} : { chatName }),
32
+ };
33
+ }
34
+ /**
35
+ * Composes DingTalk provider I/O from explicit manifest-declared values.
36
+ * Binding lookup, admission, wake policy, retry, and settlement remain Host
37
+ * responsibilities and are intentionally absent from the delivered payload.
38
+ */
39
+ export function createDingTalkConnectorRuntime(options) {
40
+ const config = {
41
+ appKey: required(options.config.appKey, 'appKey'),
42
+ appSecret: required(options.config.appSecret, 'appSecret'),
43
+ ...(options.config.robotCode === undefined ? {} : { robotCode: options.config.robotCode }),
44
+ };
45
+ const createAdapter = options.createAdapter ?? ((value, logger) => new DingTalkAdapter(logger, value));
46
+ const outbound = createAdapter(config, options.logger);
47
+ let state = 'idle';
48
+ let startPromise;
49
+ let stopPromise;
50
+ let watchdogTimer;
51
+ let reconnectTimer;
52
+ const watchdogIntervalMs = options.streamWatchdogIntervalMs ?? 15_000;
53
+ const reconnectBaseDelayMs = options.reconnectDelayMs ?? 5_000;
54
+ const reconnectMaxDelayMs = options.reconnectMaxDelayMs ?? 60_000;
55
+ let reconnectAttempts = 0;
56
+ const nextBackoffMs = () => {
57
+ const exponential = Math.min(reconnectBaseDelayMs * 2 ** reconnectAttempts, reconnectMaxDelayMs);
58
+ reconnectAttempts += 1;
59
+ return Math.round(exponential * (0.8 + Math.random() * 0.4));
60
+ };
61
+ const deliverIfRunning = async (message) => {
62
+ if (state !== 'running')
63
+ return;
64
+ await options.host.deliver(hostMessage(outbound, message));
65
+ };
66
+ // G1: the SDK retries a dropped or revoked-credential stream silently, so
67
+ // the runtime polls the client truth (connected && registered) and owns
68
+ // reconnect supervision: dead stream → state exits 'running' → error log →
69
+ // backoff → drain + fresh startStream, until stop().
70
+ const scheduleReconnect = (reason) => {
71
+ if (state === 'stopped' || reconnectTimer !== undefined)
72
+ return;
73
+ const delayMs = nextBackoffMs();
74
+ options.logger.error(`[DingTalkRuntime] ${reason}; reconnecting in ${delayMs}ms`);
75
+ reconnectTimer = setTimeout(() => {
76
+ reconnectTimer = undefined;
77
+ if (state !== 'idle')
78
+ return; // stop() or a fresh start() superseded it
79
+ state = 'starting';
80
+ startPromise = outbound.stopStream()
81
+ .catch(() => undefined)
82
+ .then(() => outbound.startStream(deliverIfRunning))
83
+ .then(() => {
84
+ if (state !== 'stopped') {
85
+ reconnectAttempts = 0;
86
+ armWatchdog();
87
+ state = 'running';
88
+ options.logger.info('[DingTalkRuntime] Provider stream started');
89
+ }
90
+ })
91
+ .catch((error) => {
92
+ // Timer-context rejection: never rethrow (unhandled rejection);
93
+ // log and reschedule the backoff instead.
94
+ if (state === 'stopped')
95
+ return;
96
+ state = 'idle';
97
+ startPromise = undefined;
98
+ options.logger.error({ error }, '[DingTalkRuntime] Reconnect attempt failed');
99
+ scheduleReconnect('reconnect attempt failed');
100
+ });
101
+ }, delayMs);
102
+ };
103
+ const armWatchdog = () => {
104
+ // Armed only on transitions into 'running': arming at the top of start()
105
+ // leaks the interval for the process lifetime when startStream rejects
106
+ // (the interval keeps the event loop alive even though the runtime
107
+ // never left 'idle').
108
+ if (watchdogTimer !== undefined)
109
+ return;
110
+ watchdogTimer = setInterval(onWatchdog, watchdogIntervalMs);
111
+ };
112
+ const onWatchdog = () => {
113
+ if (state !== 'running' || outbound.isStreamLive())
114
+ return;
115
+ state = 'idle'; // no live inbound during reconnect
116
+ startPromise = undefined;
117
+ scheduleReconnect('provider stream is not live (connected/registered dropped)');
118
+ };
119
+ return {
120
+ outbound,
121
+ start() {
122
+ if (state === 'stopped')
123
+ return Promise.reject(new Error('DingTalk connector runtime has been stopped'));
124
+ if (startPromise !== undefined)
125
+ return startPromise;
126
+ state = 'starting';
127
+ startPromise = outbound
128
+ .startStream(deliverIfRunning)
129
+ .then(() => {
130
+ if (state !== 'stopped') {
131
+ reconnectAttempts = 0;
132
+ armWatchdog();
133
+ state = 'running';
134
+ options.logger.info('[DingTalkRuntime] Provider stream started');
135
+ }
136
+ })
137
+ .catch((error) => {
138
+ if (state !== 'stopped') {
139
+ state = 'idle';
140
+ startPromise = undefined;
141
+ }
142
+ throw error;
143
+ });
144
+ return startPromise;
145
+ },
146
+ stop() {
147
+ if (stopPromise !== undefined)
148
+ return stopPromise;
149
+ if (watchdogTimer !== undefined) {
150
+ clearInterval(watchdogTimer);
151
+ watchdogTimer = undefined;
152
+ }
153
+ if (reconnectTimer !== undefined) {
154
+ clearTimeout(reconnectTimer);
155
+ reconnectTimer = undefined;
156
+ }
157
+ if (state === 'idle') {
158
+ state = 'stopped';
159
+ return Promise.resolve();
160
+ }
161
+ state = 'stopped';
162
+ stopPromise = outbound.stopStream();
163
+ return stopPromise;
164
+ },
165
+ };
166
+ }
167
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { FeatureContext } from '@clowder-ai/plugin-sdk';
2
+ type Mapping = {
3
+ readonly key: string;
4
+ readonly threadId: string;
5
+ readonly createdAt: number;
6
+ };
7
+ type Creation = {
8
+ readonly title: string;
9
+ readonly parentThreadId?: string;
10
+ readonly participants?: readonly string[];
11
+ };
12
+ export declare function threadMappings(context: FeatureContext): {
13
+ findByKey: (name: string) => Promise<import("@clowder-ai/plugin-sdk").PluginThreadSummary | null>;
14
+ bind: (name: string, threadId: string) => Promise<boolean | Mapping>;
15
+ unbind: (name: string) => Promise<boolean | Mapping>;
16
+ listBindings: () => Promise<Mapping[]>;
17
+ ensureByKey: (name: string, input: Creation) => Promise<import("@clowder-ai/plugin-sdk").PluginThreadSummary>;
18
+ ensureSystemThread: () => Promise<import("@clowder-ai/plugin-sdk").PluginThreadSummary>;
19
+ get(threadId: string): Promise<import("@clowder-ai/plugin-sdk").PluginThreadSummary | null>;
20
+ list(options?: {
21
+ readonly limit?: number;
22
+ readonly before?: {
23
+ readonly lastActiveAt: number;
24
+ readonly id: string;
25
+ };
26
+ }): Promise<readonly import("@clowder-ai/plugin-sdk").PluginThreadSummary[]>;
27
+ readMessages(threadId: string, options: {
28
+ readonly before?: {
29
+ readonly timestamp: number;
30
+ readonly id: string;
31
+ };
32
+ readonly limit: number;
33
+ }): Promise<readonly import("@clowder-ai/plugin-sdk").PluginThreadMessage[]>;
34
+ getCats(threadId: string): Promise<import("@clowder-ai/plugin-sdk").PluginThreadCats>;
35
+ addParticipants(input: {
36
+ readonly threadId: string;
37
+ readonly catIds: readonly string[];
38
+ }): Promise<import("@clowder-ai/plugin-sdk").PluginThreadSummary>;
39
+ create(input: import("@clowder-ai/plugin-sdk").PluginThreadCreateInput): Promise<import("@clowder-ai/plugin-sdk").PluginThreadSummary>;
40
+ update(threadId: string, patch: {
41
+ readonly title?: string;
42
+ readonly preferredCats?: readonly string[];
43
+ }): Promise<import("@clowder-ai/plugin-sdk").PluginThreadSummary>;
44
+ };
45
+ export {};
46
+ //# sourceMappingURL=thread-mappings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-mappings.d.ts","sourceRoot":"","sources":["../src/thread-mappings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,KAAK,OAAO,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/F,KAAK,QAAQ,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AA+CxH,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc;sBA/B1B,MAAM;iBAwBjB,MAAM,YAAY,MAAM;mBACtB,MAAM;;wBAVD,MAAM,SAAS,QAAQ;;;;sBAkBT,CAAC;uBAAiC,CAAC;;;;;;uBAG2M,CAAC;;;;;;;;;;;;;sBAA2f,CAAC;8BAAwC,CAAC;;EADzzB"}
@@ -0,0 +1,62 @@
1
+ const contexts = new WeakMap();
2
+ /** Package-owned external-conversation mapping. Host receives ordinary thread calls only. */
3
+ function createMappings(context) {
4
+ const key = 'thread-mappings.v1';
5
+ let tail = Promise.resolve();
6
+ const serialize = (run) => {
7
+ const next = tail.then(run, run);
8
+ tail = next.catch(() => { });
9
+ return next;
10
+ };
11
+ const read = async () => {
12
+ const stored = await context.storage.get(key);
13
+ const rows = stored?.value ?? [];
14
+ if (!Array.isArray(rows) || rows.some(row => !row || typeof row.key !== 'string' || typeof row.threadId !== 'string' || typeof row.createdAt !== 'number'))
15
+ throw new Error('Invalid plugin thread mappings');
16
+ return { stored, rows: rows };
17
+ };
18
+ const find = async (name) => {
19
+ const { rows } = await read();
20
+ const row = rows.find(row => row.key === name);
21
+ return row ? context.threads.get(row.threadId) : null;
22
+ };
23
+ const save = async (name, threadId) => {
24
+ const { stored, rows } = await read();
25
+ const next = rows.filter(row => row.key !== name);
26
+ if (threadId !== null) {
27
+ if (!await context.threads.get(threadId))
28
+ throw new Error('Thread unavailable');
29
+ next.push({ key: name, threadId, createdAt: Date.now() });
30
+ }
31
+ const result = await context.storage.compareAndSet(key, stored?.revision ?? null, next);
32
+ if (!result.applied)
33
+ throw new Error('Plugin thread mappings changed concurrently');
34
+ return threadId === null ? rows.length !== next.length : next.find(row => row.key === name);
35
+ };
36
+ const ensure = (name, input) => serialize(async () => {
37
+ const existing = await find(name);
38
+ if (existing)
39
+ return existing;
40
+ const thread = await context.threads.create(input);
41
+ await save(name, thread.id);
42
+ return thread;
43
+ });
44
+ return {
45
+ ...context.threads,
46
+ findByKey: find,
47
+ bind: (name, threadId) => serialize(() => save(name, threadId)),
48
+ unbind: (name) => serialize(() => save(name, null)),
49
+ listBindings: async () => (await read()).rows,
50
+ ensureByKey: ensure,
51
+ ensureSystemThread: () => ensure('command-audit', { title: '连接器命令记录' }),
52
+ };
53
+ }
54
+ export function threadMappings(context) {
55
+ let value = contexts.get(context);
56
+ if (!value) {
57
+ value = createMappings(context);
58
+ contexts.set(context, value);
59
+ }
60
+ return value;
61
+ }
62
+ //# sourceMappingURL=thread-mappings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thread-mappings.js","sourceRoot":"","sources":["../src/thread-mappings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export type ConnectorLogMethod = (...args: readonly unknown[]) => void;
2
+ export interface ConnectorLogger {
3
+ info: ConnectorLogMethod;
4
+ warn: ConnectorLogMethod;
5
+ error: ConnectorLogMethod;
6
+ debug?: ConnectorLogMethod;
7
+ }
8
+ export type RichBlock = Readonly<Record<string, unknown>>;
9
+ export interface MessageEnvelope {
10
+ header: string;
11
+ body: string;
12
+ origin: 'direct' | 'callback';
13
+ subtitle?: string;
14
+ footer?: string;
15
+ }
16
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,IAAI,CAAC;AAEvE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,kBAAkB,CAAC;IACzB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}