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.
- package/README.md +596 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +99 -0
- package/dist/src/accounts.d.ts +57 -0
- package/dist/src/accounts.js +247 -0
- package/dist/src/agent/api-client.d.ts +95 -0
- package/dist/src/agent/api-client.js +425 -0
- package/dist/src/agent/handler.d.ts +64 -0
- package/dist/src/agent/handler.js +731 -0
- package/dist/src/agent/index.d.ts +5 -0
- package/dist/src/agent/index.js +21 -0
- package/dist/src/agent/webhook.d.ts +25 -0
- package/dist/src/agent/webhook.js +294 -0
- package/dist/src/agent/xml.d.ts +21 -0
- package/dist/src/agent/xml.js +43 -0
- package/dist/src/channel.d.ts +5 -0
- package/dist/src/channel.js +815 -0
- package/dist/src/chat-queue.d.ts +31 -0
- package/dist/src/chat-queue.js +53 -0
- package/dist/src/config-schema.d.ts +587 -0
- package/dist/src/config-schema.js +146 -0
- package/dist/src/const.d.ts +128 -0
- package/dist/src/const.js +168 -0
- package/dist/src/dm-policy.d.ts +29 -0
- package/dist/src/dm-policy.js +146 -0
- package/dist/src/dynamic-agent.d.ts +37 -0
- package/dist/src/dynamic-agent.js +67 -0
- package/dist/src/dynamic-routing.d.ts +65 -0
- package/dist/src/dynamic-routing.js +62 -0
- package/dist/src/endpoint-dispatch.d.ts +54 -0
- package/dist/src/endpoint-dispatch.js +967 -0
- package/dist/src/endpoint-event-adapter.d.ts +15 -0
- package/dist/src/endpoint-event-adapter.js +427 -0
- package/dist/src/group-policy.d.ts +30 -0
- package/dist/src/group-policy.js +126 -0
- package/dist/src/http.d.ts +27 -0
- package/dist/src/http.js +168 -0
- package/dist/src/im-runtime-telemetry.d.ts +25 -0
- package/dist/src/im-runtime-telemetry.js +68 -0
- package/dist/src/interface.d.ts +192 -0
- package/dist/src/interface.js +5 -0
- package/dist/src/markdown-chunk.d.ts +1 -0
- package/dist/src/markdown-chunk.js +396 -0
- package/dist/src/mcp/index.d.ts +6 -0
- package/dist/src/mcp/index.js +28 -0
- package/dist/src/mcp/interceptors/biz-error.d.ts +11 -0
- package/dist/src/mcp/interceptors/biz-error.js +73 -0
- package/dist/src/mcp/interceptors/doc-auth-error.d.ts +10 -0
- package/dist/src/mcp/interceptors/doc-auth-error.js +235 -0
- package/dist/src/mcp/interceptors/index.d.ts +35 -0
- package/dist/src/mcp/interceptors/index.js +143 -0
- package/dist/src/mcp/interceptors/msg-media.d.ts +11 -0
- package/dist/src/mcp/interceptors/msg-media.js +201 -0
- package/dist/src/mcp/interceptors/smartpage-create.d.ts +30 -0
- package/dist/src/mcp/interceptors/smartpage-create.js +252 -0
- package/dist/src/mcp/interceptors/smartpage-export.d.ts +17 -0
- package/dist/src/mcp/interceptors/smartpage-export.js +135 -0
- package/dist/src/mcp/interceptors/smartsheet-upload.d.ts +22 -0
- package/dist/src/mcp/interceptors/smartsheet-upload.js +388 -0
- package/dist/src/mcp/interceptors/types.d.ts +64 -0
- package/dist/src/mcp/interceptors/types.js +8 -0
- package/dist/src/mcp/schema.d.ts +11 -0
- package/dist/src/mcp/schema.js +115 -0
- package/dist/src/mcp/tool.d.ts +63 -0
- package/dist/src/mcp/tool.js +318 -0
- package/dist/src/mcp/transport.d.ts +94 -0
- package/dist/src/mcp/transport.js +702 -0
- package/dist/src/media-handler.d.ts +55 -0
- package/dist/src/media-handler.js +306 -0
- package/dist/src/media-uploader.d.ts +142 -0
- package/dist/src/media-uploader.js +446 -0
- package/dist/src/message-parser.d.ts +104 -0
- package/dist/src/message-parser.js +232 -0
- package/dist/src/message-sender.d.ts +54 -0
- package/dist/src/message-sender.js +210 -0
- package/dist/src/monitor.d.ts +69 -0
- package/dist/src/monitor.js +1846 -0
- package/dist/src/onboarding.d.ts +8 -0
- package/dist/src/onboarding.js +248 -0
- package/dist/src/openclaw-compat.d.ts +148 -0
- package/dist/src/openclaw-compat.js +839 -0
- package/dist/src/proactive-markdown-send.d.ts +14 -0
- package/dist/src/proactive-markdown-send.js +205 -0
- package/dist/src/reqid-store.d.ts +23 -0
- package/dist/src/reqid-store.js +136 -0
- package/dist/src/runtime.d.ts +2 -0
- package/dist/src/runtime.js +7 -0
- package/dist/src/shared/command-auth.d.ts +23 -0
- package/dist/src/shared/command-auth.js +112 -0
- package/dist/src/shared/xml-parser.d.ts +46 -0
- package/dist/src/shared/xml-parser.js +228 -0
- package/dist/src/state-dir-resolve.d.ts +2 -0
- package/dist/src/state-dir-resolve.js +33 -0
- package/dist/src/state-manager.d.ts +115 -0
- package/dist/src/state-manager.js +413 -0
- package/dist/src/target.d.ts +35 -0
- package/dist/src/target.js +71 -0
- package/dist/src/template-card-manager.d.ts +55 -0
- package/dist/src/template-card-manager.js +316 -0
- package/dist/src/template-card-parser.d.ts +37 -0
- package/dist/src/template-card-parser.js +672 -0
- package/dist/src/timeout.d.ts +20 -0
- package/dist/src/timeout.js +57 -0
- package/dist/src/types/account.d.ts +29 -0
- package/dist/src/types/account.js +5 -0
- package/dist/src/types/config.d.ts +98 -0
- package/dist/src/types/config.js +8 -0
- package/dist/src/types/constants.d.ts +42 -0
- package/dist/src/types/constants.js +45 -0
- package/dist/src/types/index.d.ts +7 -0
- package/dist/src/types/index.js +17 -0
- package/dist/src/types/message.d.ts +238 -0
- package/dist/src/types/message.js +6 -0
- package/dist/src/utils.d.ts +148 -0
- package/dist/src/utils.js +92 -0
- package/dist/src/version.d.ts +2 -0
- package/dist/src/version.js +28 -0
- package/dist/src/webhook/command-auth.d.ts +47 -0
- package/dist/src/webhook/command-auth.js +137 -0
- package/dist/src/webhook/gateway.d.ts +36 -0
- package/dist/src/webhook/gateway.js +297 -0
- package/dist/src/webhook/handler.d.ts +19 -0
- package/dist/src/webhook/handler.js +481 -0
- package/dist/src/webhook/helpers.d.ts +157 -0
- package/dist/src/webhook/helpers.js +936 -0
- package/dist/src/webhook/http.d.ts +27 -0
- package/dist/src/webhook/http.js +168 -0
- package/dist/src/webhook/index.d.ts +11 -0
- package/dist/src/webhook/index.js +43 -0
- package/dist/src/webhook/media.d.ts +30 -0
- package/dist/src/webhook/media.js +152 -0
- package/dist/src/webhook/monitor.d.ts +59 -0
- package/dist/src/webhook/monitor.js +1672 -0
- package/dist/src/webhook/state.d.ts +220 -0
- package/dist/src/webhook/state.js +568 -0
- package/dist/src/webhook/target.d.ts +41 -0
- package/dist/src/webhook/target.js +165 -0
- package/dist/src/webhook/types.d.ts +348 -0
- package/dist/src/webhook/types.js +36 -0
- package/dist/src/webhook/video-frame.d.ts +13 -0
- package/dist/src/webhook/video-frame.js +108 -0
- package/openclaw.plugin.json +19 -0
- package/package.json +96 -0
- package/schema.json +534 -0
- package/scripts/generate-schema.mjs +33 -0
- package/skills/wecom-contact/SKILL.md +162 -0
- package/skills/wecom-doc/SKILL.md +162 -0
- package/skills/wecom-doc/references/create-doc.md +56 -0
- package/skills/wecom-doc/references/edit-doc-content.md +68 -0
- package/skills/wecom-doc/references/get-doc-content.md +88 -0
- package/skills/wecom-doc/references/smartpage-create.md +125 -0
- package/skills/wecom-doc/references/smartpage-export.md +160 -0
- package/skills/wecom-meeting/SKILL.md +441 -0
- package/skills/wecom-meeting/references/example-full.md +30 -0
- package/skills/wecom-meeting/references/example-reminder.md +46 -0
- package/skills/wecom-meeting/references/example-security.md +22 -0
- package/skills/wecom-meeting/references/response-get-meeting-info.md +148 -0
- package/skills/wecom-msg/SKILL.md +157 -0
- package/skills/wecom-msg/references/api-get-messages.md +93 -0
- package/skills/wecom-msg/references/api-get-msg-chat-list.md +58 -0
- package/skills/wecom-msg/references/api-get-msg-media.md +44 -0
- package/skills/wecom-msg/references/api-send-message.md +39 -0
- package/skills/wecom-preflight/SKILL.md +141 -0
- package/skills/wecom-schedule/SKILL.md +161 -0
- package/skills/wecom-schedule/references/api-check-availability.md +56 -0
- package/skills/wecom-schedule/references/api-create-schedule.md +38 -0
- package/skills/wecom-schedule/references/api-get-schedule-detail.md +81 -0
- package/skills/wecom-schedule/references/api-update-schedule.md +32 -0
- package/skills/wecom-schedule/references/ref-reminders.md +24 -0
- package/skills/wecom-send-media/SKILL.md +68 -0
- package/skills/wecom-send-template-card/SKILL.md +157 -0
- package/skills/wecom-send-template-card/references/api-template-card-types.md +358 -0
- package/skills/wecom-smartsheet/SKILL.md +164 -0
- package/skills/wecom-smartsheet/references/smartsheet-cell-value-formats.md +163 -0
- package/skills/wecom-smartsheet/references/smartsheet-field-types.md +44 -0
- package/skills/wecom-smartsheet/references/smartsheet-get-records.md +96 -0
- package/skills/wecom-smartsheet/references/webhook-examples.md +185 -0
- package/skills/wecom-smartsheet/references/webhook-fallback.md +184 -0
- package/skills/wecom-todo/SKILL.md +392 -0
- 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 = "";
|
|
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;
|