@ouro.bot/cli 0.1.0-alpha.230 → 0.1.0-alpha.231
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
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.231",
|
|
6
|
+
"changes": [
|
|
7
|
+
"fix: defense-in-depth group chat blocking for proactive BB delivery — sendProactiveBlueBubblesMessageToSession now rejects group chat keys (;+;) unless intent is explicit_cross_chat (bridge/delegation responses). All upper-layer paths (surface tool, send_message tool, inner-dialog delegation) now filter to DM sessions only for proactive outreach, and pass explicit_cross_chat intent for bridge/delegation returns where group responses are legitimate."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.230",
|
|
6
12
|
"changes": [
|
|
@@ -592,11 +592,10 @@ exports.sessionToolDefinitions = [
|
|
|
592
592
|
const bbDir = path.join(agentRoot, "state", "sessions", friendId, "bluebubbles");
|
|
593
593
|
if (fs.existsSync(bbDir)) {
|
|
594
594
|
const files = fs.readdirSync(bbDir).filter((f) => f.endsWith(".json"));
|
|
595
|
-
//
|
|
595
|
+
// Only use DM sessions (;-;) for proactive delivery — never group chats (;+;)
|
|
596
596
|
const dmFile = files.find((f) => f.includes(";-;"));
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
resolvedKey = chosen.replace(/\.json$/, "");
|
|
597
|
+
if (dmFile) {
|
|
598
|
+
resolvedKey = dmFile.replace(/\.json$/, "");
|
|
600
599
|
}
|
|
601
600
|
}
|
|
602
601
|
}
|
|
@@ -118,6 +118,7 @@ exports.surfaceToolDefinition = {
|
|
|
118
118
|
friendId: bridgeTarget.friendId,
|
|
119
119
|
sessionKey: bridgeTarget.key,
|
|
120
120
|
text: content,
|
|
121
|
+
intent: "explicit_cross_chat",
|
|
121
122
|
});
|
|
122
123
|
if (proactiveResult.delivered) {
|
|
123
124
|
// Inject surfaced content into the target session so it knows what was delivered
|
|
@@ -145,8 +146,8 @@ exports.surfaceToolDefinition = {
|
|
|
145
146
|
// Priority 2: Try proactive delivery first, then queue to freshest session
|
|
146
147
|
const allFriendSessions = (0, session_activity_1.listSessionActivity)({ sessionsDir, friendsDir, agentName, activeThresholdMs: Number.MAX_SAFE_INTEGER })
|
|
147
148
|
.filter((s) => s.friendId === friendId && s.channel !== "inner");
|
|
148
|
-
// 2a: Attempt proactive BB delivery on
|
|
149
|
-
const bbSession = allFriendSessions.find((s) => s.channel === "bluebubbles");
|
|
149
|
+
// 2a: Attempt proactive BB delivery on a DM session (;-; = individual, never ;+; = group)
|
|
150
|
+
const bbSession = allFriendSessions.find((s) => s.channel === "bluebubbles" && s.key.includes(";-;"));
|
|
150
151
|
if (bbSession) {
|
|
151
152
|
const { sendProactiveBlueBubblesMessageToSession } = await Promise.resolve().then(() => __importStar(require("../senses/bluebubbles")));
|
|
152
153
|
const proactiveResult = await sendProactiveBlueBubblesMessageToSession({
|
|
@@ -1137,6 +1137,21 @@ async function sendProactiveBlueBubblesMessageToSession(params, deps = {}) {
|
|
|
1137
1137
|
});
|
|
1138
1138
|
return { delivered: false, reason: "missing_target" };
|
|
1139
1139
|
}
|
|
1140
|
+
// Proactive outreach to individuals must go to DMs, never group chats.
|
|
1141
|
+
// Explicit cross-chat responses (bridge completions, delegation returns) ARE allowed to groups
|
|
1142
|
+
// because the request originated from that group.
|
|
1143
|
+
/* v8 ignore start -- group gate: only fires when proactive send targets a group session @preserve */
|
|
1144
|
+
if (chat.isGroup && params.intent !== "explicit_cross_chat") {
|
|
1145
|
+
(0, runtime_1.emitNervesEvent)({
|
|
1146
|
+
level: "warn",
|
|
1147
|
+
component: "senses",
|
|
1148
|
+
event: "senses.bluebubbles_proactive_group_blocked",
|
|
1149
|
+
message: "proactive send blocked: would route to group chat",
|
|
1150
|
+
meta: { friendId: params.friendId, sessionKey: params.sessionKey, chatGuid: chat.chatGuid ?? null, intent: params.intent ?? null },
|
|
1151
|
+
});
|
|
1152
|
+
return { delivered: false, reason: "group_blocked" };
|
|
1153
|
+
}
|
|
1154
|
+
/* v8 ignore stop */
|
|
1140
1155
|
try {
|
|
1141
1156
|
await client.sendText({ chat, text: params.text });
|
|
1142
1157
|
(0, runtime_1.emitNervesEvent)({
|
|
@@ -300,6 +300,7 @@ async function tryDeliverDelegatedCompletion(target, outboundEnvelope) {
|
|
|
300
300
|
friendId: target.friendId,
|
|
301
301
|
sessionKey: target.key,
|
|
302
302
|
text: outboundEnvelope.content,
|
|
303
|
+
intent: "explicit_cross_chat",
|
|
303
304
|
});
|
|
304
305
|
return result.delivered;
|
|
305
306
|
}
|
|
@@ -417,14 +418,15 @@ async function routeDelegatedCompletion(agentRoot, agentName, completion, draine
|
|
|
417
418
|
return;
|
|
418
419
|
}
|
|
419
420
|
// Priority 2: Freshest active friend session.
|
|
420
|
-
|
|
421
|
+
// For BB, prefer DM sessions (;-;) over group chats (;+;) — proactive outreach should never land in groups.
|
|
422
|
+
const allFriendSessions = (0, session_activity_1.listSessionActivity)({
|
|
421
423
|
sessionsDir: path.join(agentRoot, "state", "sessions"),
|
|
422
424
|
friendsDir: path.join(agentRoot, "friends"),
|
|
423
425
|
agentName,
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
if (freshest
|
|
426
|
+
}).filter((s) => s.friendId === delegatedFrom.friendId && s.channel !== "inner");
|
|
427
|
+
const bbDm = allFriendSessions.find((s) => s.channel === "bluebubbles" && s.key.includes(";-;"));
|
|
428
|
+
const freshest = bbDm ?? allFriendSessions.find((s) => s.channel !== "bluebubbles" || s.key.includes(";-;")) ?? allFriendSessions[0];
|
|
429
|
+
if (freshest) {
|
|
428
430
|
if (await tryDeliverDelegatedCompletion(freshest, outboundEnvelope)) {
|
|
429
431
|
advanceObligationQuietly(agentName, obligationId, { status: "returned", returnedAt: timestamp, returnTarget: "freshest-session" });
|
|
430
432
|
return;
|