openvisio-agent 0.19.2 → 0.19.3
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 +1 -1
- package/scripts/certify.mjs +1 -0
- package/src/watch.mjs +19 -6
package/package.json
CHANGED
package/scripts/certify.mjs
CHANGED
|
@@ -58,6 +58,7 @@ const assertions = [
|
|
|
58
58
|
['reconciled mentions reuse the guarded websocket delivery path', watcher.includes("onEvent('agent:mention'") && watcher.includes('_mentionAlreadyMarked: true')],
|
|
59
59
|
['conversation wake events preserve owned-thread follow-ups and filter other recipients before model start', watcher.includes("memory.has(controlKey, 'active')") && watcher.includes('classifyConversationTarget(msg, [...selfAliases], { threadOwned })') && events.includes("reason: 'owned-thread-follow-up'") && events.includes("reason: 'explicit-other-recipient'") && events.includes("reason: 'other-agent-chatter'")],
|
|
60
60
|
['prematurely acknowledged owned-thread replies recover exactly once', watcher.includes("!threadOwned || memory.has(sourceKey, 'received')") && watcher.includes('agent:mention replay recovered for active owned thread')],
|
|
61
|
+
['reconciliation recovers untagged human follow-ups in owned threads', watcher.includes("memory.has(activityControlKey, 'active')") && watcher.includes('const addressedActivity = mentionNeedles.some') && watcher.includes("!ownedActivity || memory.has(activitySourceKey, 'received')")],
|
|
61
62
|
['coding mentions require an action and concrete repository target', watcher.includes('conversationNeedsCode(text)') && events.includes('const action =') && events.includes('const target =')],
|
|
62
63
|
['stand-down and redirects cancel only source-thread workers', watcher.includes('cancelThread(cid, threadRoot') && watcher.includes('item.control.cancelled = true') && watcher.includes('item.control.runner?.cancelCurrent') && watcher.includes("subtype === 'canceled'")],
|
|
63
64
|
['thread cancellation is rechecked immediately before watcher delivery', watcher.includes('const newlyCancelled = suppressCancelled()') && watcher.includes('if (newlyCancelled) return newlyCancelled')],
|
package/src/watch.mjs
CHANGED
|
@@ -1361,15 +1361,28 @@ function loopBackendWs({ backend, wsUrl, apiKey, identifier, slug, claude, agent
|
|
|
1361
1361
|
? item.message
|
|
1362
1362
|
: data?.message && typeof data.message === 'object' ? data.message : item
|
|
1363
1363
|
const activityText = String(activityMessage?.content ?? activityMessage?.body ?? activityMessage?.text ?? '').toLowerCase()
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1364
|
+
const activityChannelId = item?.channel_id ?? item?.channelId ?? data?.channel_id ?? data?.channelId
|
|
1365
|
+
const activityMessageId = activityMessage?.id ?? activityMessage?.message_id ?? activityMessage?.messageId
|
|
1366
|
+
const activityParentId = activityMessage?.parent_id ?? activityMessage?.parentId
|
|
1367
|
+
const activityThreadRoot = activityParentId != null ? activityParentId : activityMessageId
|
|
1368
|
+
const activityControlKey = threadControlKey(activityChannelId, activityThreadRoot)
|
|
1369
|
+
const ownedActivity = !!activityControlKey && memory.has(activityControlKey, 'active')
|
|
1370
|
+
// Search only the source message, never the whole activity envelope: an
|
|
1371
|
+
// old tagged thread root can otherwise make another agent's new reply
|
|
1372
|
+
// look addressed to this watcher. Explicit mentions and human follow-ups
|
|
1373
|
+
// in a persistently owned thread both enter the guarded per-message path.
|
|
1374
|
+
const addressedActivity = mentionNeedles.some((needle) => activityText.includes(needle)) || ownedActivity
|
|
1375
|
+
if (!seenActivities.has(activityKey) && addressedActivity && /message|mention|channel/i.test(text)) {
|
|
1369
1376
|
seenActivities.add(activityKey); trimSeen(seenActivities); activityReplayTouched = true
|
|
1370
1377
|
// The same logical mention may already have arrived over WebSocket.
|
|
1371
1378
|
// Share the id/signature guard instead of starting a second model turn.
|
|
1372
|
-
|
|
1379
|
+
// Recover the former pre-routing acknowledgement bug exactly once
|
|
1380
|
+
// when an owned-thread source has no received ledger entry.
|
|
1381
|
+
if (markMentionHandled(activityMessage, activityChannelId)) {
|
|
1382
|
+
const activityMentionKeys = mentionDedupeKeys(activityMessage, activityChannelId)
|
|
1383
|
+
const activitySourceKey = `mention:${activityChannelId ?? '?'}:${activityMentionKeys.idKey || activityMentionKeys.signatureKey || activityThreadRoot}`
|
|
1384
|
+
if (!ownedActivity || memory.has(activitySourceKey, 'received')) continue
|
|
1385
|
+
}
|
|
1373
1386
|
mentionActivity.push({
|
|
1374
1387
|
projectId: project.id,
|
|
1375
1388
|
project: project.name,
|