@indexnetwork/protocol 6.6.2-rc.388.1 → 6.6.3-rc.389.1
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.md +1 -0
- package/dist/opportunity/opportunity.enricher.d.ts +5 -0
- package/dist/opportunity/opportunity.enricher.d.ts.map +1 -1
- package/dist/opportunity/opportunity.enricher.js +17 -1
- package/dist/opportunity/opportunity.enricher.js.map +1 -1
- package/dist/opportunity/opportunity.graph.d.ts +109 -247
- package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
- package/dist/opportunity/opportunity.graph.js +198 -4
- package/dist/opportunity/opportunity.graph.js.map +1 -1
- package/dist/opportunity/opportunity.persist.d.ts +14 -1
- package/dist/opportunity/opportunity.persist.d.ts.map +1 -1
- package/dist/opportunity/opportunity.persist.js +33 -4
- package/dist/opportunity/opportunity.persist.js.map +1 -1
- package/dist/opportunity/opportunity.state.d.ts +17 -0
- package/dist/opportunity/opportunity.state.d.ts.map +1 -1
- package/dist/opportunity/opportunity.state.js +5 -0
- package/dist/opportunity/opportunity.state.js.map +1 -1
- package/dist/shared/interfaces/database.interface.d.ts +25 -2
- package/dist/shared/interfaces/database.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/database.interface.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opportunity.graph.d.ts","sourceRoot":"/","sources":["opportunity/opportunity.graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,4CAA4C,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAyB,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAExO,OAAO,EAAwB,KAAK,gBAAgB,EAAuC,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACzK,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4CAA4C,CAAC;AAS3F,yDAAyD;AACzD,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,CAAC,EAAE,CACP,oBAAoB,EAAE,MAAM,EAC5B,UAAU,EAAE,gBAAgB,EAAE,EAC9B,OAAO,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAC3B,OAAO,CAAC,KAAK,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;KAC3C,CAAC,CAAC,CAAC;IACJ,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,KAAK,CAAC;QAC5F,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,CAAC,CAAC;KAC9H,CAAC,CAAC,CAAC;CACL,CAAC;AACF,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,4CAA4C,CAAC;AAC1F,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"opportunity.graph.d.ts","sourceRoot":"/","sources":["opportunity/opportunity.graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -71,6 +71,14 @@ function isActiveNegotiationTaskFresh(task) {
|
|
|
71
71
|
: 5 * 60 * 1000;
|
|
72
72
|
return Date.now() - new Date(task.updatedAt).getTime() < freshnessMs;
|
|
73
73
|
}
|
|
74
|
+
function triggerForOwner(opportunity, ownerUserId) {
|
|
75
|
+
return opportunity.detection.triggeredBy
|
|
76
|
+
?? opportunity.actors.find((actor) => actor.userId === ownerUserId)?.intent;
|
|
77
|
+
}
|
|
78
|
+
function belongsToOwnedIntent(opportunity, ownerUserId, triggerIntentId) {
|
|
79
|
+
return opportunity.detection.triggeredBy === triggerIntentId
|
|
80
|
+
|| opportunity.actors.some((actor) => actor.userId === ownerUserId && actor.intent === triggerIntentId);
|
|
81
|
+
}
|
|
74
82
|
/** Put an opportunity actor's exact intent first, then fill the bounded context without duplicates. */
|
|
75
83
|
export function buildPrioritizedNegotiationIntents(activeIntents, exactIntentId, fallbackIntent) {
|
|
76
84
|
const exactId = typeof exactIntentId === 'string' && exactIntentId.trim().length > 0
|
|
@@ -2503,8 +2511,22 @@ export class OpportunityGraphFactory {
|
|
|
2503
2511
|
initialStatus,
|
|
2504
2512
|
});
|
|
2505
2513
|
if (state.evaluatedOpportunities.length === 0) {
|
|
2506
|
-
persistLog.verbose('No opportunities to persist'
|
|
2507
|
-
|
|
2514
|
+
persistLog.verbose('No opportunities to persist', {
|
|
2515
|
+
triggerIntentId: state.triggerIntentId,
|
|
2516
|
+
reason: state.candidates.length === 0 ? 'no_search_candidates' : 'evaluator_rejected_all',
|
|
2517
|
+
});
|
|
2518
|
+
return {
|
|
2519
|
+
opportunities: [],
|
|
2520
|
+
persistenceOutcome: {
|
|
2521
|
+
evaluatedCount: 0,
|
|
2522
|
+
createdCount: 0,
|
|
2523
|
+
reactivatedCount: 0,
|
|
2524
|
+
sameTriggerDuplicateSuppressions: 0,
|
|
2525
|
+
pairActiveNegotiationSuppressions: 0,
|
|
2526
|
+
crossTriggerAllowedCount: 0,
|
|
2527
|
+
finalAtomicConflictCount: 0,
|
|
2528
|
+
},
|
|
2529
|
+
};
|
|
2508
2530
|
}
|
|
2509
2531
|
try {
|
|
2510
2532
|
// Recompute the authoritative owner-side scope at the final boundary.
|
|
@@ -2580,6 +2602,7 @@ export class OpportunityGraphFactory {
|
|
|
2580
2602
|
};
|
|
2581
2603
|
const itemsToPersist = [];
|
|
2582
2604
|
const reactivatedOpportunities = [];
|
|
2605
|
+
let crossTriggerAllowedCount = 0;
|
|
2583
2606
|
const existingBetweenActors = [];
|
|
2584
2607
|
const now = new Date().toISOString();
|
|
2585
2608
|
// Only skip 'draft' (chat-only) opportunities during dedup.
|
|
@@ -2883,7 +2906,137 @@ export class OpportunityGraphFactory {
|
|
|
2883
2906
|
count: overlapping.length,
|
|
2884
2907
|
results: overlapping.map(o => ({ id: o.id, status: o.status, actors: o.actors?.map((a) => ({ userId: a.userId, role: a.role })) })),
|
|
2885
2908
|
});
|
|
2886
|
-
|
|
2909
|
+
const ownedIntentTriggerId = state.discoverySource === 'intent'
|
|
2910
|
+
&& state.triggerIntentId
|
|
2911
|
+
&& state.resolvedTriggerIntentId === state.triggerIntentId
|
|
2912
|
+
? state.triggerIntentId
|
|
2913
|
+
: undefined;
|
|
2914
|
+
if (ownedIntentTriggerId && candidateUserId) {
|
|
2915
|
+
let activeNegotiation;
|
|
2916
|
+
for (const opportunity of overlapping) {
|
|
2917
|
+
if (opportunity.status !== 'negotiating')
|
|
2918
|
+
continue;
|
|
2919
|
+
const task = await this.database.getNegotiationTaskForOpportunity(opportunity.id);
|
|
2920
|
+
if (task && isActiveNegotiationTaskFresh(task)) {
|
|
2921
|
+
activeNegotiation = { opportunity, taskState: task.state };
|
|
2922
|
+
break;
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
if (activeNegotiation) {
|
|
2926
|
+
const existingTriggerIntentId = triggerForOwner(activeNegotiation.opportunity, state.userId);
|
|
2927
|
+
existingBetweenActors.push({
|
|
2928
|
+
candidateUserId: candidateUserId,
|
|
2929
|
+
networkId: (activeNegotiation.opportunity.context?.networkId ?? state.networkId ?? state.userNetworks?.[0] ?? ''),
|
|
2930
|
+
existingOpportunityId: activeNegotiation.opportunity.id,
|
|
2931
|
+
existingStatus: activeNegotiation.opportunity.status,
|
|
2932
|
+
reason: 'pair_active_negotiation',
|
|
2933
|
+
...(existingTriggerIntentId ? { existingTriggerIntentId } : {}),
|
|
2934
|
+
});
|
|
2935
|
+
persistDedupLog.info('Suppressing owned-intent match for pair-global active negotiation', {
|
|
2936
|
+
triggerIntentId: ownedIntentTriggerId,
|
|
2937
|
+
candidateUserId,
|
|
2938
|
+
existingOpportunityId: activeNegotiation.opportunity.id,
|
|
2939
|
+
existingTriggerIntentId,
|
|
2940
|
+
existingStatus: activeNegotiation.opportunity.status,
|
|
2941
|
+
existingAgeMs: Date.now() - new Date(activeNegotiation.opportunity.createdAt).getTime(),
|
|
2942
|
+
taskState: activeNegotiation.taskState,
|
|
2943
|
+
reason: 'pair_active_negotiation',
|
|
2944
|
+
});
|
|
2945
|
+
continue;
|
|
2946
|
+
}
|
|
2947
|
+
const sameTrigger = overlapping
|
|
2948
|
+
.filter((opportunity) => belongsToOwnedIntent(opportunity, state.userId, ownedIntentTriggerId))
|
|
2949
|
+
.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
2950
|
+
const otherTrigger = overlapping.filter((opportunity) => !belongsToOwnedIntent(opportunity, state.userId, ownedIntentTriggerId));
|
|
2951
|
+
const existing = sameTrigger[0];
|
|
2952
|
+
if (!existing) {
|
|
2953
|
+
if (otherTrigger.length > 0) {
|
|
2954
|
+
crossTriggerAllowedCount += 1;
|
|
2955
|
+
persistDedupLog.info('Allowing cross-trigger match for owned intent', {
|
|
2956
|
+
triggerIntentId: ownedIntentTriggerId,
|
|
2957
|
+
candidateUserId,
|
|
2958
|
+
reason: 'cross_trigger_match_allowed',
|
|
2959
|
+
otherTriggers: otherTrigger.map((opportunity) => ({
|
|
2960
|
+
opportunityId: opportunity.id,
|
|
2961
|
+
triggerIntentId: triggerForOwner(opportunity, state.userId),
|
|
2962
|
+
status: opportunity.status,
|
|
2963
|
+
ageMs: Date.now() - new Date(opportunity.createdAt).getTime(),
|
|
2964
|
+
})),
|
|
2965
|
+
});
|
|
2966
|
+
}
|
|
2967
|
+
}
|
|
2968
|
+
else {
|
|
2969
|
+
const existingIndexId = (existing.context?.networkId ?? state.networkId ?? state.userNetworks?.[0] ?? '');
|
|
2970
|
+
const isRecent = new Date(existing.createdAt).getTime() > Date.now() - DEDUP_WINDOW_MS;
|
|
2971
|
+
if (existing.status === 'expired' || existing.status === 'stalled') {
|
|
2972
|
+
const reactivated = await updateStatusIfStillEligible(existing.id, initialStatus, existing.actors, existing.status);
|
|
2973
|
+
if (reactivated) {
|
|
2974
|
+
persistLog.info('Reactivated same-trigger opportunity', {
|
|
2975
|
+
triggerIntentId: ownedIntentTriggerId,
|
|
2976
|
+
opportunityId: existing.id,
|
|
2977
|
+
candidateUserId,
|
|
2978
|
+
previousStatus: existing.status,
|
|
2979
|
+
newStatus: initialStatus,
|
|
2980
|
+
});
|
|
2981
|
+
reactivatedOpportunities.push(reactivated);
|
|
2982
|
+
}
|
|
2983
|
+
continue;
|
|
2984
|
+
}
|
|
2985
|
+
if (existing.status === 'negotiating') {
|
|
2986
|
+
const reactivated = await updateStatusIfStillEligible(existing.id, initialStatus, existing.actors, existing.status);
|
|
2987
|
+
if (reactivated) {
|
|
2988
|
+
persistLog.info('Resuming same-trigger orphaned negotiating opportunity', {
|
|
2989
|
+
triggerIntentId: ownedIntentTriggerId,
|
|
2990
|
+
opportunityId: existing.id,
|
|
2991
|
+
candidateUserId,
|
|
2992
|
+
});
|
|
2993
|
+
reactivatedOpportunities.push(reactivated);
|
|
2994
|
+
}
|
|
2995
|
+
continue;
|
|
2996
|
+
}
|
|
2997
|
+
if (existing.status === 'latent' && initialStatus !== 'latent') {
|
|
2998
|
+
const upgraded = await updateStatusIfStillEligible(existing.id, initialStatus, existing.actors, existing.status);
|
|
2999
|
+
if (upgraded) {
|
|
3000
|
+
persistLog.info('Upgraded same-trigger latent opportunity', {
|
|
3001
|
+
triggerIntentId: ownedIntentTriggerId,
|
|
3002
|
+
opportunityId: existing.id,
|
|
3003
|
+
candidateUserId,
|
|
3004
|
+
newStatus: initialStatus,
|
|
3005
|
+
});
|
|
3006
|
+
reactivatedOpportunities.push(upgraded);
|
|
3007
|
+
}
|
|
3008
|
+
continue;
|
|
3009
|
+
}
|
|
3010
|
+
if (isRecent) {
|
|
3011
|
+
existingBetweenActors.push({
|
|
3012
|
+
candidateUserId: candidateUserId,
|
|
3013
|
+
networkId: existingIndexId,
|
|
3014
|
+
existingOpportunityId: existing.id,
|
|
3015
|
+
existingStatus: existing.status,
|
|
3016
|
+
reason: 'same_trigger_recent_duplicate',
|
|
3017
|
+
existingTriggerIntentId: ownedIntentTriggerId,
|
|
3018
|
+
});
|
|
3019
|
+
persistDedupLog.info('Suppressing recent same-trigger duplicate', {
|
|
3020
|
+
triggerIntentId: ownedIntentTriggerId,
|
|
3021
|
+
candidateUserId,
|
|
3022
|
+
existingOpportunityId: existing.id,
|
|
3023
|
+
existingTriggerIntentId: ownedIntentTriggerId,
|
|
3024
|
+
existingStatus: existing.status,
|
|
3025
|
+
existingAgeMs: Date.now() - new Date(existing.createdAt).getTime(),
|
|
3026
|
+
reason: 'same_trigger_recent_duplicate',
|
|
3027
|
+
});
|
|
3028
|
+
continue;
|
|
3029
|
+
}
|
|
3030
|
+
persistDedupLog.info('Allowing same-trigger opportunity outside dedup window', {
|
|
3031
|
+
triggerIntentId: ownedIntentTriggerId,
|
|
3032
|
+
candidateUserId,
|
|
3033
|
+
existingOpportunityId: existing.id,
|
|
3034
|
+
existingStatus: existing.status,
|
|
3035
|
+
existingAgeMs: Date.now() - new Date(existing.createdAt).getTime(),
|
|
3036
|
+
});
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
else if (overlapping.length > 0) {
|
|
2887
3040
|
const existing = overlapping[0];
|
|
2888
3041
|
const existingIndexId = (existing.context?.networkId ?? state.networkId ?? state.userNetworks?.[0] ?? '');
|
|
2889
3042
|
const isRecent = new Date(existing.createdAt).getTime() > Date.now() - DEDUP_WINDOW_MS;
|
|
@@ -3076,12 +3229,42 @@ export class OpportunityGraphFactory {
|
|
|
3076
3229
|
}
|
|
3077
3230
|
}
|
|
3078
3231
|
}
|
|
3079
|
-
const
|
|
3232
|
+
const intentDedupScope = finalTriggerIntentId && state.discoverySource === 'intent'
|
|
3233
|
+
? { triggerIntentId: finalTriggerIntentId, dedupWindowMs: DEDUP_WINDOW_MS }
|
|
3234
|
+
: undefined;
|
|
3235
|
+
const { created: createdList, conflicts } = await persistOpportunities({
|
|
3080
3236
|
database: this.database,
|
|
3081
3237
|
embedder: this.embedder,
|
|
3082
3238
|
items: itemsForPersistence,
|
|
3083
3239
|
networkEligibility,
|
|
3240
|
+
intentDedupScope,
|
|
3084
3241
|
});
|
|
3242
|
+
for (const conflict of conflicts) {
|
|
3243
|
+
const item = itemsForPersistence[conflict.itemIndex];
|
|
3244
|
+
const candidateActor = item?.actors.find((actor) => actor.userId !== state.userId);
|
|
3245
|
+
if (!candidateActor)
|
|
3246
|
+
continue;
|
|
3247
|
+
existingBetweenActors.push({
|
|
3248
|
+
candidateUserId: candidateActor.userId,
|
|
3249
|
+
networkId: candidateActor.networkId,
|
|
3250
|
+
existingOpportunityId: conflict.existingOpportunityId,
|
|
3251
|
+
existingStatus: conflict.existingStatus,
|
|
3252
|
+
reason: conflict.reason,
|
|
3253
|
+
...(conflict.existingTriggerIntentId
|
|
3254
|
+
? { existingTriggerIntentId: conflict.existingTriggerIntentId }
|
|
3255
|
+
: {}),
|
|
3256
|
+
});
|
|
3257
|
+
persistDedupLog.info('Final atomic persistence conflict', {
|
|
3258
|
+
triggerIntentId: finalTriggerIntentId,
|
|
3259
|
+
candidateUserId: candidateActor.userId,
|
|
3260
|
+
existingOpportunityId: conflict.existingOpportunityId,
|
|
3261
|
+
existingTriggerIntentId: conflict.existingTriggerIntentId,
|
|
3262
|
+
existingStatus: conflict.existingStatus,
|
|
3263
|
+
existingAgeMs: Date.now() - new Date(conflict.existingCreatedAt).getTime(),
|
|
3264
|
+
reason: conflict.reason,
|
|
3265
|
+
finalAtomic: true,
|
|
3266
|
+
});
|
|
3267
|
+
}
|
|
3085
3268
|
const allOpportunities = [...reactivatedOpportunities, ...createdList];
|
|
3086
3269
|
persistLog.verbose('Persistence complete', {
|
|
3087
3270
|
created: createdList.length,
|
|
@@ -3089,10 +3272,20 @@ export class OpportunityGraphFactory {
|
|
|
3089
3272
|
existingBetweenActorsCount: existingBetweenActors.length,
|
|
3090
3273
|
status: initialStatus,
|
|
3091
3274
|
});
|
|
3275
|
+
const persistenceOutcome = {
|
|
3276
|
+
evaluatedCount: state.evaluatedOpportunities.length,
|
|
3277
|
+
createdCount: createdList.length,
|
|
3278
|
+
reactivatedCount: reactivatedOpportunities.length,
|
|
3279
|
+
sameTriggerDuplicateSuppressions: existingBetweenActors.filter((entry) => entry.reason === 'same_trigger_recent_duplicate').length,
|
|
3280
|
+
pairActiveNegotiationSuppressions: existingBetweenActors.filter((entry) => entry.reason === 'pair_active_negotiation').length,
|
|
3281
|
+
crossTriggerAllowedCount,
|
|
3282
|
+
finalAtomicConflictCount: conflicts.length,
|
|
3283
|
+
};
|
|
3092
3284
|
return {
|
|
3093
3285
|
opportunities: allOpportunities,
|
|
3094
3286
|
existingBetweenActors,
|
|
3095
3287
|
dedupAlreadyAccepted,
|
|
3288
|
+
persistenceOutcome,
|
|
3096
3289
|
trace: [{
|
|
3097
3290
|
node: "persist",
|
|
3098
3291
|
detail: `Created ${createdList.length}, reactivated ${reactivatedOpportunities.length}, ${existingBetweenActors.length} existing skipped, ${dedupAlreadyAccepted.length} already-accepted pair(s)`,
|
|
@@ -3102,6 +3295,7 @@ export class OpportunityGraphFactory {
|
|
|
3102
3295
|
existingSkipped: existingBetweenActors.length,
|
|
3103
3296
|
alreadyAccepted: dedupAlreadyAccepted.length,
|
|
3104
3297
|
totalOutput: allOpportunities.length,
|
|
3298
|
+
persistenceOutcome,
|
|
3105
3299
|
durationMs: Date.now() - startTime,
|
|
3106
3300
|
},
|
|
3107
3301
|
}],
|