@ouro.bot/cli 0.1.0-alpha.954 → 0.1.0-alpha.956

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.
@@ -37,6 +37,7 @@ exports.BLUEBUBBLES_OUTBOUND_STATE_POLICY_VERSION = void 0;
37
37
  exports.blueBubblesOutboundRecordPath = blueBubblesOutboundRecordPath;
38
38
  exports.buildBlueBubblesRouteProof = buildBlueBubblesRouteProof;
39
39
  exports.buildBlueBubblesAttachmentProof = buildBlueBubblesAttachmentProof;
40
+ exports.blueBubblesOutboundTextMatches = blueBubblesOutboundTextMatches;
40
41
  exports.readBlueBubblesOutboundRecord = readBlueBubblesOutboundRecord;
41
42
  exports.readBlueBubblesOutboundRecordByIdempotencyKey = readBlueBubblesOutboundRecordByIdempotencyKey;
42
43
  exports.reserveBlueBubblesOutbound = reserveBlueBubblesOutbound;
@@ -139,6 +140,10 @@ function buildRecord(input) {
139
140
  contentStored: false,
140
141
  };
141
142
  }
143
+ /** True when `text` is the reply this record last tried to send. */
144
+ function blueBubblesOutboundTextMatches(record, text) {
145
+ return hash(normalizeText(text)) === record.textHash;
146
+ }
142
147
  function writeJsonAtomic(filePath, value) {
143
148
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
144
149
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
@@ -240,6 +245,26 @@ function reserveBlueBubblesOutbound(input) {
240
245
  const existing = readBlueBubblesOutboundRecord(input.agentRoot, record.recordId);
241
246
  if (!existing)
242
247
  throw new Error(`bluebubbles outbound reservation is unreadable: ${record.recordId}`);
248
+ if (existing.status === "failed"
249
+ && existing.routeProof.routeHash === record.routeProof.routeHash
250
+ && existing.attachmentProof.identityHash === record.attachmentProof.identityHash) {
251
+ // A failed send to the same chat is retryable, possibly with new text:
252
+ // reserve again, keeping the first attempt's time and the failure history.
253
+ const retry = writeBlueBubblesOutboundRecord(input.agentRoot, {
254
+ ...record,
255
+ createdAt: existing.createdAt,
256
+ ...(existing.failedAttempts ? { failedAttempts: existing.failedAttempts } : {}),
257
+ ...(existing.failedAt ? { failedAt: existing.failedAt } : {}),
258
+ ...(existing.failureReason ? { failureReason: existing.failureReason } : {}),
259
+ });
260
+ (0, runtime_1.emitNervesEvent)({
261
+ component: "senses",
262
+ event: "senses.bluebubbles_outbound_reserved",
263
+ message: "reserved bluebubbles outbound idempotency key again after a failed send",
264
+ meta: { recordId: retry.recordId, textLength: retry.textLength, failedAttempts: retry.failedAttempts ?? 0 },
265
+ });
266
+ return { status: "reserved", record: retry };
267
+ }
243
268
  if (identityMatches(existing, record)) {
244
269
  emitDuplicate(existing);
245
270
  return { status: "duplicate", record: existing };
@@ -295,9 +320,11 @@ function markBlueBubblesOutboundDelivered(input) {
295
320
  });
296
321
  }
297
322
  function markBlueBubblesOutboundFailed(input) {
323
+ const failedAttempts = (readBlueBubblesOutboundRecord(input.agentRoot, input.recordId)?.failedAttempts ?? 0) + 1;
298
324
  return updateStatus(input.agentRoot, input.recordId, "failed", input.failedAt, {
299
325
  failedAt: input.failedAt,
300
326
  failureReason: input.reason.slice(0, 500),
327
+ failedAttempts,
301
328
  });
302
329
  }
303
330
  function markBlueBubblesOutboundPendingManualVerification(input) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.954",
3
+ "version": "0.1.0-alpha.956",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@ouro.bot/cli",
9
- "version": "0.1.0-alpha.954",
9
+ "version": "0.1.0-alpha.956",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "^0.78.0",
12
12
  "@azure/identity": "^4.13.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.954",
3
+ "version": "0.1.0-alpha.956",
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },