@indexnetwork/protocol 4.5.0-rc.331.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.
- package/dist/chat/chat-streaming.types.d.ts +3 -1
- package/dist/chat/chat-streaming.types.d.ts.map +1 -1
- package/dist/chat/chat-streaming.types.js.map +1 -1
- package/dist/chat/chat.agent.d.ts +1 -1
- package/dist/chat/chat.agent.d.ts.map +1 -1
- package/dist/chat/chat.agent.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/negotiation/negotiation.agent.d.ts +21 -0
- package/dist/negotiation/negotiation.agent.d.ts.map +1 -1
- package/dist/negotiation/negotiation.agent.js +79 -11
- package/dist/negotiation/negotiation.agent.js.map +1 -1
- package/dist/negotiation/negotiation.graph.d.ts +55 -24
- package/dist/negotiation/negotiation.graph.d.ts.map +1 -1
- package/dist/negotiation/negotiation.graph.js +106 -27
- package/dist/negotiation/negotiation.graph.js.map +1 -1
- package/dist/negotiation/negotiation.protocol.d.ts +287 -0
- package/dist/negotiation/negotiation.protocol.d.ts.map +1 -0
- package/dist/negotiation/negotiation.protocol.js +152 -0
- package/dist/negotiation/negotiation.protocol.js.map +1 -0
- package/dist/negotiation/negotiation.state.d.ts +34 -9
- package/dist/negotiation/negotiation.state.d.ts.map +1 -1
- package/dist/negotiation/negotiation.state.js +28 -4
- package/dist/negotiation/negotiation.state.js.map +1 -1
- package/dist/negotiation/negotiation.tools.d.ts.map +1 -1
- package/dist/negotiation/negotiation.tools.js +86 -31
- package/dist/negotiation/negotiation.tools.js.map +1 -1
- package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
- package/dist/opportunity/opportunity.graph.js +9 -0
- package/dist/opportunity/opportunity.graph.js.map +1 -1
- package/dist/opportunity/question.prompt.d.ts +1 -1
- package/dist/opportunity/question.prompt.d.ts.map +1 -1
- package/dist/opportunity/question.prompt.js.map +1 -1
- package/dist/shared/interfaces/agent-dispatcher.interface.d.ts +6 -0
- package/dist/shared/interfaces/agent-dispatcher.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/agent-dispatcher.interface.js.map +1 -1
- package/dist/shared/interfaces/database.interface.d.ts +17 -0
- package/dist/shared/interfaces/database.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/database.interface.js.map +1 -1
- package/dist/shared/schemas/discovery-question.schema.d.ts +8 -8
- package/dist/shared/schemas/discovery-question.schema.js +1 -1
- package/dist/shared/schemas/discovery-question.schema.js.map +1 -1
- package/dist/shared/schemas/negotiation-state.schema.d.ts +19 -3
- package/dist/shared/schemas/negotiation-state.schema.d.ts.map +1 -1
- package/dist/shared/schemas/negotiation-state.schema.js +15 -1
- package/dist/shared/schemas/negotiation-state.schema.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seat-scoped negotiation protocol rules (v2 client-advocate protocol).
|
|
3
|
+
*
|
|
4
|
+
* v2 fixes exactly one initiating seat per match (`metadata.initiatorUserId`,
|
|
5
|
+
* stamped at discovery time — IND-396) and makes consent asymmetric:
|
|
6
|
+
* **accept can only come from the counterparty seat**, schema-enforced.
|
|
7
|
+
*
|
|
8
|
+
* Vocabulary per seat (v2):
|
|
9
|
+
* - initiator: `outreach | counter | question | withdraw` (no accept)
|
|
10
|
+
* - counterparty: `accept | decline | counter | question`
|
|
11
|
+
* - final turn: initiator `withdraw | counter`; counterparty `accept | decline`
|
|
12
|
+
*
|
|
13
|
+
* v1 tasks keep the legacy vocabulary (`propose | accept | reject | counter |
|
|
14
|
+
* question`) — the version is inherited per conversation, never re-stamped, so
|
|
15
|
+
* in-flight v1 negotiations are grandfathered untouched.
|
|
16
|
+
*
|
|
17
|
+
* Outcome mapping is version-independent: `accept` → opportunity `pending`,
|
|
18
|
+
* `reject`/`withdraw`/`decline` → `rejected`, turn-cap → `stalled`.
|
|
19
|
+
*/
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
// ─── Shared assessment fragment ──────────────────────────────────────────────
|
|
22
|
+
const AssessmentSchema = z.object({
|
|
23
|
+
reasoning: z.string(),
|
|
24
|
+
suggestedRoles: z.object({
|
|
25
|
+
ownUser: z.enum(["agent", "patient", "peer"]),
|
|
26
|
+
otherUser: z.enum(["agent", "patient", "peer"]),
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
function turnSchema(actions) {
|
|
30
|
+
return z.object({
|
|
31
|
+
action: z.enum(actions),
|
|
32
|
+
assessment: AssessmentSchema,
|
|
33
|
+
message: z.string().nullable().optional(),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// ─── v2 seat-scoped turn schemas ─────────────────────────────────────────────
|
|
37
|
+
/** Initiator seat, non-final turn: may reach out, push back, ask, or walk away — never accept. */
|
|
38
|
+
export const InitiatorTurnSchema = turnSchema(["outreach", "counter", "question", "withdraw"]);
|
|
39
|
+
/** Counterparty seat, non-final turn: the only seat that can accept. */
|
|
40
|
+
export const CounterpartyTurnSchema = turnSchema(["accept", "decline", "counter", "question"]);
|
|
41
|
+
/** Initiator seat, final allowed turn: commit to walking away or leave the door open. */
|
|
42
|
+
export const FinalInitiatorTurnSchema = turnSchema(["withdraw", "counter"]);
|
|
43
|
+
/** Counterparty seat, final allowed turn: must decide. */
|
|
44
|
+
export const FinalCounterpartyTurnSchema = turnSchema(["accept", "decline"]);
|
|
45
|
+
// ─── Action vocabulary per version + seat ────────────────────────────────────
|
|
46
|
+
const V1_ACTIONS = ["propose", "accept", "reject", "counter", "question"];
|
|
47
|
+
const V1_FINAL_ACTIONS = ["accept", "reject"];
|
|
48
|
+
const V2_INITIATOR_ACTIONS = ["outreach", "counter", "question", "withdraw"];
|
|
49
|
+
const V2_COUNTERPARTY_ACTIONS = ["accept", "decline", "counter", "question"];
|
|
50
|
+
const V2_FINAL_INITIATOR_ACTIONS = ["withdraw", "counter"];
|
|
51
|
+
const V2_FINAL_COUNTERPARTY_ACTIONS = ["accept", "decline"];
|
|
52
|
+
/**
|
|
53
|
+
* The set of actions a given seat may submit under a given protocol version.
|
|
54
|
+
*
|
|
55
|
+
* v1 ignores the seat entirely (legacy symmetric vocabulary) so pre-v2
|
|
56
|
+
* negotiations behave exactly as before.
|
|
57
|
+
*/
|
|
58
|
+
export function allowedActionsFor(version, seat, isFinalTurn = false) {
|
|
59
|
+
if (version !== "v2")
|
|
60
|
+
return isFinalTurn ? V1_FINAL_ACTIONS : V1_ACTIONS;
|
|
61
|
+
if (seat === "initiator")
|
|
62
|
+
return isFinalTurn ? V2_FINAL_INITIATOR_ACTIONS : V2_INITIATOR_ACTIONS;
|
|
63
|
+
return isFinalTurn ? V2_FINAL_COUNTERPARTY_ACTIONS : V2_COUNTERPARTY_ACTIONS;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Zod turn schema for a system-agent turn, selected by version + seat +
|
|
67
|
+
* final-turn flag. v1 returns the legacy schemas (seat-agnostic); v2 returns
|
|
68
|
+
* the seat-scoped schemas above, making an initiator `accept` structurally
|
|
69
|
+
* impossible rather than prompt-discouraged.
|
|
70
|
+
*
|
|
71
|
+
* The v1 legacy schemas are passed in by the caller (they live in
|
|
72
|
+
* `negotiation.state.ts`) to keep this module free of a state-module import.
|
|
73
|
+
*/
|
|
74
|
+
export function turnSchemaFor(version, seat, isFinalTurn, v1Schemas) {
|
|
75
|
+
if (version !== "v2")
|
|
76
|
+
return isFinalTurn ? v1Schemas.final : v1Schemas.system;
|
|
77
|
+
if (seat === "initiator")
|
|
78
|
+
return isFinalTurn ? FinalInitiatorTurnSchema : InitiatorTurnSchema;
|
|
79
|
+
return isFinalTurn ? FinalCounterpartyTurnSchema : CounterpartyTurnSchema;
|
|
80
|
+
}
|
|
81
|
+
// ─── Action semantics (version-independent) ──────────────────────────────────
|
|
82
|
+
/** Terminal actions end the negotiation immediately. */
|
|
83
|
+
export function isTerminalAction(action) {
|
|
84
|
+
return action === "accept" || action === "reject" || action === "withdraw" || action === "decline";
|
|
85
|
+
}
|
|
86
|
+
/** Reject-like actions map the opportunity to `rejected` (v1 reject, v2 withdraw/decline). */
|
|
87
|
+
export function isRejectLikeAction(action) {
|
|
88
|
+
return action === "reject" || action === "withdraw" || action === "decline";
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Conservative action when an agent produced schema-invalid output (after the
|
|
92
|
+
* retry) or an internal error needs a seat-valid terminal placeholder.
|
|
93
|
+
*
|
|
94
|
+
* Non-final turns fall back to `counter` (keeps the dialogue open — the AC's
|
|
95
|
+
* "conservative counter"). Final turns must decide: v1 → `reject`, v2
|
|
96
|
+
* counterparty → `decline`, v2 initiator → `counter` is still legal on the
|
|
97
|
+
* final turn so it stays `counter` (finalizes as turn-cap/stalled).
|
|
98
|
+
*/
|
|
99
|
+
export function fallbackActionFor(version, seat, isFinalTurn) {
|
|
100
|
+
if (!isFinalTurn)
|
|
101
|
+
return "counter";
|
|
102
|
+
if (version !== "v2")
|
|
103
|
+
return "reject";
|
|
104
|
+
return seat === "counterparty" ? "decline" : "counter";
|
|
105
|
+
}
|
|
106
|
+
/** Seat-appropriate reject-like action for error paths. */
|
|
107
|
+
export function rejectActionFor(version, seat) {
|
|
108
|
+
if (version !== "v2")
|
|
109
|
+
return "reject";
|
|
110
|
+
return seat === "initiator" ? "withdraw" : "decline";
|
|
111
|
+
}
|
|
112
|
+
// ─── Metadata readers ────────────────────────────────────────────────────────
|
|
113
|
+
/**
|
|
114
|
+
* Read the protocol version off task metadata. Returns null when the task
|
|
115
|
+
* predates version stamping (treat as v1 at the call site when the task is a
|
|
116
|
+
* genuine prior; fresh tasks stamp from {@link configuredProtocolVersion}).
|
|
117
|
+
*/
|
|
118
|
+
export function readProtocolVersion(metadata) {
|
|
119
|
+
const v = metadata?.protocolVersion;
|
|
120
|
+
return v === "v2" ? "v2" : v === "v1" ? "v1" : null;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Protocol version for genuinely fresh negotiations, from the
|
|
124
|
+
* `NEGOTIATION_PROTOCOL_VERSION` env switch. Defaults to `v1` when unset —
|
|
125
|
+
* v2 is opt-in per environment, and rolling back is the same single switch.
|
|
126
|
+
*/
|
|
127
|
+
export function configuredProtocolVersion() {
|
|
128
|
+
return process.env.NEGOTIATION_PROTOCOL_VERSION === "v2" ? "v2" : "v1";
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Resolve the seat of `userId` on a negotiation task.
|
|
132
|
+
*
|
|
133
|
+
* Keys on `metadata.initiatorUserId` (the rigid v2 stamp), **never on turn
|
|
134
|
+
* parity** — continuations can start with either side speaking first, so
|
|
135
|
+
* parity misattributes seats across sessions. Pre-stamp tasks fall back to
|
|
136
|
+
* `sourceUserId` (the discovery-session opener), which is what the stamp
|
|
137
|
+
* defaults to anyway.
|
|
138
|
+
*/
|
|
139
|
+
export function resolveSeat(userId, metadata) {
|
|
140
|
+
const initiator = typeof metadata?.initiatorUserId === "string" && metadata.initiatorUserId.length > 0
|
|
141
|
+
? metadata.initiatorUserId
|
|
142
|
+
: typeof metadata?.sourceUserId === "string"
|
|
143
|
+
? metadata.sourceUserId
|
|
144
|
+
: undefined;
|
|
145
|
+
return initiator === userId ? "initiator" : "counterparty";
|
|
146
|
+
}
|
|
147
|
+
/** Human-readable seat-violation message shared by respond surfaces. */
|
|
148
|
+
export function seatViolationMessage(action, seat, version) {
|
|
149
|
+
const allowed = allowedActionsFor(version, seat).join(", ");
|
|
150
|
+
return `Action "${action}" is not allowed for your seat (${seat}) under negotiation protocol ${version}. Allowed actions: ${allowed}.`;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=negotiation.protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"negotiation.protocol.js","sourceRoot":"/","sources":["negotiation/negotiation.protocol.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Seat-scoped negotiation protocol rules (v2 client-advocate protocol).\n *\n * v2 fixes exactly one initiating seat per match (`metadata.initiatorUserId`,\n * stamped at discovery time — IND-396) and makes consent asymmetric:\n * **accept can only come from the counterparty seat**, schema-enforced.\n *\n * Vocabulary per seat (v2):\n * - initiator: `outreach | counter | question | withdraw` (no accept)\n * - counterparty: `accept | decline | counter | question`\n * - final turn: initiator `withdraw | counter`; counterparty `accept | decline`\n *\n * v1 tasks keep the legacy vocabulary (`propose | accept | reject | counter |\n * question`) — the version is inherited per conversation, never re-stamped, so\n * in-flight v1 negotiations are grandfathered untouched.\n *\n * Outcome mapping is version-independent: `accept` → opportunity `pending`,\n * `reject`/`withdraw`/`decline` → `rejected`, turn-cap → `stalled`.\n */\nimport { z } from \"zod\";\n\nimport type { NegotiationAction, NegotiationSeat, NegotiationProtocolVersion } from \"../shared/schemas/negotiation-state.schema.js\";\n\n// ─── Shared assessment fragment ──────────────────────────────────────────────\n\nconst AssessmentSchema = z.object({\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n otherUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n }),\n});\n\nfunction turnSchema<T extends [NegotiationAction, ...NegotiationAction[]]>(actions: T) {\n return z.object({\n action: z.enum(actions),\n assessment: AssessmentSchema,\n message: z.string().nullable().optional(),\n });\n}\n\n// ─── v2 seat-scoped turn schemas ─────────────────────────────────────────────\n\n/** Initiator seat, non-final turn: may reach out, push back, ask, or walk away — never accept. */\nexport const InitiatorTurnSchema = turnSchema([\"outreach\", \"counter\", \"question\", \"withdraw\"]);\n\n/** Counterparty seat, non-final turn: the only seat that can accept. */\nexport const CounterpartyTurnSchema = turnSchema([\"accept\", \"decline\", \"counter\", \"question\"]);\n\n/** Initiator seat, final allowed turn: commit to walking away or leave the door open. */\nexport const FinalInitiatorTurnSchema = turnSchema([\"withdraw\", \"counter\"]);\n\n/** Counterparty seat, final allowed turn: must decide. */\nexport const FinalCounterpartyTurnSchema = turnSchema([\"accept\", \"decline\"]);\n\n// ─── Action vocabulary per version + seat ────────────────────────────────────\n\nconst V1_ACTIONS: readonly NegotiationAction[] = [\"propose\", \"accept\", \"reject\", \"counter\", \"question\"];\nconst V1_FINAL_ACTIONS: readonly NegotiationAction[] = [\"accept\", \"reject\"];\nconst V2_INITIATOR_ACTIONS: readonly NegotiationAction[] = [\"outreach\", \"counter\", \"question\", \"withdraw\"];\nconst V2_COUNTERPARTY_ACTIONS: readonly NegotiationAction[] = [\"accept\", \"decline\", \"counter\", \"question\"];\nconst V2_FINAL_INITIATOR_ACTIONS: readonly NegotiationAction[] = [\"withdraw\", \"counter\"];\nconst V2_FINAL_COUNTERPARTY_ACTIONS: readonly NegotiationAction[] = [\"accept\", \"decline\"];\n\n/**\n * The set of actions a given seat may submit under a given protocol version.\n *\n * v1 ignores the seat entirely (legacy symmetric vocabulary) so pre-v2\n * negotiations behave exactly as before.\n */\nexport function allowedActionsFor(\n version: NegotiationProtocolVersion,\n seat: NegotiationSeat,\n isFinalTurn = false,\n): readonly NegotiationAction[] {\n if (version !== \"v2\") return isFinalTurn ? V1_FINAL_ACTIONS : V1_ACTIONS;\n if (seat === \"initiator\") return isFinalTurn ? V2_FINAL_INITIATOR_ACTIONS : V2_INITIATOR_ACTIONS;\n return isFinalTurn ? V2_FINAL_COUNTERPARTY_ACTIONS : V2_COUNTERPARTY_ACTIONS;\n}\n\n/**\n * Zod turn schema for a system-agent turn, selected by version + seat +\n * final-turn flag. v1 returns the legacy schemas (seat-agnostic); v2 returns\n * the seat-scoped schemas above, making an initiator `accept` structurally\n * impossible rather than prompt-discouraged.\n *\n * The v1 legacy schemas are passed in by the caller (they live in\n * `negotiation.state.ts`) to keep this module free of a state-module import.\n */\nexport function turnSchemaFor(\n version: NegotiationProtocolVersion,\n seat: NegotiationSeat,\n isFinalTurn: boolean,\n v1Schemas: { system: z.ZodTypeAny; final: z.ZodTypeAny },\n): z.ZodTypeAny {\n if (version !== \"v2\") return isFinalTurn ? v1Schemas.final : v1Schemas.system;\n if (seat === \"initiator\") return isFinalTurn ? FinalInitiatorTurnSchema : InitiatorTurnSchema;\n return isFinalTurn ? FinalCounterpartyTurnSchema : CounterpartyTurnSchema;\n}\n\n// ─── Action semantics (version-independent) ──────────────────────────────────\n\n/** Terminal actions end the negotiation immediately. */\nexport function isTerminalAction(action: string | undefined | null): boolean {\n return action === \"accept\" || action === \"reject\" || action === \"withdraw\" || action === \"decline\";\n}\n\n/** Reject-like actions map the opportunity to `rejected` (v1 reject, v2 withdraw/decline). */\nexport function isRejectLikeAction(action: string | undefined | null): boolean {\n return action === \"reject\" || action === \"withdraw\" || action === \"decline\";\n}\n\n/**\n * Conservative action when an agent produced schema-invalid output (after the\n * retry) or an internal error needs a seat-valid terminal placeholder.\n *\n * Non-final turns fall back to `counter` (keeps the dialogue open — the AC's\n * \"conservative counter\"). Final turns must decide: v1 → `reject`, v2\n * counterparty → `decline`, v2 initiator → `counter` is still legal on the\n * final turn so it stays `counter` (finalizes as turn-cap/stalled).\n */\nexport function fallbackActionFor(\n version: NegotiationProtocolVersion,\n seat: NegotiationSeat,\n isFinalTurn: boolean,\n): NegotiationAction {\n if (!isFinalTurn) return \"counter\";\n if (version !== \"v2\") return \"reject\";\n return seat === \"counterparty\" ? \"decline\" : \"counter\";\n}\n\n/** Seat-appropriate reject-like action for error paths. */\nexport function rejectActionFor(\n version: NegotiationProtocolVersion,\n seat: NegotiationSeat,\n): NegotiationAction {\n if (version !== \"v2\") return \"reject\";\n return seat === \"initiator\" ? \"withdraw\" : \"decline\";\n}\n\n// ─── Metadata readers ────────────────────────────────────────────────────────\n\n/**\n * Read the protocol version off task metadata. Returns null when the task\n * predates version stamping (treat as v1 at the call site when the task is a\n * genuine prior; fresh tasks stamp from {@link configuredProtocolVersion}).\n */\nexport function readProtocolVersion(\n metadata: { protocolVersion?: unknown } | null | undefined,\n): NegotiationProtocolVersion | null {\n const v = metadata?.protocolVersion;\n return v === \"v2\" ? \"v2\" : v === \"v1\" ? \"v1\" : null;\n}\n\n/**\n * Protocol version for genuinely fresh negotiations, from the\n * `NEGOTIATION_PROTOCOL_VERSION` env switch. Defaults to `v1` when unset —\n * v2 is opt-in per environment, and rolling back is the same single switch.\n */\nexport function configuredProtocolVersion(): NegotiationProtocolVersion {\n return process.env.NEGOTIATION_PROTOCOL_VERSION === \"v2\" ? \"v2\" : \"v1\";\n}\n\n/**\n * Resolve the seat of `userId` on a negotiation task.\n *\n * Keys on `metadata.initiatorUserId` (the rigid v2 stamp), **never on turn\n * parity** — continuations can start with either side speaking first, so\n * parity misattributes seats across sessions. Pre-stamp tasks fall back to\n * `sourceUserId` (the discovery-session opener), which is what the stamp\n * defaults to anyway.\n */\nexport function resolveSeat(\n userId: string,\n metadata: { initiatorUserId?: unknown; sourceUserId?: unknown } | null | undefined,\n): NegotiationSeat {\n const initiator =\n typeof metadata?.initiatorUserId === \"string\" && metadata.initiatorUserId.length > 0\n ? metadata.initiatorUserId\n : typeof metadata?.sourceUserId === \"string\"\n ? metadata.sourceUserId\n : undefined;\n return initiator === userId ? \"initiator\" : \"counterparty\";\n}\n\n/** Human-readable seat-violation message shared by respond surfaces. */\nexport function seatViolationMessage(\n action: string,\n seat: NegotiationSeat,\n version: NegotiationProtocolVersion,\n): string {\n const allowed = allowedActionsFor(version, seat).join(\", \");\n return `Action \"${action}\" is not allowed for your seat (${seat}) under negotiation protocol ${version}. Allowed actions: ${allowed}.`;\n}\n"]}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { NegotiationUserAnswer } from "../shared/interfaces/database.interface.js";
|
|
3
|
-
|
|
3
|
+
import { type NegotiationProtocolVersion } from "../shared/schemas/negotiation-state.schema.js";
|
|
4
|
+
/**
|
|
5
|
+
* Zod schema for a single negotiation turn (DataPart payload in A2A message).
|
|
6
|
+
* Accepts the full v1+v2 action union — which subset is valid for a given turn
|
|
7
|
+
* is enforced by the seat-scoped schemas in `negotiation.protocol.ts`.
|
|
8
|
+
*/
|
|
4
9
|
export declare const NegotiationTurnSchema: z.ZodObject<{
|
|
5
|
-
action: z.ZodEnum<["propose", "accept", "reject", "counter", "question"]>;
|
|
10
|
+
action: z.ZodEnum<["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline"]>;
|
|
6
11
|
assessment: z.ZodObject<{
|
|
7
12
|
reasoning: z.ZodString;
|
|
8
13
|
suggestedRoles: z.ZodObject<{
|
|
@@ -30,7 +35,7 @@ export declare const NegotiationTurnSchema: z.ZodObject<{
|
|
|
30
35
|
}>;
|
|
31
36
|
message: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
32
37
|
}, "strip", z.ZodTypeAny, {
|
|
33
|
-
action: "propose" | "accept" | "reject" | "counter" | "question";
|
|
38
|
+
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
|
|
34
39
|
assessment: {
|
|
35
40
|
reasoning: string;
|
|
36
41
|
suggestedRoles: {
|
|
@@ -40,7 +45,7 @@ export declare const NegotiationTurnSchema: z.ZodObject<{
|
|
|
40
45
|
};
|
|
41
46
|
message?: string | null | undefined;
|
|
42
47
|
}, {
|
|
43
|
-
action: "propose" | "accept" | "reject" | "counter" | "question";
|
|
48
|
+
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
|
|
44
49
|
assessment: {
|
|
45
50
|
reasoning: string;
|
|
46
51
|
suggestedRoles: {
|
|
@@ -50,7 +55,7 @@ export declare const NegotiationTurnSchema: z.ZodObject<{
|
|
|
50
55
|
};
|
|
51
56
|
message?: string | null | undefined;
|
|
52
57
|
}>;
|
|
53
|
-
/** Restricted turn schema for the system agent (no question action). */
|
|
58
|
+
/** Restricted v1 turn schema for the system agent (no question action). */
|
|
54
59
|
export declare const SystemNegotiationTurnSchema: z.ZodObject<{
|
|
55
60
|
action: z.ZodEnum<["propose", "accept", "reject", "counter"]>;
|
|
56
61
|
assessment: z.ZodObject<{
|
|
@@ -100,7 +105,7 @@ export declare const SystemNegotiationTurnSchema: z.ZodObject<{
|
|
|
100
105
|
};
|
|
101
106
|
message?: string | null | undefined;
|
|
102
107
|
}>;
|
|
103
|
-
/**
|
|
108
|
+
/** v1 turn schema for system agent's final allowed turn (must decide). */
|
|
104
109
|
export declare const FinalNegotiationTurnSchema: z.ZodObject<{
|
|
105
110
|
action: z.ZodEnum<["accept", "reject"]>;
|
|
106
111
|
assessment: z.ZodObject<{
|
|
@@ -227,6 +232,13 @@ export interface NegotiationGraphLike {
|
|
|
227
232
|
opportunityId?: string;
|
|
228
233
|
maxTurns?: number;
|
|
229
234
|
timeoutMs?: number;
|
|
235
|
+
/**
|
|
236
|
+
* The user who holds the initiating seat for this match (v2 client-advocate
|
|
237
|
+
* protocol). Stamped into task metadata by the init node. When omitted, the
|
|
238
|
+
* init node resolves it: inherit from the prior task for the same
|
|
239
|
+
* opportunity → conversation-scoped tie-break → fall back to sourceUser.id.
|
|
240
|
+
*/
|
|
241
|
+
initiatorUserId?: string;
|
|
230
242
|
}): Promise<{
|
|
231
243
|
outcome: NegotiationOutcome | null;
|
|
232
244
|
messages?: NegotiationMessage[];
|
|
@@ -258,8 +270,21 @@ export declare const NegotiationGraphState: import("@langchain/langgraph").Annot
|
|
|
258
270
|
prompt: string;
|
|
259
271
|
}>, unknown>;
|
|
260
272
|
seedAssessment: import("@langchain/langgraph").BaseChannel<SeedAssessment, SeedAssessment | import("@langchain/langgraph").OverwriteValue<SeedAssessment>, unknown>;
|
|
273
|
+
/**
|
|
274
|
+
* Explicit initiator seat for this match (purely additive metadata — no seat
|
|
275
|
+
* rules attach to it yet). Resolution when unset happens in the init node;
|
|
276
|
+
* the resolved value is written back to state and into task metadata.
|
|
277
|
+
*/
|
|
278
|
+
initiatorUserId: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
261
279
|
/** The explicit search query that triggered discovery (if any). */
|
|
262
280
|
discoveryQuery: import("@langchain/langgraph").BaseChannel<string | undefined, string | import("@langchain/langgraph").OverwriteValue<string | undefined> | undefined, unknown>;
|
|
281
|
+
/**
|
|
282
|
+
* Negotiation protocol version for this session's task. Resolved by the
|
|
283
|
+
* init node: inherited from the prior task on the conversation when one
|
|
284
|
+
* exists (never re-stamped — a v1 conversation stays v1 mid-flight), else
|
|
285
|
+
* stamped from `NEGOTIATION_PROTOCOL_VERSION` for genuinely fresh runs.
|
|
286
|
+
*/
|
|
287
|
+
protocolVersion: import("@langchain/langgraph").BaseChannel<NegotiationProtocolVersion, NegotiationProtocolVersion | import("@langchain/langgraph").OverwriteValue<NegotiationProtocolVersion>, unknown>;
|
|
263
288
|
/** Whether this run is continuing a prior conversation with the same pair. */
|
|
264
289
|
isContinuation: import("@langchain/langgraph").BaseChannel<boolean, boolean | import("@langchain/langgraph").OverwriteValue<boolean>, unknown>;
|
|
265
290
|
opportunityId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
@@ -278,7 +303,7 @@ export declare const NegotiationGraphState: import("@langchain/langgraph").Annot
|
|
|
278
303
|
timeoutMs: import("@langchain/langgraph").BaseChannel<number, number | import("@langchain/langgraph").OverwriteValue<number>, unknown>;
|
|
279
304
|
currentSpeaker: import("@langchain/langgraph").BaseChannel<"source" | "candidate", "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate">, unknown>;
|
|
280
305
|
lastTurn: import("@langchain/langgraph").BaseChannel<{
|
|
281
|
-
action: "propose" | "accept" | "reject" | "counter" | "question";
|
|
306
|
+
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
|
|
282
307
|
assessment: {
|
|
283
308
|
reasoning: string;
|
|
284
309
|
suggestedRoles: {
|
|
@@ -288,7 +313,7 @@ export declare const NegotiationGraphState: import("@langchain/langgraph").Annot
|
|
|
288
313
|
};
|
|
289
314
|
message?: string | null | undefined;
|
|
290
315
|
} | null, {
|
|
291
|
-
action: "propose" | "accept" | "reject" | "counter" | "question";
|
|
316
|
+
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
|
|
292
317
|
assessment: {
|
|
293
318
|
reasoning: string;
|
|
294
319
|
suggestedRoles: {
|
|
@@ -298,7 +323,7 @@ export declare const NegotiationGraphState: import("@langchain/langgraph").Annot
|
|
|
298
323
|
};
|
|
299
324
|
message?: string | null | undefined;
|
|
300
325
|
} | import("@langchain/langgraph").OverwriteValue<{
|
|
301
|
-
action: "propose" | "accept" | "reject" | "counter" | "question";
|
|
326
|
+
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline";
|
|
302
327
|
assessment: {
|
|
303
328
|
reasoning: string;
|
|
304
329
|
suggestedRoles: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiation.state.d.ts","sourceRoot":"/","sources":["negotiation/negotiation.state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"negotiation.state.d.ts","sourceRoot":"/","sources":["negotiation/negotiation.state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { Annotation } from "@langchain/langgraph";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
|
|
3
|
+
import { NEGOTIATION_ACTIONS } from "../shared/schemas/negotiation-state.schema.js";
|
|
4
|
+
/**
|
|
5
|
+
* Zod schema for a single negotiation turn (DataPart payload in A2A message).
|
|
6
|
+
* Accepts the full v1+v2 action union — which subset is valid for a given turn
|
|
7
|
+
* is enforced by the seat-scoped schemas in `negotiation.protocol.ts`.
|
|
8
|
+
*/
|
|
4
9
|
export const NegotiationTurnSchema = z.object({
|
|
5
|
-
action: z.enum(
|
|
10
|
+
action: z.enum(NEGOTIATION_ACTIONS),
|
|
6
11
|
assessment: z.object({
|
|
7
12
|
reasoning: z.string(),
|
|
8
13
|
suggestedRoles: z.object({
|
|
@@ -12,7 +17,7 @@ export const NegotiationTurnSchema = z.object({
|
|
|
12
17
|
}),
|
|
13
18
|
message: z.string().nullable().optional(),
|
|
14
19
|
});
|
|
15
|
-
/** Restricted turn schema for the system agent (no question action). */
|
|
20
|
+
/** Restricted v1 turn schema for the system agent (no question action). */
|
|
16
21
|
export const SystemNegotiationTurnSchema = z.object({
|
|
17
22
|
action: z.enum(["propose", "accept", "reject", "counter"]),
|
|
18
23
|
assessment: z.object({
|
|
@@ -24,7 +29,7 @@ export const SystemNegotiationTurnSchema = z.object({
|
|
|
24
29
|
}),
|
|
25
30
|
message: z.string().nullable().optional(),
|
|
26
31
|
});
|
|
27
|
-
/**
|
|
32
|
+
/** v1 turn schema for system agent's final allowed turn (must decide). */
|
|
28
33
|
export const FinalNegotiationTurnSchema = z.object({
|
|
29
34
|
action: z.enum(["accept", "reject"]),
|
|
30
35
|
assessment: z.object({
|
|
@@ -65,11 +70,30 @@ export const NegotiationGraphState = Annotation.Root({
|
|
|
65
70
|
reducer: (curr, next) => next ?? curr,
|
|
66
71
|
default: () => ({ reasoning: "", valencyRole: "" }),
|
|
67
72
|
}),
|
|
73
|
+
/**
|
|
74
|
+
* Explicit initiator seat for this match (purely additive metadata — no seat
|
|
75
|
+
* rules attach to it yet). Resolution when unset happens in the init node;
|
|
76
|
+
* the resolved value is written back to state and into task metadata.
|
|
77
|
+
*/
|
|
78
|
+
initiatorUserId: Annotation({
|
|
79
|
+
reducer: (curr, next) => next ?? curr,
|
|
80
|
+
default: () => undefined,
|
|
81
|
+
}),
|
|
68
82
|
/** The explicit search query that triggered discovery (if any). */
|
|
69
83
|
discoveryQuery: Annotation({
|
|
70
84
|
reducer: (curr, next) => next ?? curr,
|
|
71
85
|
default: () => undefined,
|
|
72
86
|
}),
|
|
87
|
+
/**
|
|
88
|
+
* Negotiation protocol version for this session's task. Resolved by the
|
|
89
|
+
* init node: inherited from the prior task on the conversation when one
|
|
90
|
+
* exists (never re-stamped — a v1 conversation stays v1 mid-flight), else
|
|
91
|
+
* stamped from `NEGOTIATION_PROTOCOL_VERSION` for genuinely fresh runs.
|
|
92
|
+
*/
|
|
93
|
+
protocolVersion: Annotation({
|
|
94
|
+
reducer: (curr, next) => next ?? curr,
|
|
95
|
+
default: () => "v1",
|
|
96
|
+
}),
|
|
73
97
|
/** Whether this run is continuing a prior conversation with the same pair. */
|
|
74
98
|
isContinuation: Annotation({
|
|
75
99
|
reducer: (curr, next) => next ?? curr,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiation.state.js","sourceRoot":"/","sources":["negotiation/negotiation.state.ts"],"names":[],"mappings":"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","sourcesContent":["import { Annotation } from \"@langchain/langgraph\";\nimport { z } from \"zod\";\nimport type { NegotiationUserAnswer } from \"../shared/interfaces/database.interface.js\";\n\n/** Zod schema for a single negotiation turn (DataPart payload in A2A message). */\nexport const NegotiationTurnSchema = z.object({\n action: z.enum([\"propose\", \"accept\", \"reject\", \"counter\", \"question\"]),\n assessment: z.object({\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n otherUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n }),\n }),\n message: z.string().nullable().optional(),\n});\n\n/** Restricted turn schema for the system agent (no question action). */\nexport const SystemNegotiationTurnSchema = z.object({\n action: z.enum([\"propose\", \"accept\", \"reject\", \"counter\"]),\n assessment: z.object({\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n otherUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n }),\n }),\n message: z.string().nullable().optional(),\n});\n\n/** Turn schema for system agent's final allowed turn (must decide). */\nexport const FinalNegotiationTurnSchema = z.object({\n action: z.enum([\"accept\", \"reject\"]),\n assessment: z.object({\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n otherUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n }),\n }),\n message: z.string().nullable().optional(),\n});\n\nexport type NegotiationTurn = z.infer<typeof NegotiationTurnSchema>;\n\n/** Zod schema for the negotiation outcome (Artifact payload on COMPLETED task). */\nexport const NegotiationOutcomeSchema = z.object({\n hasOpportunity: z.boolean(),\n agreedRoles: z.array(z.object({\n userId: z.string(),\n role: z.enum([\"agent\", \"patient\", \"peer\"]),\n })),\n reasoning: z.string(),\n turnCount: z.number(),\n reason: z.enum([\"turn_cap\", \"timeout\"]).optional(),\n});\n\nexport type NegotiationOutcome = z.infer<typeof NegotiationOutcomeSchema>;\n\n/** Context each agent receives about its user. */\nexport interface UserNegotiationContext {\n id: string;\n intents: Array<{ id: string; title: string; description: string; confidence: number }>;\n profile: { name?: string; bio?: string; location?: string; interests?: string[]; skills?: string[] };\n}\n\n/** Seed assessment from the evaluator pre-filter. */\nexport interface SeedAssessment {\n reasoning: string;\n valencyRole: string;\n actors?: Array<{ userId: string; role: string }>;\n}\n\n/** Typed interface for a negotiation graph's invoke signature. */\nexport interface NegotiationGraphLike {\n invoke(input: {\n sourceUser: UserNegotiationContext;\n candidateUser: UserNegotiationContext;\n indexContext: { networkId: string; prompt: string };\n seedAssessment: Omit<SeedAssessment, \"actors\">;\n discoveryQuery?: string;\n opportunityId?: string;\n maxTurns?: number;\n timeoutMs?: number;\n }): Promise<{\n outcome: NegotiationOutcome | null;\n messages?: NegotiationMessage[];\n conversationId?: string;\n isContinuation?: boolean;\n priorTurnCount?: number;\n }>;\n}\n\n/** A2A message record shape (matches messages table). */\nexport interface NegotiationMessage {\n id: string;\n senderId: string;\n role: \"agent\";\n parts: unknown[];\n createdAt: Date;\n}\n\n/** LangGraph state annotation for the negotiation graph. */\nexport const NegotiationGraphState = Annotation.Root({\n sourceUser: Annotation<UserNegotiationContext>({\n reducer: (curr, next) => next ?? curr,\n default: () => ({ id: \"\", intents: [], profile: {} }),\n }),\n candidateUser: Annotation<UserNegotiationContext>({\n reducer: (curr, next) => next ?? curr,\n default: () => ({ id: \"\", intents: [], profile: {} }),\n }),\n indexContext: Annotation<{ networkId: string; prompt: string }>({\n reducer: (curr, next) => next ?? curr,\n default: () => ({ networkId: \"\", prompt: \"\" }),\n }),\n seedAssessment: Annotation<SeedAssessment>({\n reducer: (curr, next) => next ?? curr,\n default: () => ({ reasoning: \"\", valencyRole: \"\" }),\n }),\n\n /** The explicit search query that triggered discovery (if any). */\n discoveryQuery: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n /** Whether this run is continuing a prior conversation with the same pair. */\n isContinuation: Annotation<boolean>({\n reducer: (curr, next) => next ?? curr,\n default: () => false,\n }),\n opportunityId: Annotation<string>({\n reducer: (curr, next) => next ?? curr,\n default: () => \"\",\n }),\n conversationId: Annotation<string>({\n reducer: (curr, next) => next ?? curr,\n default: () => \"\",\n }),\n taskId: Annotation<string>({\n reducer: (curr, next) => next ?? curr,\n default: () => \"\",\n }),\n messages: Annotation<NegotiationMessage[]>({\n reducer: (curr, next) => [...curr, ...(next || [])],\n default: () => [],\n }),\n turnCount: Annotation<number>({\n reducer: (curr, next) => next ?? curr,\n default: () => 0,\n }),\n maxTurns: Annotation<number | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n /**\n * Park-window budget in milliseconds. Ambient callers pass `AMBIENT_PARK_WINDOW_MS`\n * (5 minutes); orchestrator callers pass a shorter window. This annotation default\n * is a safety net for any caller that omits the field — keep it aligned with\n * `AMBIENT_PARK_WINDOW_MS` in packages/protocol/src/negotiation/negotiation.tools.ts.\n * Inlined rather than imported to avoid a state↔tools cycle.\n */\n timeoutMs: Annotation<number>({\n reducer: (curr, next) => next ?? curr,\n default: () => 5 * 60 * 1000,\n }),\n\n currentSpeaker: Annotation<\"source\" | \"candidate\">({\n reducer: (curr, next) => next ?? curr,\n default: () => \"source\" as const,\n }),\n lastTurn: Annotation<NegotiationTurn | null>({\n reducer: (curr, next) => next ?? curr,\n default: () => null,\n }),\n\n /**\n * Graph status.\n * - `active` — agents are exchanging turns (default)\n * - `waiting_for_agent` — graph suspended; awaiting external agent response or timeout\n * - `completed` — negotiation finalized (accept/reject/turn-cap/timeout)\n */\n status: Annotation<'active' | 'waiting_for_agent' | 'completed'>({\n reducer: (curr, next) => next ?? curr,\n default: () => 'active' as const,\n }),\n\n /** Number of turns present in the conversation before this session started. */\n priorTurnCount: Annotation<number>({\n reducer: (curr, next) => next ?? curr,\n default: () => 0,\n }),\n\n /** User answers collected by the questioner between negotiation sessions. */\n userAnswers: Annotation<NegotiationUserAnswer[]>({\n reducer: (curr, next) => next ?? curr,\n default: () => [],\n }),\n\n outcome: Annotation<NegotiationOutcome | null>({\n reducer: (curr, next) => next ?? curr,\n default: () => null,\n }),\n error: Annotation<string | null>({\n reducer: (curr, next) => next ?? curr,\n default: () => null,\n }),\n});\n"]}
|
|
1
|
+
{"version":3,"file":"negotiation.state.js","sourceRoot":"/","sources":["negotiation/negotiation.state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAAmC,MAAM,+CAA+C,CAAC;AAErH;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC;IACnC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YAC7C,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;SAChD,CAAC;KACH,CAAC;IACF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC1D,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YAC7C,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;SAChD,CAAC;KACH,CAAC;IACF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAEH,0EAA0E;AAC1E,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACpC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;QACnB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;QACrB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC;YACvB,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;YAC7C,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;SAChD,CAAC;KACH,CAAC;IACF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAIH,mFAAmF;AACnF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;IAC3B,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;KAC3C,CAAC,CAAC;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC;AAsDH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAC,IAAI,CAAC;IACnD,UAAU,EAAE,UAAU,CAAyB;QAC7C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;KACtD,CAAC;IACF,aAAa,EAAE,UAAU,CAAyB;QAChD,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;KACtD,CAAC;IACF,YAAY,EAAE,UAAU,CAAwC;QAC9D,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;KAC/C,CAAC;IACF,cAAc,EAAE,UAAU,CAAiB;QACzC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;KACpD,CAAC;IAEF;;;;OAIG;IACH,eAAe,EAAE,UAAU,CAAqB;QAC9C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;KACzB,CAAC;IAEF,mEAAmE;IACnE,cAAc,EAAE,UAAU,CAAqB;QAC7C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;KACzB,CAAC;IACF;;;;;OAKG;IACH,eAAe,EAAE,UAAU,CAA6B;QACtD,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAa;KAC7B,CAAC;IAEF,8EAA8E;IAC9E,cAAc,EAAE,UAAU,CAAU;QAClC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK;KACrB,CAAC;IACF,aAAa,EAAE,UAAU,CAAS;QAChC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;KAClB,CAAC;IACF,cAAc,EAAE,UAAU,CAAS;QACjC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;KAClB,CAAC;IACF,MAAM,EAAE,UAAU,CAAS;QACzB,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;KAClB,CAAC;IACF,QAAQ,EAAE,UAAU,CAAuB;QACzC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACnD,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;KAClB,CAAC;IACF,SAAS,EAAE,UAAU,CAAS;QAC5B,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;KACjB,CAAC;IACF,QAAQ,EAAE,UAAU,CAAqB;QACvC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;KACzB,CAAC;IACF;;;;;;OAMG;IACH,SAAS,EAAE,UAAU,CAAS;QAC5B,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI;KAC7B,CAAC;IAEF,cAAc,EAAE,UAAU,CAAyB;QACjD,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAiB;KACjC,CAAC;IACF,QAAQ,EAAE,UAAU,CAAyB;QAC3C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI;KACpB,CAAC;IAEF;;;;;OAKG;IACH,MAAM,EAAE,UAAU,CAA+C;QAC/D,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAiB;KACjC,CAAC;IAEF,+EAA+E;IAC/E,cAAc,EAAE,UAAU,CAAS;QACjC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;KACjB,CAAC;IAEF,6EAA6E;IAC7E,WAAW,EAAE,UAAU,CAA0B;QAC/C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE;KAClB,CAAC;IAEF,OAAO,EAAE,UAAU,CAA4B;QAC7C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI;KACpB,CAAC;IACF,KAAK,EAAE,UAAU,CAAgB;QAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,IAAI;QACrC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI;KACpB,CAAC;CACH,CAAC,CAAC","sourcesContent":["import { Annotation } from \"@langchain/langgraph\";\nimport { z } from \"zod\";\nimport type { NegotiationUserAnswer } from \"../shared/interfaces/database.interface.js\";\nimport { NEGOTIATION_ACTIONS, type NegotiationProtocolVersion } from \"../shared/schemas/negotiation-state.schema.js\";\n\n/**\n * Zod schema for a single negotiation turn (DataPart payload in A2A message).\n * Accepts the full v1+v2 action union — which subset is valid for a given turn\n * is enforced by the seat-scoped schemas in `negotiation.protocol.ts`.\n */\nexport const NegotiationTurnSchema = z.object({\n action: z.enum(NEGOTIATION_ACTIONS),\n assessment: z.object({\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n otherUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n }),\n }),\n message: z.string().nullable().optional(),\n});\n\n/** Restricted v1 turn schema for the system agent (no question action). */\nexport const SystemNegotiationTurnSchema = z.object({\n action: z.enum([\"propose\", \"accept\", \"reject\", \"counter\"]),\n assessment: z.object({\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n otherUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n }),\n }),\n message: z.string().nullable().optional(),\n});\n\n/** v1 turn schema for system agent's final allowed turn (must decide). */\nexport const FinalNegotiationTurnSchema = z.object({\n action: z.enum([\"accept\", \"reject\"]),\n assessment: z.object({\n reasoning: z.string(),\n suggestedRoles: z.object({\n ownUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n otherUser: z.enum([\"agent\", \"patient\", \"peer\"]),\n }),\n }),\n message: z.string().nullable().optional(),\n});\n\nexport type NegotiationTurn = z.infer<typeof NegotiationTurnSchema>;\n\n/** Zod schema for the negotiation outcome (Artifact payload on COMPLETED task). */\nexport const NegotiationOutcomeSchema = z.object({\n hasOpportunity: z.boolean(),\n agreedRoles: z.array(z.object({\n userId: z.string(),\n role: z.enum([\"agent\", \"patient\", \"peer\"]),\n })),\n reasoning: z.string(),\n turnCount: z.number(),\n reason: z.enum([\"turn_cap\", \"timeout\"]).optional(),\n});\n\nexport type NegotiationOutcome = z.infer<typeof NegotiationOutcomeSchema>;\n\n/** Context each agent receives about its user. */\nexport interface UserNegotiationContext {\n id: string;\n intents: Array<{ id: string; title: string; description: string; confidence: number }>;\n profile: { name?: string; bio?: string; location?: string; interests?: string[]; skills?: string[] };\n}\n\n/** Seed assessment from the evaluator pre-filter. */\nexport interface SeedAssessment {\n reasoning: string;\n valencyRole: string;\n actors?: Array<{ userId: string; role: string }>;\n}\n\n/** Typed interface for a negotiation graph's invoke signature. */\nexport interface NegotiationGraphLike {\n invoke(input: {\n sourceUser: UserNegotiationContext;\n candidateUser: UserNegotiationContext;\n indexContext: { networkId: string; prompt: string };\n seedAssessment: Omit<SeedAssessment, \"actors\">;\n discoveryQuery?: string;\n opportunityId?: string;\n maxTurns?: number;\n timeoutMs?: number;\n /**\n * The user who holds the initiating seat for this match (v2 client-advocate\n * protocol). Stamped into task metadata by the init node. When omitted, the\n * init node resolves it: inherit from the prior task for the same\n * opportunity → conversation-scoped tie-break → fall back to sourceUser.id.\n */\n initiatorUserId?: string;\n }): Promise<{\n outcome: NegotiationOutcome | null;\n messages?: NegotiationMessage[];\n conversationId?: string;\n isContinuation?: boolean;\n priorTurnCount?: number;\n }>;\n}\n\n/** A2A message record shape (matches messages table). */\nexport interface NegotiationMessage {\n id: string;\n senderId: string;\n role: \"agent\";\n parts: unknown[];\n createdAt: Date;\n}\n\n/** LangGraph state annotation for the negotiation graph. */\nexport const NegotiationGraphState = Annotation.Root({\n sourceUser: Annotation<UserNegotiationContext>({\n reducer: (curr, next) => next ?? curr,\n default: () => ({ id: \"\", intents: [], profile: {} }),\n }),\n candidateUser: Annotation<UserNegotiationContext>({\n reducer: (curr, next) => next ?? curr,\n default: () => ({ id: \"\", intents: [], profile: {} }),\n }),\n indexContext: Annotation<{ networkId: string; prompt: string }>({\n reducer: (curr, next) => next ?? curr,\n default: () => ({ networkId: \"\", prompt: \"\" }),\n }),\n seedAssessment: Annotation<SeedAssessment>({\n reducer: (curr, next) => next ?? curr,\n default: () => ({ reasoning: \"\", valencyRole: \"\" }),\n }),\n\n /**\n * Explicit initiator seat for this match (purely additive metadata — no seat\n * rules attach to it yet). Resolution when unset happens in the init node;\n * the resolved value is written back to state and into task metadata.\n */\n initiatorUserId: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n\n /** The explicit search query that triggered discovery (if any). */\n discoveryQuery: Annotation<string | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n /**\n * Negotiation protocol version for this session's task. Resolved by the\n * init node: inherited from the prior task on the conversation when one\n * exists (never re-stamped — a v1 conversation stays v1 mid-flight), else\n * stamped from `NEGOTIATION_PROTOCOL_VERSION` for genuinely fresh runs.\n */\n protocolVersion: Annotation<NegotiationProtocolVersion>({\n reducer: (curr, next) => next ?? curr,\n default: () => \"v1\" as const,\n }),\n\n /** Whether this run is continuing a prior conversation with the same pair. */\n isContinuation: Annotation<boolean>({\n reducer: (curr, next) => next ?? curr,\n default: () => false,\n }),\n opportunityId: Annotation<string>({\n reducer: (curr, next) => next ?? curr,\n default: () => \"\",\n }),\n conversationId: Annotation<string>({\n reducer: (curr, next) => next ?? curr,\n default: () => \"\",\n }),\n taskId: Annotation<string>({\n reducer: (curr, next) => next ?? curr,\n default: () => \"\",\n }),\n messages: Annotation<NegotiationMessage[]>({\n reducer: (curr, next) => [...curr, ...(next || [])],\n default: () => [],\n }),\n turnCount: Annotation<number>({\n reducer: (curr, next) => next ?? curr,\n default: () => 0,\n }),\n maxTurns: Annotation<number | undefined>({\n reducer: (curr, next) => next ?? curr,\n default: () => undefined,\n }),\n /**\n * Park-window budget in milliseconds. Ambient callers pass `AMBIENT_PARK_WINDOW_MS`\n * (5 minutes); orchestrator callers pass a shorter window. This annotation default\n * is a safety net for any caller that omits the field — keep it aligned with\n * `AMBIENT_PARK_WINDOW_MS` in packages/protocol/src/negotiation/negotiation.tools.ts.\n * Inlined rather than imported to avoid a state↔tools cycle.\n */\n timeoutMs: Annotation<number>({\n reducer: (curr, next) => next ?? curr,\n default: () => 5 * 60 * 1000,\n }),\n\n currentSpeaker: Annotation<\"source\" | \"candidate\">({\n reducer: (curr, next) => next ?? curr,\n default: () => \"source\" as const,\n }),\n lastTurn: Annotation<NegotiationTurn | null>({\n reducer: (curr, next) => next ?? curr,\n default: () => null,\n }),\n\n /**\n * Graph status.\n * - `active` — agents are exchanging turns (default)\n * - `waiting_for_agent` — graph suspended; awaiting external agent response or timeout\n * - `completed` — negotiation finalized (accept/reject/turn-cap/timeout)\n */\n status: Annotation<'active' | 'waiting_for_agent' | 'completed'>({\n reducer: (curr, next) => next ?? curr,\n default: () => 'active' as const,\n }),\n\n /** Number of turns present in the conversation before this session started. */\n priorTurnCount: Annotation<number>({\n reducer: (curr, next) => next ?? curr,\n default: () => 0,\n }),\n\n /** User answers collected by the questioner between negotiation sessions. */\n userAnswers: Annotation<NegotiationUserAnswer[]>({\n reducer: (curr, next) => next ?? curr,\n default: () => [],\n }),\n\n outcome: Annotation<NegotiationOutcome | null>({\n reducer: (curr, next) => next ?? curr,\n default: () => null,\n }),\n error: Annotation<string | null>({\n reducer: (curr, next) => next ?? curr,\n default: () => null,\n }),\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiation.tools.d.ts","sourceRoot":"/","sources":["negotiation/negotiation.tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"negotiation.tools.d.ts","sourceRoot":"/","sources":["negotiation/negotiation.tools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAY5E;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAiCpD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,4BAg2B5E"}
|