@indexnetwork/protocol 6.2.1-rc.378.1 → 6.2.3-rc.380.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.
Files changed (33) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/dist/negotiation/negotiation.graph.d.ts +7 -0
  3. package/dist/negotiation/negotiation.graph.d.ts.map +1 -1
  4. package/dist/negotiation/negotiation.graph.js +18 -3
  5. package/dist/negotiation/negotiation.graph.js.map +1 -1
  6. package/dist/negotiation/negotiation.state.d.ts +4 -0
  7. package/dist/negotiation/negotiation.state.d.ts.map +1 -1
  8. package/dist/negotiation/negotiation.state.js +5 -0
  9. package/dist/negotiation/negotiation.state.js.map +1 -1
  10. package/dist/opportunity/opportunity.actor.d.ts +16 -0
  11. package/dist/opportunity/opportunity.actor.d.ts.map +1 -0
  12. package/dist/opportunity/opportunity.actor.js +40 -0
  13. package/dist/opportunity/opportunity.actor.js.map +1 -0
  14. package/dist/opportunity/opportunity.discover.d.ts.map +1 -1
  15. package/dist/opportunity/opportunity.discover.js +15 -5
  16. package/dist/opportunity/opportunity.discover.js.map +1 -1
  17. package/dist/opportunity/opportunity.evaluator.d.ts +3 -3
  18. package/dist/opportunity/opportunity.evaluator.d.ts.map +1 -1
  19. package/dist/opportunity/opportunity.evaluator.js +4 -1
  20. package/dist/opportunity/opportunity.evaluator.js.map +1 -1
  21. package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
  22. package/dist/opportunity/opportunity.graph.js +125 -71
  23. package/dist/opportunity/opportunity.graph.js.map +1 -1
  24. package/dist/opportunity/opportunity.persist.d.ts.map +1 -1
  25. package/dist/opportunity/opportunity.persist.js +4 -2
  26. package/dist/opportunity/opportunity.persist.js.map +1 -1
  27. package/dist/opportunity/opportunity.tools.d.ts.map +1 -1
  28. package/dist/opportunity/opportunity.tools.js +34 -3
  29. package/dist/opportunity/opportunity.tools.js.map +1 -1
  30. package/dist/shared/interfaces/database.interface.d.ts +39 -5
  31. package/dist/shared/interfaces/database.interface.d.ts.map +1 -1
  32. package/dist/shared/interfaces/database.interface.js.map +1 -1
  33. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -41,6 +41,8 @@ See [STABILITY.md](./STABILITY.md) for the public-contract and tier definitions.
41
41
  - Included protocol documentation files in the published package tarball so README links remain available to package consumers.
42
42
 
43
43
  ### Fixed
44
+ - Routed continuation-created and recovered opportunities through the normal negotiation boundary, threaded each persisted attempt version into atomic negotiation-task claiming, protected active/input-required tasks from duplicate negotiation, compensated pre-task failures and timeouts to truthful draft/latent states, and refreshed continuation cards from current lifecycle state (IND-470).
45
+ - Normalized opportunity actor intent IDs at evaluator, graph, and shared persistence boundaries so blank or null-like model sentinels are omitted, valid branded string IDs remain supported, enrichment cannot use or reintroduce malformed provenance, and legacy negotiation reads fail closed (IND-469).
44
46
  - Forwarded per-attempt `AbortSignal`s through eval provider paths and hardened failure provenance against secret leakage, hostile rejection objects, classifier failures, and concurrent artifact writers (IND-444).
45
47
  - Aligned HyDE evidence scoring with the live background `0.30` cutoff, retained per-lens cosines for score/ranking revalidation, required report-stage parent recomputation, and prevented forced outputs from overwriting input evidence artifacts (IND-426).
46
48
  - Scoped pool-question adjustments to the exact answering recipient and selected intent, ignored legacy unscoped factors, and restricted Tier-0/newborn writes to exact trigger-intent provenance so shared opportunities cannot re-rank another viewer or intent.
@@ -37,6 +37,7 @@ export declare class NegotiationGraphFactory {
37
37
  memoryBySide: Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>>;
38
38
  isContinuation: boolean;
39
39
  opportunityId: string;
40
+ opportunityUpdatedAt: Date | undefined;
40
41
  conversationId: string;
41
42
  taskId: string;
42
43
  messages: import("./negotiation.state.js").NegotiationMessage[];
@@ -92,6 +93,7 @@ export declare class NegotiationGraphFactory {
92
93
  memoryBySide?: Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>> | import("@langchain/langgraph").OverwriteValue<Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>>> | undefined;
93
94
  isContinuation?: boolean | import("@langchain/langgraph").OverwriteValue<boolean> | undefined;
94
95
  opportunityId?: string | import("@langchain/langgraph").OverwriteValue<string> | undefined;
96
+ opportunityUpdatedAt?: Date | import("@langchain/langgraph").OverwriteValue<Date | undefined> | undefined;
95
97
  conversationId?: string | import("@langchain/langgraph").OverwriteValue<string> | undefined;
96
98
  taskId?: string | import("@langchain/langgraph").OverwriteValue<string> | undefined;
97
99
  messages?: import("./negotiation.state.js").NegotiationMessage[] | import("@langchain/langgraph").OverwriteValue<import("./negotiation.state.js").NegotiationMessage[]> | undefined;
@@ -173,6 +175,7 @@ export declare class NegotiationGraphFactory {
173
175
  memoryBySide: import("@langchain/langgraph").BaseChannel<Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>>, Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>> | import("@langchain/langgraph").OverwriteValue<Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>>>, unknown>;
174
176
  isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
175
177
  opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
178
+ opportunityUpdatedAt: import("@langchain/langgraph").BaseChannel<Date | undefined, Date | import("@langchain/langgraph").OverwriteValue<Date | undefined> | undefined, unknown>;
176
179
  conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
177
180
  taskId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
178
181
  messages: import("@langchain/langgraph").BaseChannel<import("./negotiation.state.js").NegotiationMessage[], import("./negotiation.state.js").NegotiationMessage[] | import("@langchain/langgraph").OverwriteValue<import("./negotiation.state.js").NegotiationMessage[]>, unknown>;
@@ -277,6 +280,7 @@ export declare class NegotiationGraphFactory {
277
280
  memoryBySide: import("@langchain/langgraph").BaseChannel<Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>>, Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>> | import("@langchain/langgraph").OverwriteValue<Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>>>, unknown>;
278
281
  isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
279
282
  opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
283
+ opportunityUpdatedAt: import("@langchain/langgraph").BaseChannel<Date | undefined, Date | import("@langchain/langgraph").OverwriteValue<Date | undefined> | undefined, unknown>;
280
284
  conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
281
285
  taskId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
282
286
  messages: import("@langchain/langgraph").BaseChannel<import("./negotiation.state.js").NegotiationMessage[], import("./negotiation.state.js").NegotiationMessage[] | import("@langchain/langgraph").OverwriteValue<import("./negotiation.state.js").NegotiationMessage[]>, unknown>;
@@ -410,6 +414,7 @@ export declare class NegotiationGraphFactory {
410
414
  memoryBySide: import("@langchain/langgraph").BaseChannel<Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>>, Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>> | import("@langchain/langgraph").OverwriteValue<Partial<Record<"source" | "candidate", NegotiatorMemoryEntry[]>>>, unknown>;
411
415
  isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
412
416
  opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
417
+ opportunityUpdatedAt: import("@langchain/langgraph").BaseChannel<Date | undefined, Date | import("@langchain/langgraph").OverwriteValue<Date | undefined> | undefined, unknown>;
413
418
  conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
414
419
  taskId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
415
420
  messages: import("@langchain/langgraph").BaseChannel<import("./negotiation.state.js").NegotiationMessage[], import("./negotiation.state.js").NegotiationMessage[] | import("@langchain/langgraph").OverwriteValue<import("./negotiation.state.js").NegotiationMessage[]>, unknown>;
@@ -525,6 +530,8 @@ export interface NegotiationCandidate {
525
530
  * (`accept` → 'pending', `reject` → 'rejected', otherwise → 'stalled').
526
531
  */
527
532
  opportunityId?: string;
533
+ /** Exact persisted lifecycle version claimed by this negotiation attempt. */
534
+ opportunityUpdatedAt?: Date;
528
535
  }
529
536
  export interface NegotiationResult {
530
537
  userId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"negotiation.graph.d.ts","sourceRoot":"/","sources":["negotiation/negotiation.graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"negotiation.graph.d.ts","sourceRoot":"/","sources":["negotiation/negotiation.graph.ts"],"names":[],"mappings":"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"}
@@ -220,7 +220,7 @@ export class NegotiationGraphFactory {
220
220
  else {
221
221
  protocolVersion = configuredProtocolVersion();
222
222
  }
223
- const task = await database.createTask(conversation.id, {
223
+ const taskMetadata = {
224
224
  type: 'negotiation',
225
225
  sourceUserId: state.sourceUser.id,
226
226
  initiatorUserId,
@@ -232,8 +232,22 @@ export class NegotiationGraphFactory {
232
232
  maxTurns,
233
233
  isContinuation,
234
234
  priorTurnCount: priorTurns.length,
235
- });
236
- if (state.opportunityId) {
235
+ };
236
+ const task = state.opportunityId && state.opportunityUpdatedAt
237
+ ? await database.createNegotiationTaskForAttempt({
238
+ conversationId: conversation.id,
239
+ opportunityId: state.opportunityId,
240
+ expectedUpdatedAt: state.opportunityUpdatedAt,
241
+ metadata: taskMetadata,
242
+ })
243
+ : await database.createTask(conversation.id, taskMetadata);
244
+ if (!task) {
245
+ throw new Error('Negotiation attempt is stale or already claimed');
246
+ }
247
+ // Attempt-bound discovery already persisted `negotiating` and the atomic
248
+ // task claim verified that exact version. Legacy/direct invocations with
249
+ // only an opportunity ID retain the prior best-effort status update.
250
+ if (state.opportunityId && !state.opportunityUpdatedAt) {
237
251
  await database.updateOpportunityStatus(state.opportunityId, 'negotiating').catch((err) => {
238
252
  initLog.error('Failed to set opportunity status to negotiating', { opportunityId: state.opportunityId, error: err });
239
253
  });
@@ -980,6 +994,7 @@ export async function negotiateCandidates(negotiationGraph, sourceUser, candidat
980
994
  },
981
995
  ...(candidate.discoveryQuery && { discoveryQuery: candidate.discoveryQuery }),
982
996
  ...(candidate.opportunityId && { opportunityId: candidate.opportunityId }),
997
+ ...(candidate.opportunityUpdatedAt && { opportunityUpdatedAt: candidate.opportunityUpdatedAt }),
983
998
  ...(initiatorUserId && { initiatorUserId }),
984
999
  ...(maxTurns !== undefined && { maxTurns }),
985
1000
  ...(timeoutMs !== undefined && { timeoutMs }),