ylib-wecom-openclaw-plugin 2026.4.29

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 (180) hide show
  1. package/README.md +596 -0
  2. package/dist/index.d.ts +10 -0
  3. package/dist/index.js +99 -0
  4. package/dist/src/accounts.d.ts +57 -0
  5. package/dist/src/accounts.js +247 -0
  6. package/dist/src/agent/api-client.d.ts +95 -0
  7. package/dist/src/agent/api-client.js +425 -0
  8. package/dist/src/agent/handler.d.ts +64 -0
  9. package/dist/src/agent/handler.js +731 -0
  10. package/dist/src/agent/index.d.ts +5 -0
  11. package/dist/src/agent/index.js +21 -0
  12. package/dist/src/agent/webhook.d.ts +25 -0
  13. package/dist/src/agent/webhook.js +294 -0
  14. package/dist/src/agent/xml.d.ts +21 -0
  15. package/dist/src/agent/xml.js +43 -0
  16. package/dist/src/channel.d.ts +5 -0
  17. package/dist/src/channel.js +815 -0
  18. package/dist/src/chat-queue.d.ts +31 -0
  19. package/dist/src/chat-queue.js +53 -0
  20. package/dist/src/config-schema.d.ts +587 -0
  21. package/dist/src/config-schema.js +146 -0
  22. package/dist/src/const.d.ts +128 -0
  23. package/dist/src/const.js +168 -0
  24. package/dist/src/dm-policy.d.ts +29 -0
  25. package/dist/src/dm-policy.js +146 -0
  26. package/dist/src/dynamic-agent.d.ts +37 -0
  27. package/dist/src/dynamic-agent.js +67 -0
  28. package/dist/src/dynamic-routing.d.ts +65 -0
  29. package/dist/src/dynamic-routing.js +62 -0
  30. package/dist/src/endpoint-dispatch.d.ts +54 -0
  31. package/dist/src/endpoint-dispatch.js +967 -0
  32. package/dist/src/endpoint-event-adapter.d.ts +15 -0
  33. package/dist/src/endpoint-event-adapter.js +427 -0
  34. package/dist/src/group-policy.d.ts +30 -0
  35. package/dist/src/group-policy.js +126 -0
  36. package/dist/src/http.d.ts +27 -0
  37. package/dist/src/http.js +168 -0
  38. package/dist/src/im-runtime-telemetry.d.ts +25 -0
  39. package/dist/src/im-runtime-telemetry.js +68 -0
  40. package/dist/src/interface.d.ts +192 -0
  41. package/dist/src/interface.js +5 -0
  42. package/dist/src/markdown-chunk.d.ts +1 -0
  43. package/dist/src/markdown-chunk.js +396 -0
  44. package/dist/src/mcp/index.d.ts +6 -0
  45. package/dist/src/mcp/index.js +28 -0
  46. package/dist/src/mcp/interceptors/biz-error.d.ts +11 -0
  47. package/dist/src/mcp/interceptors/biz-error.js +73 -0
  48. package/dist/src/mcp/interceptors/doc-auth-error.d.ts +10 -0
  49. package/dist/src/mcp/interceptors/doc-auth-error.js +235 -0
  50. package/dist/src/mcp/interceptors/index.d.ts +35 -0
  51. package/dist/src/mcp/interceptors/index.js +143 -0
  52. package/dist/src/mcp/interceptors/msg-media.d.ts +11 -0
  53. package/dist/src/mcp/interceptors/msg-media.js +201 -0
  54. package/dist/src/mcp/interceptors/smartpage-create.d.ts +30 -0
  55. package/dist/src/mcp/interceptors/smartpage-create.js +252 -0
  56. package/dist/src/mcp/interceptors/smartpage-export.d.ts +17 -0
  57. package/dist/src/mcp/interceptors/smartpage-export.js +135 -0
  58. package/dist/src/mcp/interceptors/smartsheet-upload.d.ts +22 -0
  59. package/dist/src/mcp/interceptors/smartsheet-upload.js +388 -0
  60. package/dist/src/mcp/interceptors/types.d.ts +64 -0
  61. package/dist/src/mcp/interceptors/types.js +8 -0
  62. package/dist/src/mcp/schema.d.ts +11 -0
  63. package/dist/src/mcp/schema.js +115 -0
  64. package/dist/src/mcp/tool.d.ts +63 -0
  65. package/dist/src/mcp/tool.js +318 -0
  66. package/dist/src/mcp/transport.d.ts +94 -0
  67. package/dist/src/mcp/transport.js +702 -0
  68. package/dist/src/media-handler.d.ts +55 -0
  69. package/dist/src/media-handler.js +306 -0
  70. package/dist/src/media-uploader.d.ts +142 -0
  71. package/dist/src/media-uploader.js +446 -0
  72. package/dist/src/message-parser.d.ts +104 -0
  73. package/dist/src/message-parser.js +232 -0
  74. package/dist/src/message-sender.d.ts +54 -0
  75. package/dist/src/message-sender.js +210 -0
  76. package/dist/src/monitor.d.ts +69 -0
  77. package/dist/src/monitor.js +1846 -0
  78. package/dist/src/onboarding.d.ts +8 -0
  79. package/dist/src/onboarding.js +248 -0
  80. package/dist/src/openclaw-compat.d.ts +148 -0
  81. package/dist/src/openclaw-compat.js +839 -0
  82. package/dist/src/proactive-markdown-send.d.ts +14 -0
  83. package/dist/src/proactive-markdown-send.js +205 -0
  84. package/dist/src/reqid-store.d.ts +23 -0
  85. package/dist/src/reqid-store.js +136 -0
  86. package/dist/src/runtime.d.ts +2 -0
  87. package/dist/src/runtime.js +7 -0
  88. package/dist/src/shared/command-auth.d.ts +23 -0
  89. package/dist/src/shared/command-auth.js +112 -0
  90. package/dist/src/shared/xml-parser.d.ts +46 -0
  91. package/dist/src/shared/xml-parser.js +228 -0
  92. package/dist/src/state-dir-resolve.d.ts +2 -0
  93. package/dist/src/state-dir-resolve.js +33 -0
  94. package/dist/src/state-manager.d.ts +115 -0
  95. package/dist/src/state-manager.js +413 -0
  96. package/dist/src/target.d.ts +35 -0
  97. package/dist/src/target.js +71 -0
  98. package/dist/src/template-card-manager.d.ts +55 -0
  99. package/dist/src/template-card-manager.js +316 -0
  100. package/dist/src/template-card-parser.d.ts +37 -0
  101. package/dist/src/template-card-parser.js +672 -0
  102. package/dist/src/timeout.d.ts +20 -0
  103. package/dist/src/timeout.js +57 -0
  104. package/dist/src/types/account.d.ts +29 -0
  105. package/dist/src/types/account.js +5 -0
  106. package/dist/src/types/config.d.ts +98 -0
  107. package/dist/src/types/config.js +8 -0
  108. package/dist/src/types/constants.d.ts +42 -0
  109. package/dist/src/types/constants.js +45 -0
  110. package/dist/src/types/index.d.ts +7 -0
  111. package/dist/src/types/index.js +17 -0
  112. package/dist/src/types/message.d.ts +238 -0
  113. package/dist/src/types/message.js +6 -0
  114. package/dist/src/utils.d.ts +148 -0
  115. package/dist/src/utils.js +92 -0
  116. package/dist/src/version.d.ts +2 -0
  117. package/dist/src/version.js +28 -0
  118. package/dist/src/webhook/command-auth.d.ts +47 -0
  119. package/dist/src/webhook/command-auth.js +137 -0
  120. package/dist/src/webhook/gateway.d.ts +36 -0
  121. package/dist/src/webhook/gateway.js +297 -0
  122. package/dist/src/webhook/handler.d.ts +19 -0
  123. package/dist/src/webhook/handler.js +481 -0
  124. package/dist/src/webhook/helpers.d.ts +157 -0
  125. package/dist/src/webhook/helpers.js +936 -0
  126. package/dist/src/webhook/http.d.ts +27 -0
  127. package/dist/src/webhook/http.js +168 -0
  128. package/dist/src/webhook/index.d.ts +11 -0
  129. package/dist/src/webhook/index.js +43 -0
  130. package/dist/src/webhook/media.d.ts +30 -0
  131. package/dist/src/webhook/media.js +152 -0
  132. package/dist/src/webhook/monitor.d.ts +59 -0
  133. package/dist/src/webhook/monitor.js +1672 -0
  134. package/dist/src/webhook/state.d.ts +220 -0
  135. package/dist/src/webhook/state.js +568 -0
  136. package/dist/src/webhook/target.d.ts +41 -0
  137. package/dist/src/webhook/target.js +165 -0
  138. package/dist/src/webhook/types.d.ts +348 -0
  139. package/dist/src/webhook/types.js +36 -0
  140. package/dist/src/webhook/video-frame.d.ts +13 -0
  141. package/dist/src/webhook/video-frame.js +108 -0
  142. package/openclaw.plugin.json +19 -0
  143. package/package.json +96 -0
  144. package/schema.json +534 -0
  145. package/scripts/generate-schema.mjs +33 -0
  146. package/skills/wecom-contact/SKILL.md +162 -0
  147. package/skills/wecom-doc/SKILL.md +162 -0
  148. package/skills/wecom-doc/references/create-doc.md +56 -0
  149. package/skills/wecom-doc/references/edit-doc-content.md +68 -0
  150. package/skills/wecom-doc/references/get-doc-content.md +88 -0
  151. package/skills/wecom-doc/references/smartpage-create.md +125 -0
  152. package/skills/wecom-doc/references/smartpage-export.md +160 -0
  153. package/skills/wecom-meeting/SKILL.md +441 -0
  154. package/skills/wecom-meeting/references/example-full.md +30 -0
  155. package/skills/wecom-meeting/references/example-reminder.md +46 -0
  156. package/skills/wecom-meeting/references/example-security.md +22 -0
  157. package/skills/wecom-meeting/references/response-get-meeting-info.md +148 -0
  158. package/skills/wecom-msg/SKILL.md +157 -0
  159. package/skills/wecom-msg/references/api-get-messages.md +93 -0
  160. package/skills/wecom-msg/references/api-get-msg-chat-list.md +58 -0
  161. package/skills/wecom-msg/references/api-get-msg-media.md +44 -0
  162. package/skills/wecom-msg/references/api-send-message.md +39 -0
  163. package/skills/wecom-preflight/SKILL.md +141 -0
  164. package/skills/wecom-schedule/SKILL.md +161 -0
  165. package/skills/wecom-schedule/references/api-check-availability.md +56 -0
  166. package/skills/wecom-schedule/references/api-create-schedule.md +38 -0
  167. package/skills/wecom-schedule/references/api-get-schedule-detail.md +81 -0
  168. package/skills/wecom-schedule/references/api-update-schedule.md +32 -0
  169. package/skills/wecom-schedule/references/ref-reminders.md +24 -0
  170. package/skills/wecom-send-media/SKILL.md +68 -0
  171. package/skills/wecom-send-template-card/SKILL.md +157 -0
  172. package/skills/wecom-send-template-card/references/api-template-card-types.md +358 -0
  173. package/skills/wecom-smartsheet/SKILL.md +164 -0
  174. package/skills/wecom-smartsheet/references/smartsheet-cell-value-formats.md +163 -0
  175. package/skills/wecom-smartsheet/references/smartsheet-field-types.md +44 -0
  176. package/skills/wecom-smartsheet/references/smartsheet-get-records.md +96 -0
  177. package/skills/wecom-smartsheet/references/webhook-examples.md +185 -0
  178. package/skills/wecom-smartsheet/references/webhook-fallback.md +184 -0
  179. package/skills/wecom-todo/SKILL.md +392 -0
  180. package/skills/wecom-todo/examples/workflows.md +163 -0
@@ -0,0 +1,967 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ var __generator = (this && this.__generator) || function (thisArg, body) {
31
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
32
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
33
+ function verb(n) { return function (v) { return step([n, v]); }; }
34
+ function step(op) {
35
+ if (f) throw new TypeError("Generator is already executing.");
36
+ while (_) try {
37
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
38
+ if (y = 0, t) op = [op[0] & 2, t.value];
39
+ switch (op[0]) {
40
+ case 0: case 1: t = op; break;
41
+ case 4: _.label++; return { value: op[1], done: false };
42
+ case 5: _.label++; y = op[1]; op = [0]; continue;
43
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
44
+ default:
45
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
46
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
47
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
48
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
49
+ if (t[2]) _.ops.pop();
50
+ _.trys.pop(); continue;
51
+ }
52
+ op = body.call(thisArg, _);
53
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
54
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
55
+ }
56
+ };
57
+ var __spreadArrays = (this && this.__spreadArrays) || function () {
58
+ for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
59
+ for (var r = Array(s), k = 0, i = 0; i < il; i++)
60
+ for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
61
+ r[k] = a[j];
62
+ return r;
63
+ };
64
+ exports.__esModule = true;
65
+ exports.dispatchWecomViaEndpoint = exports.resolveWecomScopeByBindings = exports.resolveWecomEndpointConfig = void 0;
66
+ var fs = __importStar(require("node:fs"));
67
+ var path = __importStar(require("node:path"));
68
+ var node_https_1 = require("node:https");
69
+ var endpoint_event_adapter_js_1 = require("./endpoint-event-adapter.js");
70
+ var utils_js_1 = require("./utils.js");
71
+ var DEFAULT_TIMEOUT_MS = 60000 * 3;
72
+ function toText(value) {
73
+ return String(value !== null && value !== void 0 ? value : "").trim();
74
+ }
75
+ function asObj(value) {
76
+ if (value && typeof value === "object" && !Array.isArray(value)) {
77
+ return value;
78
+ }
79
+ return null;
80
+ }
81
+ function parseJsonObjectSafely(raw) {
82
+ try {
83
+ var parsed = JSON.parse(raw);
84
+ return asObj(parsed);
85
+ }
86
+ catch (_a) {
87
+ return null;
88
+ }
89
+ }
90
+ function dedupeUrls(urls) {
91
+ var seen = new Set();
92
+ var out = [];
93
+ for (var _i = 0, urls_1 = urls; _i < urls_1.length; _i++) {
94
+ var url = urls_1[_i];
95
+ var value = toText(url);
96
+ if (!value || seen.has(value))
97
+ continue;
98
+ seen.add(value);
99
+ out.push(value);
100
+ }
101
+ return out;
102
+ }
103
+ function isHttpUrl(url) {
104
+ var value = toText(url).toLowerCase();
105
+ return value.startsWith("http://") || value.startsWith("https://");
106
+ }
107
+ function normalizeScope(scopeTypeRaw, projectIdRaw, workspaceIdRaw) {
108
+ var rawScope = toText(scopeTypeRaw).toLowerCase();
109
+ var workspaceId = toText(workspaceIdRaw) || toText(projectIdRaw);
110
+ var scopeType = rawScope;
111
+ if (!scopeType || scopeType === "my_workspace" || scopeType === "my-workspace" || scopeType === "project") {
112
+ scopeType = "workspace";
113
+ }
114
+ return { scopeType: "workspace", workspaceId: workspaceId, projectId: workspaceId };
115
+ }
116
+ function resolveWecomEndpointConfig(config, fallbackScope) {
117
+ var _a, _b, _c, _d, _e, _f;
118
+ var gatewayBaseUrl = toText(config.gatewayBaseUrl).replace(/\/+$/, "");
119
+ if (!gatewayBaseUrl)
120
+ return null;
121
+ var scope = normalizeScope((_c = (_b = (_a = config.scope_kind) !== null && _a !== void 0 ? _a : config.scopeKind) !== null && _b !== void 0 ? _b : config.scope_type) !== null && _c !== void 0 ? _c : config.scopeType, (_f = (_e = (_d = config.workspace_id) !== null && _d !== void 0 ? _d : config.workspaceId) !== null && _e !== void 0 ? _e : config.project_id) !== null && _f !== void 0 ? _f : config.projectId);
122
+ var effectiveScope = scope.workspaceId ? scope : (fallbackScope && fallbackScope.workspaceId ? fallbackScope : scope);
123
+ return {
124
+ gatewayBaseUrl: gatewayBaseUrl,
125
+ gatewayToken: toText(config.gatewayToken) || undefined,
126
+ uploadHost: toText(config.uploadHost) || undefined,
127
+ modelName: toText(config.modelName) || undefined,
128
+ agentId: toText(config.agentId) || undefined,
129
+ showFinalAnswerOnly: config.showFinalAnswerOnly === true,
130
+ separateSessionByConversation: config.separateSessionByConversation !== false,
131
+ groupSessionScope: config.groupSessionScope === "group" ? "group" : "group_sender",
132
+ scopeType: effectiveScope.scopeType,
133
+ workspaceId: effectiveScope.workspaceId,
134
+ projectId: effectiveScope.projectId
135
+ };
136
+ }
137
+ exports.resolveWecomEndpointConfig = resolveWecomEndpointConfig;
138
+ function resolveWecomScopeByBindings(params) {
139
+ var _a;
140
+ var rawBindings = (_a = params.cfg) === null || _a === void 0 ? void 0 : _a.bindings;
141
+ var bindings = Array.isArray(rawBindings) ? rawBindings : [];
142
+ if (!bindings.length)
143
+ return null;
144
+ var accountId = toText(params.accountId);
145
+ if (!accountId)
146
+ return null;
147
+ for (var _i = 0, bindings_1 = bindings; _i < bindings_1.length; _i++) {
148
+ var item = bindings_1[_i];
149
+ var match = (item === null || item === void 0 ? void 0 : item.match) || {};
150
+ var channel = toText(match.channel).toLowerCase();
151
+ if (channel && channel !== "wecom" && channel !== "wecom-openclaw-plugin") {
152
+ continue;
153
+ }
154
+ if (toText(match.accountId) !== accountId)
155
+ continue;
156
+ var scope = normalizeScope(match.scope_kind || match.scopeKind || match.scope_type || match.scopeType, match.workspace_id || match.workspaceId || match.project_id || match.projectId);
157
+ if (scope.workspaceId) {
158
+ return scope;
159
+ }
160
+ }
161
+ return null;
162
+ }
163
+ exports.resolveWecomScopeByBindings = resolveWecomScopeByBindings;
164
+ function buildSessionContextUser(params) {
165
+ var peerId = utils_js_1.resolveWecomSessionPeerId({
166
+ chatType: params.chatType,
167
+ chatId: params.chatId,
168
+ senderId: params.senderId,
169
+ separateSessionByConversation: params.separateSessionByConversation,
170
+ groupSessionScope: params.groupSessionScope
171
+ });
172
+ var payload = {
173
+ channel: "wecom",
174
+ accountId: params.accountId,
175
+ platform_id: params.platformId,
176
+ peerId: peerId,
177
+ chatType: params.chatType,
178
+ chatId: params.chatId,
179
+ senderId: params.senderId,
180
+ senderName: toText(params.senderName) || undefined,
181
+ chatName: toText(params.chatName) || undefined,
182
+ im_endpoint_source: true,
183
+ is_im_endpoint_call: true
184
+ };
185
+ if (params.scope.workspaceId) {
186
+ payload.scopeType = "workspace";
187
+ payload.workspaceId = params.scope.workspaceId || params.scope.projectId;
188
+ }
189
+ return JSON.stringify(payload);
190
+ }
191
+ function buildSessionNameMeta(params) {
192
+ var peerId = utils_js_1.resolveWecomSessionPeerId({
193
+ chatType: params.chatType,
194
+ chatId: params.chatId,
195
+ senderId: params.senderId,
196
+ separateSessionByConversation: params.separateSessionByConversation,
197
+ groupSessionScope: params.groupSessionScope
198
+ });
199
+ var base = {
200
+ source: "im-node-plugin",
201
+ im_endpoint_source: true,
202
+ is_im_endpoint_call: true,
203
+ channel: "wecom",
204
+ chat_type: params.chatType,
205
+ platform_id: params.platformId,
206
+ peer_id: peerId,
207
+ target_id: params.chatId,
208
+ conversation_id: params.chatId,
209
+ chat_id: params.chatId,
210
+ sender_id: params.senderId,
211
+ sender_name: toText(params.senderName) || params.senderId
212
+ };
213
+ if (params.scope.workspaceId) {
214
+ base.scope_kind = "workspace";
215
+ base.scopeKind = "workspace";
216
+ base.scope_type = "workspace";
217
+ base.scopeType = "workspace";
218
+ base.workspace_id = params.scope.workspaceId || params.scope.projectId;
219
+ base.workspaceId = params.scope.workspaceId || params.scope.projectId;
220
+ }
221
+ return base;
222
+ }
223
+ function buildEndpointCodeErrorMessage(payload) {
224
+ if (Array.isArray(payload.choices))
225
+ return null;
226
+ var rawCode = payload.code;
227
+ var codeText = typeof rawCode === "number"
228
+ ? String(rawCode)
229
+ : typeof rawCode === "string"
230
+ ? rawCode.trim()
231
+ : "";
232
+ var hasCode = codeText.length > 0;
233
+ var isSuccessCode = codeText === "0" || codeText === "200";
234
+ var codeFailed = hasCode && !isSuccessCode;
235
+ var success = payload.success;
236
+ var successFailed = typeof success === "boolean" && !success;
237
+ var msg = "";
238
+ if (typeof payload.msg === "string") {
239
+ msg = payload.msg.trim();
240
+ }
241
+ else if (typeof payload.message === "string") {
242
+ msg = payload.message.trim();
243
+ }
244
+ else if (typeof payload.error === "string") {
245
+ msg = payload.error.trim();
246
+ }
247
+ else if (payload.error &&
248
+ typeof payload.error === "object" &&
249
+ typeof payload.error.message === "string") {
250
+ msg = String(payload.error.message).trim();
251
+ }
252
+ if (!codeFailed && !successFailed)
253
+ return null;
254
+ var parts = [];
255
+ if (hasCode)
256
+ parts.push("code=" + codeText);
257
+ if (msg)
258
+ parts.push("msg=" + msg);
259
+ return parts.join(", ") || "unknown";
260
+ }
261
+ function normalizeEndpointResourceUrl(rawUrl, gatewayUrl) {
262
+ var value = toText(rawUrl);
263
+ if (!value)
264
+ return "";
265
+ if (isHttpUrl(value))
266
+ return value;
267
+ try {
268
+ return new URL(value, gatewayUrl).toString();
269
+ }
270
+ catch (_a) {
271
+ return "";
272
+ }
273
+ }
274
+ function parseEventContentObject(payload) {
275
+ var raw = payload.eventContent;
276
+ if (typeof raw === "string")
277
+ return parseJsonObjectSafely(raw);
278
+ return asObj(raw);
279
+ }
280
+ function extractContentTextFromPayload(payload) {
281
+ var eventContentObj = parseEventContentObject(payload);
282
+ var rawEventContent = eventContentObj === null || eventContentObj === void 0 ? void 0 : eventContentObj.content;
283
+ if (typeof rawEventContent === "string")
284
+ return rawEventContent;
285
+ var fromEvent = toText(rawEventContent);
286
+ if (fromEvent)
287
+ return fromEvent;
288
+ var choice = Array.isArray(payload.choices) ? asObj(payload.choices[0]) : null;
289
+ var delta = asObj(choice === null || choice === void 0 ? void 0 : choice.delta);
290
+ var message = asObj(choice === null || choice === void 0 ? void 0 : choice.message);
291
+ return toText(delta === null || delta === void 0 ? void 0 : delta.content) || toText(message === null || message === void 0 ? void 0 : message.content);
292
+ }
293
+ function getContentTypeFromObject(value) {
294
+ // Python IM 端点对齐 /ai/chat/stream/ 后,content_type 可能出现在
295
+ // eventContent 或 data 中,并且存在 snake/camel 两种命名,这里统一归一化。
296
+ return (toText(value === null || value === void 0 ? void 0 : value.content_type) || toText(value === null || value === void 0 ? void 0 : value.contentType)).toLowerCase();
297
+ }
298
+ function getAgentRunIdFromPayload(payload) {
299
+ return toText(payload.agent_run_id) || toText(payload.agentRunId);
300
+ }
301
+ function isFinalAnswerPayload(payload) {
302
+ // “只显示结论”只相信结构化 content_type=final_answer,不通过文本内容、
303
+ // responseId 或 agent 名称猜测,避免误把普通回复当最终答案。
304
+ var eventContentObj = parseEventContentObject(payload);
305
+ if (getContentTypeFromObject(eventContentObj) === "final_answer")
306
+ return true;
307
+ return getContentTypeFromObject(asObj(payload.data)) === "final_answer";
308
+ }
309
+ function extractFinalAnswerTextFromNestedMessage(item) {
310
+ var dataObj = asObj(item.data) || parseEventContentObject(item);
311
+ if (getContentTypeFromObject(dataObj) !== "final_answer")
312
+ return "";
313
+ var rawContent = dataObj === null || dataObj === void 0 ? void 0 : dataObj.content;
314
+ if (typeof rawContent === "string")
315
+ return rawContent;
316
+ return toText(rawContent);
317
+ }
318
+ function extractFinalAnswerTextFromUpsertRecord(payload) {
319
+ var _a;
320
+ // final_answer 有时不会作为 content 事件单独发出,而是落在
321
+ // upsert_record.extParams.message.external.messages 中;final-only 模式过滤普通 content 后
322
+ // 仍要从这里补取最终结论。
323
+ var eventContentObj = parseEventContentObject(payload);
324
+ var messageObj = asObj((_a = asObj(eventContentObj === null || eventContentObj === void 0 ? void 0 : eventContentObj.extParams)) === null || _a === void 0 ? void 0 : _a.message);
325
+ var externalObj = asObj(messageObj === null || messageObj === void 0 ? void 0 : messageObj.external);
326
+ var messages = Array.isArray(externalObj === null || externalObj === void 0 ? void 0 : externalObj.messages) ? externalObj.messages : [];
327
+ // 从末尾向前找,优先使用最新 final_answer,避免拿到历史中间态。
328
+ for (var i = messages.length - 1; i >= 0; i -= 1) {
329
+ var item = asObj(messages[i]);
330
+ if (!item)
331
+ continue;
332
+ var text = extractFinalAnswerTextFromNestedMessage(item);
333
+ if (text)
334
+ return text;
335
+ }
336
+ return "";
337
+ }
338
+ function extractErrorTextFromPayload(payload) {
339
+ var _a, _b;
340
+ var eventContentObj = parseEventContentObject(payload);
341
+ var source = eventContentObj || payload;
342
+ var message = toText(source.msg) ||
343
+ toText(source.message) ||
344
+ toText(source.error) ||
345
+ toText((_a = asObj(source.error)) === null || _a === void 0 ? void 0 : _a.message);
346
+ var solution = toText((_b = asObj(source.extraInfo)) === null || _b === void 0 ? void 0 : _b.solution);
347
+ var code = toText(source.code);
348
+ var lines = [];
349
+ if (message)
350
+ lines.push(message);
351
+ if (solution && solution !== message)
352
+ lines.push(solution);
353
+ if (!lines.length && code)
354
+ lines.push("\u9519\u8BEF\u7801\uFF1A" + code);
355
+ return lines.join("\n").trim();
356
+ }
357
+ function extractResourcesFromPayload(payload) {
358
+ var out = [];
359
+ var resourcesRoot = Array.isArray(payload.resources) ? payload.resources : [];
360
+ for (var _i = 0, resourcesRoot_1 = resourcesRoot; _i < resourcesRoot_1.length; _i++) {
361
+ var item = resourcesRoot_1[_i];
362
+ var obj = asObj(item);
363
+ if (obj)
364
+ out.push(obj);
365
+ }
366
+ if (out.length > 0)
367
+ return out;
368
+ var eventObj = parseEventContentObject(payload);
369
+ var resourcesInEvent = Array.isArray(eventObj === null || eventObj === void 0 ? void 0 : eventObj.resources) ? eventObj.resources : [];
370
+ for (var _a = 0, resourcesInEvent_1 = resourcesInEvent; _a < resourcesInEvent_1.length; _a++) {
371
+ var item = resourcesInEvent_1[_a];
372
+ var obj = asObj(item);
373
+ if (obj)
374
+ out.push(obj);
375
+ }
376
+ return out;
377
+ }
378
+ function extractMediaDirectives(text) {
379
+ var src = String(text || "");
380
+ if (!src)
381
+ return { cleanedText: "", mediaUrls: [] };
382
+ var lines = src.split(/\r?\n/);
383
+ var kept = [];
384
+ var mediaUrls = [];
385
+ for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
386
+ var line = lines_1[_i];
387
+ var trimmed = line.trim();
388
+ var match = /^MEDIA:\s*(\S+)\s*$/i.exec(trimmed);
389
+ if (match === null || match === void 0 ? void 0 : match[1]) {
390
+ var url = toText(match[1]);
391
+ if (url && isHttpUrl(url)) {
392
+ mediaUrls.push(url);
393
+ continue;
394
+ }
395
+ }
396
+ kept.push(line);
397
+ }
398
+ return {
399
+ cleanedText: kept.join("\n"),
400
+ mediaUrls: dedupeUrls(mediaUrls)
401
+ };
402
+ }
403
+ function collectResourceMediaUrls(resources) {
404
+ var urls = [];
405
+ for (var _i = 0, resources_1 = resources; _i < resources_1.length; _i++) {
406
+ var item = resources_1[_i];
407
+ if (isHttpUrl(item.url)) {
408
+ urls.push(item.url);
409
+ }
410
+ }
411
+ return dedupeUrls(urls);
412
+ }
413
+ function isImageMediaType(mediaType) {
414
+ return toText(mediaType).toLowerCase().startsWith("image/");
415
+ }
416
+ function stripInboundLocalPathFromUserContent(userContent, mediaPath) {
417
+ var source = String(userContent || "");
418
+ var target = toText(mediaPath);
419
+ if (!source || !target)
420
+ return source;
421
+ return source.split(target).join("").replace(/\n{3,}/g, "\n\n").trim();
422
+ }
423
+ function sanitizeDisplayFileName(name) {
424
+ var trimmed = toText(name);
425
+ if (!trimmed)
426
+ return "";
427
+ var base = path.basename(trimmed);
428
+ var safe = base.replace(/[\\/:*?"<>|\u0000-\u001f]/g, "_");
429
+ return safe === "." || safe === ".." ? "" : safe;
430
+ }
431
+ function buildYuceMediaPublicUrl(uploadHost, dataPath) {
432
+ var base = uploadHost.replace(/\/+$/, "");
433
+ if (!dataPath)
434
+ return base;
435
+ if (dataPath.startsWith("http://") || dataPath.startsWith("https://")) {
436
+ return dataPath;
437
+ }
438
+ return "" + base + (dataPath.startsWith("/") ? "" : "/") + dataPath;
439
+ }
440
+ function uploadInboundMediaToYuceApiWithReason(localPath, opts) {
441
+ var _a;
442
+ return __awaiter(this, void 0, void 0, function () {
443
+ var token, base, timeoutMs, url, buf, form, uploadFileName, controller_1, timer, response, raw, parsed, err_1;
444
+ return __generator(this, function (_b) {
445
+ switch (_b.label) {
446
+ case 0:
447
+ if (!fs.existsSync(localPath)) {
448
+ return [2 /*return*/, { url: null, reason: "本地文件不存在" }];
449
+ }
450
+ token = toText(opts.sessionToken);
451
+ if (!token)
452
+ return [2 /*return*/, { url: null, reason: "缺少 gatewayToken" }];
453
+ base = toText(opts.uploadHost).replace(/\/+$/, "");
454
+ if (!base)
455
+ return [2 /*return*/, { url: null, reason: "未配置 uploadHost" }];
456
+ timeoutMs = (_a = opts.timeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_TIMEOUT_MS;
457
+ url = base + "/api/media/upload";
458
+ _b.label = 1;
459
+ case 1:
460
+ _b.trys.push([1, 4, , 5]);
461
+ buf = fs.readFileSync(localPath);
462
+ form = new FormData();
463
+ uploadFileName = toText(opts.uploadFileName) || path.basename(localPath) || "resource.bin";
464
+ form.append("file", new Blob([buf]), uploadFileName);
465
+ controller_1 = new AbortController();
466
+ timer = setTimeout(function () { return controller_1.abort(); }, timeoutMs);
467
+ return [4 /*yield*/, fetch(url, {
468
+ method: "POST",
469
+ headers: {
470
+ Cookie: "YCSESSIONID=" + token
471
+ },
472
+ body: form,
473
+ signal: controller_1.signal
474
+ })];
475
+ case 2:
476
+ response = _b.sent();
477
+ clearTimeout(timer);
478
+ return [4 /*yield*/, response.text()];
479
+ case 3:
480
+ raw = _b.sent();
481
+ parsed = void 0;
482
+ try {
483
+ parsed = JSON.parse(raw);
484
+ }
485
+ catch (_c) {
486
+ return [2 /*return*/, { url: null, reason: "上传接口返回非 JSON" }];
487
+ }
488
+ if (!parsed.success || String(parsed.code || "") !== "200") {
489
+ return [2 /*return*/, {
490
+ url: null,
491
+ reason: toText(parsed.msg) || "\u4E0A\u4F20\u5931\u8D25(code=" + String(parsed.code || "unknown") + ")"
492
+ }];
493
+ }
494
+ if (!toText(parsed.data)) {
495
+ return [2 /*return*/, { url: null, reason: "上传成功但返回地址为空" }];
496
+ }
497
+ return [2 /*return*/, { url: buildYuceMediaPublicUrl(base, String(parsed.data)) }];
498
+ case 4:
499
+ err_1 = _b.sent();
500
+ return [2 /*return*/, { url: null, reason: String(err_1) || "上传异常" }];
501
+ case 5: return [2 /*return*/];
502
+ }
503
+ });
504
+ });
505
+ }
506
+ function buildUserContentWithInboundMedia(params) {
507
+ return __awaiter(this, void 0, void 0, function () {
508
+ var userContent, mediaPath, displayName, safeUserContent, uploadRet, imageLike, imageMarkdown, failNote, fileNote;
509
+ return __generator(this, function (_a) {
510
+ switch (_a.label) {
511
+ case 0:
512
+ userContent = String(params.userContent || "");
513
+ mediaPath = toText(params.mediaPath);
514
+ if (!mediaPath)
515
+ return [2 /*return*/, userContent];
516
+ displayName = sanitizeDisplayFileName(params.mediaFileName || "") ||
517
+ sanitizeDisplayFileName(path.basename(mediaPath)) ||
518
+ "resource";
519
+ safeUserContent = stripInboundLocalPathFromUserContent(userContent, mediaPath);
520
+ return [4 /*yield*/, uploadInboundMediaToYuceApiWithReason(mediaPath, {
521
+ uploadHost: params.endpointConfig.uploadHost,
522
+ sessionToken: params.endpointConfig.gatewayToken,
523
+ uploadFileName: displayName
524
+ })];
525
+ case 1:
526
+ uploadRet = _a.sent();
527
+ imageLike = isImageMediaType(params.mediaType);
528
+ if (imageLike) {
529
+ if (uploadRet.url) {
530
+ imageMarkdown = "![image](" + uploadRet.url + ")";
531
+ return [2 /*return*/, safeUserContent ? safeUserContent + "\n\n" + imageMarkdown : imageMarkdown];
532
+ }
533
+ failNote = "[\u56FE\u7247\u8FDC\u7A0B\u5730\u5740\u83B7\u53D6\u5931\u8D25: " + (uploadRet.reason || "上传失败") + "]";
534
+ return [2 /*return*/, safeUserContent ? safeUserContent + "\n\n" + failNote : failNote];
535
+ }
536
+ fileNote = uploadRet.url
537
+ ? "[\u6587\u4EF6: " + displayName + "] [\u6587\u4EF6\u8FDC\u7A0B\u5730\u5740: " + uploadRet.url + "\uFF0C\u8BF7\u57FA\u4E8E\u6587\u4EF6\u540D\u548C\u4E0A\u4E0B\u6587\u56DE\u7B54]"
538
+ : "[\u6587\u4EF6: " + displayName + "] [\u6587\u4EF6\u8FDC\u7A0B\u5730\u5740\u83B7\u53D6\u5931\u8D25: " + (uploadRet.reason || "上传失败") + "]";
539
+ return [2 /*return*/, safeUserContent ? safeUserContent + "\n\n" + fileNote : fileNote];
540
+ }
541
+ });
542
+ });
543
+ }
544
+ function streamFromEndpoint(params) {
545
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
546
+ return __awaiter(this, void 0, void 0, function () {
547
+ var gatewayUrl, body, _r, _s, headers, queryParams, parsedUrl, requestCookie, requestBodyText, controller, timer, fetchOptions, response, text, _t, parsed, normalizedBody, contentType, text, reader, decoder, buffer, currentEventType, accumulatedText, resources, handledConfirmationKeys, subAgentRunIds, announcedSubAgentRunIds, emittedFinalAnswerResponseIds, errorPrefixSent, done, part, decodedChunk, lines, _i, lines_2, line, isJsonLine, data, dataPayload, payloadEventType, eventType, adapted, announceKey, dedupKey, resourceList, _u, resourceList_1, item, rawUrl, normalizedUrl, chunk_1, responseId, chunk_2, chunk_3, outputChunk, chunk, genericPayload, endpointError;
548
+ return __generator(this, function (_v) {
549
+ switch (_v.label) {
550
+ case 0:
551
+ gatewayUrl = params.endpointConfig.gatewayBaseUrl.replace(/\/+$/, "") + "/v1/im/chat/completions";
552
+ _r = {
553
+ model: params.modelName,
554
+ agent_id: params.agentId
555
+ };
556
+ _s = {
557
+ role: "user"
558
+ };
559
+ return [4 /*yield*/, buildUserContentWithInboundMedia({
560
+ userContent: params.userContent,
561
+ mediaPath: params.mediaPath,
562
+ mediaType: params.mediaType,
563
+ mediaFileName: params.mediaFileName,
564
+ endpointConfig: params.endpointConfig
565
+ })];
566
+ case 1:
567
+ body = (_r.messages = [
568
+ (_s.content = _v.sent(),
569
+ _s)
570
+ ],
571
+ _r.stream = true,
572
+ // 透传给 Python IM 端点:让 /new、/help 等控制指令可按 final-only 契约返回 final_answer。
573
+ _r.showFinalAnswerOnly = params.endpointConfig.showFinalAnswerOnly === true,
574
+ _r.show_final_answer_only = params.endpointConfig.showFinalAnswerOnly === true,
575
+ _r.user = params.sessionContextUser,
576
+ _r.session_name_meta = params.sessionNameMeta,
577
+ _r);
578
+ headers = {
579
+ "Content-Type": "application/json",
580
+ "X-OpenClaw-Agent-Id": params.agentId
581
+ };
582
+ if (params.endpointConfig.gatewayToken) {
583
+ headers.Authorization = "Bearer " + params.endpointConfig.gatewayToken;
584
+ }
585
+ if (params.memoryUser) {
586
+ headers["X-OpenClaw-Memory-User"] = Buffer.from(params.memoryUser, "utf-8").toString("base64");
587
+ }
588
+ try {
589
+ headers.Origin = new URL(gatewayUrl).origin;
590
+ }
591
+ catch (_w) {
592
+ // ignore
593
+ }
594
+ queryParams = {};
595
+ try {
596
+ parsedUrl = new URL(gatewayUrl);
597
+ queryParams = Object.fromEntries(parsedUrl.searchParams.entries());
598
+ }
599
+ catch (_x) {
600
+ queryParams = {};
601
+ }
602
+ requestCookie = headers.Cookie || headers.cookie || "";
603
+ requestBodyText = JSON.stringify(body);
604
+ (_a = params.runtimeLog) === null || _a === void 0 ? void 0 : _a.call(params, "[wecom][endpoint] request python endpoint url=" + gatewayUrl + " agentId=" + params.agentId + " model=" + params.modelName + " userLen=" + params.sessionContextUser.length + " contentLen=" + (((_c = (_b = body.messages[0]) === null || _b === void 0 ? void 0 : _b.content) === null || _c === void 0 ? void 0 : _c.length) || 0));
605
+ (_d = params.runtimeLog) === null || _d === void 0 ? void 0 : _d.call(params, "[wecom][endpoint] request query params=" + JSON.stringify(queryParams));
606
+ (_e = params.runtimeLog) === null || _e === void 0 ? void 0 : _e.call(params, "[wecom][endpoint] request headers=" + JSON.stringify(headers));
607
+ (_f = params.runtimeLog) === null || _f === void 0 ? void 0 : _f.call(params, "[wecom][endpoint] request cookie=" + (requestCookie || "(empty)"));
608
+ (_g = params.runtimeLog) === null || _g === void 0 ? void 0 : _g.call(params, "[wecom][endpoint] request body=" + requestBodyText);
609
+ controller = new AbortController();
610
+ timer = setTimeout(function () { return controller.abort(); }, DEFAULT_TIMEOUT_MS);
611
+ fetchOptions = {
612
+ method: "POST",
613
+ headers: headers,
614
+ body: requestBodyText,
615
+ signal: controller.signal
616
+ };
617
+ if (gatewayUrl.startsWith("https://")) {
618
+ fetchOptions.agent = new node_https_1.Agent({ rejectUnauthorized: false });
619
+ }
620
+ return [4 /*yield*/, fetch(gatewayUrl, fetchOptions)];
621
+ case 2:
622
+ response = _v.sent();
623
+ clearTimeout(timer);
624
+ (_h = params.runtimeLog) === null || _h === void 0 ? void 0 : _h.call(params, "[wecom][endpoint] python endpoint response status=" + response.status + " ok=" + response.ok + " contentType=" + String(response.headers.get("content-type") || ""));
625
+ (_j = params.runtimeLog) === null || _j === void 0 ? void 0 : _j.call(params, "[wecom][endpoint] response set-cookie=" + String(response.headers.get("set-cookie") || "(empty)"));
626
+ if (!(!response.ok || !response.body)) return [3 /*break*/, 6];
627
+ if (!response.body) return [3 /*break*/, 4];
628
+ return [4 /*yield*/, response.text()];
629
+ case 3:
630
+ _t = _v.sent();
631
+ return [3 /*break*/, 5];
632
+ case 4:
633
+ _t = "(no body)";
634
+ _v.label = 5;
635
+ case 5:
636
+ text = _t;
637
+ (_k = params.runtimeError) === null || _k === void 0 ? void 0 : _k.call(params, "[wecom][endpoint] python endpoint non-ok body=" + text.slice(0, 500));
638
+ parsed = parseJsonObjectSafely(text);
639
+ normalizedBody = parsed ? JSON.stringify(parsed) : text;
640
+ throw new Error("endpoint error " + response.status + ": " + normalizedBody);
641
+ case 6:
642
+ contentType = String(response.headers.get("content-type") || "").toLowerCase();
643
+ if (!(!contentType.includes("text/event-stream") && !contentType.includes("application/json"))) return [3 /*break*/, 8];
644
+ return [4 /*yield*/, response.text()];
645
+ case 7:
646
+ text = (_v.sent()).trim();
647
+ return [2 /*return*/, { text: text, resources: [] }];
648
+ case 8:
649
+ reader = response.body.getReader();
650
+ decoder = new TextDecoder();
651
+ buffer = "";
652
+ currentEventType = "message";
653
+ accumulatedText = "";
654
+ resources = [];
655
+ handledConfirmationKeys = new Set();
656
+ subAgentRunIds = new Set();
657
+ announcedSubAgentRunIds = new Set();
658
+ emittedFinalAnswerResponseIds = new Set();
659
+ errorPrefixSent = false;
660
+ done = false;
661
+ _v.label = 9;
662
+ case 9:
663
+ if (!!done) return [3 /*break*/, 34];
664
+ return [4 /*yield*/, reader.read()];
665
+ case 10:
666
+ part = _v.sent();
667
+ if (part.done)
668
+ return [3 /*break*/, 34];
669
+ decodedChunk = decoder.decode(part.value, { stream: true });
670
+ if (decodedChunk) {
671
+ (_l = params.runtimeLog) === null || _l === void 0 ? void 0 : _l.call(params, "[wecom][endpoint][raw-chunk] " + decodedChunk.slice(0, 8192));
672
+ }
673
+ buffer += decodedChunk;
674
+ lines = buffer.split("\n");
675
+ buffer = (_m = lines.pop()) !== null && _m !== void 0 ? _m : "";
676
+ _i = 0, lines_2 = lines;
677
+ _v.label = 11;
678
+ case 11:
679
+ if (!(_i < lines_2.length)) return [3 /*break*/, 33];
680
+ line = lines_2[_i];
681
+ (_o = params.runtimeLog) === null || _o === void 0 ? void 0 : _o.call(params, "[wecom][endpoint][raw-line] " + line.slice(0, 8192));
682
+ if (line === "" || line === "\r") {
683
+ currentEventType = "message";
684
+ return [3 /*break*/, 32];
685
+ }
686
+ if (line.startsWith("event:")) {
687
+ currentEventType = line.slice(line.indexOf(":") + 1).trim();
688
+ return [3 /*break*/, 32];
689
+ }
690
+ isJsonLine = !line.startsWith("data: ") &&
691
+ !line.startsWith(":") &&
692
+ line.trim().startsWith("{") &&
693
+ line.trim().endsWith("}");
694
+ if (!line.startsWith("data: ") && !isJsonLine)
695
+ return [3 /*break*/, 32];
696
+ data = line.startsWith("data: ") ? line.slice(6).trim() : line.trim();
697
+ if (data === "[DONE]") {
698
+ done = true;
699
+ return [3 /*break*/, 33];
700
+ }
701
+ dataPayload = parseJsonObjectSafely(data);
702
+ payloadEventType = toText(dataPayload === null || dataPayload === void 0 ? void 0 : dataPayload.eventType).toLowerCase();
703
+ eventType = (currentEventType === "message" || !currentEventType) && payloadEventType
704
+ ? payloadEventType
705
+ : (currentEventType || payloadEventType).toLowerCase();
706
+ if (!dataPayload) return [3 /*break*/, 29];
707
+ adapted = endpoint_event_adapter_js_1.adaptEndpointEvent({
708
+ rawText: data,
709
+ currentEventType: eventType
710
+ });
711
+ if (!adapted.subAgentStartLine) return [3 /*break*/, 14];
712
+ // call_sub_agent 是子代理输出边界的起点;后续同 run_id 事件按子代理内部过程处理。
713
+ if (adapted.subAgentRunId) {
714
+ subAgentRunIds.add(adapted.subAgentRunId);
715
+ }
716
+ announceKey = adapted.subAgentRunId || adapted.subAgentStartLine;
717
+ if (!(!params.endpointConfig.showFinalAnswerOnly && !announcedSubAgentRunIds.has(announceKey))) return [3 /*break*/, 13];
718
+ announcedSubAgentRunIds.add(announceKey);
719
+ accumulatedText += adapted.subAgentStartLine;
720
+ if (!params.onChunk) return [3 /*break*/, 13];
721
+ return [4 /*yield*/, params.onChunk(adapted.subAgentStartLine, accumulatedText)];
722
+ case 12:
723
+ _v.sent();
724
+ _v.label = 13;
725
+ case 13:
726
+ currentEventType = "message";
727
+ return [3 /*break*/, 32];
728
+ case 14:
729
+ if (adapted.subAgentRunId &&
730
+ subAgentRunIds.has(adapted.subAgentRunId) &&
731
+ eventType !== "error") {
732
+ // 子代理内部过程不展示;error 留给 error 分支输出,避免静默吞掉失败原因。
733
+ // sub agent 理论上不应该发起 confirm;这里把 confirm 一并挡住只是防御性兜底,避免内部确认意外打断主会话。
734
+ (_p = params.runtimeLog) === null || _p === void 0 ? void 0 : _p.call(params, "[wecom][endpoint][sse] ignore sub-agent event: agent_run_id=" + adapted.subAgentRunId + " event=" + (adapted.eventType || eventType));
735
+ currentEventType = "message";
736
+ return [3 /*break*/, 32];
737
+ }
738
+ if (!adapted.confirmationText) return [3 /*break*/, 17];
739
+ dedupKey = adapted.confirmationDedupKey;
740
+ if (dedupKey && handledConfirmationKeys.has(dedupKey)) {
741
+ currentEventType = "message";
742
+ return [3 /*break*/, 32];
743
+ }
744
+ if (dedupKey)
745
+ handledConfirmationKeys.add(dedupKey);
746
+ if (!params.onConfirmationAction) return [3 /*break*/, 16];
747
+ return [4 /*yield*/, params.onConfirmationAction(adapted.confirmationText)];
748
+ case 15:
749
+ _v.sent();
750
+ _v.label = 16;
751
+ case 16:
752
+ currentEventType = "message";
753
+ return [3 /*break*/, 32];
754
+ case 17:
755
+ if (adapted.ignoreAsNoise &&
756
+ !(eventType === "upsert_record" && params.endpointConfig.showFinalAnswerOnly)) {
757
+ currentEventType = "message";
758
+ return [3 /*break*/, 32];
759
+ }
760
+ if (eventType === "resource") {
761
+ if (params.endpointConfig.showFinalAnswerOnly) {
762
+ // 资源属于过程产物;final-only 模式只保留最终结论、错误和主流程确认兜底。
763
+ currentEventType = "message";
764
+ return [3 /*break*/, 32];
765
+ }
766
+ try {
767
+ resourceList = extractResourcesFromPayload(dataPayload);
768
+ for (_u = 0, resourceList_1 = resourceList; _u < resourceList_1.length; _u++) {
769
+ item = resourceList_1[_u];
770
+ rawUrl = toText(item.full_url) || toText(item.url);
771
+ normalizedUrl = normalizeEndpointResourceUrl(rawUrl, gatewayUrl);
772
+ if (!normalizedUrl)
773
+ continue;
774
+ resources.push({
775
+ type: toText(item.type).toLowerCase(),
776
+ title: toText(item.title) || "resource",
777
+ url: normalizedUrl
778
+ });
779
+ }
780
+ }
781
+ catch (err) {
782
+ (_q = params.runtimeError) === null || _q === void 0 ? void 0 : _q.call(params, "[wecom][endpoint] parse resource event failed: " + String(err));
783
+ }
784
+ currentEventType = "message";
785
+ return [3 /*break*/, 32];
786
+ }
787
+ if (!(eventType === "content")) return [3 /*break*/, 20];
788
+ if (params.endpointConfig.showFinalAnswerOnly &&
789
+ !isFinalAnswerPayload(dataPayload)) {
790
+ // 只显示结论时,普通 ai_message/content 过程文本不进入聊天。
791
+ // /new 等控制指令由 Python 端按 showFinalAnswerOnly 返回 final_answer。
792
+ currentEventType = "message";
793
+ return [3 /*break*/, 32];
794
+ }
795
+ chunk_1 = extractContentTextFromPayload(dataPayload);
796
+ if (!chunk_1) return [3 /*break*/, 19];
797
+ accumulatedText += chunk_1;
798
+ if (!params.onChunk) return [3 /*break*/, 19];
799
+ return [4 /*yield*/, params.onChunk(chunk_1, accumulatedText)];
800
+ case 18:
801
+ _v.sent();
802
+ _v.label = 19;
803
+ case 19:
804
+ currentEventType = "message";
805
+ return [3 /*break*/, 32];
806
+ case 20:
807
+ if (!(eventType === "upsert_record")) return [3 /*break*/, 23];
808
+ if (!params.endpointConfig.showFinalAnswerOnly) return [3 /*break*/, 22];
809
+ responseId = toText(dataPayload.responseId) || toText(dataPayload.response_id);
810
+ if (!(!responseId || !emittedFinalAnswerResponseIds.has(responseId))) return [3 /*break*/, 22];
811
+ chunk_2 = adapted.finalAnswerText || extractFinalAnswerTextFromUpsertRecord(dataPayload);
812
+ if (!chunk_2) return [3 /*break*/, 22];
813
+ if (responseId)
814
+ emittedFinalAnswerResponseIds.add(responseId);
815
+ accumulatedText += chunk_2;
816
+ if (!params.onChunk) return [3 /*break*/, 22];
817
+ return [4 /*yield*/, params.onChunk(chunk_2, accumulatedText)];
818
+ case 21:
819
+ _v.sent();
820
+ _v.label = 22;
821
+ case 22:
822
+ currentEventType = "message";
823
+ return [3 /*break*/, 32];
824
+ case 23:
825
+ if (!(eventType === "error")) return [3 /*break*/, 26];
826
+ chunk_3 = extractErrorTextFromPayload(dataPayload);
827
+ if (!chunk_3) return [3 /*break*/, 25];
828
+ outputChunk = errorPrefixSent ? chunk_3 : "\u9519\u8BEF\uFF1A" + chunk_3;
829
+ errorPrefixSent = true;
830
+ accumulatedText += outputChunk;
831
+ if (!params.onChunk) return [3 /*break*/, 25];
832
+ return [4 /*yield*/, params.onChunk(outputChunk, accumulatedText)];
833
+ case 24:
834
+ _v.sent();
835
+ _v.label = 25;
836
+ case 25:
837
+ currentEventType = "message";
838
+ return [3 /*break*/, 32];
839
+ case 26:
840
+ if (params.endpointConfig.showFinalAnswerOnly) {
841
+ // 未标注 content_type 的兼容 payload 不能证明是 final_answer,final-only 模式直接跳过。
842
+ currentEventType = "message";
843
+ return [3 /*break*/, 32];
844
+ }
845
+ chunk = extractContentTextFromPayload(dataPayload);
846
+ if (!chunk) return [3 /*break*/, 29];
847
+ accumulatedText += chunk;
848
+ if (!params.onChunk) return [3 /*break*/, 28];
849
+ return [4 /*yield*/, params.onChunk(chunk, accumulatedText)];
850
+ case 27:
851
+ _v.sent();
852
+ _v.label = 28;
853
+ case 28:
854
+ currentEventType = "message";
855
+ return [3 /*break*/, 32];
856
+ case 29:
857
+ genericPayload = parseJsonObjectSafely(data);
858
+ endpointError = genericPayload ? buildEndpointCodeErrorMessage(genericPayload) : null;
859
+ if (endpointError) {
860
+ throw new Error("endpoint code error: " + endpointError);
861
+ }
862
+ if (!!dataPayload) return [3 /*break*/, 31];
863
+ if (params.endpointConfig.showFinalAnswerOnly) {
864
+ // 非结构化文本没有 final_answer 标记,final-only 模式不输出。
865
+ currentEventType = "message";
866
+ return [3 /*break*/, 32];
867
+ }
868
+ accumulatedText += data;
869
+ if (!params.onChunk) return [3 /*break*/, 31];
870
+ return [4 /*yield*/, params.onChunk(data, accumulatedText)];
871
+ case 30:
872
+ _v.sent();
873
+ _v.label = 31;
874
+ case 31:
875
+ currentEventType = "message";
876
+ _v.label = 32;
877
+ case 32:
878
+ _i++;
879
+ return [3 /*break*/, 11];
880
+ case 33: return [3 /*break*/, 9];
881
+ case 34: return [2 /*return*/, {
882
+ text: accumulatedText,
883
+ resources: resources
884
+ }];
885
+ }
886
+ });
887
+ });
888
+ }
889
+ function dispatchWecomViaEndpoint(params) {
890
+ return __awaiter(this, void 0, void 0, function () {
891
+ var scope, sessionContextUser, sessionNameMeta, sessionPeerId, agentId, modelName, memoryUser, response, mediaDirectiveParsed, resourceMediaUrls, allMediaUrls, mergedText, outboundText;
892
+ return __generator(this, function (_a) {
893
+ switch (_a.label) {
894
+ case 0:
895
+ scope = {
896
+ scopeType: params.endpointConfig.scopeType,
897
+ workspaceId: params.endpointConfig.workspaceId,
898
+ projectId: params.endpointConfig.projectId
899
+ };
900
+ sessionContextUser = buildSessionContextUser({
901
+ platformId: params.platformId,
902
+ chatId: params.chatId,
903
+ chatType: params.chatType,
904
+ senderId: params.senderId,
905
+ senderName: params.senderName,
906
+ chatName: params.chatName,
907
+ accountId: params.accountId,
908
+ scope: scope,
909
+ separateSessionByConversation: params.endpointConfig.separateSessionByConversation,
910
+ groupSessionScope: params.endpointConfig.groupSessionScope
911
+ });
912
+ sessionNameMeta = buildSessionNameMeta({
913
+ platformId: params.platformId,
914
+ chatId: params.chatId,
915
+ chatType: params.chatType,
916
+ senderId: params.senderId,
917
+ senderName: params.senderName,
918
+ scope: scope,
919
+ separateSessionByConversation: params.endpointConfig.separateSessionByConversation,
920
+ groupSessionScope: params.endpointConfig.groupSessionScope
921
+ });
922
+ sessionPeerId = utils_js_1.resolveWecomSessionPeerId({
923
+ chatType: params.chatType,
924
+ chatId: params.chatId,
925
+ senderId: params.senderId,
926
+ separateSessionByConversation: params.endpointConfig.separateSessionByConversation,
927
+ groupSessionScope: params.endpointConfig.groupSessionScope
928
+ });
929
+ agentId = toText(params.routeAgentId) ||
930
+ toText(params.endpointConfig.agentId) ||
931
+ "main";
932
+ modelName = toText(params.endpointConfig.modelName) || "main";
933
+ memoryUser = "wecom:" + params.platformId + ":" + sessionPeerId;
934
+ return [4 /*yield*/, streamFromEndpoint({
935
+ endpointConfig: params.endpointConfig,
936
+ agentId: agentId,
937
+ modelName: modelName,
938
+ memoryUser: memoryUser,
939
+ sessionContextUser: sessionContextUser,
940
+ sessionNameMeta: sessionNameMeta,
941
+ userContent: params.userContent,
942
+ mediaPath: params.mediaPath,
943
+ mediaType: params.mediaType,
944
+ mediaFileName: params.mediaFileName,
945
+ onConfirmationAction: params.onConfirmationAction,
946
+ onChunk: params.onChunk,
947
+ runtimeLog: params.runtimeLog,
948
+ runtimeError: params.runtimeError
949
+ })];
950
+ case 1:
951
+ response = _a.sent();
952
+ mediaDirectiveParsed = extractMediaDirectives(response.text || "");
953
+ resourceMediaUrls = collectResourceMediaUrls(response.resources);
954
+ allMediaUrls = dedupeUrls(__spreadArrays(mediaDirectiveParsed.mediaUrls, resourceMediaUrls));
955
+ mergedText = String(mediaDirectiveParsed.cleanedText || "").trim();
956
+ outboundText = mergedText || "当前没有可展示的回复内容";
957
+ return [2 /*return*/, {
958
+ outboundText: outboundText,
959
+ mediaUrls: allMediaUrls,
960
+ resourceCount: response.resources.length,
961
+ textLength: outboundText.length
962
+ }];
963
+ }
964
+ });
965
+ });
966
+ }
967
+ exports.dispatchWecomViaEndpoint = dispatchWecomViaEndpoint;