@ycodium-ai/plugin-im 0.2.3220 → 0.2.3230
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/assets/ui.js +3 -3
- package/dist/index.js +504 -186
- package/locales/en.json +17 -0
- package/locales/zh-CN.json +17 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -126460,9 +126460,21 @@ var makeConclusionLedger = (core) => {
|
|
|
126460
126460
|
unpersisted.delete(key);
|
|
126461
126461
|
if (added) await recover?.(debt);
|
|
126462
126462
|
},
|
|
126463
|
+
/** selection 为 null 表示执行视图不可读且本会话仍有欠账,须等恢复器判定后投递。 */
|
|
126463
126464
|
forTurn: async (threadId, turnId = null) => {
|
|
126464
126465
|
await Promise.all(registering.get(threadId) ?? []);
|
|
126465
|
-
const execution = await core.host.projections.getThreadExecution(threadId)
|
|
126466
|
+
const execution = await core.host.projections.getThreadExecution(threadId).catch((error) => {
|
|
126467
|
+
const owes = Object.values(conclusionDebtsOf(core.state)).some(
|
|
126468
|
+
(debt) => debt.threadId === threadId
|
|
126469
|
+
);
|
|
126470
|
+
if (!owes) return null;
|
|
126471
|
+
core.host.log.warn("chat deferred a conclusion until its execution can be read", {
|
|
126472
|
+
threadId,
|
|
126473
|
+
error: describeError(error)
|
|
126474
|
+
});
|
|
126475
|
+
return void 0;
|
|
126476
|
+
});
|
|
126477
|
+
if (execution === void 0) return { selection: null, handled: false, execution: null };
|
|
126466
126478
|
return {
|
|
126467
126479
|
execution,
|
|
126468
126480
|
...execution === null ? { selection: void 0, handled: false } : forExecutionTurn(
|
|
@@ -133354,6 +133366,87 @@ var makeCommands = (core, deps) => {
|
|
|
133354
133366
|
return { handleCommand, executeCommand, targetOf };
|
|
133355
133367
|
};
|
|
133356
133368
|
|
|
133369
|
+
// src/connectionError.ts
|
|
133370
|
+
var NETWORK_HINTS = {
|
|
133371
|
+
ENOTFOUND: "networkDns",
|
|
133372
|
+
EAI_AGAIN: "networkDns",
|
|
133373
|
+
ECONNREFUSED: "networkRefused",
|
|
133374
|
+
ECONNRESET: "networkReset",
|
|
133375
|
+
EPIPE: "networkReset",
|
|
133376
|
+
UND_ERR_SOCKET: "networkReset",
|
|
133377
|
+
ENETUNREACH: "networkUnreachable",
|
|
133378
|
+
EHOSTUNREACH: "networkUnreachable",
|
|
133379
|
+
ERR_NETWORK_ACCESS_DENIED: "networkUnreachable",
|
|
133380
|
+
CERT_HAS_EXPIRED: "networkTls",
|
|
133381
|
+
CERT_NOT_YET_VALID: "networkTls",
|
|
133382
|
+
DEPTH_ZERO_SELF_SIGNED_CERT: "networkTls",
|
|
133383
|
+
SELF_SIGNED_CERT_IN_CHAIN: "networkTls",
|
|
133384
|
+
UNABLE_TO_VERIFY_LEAF_SIGNATURE: "networkTls",
|
|
133385
|
+
UNABLE_TO_GET_ISSUER_CERT_LOCALLY: "networkTls",
|
|
133386
|
+
ERR_TLS_CERT_ALTNAME_INVALID: "networkTls",
|
|
133387
|
+
ERR_SSL_WRONG_VERSION_NUMBER: "networkTls",
|
|
133388
|
+
ERR_TLS_HANDSHAKE_TIMEOUT: "networkTls",
|
|
133389
|
+
ERR_SSL_TLSV1_ALERT_INTERNAL_ERROR: "networkTls",
|
|
133390
|
+
ETIMEDOUT: "networkTimeout",
|
|
133391
|
+
UND_ERR_CONNECT_TIMEOUT: "networkTimeout",
|
|
133392
|
+
UND_ERR_HEADERS_TIMEOUT: "networkTimeout",
|
|
133393
|
+
UND_ERR_BODY_TIMEOUT: "networkTimeout",
|
|
133394
|
+
timeout: "networkTimeout",
|
|
133395
|
+
ERR_PROXY_CONNECTION_FAILED: "networkProxy"
|
|
133396
|
+
};
|
|
133397
|
+
var NETWORK_REASONS = new Set(Object.keys(NETWORK_HINTS));
|
|
133398
|
+
var GENERIC_REASONS = /* @__PURE__ */ new Set(["timeout"]);
|
|
133399
|
+
var MAX_NODES = 16;
|
|
133400
|
+
var recordOf = (value2) => value2 !== null && typeof value2 === "object" ? value2 : void 0;
|
|
133401
|
+
var httpStatusOf = (value2) => typeof value2 === "number" && Number.isInteger(value2) && value2 >= 100 && value2 <= 599 ? value2 : void 0;
|
|
133402
|
+
var networkReason = (value2) => typeof value2 === "string" && NETWORK_REASONS.has(value2) ? value2 : void 0;
|
|
133403
|
+
var canonicalCode = (entry) => entry["name"] === "TimeoutError" ? "timeout" : entry["code"];
|
|
133404
|
+
var visitedErrors = (error) => {
|
|
133405
|
+
const queue = [error];
|
|
133406
|
+
const seen = /* @__PURE__ */ new Set();
|
|
133407
|
+
const chain = [];
|
|
133408
|
+
while (queue.length > 0 && chain.length < MAX_NODES) {
|
|
133409
|
+
const entry = recordOf(queue.shift());
|
|
133410
|
+
if (entry === void 0 || seen.has(entry)) continue;
|
|
133411
|
+
seen.add(entry);
|
|
133412
|
+
chain.push(entry);
|
|
133413
|
+
if (recordOf(entry["cause"]) !== void 0) queue.push(entry["cause"]);
|
|
133414
|
+
if (Array.isArray(entry["errors"])) queue.push(...entry["errors"].slice(0, MAX_NODES));
|
|
133415
|
+
}
|
|
133416
|
+
return chain;
|
|
133417
|
+
};
|
|
133418
|
+
var connectionFacts = (error) => {
|
|
133419
|
+
const nodes = visitedErrors(error).map((entry) => {
|
|
133420
|
+
const response = recordOf(entry["response"]);
|
|
133421
|
+
const fromCode = networkReason(canonicalCode(entry));
|
|
133422
|
+
return {
|
|
133423
|
+
reasons: fromCode === void 0 ? [] : [fromCode],
|
|
133424
|
+
httpStatus: httpStatusOf(entry["status"] ?? entry["statusCode"] ?? response?.["status"])
|
|
133425
|
+
};
|
|
133426
|
+
});
|
|
133427
|
+
const all2 = [...new Set(nodes.flatMap((node) => node.reasons))];
|
|
133428
|
+
const precise = all2.filter((reason) => !GENERIC_REASONS.has(reason));
|
|
133429
|
+
const httpStatus = nodes.find((node) => node.httpStatus !== void 0)?.httpStatus;
|
|
133430
|
+
return {
|
|
133431
|
+
reasons: precise.length > 0 ? precise : all2,
|
|
133432
|
+
...httpStatus !== void 0 ? { httpStatus } : {}
|
|
133433
|
+
};
|
|
133434
|
+
};
|
|
133435
|
+
var connectionHint = (error) => {
|
|
133436
|
+
const { reasons, httpStatus } = connectionFacts(error);
|
|
133437
|
+
if (reasons.length > 1) return "networkMultipleCauses";
|
|
133438
|
+
const mapped = reasons[0] !== void 0 ? NETWORK_HINTS[reasons[0]] : void 0;
|
|
133439
|
+
if (mapped !== void 0) return mapped;
|
|
133440
|
+
if (httpStatus === 407) return "networkProxy";
|
|
133441
|
+
if (httpStatus === 429) return "platformRateLimited";
|
|
133442
|
+
if (httpStatus !== void 0 && httpStatus >= 500) return "platformUnavailable";
|
|
133443
|
+
return void 0;
|
|
133444
|
+
};
|
|
133445
|
+
var connectionHintFields = (error, platformHint) => {
|
|
133446
|
+
const hint = platformHint ?? connectionHint(error);
|
|
133447
|
+
return hint === void 0 ? {} : { hint };
|
|
133448
|
+
};
|
|
133449
|
+
|
|
133357
133450
|
// src/inboundStore.ts
|
|
133358
133451
|
import * as NodeCrypto from "node:crypto";
|
|
133359
133452
|
import * as NodeFSP from "node:fs/promises";
|
|
@@ -134068,7 +134161,7 @@ var startConnections = (core, inboundHandlersFor, inboundState, recovery) => {
|
|
|
134068
134161
|
state: "failed",
|
|
134069
134162
|
...status.reason === void 0 ? {} : { reason: status.reason },
|
|
134070
134163
|
...status.error === void 0 ? {} : { error: redactor.redact(describeError(status.error)) },
|
|
134071
|
-
...status.
|
|
134164
|
+
...connectionHintFields(status.error, status.hint)
|
|
134072
134165
|
});
|
|
134073
134166
|
}
|
|
134074
134167
|
});
|
|
@@ -134081,7 +134174,7 @@ var startConnections = (core, inboundHandlersFor, inboundState, recovery) => {
|
|
|
134081
134174
|
record4(bot.rowId, {
|
|
134082
134175
|
state: "failed",
|
|
134083
134176
|
error: detail,
|
|
134084
|
-
...error instanceof InboxUnreadableError ? { reason: "inbox-unreadable", hint: "inboxUnreadable" } :
|
|
134177
|
+
...error instanceof InboxUnreadableError ? { reason: "inbox-unreadable", hint: "inboxUnreadable" } : connectionHintFields(error)
|
|
134085
134178
|
});
|
|
134086
134179
|
host.log.warn("chat could not start an inbound connection", {
|
|
134087
134180
|
bot: bot.displayName,
|
|
@@ -135640,11 +135733,11 @@ var parseNumberedReply = (item, text4, t) => {
|
|
|
135640
135733
|
// src/questionFlow.ts
|
|
135641
135734
|
var makeQuestionFlow = (host) => {
|
|
135642
135735
|
const { t } = host;
|
|
135643
|
-
const
|
|
135644
|
-
const itemOf = (requestId, questionId) =>
|
|
135736
|
+
const recordOf2 = (requestId) => questionsOf(host.state())[requestId];
|
|
135737
|
+
const itemOf = (requestId, questionId) => recordOf2(requestId)?.items.find((item) => item.id === questionId);
|
|
135645
135738
|
const hasButtons = (chatKey) => host.target(chatKey)?.adapter.choiceCards !== void 0;
|
|
135646
135739
|
const redraw = async (requestId, questionId) => {
|
|
135647
|
-
const record4 =
|
|
135740
|
+
const record4 = recordOf2(requestId);
|
|
135648
135741
|
const item = itemOf(requestId, questionId);
|
|
135649
135742
|
const target2 = record4 === void 0 ? void 0 : host.target(record4.chatKey);
|
|
135650
135743
|
if (record4 === void 0 || item?.cardId === void 0 || target2 === void 0) return;
|
|
@@ -135660,7 +135753,7 @@ var makeQuestionFlow = (host) => {
|
|
|
135660
135753
|
}
|
|
135661
135754
|
};
|
|
135662
135755
|
const freeze = async (requestId, questionId) => {
|
|
135663
|
-
const record4 =
|
|
135756
|
+
const record4 = recordOf2(requestId);
|
|
135664
135757
|
const item = itemOf(requestId, questionId);
|
|
135665
135758
|
const target2 = record4 === void 0 ? void 0 : host.target(record4.chatKey);
|
|
135666
135759
|
if (record4 === void 0 || item?.cardId === void 0 || target2 === void 0) return;
|
|
@@ -135681,7 +135774,7 @@ var makeQuestionFlow = (host) => {
|
|
|
135681
135774
|
}
|
|
135682
135775
|
};
|
|
135683
135776
|
const sayNext = async (requestId) => {
|
|
135684
|
-
const record4 =
|
|
135777
|
+
const record4 = recordOf2(requestId);
|
|
135685
135778
|
if (record4 === void 0 || record4.resolved) return;
|
|
135686
135779
|
const item = record4.items.find(isUnanswered);
|
|
135687
135780
|
if (item === void 0) return;
|
|
@@ -135691,7 +135784,7 @@ var makeQuestionFlow = (host) => {
|
|
|
135691
135784
|
);
|
|
135692
135785
|
};
|
|
135693
135786
|
const post = async (requestId) => {
|
|
135694
|
-
const first =
|
|
135787
|
+
const first = recordOf2(requestId);
|
|
135695
135788
|
const target2 = first === void 0 ? void 0 : host.target(first.chatKey);
|
|
135696
135789
|
if (first === void 0 || target2 === void 0) return;
|
|
135697
135790
|
const cards = target2.adapter.choiceCards;
|
|
@@ -135700,7 +135793,7 @@ var makeQuestionFlow = (host) => {
|
|
|
135700
135793
|
return;
|
|
135701
135794
|
}
|
|
135702
135795
|
for (const questionId of first.items.map((item) => item.id)) {
|
|
135703
|
-
const record4 =
|
|
135796
|
+
const record4 = recordOf2(requestId);
|
|
135704
135797
|
const item = itemOf(requestId, questionId);
|
|
135705
135798
|
if (record4 === void 0 || record4.resolved || item === void 0) return;
|
|
135706
135799
|
try {
|
|
@@ -135710,7 +135803,7 @@ var makeQuestionFlow = (host) => {
|
|
|
135710
135803
|
);
|
|
135711
135804
|
if (cardId === null) continue;
|
|
135712
135805
|
host.commit("question-carded", { requestId, questionId, cardId });
|
|
135713
|
-
const after =
|
|
135806
|
+
const after = recordOf2(requestId);
|
|
135714
135807
|
if (after?.resolved === true || itemOf(requestId, questionId)?.answer !== void 0) {
|
|
135715
135808
|
await freeze(requestId, questionId);
|
|
135716
135809
|
}
|
|
@@ -135727,7 +135820,7 @@ var makeQuestionFlow = (host) => {
|
|
|
135727
135820
|
host.warn("chat cannot show questions on this platform");
|
|
135728
135821
|
return;
|
|
135729
135822
|
}
|
|
135730
|
-
const fresh = pending.filter((request) =>
|
|
135823
|
+
const fresh = pending.filter((request) => recordOf2(request.requestId) === void 0);
|
|
135731
135824
|
for (const request of buttons ? fresh : fresh.slice(0, 1)) {
|
|
135732
135825
|
host.commit("question-offered", {
|
|
135733
135826
|
chatKey,
|
|
@@ -135750,18 +135843,18 @@ var makeQuestionFlow = (host) => {
|
|
|
135750
135843
|
...question.multiSelect ? { submitToken: host.newToken() } : {}
|
|
135751
135844
|
}))
|
|
135752
135845
|
});
|
|
135753
|
-
if (
|
|
135846
|
+
if (recordOf2(request.requestId) === void 0) continue;
|
|
135754
135847
|
host.outbound(chatKey, () => post(request.requestId));
|
|
135755
135848
|
}
|
|
135756
135849
|
};
|
|
135757
135850
|
const answer = async (requestId, questionId, value2, label) => {
|
|
135758
|
-
const before =
|
|
135851
|
+
const before = recordOf2(requestId);
|
|
135759
135852
|
const item = itemOf(requestId, questionId);
|
|
135760
135853
|
if (before === void 0 || before.resolved || item === void 0 || !isUnanswered(item)) {
|
|
135761
135854
|
return false;
|
|
135762
135855
|
}
|
|
135763
135856
|
host.commit("question-answered", { requestId, questionId, answer: value2, label });
|
|
135764
|
-
const after =
|
|
135857
|
+
const after = recordOf2(requestId);
|
|
135765
135858
|
if (after === void 0) return false;
|
|
135766
135859
|
const complete = after.items.every((entry) => !isUnanswered(entry));
|
|
135767
135860
|
if (complete) host.commit("question-resolved", { requestId, ending: "here" });
|
|
@@ -135840,7 +135933,7 @@ var makeQuestionFlow = (host) => {
|
|
|
135840
135933
|
};
|
|
135841
135934
|
const answerText = (input) => answer(input.requestId, input.questionId, input.value, input.label);
|
|
135842
135935
|
const resolved = (requestId, outcome) => {
|
|
135843
|
-
const record4 =
|
|
135936
|
+
const record4 = recordOf2(requestId);
|
|
135844
135937
|
if (record4 === void 0 || record4.resolved) return;
|
|
135845
135938
|
const ending = outcome === "answered" ? "elsewhere" : "cancelled";
|
|
135846
135939
|
host.commit("question-resolved", { requestId, ending });
|
|
@@ -135938,7 +136031,7 @@ var makeQueueFlow = (host, deps) => {
|
|
|
135938
136031
|
const { t } = host;
|
|
135939
136032
|
const shown = /* @__PURE__ */ new Map();
|
|
135940
136033
|
const notes = /* @__PURE__ */ new Map();
|
|
135941
|
-
const
|
|
136034
|
+
const recordOf2 = (intentId) => queueOf(host.state())[intentId];
|
|
135942
136035
|
const factsOf = (execution, intentId) => ({
|
|
135943
136036
|
activeTurnId: execution.activeTurnId,
|
|
135944
136037
|
queuePaused: execution.queuePaused,
|
|
@@ -135976,7 +136069,7 @@ var makeQueueFlow = (host, deps) => {
|
|
|
135976
136069
|
resumeToken: host.newToken()
|
|
135977
136070
|
});
|
|
135978
136071
|
host.outbound(chatKey, async () => {
|
|
135979
|
-
const record4 =
|
|
136072
|
+
const record4 = recordOf2(intentId);
|
|
135980
136073
|
if (record4 === void 0) return;
|
|
135981
136074
|
try {
|
|
135982
136075
|
const latest = await deps.readExecution(threadId) ?? execution;
|
|
@@ -136002,7 +136095,7 @@ var makeQueueFlow = (host, deps) => {
|
|
|
136002
136095
|
});
|
|
136003
136096
|
};
|
|
136004
136097
|
const redraw = async (intentId, released) => {
|
|
136005
|
-
const record4 =
|
|
136098
|
+
const record4 = recordOf2(intentId);
|
|
136006
136099
|
const target2 = record4 === void 0 ? void 0 : host.target(record4.chatKey);
|
|
136007
136100
|
if (record4 === void 0 || record4.settled !== void 0 || target2 === void 0) return;
|
|
136008
136101
|
if (record4.cardId === void 0) return;
|
|
@@ -138406,6 +138499,9 @@ var fetchUserName = async (input) => {
|
|
|
138406
138499
|
};
|
|
138407
138500
|
var sendChatText = async (input) => postMessage({ ...input, operation: "send", msgType: "text", content: { text: input.text } });
|
|
138408
138501
|
var LARK_WORKING_REACTION = "OnIt";
|
|
138502
|
+
var LARK_DONE_REACTION = "DONE";
|
|
138503
|
+
var LARK_FAILED_REACTION = "ERROR";
|
|
138504
|
+
var LARK_REACTION_TIMEOUT_MS = 2e3;
|
|
138409
138505
|
var addReaction = async (input) => {
|
|
138410
138506
|
const response = await input.http(
|
|
138411
138507
|
`${LARK_BASE}/im/v1/messages/${encodeURIComponent(input.messageId)}/reactions`,
|
|
@@ -138415,7 +138511,8 @@ var addReaction = async (input) => {
|
|
|
138415
138511
|
authorization: `Bearer ${input.token}`,
|
|
138416
138512
|
"content-type": "application/json; charset=utf-8"
|
|
138417
138513
|
},
|
|
138418
|
-
body: JSON.stringify({ reaction_type: { emoji_type: input.emojiType } })
|
|
138514
|
+
body: JSON.stringify({ reaction_type: { emoji_type: input.emojiType } }),
|
|
138515
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
138419
138516
|
}
|
|
138420
138517
|
);
|
|
138421
138518
|
const body = await readEnvelope("reactions.create", response);
|
|
@@ -138426,7 +138523,8 @@ var removeReaction = async (input) => {
|
|
|
138426
138523
|
`${LARK_BASE}/im/v1/messages/${encodeURIComponent(input.messageId)}/reactions/${encodeURIComponent(input.reactionId)}`,
|
|
138427
138524
|
{
|
|
138428
138525
|
method: "DELETE",
|
|
138429
|
-
headers: { authorization: `Bearer ${input.token}` }
|
|
138526
|
+
headers: { authorization: `Bearer ${input.token}` },
|
|
138527
|
+
...input.signal === void 0 ? {} : { signal: input.signal }
|
|
138430
138528
|
}
|
|
138431
138529
|
);
|
|
138432
138530
|
await readEnvelope("reactions.delete", response);
|
|
@@ -144251,7 +144349,7 @@ var startLarkInbound = (input) => {
|
|
|
144251
144349
|
state: "failed",
|
|
144252
144350
|
reason: hint === "larkCredentials" ? "credentials-rejected" : "disconnected",
|
|
144253
144351
|
error,
|
|
144254
|
-
...
|
|
144352
|
+
...connectionHintFields(error, hint)
|
|
144255
144353
|
});
|
|
144256
144354
|
}
|
|
144257
144355
|
};
|
|
@@ -144310,6 +144408,22 @@ var larkInboundPersistence = (contextFor) => ({
|
|
|
144310
144408
|
}
|
|
144311
144409
|
});
|
|
144312
144410
|
|
|
144411
|
+
// src/deadline.ts
|
|
144412
|
+
var withDeadline2 = async (timeoutMs, load) => {
|
|
144413
|
+
const signal = AbortSignal.timeout(timeoutMs);
|
|
144414
|
+
let onAbort = () => {
|
|
144415
|
+
};
|
|
144416
|
+
const aborted = new Promise((_, reject) => {
|
|
144417
|
+
onAbort = () => reject(signal.reason);
|
|
144418
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
144419
|
+
});
|
|
144420
|
+
try {
|
|
144421
|
+
return await Promise.race([load(signal), aborted]);
|
|
144422
|
+
} finally {
|
|
144423
|
+
signal.removeEventListener("abort", onAbort);
|
|
144424
|
+
}
|
|
144425
|
+
};
|
|
144426
|
+
|
|
144313
144427
|
// src/boundedSeen.ts
|
|
144314
144428
|
var makeBoundedSeen = (limit) => {
|
|
144315
144429
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -144328,22 +144442,6 @@ var makeBoundedSeen = (limit) => {
|
|
|
144328
144442
|
};
|
|
144329
144443
|
};
|
|
144330
144444
|
|
|
144331
|
-
// src/deadline.ts
|
|
144332
|
-
var withDeadline2 = async (timeoutMs, load) => {
|
|
144333
|
-
const signal = AbortSignal.timeout(timeoutMs);
|
|
144334
|
-
let onAbort = () => {
|
|
144335
|
-
};
|
|
144336
|
-
const aborted = new Promise((_, reject) => {
|
|
144337
|
-
onAbort = () => reject(signal.reason);
|
|
144338
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
144339
|
-
});
|
|
144340
|
-
try {
|
|
144341
|
-
return await Promise.race([load(signal), aborted]);
|
|
144342
|
-
} finally {
|
|
144343
|
-
signal.removeEventListener("abort", onAbort);
|
|
144344
|
-
}
|
|
144345
|
-
};
|
|
144346
|
-
|
|
144347
144445
|
// src/replyReference.ts
|
|
144348
144446
|
import * as NodeCrypto4 from "node:crypto";
|
|
144349
144447
|
|
|
@@ -144977,12 +145075,11 @@ var makeLarkAdapter = (deps) => {
|
|
|
144977
145075
|
detail: `token ok; expiresIn=${String(expiresInSeconds)}s`
|
|
144978
145076
|
};
|
|
144979
145077
|
} catch (error) {
|
|
144980
|
-
const hint = larkConnectionHint(error);
|
|
144981
145078
|
return {
|
|
144982
145079
|
stage: "tenant_access_token",
|
|
144983
145080
|
ok: false,
|
|
144984
145081
|
detail: describeError(error),
|
|
144985
|
-
...
|
|
145082
|
+
...connectionHintFields(error, larkConnectionHint(error))
|
|
144986
145083
|
};
|
|
144987
145084
|
}
|
|
144988
145085
|
},
|
|
@@ -145087,13 +145184,22 @@ var makeLarkAdapter = (deps) => {
|
|
|
145087
145184
|
messageId,
|
|
145088
145185
|
emojiType: LARK_WORKING_REACTION
|
|
145089
145186
|
}),
|
|
145090
|
-
clearAcknowledge: async (binding, messageId, ackId) => {
|
|
145091
|
-
await
|
|
145092
|
-
|
|
145093
|
-
|
|
145094
|
-
messageId,
|
|
145095
|
-
|
|
145096
|
-
|
|
145187
|
+
clearAcknowledge: async (binding, messageId, ackId, outcome) => {
|
|
145188
|
+
const token = await tenantToken(binding);
|
|
145189
|
+
await withDeadline2(
|
|
145190
|
+
LARK_REACTION_TIMEOUT_MS,
|
|
145191
|
+
(signal) => removeReaction({ http: deps.http, token, messageId, reactionId: ackId, signal })
|
|
145192
|
+
);
|
|
145193
|
+
const emojiType = outcome === "done" ? LARK_DONE_REACTION : outcome === "failed" ? LARK_FAILED_REACTION : null;
|
|
145194
|
+
if (emojiType === null) return;
|
|
145195
|
+
try {
|
|
145196
|
+
await withDeadline2(
|
|
145197
|
+
LARK_REACTION_TIMEOUT_MS,
|
|
145198
|
+
(signal) => addReaction({ http: deps.http, token, messageId, emojiType, signal })
|
|
145199
|
+
);
|
|
145200
|
+
} catch (error) {
|
|
145201
|
+
deps.log.warn("lark could not react to the message", { error: describeError(error) });
|
|
145202
|
+
}
|
|
145097
145203
|
},
|
|
145098
145204
|
fetchResource: async (binding, input) => {
|
|
145099
145205
|
const resource = input.resource;
|
|
@@ -145330,6 +145436,13 @@ var en_default = {
|
|
|
145330
145436
|
turnFailedNoDetail: "This turn didn't finish. Reference {{ref}}. Send the message again; if it keeps failing, send /new to start a new conversation.",
|
|
145331
145437
|
turnFailedBrief: "This turn didn't finish: {{detail}}\nSend the message again; if it keeps failing, send /new to start a new conversation.",
|
|
145332
145438
|
turnFailedBriefNoDetail: "This turn didn't finish. Send the message again; if it keeps failing, send /new to start a new conversation.",
|
|
145439
|
+
turnFailedWithReference: "{{message}}\nReference {{ref}}.",
|
|
145440
|
+
turnFailedQuota: "The model quota or balance is insufficient, so this turn didn't finish. Send /model to switch to another model, or ask an administrator to add quota, then try again.",
|
|
145441
|
+
turnFailedRateLimit: "The model service is rate-limiting requests, so this turn didn't finish. Please try again later.",
|
|
145442
|
+
turnFailedContextLimit: "This conversation exceeds the model context limit, so this turn didn't finish. Send /new to start a new conversation, then send your request again.",
|
|
145443
|
+
turnFailedAuth: "The model credentials are missing or invalid, so this turn didn't finish. Ask an administrator to check the model settings, then try again.",
|
|
145444
|
+
turnFailedModelUnavailable: "The current model does not exist or does not support the selected settings, so this turn didn't finish. Send /model to list models, then send /model followed by a number (for example /model 2) to pick one for this chat, and send your request again.",
|
|
145445
|
+
turnFailedTransport: "The model service is temporarily unreachable, so this turn didn't finish. Please try again later.",
|
|
145333
145446
|
attachmentReceived: "Got {{names}} ({{count}} waiting). Tell me what to do with them.",
|
|
145334
145447
|
attachmentFailed: "Could not take {{name}}: {{reason}}.",
|
|
145335
145448
|
attachmentReason: {
|
|
@@ -145681,6 +145794,16 @@ var en_default = {
|
|
|
145681
145794
|
failed: "Connection failed",
|
|
145682
145795
|
notSaved: "Save this row first (credentials are read from saved config only).",
|
|
145683
145796
|
hint: {
|
|
145797
|
+
networkMultipleCauses: "This failure has more than one network cause. Check this machine's network and this bot's Proxy setting, then check again.",
|
|
145798
|
+
networkDns: "The service's domain name could not be resolved. Check this machine's DNS and network settings, then check again.",
|
|
145799
|
+
networkRefused: "The connection was refused. Check whether a firewall or security software on this machine or its network is blocking it, then check again.",
|
|
145800
|
+
networkReset: "The connection was cut off by the other side. Check this machine's network and whether the target service is running normally, then check again.",
|
|
145801
|
+
networkUnreachable: "The target network is unreachable. Check this machine's outbound network access and access restrictions, then check again.",
|
|
145802
|
+
networkTls: "TLS or certificate validation failed. Check this machine's system clock, certificate chain and network settings, and whether a proxy or security software is intercepting HTTPS, then check again.",
|
|
145803
|
+
networkTimeout: "The request timed out. Check whether the target service is running normally and check this machine's network, then check again.",
|
|
145804
|
+
networkProxy: "Proxy connection or authentication failed. Check this row's Proxy setting and the selected proxy's configuration on this machine; if no proxy is set, check other proxies on this machine or its network, then check again.",
|
|
145805
|
+
platformRateLimited: "The platform is rate limiting requests. Try again later.",
|
|
145806
|
+
platformUnavailable: "The target service is temporarily having problems. Try again later.",
|
|
145684
145807
|
connecting: "Still connecting. There is usually a result within 20 seconds; check again in a moment.",
|
|
145685
145808
|
badToken: "This does not look like a bot token. Copy it again from BotFather: digits, a colon, then the key.",
|
|
145686
145809
|
unauthorized: "Telegram does not accept this token. It may have been revoked; get the current one from BotFather. Save the corrected token here to reconnect automatically; if nothing needs changing, use Reconnect below.",
|
|
@@ -146100,6 +146223,13 @@ var zh_CN_default = {
|
|
|
146100
146223
|
turnFailedNoDetail: "\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5B8C\u6210\u3002\u53C2\u8003\u53F7 {{ref}}\u3002\u53EF\u4EE5\u76F4\u63A5\u518D\u53D1\u4E00\u6B21\uFF1B\u4E00\u76F4\u4E0D\u884C\u5C31\u53D1 /new \u5F00\u4E2A\u65B0\u4F1A\u8BDD\u3002",
|
|
146101
146224
|
turnFailedBrief: "\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5B8C\u6210\uFF1A{{detail}}\n\u53EF\u4EE5\u76F4\u63A5\u518D\u53D1\u4E00\u6B21\uFF1B\u4E00\u76F4\u4E0D\u884C\u5C31\u53D1 /new \u5F00\u4E2A\u65B0\u4F1A\u8BDD\u3002",
|
|
146102
146225
|
turnFailedBriefNoDetail: "\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5B8C\u6210\u3002\u53EF\u4EE5\u76F4\u63A5\u518D\u53D1\u4E00\u6B21\uFF1B\u4E00\u76F4\u4E0D\u884C\u5C31\u53D1 /new \u5F00\u4E2A\u65B0\u4F1A\u8BDD\u3002",
|
|
146226
|
+
turnFailedWithReference: "{{message}}\n\u53C2\u8003\u53F7 {{ref}}\u3002",
|
|
146227
|
+
turnFailedQuota: "\u6A21\u578B\u989D\u5EA6\u6216\u4F59\u989D\u4E0D\u8DB3\uFF0C\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5B8C\u6210\u3002\u53EF\u4EE5\u53D1 /model \u6362\u4E2A\u6A21\u578B\u518D\u8BD5\uFF0C\u6216\u8BF7\u7BA1\u7406\u5458\u8865\u5145\u989D\u5EA6\u540E\u91CD\u8BD5\u3002",
|
|
146228
|
+
turnFailedRateLimit: "\u6A21\u578B\u670D\u52A1\u6B63\u5728\u9650\u6D41\uFF0C\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5B8C\u6210\u3002\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
|
|
146229
|
+
turnFailedContextLimit: "\u5F53\u524D\u4F1A\u8BDD\u5185\u5BB9\u8D85\u8FC7\u6A21\u578B\u4E0A\u4E0B\u6587\u4E0A\u9650\uFF0C\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5B8C\u6210\u3002\u8BF7\u53D1 /new \u5F00\u4E2A\u65B0\u4F1A\u8BDD\uFF0C\u518D\u628A\u8BF7\u6C42\u91CD\u65B0\u53D1\u4E00\u904D\u3002",
|
|
146230
|
+
turnFailedAuth: "\u6A21\u578B\u51ED\u636E\u7F3A\u5931\u6216\u65E0\u6548\uFF0C\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5B8C\u6210\u3002\u8BF7\u7BA1\u7406\u5458\u68C0\u67E5\u6A21\u578B\u914D\u7F6E\uFF0C\u4E4B\u540E\u4F60\u518D\u53D1\u4E00\u6B21\u3002",
|
|
146231
|
+
turnFailedModelUnavailable: "\u5F53\u524D\u6A21\u578B\u4E0D\u5B58\u5728\u6216\u4E0D\u652F\u6301\u6240\u9009\u914D\u7F6E\uFF0C\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5B8C\u6210\u3002\u8BF7\u53D1 /model \u67E5\u770B\u53EF\u9009\u6A21\u578B\uFF0C\u518D\u53D1 /model \u52A0\u7F16\u53F7\uFF08\u4F8B\u5982 /model 2\uFF09\u4E3A\u8FD9\u4E2A\u804A\u5929\u9009\u4E00\u4E2A\uFF0C\u7136\u540E\u91CD\u53D1\u8BF7\u6C42\u3002",
|
|
146232
|
+
turnFailedTransport: "\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5\u6A21\u578B\u670D\u52A1\uFF0C\u8FD9\u4E00\u8F6E\u6CA1\u80FD\u5B8C\u6210\u3002\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
|
|
146103
146233
|
attachmentReceived: "\u6536\u5230 {{names}}\uFF08\u73B0\u6709 {{count}} \u4E2A\u5F85\u5904\u7406\uFF09\u3002\u8BF4\u4E00\u53E5\u60F3\u8BA9\u6211\u600E\u4E48\u5904\u7406\u3002",
|
|
146104
146234
|
attachmentFailed: "\u6CA1\u80FD\u6536\u4E0B {{name}}\uFF1A{{reason}}\u3002",
|
|
146105
146235
|
attachmentReason: {
|
|
@@ -146451,6 +146581,16 @@ var zh_CN_default = {
|
|
|
146451
146581
|
failed: "\u8FDE\u63A5\u5931\u8D25",
|
|
146452
146582
|
notSaved: "\u8BF7\u5148\u4FDD\u5B58\u8FD9\u4E00\u884C\u518D\u68C0\u67E5\u8FDE\u63A5\uFF08\u51ED\u636E\u53EA\u4ECE\u5DF2\u4FDD\u5B58\u914D\u7F6E\u8BFB\u53D6\uFF09\u3002",
|
|
146453
146583
|
hint: {
|
|
146584
|
+
networkMultipleCauses: "\u8FD9\u6B21\u5931\u8D25\u80CC\u540E\u4E0D\u6B62\u4E00\u79CD\u7F51\u7EDC\u95EE\u9898\u3002\u8BF7\u68C0\u67E5\u8FD9\u53F0\u673A\u5668\u7684\u7F51\u7EDC\u548C\u8FD9\u4E2A\u673A\u5668\u4EBA\u7684\u300C\u4EE3\u7406\u300D\u8BBE\u7F6E\uFF0C\u518D\u68C0\u67E5\u4E00\u6B21\u3002",
|
|
146585
|
+
networkDns: "\u670D\u52A1\u57DF\u540D\u89E3\u6790\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u8FD9\u53F0\u673A\u5668\u7684 DNS \u548C\u7F51\u7EDC\u8BBE\u7F6E\uFF0C\u518D\u68C0\u67E5\u4E00\u6B21\u3002",
|
|
146586
|
+
networkRefused: "\u76EE\u6807\u62D2\u7EDD\u4E86\u8FDE\u63A5\u3002\u8BF7\u68C0\u67E5\u8FD9\u53F0\u673A\u5668\u548C\u6240\u5728\u7F51\u7EDC\u7684\u9632\u706B\u5899\u3001\u5B89\u5168\u8F6F\u4EF6\u662F\u5426\u62E6\u4E86\u8FD9\u4E2A\u8FDE\u63A5\uFF0C\u518D\u68C0\u67E5\u4E00\u6B21\u3002",
|
|
146587
|
+
networkReset: "\u8FDE\u63A5\u88AB\u5BF9\u65B9\u4E2D\u65AD\u3002\u8BF7\u68C0\u67E5\u8FD9\u53F0\u673A\u5668\u7684\u7F51\u7EDC\uFF0C\u4EE5\u53CA\u76EE\u6807\u670D\u52A1\u662F\u5426\u5728\u6B63\u5E38\u8FD0\u884C\uFF0C\u518D\u68C0\u67E5\u4E00\u6B21\u3002",
|
|
146588
|
+
networkUnreachable: "\u76EE\u6807\u7F51\u7EDC\u4E0D\u53EF\u8FBE\u3002\u8BF7\u68C0\u67E5\u8FD9\u53F0\u673A\u5668\u7684\u7F51\u7EDC\u51FA\u53E3\u548C\u8BBF\u95EE\u9650\u5236\uFF0C\u518D\u68C0\u67E5\u4E00\u6B21\u3002",
|
|
146589
|
+
networkTls: "TLS \u6216\u8BC1\u4E66\u6821\u9A8C\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u8FD9\u53F0\u673A\u5668\u7684\u7CFB\u7EDF\u65F6\u95F4\u3001\u8BC1\u4E66\u94FE\u548C\u7F51\u7EDC\u8BBE\u7F6E\uFF0C\u4EE5\u53CA\u4EE3\u7406\u6216\u5B89\u5168\u8F6F\u4EF6\u662F\u5426\u62E6\u622A\u4E86 HTTPS \u8FDE\u63A5\uFF0C\u518D\u68C0\u67E5\u4E00\u6B21\u3002",
|
|
146590
|
+
networkTimeout: "\u8BF7\u6C42\u8D85\u65F6\u3002\u8BF7\u786E\u8BA4\u76EE\u6807\u670D\u52A1\u662F\u5426\u5728\u6B63\u5E38\u8FD0\u884C\uFF0C\u5E76\u68C0\u67E5\u8FD9\u53F0\u673A\u5668\u7684\u7F51\u7EDC\uFF0C\u518D\u68C0\u67E5\u4E00\u6B21\u3002",
|
|
146591
|
+
networkProxy: "\u4EE3\u7406\u8FDE\u63A5\u6216\u8BA4\u8BC1\u5931\u8D25\u3002\u8BF7\u68C0\u67E5\u8FD9\u4E00\u884C\u7684\u300C\u4EE3\u7406\u300D\u8BBE\u7F6E\u548C\u6240\u9009\u4EE3\u7406\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u7684\u914D\u7F6E\uFF1B\u6CA1\u8BBE\u4EE3\u7406\u7684\u8BDD\uFF0C\u68C0\u67E5\u8FD9\u53F0\u673A\u5668\u6216\u6240\u5728\u7F51\u7EDC\u4E0A\u7684\u5176\u4ED6\u4EE3\u7406\uFF0C\u518D\u68C0\u67E5\u4E00\u6B21\u3002",
|
|
146592
|
+
platformRateLimited: "\u5E73\u53F0\u6B63\u5728\u9650\u6D41\u3002\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
|
|
146593
|
+
platformUnavailable: "\u76EE\u6807\u670D\u52A1\u6682\u65F6\u5F02\u5E38\u3002\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
|
|
146454
146594
|
connecting: "\u8FD8\u5728\u8FDE\u63A5\uFF0C\u4E00\u822C 20 \u79D2\u5185\u4F1A\u6709\u7ED3\u679C\uFF0C\u7A0D\u540E\u518D\u68C0\u67E5\u4E00\u6B21\u3002",
|
|
146455
146595
|
badToken: "\u8FD9\u4E0D\u50CF\u673A\u5668\u4EBA\u7684 token\u3002\u5230 BotFather \u91CD\u65B0\u590D\u5236\u4E00\u4EFD\uFF1A\u6570\u5B57\u3001\u5192\u53F7\uFF0C\u540E\u9762\u662F\u5BC6\u94A5\u3002",
|
|
146456
146596
|
unauthorized: "Telegram \u4E0D\u8BA4\u8FD9\u4E2A token\uFF0C\u53EF\u80FD\u5DF2\u7ECF\u4F5C\u5E9F\u3002\u5230 BotFather \u53D6\u73B0\u5728\u7684\u90A3\u4E00\u4EFD\u3002\u6539\u597D\u540E\u5728\u8FD9\u91CC\u4FDD\u5B58\uFF0C\u673A\u5668\u4EBA\u4F1A\u81EA\u52A8\u91CD\u65B0\u8FDE\u63A5\uFF1B\u6CA1\u6709\u8981\u6539\u7684\u4E5F\u53EF\u4EE5\u70B9\u4E0B\u65B9\u7684\u300C\u91CD\u65B0\u8FDE\u63A5\u300D\u3002",
|
|
@@ -146856,11 +146996,11 @@ var makeConclusionRecovery = (core, ledger, delivery, failures) => {
|
|
|
146856
146996
|
enqueueConclusion(core, ledger, binding, selection, async (owed) => {
|
|
146857
146997
|
try {
|
|
146858
146998
|
if (turn.state === "error") {
|
|
146859
|
-
const
|
|
146999
|
+
const session = execution.latestTurn?.state === "error" && execution.latestTurn.turnId === turn.turnId ? execution.session : void 0;
|
|
146860
147000
|
return delivery.sendText(
|
|
146861
147001
|
binding,
|
|
146862
147002
|
debt.threadId,
|
|
146863
|
-
failures.forFailure(debt.threadId,
|
|
147003
|
+
failures.forFailure(debt.threadId, session?.lastError, session?.failureCategory),
|
|
146864
147004
|
true,
|
|
146865
147005
|
turn.turnId,
|
|
146866
147006
|
owed
|
|
@@ -146978,7 +147118,7 @@ var makeNotifications = (core, deps) => {
|
|
|
146978
147118
|
(debt) => debt.threadId === threadId
|
|
146979
147119
|
);
|
|
146980
147120
|
const { selection, handled, execution } = said || owes || targets.length > 0 ? await conclusions.forTurn(threadId) : { selection: void 0, handled: false, execution: null };
|
|
146981
|
-
if (selection !== void 0) {
|
|
147121
|
+
if (selection !== void 0 && selection !== null) {
|
|
146982
147122
|
const binding = bindingForChatKey(selection.debt.chatKey);
|
|
146983
147123
|
if (binding !== void 0 && !streamsTo(binding, threadId) && execution?.session?.activeTurnId == null && execution?.latestTurn?.state !== "running" && execution?.latestTurn?.state !== "error" && payload.session?.status !== "error") {
|
|
146984
147124
|
const turnId = execution?.latestTurn?.turnId ?? null;
|
|
@@ -146987,7 +147127,7 @@ var makeNotifications = (core, deps) => {
|
|
|
146987
147127
|
return send(binding, { recovered: false, streaming: false, owed });
|
|
146988
147128
|
});
|
|
146989
147129
|
}
|
|
146990
|
-
} else if (said && !handled) {
|
|
147130
|
+
} else if (selection !== null && said && !handled) {
|
|
146991
147131
|
const send = await delivery.prepareConclusion(threadId);
|
|
146992
147132
|
for (const binding of targets) {
|
|
146993
147133
|
const streaming = streamsTo(binding, threadId);
|
|
@@ -147018,16 +147158,17 @@ var makeNotifications = (core, deps) => {
|
|
|
147018
147158
|
await ready;
|
|
147019
147159
|
const targets = targetsForProject(threadId, await projectOfThread(threadId));
|
|
147020
147160
|
const { selection, handled, execution } = await conclusions.forTurn(threadId);
|
|
147021
|
-
const debtBinding = selection
|
|
147022
|
-
const recipients = selection
|
|
147023
|
-
const textTargets = handled ? [] : recipients.filter(
|
|
147161
|
+
const debtBinding = selection == null ? void 0 : bindingForChatKey(selection.debt.chatKey);
|
|
147162
|
+
const recipients = selection == null ? targets : debtBinding === void 0 ? [] : [debtBinding];
|
|
147163
|
+
const textTargets = handled || selection === null ? [] : recipients.filter(
|
|
147024
147164
|
(binding) => !(streamsTo(binding, threadId) && turnCards.covers(threadId))
|
|
147025
147165
|
);
|
|
147026
147166
|
const drawingTurn = turnCards.drawingTurn(threadId);
|
|
147027
|
-
const
|
|
147167
|
+
const failure2 = readThreadFailed(event);
|
|
147168
|
+
const notice = textTargets.length > 0 || drawingTurn !== null ? failures.forFailure(threadId, failure2?.detail, failure2?.failureCategory) : null;
|
|
147028
147169
|
if (notice !== null && drawingTurn !== null)
|
|
147029
147170
|
failures.holdForCard(threadId, drawingTurn, notice);
|
|
147030
|
-
if (notice !== null) {
|
|
147171
|
+
if (notice !== null && selection !== null) {
|
|
147031
147172
|
for (const binding of textTargets) {
|
|
147032
147173
|
const send = (owed) => delivery.sendText(binding, threadId, notice, false, null, owed);
|
|
147033
147174
|
enqueueConclusion(core, conclusions, binding, selection, send);
|
|
@@ -147602,6 +147743,17 @@ var makeProjectRows = (core) => {
|
|
|
147602
147743
|
};
|
|
147603
147744
|
|
|
147604
147745
|
// src/failureNotices.ts
|
|
147746
|
+
var PROVIDER_FAILURES = {
|
|
147747
|
+
quota: { code: "MODEL_QUOTA", messageKey: "reply.turnFailedQuota" },
|
|
147748
|
+
"rate-limit": { code: "MODEL_RATE_LIMIT", messageKey: "reply.turnFailedRateLimit" },
|
|
147749
|
+
"context-limit": { code: "MODEL_CONTEXT_LIMIT", messageKey: "reply.turnFailedContextLimit" },
|
|
147750
|
+
auth: { code: "MODEL_AUTH", messageKey: "reply.turnFailedAuth" },
|
|
147751
|
+
"model-unavailable": {
|
|
147752
|
+
code: "MODEL_UNAVAILABLE",
|
|
147753
|
+
messageKey: "reply.turnFailedModelUnavailable"
|
|
147754
|
+
},
|
|
147755
|
+
transport: { code: "MODEL_TRANSPORT", messageKey: "reply.turnFailedTransport" }
|
|
147756
|
+
};
|
|
147605
147757
|
var excerptSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
147606
147758
|
var graphemeExcerpt = (value2) => {
|
|
147607
147759
|
const characters = Array.from(
|
|
@@ -147639,9 +147791,20 @@ var makeFailureNotices = (core) => {
|
|
|
147639
147791
|
return core.t("reply.turnRetrying", { ref: reference2 });
|
|
147640
147792
|
},
|
|
147641
147793
|
/** 一次失败通知的那句话(带新参考号,同号进日志):实时失败事件与重启补发各取一次。 */
|
|
147642
|
-
forFailure: (threadId, detail) => {
|
|
147794
|
+
forFailure: (threadId, detail, category) => {
|
|
147643
147795
|
const reference2 = diagnosticRef("msg");
|
|
147644
|
-
|
|
147796
|
+
const failure2 = category === void 0 || category === "unknown" ? null : PROVIDER_FAILURES[category];
|
|
147797
|
+
core.host.log.warn("chat turn failed", {
|
|
147798
|
+
threadId,
|
|
147799
|
+
reference: reference2,
|
|
147800
|
+
code: failure2?.code ?? null,
|
|
147801
|
+
detail
|
|
147802
|
+
});
|
|
147803
|
+
if (failure2 !== null)
|
|
147804
|
+
return core.t("reply.turnFailedWithReference", {
|
|
147805
|
+
message: core.t(failure2.messageKey),
|
|
147806
|
+
ref: reference2
|
|
147807
|
+
});
|
|
147645
147808
|
const said = reasonOf2(detail);
|
|
147646
147809
|
const text4 = said === "" ? core.t("reply.turnFailedNoDetail", { ref: reference2 }) : core.t("reply.turnFailed", { detail: said, ref: reference2 });
|
|
147647
147810
|
return text4;
|
|
@@ -147654,11 +147817,13 @@ var makeFailureNotices = (core) => {
|
|
|
147654
147817
|
* 卡收尾(无论怎么收的都调):清掉这条会话的寄存。失败收尾时,寄存是这一轮的就用它(同一个号),
|
|
147655
147818
|
* 否则只写原因与下一步,不另取号。不是失败收尾回 null。
|
|
147656
147819
|
*/
|
|
147657
|
-
forCard: (threadId, turnId, detail, failed) => {
|
|
147820
|
+
forCard: (threadId, turnId, detail, failed, category) => {
|
|
147658
147821
|
const held = heldForCard.get(threadId);
|
|
147659
147822
|
heldForCard.delete(threadId);
|
|
147660
147823
|
if (!failed) return null;
|
|
147661
147824
|
if (held !== void 0 && held.turnId === turnId) return held.text;
|
|
147825
|
+
if (category !== void 0 && category !== "unknown")
|
|
147826
|
+
return core.t(PROVIDER_FAILURES[category].messageKey);
|
|
147662
147827
|
const said = reasonOf2(detail);
|
|
147663
147828
|
return said === "" ? core.t("reply.turnFailedBriefNoDetail") : core.t("reply.turnFailedBrief", { detail: said });
|
|
147664
147829
|
}
|
|
@@ -148009,7 +148174,8 @@ var makeReplyCards = (core, failures, anchors, conclusions, delivery) => {
|
|
|
148009
148174
|
threadId,
|
|
148010
148175
|
turnId,
|
|
148011
148176
|
session?.lastError,
|
|
148012
|
-
outcome === "failed"
|
|
148177
|
+
outcome === "failed",
|
|
148178
|
+
session?.failureCategory
|
|
148013
148179
|
);
|
|
148014
148180
|
if (errorText2 !== null) return { status: "error", errorText: errorText2 };
|
|
148015
148181
|
if (stopped || outcome === "stopped") {
|
|
@@ -148022,6 +148188,7 @@ var makeReplyCards = (core, failures, anchors, conclusions, delivery) => {
|
|
|
148022
148188
|
finalize: async (threadId, turnId, chatKey, send) => {
|
|
148023
148189
|
const { selection, handled } = await conclusions.forTurn(threadId, turnId);
|
|
148024
148190
|
if (handled) return true;
|
|
148191
|
+
if (selection === null) return false;
|
|
148025
148192
|
if (selection === void 0) return send();
|
|
148026
148193
|
if (!await conclusions.deliver(selection, send)) return false;
|
|
148027
148194
|
const binding = bindingForChatKey(chatKey);
|
|
@@ -148032,7 +148199,7 @@ var makeReplyCards = (core, failures, anchors, conclusions, delivery) => {
|
|
|
148032
148199
|
},
|
|
148033
148200
|
fallback: async (threadId, turnId, chatKey, view) => {
|
|
148034
148201
|
const { selection, handled } = await conclusions.forTurn(threadId, turnId);
|
|
148035
|
-
if (handled) return;
|
|
148202
|
+
if (handled || selection === null) return;
|
|
148036
148203
|
const binding = bindingForChatKey(chatKey);
|
|
148037
148204
|
if (binding === void 0) return;
|
|
148038
148205
|
const text4 = [view.body, view.errorText ?? ""].filter((part) => part !== "").join("\n\n");
|
|
@@ -148499,12 +148666,14 @@ import * as NodeCrypto6 from "node:crypto";
|
|
|
148499
148666
|
// src/telegramApiResponse.ts
|
|
148500
148667
|
var TelegramApiError = class extends Error {
|
|
148501
148668
|
code;
|
|
148669
|
+
status;
|
|
148502
148670
|
/** 限流(429)时平台给的等待秒数;别的错误没有。 */
|
|
148503
148671
|
retryAfterSeconds;
|
|
148504
|
-
constructor(method, code2, description, retryAfterSeconds) {
|
|
148505
|
-
super(`telegram ${method} failed (${String(code2 ?? "?")}): ${description}
|
|
148672
|
+
constructor(method, code2, description, retryAfterSeconds, options) {
|
|
148673
|
+
super(`telegram ${method} failed (${String(code2 ?? "?")}): ${description}`, options);
|
|
148506
148674
|
this.name = "TelegramApiError";
|
|
148507
148675
|
this.code = code2;
|
|
148676
|
+
this.status = options?.status;
|
|
148508
148677
|
this.retryAfterSeconds = retryAfterSeconds;
|
|
148509
148678
|
}
|
|
148510
148679
|
};
|
|
@@ -148519,7 +148688,8 @@ var readTelegramResponse = async (method, response) => {
|
|
|
148519
148688
|
method,
|
|
148520
148689
|
response.status === 401 ? 401 : envelope?.error_code ?? (response.ok ? void 0 : response.status),
|
|
148521
148690
|
envelope?.description ?? "no reason",
|
|
148522
|
-
envelope?.parameters?.retry_after
|
|
148691
|
+
envelope?.parameters?.retry_after,
|
|
148692
|
+
{ status: response.status }
|
|
148523
148693
|
);
|
|
148524
148694
|
}
|
|
148525
148695
|
return envelope.result;
|
|
@@ -148653,7 +148823,13 @@ var makeTelegramApi = (input) => {
|
|
|
148653
148823
|
return await input.http(url, { ...init, signal: AbortSignal.timeout(timeoutMs) });
|
|
148654
148824
|
} catch (error) {
|
|
148655
148825
|
if (error instanceof Error && error.name === "TimeoutError") {
|
|
148656
|
-
throw new TelegramApiError(
|
|
148826
|
+
throw new TelegramApiError(
|
|
148827
|
+
method,
|
|
148828
|
+
void 0,
|
|
148829
|
+
`timed out after ${String(timeoutMs)} ms`,
|
|
148830
|
+
void 0,
|
|
148831
|
+
{ cause: error }
|
|
148832
|
+
);
|
|
148657
148833
|
}
|
|
148658
148834
|
throw error;
|
|
148659
148835
|
}
|
|
@@ -148878,6 +149054,98 @@ var TELEGRAM_MENU = [
|
|
|
148878
149054
|
];
|
|
148879
149055
|
var telegramCommandMenu = (t) => TELEGRAM_MENU.map((item) => ({ command: item.command, description: t(item.key) }));
|
|
148880
149056
|
|
|
149057
|
+
// src/telegramConnectionCheck.ts
|
|
149058
|
+
var webhookHost = (url) => {
|
|
149059
|
+
try {
|
|
149060
|
+
return new URL(url).host;
|
|
149061
|
+
} catch {
|
|
149062
|
+
return "(unreadable)";
|
|
149063
|
+
}
|
|
149064
|
+
};
|
|
149065
|
+
var NOT_BOT_DETAIL = "token is not a bot's";
|
|
149066
|
+
var webhookActiveDetail = (url) => `webhook is set (host ${webhookHost(url)})`;
|
|
149067
|
+
var transportFailure = (stage, error) => ({
|
|
149068
|
+
ok: false,
|
|
149069
|
+
stage,
|
|
149070
|
+
detail: describeError(error),
|
|
149071
|
+
error
|
|
149072
|
+
});
|
|
149073
|
+
var probeTelegramBot = async (api) => {
|
|
149074
|
+
let own;
|
|
149075
|
+
try {
|
|
149076
|
+
own = await api.getMe();
|
|
149077
|
+
} catch (error) {
|
|
149078
|
+
return transportFailure("getMe", error);
|
|
149079
|
+
}
|
|
149080
|
+
if (own.is_bot !== true) {
|
|
149081
|
+
return { ok: false, stage: "getMe", hint: "notBot", detail: NOT_BOT_DETAIL };
|
|
149082
|
+
}
|
|
149083
|
+
let webhook = "";
|
|
149084
|
+
try {
|
|
149085
|
+
webhook = (await api.getWebhookInfo()).url ?? "";
|
|
149086
|
+
} catch (error) {
|
|
149087
|
+
return transportFailure("getWebhookInfo", error);
|
|
149088
|
+
}
|
|
149089
|
+
if (webhook !== "") {
|
|
149090
|
+
return {
|
|
149091
|
+
ok: false,
|
|
149092
|
+
stage: "getWebhookInfo",
|
|
149093
|
+
hint: "webhookActive",
|
|
149094
|
+
detail: webhookActiveDetail(webhook)
|
|
149095
|
+
};
|
|
149096
|
+
}
|
|
149097
|
+
return { ok: true, username: own.username, id: own.id };
|
|
149098
|
+
};
|
|
149099
|
+
var TelegramConnectGateError = class extends Error {
|
|
149100
|
+
hint;
|
|
149101
|
+
constructor(hint, detail) {
|
|
149102
|
+
super(detail);
|
|
149103
|
+
this.name = "TelegramConnectGateError";
|
|
149104
|
+
this.hint = hint;
|
|
149105
|
+
}
|
|
149106
|
+
};
|
|
149107
|
+
var assertTelegramPollingReady = async (api) => {
|
|
149108
|
+
const probed = await probeTelegramBot(api);
|
|
149109
|
+
if (!probed.ok) {
|
|
149110
|
+
if ("error" in probed) throw probed.error;
|
|
149111
|
+
throw new TelegramConnectGateError(probed.hint, probed.detail);
|
|
149112
|
+
}
|
|
149113
|
+
return { username: probed.username ?? null, id: probed.id };
|
|
149114
|
+
};
|
|
149115
|
+
var telegramPollingFailureHint = (error) => error instanceof TelegramConnectGateError ? error.hint : error instanceof TelegramApiError && error.code === 409 ? "webhookActive" : void 0;
|
|
149116
|
+
var checkTelegramConnection = async (bot, token, apiFor) => {
|
|
149117
|
+
if (token === "") {
|
|
149118
|
+
return { stage: "credentials", ok: false, detail: "missing bot token in saved config" };
|
|
149119
|
+
}
|
|
149120
|
+
if (!isTelegramToken(token)) {
|
|
149121
|
+
return {
|
|
149122
|
+
stage: "token-format",
|
|
149123
|
+
ok: false,
|
|
149124
|
+
detail: "saved token is not in the BotFather format",
|
|
149125
|
+
hint: "badToken"
|
|
149126
|
+
};
|
|
149127
|
+
}
|
|
149128
|
+
const api = await apiFor(bot);
|
|
149129
|
+
const probed = await probeTelegramBot(api);
|
|
149130
|
+
if (probed.ok) {
|
|
149131
|
+
const name = probed.username;
|
|
149132
|
+
const username = name !== void 0 && name !== "" ? `@${name}` : "(no username)";
|
|
149133
|
+
return { stage: "getMe", ok: true, detail: `username=${username} webhook=none` };
|
|
149134
|
+
}
|
|
149135
|
+
if ("error" in probed) {
|
|
149136
|
+
return {
|
|
149137
|
+
stage: probed.stage,
|
|
149138
|
+
ok: false,
|
|
149139
|
+
detail: probed.detail,
|
|
149140
|
+
...connectionHintFields(
|
|
149141
|
+
probed.error,
|
|
149142
|
+
probed.stage === "getMe" && isTelegramCredentialsRejected(probed.error) ? "unauthorized" : void 0
|
|
149143
|
+
)
|
|
149144
|
+
};
|
|
149145
|
+
}
|
|
149146
|
+
return { stage: probed.stage, ok: false, detail: probed.detail, hint: probed.hint };
|
|
149147
|
+
};
|
|
149148
|
+
|
|
148881
149149
|
// src/telegramChoice.ts
|
|
148882
149150
|
var renderChoiceCard = (card) => ({
|
|
148883
149151
|
text: [card.title, card.heading ?? "", card.body, card.note ?? ""].filter((part) => part !== "").join("\n\n"),
|
|
@@ -149069,15 +149337,13 @@ var tokenFingerprint = (bot) => NodeCrypto6.createHash("sha256").update(tokenOf(
|
|
|
149069
149337
|
var REACTION_WORKING = "\u{1F440}";
|
|
149070
149338
|
var REACTION_DONE = "\u{1F44D}";
|
|
149071
149339
|
var REACTION_FAILED = "\u{1F44E}";
|
|
149072
|
-
var telegramConfigIssues = (binding) =>
|
|
149073
|
-
|
|
149074
|
-
|
|
149075
|
-
|
|
149076
|
-
|
|
149077
|
-
} catch {
|
|
149078
|
-
return "(unreadable)";
|
|
149079
|
-
}
|
|
149340
|
+
var telegramConfigIssues = (binding) => {
|
|
149341
|
+
const token = tokenOf(binding);
|
|
149342
|
+
if (token === "") return [{ column: "telegramToken", code: "required" }];
|
|
149343
|
+
if (!isTelegramToken(token)) return [{ column: "telegramToken", code: "format" }];
|
|
149344
|
+
return [];
|
|
149080
149345
|
};
|
|
149346
|
+
var defaultSleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
149081
149347
|
var makeTelegramAdapter = (deps) => {
|
|
149082
149348
|
const apis = /* @__PURE__ */ new Map();
|
|
149083
149349
|
const sleep4 = deps.sleep ?? defaultSleep;
|
|
@@ -149179,7 +149445,7 @@ var makeTelegramAdapter = (deps) => {
|
|
|
149179
149445
|
quotesReplies: true,
|
|
149180
149446
|
columns: COLUMNS2,
|
|
149181
149447
|
validate: telegramConfigIssues,
|
|
149182
|
-
isConfigured: (binding) => telegramConfigIssues(binding).
|
|
149448
|
+
isConfigured: (binding) => telegramConfigIssues(binding).every((issue) => issue.code !== "required"),
|
|
149183
149449
|
connect: async (binding, handlers) => {
|
|
149184
149450
|
let stop = () => {
|
|
149185
149451
|
};
|
|
@@ -149217,8 +149483,8 @@ var makeTelegramAdapter = (deps) => {
|
|
|
149217
149483
|
liveApi = api;
|
|
149218
149484
|
if (!running) return;
|
|
149219
149485
|
if (botUsername == null) {
|
|
149220
|
-
const own = await api
|
|
149221
|
-
botUsername = own.username
|
|
149486
|
+
const own = await assertTelegramPollingReady(api);
|
|
149487
|
+
botUsername = own.username;
|
|
149222
149488
|
botId = own.id;
|
|
149223
149489
|
if (running) handlers.onConnectionState?.({ state: "connected" });
|
|
149224
149490
|
}
|
|
@@ -149344,7 +149610,12 @@ var makeTelegramAdapter = (deps) => {
|
|
|
149344
149610
|
});
|
|
149345
149611
|
return;
|
|
149346
149612
|
}
|
|
149347
|
-
if (checkingConnection)
|
|
149613
|
+
if (checkingConnection)
|
|
149614
|
+
handlers.onConnectionState?.({
|
|
149615
|
+
state: "failed",
|
|
149616
|
+
error,
|
|
149617
|
+
...connectionHintFields(error, telegramPollingFailureHint(error))
|
|
149618
|
+
});
|
|
149348
149619
|
handlers.onError(error instanceof Error ? error.message : String(error));
|
|
149349
149620
|
await Promise.race([(deps.sleep ?? defaultSleep)(backoff), stopped]);
|
|
149350
149621
|
backoff = Math.min(backoff * 2, BACKOFF_MAX_MS);
|
|
@@ -149366,50 +149637,7 @@ var makeTelegramAdapter = (deps) => {
|
|
|
149366
149637
|
const api = await apiFor(binding);
|
|
149367
149638
|
await api.sendMessage(binding.chatId, text4, options?.retry, binding.reply?.messageId);
|
|
149368
149639
|
},
|
|
149369
|
-
checkConnection:
|
|
149370
|
-
const token = tokenOf(bot);
|
|
149371
|
-
if (token === "") {
|
|
149372
|
-
return { stage: "credentials", ok: false, detail: "missing bot token in saved config" };
|
|
149373
|
-
}
|
|
149374
|
-
if (!isTelegramToken(token)) {
|
|
149375
|
-
return {
|
|
149376
|
-
stage: "token-format",
|
|
149377
|
-
ok: false,
|
|
149378
|
-
detail: "saved token is not in the BotFather format",
|
|
149379
|
-
hint: "badToken"
|
|
149380
|
-
};
|
|
149381
|
-
}
|
|
149382
|
-
const api = await apiFor(bot);
|
|
149383
|
-
let username;
|
|
149384
|
-
try {
|
|
149385
|
-
const me = await api.getMe();
|
|
149386
|
-
if (me.is_bot !== true) {
|
|
149387
|
-
return { stage: "getMe", ok: false, detail: "token is not a bot's", hint: "notBot" };
|
|
149388
|
-
}
|
|
149389
|
-
username = me.username !== void 0 && me.username !== "" ? `@${me.username}` : "(no username)";
|
|
149390
|
-
} catch (error) {
|
|
149391
|
-
return {
|
|
149392
|
-
stage: "getMe",
|
|
149393
|
-
ok: false,
|
|
149394
|
-
detail: describeError(error),
|
|
149395
|
-
...isTelegramCredentialsRejected(error) ? { hint: "unauthorized" } : {}
|
|
149396
|
-
};
|
|
149397
|
-
}
|
|
149398
|
-
try {
|
|
149399
|
-
const webhook = (await api.getWebhookInfo()).url ?? "";
|
|
149400
|
-
if (webhook !== "") {
|
|
149401
|
-
return {
|
|
149402
|
-
stage: "getWebhookInfo",
|
|
149403
|
-
ok: false,
|
|
149404
|
-
detail: `webhook is set (host ${webhookHost(webhook)})`,
|
|
149405
|
-
hint: "webhookActive"
|
|
149406
|
-
};
|
|
149407
|
-
}
|
|
149408
|
-
} catch (error) {
|
|
149409
|
-
return { stage: "getWebhookInfo", ok: false, detail: describeError(error) };
|
|
149410
|
-
}
|
|
149411
|
-
return { stage: "getMe", ok: true, detail: `username=${username} webhook=none` };
|
|
149412
|
-
},
|
|
149640
|
+
checkConnection: (bot) => checkTelegramConnection(bot, tokenOf(bot), apiFor),
|
|
149413
149641
|
sendTyping: async (binding) => {
|
|
149414
149642
|
await (await apiFor(binding)).sendTyping(binding.chatId);
|
|
149415
149643
|
},
|
|
@@ -150150,7 +150378,13 @@ var probe = async (adapters, bot) => {
|
|
|
150150
150378
|
result2.hint
|
|
150151
150379
|
);
|
|
150152
150380
|
} catch (error) {
|
|
150153
|
-
return reportOf(
|
|
150381
|
+
return reportOf(
|
|
150382
|
+
bot,
|
|
150383
|
+
"check",
|
|
150384
|
+
false,
|
|
150385
|
+
redactor.redact(describeError(error)),
|
|
150386
|
+
connectionHint(error)
|
|
150387
|
+
);
|
|
150154
150388
|
}
|
|
150155
150389
|
};
|
|
150156
150390
|
var emitReport = (emit, report, action) => {
|
|
@@ -150676,6 +150910,16 @@ var makeWechatAdapter = (deps) => {
|
|
|
150676
150910
|
};
|
|
150677
150911
|
};
|
|
150678
150912
|
|
|
150913
|
+
// src/wecomAckError.ts
|
|
150914
|
+
var WecomAckError = class extends Error {
|
|
150915
|
+
code;
|
|
150916
|
+
constructor(code2, msg) {
|
|
150917
|
+
super(`WeCom ack failed: ${String(code2)} ${msg}`);
|
|
150918
|
+
this.name = "WecomAckError";
|
|
150919
|
+
this.code = code2;
|
|
150920
|
+
}
|
|
150921
|
+
};
|
|
150922
|
+
|
|
150679
150923
|
// src/wecomUpload.ts
|
|
150680
150924
|
import * as NodeCrypto8 from "node:crypto";
|
|
150681
150925
|
var WECOM_CHUNK_BYTES = 512 * 1024;
|
|
@@ -150888,15 +151132,12 @@ var parseWecomMessage = (frame, botId) => {
|
|
|
150888
151132
|
};
|
|
150889
151133
|
};
|
|
150890
151134
|
var splitForWecom = (text4, limit = WECOM_TEXT_MAX_CHARS) => splitMessage(text4, limit);
|
|
150891
|
-
var
|
|
150892
|
-
|
|
150893
|
-
|
|
150894
|
-
constructor(code2, msg) {
|
|
150895
|
-
super(`WeCom ack failed: ${String(code2)} ${msg}`);
|
|
150896
|
-
this.name = "WecomAckError";
|
|
150897
|
-
this.code = code2;
|
|
151135
|
+
var sendWecomText = async (text4, sendChunk) => {
|
|
151136
|
+
for (const [index, content] of splitForWecom(text4).entries()) {
|
|
151137
|
+
await sendChunk(content, index === 0);
|
|
150898
151138
|
}
|
|
150899
151139
|
};
|
|
151140
|
+
var decoder = new TextDecoder();
|
|
150900
151141
|
var subscriptionHint = (error) => {
|
|
150901
151142
|
if (!(error instanceof WecomAckError)) return void 0;
|
|
150902
151143
|
switch (error.code) {
|
|
@@ -151029,41 +151270,39 @@ var runWecomClient = (input) => {
|
|
|
151029
151270
|
return false;
|
|
151030
151271
|
}
|
|
151031
151272
|
);
|
|
151032
|
-
const
|
|
151033
|
-
|
|
151034
|
-
|
|
151035
|
-
|
|
151036
|
-
|
|
151037
|
-
|
|
151038
|
-
|
|
151039
|
-
|
|
151040
|
-
|
|
151041
|
-
|
|
151042
|
-
|
|
151043
|
-
}
|
|
151044
|
-
});
|
|
151045
|
-
continue;
|
|
151046
|
-
}
|
|
151047
|
-
const requestId = nextRequestId("aibot_send_msg");
|
|
151048
|
-
const ack = new Promise((resolve2, reject) => {
|
|
151049
|
-
pendingAcks.set(requestId, { resolve: () => resolve2(), reject });
|
|
151050
|
-
setTimeout(() => {
|
|
151051
|
-
if (pendingAcks.delete(requestId)) resolve2();
|
|
151052
|
-
}, SEND_ACK_TIMEOUT_MS);
|
|
151273
|
+
const sendTextChunk = async (chatId, content, firstChunk) => {
|
|
151274
|
+
const inboundRequestId = firstChunk ? pendingRequests.get(chatId) : void 0;
|
|
151275
|
+
if (inboundRequestId !== void 0) {
|
|
151276
|
+
pendingRequests.delete(chatId);
|
|
151277
|
+
await send({
|
|
151278
|
+
cmd: "aibot_respond_msg",
|
|
151279
|
+
headers: { req_id: inboundRequestId },
|
|
151280
|
+
body: {
|
|
151281
|
+
msgtype: "stream",
|
|
151282
|
+
stream: { id: nextRequestId("stream"), finish: true, content }
|
|
151283
|
+
}
|
|
151053
151284
|
});
|
|
151054
|
-
|
|
151055
|
-
|
|
151056
|
-
|
|
151057
|
-
|
|
151058
|
-
|
|
151059
|
-
|
|
151060
|
-
|
|
151061
|
-
|
|
151062
|
-
|
|
151063
|
-
|
|
151064
|
-
|
|
151065
|
-
|
|
151066
|
-
|
|
151285
|
+
return;
|
|
151286
|
+
}
|
|
151287
|
+
const requestId = nextRequestId("aibot_send_msg");
|
|
151288
|
+
const ack = new Promise((resolve2, reject) => {
|
|
151289
|
+
pendingAcks.set(requestId, { resolve: () => resolve2(), reject });
|
|
151290
|
+
setTimeout(() => {
|
|
151291
|
+
if (pendingAcks.delete(requestId)) resolve2();
|
|
151292
|
+
}, SEND_ACK_TIMEOUT_MS);
|
|
151293
|
+
});
|
|
151294
|
+
try {
|
|
151295
|
+
await Promise.all([
|
|
151296
|
+
send({
|
|
151297
|
+
cmd: "aibot_send_msg",
|
|
151298
|
+
headers: { req_id: requestId },
|
|
151299
|
+
body: { chatid: chatId, msgtype: "markdown", markdown: { content } }
|
|
151300
|
+
}),
|
|
151301
|
+
ack
|
|
151302
|
+
]);
|
|
151303
|
+
} catch (error) {
|
|
151304
|
+
pendingAcks.delete(requestId);
|
|
151305
|
+
throw error;
|
|
151067
151306
|
}
|
|
151068
151307
|
};
|
|
151069
151308
|
const request = async (cmd, body) => {
|
|
@@ -151140,7 +151379,8 @@ var runWecomClient = (input) => {
|
|
|
151140
151379
|
};
|
|
151141
151380
|
};
|
|
151142
151381
|
return {
|
|
151143
|
-
sendText,
|
|
151382
|
+
sendText: (chatId, text4) => sendWecomText(text4, (content, firstChunk) => sendTextChunk(chatId, content, firstChunk)),
|
|
151383
|
+
sendTextChunk,
|
|
151144
151384
|
sendMedia,
|
|
151145
151385
|
rememberConversation: (chatId, conversation) => {
|
|
151146
151386
|
conversations.set(chatId, conversation);
|
|
@@ -151245,6 +151485,38 @@ var fetchWecomMedia = async (input) => {
|
|
|
151245
151485
|
return { bytes, name };
|
|
151246
151486
|
};
|
|
151247
151487
|
|
|
151488
|
+
// src/wecomSendError.ts
|
|
151489
|
+
var WecomSendError = class extends Error {
|
|
151490
|
+
operation;
|
|
151491
|
+
code;
|
|
151492
|
+
providerCode;
|
|
151493
|
+
constructor(cause, operation, code2, providerCode) {
|
|
151494
|
+
super(
|
|
151495
|
+
providerCode === void 0 && cause instanceof Error ? cause.message : `WeCom ${operation} failed (${code2}, provider=${providerCode ?? "-"})`,
|
|
151496
|
+
{ cause }
|
|
151497
|
+
);
|
|
151498
|
+
this.name = "WecomSendError";
|
|
151499
|
+
this.operation = operation;
|
|
151500
|
+
this.code = code2;
|
|
151501
|
+
this.providerCode = providerCode;
|
|
151502
|
+
}
|
|
151503
|
+
};
|
|
151504
|
+
var wecomSendError = (error, operation) => {
|
|
151505
|
+
if (error instanceof ImNotConnectedError || error instanceof WecomSendError || error instanceof Error && error.name === "AbortError" || error instanceof TypeError || error instanceof ReferenceError || error instanceof SyntaxError)
|
|
151506
|
+
return error;
|
|
151507
|
+
const providerCode = error instanceof WecomAckError ? error.code : void 0;
|
|
151508
|
+
let code2 = providerCode === void 0 ? "channel-delivery-uncertain" : "channel-delivery-failed";
|
|
151509
|
+
if (providerCode === 48002) code2 = "channel-permission";
|
|
151510
|
+
if (providerCode === 45009) code2 = "channel-rate-limit";
|
|
151511
|
+
return new WecomSendError(error, operation, code2, providerCode);
|
|
151512
|
+
};
|
|
151513
|
+
var wecomSendDiagnostic = (error) => error instanceof WecomSendError ? {
|
|
151514
|
+
operation: error.operation,
|
|
151515
|
+
code: error.code,
|
|
151516
|
+
providerCode: error.providerCode
|
|
151517
|
+
} : void 0;
|
|
151518
|
+
var wecomSendVerdict = (error) => error instanceof ImNotConnectedError || error instanceof WecomSendError && error.code === "channel-rate-limit" ? { retry: true } : NO_RETRY;
|
|
151519
|
+
|
|
151248
151520
|
// src/wecomAdapter.ts
|
|
151249
151521
|
var WECOM_CARD_THROTTLE_MS = 400;
|
|
151250
151522
|
var LIVE_STREAM_LIMIT = 200;
|
|
@@ -151271,6 +151543,16 @@ var makeWecomAdapter = (deps) => {
|
|
|
151271
151543
|
const clients = /* @__PURE__ */ new Map();
|
|
151272
151544
|
const managedConnections = /* @__PURE__ */ new Map();
|
|
151273
151545
|
const t = deps.translate;
|
|
151546
|
+
const sending = async (operation, request) => {
|
|
151547
|
+
try {
|
|
151548
|
+
return await request();
|
|
151549
|
+
} catch (error) {
|
|
151550
|
+
const failure2 = wecomSendError(error, operation);
|
|
151551
|
+
const diagnostic = wecomSendDiagnostic(failure2);
|
|
151552
|
+
if (diagnostic !== void 0) deps.log.warn("wecom send failed", diagnostic);
|
|
151553
|
+
throw failure2;
|
|
151554
|
+
}
|
|
151555
|
+
};
|
|
151274
151556
|
const liveStreams = /* @__PURE__ */ new Map();
|
|
151275
151557
|
const rememberStream = (key, entry) => {
|
|
151276
151558
|
liveStreams.set(key, entry);
|
|
@@ -151291,19 +151573,19 @@ var makeWecomAdapter = (deps) => {
|
|
|
151291
151573
|
shown = `${t("card.truncated", { count: body.length - kept.length })}
|
|
151292
151574
|
${kept}`;
|
|
151293
151575
|
}
|
|
151294
|
-
await entry.stream.send(joinParts(head, shown, foot), false);
|
|
151576
|
+
await sending("replyStream", () => entry.stream.send(joinParts(head, shown, foot), false));
|
|
151295
151577
|
return;
|
|
151296
151578
|
}
|
|
151297
151579
|
const chunks = splitForWecom(joinParts(head, body, foot));
|
|
151298
|
-
const delivered = await entry.stream.send(chunks[0] ?? "", true);
|
|
151580
|
+
const delivered = await sending("replyStream", () => entry.stream.send(chunks[0] ?? "", true));
|
|
151299
151581
|
for (const chunk of delivered ? chunks.slice(1) : chunks) {
|
|
151300
|
-
await entry.client.sendText(entry.chatId, chunk);
|
|
151582
|
+
await sending("sendMessage", () => entry.client.sendText(entry.chatId, chunk));
|
|
151301
151583
|
}
|
|
151302
151584
|
};
|
|
151303
151585
|
const sendMedia = async (binding, kind, media) => {
|
|
151304
151586
|
const client = clients.get(binding.rowId);
|
|
151305
151587
|
if (client === void 0) throw new Error("WeCom is not connected right now");
|
|
151306
|
-
await client.sendMedia(binding.chatId, kind, media);
|
|
151588
|
+
await sending("sendMedia", () => client.sendMedia(binding.chatId, kind, media));
|
|
151307
151589
|
deps.log.info("wecom delivered a file", { name: media.name, as: kind });
|
|
151308
151590
|
};
|
|
151309
151591
|
return {
|
|
@@ -151418,13 +151700,26 @@ ${kept}`;
|
|
|
151418
151700
|
}
|
|
151419
151701
|
};
|
|
151420
151702
|
},
|
|
151421
|
-
|
|
151422
|
-
|
|
151423
|
-
|
|
151424
|
-
|
|
151425
|
-
|
|
151426
|
-
|
|
151427
|
-
|
|
151703
|
+
sendText: async (binding, text4, options) => {
|
|
151704
|
+
await sendWecomText(
|
|
151705
|
+
text4,
|
|
151706
|
+
(chunk, firstChunk) => sendWithRetry(
|
|
151707
|
+
async () => {
|
|
151708
|
+
const client = clients.get(binding.rowId);
|
|
151709
|
+
if (client === void 0) {
|
|
151710
|
+
throw new ImNotConnectedError(
|
|
151711
|
+
`wecom bot '${binding.displayName}' has no connection.`
|
|
151712
|
+
);
|
|
151713
|
+
}
|
|
151714
|
+
await sending(
|
|
151715
|
+
"sendMessage",
|
|
151716
|
+
() => client.sendTextChunk(binding.chatId, chunk, firstChunk)
|
|
151717
|
+
);
|
|
151718
|
+
},
|
|
151719
|
+
wecomSendVerdict,
|
|
151720
|
+
options?.retry
|
|
151721
|
+
)
|
|
151722
|
+
);
|
|
151428
151723
|
},
|
|
151429
151724
|
checkConnection: async (bot) => {
|
|
151430
151725
|
const managed = managedConnections.get(bot.rowId);
|
|
@@ -151498,7 +151793,10 @@ ${kept}`;
|
|
|
151498
151793
|
}
|
|
151499
151794
|
},
|
|
151500
151795
|
askApproval: async (binding, request) => {
|
|
151501
|
-
|
|
151796
|
+
const client = clients.get(binding.rowId);
|
|
151797
|
+
const text4 = numberedApprovalText(request);
|
|
151798
|
+
if (client !== void 0)
|
|
151799
|
+
await sending("sendMessage", () => client.sendText(binding.chatId, text4));
|
|
151502
151800
|
return null;
|
|
151503
151801
|
},
|
|
151504
151802
|
turnCards: {
|
|
@@ -151555,6 +151853,7 @@ var REQUEST_TIMEOUT_MS = 15e3;
|
|
|
151555
151853
|
var MEDIA_TIMEOUT_MS = 6e4;
|
|
151556
151854
|
var WecomAppApiError = class extends Error {
|
|
151557
151855
|
code;
|
|
151856
|
+
status;
|
|
151558
151857
|
providerCode;
|
|
151559
151858
|
hint;
|
|
151560
151859
|
invalidUsers;
|
|
@@ -151562,6 +151861,7 @@ var WecomAppApiError = class extends Error {
|
|
|
151562
151861
|
super(message);
|
|
151563
151862
|
this.name = "WecomAppApiError";
|
|
151564
151863
|
this.code = code2;
|
|
151864
|
+
this.status = extras?.status;
|
|
151565
151865
|
this.providerCode = extras?.providerCode;
|
|
151566
151866
|
this.hint = extras?.hint;
|
|
151567
151867
|
this.invalidUsers = extras?.invalidUsers ?? [];
|
|
@@ -151771,30 +152071,31 @@ var WecomAppApi = class {
|
|
|
151771
152071
|
});
|
|
151772
152072
|
}
|
|
151773
152073
|
}
|
|
151774
|
-
#apiError(errcode, errmsg, invalidUsers) {
|
|
152074
|
+
#apiError(errcode, errmsg, invalidUsers, status) {
|
|
151775
152075
|
const code2 = String(errcode);
|
|
152076
|
+
const details = { providerCode: code2, status };
|
|
151776
152077
|
const message = typeof errmsg === "string" && errmsg !== "" ? `WeCom API failed (${code2}): ${errmsg}` : `WeCom API failed (${code2}).`;
|
|
151777
152078
|
if (TOKEN_INVALID_CODES.has(code2)) this.invalidateToken();
|
|
151778
152079
|
if (errcode === 60020) {
|
|
151779
152080
|
return new WecomAppApiError("trusted-ip", "WeCom rejected the outbound IP (errcode 60020).", {
|
|
151780
|
-
|
|
152081
|
+
...details,
|
|
151781
152082
|
hint: "wecomTrustedIp"
|
|
151782
152083
|
});
|
|
151783
152084
|
}
|
|
151784
152085
|
if (errcode === 81013) {
|
|
151785
152086
|
return new WecomAppApiError("invalid-user", message, {
|
|
151786
|
-
|
|
152087
|
+
...details,
|
|
151787
152088
|
hint: "wecomInvalidUser",
|
|
151788
152089
|
invalidUsers: parseInvalidUsers(invalidUsers)
|
|
151789
152090
|
});
|
|
151790
152091
|
}
|
|
151791
152092
|
if (errcode === 40056) {
|
|
151792
152093
|
return new WecomAppApiError("invalid-agent", message, {
|
|
151793
|
-
|
|
152094
|
+
...details,
|
|
151794
152095
|
hint: "wecomInvalidAgent"
|
|
151795
152096
|
});
|
|
151796
152097
|
}
|
|
151797
|
-
return new WecomAppApiError("api-failed", message,
|
|
152098
|
+
return new WecomAppApiError("api-failed", message, details);
|
|
151798
152099
|
}
|
|
151799
152100
|
async #withRequest(url, init, timeoutMs, read) {
|
|
151800
152101
|
const deadline = new AbortController();
|
|
@@ -151821,15 +152122,29 @@ var WecomAppApi = class {
|
|
|
151821
152122
|
} catch {
|
|
151822
152123
|
throw new WecomAppApiError(
|
|
151823
152124
|
"bad-response",
|
|
151824
|
-
`WeCom returned non-JSON (HTTP ${String(response.status)})
|
|
152125
|
+
`WeCom returned non-JSON (HTTP ${String(response.status)}).`,
|
|
152126
|
+
{ status: response.status }
|
|
151825
152127
|
);
|
|
151826
152128
|
}
|
|
151827
152129
|
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
151828
|
-
throw new WecomAppApiError("bad-response", "WeCom returned a non-object JSON body."
|
|
152130
|
+
throw new WecomAppApiError("bad-response", "WeCom returned a non-object JSON body.", {
|
|
152131
|
+
status: response.status
|
|
152132
|
+
});
|
|
151829
152133
|
}
|
|
151830
152134
|
const result2 = payload;
|
|
151831
152135
|
const errcode = Number(result2["errcode"] ?? 0);
|
|
151832
|
-
if (errcode !== 0)
|
|
152136
|
+
if (errcode !== 0) {
|
|
152137
|
+
throw this.#apiError(errcode, result2["errmsg"], result2["invaliduser"], response.status);
|
|
152138
|
+
}
|
|
152139
|
+
if (!response.ok) {
|
|
152140
|
+
throw new WecomAppApiError(
|
|
152141
|
+
"bad-response",
|
|
152142
|
+
`WeCom returned HTTP ${String(response.status)}.`,
|
|
152143
|
+
{
|
|
152144
|
+
status: response.status
|
|
152145
|
+
}
|
|
152146
|
+
);
|
|
152147
|
+
}
|
|
151833
152148
|
return result2;
|
|
151834
152149
|
});
|
|
151835
152150
|
}
|
|
@@ -152565,7 +152880,10 @@ var makeWecomAppAdapter = (deps) => {
|
|
|
152565
152880
|
stage: "gettoken",
|
|
152566
152881
|
ok: false,
|
|
152567
152882
|
detail: describeError(error),
|
|
152568
|
-
...
|
|
152883
|
+
...connectionHintFields(
|
|
152884
|
+
error,
|
|
152885
|
+
error instanceof WecomAppApiError ? error.hint : void 0
|
|
152886
|
+
)
|
|
152569
152887
|
};
|
|
152570
152888
|
}
|
|
152571
152889
|
},
|
|
@@ -152584,7 +152902,7 @@ var makeWecomAppAdapter = (deps) => {
|
|
|
152584
152902
|
const report = (state) => {
|
|
152585
152903
|
if (closed) return;
|
|
152586
152904
|
handlers.onConnectionState?.(
|
|
152587
|
-
state.state === "failed" && state.error instanceof WecomAppApiError && state.error.hint !== void 0 ? { ...state, hint: state.error.hint } : state
|
|
152905
|
+
state.state === "failed" && state.error instanceof WecomAppApiError && state.error.hint !== void 0 ? { ...state, hint: state.error.hint } : state.state === "failed" ? { ...state, ...connectionHintFields(state.error, state.hint) } : state
|
|
152588
152906
|
);
|
|
152589
152907
|
};
|
|
152590
152908
|
apis.set(bot.rowId, { api, report });
|