@ouro.bot/cli 0.1.0-alpha.695 → 0.1.0-alpha.697
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/changelog.json +15 -0
- package/dist/arc/flight-recorder.js +139 -21
- package/dist/arc/obligations.js +28 -6
- package/dist/arc/packets.js +48 -0
- package/dist/heart/autonomy-budget.js +434 -0
- package/dist/heart/core.js +11 -0
- package/dist/heart/daemon/cadence.js +110 -0
- package/dist/heart/daemon/cli-exec.js +20 -0
- package/dist/heart/daemon/cli-help.js +74 -0
- package/dist/heart/daemon/cli-parse.js +466 -0
- package/dist/heart/daemon/daemon.js +24 -3
- package/dist/heart/daemon/doctor.js +151 -0
- package/dist/heart/daemon/stale-bundle-prune.js +23 -6
- package/dist/heart/habits/habit-parser.js +4 -1
- package/dist/heart/habits/habit-scheduler.js +46 -38
- package/dist/heart/habits/habit-session.js +2 -3
- package/dist/heart/run-ledger.js +247 -0
- package/dist/heart/runtime-credentials.js +12 -3
- package/dist/heart/work-card.js +1 -11
- package/dist/mind/prompt-budget.js +380 -0
- package/dist/repertoire/tools-base.js +2 -0
- package/dist/repertoire/tools-obligations.js +39 -0
- package/dist/repertoire/tools-rsvp.js +139 -0
- package/dist/rsvp/aisleplanner-client.js +354 -0
- package/dist/rsvp/cli.js +679 -0
- package/dist/rsvp/config.js +327 -0
- package/dist/rsvp/cutover.js +431 -0
- package/dist/rsvp/diagnostics.js +222 -0
- package/dist/rsvp/diff-renderer.js +159 -0
- package/dist/rsvp/habit-policy.js +85 -0
- package/dist/rsvp/habit-stage.js +93 -0
- package/dist/rsvp/incident-bundle.js +97 -0
- package/dist/rsvp/migration.js +204 -0
- package/dist/rsvp/outbound-state.js +254 -0
- package/dist/rsvp/query.js +118 -0
- package/dist/rsvp/replay.js +233 -0
- package/dist/rsvp/snapshot.js +232 -0
- package/dist/senses/bluebubbles/client.js +13 -7
- package/dist/senses/bluebubbles/index.js +227 -22
- package/dist/senses/bluebubbles/outbound-state.js +304 -0
- package/dist/senses/bluebubbles/replay.js +147 -0
- package/dist/senses/context-packet-ledger.js +245 -0
- package/dist/senses/context-packets.js +154 -0
- package/dist/senses/pipeline.js +92 -12
- package/dist/senses/private-runtime-worker.js +170 -31
- package/dist/senses/private-runtime.js +13 -1
- package/dist/senses/voice/twilio-phone.js +9 -5
- package/package.json +1 -1
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.BLUEBUBBLES_OUTBOUND_STATE_POLICY_VERSION = void 0;
|
|
37
|
+
exports.blueBubblesOutboundRecordPath = blueBubblesOutboundRecordPath;
|
|
38
|
+
exports.buildBlueBubblesRouteProof = buildBlueBubblesRouteProof;
|
|
39
|
+
exports.buildBlueBubblesAttachmentProof = buildBlueBubblesAttachmentProof;
|
|
40
|
+
exports.readBlueBubblesOutboundRecord = readBlueBubblesOutboundRecord;
|
|
41
|
+
exports.reserveBlueBubblesOutbound = reserveBlueBubblesOutbound;
|
|
42
|
+
exports.markBlueBubblesOutboundAccepted = markBlueBubblesOutboundAccepted;
|
|
43
|
+
exports.markBlueBubblesOutboundEnqueued = markBlueBubblesOutboundEnqueued;
|
|
44
|
+
exports.markBlueBubblesOutboundLocalVisible = markBlueBubblesOutboundLocalVisible;
|
|
45
|
+
exports.markBlueBubblesOutboundDelivered = markBlueBubblesOutboundDelivered;
|
|
46
|
+
exports.markBlueBubblesOutboundFailed = markBlueBubblesOutboundFailed;
|
|
47
|
+
exports.markBlueBubblesOutboundPendingManualVerification = markBlueBubblesOutboundPendingManualVerification;
|
|
48
|
+
const fs = __importStar(require("node:fs"));
|
|
49
|
+
const path = __importStar(require("node:path"));
|
|
50
|
+
const node_crypto_1 = require("node:crypto");
|
|
51
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
52
|
+
exports.BLUEBUBBLES_OUTBOUND_STATE_POLICY_VERSION = "bluebubbles-outbound-state/v1";
|
|
53
|
+
function sha256Hex(input) {
|
|
54
|
+
return (0, node_crypto_1.createHash)("sha256").update(input).digest("hex");
|
|
55
|
+
}
|
|
56
|
+
function hash(input) {
|
|
57
|
+
return `sha256:${sha256Hex(canonicalJson(input))}`;
|
|
58
|
+
}
|
|
59
|
+
function canonicalJson(value) {
|
|
60
|
+
if (Array.isArray(value))
|
|
61
|
+
return `[${value.map((entry) => canonicalJson(entry)).join(",")}]`;
|
|
62
|
+
if (value && typeof value === "object") {
|
|
63
|
+
const record = value;
|
|
64
|
+
return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(",")}}`;
|
|
65
|
+
}
|
|
66
|
+
return JSON.stringify(value);
|
|
67
|
+
}
|
|
68
|
+
function nowIso(input) {
|
|
69
|
+
return input ?? new Date().toISOString();
|
|
70
|
+
}
|
|
71
|
+
function recordIdFor(idempotencyKey) {
|
|
72
|
+
return `bbout_${sha256Hex(`bluebubbles-outbound:${idempotencyKey}`).slice(0, 32)}`;
|
|
73
|
+
}
|
|
74
|
+
function normalizeText(value) {
|
|
75
|
+
return value.trim().replace(/\s+/g, " ");
|
|
76
|
+
}
|
|
77
|
+
function endpointOrigin(serverUrl) {
|
|
78
|
+
const parsed = new URL(serverUrl);
|
|
79
|
+
return parsed.origin;
|
|
80
|
+
}
|
|
81
|
+
function blueBubblesOutboundDir(agentRoot) {
|
|
82
|
+
return path.join(agentRoot, "state", "bluebubbles", "outbound");
|
|
83
|
+
}
|
|
84
|
+
function blueBubblesOutboundRecordPath(agentRoot, recordId) {
|
|
85
|
+
return path.join(blueBubblesOutboundDir(agentRoot), `${recordId}.json`);
|
|
86
|
+
}
|
|
87
|
+
function buildBlueBubblesRouteProof(chat) {
|
|
88
|
+
const participantHandles = [...chat.participantHandles].sort();
|
|
89
|
+
const base = {
|
|
90
|
+
chatGuid: chat.chatGuid?.trim() || null,
|
|
91
|
+
chatIdentifier: chat.chatIdentifier?.trim() || null,
|
|
92
|
+
sendTarget: chat.sendTarget,
|
|
93
|
+
sessionKey: chat.sessionKey,
|
|
94
|
+
isGroup: chat.isGroup,
|
|
95
|
+
participantHandles,
|
|
96
|
+
};
|
|
97
|
+
return {
|
|
98
|
+
chatGuid: base.chatGuid,
|
|
99
|
+
chatIdentifier: base.chatIdentifier,
|
|
100
|
+
sendTarget: base.sendTarget,
|
|
101
|
+
sessionKey: base.sessionKey,
|
|
102
|
+
isGroup: base.isGroup,
|
|
103
|
+
participantHandlesHash: hash(participantHandles),
|
|
104
|
+
routeHash: hash(base),
|
|
105
|
+
rawParticipantHandlesStored: false,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function buildBlueBubblesAttachmentProof(input) {
|
|
109
|
+
const proof = {
|
|
110
|
+
endpointOrigin: endpointOrigin(input.serverUrl),
|
|
111
|
+
accountId: input.accountId?.trim() || null,
|
|
112
|
+
};
|
|
113
|
+
return {
|
|
114
|
+
...proof,
|
|
115
|
+
identityHash: hash(proof),
|
|
116
|
+
secretStored: false,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function buildRecord(input) {
|
|
120
|
+
const createdAt = nowIso(input.now);
|
|
121
|
+
const idempotencyKey = input.idempotencyKey.trim();
|
|
122
|
+
const text = normalizeText(input.text);
|
|
123
|
+
return {
|
|
124
|
+
schemaVersion: 1,
|
|
125
|
+
policyVersion: exports.BLUEBUBBLES_OUTBOUND_STATE_POLICY_VERSION,
|
|
126
|
+
recordId: recordIdFor(idempotencyKey),
|
|
127
|
+
idempotencyKey,
|
|
128
|
+
idempotencyHash: hash(idempotencyKey),
|
|
129
|
+
status: "reserved",
|
|
130
|
+
createdAt,
|
|
131
|
+
updatedAt: createdAt,
|
|
132
|
+
tempGuid: input.tempGuid.trim(),
|
|
133
|
+
routeProof: buildBlueBubblesRouteProof(input.chat),
|
|
134
|
+
attachmentProof: buildBlueBubblesAttachmentProof(input.attachment),
|
|
135
|
+
textHash: hash(text),
|
|
136
|
+
textLength: text.length,
|
|
137
|
+
...(input.replyToMessageGuid?.trim() ? { replyToMessageGuidHash: hash(input.replyToMessageGuid.trim()) } : {}),
|
|
138
|
+
contentStored: false,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function writeJsonAtomic(filePath, value) {
|
|
142
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
143
|
+
const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
|
|
144
|
+
fs.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, "utf-8");
|
|
145
|
+
fs.renameSync(tmp, filePath);
|
|
146
|
+
}
|
|
147
|
+
function readJson(filePath) {
|
|
148
|
+
if (!fs.existsSync(filePath))
|
|
149
|
+
return null;
|
|
150
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
151
|
+
}
|
|
152
|
+
function isOutboundRecord(value) {
|
|
153
|
+
const row = value;
|
|
154
|
+
return !!row
|
|
155
|
+
&& row.schemaVersion === 1
|
|
156
|
+
&& row.policyVersion === exports.BLUEBUBBLES_OUTBOUND_STATE_POLICY_VERSION
|
|
157
|
+
&& typeof row.recordId === "string"
|
|
158
|
+
&& typeof row.idempotencyKey === "string"
|
|
159
|
+
&& typeof row.idempotencyHash === "string"
|
|
160
|
+
&& typeof row.status === "string"
|
|
161
|
+
&& typeof row.createdAt === "string"
|
|
162
|
+
&& typeof row.updatedAt === "string"
|
|
163
|
+
&& typeof row.tempGuid === "string"
|
|
164
|
+
&& typeof row.textHash === "string"
|
|
165
|
+
&& typeof row.textLength === "number"
|
|
166
|
+
&& row.contentStored === false;
|
|
167
|
+
}
|
|
168
|
+
function readBlueBubblesOutboundRecord(agentRoot, recordId) {
|
|
169
|
+
try {
|
|
170
|
+
const parsed = readJson(blueBubblesOutboundRecordPath(agentRoot, recordId));
|
|
171
|
+
return isOutboundRecord(parsed) ? parsed : null;
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function writeBlueBubblesOutboundRecord(agentRoot, record) {
|
|
178
|
+
writeJsonAtomic(blueBubblesOutboundRecordPath(agentRoot, record.recordId), record);
|
|
179
|
+
return record;
|
|
180
|
+
}
|
|
181
|
+
function identityMatches(left, right) {
|
|
182
|
+
return left.routeProof.routeHash === right.routeProof.routeHash
|
|
183
|
+
&& left.attachmentProof.identityHash === right.attachmentProof.identityHash
|
|
184
|
+
&& left.textHash === right.textHash
|
|
185
|
+
&& left.replyToMessageGuidHash === right.replyToMessageGuidHash;
|
|
186
|
+
}
|
|
187
|
+
function emitDuplicate(record) {
|
|
188
|
+
(0, runtime_1.emitNervesEvent)({
|
|
189
|
+
level: "warn",
|
|
190
|
+
component: "senses",
|
|
191
|
+
event: "senses.bluebubbles_outbound_duplicate",
|
|
192
|
+
message: "duplicate bluebubbles outbound reservation suppressed",
|
|
193
|
+
meta: { recordId: record.recordId, status: record.status },
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function markPendingManualVerification(agentRoot, record, decidedAt, reason) {
|
|
197
|
+
const updated = writeBlueBubblesOutboundRecord(agentRoot, {
|
|
198
|
+
...record,
|
|
199
|
+
status: "pending-manual-verification",
|
|
200
|
+
updatedAt: decidedAt,
|
|
201
|
+
manualVerificationReason: reason,
|
|
202
|
+
});
|
|
203
|
+
(0, runtime_1.emitNervesEvent)({
|
|
204
|
+
level: "warn",
|
|
205
|
+
component: "senses",
|
|
206
|
+
event: "senses.bluebubbles_outbound_pending_manual_verification",
|
|
207
|
+
message: "bluebubbles outbound requires manual verification",
|
|
208
|
+
meta: { recordId: updated.recordId, reason },
|
|
209
|
+
});
|
|
210
|
+
return updated;
|
|
211
|
+
}
|
|
212
|
+
function reserveBlueBubblesOutbound(input) {
|
|
213
|
+
const record = buildRecord(input);
|
|
214
|
+
const filePath = blueBubblesOutboundRecordPath(input.agentRoot, record.recordId);
|
|
215
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
216
|
+
try {
|
|
217
|
+
const fd = fs.openSync(filePath, "wx");
|
|
218
|
+
try {
|
|
219
|
+
fs.writeFileSync(fd, `${JSON.stringify(record, null, 2)}\n`, "utf-8");
|
|
220
|
+
}
|
|
221
|
+
finally {
|
|
222
|
+
fs.closeSync(fd);
|
|
223
|
+
}
|
|
224
|
+
(0, runtime_1.emitNervesEvent)({
|
|
225
|
+
component: "senses",
|
|
226
|
+
event: "senses.bluebubbles_outbound_reserved",
|
|
227
|
+
message: "reserved bluebubbles outbound idempotency key",
|
|
228
|
+
meta: { recordId: record.recordId, textLength: record.textLength },
|
|
229
|
+
});
|
|
230
|
+
return { status: "reserved", record };
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
/* v8 ignore next -- non-EEXIST filesystem failures are rethrown fail-closed; hard to trigger portably after mkdir succeeds @preserve */
|
|
234
|
+
if (!isNodeFileExistsError(error))
|
|
235
|
+
throw error;
|
|
236
|
+
const existing = readBlueBubblesOutboundRecord(input.agentRoot, record.recordId);
|
|
237
|
+
if (!existing)
|
|
238
|
+
throw new Error(`bluebubbles outbound reservation is unreadable: ${record.recordId}`);
|
|
239
|
+
if (identityMatches(existing, record)) {
|
|
240
|
+
emitDuplicate(existing);
|
|
241
|
+
return { status: "duplicate", record: existing };
|
|
242
|
+
}
|
|
243
|
+
const updated = markPendingManualVerification(input.agentRoot, existing, nowIso(input.now), "identity-proof-mismatch");
|
|
244
|
+
return { status: "pending-manual-verification", reason: "identity-proof-mismatch", record: updated };
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
function isNodeFileExistsError(error) {
|
|
248
|
+
return typeof error === "object" && error !== null && error.code === "EEXIST";
|
|
249
|
+
}
|
|
250
|
+
function updateStatus(agentRoot, recordId, status, updatedAt, patch) {
|
|
251
|
+
const existing = readBlueBubblesOutboundRecord(agentRoot, recordId);
|
|
252
|
+
if (!existing)
|
|
253
|
+
throw new Error(`bluebubbles outbound record not found: ${recordId}`);
|
|
254
|
+
const updated = writeBlueBubblesOutboundRecord(agentRoot, {
|
|
255
|
+
...existing,
|
|
256
|
+
...patch,
|
|
257
|
+
status,
|
|
258
|
+
updatedAt,
|
|
259
|
+
});
|
|
260
|
+
(0, runtime_1.emitNervesEvent)({
|
|
261
|
+
component: "senses",
|
|
262
|
+
event: "senses.bluebubbles_outbound_state_changed",
|
|
263
|
+
message: "bluebubbles outbound state changed",
|
|
264
|
+
meta: { recordId, status },
|
|
265
|
+
});
|
|
266
|
+
return updated;
|
|
267
|
+
}
|
|
268
|
+
function markBlueBubblesOutboundAccepted(input) {
|
|
269
|
+
return updateStatus(input.agentRoot, input.recordId, "accepted", input.acceptedAt, {
|
|
270
|
+
acceptedAt: input.acceptedAt,
|
|
271
|
+
...(input.messageGuid?.trim() ? { messageGuid: input.messageGuid.trim() } : {}),
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function markBlueBubblesOutboundEnqueued(input) {
|
|
275
|
+
return updateStatus(input.agentRoot, input.recordId, "enqueued", input.enqueuedAt, {
|
|
276
|
+
enqueuedAt: input.enqueuedAt,
|
|
277
|
+
messageGuid: input.messageGuid.trim(),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
function markBlueBubblesOutboundLocalVisible(input) {
|
|
281
|
+
return updateStatus(input.agentRoot, input.recordId, "local-visible", input.visibleAt, {
|
|
282
|
+
localVisibleAt: input.visibleAt,
|
|
283
|
+
messageGuid: input.messageGuid.trim(),
|
|
284
|
+
...(input.tempGuid?.trim() ? { tempGuid: input.tempGuid.trim() } : {}),
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
function markBlueBubblesOutboundDelivered(input) {
|
|
288
|
+
return updateStatus(input.agentRoot, input.recordId, "delivered", input.deliveredAt, {
|
|
289
|
+
deliveredAt: input.deliveredAt,
|
|
290
|
+
...(input.messageGuid?.trim() ? { messageGuid: input.messageGuid.trim() } : {}),
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
function markBlueBubblesOutboundFailed(input) {
|
|
294
|
+
return updateStatus(input.agentRoot, input.recordId, "failed", input.failedAt, {
|
|
295
|
+
failedAt: input.failedAt,
|
|
296
|
+
failureReason: input.reason.slice(0, 500),
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
function markBlueBubblesOutboundPendingManualVerification(input) {
|
|
300
|
+
const existing = readBlueBubblesOutboundRecord(input.agentRoot, input.recordId);
|
|
301
|
+
if (!existing)
|
|
302
|
+
throw new Error(`bluebubbles outbound record not found: ${input.recordId}`);
|
|
303
|
+
return markPendingManualVerification(input.agentRoot, existing, input.decidedAt, input.reason);
|
|
304
|
+
}
|
|
@@ -1,7 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.replayBlueBubblesFixture = replayBlueBubblesFixture;
|
|
37
|
+
exports.replayJuly9BlueBubblesContextFixture = replayJuly9BlueBubblesContextFixture;
|
|
3
38
|
exports.replayBlueBubblesMessage = replayBlueBubblesMessage;
|
|
4
39
|
exports.formatBlueBubblesReplayText = formatBlueBubblesReplayText;
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
5
41
|
const render_1 = require("../../heart/attachments/render");
|
|
6
42
|
const bluebubbles_1 = require("../../heart/attachments/sources/bluebubbles");
|
|
7
43
|
const machine_identity_1 = require("../../heart/machine-identity");
|
|
@@ -18,6 +54,117 @@ function buildReplayHint(probeEventType, event) {
|
|
|
18
54
|
}
|
|
19
55
|
return undefined;
|
|
20
56
|
}
|
|
57
|
+
function isRecord(value) {
|
|
58
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
59
|
+
}
|
|
60
|
+
function requiredString(record, key) {
|
|
61
|
+
const value = record[key];
|
|
62
|
+
if (typeof value !== "string" || value.trim().length === 0)
|
|
63
|
+
throw new Error(`bluebubbles fixture missing ${key}`);
|
|
64
|
+
return value.trim();
|
|
65
|
+
}
|
|
66
|
+
async function replayBlueBubblesFixture(input) {
|
|
67
|
+
const fixture = input.fixture;
|
|
68
|
+
if (fixture.schemaVersion !== 1 || fixture.policyVersion !== "bluebubbles-replay/v1") {
|
|
69
|
+
throw new Error("unsupported BlueBubbles replay fixture");
|
|
70
|
+
}
|
|
71
|
+
const expected = isRecord(fixture.expected) ? fixture.expected : null;
|
|
72
|
+
const privacy = isRecord(fixture.privacy) ? fixture.privacy : null;
|
|
73
|
+
if (!expected || !privacy || privacy.rawTranscriptStored !== false || privacy.searchIndex !== false || privacy.vectorIndex !== false) {
|
|
74
|
+
throw new Error("BlueBubbles replay fixture must be minimized and private");
|
|
75
|
+
}
|
|
76
|
+
const result = {
|
|
77
|
+
sideEffect: false,
|
|
78
|
+
contextPacketHash: requiredString(expected, "contextPacketHash"),
|
|
79
|
+
modelInputHash: requiredString(expected, "modelInputHash"),
|
|
80
|
+
};
|
|
81
|
+
(0, runtime_1.emitNervesEvent)({
|
|
82
|
+
component: "senses",
|
|
83
|
+
event: "senses.bluebubbles_fixture_replayed",
|
|
84
|
+
message: "replayed bluebubbles fixture offline",
|
|
85
|
+
meta: { contextPacketHash: result.contextPacketHash, modelInputHash: result.modelInputHash },
|
|
86
|
+
});
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
function readJsonManifest(filePath) {
|
|
90
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
91
|
+
if (!isRecord(parsed))
|
|
92
|
+
throw new Error("replay manifest must be an object");
|
|
93
|
+
return parsed;
|
|
94
|
+
}
|
|
95
|
+
function manifestExpected(manifest) {
|
|
96
|
+
const expected = isRecord(manifest.expected) ? manifest.expected : null;
|
|
97
|
+
if (!expected)
|
|
98
|
+
throw new Error("July 9 replay manifest missing expected block");
|
|
99
|
+
return expected;
|
|
100
|
+
}
|
|
101
|
+
function july9PrivacyViolations(manifest) {
|
|
102
|
+
const privacy = isRecord(manifest.privacy) ? manifest.privacy : null;
|
|
103
|
+
if (!privacy)
|
|
104
|
+
return ["privacy"];
|
|
105
|
+
const violations = [];
|
|
106
|
+
if (privacy.rawLiveTranscriptStored !== false)
|
|
107
|
+
violations.push("rawLiveTranscriptStored");
|
|
108
|
+
if (privacy.credentialsStored !== false)
|
|
109
|
+
violations.push("credentialsStored");
|
|
110
|
+
if (privacy.searchIndex !== false)
|
|
111
|
+
violations.push("searchIndex");
|
|
112
|
+
if (privacy.vectorIndex !== false)
|
|
113
|
+
violations.push("vectorIndex");
|
|
114
|
+
return violations;
|
|
115
|
+
}
|
|
116
|
+
function assertJuly9ReplayPrivacy(manifest) {
|
|
117
|
+
const violations = july9PrivacyViolations(manifest);
|
|
118
|
+
if (violations.length > 0) {
|
|
119
|
+
throw new Error(`July 9 replay fixture must be repo-safe and non-indexed: ${violations.join(", ")}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function manifestMessages(manifest) {
|
|
123
|
+
const conversation = isRecord(manifest.conversation) ? manifest.conversation : null;
|
|
124
|
+
const messages = conversation && Array.isArray(conversation.messages) ? conversation.messages : [];
|
|
125
|
+
return messages.filter(isRecord);
|
|
126
|
+
}
|
|
127
|
+
function optionalString(record, key) {
|
|
128
|
+
const value = record[key];
|
|
129
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
130
|
+
}
|
|
131
|
+
function messageLine(message) {
|
|
132
|
+
const timestamp = optionalString(message, "timestamp");
|
|
133
|
+
const author = optionalString(message, "authorLabel");
|
|
134
|
+
const body = optionalString(message, "body");
|
|
135
|
+
if (!timestamp || !author || !body)
|
|
136
|
+
return null;
|
|
137
|
+
return `[${timestamp}] ${author}: ${body}`;
|
|
138
|
+
}
|
|
139
|
+
async function replayJuly9BlueBubblesContextFixture(input) {
|
|
140
|
+
const manifest = readJsonManifest(input.manifestPath);
|
|
141
|
+
if (manifest.schemaVersion !== 1 || manifest.policyVersion !== "july-9-rsvp-regression/v1") {
|
|
142
|
+
throw new Error("unsupported July 9 replay manifest");
|
|
143
|
+
}
|
|
144
|
+
assertJuly9ReplayPrivacy(manifest);
|
|
145
|
+
const expected = manifestExpected(manifest);
|
|
146
|
+
const modelInput = manifestMessages(manifest)
|
|
147
|
+
.map(messageLine)
|
|
148
|
+
.filter((line) => !!line)
|
|
149
|
+
.join("\n\n");
|
|
150
|
+
const result = {
|
|
151
|
+
sideEffect: false,
|
|
152
|
+
contextPacketHash: requiredString(expected, "contextPacketHash"),
|
|
153
|
+
renderedModelInputHash: requiredString(expected, "renderedModelInputHash"),
|
|
154
|
+
modelInput,
|
|
155
|
+
};
|
|
156
|
+
(0, runtime_1.emitNervesEvent)({
|
|
157
|
+
component: "senses",
|
|
158
|
+
event: "senses.bluebubbles_july9_fixture_replayed",
|
|
159
|
+
message: "replayed July 9 BlueBubbles context fixture",
|
|
160
|
+
meta: {
|
|
161
|
+
contextPacketHash: result.contextPacketHash,
|
|
162
|
+
renderedModelInputHash: result.renderedModelInputHash,
|
|
163
|
+
messageCount: manifestMessages(manifest).length,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
21
168
|
async function replayBlueBubblesMessage(params, deps = {}) {
|
|
22
169
|
const agentName = params.agentName.trim();
|
|
23
170
|
const messageGuid = params.messageGuid.trim();
|