import { z } from "zod"; import type { NegotiationContinuationExecution, NegotiationContinuationReceipt, NegotiationPrivateConsultation, NegotiationUserAnswer, OpportunityStatus } from "../../shared/interfaces/database.interface.js"; import type { ScreenDecisionRecord } from "./negotiation.screen.contracts.js"; import type { DeadlockShiftRecord } from "./negotiation.deadlock.contracts.js"; import type { NegotiatorMemoryEntry } from "./negotiation.memory.js"; import { type NegotiationProtocolVersion } from "../../shared/schemas/negotiation-state.schema.js"; /** * Zod schema for a single negotiation turn (DataPart payload in A2A message). * Accepts the full v1+v2 action union — which subset is valid for a given turn * is enforced by the seat-scoped schemas in `negotiation.protocol.ts`. */ export declare const NegotiationTurnSchema: z.ZodObject<{ action: z.ZodEnum<["propose", "accept", "reject", "counter", "question", "outreach", "withdraw", "decline", "ask_user"]>; assessment: z.ZodObject<{ reasoning: z.ZodString; suggestedRoles: z.ZodObject<{ ownUser: z.ZodEnum<["agent", "patient", "peer"]>; otherUser: z.ZodEnum<["agent", "patient", "peer"]>; }, "strip", z.ZodTypeAny, { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }, { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }>; }, "strip", z.ZodTypeAny, { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }, { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }>; message: z.ZodOptional>; /** Present when action is `ask_user` (v2, P3.2). */ askUser: z.ZodOptional; }, "strict", z.ZodTypeAny, { reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority"; }, { reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority"; }>>>; }, "strip", z.ZodTypeAny, { action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user"; assessment: { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }; message?: string | null | undefined; askUser?: { reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority"; } | null | undefined; }, { action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user"; assessment: { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }; message?: string | null | undefined; askUser?: { reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority"; } | null | undefined; }>; /** Restricted v1 turn schema for the system agent (no question action). */ export declare const SystemNegotiationTurnSchema: z.ZodObject<{ action: z.ZodEnum<["propose", "accept", "reject", "counter"]>; assessment: z.ZodObject<{ reasoning: z.ZodString; suggestedRoles: z.ZodObject<{ ownUser: z.ZodEnum<["agent", "patient", "peer"]>; otherUser: z.ZodEnum<["agent", "patient", "peer"]>; }, "strip", z.ZodTypeAny, { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }, { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }>; }, "strip", z.ZodTypeAny, { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }, { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }>; message: z.ZodOptional>; }, "strip", z.ZodTypeAny, { action: "propose" | "accept" | "reject" | "counter"; assessment: { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }; message?: string | null | undefined; }, { action: "propose" | "accept" | "reject" | "counter"; assessment: { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }; message?: string | null | undefined; }>; /** v1 turn schema for system agent's final allowed turn (must decide). */ export declare const FinalNegotiationTurnSchema: z.ZodObject<{ action: z.ZodEnum<["accept", "reject"]>; assessment: z.ZodObject<{ reasoning: z.ZodString; suggestedRoles: z.ZodObject<{ ownUser: z.ZodEnum<["agent", "patient", "peer"]>; otherUser: z.ZodEnum<["agent", "patient", "peer"]>; }, "strip", z.ZodTypeAny, { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }, { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }>; }, "strip", z.ZodTypeAny, { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }, { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }>; message: z.ZodOptional>; }, "strip", z.ZodTypeAny, { action: "accept" | "reject"; assessment: { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }; message?: string | null | undefined; }, { action: "accept" | "reject"; assessment: { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }; message?: string | null | undefined; }>; export type NegotiationTurn = z.infer; /** Zod schema for the negotiation outcome (Artifact payload on COMPLETED task). */ export declare const NegotiationOutcomeSchema: z.ZodObject<{ hasOpportunity: z.ZodBoolean; agreedRoles: z.ZodArray; }, "strip", z.ZodTypeAny, { userId: string; role: "agent" | "patient" | "peer"; }, { userId: string; role: "agent" | "patient" | "peer"; }>, "many">; reasoning: z.ZodString; turnCount: z.ZodNumber; reason: z.ZodOptional>; }, "strip", z.ZodTypeAny, { reasoning: string; hasOpportunity: boolean; agreedRoles: { userId: string; role: "agent" | "patient" | "peer"; }[]; turnCount: number; reason?: "timeout" | "turn_cap" | "screened_out" | undefined; }, { reasoning: string; hasOpportunity: boolean; agreedRoles: { userId: string; role: "agent" | "patient" | "peer"; }[]; turnCount: number; reason?: "timeout" | "turn_cap" | "screened_out" | undefined; }>; export type NegotiationOutcome = z.infer; /** Context each agent receives about its user. */ export interface UserNegotiationContext { id: string; intents: Array<{ id: string; title: string; description: string; confidence: number; }>; profile: { name?: string; bio?: string; location?: string; interests?: string[]; skills?: string[]; }; } /** Seed assessment from the evaluator pre-filter. */ export interface SeedAssessment { reasoning: string; valencyRole: string; actors?: Array<{ userId: string; role: string; }>; } /** Typed interface for a negotiation graph's invoke signature. */ export interface NegotiationGraphLike { invoke(input: { sourceUser: UserNegotiationContext; candidateUser: UserNegotiationContext; /** Exact opportunity-actor intent bindings; never inferred from intent array order. */ sourceIntentId?: string; candidateIntentId?: string; indexContext: { networkId: string; prompt: string; }; seedAssessment: Omit; discoveryQuery?: string; opportunityId?: string; /** Exact persisted lifecycle state claimed by this negotiation attempt. */ opportunityStatus?: OpportunityStatus; opportunityUpdatedAt?: Date; maxTurns?: number; timeoutMs?: number; /** * The user who holds the initiating seat for this match (v2 client-advocate * protocol). Stamped into task metadata by the init node. When omitted, the * init node resolves it: inherit from the prior task for the same * opportunity → conversation-scoped tie-break → fall back to sourceUser.id. */ initiatorUserId?: string; /** Exact settled task for a durable ask_user continuation. */ resumeFromTaskId?: string; /** Deterministic durable settlement/outbox identifier. */ continuationSettlementId?: string; /** Current durable lease/fence for the exact successor execution. */ continuationExecution?: NegotiationContinuationExecution; }): Promise<{ outcome: NegotiationOutcome | null; messages?: NegotiationMessage[]; conversationId?: string; isContinuation?: boolean; priorTurnCount?: number; error?: string | null; continuationReceipt?: NegotiationContinuationReceipt; }>; } /** A2A message record shape (matches messages table). */ export interface NegotiationMessage { id: string; senderId: string; role: "agent"; parts: unknown[]; createdAt: Date; /** * Originating negotiation task (IND-569). Seeded prior messages carry their * source task's id; turns persisted this session carry the current task id. * Optional/undefined for legacy hosts whose `getMessagesForConversation` * does not project task attribution — such turns degrade to the unattributed * prior-dialogue block, never into the current opportunity's turns. */ taskId?: string | null; } /** LangGraph state annotation for the negotiation graph. */ export declare const NegotiationGraphState: import("@langchain/langgraph").AnnotationRoot<{ sourceUser: import("@langchain/langgraph").BaseChannel, unknown>; candidateUser: import("@langchain/langgraph").BaseChannel, unknown>; sourceIntentId: import("@langchain/langgraph").BaseChannel | undefined, unknown>; candidateIntentId: import("@langchain/langgraph").BaseChannel | undefined, unknown>; indexContext: import("@langchain/langgraph").BaseChannel<{ networkId: string; prompt: string; }, { networkId: string; prompt: string; } | import("@langchain/langgraph").OverwriteValue<{ networkId: string; prompt: string; }>, unknown>; seedAssessment: import("@langchain/langgraph").BaseChannel, unknown>; /** * Explicit initiator seat for this match (purely additive metadata — no seat * rules attach to it yet). Resolution when unset happens in the init node; * the resolved value is written back to state and into task metadata. */ initiatorUserId: import("@langchain/langgraph").BaseChannel | undefined, unknown>; /** The explicit search query that triggered discovery (if any). */ discoveryQuery: import("@langchain/langgraph").BaseChannel | undefined, unknown>; /** * Negotiation protocol version for this session's task. Resolved by the * init node: inherited from the prior task on the conversation when one * exists (never re-stamped — a v1 conversation stays v1 mid-flight), else * stamped from `NEGOTIATION_PROTOCOL_VERSION` for genuinely fresh runs. */ protocolVersion: import("@langchain/langgraph").BaseChannel, unknown>; /** * Screen-gate decision for this fresh run (P2.1 shadow mode). Written by the * screen node; null when the gate is off, on continuations, or before the * node runs. Mirrors `tasks.metadata.screenDecision`. */ screenDecision: import("@langchain/langgraph").BaseChannel | null, unknown>; /** * First applied deadlock→bargaining shift in this session (IND-428). * Written by the turn node when the system agent first drafts in the * bargaining stance; used to record the shift exactly once per session. * Internal analytics only — mirrored to `tasks.metadata.deadlockShift`, * never into any turn payload or public projection. */ deadlockShift: import("@langchain/langgraph").BaseChannel | null, unknown>; /** * Per-side negotiator-memory cache (P5.3 read path). Populated lazily the * first time each side's memory is retrieved (screen node for the client, * turn node for the speaker) so a multi-turn session pays for retrieval at * most once per side. `undefined` per side = not yet retrieved; `[]` = * retrieved and empty (flag off / no rows / retrieval failed). */ memoryBySide: import("@langchain/langgraph").BaseChannel>, Partial> | import("@langchain/langgraph").OverwriteValue>>, unknown>; /** Whether this run is continuing a prior conversation with the same pair. */ isContinuation: import("@langchain/langgraph").BaseChannel, unknown>; /** * Immutable attributed prior dialogue derived once in the init node from the * seeded prior messages (IND-569). Groups earlier-opportunity turns and * legacy unattributed turns so the screen node and every turn prompt can * label prior context per opportunity. Null on fresh runs / when there is no * seeded prior dialogue. Typed as `unknown` to avoid a module cycle * (attribution module imports NegotiationTurn from this module's shim); * callers cast to `SeededAttribution` via the negotiation.attribution module. */ priorAttribution: import("@langchain/langgraph").BaseChannel; /** * Whether the initiator has actually opened `outreach` within THIS task * (IND-564). Set by the turn node the first time an `outreach` turn is * persisted in the current session; seeded prior-task turns never flip it. * `withdraw` is only legal after an in-task outreach — a withdraw before one * would retract an outreach never made here and drop a spurious message into * the shared thread, so the turn node maps it to a quiet screen-out instead. */ outreachOpened: import("@langchain/langgraph").BaseChannel, unknown>; /** * Set by the turn node when an opening-move `withdraw` (no in-task outreach) * was blocked (IND-564). Signals finalize to record the quiet screen-out * outcome (`reason: "screened_out"`, opportunity `rejected`) without ever * persisting the withdraw message into the shared `dm_pair` conversation. */ firstTurnScreenedOut: import("@langchain/langgraph").BaseChannel, unknown>; opportunityId: import("@langchain/langgraph").BaseChannel, unknown>; /** Exact persisted lifecycle state claimed by this negotiation attempt. */ opportunityStatus: import("@langchain/langgraph").BaseChannel | undefined, unknown>; opportunityUpdatedAt: import("@langchain/langgraph").BaseChannel | undefined, unknown>; /** Exact prior task selected by a durable continuation; bypasses latest-task lookup. */ resumeFromTaskId: import("@langchain/langgraph").BaseChannel | undefined, unknown>; /** Deterministic settlement key used to idempotently reuse a successor task. */ continuationSettlementId: import("@langchain/langgraph").BaseChannel | undefined, unknown>; continuationExecution: import("@langchain/langgraph").BaseChannel | undefined, unknown>; continuationReceipt: import("@langchain/langgraph").BaseChannel | undefined, unknown>; privateConsultation: import("@langchain/langgraph").BaseChannel | undefined, unknown>; /** Server-only IND-508 category recovered from the exact prior task binding. */ consultationPolicyReason: import("@langchain/langgraph").BaseChannel<"unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority" | undefined, "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority" | import("@langchain/langgraph").OverwriteValue<"unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority" | undefined> | undefined, unknown>; conversationId: import("@langchain/langgraph").BaseChannel, unknown>; taskId: import("@langchain/langgraph").BaseChannel, unknown>; messages: import("@langchain/langgraph").BaseChannel, unknown>; turnCount: import("@langchain/langgraph").BaseChannel, unknown>; maxTurns: import("@langchain/langgraph").BaseChannel | undefined, unknown>; /** * Park-window budget in milliseconds. The annotation default is a safety net * for any caller that omits the field — keep it aligned with * `AMBIENT_PARK_WINDOW_MS` in packages/protocol/src/negotiation/negotiation.tools.ts. * Inlined rather than imported to avoid a state↔tools cycle. */ timeoutMs: import("@langchain/langgraph").BaseChannel, unknown>; currentSpeaker: import("@langchain/langgraph").BaseChannel<"source" | "candidate", "source" | "candidate" | import("@langchain/langgraph").OverwriteValue<"source" | "candidate">, unknown>; lastTurn: import("@langchain/langgraph").BaseChannel<{ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user"; assessment: { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }; message?: string | null | undefined; askUser?: { reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority"; } | null | undefined; } | null, { action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user"; assessment: { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }; message?: string | null | undefined; askUser?: { reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority"; } | null | undefined; } | import("@langchain/langgraph").OverwriteValue<{ action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user"; assessment: { reasoning: string; suggestedRoles: { ownUser: "agent" | "patient" | "peer"; otherUser: "agent" | "patient" | "peer"; }; }; message?: string | null | undefined; askUser?: { reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority"; } | null | undefined; } | null> | null, unknown>; /** * Graph status. * - `active` — agents are exchanging turns (default) * - `waiting_for_agent` — graph suspended; awaiting external agent response or timeout * - `input_required` — graph suspended on an `ask_user` pause; awaiting the * negotiator's own client (answer or 24 h window expiry resumes it) * - `completed` — negotiation finalized (accept/reject/turn-cap/timeout) */ status: import("@langchain/langgraph").BaseChannel<"waiting_for_agent" | "input_required" | "completed" | "active", "waiting_for_agent" | "input_required" | "completed" | "active" | import("@langchain/langgraph").OverwriteValue<"waiting_for_agent" | "input_required" | "completed" | "active">, unknown>; /** Number of turns present in the conversation before this session started. */ priorTurnCount: import("@langchain/langgraph").BaseChannel, unknown>; /** User answers collected by the questioner between negotiation sessions. */ userAnswers: import("@langchain/langgraph").BaseChannel, unknown>; outcome: import("@langchain/langgraph").BaseChannel<{ reasoning: string; hasOpportunity: boolean; agreedRoles: { userId: string; role: "agent" | "patient" | "peer"; }[]; turnCount: number; reason?: "timeout" | "turn_cap" | "screened_out" | undefined; } | null, { reasoning: string; hasOpportunity: boolean; agreedRoles: { userId: string; role: "agent" | "patient" | "peer"; }[]; turnCount: number; reason?: "timeout" | "turn_cap" | "screened_out" | undefined; } | import("@langchain/langgraph").OverwriteValue<{ reasoning: string; hasOpportunity: boolean; agreedRoles: { userId: string; role: "agent" | "patient" | "peer"; }[]; turnCount: number; reason?: "timeout" | "turn_cap" | "screened_out" | undefined; } | null> | null, unknown>; error: import("@langchain/langgraph").BaseChannel | null, unknown>; }>;