@indexnetwork/protocol 4.5.0-rc.332.1 → 4.5.0-rc.333.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 (43) hide show
  1. package/dist/chat/chat-streaming.types.d.ts +1 -1
  2. package/dist/chat/chat-streaming.types.d.ts.map +1 -1
  3. package/dist/chat/chat-streaming.types.js.map +1 -1
  4. package/dist/chat/chat.agent.d.ts +1 -1
  5. package/dist/chat/chat.agent.d.ts.map +1 -1
  6. package/dist/chat/chat.agent.js.map +1 -1
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +3 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/negotiation/negotiation.agent.d.ts +21 -0
  12. package/dist/negotiation/negotiation.agent.d.ts.map +1 -1
  13. package/dist/negotiation/negotiation.agent.js +79 -11
  14. package/dist/negotiation/negotiation.agent.js.map +1 -1
  15. package/dist/negotiation/negotiation.graph.d.ts +37 -24
  16. package/dist/negotiation/negotiation.graph.d.ts.map +1 -1
  17. package/dist/negotiation/negotiation.graph.js +68 -17
  18. package/dist/negotiation/negotiation.graph.js.map +1 -1
  19. package/dist/negotiation/negotiation.protocol.d.ts +287 -0
  20. package/dist/negotiation/negotiation.protocol.d.ts.map +1 -0
  21. package/dist/negotiation/negotiation.protocol.js +152 -0
  22. package/dist/negotiation/negotiation.protocol.js.map +1 -0
  23. package/dist/negotiation/negotiation.state.d.ts +21 -9
  24. package/dist/negotiation/negotiation.state.d.ts.map +1 -1
  25. package/dist/negotiation/negotiation.state.js +19 -4
  26. package/dist/negotiation/negotiation.state.js.map +1 -1
  27. package/dist/negotiation/negotiation.tools.d.ts.map +1 -1
  28. package/dist/negotiation/negotiation.tools.js +86 -31
  29. package/dist/negotiation/negotiation.tools.js.map +1 -1
  30. package/dist/opportunity/question.prompt.d.ts +1 -1
  31. package/dist/opportunity/question.prompt.d.ts.map +1 -1
  32. package/dist/opportunity/question.prompt.js.map +1 -1
  33. package/dist/shared/interfaces/agent-dispatcher.interface.d.ts +6 -0
  34. package/dist/shared/interfaces/agent-dispatcher.interface.d.ts.map +1 -1
  35. package/dist/shared/interfaces/agent-dispatcher.interface.js.map +1 -1
  36. package/dist/shared/schemas/discovery-question.schema.d.ts +8 -8
  37. package/dist/shared/schemas/discovery-question.schema.js +1 -1
  38. package/dist/shared/schemas/discovery-question.schema.js.map +1 -1
  39. package/dist/shared/schemas/negotiation-state.schema.d.ts +19 -3
  40. package/dist/shared/schemas/negotiation-state.schema.d.ts.map +1 -1
  41. package/dist/shared/schemas/negotiation-state.schema.js +15 -1
  42. package/dist/shared/schemas/negotiation-state.schema.js.map +1 -1
  43. package/package.json +1 -1
@@ -3,6 +3,7 @@ import type { NegotiationGraphDatabase } from "../shared/interfaces/database.int
3
3
  import type { NegotiationTimeoutQueue } from "../shared/interfaces/negotiation-events.interface.js";
4
4
  import type { AgentDispatcher } from "../shared/interfaces/agent-dispatcher.interface.js";
5
5
  import { type NegotiationTurn, type NegotiationOutcome, type UserNegotiationContext, type SeedAssessment, type NegotiationGraphLike } from "./negotiation.state.js";
6
+ import type { NegotiationProtocolVersion } from "../shared/schemas/negotiation-state.schema.js";
6
7
  import type { QuestionerEnqueueFn } from "../questioner/questioner.types.js";
7
8
  /**
8
9
  * Factory for the bilateral negotiation LangGraph state machine.
@@ -24,6 +25,7 @@ export declare class NegotiationGraphFactory {
24
25
  seedAssessment: SeedAssessment;
25
26
  initiatorUserId: string | undefined;
26
27
  discoveryQuery: string | undefined;
28
+ protocolVersion: NegotiationProtocolVersion;
27
29
  isContinuation: boolean;
28
30
  opportunityId: string;
29
31
  conversationId: string;
@@ -34,7 +36,7 @@ export declare class NegotiationGraphFactory {
34
36
  timeoutMs: number;
35
37
  currentSpeaker: "source" | "candidate";
36
38
  lastTurn: {
37
- action: "propose" | "accept" | "reject" | "counter" | "question";
39
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
38
40
  assessment: {
39
41
  reasoning: string;
40
42
  suggestedRoles: {
@@ -71,6 +73,7 @@ export declare class NegotiationGraphFactory {
71
73
  seedAssessment?: SeedAssessment | import("@langchain/langgraph").OverwriteValue<SeedAssessment> | undefined;
72
74
  initiatorUserId?: string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined;
73
75
  discoveryQuery?: string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined;
76
+ protocolVersion?: NegotiationProtocolVersion | import("@langchain/langgraph").OverwriteValue<NegotiationProtocolVersion> | undefined;
74
77
  isContinuation?: boolean | import("@langchain/langgraph").OverwriteValue<boolean> | undefined;
75
78
  opportunityId?: string | import("@langchain/langgraph").OverwriteValue<string> | undefined;
76
79
  conversationId?: string | import("@langchain/langgraph").OverwriteValue<string> | undefined;
@@ -81,7 +84,7 @@ export declare class NegotiationGraphFactory {
81
84
  timeoutMs?: number | import("@langchain/langgraph").OverwriteValue<number> | undefined;
82
85
  currentSpeaker?: "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate"> | undefined;
83
86
  lastTurn?: {
84
- action: "propose" | "accept" | "reject" | "counter" | "question";
87
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
85
88
  assessment: {
86
89
  reasoning: string;
87
90
  suggestedRoles: {
@@ -91,7 +94,7 @@ export declare class NegotiationGraphFactory {
91
94
  };
92
95
  message?: string | null | undefined;
93
96
  } | import("@langchain/langgraph").OverwriteValue<{
94
- action: "propose" | "accept" | "reject" | "counter" | "question";
97
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
95
98
  assessment: {
96
99
  reasoning: string;
97
100
  suggestedRoles: {
@@ -140,6 +143,7 @@ export declare class NegotiationGraphFactory {
140
143
  seedAssessment: import("@langchain/langgraph").BaseChannel<SeedAssessment, SeedAssessment | import("@langchain/langgraph").OverwriteValue<SeedAssessment>, unknown>;
141
144
  initiatorUserId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
142
145
  discoveryQuery: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
146
+ protocolVersion: import("@langchain/langgraph").BaseChannel<NegotiationProtocolVersion, NegotiationProtocolVersion | import("@langchain/langgraph").OverwriteValue<NegotiationProtocolVersion>, unknown>;
143
147
  isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
144
148
  opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
145
149
  conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
@@ -150,7 +154,7 @@ export declare class NegotiationGraphFactory {
150
154
  timeoutMs: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
151
155
  currentSpeaker: import("@langchain/langgraph").BaseChannel<"source" | "candidate", "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate">, unknown>;
152
156
  lastTurn: import("@langchain/langgraph").BaseChannel<{
153
- action: "propose" | "accept" | "reject" | "counter" | "question";
157
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
154
158
  assessment: {
155
159
  reasoning: string;
156
160
  suggestedRoles: {
@@ -160,7 +164,7 @@ export declare class NegotiationGraphFactory {
160
164
  };
161
165
  message?: string | null | undefined;
162
166
  } | null, {
163
- action: "propose" | "accept" | "reject" | "counter" | "question";
167
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
164
168
  assessment: {
165
169
  reasoning: string;
166
170
  suggestedRoles: {
@@ -170,7 +174,7 @@ export declare class NegotiationGraphFactory {
170
174
  };
171
175
  message?: string | null | undefined;
172
176
  } | import("@langchain/langgraph").OverwriteValue<{
173
- action: "propose" | "accept" | "reject" | "counter" | "question";
177
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
174
178
  assessment: {
175
179
  reasoning: string;
176
180
  suggestedRoles: {
@@ -228,6 +232,7 @@ export declare class NegotiationGraphFactory {
228
232
  seedAssessment: import("@langchain/langgraph").BaseChannel<SeedAssessment, SeedAssessment | import("@langchain/langgraph").OverwriteValue<SeedAssessment>, unknown>;
229
233
  initiatorUserId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
230
234
  discoveryQuery: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
235
+ protocolVersion: import("@langchain/langgraph").BaseChannel<NegotiationProtocolVersion, NegotiationProtocolVersion | import("@langchain/langgraph").OverwriteValue<NegotiationProtocolVersion>, unknown>;
231
236
  isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
232
237
  opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
233
238
  conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
@@ -238,7 +243,7 @@ export declare class NegotiationGraphFactory {
238
243
  timeoutMs: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
239
244
  currentSpeaker: import("@langchain/langgraph").BaseChannel<"source" | "candidate", "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate">, unknown>;
240
245
  lastTurn: import("@langchain/langgraph").BaseChannel<{
241
- action: "propose" | "accept" | "reject" | "counter" | "question";
246
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
242
247
  assessment: {
243
248
  reasoning: string;
244
249
  suggestedRoles: {
@@ -248,7 +253,7 @@ export declare class NegotiationGraphFactory {
248
253
  };
249
254
  message?: string | null | undefined;
250
255
  } | null, {
251
- action: "propose" | "accept" | "reject" | "counter" | "question";
256
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
252
257
  assessment: {
253
258
  reasoning: string;
254
259
  suggestedRoles: {
@@ -258,7 +263,7 @@ export declare class NegotiationGraphFactory {
258
263
  };
259
264
  message?: string | null | undefined;
260
265
  } | import("@langchain/langgraph").OverwriteValue<{
261
- action: "propose" | "accept" | "reject" | "counter" | "question";
266
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
262
267
  assessment: {
263
268
  reasoning: string;
264
269
  suggestedRoles: {
@@ -319,6 +324,7 @@ export declare class NegotiationGraphFactory {
319
324
  maxTurns: number;
320
325
  isContinuation: boolean;
321
326
  initiatorUserId: string;
327
+ protocolVersion: NegotiationProtocolVersion;
322
328
  priorTurnCount: number;
323
329
  error?: undefined;
324
330
  };
@@ -338,6 +344,7 @@ export declare class NegotiationGraphFactory {
338
344
  seedAssessment: import("@langchain/langgraph").BaseChannel<SeedAssessment, SeedAssessment | import("@langchain/langgraph").OverwriteValue<SeedAssessment>, unknown>;
339
345
  initiatorUserId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
340
346
  discoveryQuery: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
347
+ protocolVersion: import("@langchain/langgraph").BaseChannel<NegotiationProtocolVersion, NegotiationProtocolVersion | import("@langchain/langgraph").OverwriteValue<NegotiationProtocolVersion>, unknown>;
341
348
  isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
342
349
  opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
343
350
  conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
@@ -348,7 +355,7 @@ export declare class NegotiationGraphFactory {
348
355
  timeoutMs: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
349
356
  currentSpeaker: import("@langchain/langgraph").BaseChannel<"source" | "candidate", "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate">, unknown>;
350
357
  lastTurn: import("@langchain/langgraph").BaseChannel<{
351
- action: "propose" | "accept" | "reject" | "counter" | "question";
358
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
352
359
  assessment: {
353
360
  reasoning: string;
354
361
  suggestedRoles: {
@@ -358,7 +365,7 @@ export declare class NegotiationGraphFactory {
358
365
  };
359
366
  message?: string | null | undefined;
360
367
  } | null, {
361
- action: "propose" | "accept" | "reject" | "counter" | "question";
368
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
362
369
  assessment: {
363
370
  reasoning: string;
364
371
  suggestedRoles: {
@@ -368,7 +375,7 @@ export declare class NegotiationGraphFactory {
368
375
  };
369
376
  message?: string | null | undefined;
370
377
  } | import("@langchain/langgraph").OverwriteValue<{
371
- action: "propose" | "accept" | "reject" | "counter" | "question";
378
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
372
379
  assessment: {
373
380
  reasoning: string;
374
381
  suggestedRoles: {
@@ -507,6 +514,7 @@ export declare function createDefaultNegotiationGraph(deps: {
507
514
  seedAssessment: SeedAssessment;
508
515
  initiatorUserId: string | undefined;
509
516
  discoveryQuery: string | undefined;
517
+ protocolVersion: NegotiationProtocolVersion;
510
518
  isContinuation: boolean;
511
519
  opportunityId: string;
512
520
  conversationId: string;
@@ -517,7 +525,7 @@ export declare function createDefaultNegotiationGraph(deps: {
517
525
  timeoutMs: number;
518
526
  currentSpeaker: "source" | "candidate";
519
527
  lastTurn: {
520
- action: "propose" | "accept" | "reject" | "counter" | "question";
528
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
521
529
  assessment: {
522
530
  reasoning: string;
523
531
  suggestedRoles: {
@@ -554,6 +562,7 @@ export declare function createDefaultNegotiationGraph(deps: {
554
562
  seedAssessment?: SeedAssessment | import("@langchain/langgraph").OverwriteValue<SeedAssessment> | undefined;
555
563
  initiatorUserId?: string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined;
556
564
  discoveryQuery?: string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined;
565
+ protocolVersion?: NegotiationProtocolVersion | import("@langchain/langgraph").OverwriteValue<NegotiationProtocolVersion> | undefined;
557
566
  isContinuation?: boolean | import("@langchain/langgraph").OverwriteValue<boolean> | undefined;
558
567
  opportunityId?: string | import("@langchain/langgraph").OverwriteValue<string> | undefined;
559
568
  conversationId?: string | import("@langchain/langgraph").OverwriteValue<string> | undefined;
@@ -564,7 +573,7 @@ export declare function createDefaultNegotiationGraph(deps: {
564
573
  timeoutMs?: number | import("@langchain/langgraph").OverwriteValue<number> | undefined;
565
574
  currentSpeaker?: "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate"> | undefined;
566
575
  lastTurn?: {
567
- action: "propose" | "accept" | "reject" | "counter" | "question";
576
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
568
577
  assessment: {
569
578
  reasoning: string;
570
579
  suggestedRoles: {
@@ -574,7 +583,7 @@ export declare function createDefaultNegotiationGraph(deps: {
574
583
  };
575
584
  message?: string | null | undefined;
576
585
  } | import("@langchain/langgraph").OverwriteValue<{
577
- action: "propose" | "accept" | "reject" | "counter" | "question";
586
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
578
587
  assessment: {
579
588
  reasoning: string;
580
589
  suggestedRoles: {
@@ -623,6 +632,7 @@ export declare function createDefaultNegotiationGraph(deps: {
623
632
  seedAssessment: import("@langchain/langgraph").BaseChannel<SeedAssessment, SeedAssessment | import("@langchain/langgraph").OverwriteValue<SeedAssessment>, unknown>;
624
633
  initiatorUserId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
625
634
  discoveryQuery: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
635
+ protocolVersion: import("@langchain/langgraph").BaseChannel<NegotiationProtocolVersion, NegotiationProtocolVersion | import("@langchain/langgraph").OverwriteValue<NegotiationProtocolVersion>, unknown>;
626
636
  isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
627
637
  opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
628
638
  conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
@@ -633,7 +643,7 @@ export declare function createDefaultNegotiationGraph(deps: {
633
643
  timeoutMs: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
634
644
  currentSpeaker: import("@langchain/langgraph").BaseChannel<"source" | "candidate", "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate">, unknown>;
635
645
  lastTurn: import("@langchain/langgraph").BaseChannel<{
636
- action: "propose" | "accept" | "reject" | "counter" | "question";
646
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
637
647
  assessment: {
638
648
  reasoning: string;
639
649
  suggestedRoles: {
@@ -643,7 +653,7 @@ export declare function createDefaultNegotiationGraph(deps: {
643
653
  };
644
654
  message?: string | null | undefined;
645
655
  } | null, {
646
- action: "propose" | "accept" | "reject" | "counter" | "question";
656
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
647
657
  assessment: {
648
658
  reasoning: string;
649
659
  suggestedRoles: {
@@ -653,7 +663,7 @@ export declare function createDefaultNegotiationGraph(deps: {
653
663
  };
654
664
  message?: string | null | undefined;
655
665
  } | import("@langchain/langgraph").OverwriteValue<{
656
- action: "propose" | "accept" | "reject" | "counter" | "question";
666
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
657
667
  assessment: {
658
668
  reasoning: string;
659
669
  suggestedRoles: {
@@ -711,6 +721,7 @@ export declare function createDefaultNegotiationGraph(deps: {
711
721
  seedAssessment: import("@langchain/langgraph").BaseChannel<SeedAssessment, SeedAssessment | import("@langchain/langgraph").OverwriteValue<SeedAssessment>, unknown>;
712
722
  initiatorUserId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
713
723
  discoveryQuery: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
724
+ protocolVersion: import("@langchain/langgraph").BaseChannel<NegotiationProtocolVersion, NegotiationProtocolVersion | import("@langchain/langgraph").OverwriteValue<NegotiationProtocolVersion>, unknown>;
714
725
  isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
715
726
  opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
716
727
  conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
@@ -721,7 +732,7 @@ export declare function createDefaultNegotiationGraph(deps: {
721
732
  timeoutMs: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
722
733
  currentSpeaker: import("@langchain/langgraph").BaseChannel<"source" | "candidate", "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate">, unknown>;
723
734
  lastTurn: import("@langchain/langgraph").BaseChannel<{
724
- action: "propose" | "accept" | "reject" | "counter" | "question";
735
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
725
736
  assessment: {
726
737
  reasoning: string;
727
738
  suggestedRoles: {
@@ -731,7 +742,7 @@ export declare function createDefaultNegotiationGraph(deps: {
731
742
  };
732
743
  message?: string | null | undefined;
733
744
  } | null, {
734
- action: "propose" | "accept" | "reject" | "counter" | "question";
745
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
735
746
  assessment: {
736
747
  reasoning: string;
737
748
  suggestedRoles: {
@@ -741,7 +752,7 @@ export declare function createDefaultNegotiationGraph(deps: {
741
752
  };
742
753
  message?: string | null | undefined;
743
754
  } | import("@langchain/langgraph").OverwriteValue<{
744
- action: "propose" | "accept" | "reject" | "counter" | "question";
755
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
745
756
  assessment: {
746
757
  reasoning: string;
747
758
  suggestedRoles: {
@@ -802,6 +813,7 @@ export declare function createDefaultNegotiationGraph(deps: {
802
813
  maxTurns: number;
803
814
  isContinuation: boolean;
804
815
  initiatorUserId: string;
816
+ protocolVersion: NegotiationProtocolVersion;
805
817
  priorTurnCount: number;
806
818
  error?: undefined;
807
819
  };
@@ -821,6 +833,7 @@ export declare function createDefaultNegotiationGraph(deps: {
821
833
  seedAssessment: import("@langchain/langgraph").BaseChannel<SeedAssessment, SeedAssessment | import("@langchain/langgraph").OverwriteValue<SeedAssessment>, unknown>;
822
834
  initiatorUserId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
823
835
  discoveryQuery: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
836
+ protocolVersion: import("@langchain/langgraph").BaseChannel<NegotiationProtocolVersion, NegotiationProtocolVersion | import("@langchain/langgraph").OverwriteValue<NegotiationProtocolVersion>, unknown>;
824
837
  isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
825
838
  opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
826
839
  conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
@@ -831,7 +844,7 @@ export declare function createDefaultNegotiationGraph(deps: {
831
844
  timeoutMs: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
832
845
  currentSpeaker: import("@langchain/langgraph").BaseChannel<"source" | "candidate", "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate">, unknown>;
833
846
  lastTurn: import("@langchain/langgraph").BaseChannel<{
834
- action: "propose" | "accept" | "reject" | "counter" | "question";
847
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
835
848
  assessment: {
836
849
  reasoning: string;
837
850
  suggestedRoles: {
@@ -841,7 +854,7 @@ export declare function createDefaultNegotiationGraph(deps: {
841
854
  };
842
855
  message?: string | null | undefined;
843
856
  } | null, {
844
- action: "propose" | "accept" | "reject" | "counter" | "question";
857
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
845
858
  assessment: {
846
859
  reasoning: string;
847
860
  suggestedRoles: {
@@ -851,7 +864,7 @@ export declare function createDefaultNegotiationGraph(deps: {
851
864
  };
852
865
  message?: string | null | undefined;
853
866
  } | import("@langchain/langgraph").OverwriteValue<{
854
- action: "propose" | "accept" | "reject" | "counter" | "question";
867
+ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
855
868
  assessment: {
856
869
  reasoning: string;
857
870
  suggestedRoles: {
@@ -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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"}
@@ -3,6 +3,7 @@ import { invokeWithAbortSignal } from "../shared/agent/model-signal.js";
3
3
  import { requestContext } from "../shared/observability/request-context.js";
4
4
  import { NegotiationGraphState } from "./negotiation.state.js";
5
5
  import { IndexNegotiator } from "./negotiation.agent.js";
6
+ import { allowedActionsFor, configuredProtocolVersion, fallbackActionFor, isRejectLikeAction, isTerminalAction, readProtocolVersion, rejectActionFor } from "./negotiation.protocol.js";
6
7
  import { protocolLogger } from "../shared/observability/protocol.logger.js";
7
8
  const logger = protocolLogger("NegotiationGraph");
8
9
  const initLog = protocolLogger("NegotiationGraph:Init");
@@ -87,9 +88,13 @@ export class NegotiationGraphFactory {
87
88
  return typeof v === 'string' && v.length > 0 ? v : null;
88
89
  };
89
90
  let initiatorUserId = readInitiator(priorTask?.metadata) ?? state.initiatorUserId ?? state.sourceUser.id;
91
+ // Conversation-scoped prior task: reused for both the initiator tie-break
92
+ // (only when active+fresh) and protocol-version inheritance (any prior
93
+ // task on the conversation pins the version).
94
+ const convTask = (!readInitiator(priorTask?.metadata) || !readProtocolVersion(priorTask?.metadata))
95
+ ? await database.getLatestNegotiationTaskForConversation?.(conversation.id).catch(() => null)
96
+ : null;
90
97
  if (!readInitiator(priorTask?.metadata)) {
91
- const convTask = await database.getLatestNegotiationTaskForConversation?.(conversation.id)
92
- .catch(() => null);
93
98
  if (convTask && convTask.id !== priorTask?.id && isActiveAndFresh(convTask)) {
94
99
  const convInitiator = readInitiator(convTask.metadata);
95
100
  if (convInitiator) {
@@ -102,10 +107,29 @@ export class NegotiationGraphFactory {
102
107
  }
103
108
  }
104
109
  }
110
+ // --- Protocol version: inherited, never re-stamped ---
111
+ // Every session (including continuations) creates a new task row, so a
112
+ // naïve "stamp from env at init" would flip a v1 conversation to v2
113
+ // mid-flight. Rule: any prior negotiation task on this conversation pins
114
+ // the version (absent field on a genuine prior = pre-v2 task = v1);
115
+ // prior turns without a readable task also grandfather to v1; only
116
+ // genuinely fresh negotiations stamp from NEGOTIATION_PROTOCOL_VERSION.
117
+ let protocolVersion;
118
+ const priorVersionSource = priorTask ?? convTask;
119
+ if (priorVersionSource) {
120
+ protocolVersion = readProtocolVersion(priorVersionSource.metadata) ?? 'v1';
121
+ }
122
+ else if (isContinuation) {
123
+ protocolVersion = 'v1';
124
+ }
125
+ else {
126
+ protocolVersion = configuredProtocolVersion();
127
+ }
105
128
  const task = await database.createTask(conversation.id, {
106
129
  type: 'negotiation',
107
130
  sourceUserId: state.sourceUser.id,
108
131
  initiatorUserId,
132
+ protocolVersion,
109
133
  candidateUserId: state.candidateUser.id,
110
134
  networkId: state.indexContext.networkId,
111
135
  ...(state.opportunityId && { opportunityId: state.opportunityId }),
@@ -141,6 +165,7 @@ export class NegotiationGraphFactory {
141
165
  maxTurns,
142
166
  isContinuation,
143
167
  initiatorUserId,
168
+ protocolVersion,
144
169
  priorTurnCount: priorTurns.length,
145
170
  ...(userAnswers.length > 0 && { userAnswers }),
146
171
  ...(seedMessages.length > 0 && { messages: seedMessages }),
@@ -167,6 +192,13 @@ export class NegotiationGraphFactory {
167
192
  // Determine if this is the system agent's final allowed turn
168
193
  const maxTurns = state.maxTurns ?? 0;
169
194
  const isFinalTurn = maxTurns > 0 && (state.turnCount + 1) >= maxTurns;
195
+ // Seat attribution keys on initiatorUserId (rigid v2 stamp), never on
196
+ // parity or source/candidate position — under the conversation-scoped
197
+ // tie-break this run's source may hold the counterparty seat.
198
+ const version = state.protocolVersion ?? 'v1';
199
+ const seat = ownUser.id === (state.initiatorUserId ?? state.sourceUser.id)
200
+ ? 'initiator'
201
+ : 'counterparty';
170
202
  const payload = {
171
203
  negotiationId: state.taskId,
172
204
  ownUser,
@@ -176,14 +208,25 @@ export class NegotiationGraphFactory {
176
208
  history,
177
209
  isFinalTurn,
178
210
  isDiscoverer: isSource,
211
+ seat,
212
+ protocolVersion: version,
213
+ allowedActions: [...allowedActionsFor(version, seat, isFinalTurn)],
179
214
  ...(state.discoveryQuery && isSource && { discoveryQuery: state.discoveryQuery }),
180
215
  };
181
216
  const scope = { action: 'manage:negotiations', scopeType: 'network', scopeId: state.indexContext.networkId };
182
217
  const dispatchResult = await dispatcher.dispatch(ownUser.id, scope, payload, { timeoutMs: state.timeoutMs });
183
218
  let turn;
184
219
  if (dispatchResult.handled) {
185
- // Personal agent responded
220
+ // Personal agent responded. Under v2, coerce out-of-seat actions to
221
+ // the conservative fallback — the polling/respond surfaces reject
222
+ // these with a 400, but locally-dispatched turns land here directly.
186
223
  turn = dispatchResult.turn;
224
+ if (version === 'v2' && !allowedActionsFor(version, seat, isFinalTurn).includes(turn.action)) {
225
+ turnLog.warn('Personal agent returned out-of-seat action, coercing to conservative fallback', {
226
+ action: turn.action, seat, isFinalTurn,
227
+ });
228
+ turn = { ...turn, action: fallbackActionFor(version, seat, isFinalTurn) };
229
+ }
187
230
  }
188
231
  else if (dispatchResult.reason === 'waiting') {
189
232
  // Long timeout — graph suspends. Persist the full turn context so the
@@ -216,16 +259,24 @@ export class NegotiationGraphFactory {
216
259
  history,
217
260
  isFinalTurn,
218
261
  isDiscoverer: isSource,
262
+ seat,
263
+ protocolVersion: version,
219
264
  ...(state.discoveryQuery && isSource && { discoveryQuery: state.discoveryQuery }),
220
265
  isContinuation: state.isContinuation,
221
266
  ...(state.userAnswers.length > 0 && { userAnswers: state.userAnswers }),
222
267
  });
223
268
  }
224
269
  traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: `${turn.action}` });
225
- // First turn must be "propose" (unless continuing a prior conversation)
226
- if (state.turnCount === 0 && !state.isContinuation && turn.action !== "propose") {
227
- turnLog.warn("Agent returned unexpected action on turn 0, forcing to propose", { action: turn.action });
228
- turn.action = "propose";
270
+ // First turn must open the negotiation (unless continuing a prior
271
+ // conversation): v1 → "propose"; v2 initiator → "outreach". A v2 turn-0
272
+ // speaker holding the counterparty seat (tie-break inheritance) is left
273
+ // unforced — it is responding, not opening.
274
+ if (state.turnCount === 0 && !state.isContinuation) {
275
+ const openingAction = version === 'v2' ? 'outreach' : 'propose';
276
+ if ((version !== 'v2' || seat === 'initiator') && turn.action !== openingAction) {
277
+ turnLog.warn(`Agent returned unexpected action on turn 0, forcing to ${openingAction}`, { action: turn.action });
278
+ turn.action = openingAction;
279
+ }
229
280
  }
230
281
  const parts = [{ kind: "data", data: turn }];
231
282
  const message = await database.createMessage({
@@ -267,9 +318,12 @@ export class NegotiationGraphFactory {
267
318
  const errMsg = err instanceof Error ? err.message : String(err);
268
319
  turnLog.error("Agent invocation failed", { error: errMsg, stack: err instanceof Error ? err.stack : undefined, turnCount: state.turnCount });
269
320
  traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: `error: ${errMsg}` });
321
+ const errorSeat = (state.currentSpeaker === 'source' ? state.sourceUser.id : state.candidateUser.id) === (state.initiatorUserId ?? state.sourceUser.id)
322
+ ? 'initiator'
323
+ : 'counterparty';
270
324
  return {
271
325
  lastTurn: {
272
- action: "reject",
326
+ action: rejectActionFor(state.protocolVersion ?? 'v1', errorSeat),
273
327
  assessment: { reasoning: `Agent error: ${errMsg}`, suggestedRoles: { ownUser: "peer", otherUser: "peer" } },
274
328
  },
275
329
  turnCount: state.turnCount + 1,
@@ -284,9 +338,8 @@ export class NegotiationGraphFactory {
284
338
  return "finalize";
285
339
  if (!state.lastTurn)
286
340
  return "finalize";
287
- if (state.lastTurn.action === "accept")
288
- return "finalize";
289
- if (state.lastTurn.action === "reject")
341
+ // Terminal actions: accept (v1+v2), reject (v1), withdraw/decline (v2)
342
+ if (isTerminalAction(state.lastTurn.action))
290
343
  return "finalize";
291
344
  // question routes same as counter — next turn
292
345
  if ((state.maxTurns ?? 0) > 0 && state.turnCount >= state.maxTurns)
@@ -311,7 +364,7 @@ export class NegotiationGraphFactory {
311
364
  const history = turnsFromMessages(state.messages);
312
365
  const lastTurn = state.lastTurn;
313
366
  const hasOpportunity = lastTurn?.action === "accept";
314
- const atCap = (state.maxTurns ?? 0) > 0 && state.turnCount >= state.maxTurns && lastTurn?.action !== "accept" && lastTurn?.action !== "reject";
367
+ const atCap = (state.maxTurns ?? 0) > 0 && state.turnCount >= state.maxTurns && !isTerminalAction(lastTurn?.action);
315
368
  let agreedRoles = [];
316
369
  if (hasOpportunity && history.length >= 2) {
317
370
  const acceptTurn = history[history.length - 1];
@@ -352,7 +405,7 @@ export class NegotiationGraphFactory {
352
405
  if (state.opportunityId) {
353
406
  const nextStatus = lastTurn?.action === 'accept'
354
407
  ? 'pending'
355
- : lastTurn?.action === 'reject'
408
+ : isRejectLikeAction(lastTurn?.action)
356
409
  ? 'rejected'
357
410
  : 'stalled';
358
411
  await database.updateOpportunityStatus(state.opportunityId, nextStatus).catch((err) => {
@@ -370,9 +423,7 @@ export class NegotiationGraphFactory {
370
423
  ? "turn_cap"
371
424
  : state.error && /timeout/i.test(state.error)
372
425
  ? "timed_out"
373
- : lastTurn?.action === "reject"
374
- ? "rejected_stalled"
375
- : "rejected_stalled";
426
+ : "rejected_stalled";
376
427
  emitWide({
377
428
  type: "negotiation_outcome",
378
429
  opportunityId: state.opportunityId,
@@ -392,7 +443,7 @@ export class NegotiationGraphFactory {
392
443
  }
393
444
  // Enqueue question generation for stalled/capped negotiations (not accepted or explicitly rejected).
394
445
  // Require turnCount > 0 so early init/turn errors don't enqueue with empty context.
395
- if (!hasOpportunity && lastTurn?.action !== 'reject' && state.turnCount > 0 && state.opportunityId && questionerEnqueue) {
446
+ if (!hasOpportunity && !isRejectLikeAction(lastTurn?.action) && state.turnCount > 0 && state.opportunityId && questionerEnqueue) {
396
447
  const stallReason = atCap
397
448
  ? 'turn_cap'
398
449
  : (state.error && /timeout/i.test(state.error))