codex-to-im 1.0.48 → 1.0.49
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/dist/daemon.mjs +25 -57
- package/package.json +1 -1
package/dist/daemon.mjs
CHANGED
|
@@ -1415,7 +1415,8 @@ function buildPermissionButtonCard(text2, permissionRequestId, chatId) {
|
|
|
1415
1415
|
// src/lib/bridge/adapters/feishu-adapter.ts
|
|
1416
1416
|
var DEDUP_MAX = 1e3;
|
|
1417
1417
|
var MAX_FILE_SIZE = 20 * 1024 * 1024;
|
|
1418
|
-
var
|
|
1418
|
+
var COMPLETED_EMOJI = "DONE";
|
|
1419
|
+
var ERROR_EMOJI = "ERROR";
|
|
1419
1420
|
var CARD_THROTTLE_MS = 1e3;
|
|
1420
1421
|
var CARD_REQUEST_TIMEOUT_MS = 15e3;
|
|
1421
1422
|
var CARD_FINALIZE_FLUSH_WAIT_EXTRA_MS = 1e3;
|
|
@@ -1484,14 +1485,8 @@ var FeishuAdapter = class extends BaseChannelAdapter {
|
|
|
1484
1485
|
botOpenId = null;
|
|
1485
1486
|
/** All known bot IDs (open_id, user_id, union_id) for mention matching. */
|
|
1486
1487
|
botIds = /* @__PURE__ */ new Set();
|
|
1487
|
-
/** Track last incoming message ID per chat for
|
|
1488
|
+
/** Track last incoming message ID per chat for replying with streaming cards. */
|
|
1488
1489
|
lastIncomingMessageId = /* @__PURE__ */ new Map();
|
|
1489
|
-
/** Track active typing reaction IDs per stream key for cleanup. */
|
|
1490
|
-
typingReactions = /* @__PURE__ */ new Map();
|
|
1491
|
-
/** Track in-flight typing reaction creates so repeated status updates stay idempotent. */
|
|
1492
|
-
typingReactionCreatePromises = /* @__PURE__ */ new Map();
|
|
1493
|
-
/** Track streams that ended before the async reaction create finished. */
|
|
1494
|
-
typingReactionCleanupRequested = /* @__PURE__ */ new Set();
|
|
1495
1490
|
/** Active streaming card state per stream key. */
|
|
1496
1491
|
activeCards = /* @__PURE__ */ new Map();
|
|
1497
1492
|
/** In-flight card creation promises per stream key — prevents duplicate creation. */
|
|
@@ -1598,9 +1593,6 @@ var FeishuAdapter = class extends BaseChannelAdapter {
|
|
|
1598
1593
|
this.cardCreatePromises.clear();
|
|
1599
1594
|
this.seenMessageIds.clear();
|
|
1600
1595
|
this.lastIncomingMessageId.clear();
|
|
1601
|
-
this.typingReactions.clear();
|
|
1602
|
-
this.typingReactionCreatePromises.clear();
|
|
1603
|
-
this.typingReactionCleanupRequested.clear();
|
|
1604
1596
|
console.log("[feishu-adapter] Stopped");
|
|
1605
1597
|
}
|
|
1606
1598
|
isRunning() {
|
|
@@ -1610,67 +1602,24 @@ var FeishuAdapter = class extends BaseChannelAdapter {
|
|
|
1610
1602
|
consumeOne() {
|
|
1611
1603
|
return this.consumeInboundMessage(this.running);
|
|
1612
1604
|
}
|
|
1613
|
-
// ──
|
|
1605
|
+
// ── Streaming lifecycle hooks ──────────────────────────────
|
|
1614
1606
|
/**
|
|
1615
|
-
*
|
|
1607
|
+
* Create the streaming card as early as possible.
|
|
1616
1608
|
* Called by bridge-manager via onMessageStart().
|
|
1617
1609
|
*/
|
|
1618
1610
|
onMessageStart(chatId, streamKey) {
|
|
1619
1611
|
const messageId = this.lastIncomingMessageId.get(chatId);
|
|
1620
|
-
const reactionKey = this.resolveStreamKey(chatId, streamKey);
|
|
1621
1612
|
if (messageId && this.isStreamingEnabled()) {
|
|
1622
1613
|
this.createStreamingCard(chatId, messageId, streamKey).catch(() => {
|
|
1623
1614
|
});
|
|
1624
1615
|
}
|
|
1625
|
-
if (!messageId || !this.restClient) return;
|
|
1626
|
-
if (this.typingReactions.has(reactionKey) || this.typingReactionCreatePromises.has(reactionKey)) {
|
|
1627
|
-
return;
|
|
1628
|
-
}
|
|
1629
|
-
const createPromise = this.restClient.im.messageReaction.create({
|
|
1630
|
-
path: { message_id: messageId },
|
|
1631
|
-
data: { reaction_type: { emoji_type: TYPING_EMOJI } }
|
|
1632
|
-
}).then((res) => {
|
|
1633
|
-
const reactionId = res?.data?.reaction_id;
|
|
1634
|
-
if (reactionId) {
|
|
1635
|
-
this.typingReactions.set(reactionKey, { messageId, reactionId });
|
|
1636
|
-
if (this.typingReactionCleanupRequested.delete(reactionKey)) {
|
|
1637
|
-
this.removeTypingReaction(reactionKey);
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
}).catch((err) => {
|
|
1641
|
-
const code2 = err?.code;
|
|
1642
|
-
if (code2 !== 99991400 && code2 !== 99991403) {
|
|
1643
|
-
console.warn("[feishu-adapter] Typing indicator failed:", err instanceof Error ? err.message : err);
|
|
1644
|
-
}
|
|
1645
|
-
}).finally(() => {
|
|
1646
|
-
this.typingReactionCreatePromises.delete(reactionKey);
|
|
1647
|
-
if (!this.typingReactions.has(reactionKey)) {
|
|
1648
|
-
this.typingReactionCleanupRequested.delete(reactionKey);
|
|
1649
|
-
}
|
|
1650
|
-
});
|
|
1651
|
-
this.typingReactionCreatePromises.set(reactionKey, createPromise);
|
|
1652
1616
|
}
|
|
1653
1617
|
/**
|
|
1654
|
-
*
|
|
1618
|
+
* Clean up card state.
|
|
1655
1619
|
* Called by bridge-manager via onMessageEnd().
|
|
1656
1620
|
*/
|
|
1657
1621
|
onMessageEnd(chatId, streamKey) {
|
|
1658
1622
|
this.cleanupCard(chatId, streamKey);
|
|
1659
|
-
const reactionKey = this.resolveStreamKey(chatId, streamKey);
|
|
1660
|
-
if (this.typingReactionCreatePromises.has(reactionKey) && !this.typingReactions.has(reactionKey)) {
|
|
1661
|
-
this.typingReactionCleanupRequested.add(reactionKey);
|
|
1662
|
-
return;
|
|
1663
|
-
}
|
|
1664
|
-
this.removeTypingReaction(reactionKey);
|
|
1665
|
-
}
|
|
1666
|
-
removeTypingReaction(reactionKey) {
|
|
1667
|
-
const reaction = this.typingReactions.get(reactionKey);
|
|
1668
|
-
if (!reaction || !this.restClient) return;
|
|
1669
|
-
this.typingReactions.delete(reactionKey);
|
|
1670
|
-
this.restClient.im.messageReaction.delete({
|
|
1671
|
-
path: { message_id: reaction.messageId, reaction_id: reaction.reactionId }
|
|
1672
|
-
}).catch(() => {
|
|
1673
|
-
});
|
|
1674
1623
|
}
|
|
1675
1624
|
// ── Card Action Handler ─────────────────────────────────────
|
|
1676
1625
|
/**
|
|
@@ -2055,6 +2004,10 @@ ${trimmedResponse}`;
|
|
|
2055
2004
|
sequence: state.sequence
|
|
2056
2005
|
}
|
|
2057
2006
|
}));
|
|
2007
|
+
const terminalReactionEmoji = status === "completed" ? COMPLETED_EMOJI : status === "error" ? ERROR_EMOJI : null;
|
|
2008
|
+
if (terminalReactionEmoji) {
|
|
2009
|
+
await this.addTerminalReaction(cardKey, state.messageId, terminalReactionEmoji);
|
|
2010
|
+
}
|
|
2058
2011
|
console.log(`[feishu-adapter] Card finalized: streamKey=${cardKey}, cardId=${state.cardId}, status=${status}, elapsed=${formatElapsed(elapsedMs)}`);
|
|
2059
2012
|
return true;
|
|
2060
2013
|
} catch (err) {
|
|
@@ -2064,6 +2017,21 @@ ${trimmedResponse}`;
|
|
|
2064
2017
|
this.activeCards.delete(cardKey);
|
|
2065
2018
|
}
|
|
2066
2019
|
}
|
|
2020
|
+
async addTerminalReaction(streamKey, messageId, emojiType) {
|
|
2021
|
+
const messageReaction = this.restClient?.im?.messageReaction;
|
|
2022
|
+
if (typeof messageReaction?.create !== "function") return;
|
|
2023
|
+
try {
|
|
2024
|
+
await this.withFeishuRequestTimeout(streamKey, `im.messageReaction.create:${emojiType}`, () => messageReaction.create({
|
|
2025
|
+
path: { message_id: messageId },
|
|
2026
|
+
data: { reaction_type: { emoji_type: emojiType } }
|
|
2027
|
+
}));
|
|
2028
|
+
} catch (err) {
|
|
2029
|
+
const code2 = err?.code;
|
|
2030
|
+
if (code2 !== 99991400 && code2 !== 99991403) {
|
|
2031
|
+
console.warn("[feishu-adapter] Terminal reaction failed:", err instanceof Error ? err.message : err);
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2067
2035
|
/**
|
|
2068
2036
|
* Clean up card state without finalizing (e.g. on unexpected errors).
|
|
2069
2037
|
*/
|
package/package.json
CHANGED