@indexnetwork/protocol 11.0.1-rc.455.1 → 11.1.0-rc.457.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/capabilities/negotiation.facade.d.ts +4 -1
- package/dist/capabilities/negotiation.facade.js +2 -1
- package/dist/capabilities/negotiation.questions.facade.d.ts +1 -1
- package/dist/capabilities/negotiation.questions.facade.js +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.js +5 -1
- package/dist/negotiation/application/negotiation.agent.d.ts +7 -1
- package/dist/negotiation/application/negotiation.agent.js +6 -4
- package/dist/negotiation/application/negotiation.detail-reader.js +3 -6
- package/dist/negotiation/application/negotiation.graph.d.ts +17 -29
- package/dist/negotiation/application/negotiation.graph.js +35 -49
- package/dist/negotiation/application/negotiation.tools.js +40 -43
- package/dist/negotiation/domain/index.d.ts +5 -0
- package/dist/negotiation/domain/index.js +4 -0
- package/dist/negotiation/domain/negotiation.consultation-policy.d.ts +2 -3
- package/dist/negotiation/domain/negotiation.expected-speaker.d.ts +19 -0
- package/dist/negotiation/domain/negotiation.expected-speaker.js +47 -0
- package/dist/negotiation/domain/negotiation.hermes-contract.d.ts +31 -0
- package/dist/negotiation/domain/negotiation.hermes-contract.js +72 -0
- package/dist/negotiation/domain/negotiation.protocol.d.ts +36 -66
- package/dist/negotiation/domain/negotiation.state.d.ts +10 -19
- package/dist/negotiation/domain/negotiation.turn-cap.d.ts +9 -0
- package/dist/negotiation/domain/negotiation.turn-cap.js +12 -0
- package/dist/negotiation/public/index.d.ts +4 -1
- package/dist/negotiation/public/index.js +3 -1
- package/dist/questions/application/question.input.d.ts +4 -8
- package/dist/questions/application/question.input.js +3 -8
- package/dist/questions/application/question.presets.js +10 -11
- package/dist/shared/agent/model-signal.d.ts +6 -1
- package/dist/shared/agent/model-signal.js +5 -2
- package/dist/shared/interfaces/agent-dispatcher.interface.d.ts +3 -0
- package/dist/shared/interfaces/database.interface.d.ts +1 -1
- package/dist/shared/interfaces/negotiation-events.interface.d.ts +12 -2
- package/dist/shared/schemas/negotiation-state.schema.d.ts +17 -23
- package/dist/shared/schemas/negotiation-state.schema.js +13 -8
- package/dist/signals/application/intake.orchestrator.d.ts +63 -13
- package/dist/signals/application/intake.orchestrator.js +107 -18
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -51,6 +51,8 @@ pin a supported release, use `latest`.
|
|
|
51
51
|
enrichment are unchanged.
|
|
52
52
|
|
|
53
53
|
### Added
|
|
54
|
+
- Add the Personal Agent Hermes negotiation-runtime contract (11.1.0). The public negotiation facade now exports `configuredAskUserEnabled` and `askUserAnswerWindowMs` for host-side owner-consultation admission, with regenerated consumer/export inventories. The generated Hermes negotiator skill receives a privacy-minimal structural envelope: server-provided seat, protocol version, deadlines, closed allowed actions, consultation eligibility, opportunity identifiers/status, and message-free history. Owner memory, private context, consultation text, evaluator reasoning, actor prose, and shared-message prose are excluded; each scheduled pass permits at most one response or owner consultation and treats all pickup prose as untrusted data.
|
|
55
|
+
- Add a live answer-first signal-intake eval with unrelated, relevant, and no-bridge profile cases plus provider-free corpus, runner, and scorer checks.
|
|
54
56
|
- Add the protocol-only Guided Atlas, deterministic architecture inventory
|
|
55
57
|
generator, and source-evidenced Configuration Lab. The atlas explains
|
|
56
58
|
normative concepts, the current `packages/protocol` reference implementation,
|
|
@@ -69,6 +71,7 @@ pin a supported release, use `latest`.
|
|
|
69
71
|
`SynthesisResult` types. Minor bump: additive surface only.
|
|
70
72
|
|
|
71
73
|
### Changed
|
|
74
|
+
- Make fast signal-intake follow-ups answer-first with a two-stage model boundary: an answer-only core call chooses the missing axis and supplies two or three concrete domain options, then an isolated bridge call may append at most one premise-derived profile option so an existing profile theme cannot dominate or reorder a newly stated intent.
|
|
72
75
|
- Remove unsupported deprecated source/deep forwarding shims after migrating repository consumers to canonical modules; stable package-root exports are unchanged.
|
|
73
76
|
- Add a fail-closed isolated provider-free test gate (10.1.1). Tooling-only
|
|
74
77
|
safety foundation; no runtime or public API behavior changes.
|
|
@@ -76,6 +79,9 @@ pin a supported release, use `latest`.
|
|
|
76
79
|
boundary gate and the protocol atlas generator; allowed dependency directions
|
|
77
80
|
are unchanged.
|
|
78
81
|
|
|
82
|
+
### Security
|
|
83
|
+
- The Hermes skill contract is restricted to the four negotiator tools, never treats model prose as authority, never forwards secrets or owner-private context, and relies on Index's validated action/consultation and bounded fallback paths. **This branch targets dev/private testing only. Production distribution remains blocked until the Mac owner credential is migrated to Keychain and the plaintext file/directory is removed, hardened runtime and App Sandbox are restored, the app is signed/notarized, and the credential TTL/revocation checklist is verified.**
|
|
84
|
+
|
|
79
85
|
### Fixed
|
|
80
86
|
- Add an independent complete-payload golden digest and stronger audit/report leak
|
|
81
87
|
sentinels for the historical discovery seed serializer, and clarify the H4 review
|
|
@@ -16,8 +16,11 @@ export { NegotiationReflector } from "../negotiation/public/index.js";
|
|
|
16
16
|
export type { DistilledMemory, ReflectionTranscriptEntry, NegotiationReflectionInput, ChatReflectionInput, NegotiationReflectJobData, ReflectEnqueueFn } from "../negotiation/public/index.js";
|
|
17
17
|
export type { NegotiatorMemoryEntry } from "../negotiation/public/index.js";
|
|
18
18
|
export type { NegotiationGraphLike } from "../negotiation/public/index.js";
|
|
19
|
+
export { HERMES_OWNER_DIRECTIVE, HERMES_SHARED_MESSAGE_TEMPLATES, HermesNegotiationActionSchema, HermesNegotiationResponseSchema, HermesOwnerDirectiveSchema, HermesRoleAlignmentSchema, allowedHermesActionsFor, buildHermesNegotiationTurn, } from "../negotiation/public/index.js";
|
|
20
|
+
export type { HermesNegotiationAction, HermesNegotiationResponse, HermesOwnerDirective, HermesRoleAlignment, } from "../negotiation/public/index.js";
|
|
19
21
|
export { AMBIENT_PARK_WINDOW_MS } from "../negotiation/public/index.js";
|
|
20
|
-
export { allowedActionsFor, isTerminalAction, isRejectLikeAction, readProtocolVersion, resolveSeat, seatViolationMessage } from "../negotiation/public/index.js";
|
|
22
|
+
export { DEFAULT_NEGOTIATION_MAX_TURNS, isNegotiationTurnCapReached, expectedNegotiationSpeaker, allowedActionsFor, askUserAnswerWindowMs, configuredAskUserEnabled, isTerminalAction, isRejectLikeAction, readProtocolVersion, resolveSeat, seatViolationMessage } from "../negotiation/public/index.js";
|
|
23
|
+
export type { NegotiationSpeakerParticipants, NegotiationSpeakerMessage } from "../negotiation/public/index.js";
|
|
21
24
|
export { assessConsultationEligibility, consultationPromptFor, negotiationConsultationPolicyMode } from "../negotiation/public/index.js";
|
|
22
25
|
export type { ConsultationEligibility, ConsultationEligibilityInput, NegotiationConsultationPolicyMode, NegotiationConsultationReason } from "../negotiation/public/index.js";
|
|
23
26
|
export { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, NEGOTIATION_QUESTION_GENERIC_UPTAKE_ACTIVITY, isSafeNegotiationQuestionText, validateInflightAskUserFields, negotiationQuestionSettlementId, } from "../negotiation/public/index.js";
|
|
@@ -11,7 +11,8 @@ export { NegotiationInsightsGenerator } from "../negotiation/public/index.js";
|
|
|
11
11
|
export { IndexNegotiator } from "../negotiation/public/index.js";
|
|
12
12
|
export { NegotiationScreener } from "../negotiation/public/index.js";
|
|
13
13
|
export { NegotiationReflector } from "../negotiation/public/index.js";
|
|
14
|
+
export { HERMES_OWNER_DIRECTIVE, HERMES_SHARED_MESSAGE_TEMPLATES, HermesNegotiationActionSchema, HermesNegotiationResponseSchema, HermesOwnerDirectiveSchema, HermesRoleAlignmentSchema, allowedHermesActionsFor, buildHermesNegotiationTurn, } from "../negotiation/public/index.js";
|
|
14
15
|
export { AMBIENT_PARK_WINDOW_MS } from "../negotiation/public/index.js";
|
|
15
|
-
export { allowedActionsFor, isTerminalAction, isRejectLikeAction, readProtocolVersion, resolveSeat, seatViolationMessage } from "../negotiation/public/index.js";
|
|
16
|
+
export { DEFAULT_NEGOTIATION_MAX_TURNS, isNegotiationTurnCapReached, expectedNegotiationSpeaker, allowedActionsFor, askUserAnswerWindowMs, configuredAskUserEnabled, isTerminalAction, isRejectLikeAction, readProtocolVersion, resolveSeat, seatViolationMessage } from "../negotiation/public/index.js";
|
|
16
17
|
export { assessConsultationEligibility, consultationPromptFor, negotiationConsultationPolicyMode } from "../negotiation/public/index.js";
|
|
17
18
|
export { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, NEGOTIATION_QUESTION_GENERIC_UPTAKE_ACTIVITY, isSafeNegotiationQuestionText, validateInflightAskUserFields, negotiationQuestionSettlementId, } from "../negotiation/public/index.js";
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Narrow question-policy port consumed by the Questions capability — IND-550.
|
|
3
3
|
* Sources now route through the canonical negotiation module public surface.
|
|
4
4
|
*/
|
|
5
|
-
export { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, NEGOTIATION_QUESTION_GENERIC_UPTAKE_ACTIVITY, isSafeNegotiationQuestionText, } from "../negotiation/public/index.js";
|
|
5
|
+
export { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, NEGOTIATION_QUESTION_GENERIC_UPTAKE_ACTIVITY, consultationPromptFor, isSafeNegotiationQuestionText, } from "../negotiation/public/index.js";
|
|
6
6
|
export type { NegotiationConsultationReason } from "../negotiation/public/index.js";
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Narrow question-policy port consumed by the Questions capability — IND-550.
|
|
3
3
|
* Sources now route through the canonical negotiation module public surface.
|
|
4
4
|
*/
|
|
5
|
-
export { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, NEGOTIATION_QUESTION_GENERIC_UPTAKE_ACTIVITY, isSafeNegotiationQuestionText, } from "../negotiation/public/index.js";
|
|
5
|
+
export { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, NEGOTIATION_QUESTION_GENERIC_UPTAKE_ACTIVITY, consultationPromptFor, isSafeNegotiationQuestionText, } from "../negotiation/public/index.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type { IntegrationAdapter, IntegrationConnection, IntegrationSession, Int
|
|
|
21
21
|
export type { IntentGraphQueue } from "./shared/interfaces/queue.interface.js";
|
|
22
22
|
export type { Scraper } from "./shared/interfaces/scraper.interface.js";
|
|
23
23
|
export type { EnrichmentRunInput, EnrichmentRunRecord } from "./shared/interfaces/enrichment-run.interface.js";
|
|
24
|
-
export type { NegotiationTimeoutQueue, AskUserExpiryPayload } from "./shared/interfaces/negotiation-events.interface.js";
|
|
24
|
+
export type { NegotiationTimeoutQueue, AskUserExpiryPayload, NegotiationContinuationTimeoutIdentity, } from "./shared/interfaces/negotiation-events.interface.js";
|
|
25
25
|
export type { AgentDispatcher, AgentDispatchResult, NegotiationTurnPayload } from "./shared/interfaces/agent-dispatcher.interface.js";
|
|
26
26
|
export { SYSTEM_AGENT_IDS } from './capabilities/participant-agents.facade.js';
|
|
27
27
|
export { ChatContextDigestSchema, type ChatContextDigest } from "./shared/schemas/chat-context.schema.js";
|
|
@@ -151,10 +151,14 @@ export { MCP_AGENT_ADMIN_TOOLS, CANONICAL_MCP_CAPABILITY_POLICY_OPTIONS, CANONIC
|
|
|
151
151
|
export { ActivityQuestionCountsSchema, ActivityQuestionDomainSchema, ActivitySummaryDomainSchema, ActivitySummaryResponseSchema, McpActivityCallerSchema, QUESTION_MODE_TO_DOMAIN, READ_ACTIVITY_SUMMARY_TOOL_NAME, activitySummaryNetworkId, projectActivitySummary, resolveActivitySummaryDomains, } from "./shared/agent/activity-projection.js";
|
|
152
152
|
export type { ActivityQuestionCounts, ActivityQuestionDomain, ActivitySummaryDomain, McpActivityCaller, ProjectedActivitySummary, } from "./shared/agent/activity-projection.js";
|
|
153
153
|
export type { McpAuthorizationDenialEvent, McpAuthorizationObserver, McpCapabilityDecision, McpCapabilityDecisionReason, McpCapabilityPolicyOptions, McpCapabilitySubject, McpPermissionAction, McpPolicyAgentSnapshot, McpPrincipalProfile, McpToolPermissionMap, McpToolPermissionRequirement, McpToolAccessRule, McpToolAccessRuleMap, ResolveMcpCapabilitySubjectInput, } from "./mcp/mcp.authorization-policy.js";
|
|
154
|
+
export { AskUserPayloadSchema, NEGOTIATION_CONSULTATION_REASONS, NegotiationConsultationReasonSchema, } from "./shared/schemas/negotiation-state.schema.js";
|
|
154
155
|
export type { UserNegotiationContext, NegotiationTurn, NegotiationOutcome, SeedAssessment } from "./shared/schemas/negotiation-state.schema.js";
|
|
155
|
-
export type { NegotiationAction, NegotiationSeat, NegotiationProtocolVersion } from "./shared/schemas/negotiation-state.schema.js";
|
|
156
|
+
export type { NegotiationAction, NegotiationConsultationReason, NegotiationSeat, NegotiationProtocolVersion } from "./shared/schemas/negotiation-state.schema.js";
|
|
156
157
|
export type { NegotiationGraphLike } from "./capabilities/negotiation.facade.js";
|
|
157
|
-
export {
|
|
158
|
+
export { HERMES_OWNER_DIRECTIVE, HERMES_SHARED_MESSAGE_TEMPLATES, HermesNegotiationActionSchema, HermesNegotiationResponseSchema, HermesOwnerDirectiveSchema, HermesRoleAlignmentSchema, allowedHermesActionsFor, buildHermesNegotiationTurn, } from "./capabilities/negotiation.facade.js";
|
|
159
|
+
export type { HermesNegotiationAction, HermesNegotiationResponse, HermesOwnerDirective, HermesRoleAlignment, } from "./capabilities/negotiation.facade.js";
|
|
160
|
+
export { DEFAULT_NEGOTIATION_MAX_TURNS, isNegotiationTurnCapReached, expectedNegotiationSpeaker, allowedActionsFor, askUserAnswerWindowMs, configuredAskUserEnabled, isTerminalAction, isRejectLikeAction, readProtocolVersion, resolveSeat, seatViolationMessage } from "./capabilities/negotiation.facade.js";
|
|
161
|
+
export type { NegotiationSpeakerParticipants, NegotiationSpeakerMessage } from "./capabilities/negotiation.facade.js";
|
|
158
162
|
export { assessConsultationEligibility, consultationPromptFor, negotiationConsultationPolicyMode } from "./capabilities/negotiation.facade.js";
|
|
159
|
-
export type { ConsultationEligibility, ConsultationEligibilityInput, NegotiationConsultationPolicyMode
|
|
163
|
+
export type { ConsultationEligibility, ConsultationEligibilityInput, NegotiationConsultationPolicyMode } from "./capabilities/negotiation.facade.js";
|
|
160
164
|
export { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, NEGOTIATION_QUESTION_GENERIC_UPTAKE_ACTIVITY, isSafeNegotiationQuestionText, negotiationQuestionSettlementId, validateInflightAskUserFields, } from "./capabilities/negotiation.facade.js";
|
package/dist/index.js
CHANGED
|
@@ -121,7 +121,11 @@ export { normalizeTelegramHandle } from './shared/utils/telegram-handle.js';
|
|
|
121
121
|
export { createMcpServer, buildMcpOnboardingMessage, ONBOARDING_ALLOWED } from "./mcp/mcp.server.js";
|
|
122
122
|
export { MCP_AGENT_ADMIN_TOOLS, CANONICAL_MCP_CAPABILITY_POLICY_OPTIONS, CANONICAL_MCP_TOOL_ACCESS_RULES, MCP_INFORMATIONAL_TOOLS, MCP_PERMISSION_ACTIONS, McpCapabilityPolicy, McpCapabilitySubjectSchema, McpPermissionActionSchema, McpPolicyAgentSnapshotSchema, McpPrincipalProfileSchema, McpToolPermissionRequirementSchema, McpToolAccessRuleSchema, buildMcpAuthorizationDenialEvent, defineMcpToolAccessRules, defineMcpToolPermissionMap, resolveMcpActivityCaller, resolveMcpCapabilitySubject, } from "./mcp/mcp.authorization-policy.js";
|
|
123
123
|
export { ActivityQuestionCountsSchema, ActivityQuestionDomainSchema, ActivitySummaryDomainSchema, ActivitySummaryResponseSchema, McpActivityCallerSchema, QUESTION_MODE_TO_DOMAIN, READ_ACTIVITY_SUMMARY_TOOL_NAME, activitySummaryNetworkId, projectActivitySummary, resolveActivitySummaryDomains, } from "./shared/agent/activity-projection.js";
|
|
124
|
+
// ─── States (for advanced graph consumers) ────────────────────────────────────
|
|
125
|
+
// @experimental — internal graph-state shapes; may change in a minor release.
|
|
126
|
+
export { AskUserPayloadSchema, NEGOTIATION_CONSULTATION_REASONS, NegotiationConsultationReasonSchema, } from "./shared/schemas/negotiation-state.schema.js";
|
|
127
|
+
export { HERMES_OWNER_DIRECTIVE, HERMES_SHARED_MESSAGE_TEMPLATES, HermesNegotiationActionSchema, HermesNegotiationResponseSchema, HermesOwnerDirectiveSchema, HermesRoleAlignmentSchema, allowedHermesActionsFor, buildHermesNegotiationTurn, } from "./capabilities/negotiation.facade.js";
|
|
124
128
|
// ─── Negotiation seat rules (v2 client-advocate protocol) ───────────────────
|
|
125
|
-
export { allowedActionsFor, isTerminalAction, isRejectLikeAction, readProtocolVersion, resolveSeat, seatViolationMessage } from "./capabilities/negotiation.facade.js";
|
|
129
|
+
export { DEFAULT_NEGOTIATION_MAX_TURNS, isNegotiationTurnCapReached, expectedNegotiationSpeaker, allowedActionsFor, askUserAnswerWindowMs, configuredAskUserEnabled, isTerminalAction, isRejectLikeAction, readProtocolVersion, resolveSeat, seatViolationMessage } from "./capabilities/negotiation.facade.js";
|
|
126
130
|
export { assessConsultationEligibility, consultationPromptFor, negotiationConsultationPolicyMode } from "./capabilities/negotiation.facade.js";
|
|
127
131
|
export { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, NEGOTIATION_QUESTION_GENERIC_UPTAKE_ACTIVITY, isSafeNegotiationQuestionText, negotiationQuestionSettlementId, validateInflightAskUserFields, } from "./capabilities/negotiation.facade.js";
|
|
@@ -69,6 +69,12 @@ export interface NegotiationAgentInput {
|
|
|
69
69
|
* falls back to the flat continuation history (byte-identical to before).
|
|
70
70
|
*/
|
|
71
71
|
priorDialogue?: AttributedPriorDialogue;
|
|
72
|
+
/**
|
|
73
|
+
* Durable caller-owned execution identity. Timeout workers reuse this exact
|
|
74
|
+
* value across delivery retries; it is forwarded as model-run metadata for
|
|
75
|
+
* deterministic provider tracing/idempotency without entering the prompt.
|
|
76
|
+
*/
|
|
77
|
+
executionId?: string;
|
|
72
78
|
}
|
|
73
79
|
export interface IndexNegotiatorConfig {
|
|
74
80
|
/**
|
|
@@ -106,5 +112,5 @@ export declare class IndexNegotiator {
|
|
|
106
112
|
protected callModel(model: ReturnType<typeof createStructuredModel>, chatMessages: Array<{
|
|
107
113
|
role: string;
|
|
108
114
|
content: string;
|
|
109
|
-
}
|
|
115
|
+
}>, executionId?: string): Promise<unknown>;
|
|
110
116
|
}
|
|
@@ -56,7 +56,7 @@ const V2_INITIATOR_RULES = `- You hold the INITIATING seat: your user's side sur
|
|
|
56
56
|
* prompt (or the schema) otherwise.
|
|
57
57
|
*/
|
|
58
58
|
const ASK_USER_RULE = `
|
|
59
|
-
- "ask_user" if you need {userName}'s OWN input before you can proceed
|
|
59
|
+
- "ask_user" if you need {userName}'s OWN input before you can proceed. This PAUSES the negotiation until they answer (up to 24h), so use it only when proceeding without their input would risk over-disclosure or a wrong call. You get AT MOST ONE client consultation per negotiation. Set askUser to exactly one closed server category: { reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority" }. Never write question text or instructions in askUser; the server owns all owner-facing copy. Use "question" (not "ask_user") when clarification should come from the other side.`;
|
|
60
60
|
/** v2 counterparty seat: receiving stance — acceptance is this seat's decision alone. */
|
|
61
61
|
const V2_COUNTERPARTY_RULES = `- You hold the RECEIVING seat: the other side reached out to {userName}. Whether to accept is YOUR seat's decision alone.
|
|
62
62
|
- Evaluate the initiator's arguments. Either:
|
|
@@ -233,7 +233,7 @@ ${input.history.length === 0 && !input.isContinuation ? (version === "v2" && sea
|
|
|
233
233
|
// out-of-vocabulary actions. Validate; retry once; then fall back to the
|
|
234
234
|
// conservative seat-valid action instead of poisoning the turn history.
|
|
235
235
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
236
|
-
const result = await this.callModel(model, chatMessages);
|
|
236
|
+
const result = await this.callModel(model, chatMessages, input.executionId);
|
|
237
237
|
const parsed = schema.safeParse(result);
|
|
238
238
|
if (parsed.success)
|
|
239
239
|
return parsed.data;
|
|
@@ -262,7 +262,9 @@ ${input.history.length === 0 && !input.isContinuation ? (version === "v2" && sea
|
|
|
262
262
|
* Raw structured-model round trip. Split out as a seam so tests can drive
|
|
263
263
|
* the validate→retry→fallback loop without a live provider.
|
|
264
264
|
*/
|
|
265
|
-
async callModel(model, chatMessages) {
|
|
266
|
-
return invokeWithAbortSignal(model, chatMessages, AbortSignal.timeout(this.turnTimeoutMs)
|
|
265
|
+
async callModel(model, chatMessages, executionId) {
|
|
266
|
+
return invokeWithAbortSignal(model, chatMessages, AbortSignal.timeout(this.turnTimeoutMs), executionId
|
|
267
|
+
? { metadata: { timeoutExecutionId: executionId }, tags: ['negotiation-timeout'] }
|
|
268
|
+
: undefined);
|
|
267
269
|
}
|
|
268
270
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { expectedNegotiationSpeaker } from '../domain/negotiation.expected-speaker.js';
|
|
1
2
|
import { buildLifecycleNarration } from '../domain/negotiation.lifecycle-narration.js';
|
|
2
3
|
import { allowedActionsFor, readProtocolVersion, resolveSeat } from '../domain/negotiation.protocol.js';
|
|
3
4
|
/**
|
|
@@ -53,16 +54,12 @@ export async function readAuthorizedNegotiationDetail(input) {
|
|
|
53
54
|
? outcomeArtifact.parts?.find((part) => part.kind === 'data')?.data
|
|
54
55
|
: null;
|
|
55
56
|
const turnCount = messages.length;
|
|
56
|
-
const
|
|
57
|
-
const currentSpeaker = lastSenderId
|
|
58
|
-
? (lastSenderId === `agent:${metadata.sourceUserId}` ? 'candidate' : 'source')
|
|
59
|
-
: (turnCount % 2 === 0 ? 'source' : 'candidate');
|
|
57
|
+
const expectedSpeaker = expectedNegotiationSpeaker(metadata, messages);
|
|
60
58
|
const status = task.state === 'working' ? 'active'
|
|
61
59
|
: task.state === 'waiting_for_agent' ? 'waiting_for_agent'
|
|
62
60
|
: task.state === 'completed' ? 'completed'
|
|
63
61
|
: task.state;
|
|
64
|
-
const isUsersTurn = status !== 'completed' &&
|
|
65
|
-
((isSource && currentSpeaker === 'source') || (!isSource && currentSpeaker === 'candidate'));
|
|
62
|
+
const isUsersTurn = status !== 'completed' && expectedSpeaker === callerUserId;
|
|
66
63
|
const protocolVersion = readProtocolVersion(metadata) ?? 'v1';
|
|
67
64
|
const seat = resolveSeat(callerUserId, metadata);
|
|
68
65
|
const priorTurnCount = metadata.priorTurnCount ?? 0;
|
|
@@ -50,7 +50,7 @@ export declare class NegotiationGraphFactory {
|
|
|
50
50
|
continuationExecution: import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | undefined;
|
|
51
51
|
continuationReceipt: NegotiationContinuationReceipt | undefined;
|
|
52
52
|
privateConsultation: import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | undefined;
|
|
53
|
-
consultationPolicyReason:
|
|
53
|
+
consultationPolicyReason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority" | undefined;
|
|
54
54
|
conversationId: string;
|
|
55
55
|
taskId: string;
|
|
56
56
|
messages: import("../domain/negotiation.state.js").NegotiationMessage[];
|
|
@@ -69,8 +69,7 @@ export declare class NegotiationGraphFactory {
|
|
|
69
69
|
};
|
|
70
70
|
message?: string | null | undefined;
|
|
71
71
|
askUser?: {
|
|
72
|
-
|
|
73
|
-
draftQuestion?: string | null | undefined;
|
|
72
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
74
73
|
} | null | undefined;
|
|
75
74
|
} | null;
|
|
76
75
|
status: "waiting_for_agent" | "input_required" | "completed" | "active";
|
|
@@ -118,7 +117,7 @@ export declare class NegotiationGraphFactory {
|
|
|
118
117
|
continuationExecution?: import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | import("@langchain/langgraph").OverwriteValue<import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | undefined> | undefined;
|
|
119
118
|
continuationReceipt?: NegotiationContinuationReceipt | import("@langchain/langgraph").OverwriteValue<NegotiationContinuationReceipt | undefined> | undefined;
|
|
120
119
|
privateConsultation?: import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | import("@langchain/langgraph").OverwriteValue<import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | undefined> | undefined;
|
|
121
|
-
consultationPolicyReason?:
|
|
120
|
+
consultationPolicyReason?: "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;
|
|
122
121
|
conversationId?: string | import("@langchain/langgraph").OverwriteValue<string> | undefined;
|
|
123
122
|
taskId?: string | import("@langchain/langgraph").OverwriteValue<string> | undefined;
|
|
124
123
|
messages?: import("../domain/negotiation.state.js").NegotiationMessage[] | import("@langchain/langgraph").OverwriteValue<import("../domain/negotiation.state.js").NegotiationMessage[]> | undefined;
|
|
@@ -137,8 +136,7 @@ export declare class NegotiationGraphFactory {
|
|
|
137
136
|
};
|
|
138
137
|
message?: string | null | undefined;
|
|
139
138
|
askUser?: {
|
|
140
|
-
|
|
141
|
-
draftQuestion?: string | null | undefined;
|
|
139
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
142
140
|
} | null | undefined;
|
|
143
141
|
} | import("@langchain/langgraph").OverwriteValue<{
|
|
144
142
|
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
|
|
@@ -151,8 +149,7 @@ export declare class NegotiationGraphFactory {
|
|
|
151
149
|
};
|
|
152
150
|
message?: string | null | undefined;
|
|
153
151
|
askUser?: {
|
|
154
|
-
|
|
155
|
-
draftQuestion?: string | null | undefined;
|
|
152
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
156
153
|
} | null | undefined;
|
|
157
154
|
} | null> | null | undefined;
|
|
158
155
|
status?: "waiting_for_agent" | "input_required" | "completed" | "active" | import("@langchain/langgraph").OverwriteValue<"waiting_for_agent" | "input_required" | "completed" | "active"> | undefined;
|
|
@@ -212,7 +209,7 @@ export declare class NegotiationGraphFactory {
|
|
|
212
209
|
continuationExecution: import("@langchain/langgraph").BaseChannel<import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | undefined, import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | import("@langchain/langgraph").OverwriteValue<import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | undefined> | undefined, unknown>;
|
|
213
210
|
continuationReceipt: import("@langchain/langgraph").BaseChannel<NegotiationContinuationReceipt | undefined, NegotiationContinuationReceipt | import("@langchain/langgraph").OverwriteValue<NegotiationContinuationReceipt | undefined> | undefined, unknown>;
|
|
214
211
|
privateConsultation: import("@langchain/langgraph").BaseChannel<import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | undefined, import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | import("@langchain/langgraph").OverwriteValue<import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | undefined> | undefined, unknown>;
|
|
215
|
-
consultationPolicyReason: import("@langchain/langgraph").BaseChannel<
|
|
212
|
+
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>;
|
|
216
213
|
conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
217
214
|
taskId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
218
215
|
messages: import("@langchain/langgraph").BaseChannel<import("../domain/negotiation.state.js").NegotiationMessage[], import("../domain/negotiation.state.js").NegotiationMessage[] | import("@langchain/langgraph").OverwriteValue<import("../domain/negotiation.state.js").NegotiationMessage[]>, unknown>;
|
|
@@ -231,8 +228,7 @@ export declare class NegotiationGraphFactory {
|
|
|
231
228
|
};
|
|
232
229
|
message?: string | null | undefined;
|
|
233
230
|
askUser?: {
|
|
234
|
-
|
|
235
|
-
draftQuestion?: string | null | undefined;
|
|
231
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
236
232
|
} | null | undefined;
|
|
237
233
|
} | null, {
|
|
238
234
|
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
|
|
@@ -245,8 +241,7 @@ export declare class NegotiationGraphFactory {
|
|
|
245
241
|
};
|
|
246
242
|
message?: string | null | undefined;
|
|
247
243
|
askUser?: {
|
|
248
|
-
|
|
249
|
-
draftQuestion?: string | null | undefined;
|
|
244
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
250
245
|
} | null | undefined;
|
|
251
246
|
} | import("@langchain/langgraph").OverwriteValue<{
|
|
252
247
|
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
|
|
@@ -259,8 +254,7 @@ export declare class NegotiationGraphFactory {
|
|
|
259
254
|
};
|
|
260
255
|
message?: string | null | undefined;
|
|
261
256
|
askUser?: {
|
|
262
|
-
|
|
263
|
-
draftQuestion?: string | null | undefined;
|
|
257
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
264
258
|
} | null | undefined;
|
|
265
259
|
} | null> | null, unknown>;
|
|
266
260
|
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>;
|
|
@@ -329,7 +323,7 @@ export declare class NegotiationGraphFactory {
|
|
|
329
323
|
continuationExecution: import("@langchain/langgraph").BaseChannel<import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | undefined, import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | import("@langchain/langgraph").OverwriteValue<import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | undefined> | undefined, unknown>;
|
|
330
324
|
continuationReceipt: import("@langchain/langgraph").BaseChannel<NegotiationContinuationReceipt | undefined, NegotiationContinuationReceipt | import("@langchain/langgraph").OverwriteValue<NegotiationContinuationReceipt | undefined> | undefined, unknown>;
|
|
331
325
|
privateConsultation: import("@langchain/langgraph").BaseChannel<import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | undefined, import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | import("@langchain/langgraph").OverwriteValue<import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | undefined> | undefined, unknown>;
|
|
332
|
-
consultationPolicyReason: import("@langchain/langgraph").BaseChannel<
|
|
326
|
+
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>;
|
|
333
327
|
conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
334
328
|
taskId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
335
329
|
messages: import("@langchain/langgraph").BaseChannel<import("../domain/negotiation.state.js").NegotiationMessage[], import("../domain/negotiation.state.js").NegotiationMessage[] | import("@langchain/langgraph").OverwriteValue<import("../domain/negotiation.state.js").NegotiationMessage[]>, unknown>;
|
|
@@ -348,8 +342,7 @@ export declare class NegotiationGraphFactory {
|
|
|
348
342
|
};
|
|
349
343
|
message?: string | null | undefined;
|
|
350
344
|
askUser?: {
|
|
351
|
-
|
|
352
|
-
draftQuestion?: string | null | undefined;
|
|
345
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
353
346
|
} | null | undefined;
|
|
354
347
|
} | null, {
|
|
355
348
|
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
|
|
@@ -362,8 +355,7 @@ export declare class NegotiationGraphFactory {
|
|
|
362
355
|
};
|
|
363
356
|
message?: string | null | undefined;
|
|
364
357
|
askUser?: {
|
|
365
|
-
|
|
366
|
-
draftQuestion?: string | null | undefined;
|
|
358
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
367
359
|
} | null | undefined;
|
|
368
360
|
} | import("@langchain/langgraph").OverwriteValue<{
|
|
369
361
|
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
|
|
@@ -376,8 +368,7 @@ export declare class NegotiationGraphFactory {
|
|
|
376
368
|
};
|
|
377
369
|
message?: string | null | undefined;
|
|
378
370
|
askUser?: {
|
|
379
|
-
|
|
380
|
-
draftQuestion?: string | null | undefined;
|
|
371
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
381
372
|
} | null | undefined;
|
|
382
373
|
} | null> | null, unknown>;
|
|
383
374
|
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>;
|
|
@@ -501,7 +492,7 @@ export declare class NegotiationGraphFactory {
|
|
|
501
492
|
continuationExecution: import("@langchain/langgraph").BaseChannel<import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | undefined, import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | import("@langchain/langgraph").OverwriteValue<import("../../shared/interfaces/database.interface.js").NegotiationContinuationExecution | undefined> | undefined, unknown>;
|
|
502
493
|
continuationReceipt: import("@langchain/langgraph").BaseChannel<NegotiationContinuationReceipt | undefined, NegotiationContinuationReceipt | import("@langchain/langgraph").OverwriteValue<NegotiationContinuationReceipt | undefined> | undefined, unknown>;
|
|
503
494
|
privateConsultation: import("@langchain/langgraph").BaseChannel<import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | undefined, import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | import("@langchain/langgraph").OverwriteValue<import("../../shared/interfaces/database.interface.js").NegotiationPrivateConsultation | undefined> | undefined, unknown>;
|
|
504
|
-
consultationPolicyReason: import("@langchain/langgraph").BaseChannel<
|
|
495
|
+
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>;
|
|
505
496
|
conversationId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
506
497
|
taskId: import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
|
|
507
498
|
messages: import("@langchain/langgraph").BaseChannel<import("../domain/negotiation.state.js").NegotiationMessage[], import("../domain/negotiation.state.js").NegotiationMessage[] | import("@langchain/langgraph").OverwriteValue<import("../domain/negotiation.state.js").NegotiationMessage[]>, unknown>;
|
|
@@ -520,8 +511,7 @@ export declare class NegotiationGraphFactory {
|
|
|
520
511
|
};
|
|
521
512
|
message?: string | null | undefined;
|
|
522
513
|
askUser?: {
|
|
523
|
-
|
|
524
|
-
draftQuestion?: string | null | undefined;
|
|
514
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
525
515
|
} | null | undefined;
|
|
526
516
|
} | null, {
|
|
527
517
|
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
|
|
@@ -534,8 +524,7 @@ export declare class NegotiationGraphFactory {
|
|
|
534
524
|
};
|
|
535
525
|
message?: string | null | undefined;
|
|
536
526
|
askUser?: {
|
|
537
|
-
|
|
538
|
-
draftQuestion?: string | null | undefined;
|
|
527
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
539
528
|
} | null | undefined;
|
|
540
529
|
} | import("@langchain/langgraph").OverwriteValue<{
|
|
541
530
|
action: "propose" | "accept" | "reject" | "counter" | "question" | "outreach" | "withdraw" | "decline" | "ask_user";
|
|
@@ -548,8 +537,7 @@ export declare class NegotiationGraphFactory {
|
|
|
548
537
|
};
|
|
549
538
|
message?: string | null | undefined;
|
|
550
539
|
askUser?: {
|
|
551
|
-
|
|
552
|
-
draftQuestion?: string | null | undefined;
|
|
540
|
+
reason: "unresolved_owner_constraint" | "consequential_disclosure_permission" | "repeated_non_convergence" | "insufficient_commitment_authority";
|
|
553
541
|
} | null | undefined;
|
|
554
542
|
} | null> | null, unknown>;
|
|
555
543
|
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>;
|
|
@@ -9,9 +9,11 @@ import { blocksNegotiationBeforeFirstTurn, NegotiationScreener } from "./negotia
|
|
|
9
9
|
import { configuredScreenMode } from "../domain/negotiation.screen.contracts.js";
|
|
10
10
|
import { assessDeadlock, configuredDeadlockShiftEnabled, configuredDeadlockThreshold } from "../domain/negotiation.deadlock.js";
|
|
11
11
|
import { protocolLogger } from "../../shared/observability/protocol.logger.js";
|
|
12
|
-
import { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, negotiationQuestionSettlementId
|
|
12
|
+
import { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, negotiationQuestionSettlementId } from '../domain/negotiation.question-safety.js';
|
|
13
13
|
import { buildIntentSnapshots } from "../domain/negotiation.intent-snapshot-provenance.js";
|
|
14
14
|
import { holdsNegotiationConversationLock } from "../domain/negotiation.task-lock-policy.js";
|
|
15
|
+
import { isNegotiationTurnCapReached } from "../domain/negotiation.turn-cap.js";
|
|
16
|
+
import { expectedNegotiationSpeaker } from "../domain/negotiation.expected-speaker.js";
|
|
15
17
|
import { attributedDialogueIsEmpty, buildSeededAttribution, combineAttributedDialogue } from '../negotiation.attribution.js';
|
|
16
18
|
const logger = protocolLogger("NegotiationGraph");
|
|
17
19
|
const initLog = protocolLogger("NegotiationGraph:Init");
|
|
@@ -196,22 +198,15 @@ export class NegotiationGraphFactory {
|
|
|
196
198
|
// --- Load prior messages and determine continuation ---
|
|
197
199
|
const priorTurns = turnsFromMessages(priorMessages);
|
|
198
200
|
const isContinuation = priorTurns.length > 0;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (lastAction === 'ask_user') {
|
|
209
|
-
currentSpeaker = lastMessage.senderId === agentIdA ? 'source' : 'candidate';
|
|
210
|
-
}
|
|
211
|
-
else {
|
|
212
|
-
currentSpeaker = lastMessage.senderId === agentIdA ? 'candidate' : 'source';
|
|
213
|
-
}
|
|
214
|
-
}
|
|
201
|
+
const expectedSpeaker = expectedNegotiationSpeaker({
|
|
202
|
+
sourceUserId: state.sourceUser.id,
|
|
203
|
+
candidateUserId: state.candidateUser.id,
|
|
204
|
+
}, priorMessages);
|
|
205
|
+
if (!expectedSpeaker)
|
|
206
|
+
return { error: 'invalid negotiation participants' };
|
|
207
|
+
const currentSpeaker = expectedSpeaker === state.sourceUser.id
|
|
208
|
+
? 'source'
|
|
209
|
+
: 'candidate';
|
|
215
210
|
// Determine scenario-based maxTurns
|
|
216
211
|
const scope = { action: 'manage:negotiations', scopeType: 'network', scopeId: state.indexContext.networkId };
|
|
217
212
|
const [sourceHasAgent, candidateHasAgent] = await Promise.all([
|
|
@@ -485,9 +480,8 @@ export class NegotiationGraphFactory {
|
|
|
485
480
|
const ownUser = isSource ? state.sourceUser : state.candidateUser;
|
|
486
481
|
const otherUser = isSource ? state.candidateUser : state.sourceUser;
|
|
487
482
|
const ownIntentId = isSource ? state.sourceIntentId : state.candidateIntentId;
|
|
488
|
-
// Determine if this is the system agent's final allowed turn
|
|
489
|
-
const
|
|
490
|
-
const isFinalTurn = maxTurns > 0 && (state.turnCount + 1) >= maxTurns;
|
|
483
|
+
// Determine if this is the system agent's final allowed turn.
|
|
484
|
+
const isFinalTurn = isNegotiationTurnCapReached(state.turnCount + 1, state.maxTurns);
|
|
491
485
|
// Seat attribution keys on initiatorUserId (rigid v2 stamp), never on
|
|
492
486
|
// parity or source/candidate position — under the conversation-scoped
|
|
493
487
|
// tie-break this run's source may hold the counterparty seat.
|
|
@@ -558,6 +552,17 @@ export class NegotiationGraphFactory {
|
|
|
558
552
|
...(state.privateConsultation?.recipientUserId === ownUser.id
|
|
559
553
|
? { privateConsultation: state.privateConsultation }
|
|
560
554
|
: {}),
|
|
555
|
+
...(state.continuationExecution
|
|
556
|
+
? {
|
|
557
|
+
timeoutContinuation: {
|
|
558
|
+
priorTaskId: state.continuationExecution.taskId,
|
|
559
|
+
settlementId: state.continuationExecution.settlementId,
|
|
560
|
+
successorTaskId: state.continuationExecution.successorTaskId,
|
|
561
|
+
token: state.continuationExecution.token,
|
|
562
|
+
fence: state.continuationExecution.fence,
|
|
563
|
+
},
|
|
564
|
+
}
|
|
565
|
+
: {}),
|
|
561
566
|
};
|
|
562
567
|
const scope = { action: 'manage:negotiations', scopeType: 'network', scopeId: state.indexContext.networkId };
|
|
563
568
|
const dispatchResult = await dispatcher.dispatch(ownUser.id, scope, payload, { timeoutMs: state.timeoutMs });
|
|
@@ -595,7 +600,7 @@ export class NegotiationGraphFactory {
|
|
|
595
600
|
? { privateConsultation: state.privateConsultation }
|
|
596
601
|
: {}),
|
|
597
602
|
}, state.continuationExecution);
|
|
598
|
-
await database.updateTaskState(state.taskId, "waiting_for_agent", undefined, state.continuationExecution);
|
|
603
|
+
await database.updateTaskState(state.taskId, "waiting_for_agent", undefined, state.continuationExecution, dispatchResult.resumeToken);
|
|
599
604
|
return { status: 'waiting_for_agent' };
|
|
600
605
|
}
|
|
601
606
|
else {
|
|
@@ -703,7 +708,7 @@ export class NegotiationGraphFactory {
|
|
|
703
708
|
reasoning: 'Client consultation required.',
|
|
704
709
|
suggestedRoles: turn.assessment.suggestedRoles,
|
|
705
710
|
},
|
|
706
|
-
askUser:
|
|
711
|
+
askUser: { reason: consultationPolicyReason },
|
|
707
712
|
};
|
|
708
713
|
emitConsultationTelemetry('asked', consultationPolicyReason);
|
|
709
714
|
}
|
|
@@ -775,27 +780,10 @@ export class NegotiationGraphFactory {
|
|
|
775
780
|
// like the waiting_for_agent suspend; the answer (or window expiry)
|
|
776
781
|
// resumes via the run-existing continuation path.
|
|
777
782
|
if (turn.action === 'ask_user') {
|
|
778
|
-
const
|
|
779
|
-
const safeAskUser =
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
forbiddenIdentifiers: [
|
|
783
|
-
counterparty.id,
|
|
784
|
-
counterparty.profile.name ?? '',
|
|
785
|
-
state.opportunityId,
|
|
786
|
-
state.taskId,
|
|
787
|
-
state.indexContext.networkId,
|
|
788
|
-
isSource ? state.candidateIntentId ?? '' : state.sourceIntentId ?? '',
|
|
789
|
-
],
|
|
790
|
-
forbiddenSourceText: [
|
|
791
|
-
counterparty.profile.bio ?? '',
|
|
792
|
-
counterparty.profile.location ?? '',
|
|
793
|
-
...counterparty.intents.flatMap((intent) => [intent.title, intent.description]),
|
|
794
|
-
state.seedAssessment.reasoning,
|
|
795
|
-
state.indexContext.prompt,
|
|
796
|
-
state.discoveryQuery ?? '',
|
|
797
|
-
],
|
|
798
|
-
});
|
|
783
|
+
const consultationReason = turn.askUser?.reason;
|
|
784
|
+
const safeAskUser = consultationReason
|
|
785
|
+
? consultationPromptFor(consultationReason)
|
|
786
|
+
: null;
|
|
799
787
|
const settlementId = negotiationQuestionSettlementId(state.taskId);
|
|
800
788
|
const askUserBinding = await database.captureNegotiationAskUserBinding({
|
|
801
789
|
taskId: state.taskId,
|
|
@@ -810,7 +798,7 @@ export class NegotiationGraphFactory {
|
|
|
810
798
|
indexContext: state.indexContext,
|
|
811
799
|
seedAssessment: state.seedAssessment,
|
|
812
800
|
...(isSource && state.discoveryQuery && { discoveryQuery: state.discoveryQuery }),
|
|
813
|
-
...(
|
|
801
|
+
...(consultationReason && { consultationPolicyReason: consultationReason }),
|
|
814
802
|
},
|
|
815
803
|
...(state.continuationExecution ? { continuationExecution: state.continuationExecution } : {}),
|
|
816
804
|
});
|
|
@@ -852,10 +840,8 @@ export class NegotiationGraphFactory {
|
|
|
852
840
|
context: {
|
|
853
841
|
negotiationId: state.taskId,
|
|
854
842
|
counterpartyHint: NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY,
|
|
855
|
-
disclosureSubject: safeAskUser.disclosureSubject,
|
|
856
|
-
...(safeAskUser.draftQuestion && { draftQuestion: safeAskUser.draftQuestion }),
|
|
857
843
|
indexContext: NEGOTIATION_QUESTION_GENERIC_NETWORK,
|
|
858
|
-
|
|
844
|
+
consultationPolicyReason: consultationReason,
|
|
859
845
|
...(userContext && { userContext }),
|
|
860
846
|
},
|
|
861
847
|
}).catch((error) => {
|
|
@@ -965,7 +951,7 @@ export class NegotiationGraphFactory {
|
|
|
965
951
|
if (isTerminalAction(state.lastTurn.action))
|
|
966
952
|
return "finalize";
|
|
967
953
|
// question routes same as counter — next turn
|
|
968
|
-
if ((state.
|
|
954
|
+
if (isNegotiationTurnCapReached(state.turnCount, state.maxTurns))
|
|
969
955
|
return "finalize";
|
|
970
956
|
return "turn";
|
|
971
957
|
};
|
|
@@ -1038,7 +1024,7 @@ export class NegotiationGraphFactory {
|
|
|
1038
1024
|
const blockedByScreenNode = blocksNegotiationBeforeFirstTurn(state.screenDecision, state.turnCount);
|
|
1039
1025
|
const refusedAtOpeningTurn = state.firstTurnScreenedOut === true;
|
|
1040
1026
|
const screenedOut = blockedByScreenNode || refusedAtOpeningTurn;
|
|
1041
|
-
const atCap = !screenedOut && (state.
|
|
1027
|
+
const atCap = !screenedOut && isNegotiationTurnCapReached(state.turnCount, state.maxTurns) && !isTerminalAction(lastTurn?.action);
|
|
1042
1028
|
let agreedRoles = [];
|
|
1043
1029
|
if (hasOpportunity && history.length >= 2) {
|
|
1044
1030
|
const acceptTurn = history[history.length - 1];
|