@indexnetwork/protocol 6.13.22-rc.405.1 → 6.14.0-rc.406.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 +9 -0
- package/dist/negotiation/application/negotiation.graph.d.ts +2 -0
- package/dist/negotiation/application/negotiation.graph.js +4 -3
- package/dist/opportunity/application/opportunity.existing-negotiation.d.ts +3 -1
- package/dist/opportunity/application/opportunity.existing-negotiation.js +15 -6
- package/dist/opportunity/application/opportunity.graph.js +19 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,15 @@ See [STABILITY.md](./STABILITY.md) for the public-contract and tier definitions.
|
|
|
12
12
|
|
|
13
13
|
## [Unreleased]
|
|
14
14
|
|
|
15
|
+
## [6.14.0] — 2026-07-25
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Add `NEGOTIATION_INCLUDE_OTHER_INTENTS` (IND-571), a strict boolean
|
|
19
|
+
deployment policy for autonomous opportunity negotiation. The default
|
|
20
|
+
preserves exact-first bounded active-intent context; `false` isolates each
|
|
21
|
+
participant to its exact opportunity-bound intent across fresh and
|
|
22
|
+
continuation negotiation contexts.
|
|
23
|
+
|
|
15
24
|
## [6.13.22] — 2026-07-25
|
|
16
25
|
|
|
17
26
|
### Added
|
|
@@ -593,6 +593,8 @@ export interface NegotiationCandidate {
|
|
|
593
593
|
/** Exact opportunity-bound source and candidate intent IDs. */
|
|
594
594
|
sourceIntentId?: string;
|
|
595
595
|
candidateIntentId?: string;
|
|
596
|
+
/** Per-opportunity source context when its exact actor intent differs across a fan-out. */
|
|
597
|
+
sourceUser?: UserNegotiationContext;
|
|
596
598
|
reasoning: string;
|
|
597
599
|
valencyRole: string;
|
|
598
600
|
networkId?: string;
|
|
@@ -1249,15 +1249,16 @@ export async function negotiateCandidates(negotiationGraph, sourceUser, candidat
|
|
|
1249
1249
|
const emitWide = (event) => traceEmitter?.(event);
|
|
1250
1250
|
const results = await Promise.all(candidates.map(async (candidate) => {
|
|
1251
1251
|
const start = Date.now();
|
|
1252
|
+
const candidateSourceUser = candidate.sourceUser ?? sourceUser;
|
|
1252
1253
|
if (candidate.opportunityId) {
|
|
1253
1254
|
const candidateName = candidate.candidateUser?.profile?.name;
|
|
1254
1255
|
emitWide({
|
|
1255
1256
|
type: "negotiation_session_start",
|
|
1256
1257
|
opportunityId: candidate.opportunityId,
|
|
1257
1258
|
negotiationConversationId: "", // filled in on session_end
|
|
1258
|
-
sourceUserId:
|
|
1259
|
+
sourceUserId: candidateSourceUser.id,
|
|
1259
1260
|
candidateUserId: candidate.userId,
|
|
1260
|
-
initiatorUserId: initiatorUserId ??
|
|
1261
|
+
initiatorUserId: initiatorUserId ?? candidateSourceUser.id,
|
|
1261
1262
|
...(candidateName && { candidateName }),
|
|
1262
1263
|
trigger: trigger ?? "ambient",
|
|
1263
1264
|
startedAt: start,
|
|
@@ -1269,7 +1270,7 @@ export async function negotiateCandidates(negotiationGraph, sourceUser, candidat
|
|
|
1269
1270
|
? { networkId: candidate.networkId, prompt: indexContextOverrides?.get(candidate.networkId) ?? '' }
|
|
1270
1271
|
: indexContext;
|
|
1271
1272
|
const result = await invokeWithAbortSignal(negotiationGraph, {
|
|
1272
|
-
sourceUser,
|
|
1273
|
+
sourceUser: candidateSourceUser,
|
|
1273
1274
|
candidateUser: candidate.candidateUser,
|
|
1274
1275
|
...(candidate.sourceIntentId && { sourceIntentId: candidate.sourceIntentId }),
|
|
1275
1276
|
...(candidate.candidateIntentId && { candidateIntentId: candidate.candidateIntentId }),
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { NegotiationContinuationExecution, NegotiationContinuationReceipt, Opportunity, OpportunityGraphDatabase } from '../../shared/interfaces/database.interface.js';
|
|
2
2
|
import type { QueueOpportunityNotificationFn } from './opportunity.lifecycle.js';
|
|
3
|
+
/** Default-compatible deployment policy for autonomous opportunity negotiation. */
|
|
4
|
+
export declare function negotiationIncludesOtherIntents(): boolean;
|
|
3
5
|
interface NegotiationIntentSource {
|
|
4
6
|
id?: string | null;
|
|
5
7
|
summary?: string | null;
|
|
@@ -34,7 +36,7 @@ interface ExistingOpportunityNegotiationCandidate {
|
|
|
34
36
|
candidateUser: ExistingOpportunityNegotiationUser;
|
|
35
37
|
}
|
|
36
38
|
/** Put an opportunity actor's exact intent first, then fill the bounded context without duplicates. */
|
|
37
|
-
export declare function buildPrioritizedNegotiationIntents(activeIntents: readonly NegotiationIntentSource[], exactIntentId?: string | null, fallbackIntent?: NegotiationIntentSource | null): ExistingOpportunityNegotiationUser['intents'];
|
|
39
|
+
export declare function buildPrioritizedNegotiationIntents(activeIntents: readonly NegotiationIntentSource[], exactIntentId?: string | null, fallbackIntent?: NegotiationIntentSource | null, includeOtherIntents?: boolean): ExistingOpportunityNegotiationUser['intents'];
|
|
38
40
|
/** Narrow port for translating one persisted opportunity into a negotiation invocation. */
|
|
39
41
|
export type ExistingOpportunityNegotiationPort = Pick<OpportunityGraphDatabase, 'getActiveIntents' | 'getIntent' | 'getNetworkMemberContext' | 'getOpportunity' | 'getProfile' | 'getUser'>;
|
|
40
42
|
export interface ExistingOpportunityNegotiationInput {
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { resolveOpportunityActorIntent } from '../domain/opportunity.actor.js';
|
|
2
2
|
const NEGOTIATION_INTENT_LIMIT = 5;
|
|
3
|
+
/** Default-compatible deployment policy for autonomous opportunity negotiation. */
|
|
4
|
+
export function negotiationIncludesOtherIntents() {
|
|
5
|
+
return process.env.NEGOTIATION_INCLUDE_OTHER_INTENTS !== 'false';
|
|
6
|
+
}
|
|
3
7
|
/** Put an opportunity actor's exact intent first, then fill the bounded context without duplicates. */
|
|
4
|
-
export function buildPrioritizedNegotiationIntents(activeIntents, exactIntentId, fallbackIntent) {
|
|
8
|
+
export function buildPrioritizedNegotiationIntents(activeIntents, exactIntentId, fallbackIntent, includeOtherIntents = true) {
|
|
5
9
|
const exactId = typeof exactIntentId === 'string' && exactIntentId.trim().length > 0 ? exactIntentId : null;
|
|
6
10
|
const exactActive = exactId ? activeIntents.find((intent) => intent.id === exactId) : undefined;
|
|
7
11
|
const ordered = [
|
|
8
12
|
...(exactActive ? [exactActive] : []),
|
|
9
13
|
...(!exactActive && fallbackIntent?.id === exactId ? [fallbackIntent] : []),
|
|
10
|
-
...activeIntents,
|
|
14
|
+
...(includeOtherIntents ? activeIntents : []),
|
|
11
15
|
];
|
|
12
16
|
const seen = new Set();
|
|
13
17
|
const intents = [];
|
|
@@ -51,13 +55,18 @@ export async function negotiateExistingOpportunity(database, executeNegotiation,
|
|
|
51
55
|
return { kind: 'skipped', reason: 'no_candidate_actor' };
|
|
52
56
|
const sourceIntentId = resolveOpportunityActorIntent(sourceActor);
|
|
53
57
|
const candidateIntentId = resolveOpportunityActorIntent(candidateActor);
|
|
58
|
+
const includeOtherIntents = negotiationIncludesOtherIntents();
|
|
54
59
|
const [sourceAccount, sourceProfile, sourceIntents, candidateAccount, candidateProfile, candidateIntents] = await Promise.all([
|
|
55
60
|
database.getUser(sourceActor.userId).catch(() => null),
|
|
56
61
|
database.getProfile(sourceActor.userId).catch(() => null),
|
|
57
|
-
|
|
62
|
+
includeOtherIntents
|
|
63
|
+
? database.getActiveIntents(sourceActor.userId).catch(() => [])
|
|
64
|
+
: Promise.resolve([]),
|
|
58
65
|
database.getUser(candidateActor.userId).catch(() => null),
|
|
59
66
|
database.getProfile(candidateActor.userId).catch(() => null),
|
|
60
|
-
|
|
67
|
+
includeOtherIntents
|
|
68
|
+
? database.getActiveIntents(candidateActor.userId).catch(() => [])
|
|
69
|
+
: Promise.resolve([]),
|
|
61
70
|
]);
|
|
62
71
|
const [sourceFallbackIntent, candidateFallbackIntent] = await Promise.all([
|
|
63
72
|
sourceIntentId && !sourceIntents.some((intent) => intent.id === sourceIntentId) ? database.getIntent(sourceIntentId).catch(() => null) : null,
|
|
@@ -65,7 +74,7 @@ export async function negotiateExistingOpportunity(database, executeNegotiation,
|
|
|
65
74
|
]);
|
|
66
75
|
const sourceUser = {
|
|
67
76
|
id: sourceActor.userId,
|
|
68
|
-
intents: buildPrioritizedNegotiationIntents(sourceIntents, sourceIntentId, sourceFallbackIntent?.userId === sourceActor.userId ? sourceFallbackIntent : null),
|
|
77
|
+
intents: buildPrioritizedNegotiationIntents(sourceIntents, sourceIntentId, sourceFallbackIntent?.userId === sourceActor.userId ? sourceFallbackIntent : null, includeOtherIntents),
|
|
69
78
|
profile: {
|
|
70
79
|
name: sourceProfile?.identity?.name ?? sourceAccount?.name,
|
|
71
80
|
bio: sourceProfile?.identity?.bio ?? sourceAccount?.intro ?? undefined,
|
|
@@ -84,7 +93,7 @@ export async function negotiateExistingOpportunity(database, executeNegotiation,
|
|
|
84
93
|
networkId: candidateActor.networkId,
|
|
85
94
|
candidateUser: {
|
|
86
95
|
id: candidateActor.userId,
|
|
87
|
-
intents: buildPrioritizedNegotiationIntents(candidateIntents, candidateIntentId, candidateFallbackIntent?.userId === candidateActor.userId ? candidateFallbackIntent : null),
|
|
96
|
+
intents: buildPrioritizedNegotiationIntents(candidateIntents, candidateIntentId, candidateFallbackIntent?.userId === candidateActor.userId ? candidateFallbackIntent : null, includeOtherIntents),
|
|
88
97
|
profile: {
|
|
89
98
|
name: candidateProfile?.identity?.name ?? candidateAccount?.name,
|
|
90
99
|
bio: candidateProfile?.identity?.bio ?? candidateAccount?.intro ?? undefined,
|
|
@@ -34,7 +34,7 @@ import { mergeOpportunityEvidence, withCandidateEvidence, withMatchedStrategies
|
|
|
34
34
|
import { normalizeOpportunityActorIntent, resolveOpportunityActorIntent } from '../domain/opportunity.actor.js';
|
|
35
35
|
import { approveOpportunityIntroduction, deleteOpportunityLifecycle, sendOpportunityLifecycle, updateOpportunityLifecycle } from './opportunity.lifecycle.js';
|
|
36
36
|
import { stampEligibleNewbornOpportunities } from './opportunity.newborn-stamping.js';
|
|
37
|
-
import { buildPrioritizedNegotiationIntents, negotiateExistingOpportunity } from './opportunity.existing-negotiation.js';
|
|
37
|
+
import { buildPrioritizedNegotiationIntents, negotiateExistingOpportunity, negotiationIncludesOtherIntents } from './opportunity.existing-negotiation.js';
|
|
38
38
|
import { admitOpportunityPersistence, createEligibleOpportunityStatusUpdater } from './opportunity.persistence-admission.js';
|
|
39
39
|
export { buildPrioritizedNegotiationIntents } from './opportunity.existing-negotiation.js';
|
|
40
40
|
const logger = protocolLogger('OpportunityGraph');
|
|
@@ -1878,6 +1878,7 @@ export class OpportunityGraphFactory {
|
|
|
1878
1878
|
try {
|
|
1879
1879
|
// Use the same discoveryUserId pattern as evaluationNode
|
|
1880
1880
|
const discoveryUserId = (state.onBehalfOfUserId ?? state.userId);
|
|
1881
|
+
const includeOtherIntents = negotiationIncludesOtherIntents();
|
|
1881
1882
|
const sourceAccount = await this.database.getUser(discoveryUserId).catch(() => null);
|
|
1882
1883
|
const sourceIntentInputs = (state.indexedIntents ?? []).map((intent) => ({
|
|
1883
1884
|
id: intent.intentId,
|
|
@@ -1893,7 +1894,7 @@ export class OpportunityGraphFactory {
|
|
|
1893
1894
|
: null;
|
|
1894
1895
|
const sourceUser = {
|
|
1895
1896
|
id: discoveryUserId,
|
|
1896
|
-
intents: buildPrioritizedNegotiationIntents(sourceIntentInputs, state.triggerIntentId, ownedSourceFallback),
|
|
1897
|
+
intents: buildPrioritizedNegotiationIntents(sourceIntentInputs, state.triggerIntentId, ownedSourceFallback, includeOtherIntents),
|
|
1897
1898
|
profile: {
|
|
1898
1899
|
name: state.sourceProfile?.identity?.name ?? sourceAccount?.name,
|
|
1899
1900
|
bio: state.sourceProfile?.identity?.bio ?? sourceAccount?.intro ?? undefined,
|
|
@@ -1945,20 +1946,33 @@ export class OpportunityGraphFactory {
|
|
|
1945
1946
|
const userId = candidateActor.userId;
|
|
1946
1947
|
const sourceIntentId = resolveOpportunityActorIntent(sourceActor);
|
|
1947
1948
|
const candidateIntentId = resolveOpportunityActorIntent(candidateActor);
|
|
1948
|
-
const
|
|
1949
|
+
const sourceExactActive = sourceIntentId
|
|
1950
|
+
? sourceIntentInputs.find((sourceIntent) => sourceIntent.id === sourceIntentId)
|
|
1951
|
+
: undefined;
|
|
1952
|
+
const [profile, user, activeIntents, intent, sourceIntent] = await Promise.all([
|
|
1949
1953
|
this.database.getProfile(userId).catch(() => null),
|
|
1950
1954
|
this.database.getUser(userId).catch(() => null),
|
|
1951
|
-
|
|
1955
|
+
includeOtherIntents
|
|
1956
|
+
? this.database.getActiveIntents(userId).catch(() => [])
|
|
1957
|
+
: Promise.resolve([]),
|
|
1952
1958
|
candidateIntentId
|
|
1953
1959
|
? this.database.getIntent(candidateIntentId).catch(() => null)
|
|
1954
1960
|
: null,
|
|
1961
|
+
sourceIntentId && !sourceExactActive
|
|
1962
|
+
? this.database.getIntent(sourceIntentId).catch(() => null)
|
|
1963
|
+
: null,
|
|
1955
1964
|
]);
|
|
1956
1965
|
const ownedFallbackIntent = intent?.userId === userId ? intent : null;
|
|
1957
|
-
const
|
|
1966
|
+
const ownedSourceIntent = sourceIntent?.userId === discoveryUserId ? sourceIntent : null;
|
|
1967
|
+
const candidateIntents = buildPrioritizedNegotiationIntents(activeIntents, candidateIntentId, ownedFallbackIntent, includeOtherIntents);
|
|
1958
1968
|
return {
|
|
1959
1969
|
userId,
|
|
1960
1970
|
...(sourceIntentId ? { sourceIntentId } : {}),
|
|
1961
1971
|
...(candidateIntentId ? { candidateIntentId } : {}),
|
|
1972
|
+
sourceUser: {
|
|
1973
|
+
...sourceUser,
|
|
1974
|
+
intents: buildPrioritizedNegotiationIntents(sourceIntentInputs, sourceIntentId, ownedSourceIntent, includeOtherIntents),
|
|
1975
|
+
},
|
|
1962
1976
|
opportunityId: opp.id,
|
|
1963
1977
|
opportunityStatus: opp.status,
|
|
1964
1978
|
opportunityUpdatedAt: opp.updatedAt,
|