@cocorograph/hub-agent 0.8.63 → 0.8.64
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/package.json
CHANGED
|
@@ -563,6 +563,9 @@ export class ClaudeStreamSession {
|
|
|
563
563
|
* メッセージが後着して実行される「ゴースト実行」を防ぐ)。到着で消費 (delete)。
|
|
564
564
|
* 無限増加を避けるため上限で全クリアする (キャンセルは低頻度)。 */
|
|
565
565
|
this._canceledInputIds = new Set()
|
|
566
|
+
/** 取消成功した input_id の直近リング。accepted は配達確認と二重実行防止の根拠なので外さず、
|
|
567
|
+
* browser が「accepted + キュー不在」のバブル昇格から取消済み id を除外する別軸にする。 */
|
|
568
|
+
this._cancelledInputIds = []
|
|
566
569
|
/** 改修3: 直近 browser へ通知した queue 署名 (件数 + id 列)。変化時のみ emit する。
|
|
567
570
|
* 空キューの署名 ("0:") で初期化し、空→空の冗長 emit を抑止する。 */
|
|
568
571
|
this._lastEmittedQueueSig = "0:"
|
|
@@ -1313,7 +1316,10 @@ export class ClaudeStreamSession {
|
|
|
1313
1316
|
// チップを固着させる。ack を返す条件 (accepted) と同じ場所で 1 回だけ記録する。
|
|
1314
1317
|
const inputId =
|
|
1315
1318
|
typeof opts?.input_id === "string" && opts.input_id ? opts.input_id : null
|
|
1316
|
-
if (inputId && result?.accepted)
|
|
1319
|
+
if (inputId && result?.accepted) {
|
|
1320
|
+
this._recordAcceptedInput(inputId)
|
|
1321
|
+
if (result.preCancelled) this._recordCancelledInput(inputId)
|
|
1322
|
+
}
|
|
1317
1323
|
return result
|
|
1318
1324
|
}
|
|
1319
1325
|
|
|
@@ -1336,7 +1342,7 @@ export class ClaudeStreamSession {
|
|
|
1336
1342
|
{ stream_id: this.stream_id, input_id: inputId },
|
|
1337
1343
|
"dropped pre-canceled input (cancel arrived before input)",
|
|
1338
1344
|
)
|
|
1339
|
-
return { accepted: true }
|
|
1345
|
+
return { accepted: true, preCancelled: true }
|
|
1340
1346
|
}
|
|
1341
1347
|
|
|
1342
1348
|
// ultracode ワンショット (0.6.28): このターンのみ xhigh effort + 常時 dynamic-workflow
|
|
@@ -1713,6 +1719,8 @@ export class ClaudeStreamSession {
|
|
|
1713
1719
|
* snapshot の `accepted` として browser へ載せ、ack 喪失時の自己回復に使う。 */
|
|
1714
1720
|
_recordAcceptedInput(inputId) {
|
|
1715
1721
|
if (typeof inputId !== "string" || !inputId) return
|
|
1722
|
+
const cancelledAt = this._cancelledInputIds.indexOf(inputId)
|
|
1723
|
+
if (cancelledAt !== -1) this._cancelledInputIds.splice(cancelledAt, 1)
|
|
1716
1724
|
const at = this._acceptedInputIds.indexOf(inputId)
|
|
1717
1725
|
if (at !== -1) this._acceptedInputIds.splice(at, 1)
|
|
1718
1726
|
this._acceptedInputIds.push(inputId)
|
|
@@ -1724,6 +1732,19 @@ export class ClaudeStreamSession {
|
|
|
1724
1732
|
}
|
|
1725
1733
|
}
|
|
1726
1734
|
|
|
1735
|
+
_recordCancelledInput(inputId) {
|
|
1736
|
+
if (typeof inputId !== "string" || !inputId) return
|
|
1737
|
+
const at = this._cancelledInputIds.indexOf(inputId)
|
|
1738
|
+
if (at !== -1) this._cancelledInputIds.splice(at, 1)
|
|
1739
|
+
this._cancelledInputIds.push(inputId)
|
|
1740
|
+
if (this._cancelledInputIds.length > ACCEPTED_INPUT_ID_RING_MAX) {
|
|
1741
|
+
this._cancelledInputIds.splice(
|
|
1742
|
+
0,
|
|
1743
|
+
this._cancelledInputIds.length - ACCEPTED_INPUT_ID_RING_MAX,
|
|
1744
|
+
)
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1727
1748
|
/** キャンセル機能 (0.6.26): browser から id 指定で送信待ちメッセージを 1 件取り消す。
|
|
1728
1749
|
* 実行開始済み (既に drain された) メッセージは pending に残っていないので no-op になる。
|
|
1729
1750
|
* 削除に成功したら queue_state を再 emit して送信待ちチップを更新する。 */
|
|
@@ -1740,6 +1761,8 @@ export class ClaudeStreamSession {
|
|
|
1740
1761
|
this._pendingMessages = this._pendingMessages.filter((m) => m.id !== id)
|
|
1741
1762
|
const removed = before !== this._pendingMessages.length
|
|
1742
1763
|
if (removed) {
|
|
1764
|
+
this._canceledInputIds.delete(id)
|
|
1765
|
+
this._recordCancelledInput(id)
|
|
1743
1766
|
this.logger?.info(
|
|
1744
1767
|
{ stream_id: this.stream_id, id, queued: this._pendingMessages.length },
|
|
1745
1768
|
"queued message canceled",
|
|
@@ -1855,6 +1878,7 @@ export class ClaudeStreamSession {
|
|
|
1855
1878
|
// と判定して楽観チップを消し、「キューに無い + ここにも無い = 未配達」なら
|
|
1856
1879
|
// 消さずに再送導線を出す (無言削除の回帰を作らないための 2 軸判定)。
|
|
1857
1880
|
accepted: [...this._acceptedInputIds],
|
|
1881
|
+
cancelled: [...this._cancelledInputIds],
|
|
1858
1882
|
}
|
|
1859
1883
|
}
|
|
1860
1884
|
|
|
@@ -973,6 +973,9 @@ export class CodexStreamBridge extends EventEmitter {
|
|
|
973
973
|
queueStateSeq: 0,
|
|
974
974
|
/** ack 喪失からの自己回復用、受理済み browser input_id の bounded ring。 */
|
|
975
975
|
acceptedInputIds: [],
|
|
976
|
+
/** 取消成功 id は accepted(二重実行ガード)から外さず、browser が「accepted +キュー不在」
|
|
977
|
+
* のバブル昇格から除外するための別軸として保持する。 */
|
|
978
|
+
cancelledInputIds: [],
|
|
976
979
|
/** @type {{resolve: Function, timer: any} | null} round3 major#2: turn/start 後に turn/started
|
|
977
980
|
* (activeTurnId 確定) を待つ barrier の待機者。timeout 付きでハングを防ぐ。 */
|
|
978
981
|
_turnActiveWaiter: null,
|
|
@@ -2062,6 +2065,9 @@ export class CodexStreamBridge extends EventEmitter {
|
|
|
2062
2065
|
|
|
2063
2066
|
_recordAcceptedInput(session, inputId) {
|
|
2064
2067
|
if (!session || typeof inputId !== "string" || !inputId) return
|
|
2068
|
+
const cancelledIds = session.cancelledInputIds || (session.cancelledInputIds = [])
|
|
2069
|
+
const cancelledAt = cancelledIds.indexOf(inputId)
|
|
2070
|
+
if (cancelledAt !== -1) cancelledIds.splice(cancelledAt, 1)
|
|
2065
2071
|
const ids = session.acceptedInputIds || (session.acceptedInputIds = [])
|
|
2066
2072
|
const at = ids.indexOf(inputId)
|
|
2067
2073
|
if (at !== -1) ids.splice(at, 1)
|
|
@@ -2071,6 +2077,17 @@ export class CodexStreamBridge extends EventEmitter {
|
|
|
2071
2077
|
}
|
|
2072
2078
|
}
|
|
2073
2079
|
|
|
2080
|
+
_recordCancelledInput(session, inputId) {
|
|
2081
|
+
if (!session || typeof inputId !== "string" || !inputId) return
|
|
2082
|
+
const ids = session.cancelledInputIds || (session.cancelledInputIds = [])
|
|
2083
|
+
const at = ids.indexOf(inputId)
|
|
2084
|
+
if (at !== -1) ids.splice(at, 1)
|
|
2085
|
+
ids.push(inputId)
|
|
2086
|
+
if (ids.length > ACCEPTED_INPUT_ID_RING_MAX) {
|
|
2087
|
+
ids.splice(0, ids.length - ACCEPTED_INPUT_ID_RING_MAX)
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2074
2091
|
/**
|
|
2075
2092
|
* 重複ガードの台帳から id を取り消す (2026-08-05)。
|
|
2076
2093
|
*
|
|
@@ -2103,6 +2120,7 @@ export class CodexStreamBridge extends EventEmitter {
|
|
|
2103
2120
|
seq: session.queueStateSeq || 0,
|
|
2104
2121
|
generation: session.seq,
|
|
2105
2122
|
accepted: [...(session.acceptedInputIds || [])],
|
|
2123
|
+
cancelled: [...(session.cancelledInputIds || [])],
|
|
2106
2124
|
}
|
|
2107
2125
|
}
|
|
2108
2126
|
|
|
@@ -2121,6 +2139,7 @@ export class CodexStreamBridge extends EventEmitter {
|
|
|
2121
2139
|
return false
|
|
2122
2140
|
}
|
|
2123
2141
|
const [item] = session.inputQueue.splice(index, 1)
|
|
2142
|
+
this._recordCancelledInput(session, item.inputId || item.deliveryId)
|
|
2124
2143
|
if (!item.acceptedAsQueued) {
|
|
2125
2144
|
const err = Object.assign(new Error("codex queued input cancelled"), {
|
|
2126
2145
|
reason: "cancelled",
|