@indexnetwork/protocol 22.0.0-rc.498.1 → 64.0.0-rc.604.2
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 +1841 -0
- package/IMPLEMENTATION.md +140 -181
- package/README.md +16 -20
- package/STABILITY.md +16 -11
- package/dist/{intents/intent.module.d.ts → capabilities/intents.d.ts} +182 -192
- package/dist/capabilities/intents.js +88 -0
- package/dist/capabilities/negotiations.d.ts +17 -0
- package/dist/capabilities/negotiations.js +16 -0
- package/dist/{networks/network.module.d.ts → capabilities/networks.d.ts} +33 -169
- package/dist/{networks/network.module.js → capabilities/networks.js} +6 -17
- package/dist/index.d.ts +57 -132
- package/dist/index.js +41 -100
- package/dist/internal/agents/agent.repository.port.d.ts +59 -0
- package/dist/internal/agents/agent.repository.port.js +7 -0
- package/dist/internal/agents/agent.types.d.ts +35 -0
- package/dist/{agents → internal/agents}/agent.types.js +1 -6
- package/dist/{intents → internal/intents}/graph/intent.graph.d.ts +142 -151
- package/dist/{intents → internal/intents}/graph/intent.graph.execute.d.ts +5 -1
- package/dist/{intents → internal/intents}/graph/intent.graph.execute.js +165 -46
- package/dist/internal/intents/graph/intent.graph.infer.d.ts +78 -0
- package/dist/internal/intents/graph/intent.graph.infer.js +122 -0
- package/dist/internal/intents/graph/intent.graph.js +108 -0
- package/dist/{intents → internal/intents}/graph/intent.graph.reconcile.d.ts +18 -9
- package/dist/internal/intents/graph/intent.graph.reconcile.js +173 -0
- package/dist/internal/intents/graph/intent.graph.shared.d.ts +55 -0
- package/dist/{intents → internal/intents}/graph/intent.graph.shared.js +25 -70
- package/dist/{intents → internal/intents}/graph/intent.graph.state.d.ts +96 -32
- package/dist/{intents → internal/intents}/graph/intent.graph.state.js +42 -31
- package/dist/internal/intents/intent.admission.d.ts +16 -0
- package/dist/internal/intents/intent.admission.js +30 -0
- package/dist/{intents → internal/intents}/intent.inferrer.d.ts +1 -40
- package/dist/{intents → internal/intents}/intent.inferrer.js +13 -49
- package/dist/internal/intents/intent.preparer.d.ts +52 -0
- package/dist/internal/intents/intent.preparer.js +87 -0
- package/dist/{intents → internal/intents}/intent.verifier.d.ts +3 -36
- package/dist/{intents → internal/intents}/intent.verifier.js +0 -17
- package/dist/{networks → internal/networks}/indexer.graph.d.ts +15 -200
- package/dist/{networks → internal/networks}/indexer.graph.js +19 -128
- package/dist/{networks → internal/networks}/indexer.state.d.ts +8 -63
- package/dist/internal/networks/indexer.state.js +70 -0
- package/dist/{networks → internal/networks}/membership.graph.d.ts +6 -6
- package/dist/{networks → internal/networks}/membership.graph.js +3 -3
- package/dist/{networks → internal/networks}/membership.state.d.ts +2 -2
- package/dist/{networks → internal/networks}/membership.state.js +2 -2
- package/dist/{networks → internal/networks}/network.graph.d.ts +9 -22
- package/dist/{networks → internal/networks}/network.graph.js +13 -27
- package/dist/{networks → internal/networks}/network.recommender.d.ts +2 -2
- package/dist/{networks → internal/networks}/network.recommender.js +2 -2
- package/dist/{networks → internal/networks}/network.state.d.ts +4 -7
- package/dist/{networks → internal/networks}/network.state.js +4 -4
- package/dist/internal/opportunities/negotiation-context.loader.d.ts +26 -0
- package/dist/internal/opportunities/negotiation-context.loader.js +36 -0
- package/dist/{opportunities → internal/opportunities}/opportunity.actor.d.ts +1 -1
- package/dist/{opportunities → internal/opportunities}/opportunity.actor.js +7 -1
- package/dist/internal/opportunities/opportunity.counterparties.d.ts +17 -0
- package/dist/internal/opportunities/opportunity.counterparties.js +19 -0
- package/dist/internal/opportunities/opportunity.events.d.ts +38 -0
- package/dist/internal/opportunities/opportunity.events.js +94 -0
- package/dist/{opportunities → internal/opportunities}/opportunity.feed-selection.d.ts +3 -9
- package/dist/internal/opportunities/opportunity.feed-selection.js +40 -0
- package/dist/internal/opportunities/opportunity.graph.modes.d.ts +39 -0
- package/dist/internal/opportunities/opportunity.graph.modes.js +138 -0
- package/dist/{opportunities → internal/opportunities}/opportunity.labels.d.ts +2 -3
- package/dist/internal/opportunities/opportunity.labels.js +9 -0
- package/dist/{opportunities → internal/opportunities}/opportunity.presentation.d.ts +17 -86
- package/dist/{opportunities → internal/opportunities}/opportunity.presentation.js +54 -447
- package/dist/{opportunities → internal/opportunities}/opportunity.update-admission.d.ts +2 -2
- package/dist/internal/opportunities/opportunity.utils.d.ts +105 -0
- package/dist/internal/opportunities/opportunity.utils.js +165 -0
- package/dist/{opportunities → internal/opportunities}/radar/radar.graph.d.ts +17 -17
- package/dist/{opportunities → internal/opportunities}/radar/radar.graph.js +41 -161
- package/dist/{opportunities → internal/opportunities}/radar/radar.state.d.ts +4 -11
- package/dist/{shared → internal/shared}/agent/model-signal.d.ts +1 -1
- package/dist/{shared → internal/shared}/agent/model-signal.js +1 -1
- package/dist/{shared → internal/shared}/agent/model.config.d.ts +28 -86
- package/dist/{shared → internal/shared}/agent/model.config.js +58 -69
- package/dist/internal/shared/agent/model.resolver.d.ts +33 -0
- package/dist/{shared → internal/shared}/agent/model.resolver.js +18 -33
- package/dist/internal/shared/agent/scope.d.ts +20 -0
- package/dist/internal/shared/agent/scope.js +24 -0
- package/dist/internal/shared/assignment/network-assignment.policy.d.ts +23 -0
- package/dist/internal/shared/assignment/network-assignment.policy.js +28 -0
- package/dist/{shared → internal/shared}/observability/log.d.ts +3 -6
- package/dist/{shared → internal/shared}/observability/log.js +9 -18
- package/dist/{shared → internal/shared}/observability/protocol.logger.d.ts +1 -1
- package/dist/{shared → internal/shared}/observability/protocol.logger.js +1 -1
- package/dist/internal/shared/observability/request-context.d.ts +29 -0
- package/dist/internal/shared/observability/request-context.js +17 -0
- package/dist/{shared → internal/shared}/utils/social-label.d.ts +2 -2
- package/dist/{shared → internal/shared}/utils/social-label.js +1 -1
- package/dist/platform/database/capabilities.d.ts +59 -0
- package/dist/{shared/interfaces/database.entities.d.ts → platform/database/entities.d.ts} +81 -121
- package/dist/{shared/interfaces/database.identity-queries.d.ts → platform/database/identity-queries.d.ts} +55 -20
- package/dist/platform/database/member-queries.d.ts +55 -0
- package/dist/platform/database/member-queries.js +4 -0
- package/dist/platform/database/negotiation.d.ts +38 -0
- package/dist/{shared/interfaces/database.network-queries.d.ts → platform/database/network-queries.d.ts} +66 -67
- package/dist/platform/database/network-queries.js +4 -0
- package/dist/{shared/interfaces/database.opportunity-queries.d.ts → platform/database/opportunity-queries.d.ts} +25 -109
- package/dist/{shared/interfaces/database.port.d.ts → platform/database/port.d.ts} +52 -117
- package/dist/{shared/interfaces/database.port.js → platform/database/port.js} +3 -5
- package/dist/platform/database.d.ts +23 -0
- package/dist/{shared/interfaces/database.interface.js → platform/database.js} +1 -1
- package/dist/{shared/interfaces/cache.interface.d.ts → platform/discovery/cache.d.ts} +2 -4
- package/dist/{shared/interfaces/cache.interface.js → platform/discovery/cache.js} +1 -1
- package/dist/platform/discovery/embedder.d.ts +31 -0
- package/dist/platform/runtime/errors.d.ts +6 -0
- package/dist/platform/runtime/errors.js +9 -0
- package/dist/platform/runtime/follow-up.d.ts +36 -0
- package/dist/platform/runtime/follow-up.js +4 -0
- package/dist/platform/runtime/observability.d.ts +34 -0
- package/dist/protocol/core.d.ts +11 -0
- package/dist/protocol/discovery.rules.d.ts +21 -0
- package/dist/protocol/discovery.rules.js +29 -0
- package/dist/protocol/negotiation.constants.d.ts +3 -0
- package/dist/protocol/negotiation.constants.js +3 -0
- package/dist/protocol/negotiation.rules.d.ts +73 -0
- package/dist/protocol/negotiation.rules.js +68 -0
- package/dist/protocol/protocol.prompt.d.ts +13 -0
- package/dist/protocol/protocol.prompt.js +190 -0
- package/dist/{shared → protocol}/schemas/discovery-question.schema.d.ts +13 -13
- package/dist/{shared → protocol}/schemas/discovery-question.schema.js +2 -2
- package/dist/{shared → protocol}/schemas/identity.schema.d.ts +4 -4
- package/dist/{shared → protocol}/schemas/identity.schema.js +4 -4
- package/dist/{shared → protocol}/schemas/network-assignment.schema.d.ts +11 -20
- package/dist/{shared → protocol}/schemas/network-assignment.schema.js +2 -9
- package/dist/protocol/schemas/underspecification.schema.d.ts +9 -0
- package/dist/protocol/schemas/underspecification.schema.js +12 -0
- package/package.json +7 -15
- package/dist/agents/agent.dispatcher.port.d.ts +0 -25
- package/dist/agents/agent.module.d.ts +0 -19
- package/dist/agents/agent.module.js +0 -11
- package/dist/agents/agent.repository.port.d.ts +0 -118
- package/dist/agents/agent.repository.port.js +0 -10
- package/dist/agents/agent.tools.d.ts +0 -16
- package/dist/agents/agent.tools.js +0 -351
- package/dist/agents/agent.tools.port.d.ts +0 -22
- package/dist/agents/agent.tools.port.js +0 -18
- package/dist/agents/agent.types.d.ts +0 -76
- package/dist/chat/chat-streaming.types.d.ts +0 -618
- package/dist/chat/chat-streaming.types.js +0 -297
- package/dist/chat/chat.agent.d.ts +0 -292
- package/dist/chat/chat.agent.js +0 -1010
- package/dist/chat/chat.graph.d.ts +0 -424
- package/dist/chat/chat.graph.js +0 -257
- package/dist/chat/chat.interrupt.classifier.d.ts +0 -25
- package/dist/chat/chat.interrupt.classifier.js +0 -64
- package/dist/chat/chat.persona.d.ts +0 -39
- package/dist/chat/chat.prompt.d.ts +0 -4
- package/dist/chat/chat.prompt.js +0 -12
- package/dist/chat/chat.prompt.modules.d.ts +0 -30
- package/dist/chat/chat.prompt.modules.js +0 -40
- package/dist/chat/chat.question-dedup.d.ts +0 -14
- package/dist/chat/chat.question-dedup.js +0 -17
- package/dist/chat/chat.state.d.ts +0 -135
- package/dist/chat/chat.state.js +0 -120
- package/dist/chat/chat.streamer.d.ts +0 -64
- package/dist/chat/chat.streamer.js +0 -217
- package/dist/chat/chat.suggester.d.ts +0 -23
- package/dist/chat/chat.suggester.js +0 -95
- package/dist/chat/chat.summarizer.d.ts +0 -20
- package/dist/chat/chat.summarizer.js +0 -97
- package/dist/chat/chat.title.generator.d.ts +0 -19
- package/dist/chat/chat.title.generator.js +0 -66
- package/dist/chat/chat.tools.d.ts +0 -5
- package/dist/chat/chat.tools.js +0 -62
- package/dist/chat/chat.utils.d.ts +0 -41
- package/dist/chat/chat.utils.js +0 -88
- package/dist/chat/negotiator.persona.d.ts +0 -74
- package/dist/chat/negotiator.persona.js +0 -154
- package/dist/chat/negotiator.prompt.d.ts +0 -45
- package/dist/chat/negotiator.prompt.js +0 -160
- package/dist/chat/negotiator.tools.d.ts +0 -42
- package/dist/chat/negotiator.tools.js +0 -134
- package/dist/chat/onboarding.persona.d.ts +0 -28
- package/dist/chat/onboarding.persona.js +0 -86
- package/dist/chat/onboarding.prompt.d.ts +0 -6
- package/dist/chat/onboarding.prompt.js +0 -63
- package/dist/chat/signal.persona.d.ts +0 -47
- package/dist/chat/signal.persona.js +0 -319
- package/dist/chat/signal.prompt.d.ts +0 -39
- package/dist/chat/signal.prompt.js +0 -136
- package/dist/contacts/contact.module.d.ts +0 -8
- package/dist/contacts/contact.module.js +0 -6
- package/dist/contacts/contact.repository.port.d.ts +0 -21
- package/dist/contacts/contact.repository.port.js +0 -12
- package/dist/contacts/contact.tools.d.ts +0 -17
- package/dist/contacts/contact.tools.js +0 -108
- package/dist/contacts/contact.tools.port.d.ts +0 -20
- package/dist/contacts/contact.tools.port.js +0 -16
- package/dist/contacts/contact.types.d.ts +0 -24
- package/dist/contacts/contact.types.js +0 -8
- package/dist/contexts/context.generator.d.ts +0 -95
- package/dist/contexts/context.generator.js +0 -127
- package/dist/contexts/context.module.d.ts +0 -13
- package/dist/contexts/context.module.js +0 -12
- package/dist/contexts/context.tools.port.d.ts +0 -9
- package/dist/discovery/hyde.documents.d.ts +0 -9
- package/dist/discovery/hyde.documents.js +0 -49
- package/dist/discovery/hyde.env.d.ts +0 -8
- package/dist/discovery/hyde.env.js +0 -9
- package/dist/discovery/hyde.frame.d.ts +0 -150
- package/dist/discovery/hyde.frame.js +0 -107
- package/dist/discovery/hyde.generator.d.ts +0 -38
- package/dist/discovery/hyde.generator.js +0 -103
- package/dist/discovery/hyde.graph.d.ts +0 -209
- package/dist/discovery/hyde.graph.js +0 -482
- package/dist/discovery/hyde.state.d.ts +0 -70
- package/dist/discovery/hyde.state.js +0 -85
- package/dist/discovery/hyde.strategies.d.ts +0 -17
- package/dist/discovery/hyde.strategies.js +0 -34
- package/dist/discovery/hyde.validator.d.ts +0 -78
- package/dist/discovery/hyde.validator.js +0 -48
- package/dist/discovery/index.d.ts +0 -26
- package/dist/discovery/index.js +0 -19
- package/dist/discovery/lens.inferrer.d.ts +0 -214
- package/dist/discovery/lens.inferrer.js +0 -152
- package/dist/enrichment/enrichment.generator.d.ts +0 -68
- package/dist/enrichment/enrichment.generator.js +0 -95
- package/dist/enrichment/enrichment.graph.d.ts +0 -544
- package/dist/enrichment/enrichment.graph.js +0 -695
- package/dist/enrichment/enrichment.state.d.ts +0 -141
- package/dist/enrichment/enrichment.state.js +0 -115
- package/dist/enrichment/enrichment.tools.context-read.d.ts +0 -10
- package/dist/enrichment/enrichment.tools.context-read.js +0 -353
- package/dist/enrichment/enrichment.tools.context-write.d.ts +0 -9
- package/dist/enrichment/enrichment.tools.context-write.js +0 -417
- package/dist/enrichment/enrichment.tools.d.ts +0 -13
- package/dist/enrichment/enrichment.tools.helpers.d.ts +0 -139
- package/dist/enrichment/enrichment.tools.helpers.js +0 -234
- package/dist/enrichment/enrichment.tools.js +0 -153
- package/dist/intents/graph/intent.graph.infer.d.ts +0 -44
- package/dist/intents/graph/intent.graph.infer.js +0 -97
- package/dist/intents/graph/intent.graph.js +0 -134
- package/dist/intents/graph/intent.graph.reconcile.js +0 -274
- package/dist/intents/graph/intent.graph.shared.d.ts +0 -68
- package/dist/intents/intake/intake.orchestrator.d.ts +0 -203
- package/dist/intents/intake/intake.orchestrator.js +0 -255
- package/dist/intents/intake/intake.pack.generator.d.ts +0 -57
- package/dist/intents/intake/intake.pack.generator.js +0 -90
- package/dist/intents/intent.clarifier.d.ts +0 -51
- package/dist/intents/intent.clarifier.js +0 -201
- package/dist/intents/intent.indexer.d.ts +0 -82
- package/dist/intents/intent.indexer.js +0 -170
- package/dist/intents/intent.module.js +0 -103
- package/dist/intents/intent.proposal.d.ts +0 -37
- package/dist/intents/intent.proposal.js +0 -14
- package/dist/intents/intent.reconciler.d.ts +0 -105
- package/dist/intents/intent.reconciler.js +0 -186
- package/dist/intents/intent.tools.d.ts +0 -27
- package/dist/intents/intent.tools.js +0 -808
- package/dist/maintenance/maintenance.graph.d.ts +0 -239
- package/dist/maintenance/maintenance.graph.js +0 -199
- package/dist/maintenance/maintenance.state.d.ts +0 -35
- package/dist/maintenance/maintenance.state.js +0 -55
- package/dist/mcp/elicitation.builder.d.ts +0 -53
- package/dist/mcp/elicitation.builder.js +0 -74
- package/dist/mcp/elicitation.dispatcher.d.ts +0 -36
- package/dist/mcp/elicitation.dispatcher.js +0 -86
- package/dist/mcp/mcp.authorization-policy.d.ts +0 -252
- package/dist/mcp/mcp.authorization-policy.js +0 -535
- package/dist/mcp/mcp.server.d.ts +0 -90
- package/dist/mcp/mcp.server.js +0 -631
- package/dist/negotiations/insight.generator.d.ts +0 -31
- package/dist/negotiations/insight.generator.js +0 -105
- package/dist/negotiations/negotiation.agent.d.ts +0 -130
- package/dist/negotiations/negotiation.agent.js +0 -396
- package/dist/negotiations/negotiation.answer-consumption.d.ts +0 -223
- package/dist/negotiations/negotiation.answer-consumption.js +0 -275
- package/dist/negotiations/negotiation.attribution.d.ts +0 -91
- package/dist/negotiations/negotiation.attribution.js +0 -109
- package/dist/negotiations/negotiation.candidates.d.ts +0 -83
- package/dist/negotiations/negotiation.candidates.js +0 -162
- package/dist/negotiations/negotiation.client-dm.d.ts +0 -50
- package/dist/negotiations/negotiation.client-dm.js +0 -66
- package/dist/negotiations/negotiation.consultation-policy.d.ts +0 -95
- package/dist/negotiations/negotiation.consultation-policy.js +0 -159
- package/dist/negotiations/negotiation.deadlock.contracts.d.ts +0 -10
- package/dist/negotiations/negotiation.deadlock.d.ts +0 -87
- package/dist/negotiations/negotiation.deadlock.js +0 -150
- package/dist/negotiations/negotiation.detail-reader.d.ts +0 -94
- package/dist/negotiations/negotiation.detail-reader.js +0 -91
- package/dist/negotiations/negotiation.expected-speaker.d.ts +0 -33
- package/dist/negotiations/negotiation.expected-speaker.js +0 -59
- package/dist/negotiations/negotiation.graph.d.ts +0 -694
- package/dist/negotiations/negotiation.graph.finalize.d.ts +0 -5
- package/dist/negotiations/negotiation.graph.finalize.js +0 -403
- package/dist/negotiations/negotiation.graph.init.d.ts +0 -54
- package/dist/negotiations/negotiation.graph.init.js +0 -256
- package/dist/negotiations/negotiation.graph.js +0 -94
- package/dist/negotiations/negotiation.graph.screen.d.ts +0 -23
- package/dist/negotiations/negotiation.graph.screen.js +0 -108
- package/dist/negotiations/negotiation.graph.shared.d.ts +0 -111
- package/dist/negotiations/negotiation.graph.shared.js +0 -168
- package/dist/negotiations/negotiation.graph.turn.d.ts +0 -134
- package/dist/negotiations/negotiation.graph.turn.js +0 -662
- package/dist/negotiations/negotiation.hermes-contract.d.ts +0 -31
- package/dist/negotiations/negotiation.hermes-contract.js +0 -72
- package/dist/negotiations/negotiation.intent-snapshot-provenance.d.ts +0 -21
- package/dist/negotiations/negotiation.intent-snapshot-provenance.js +0 -28
- package/dist/negotiations/negotiation.lifecycle-narration.d.ts +0 -18
- package/dist/negotiations/negotiation.lifecycle-narration.js +0 -87
- package/dist/negotiations/negotiation.memory.d.ts +0 -65
- package/dist/negotiations/negotiation.memory.js +0 -83
- package/dist/negotiations/negotiation.module.d.ts +0 -36
- package/dist/negotiations/negotiation.module.js +0 -23
- package/dist/negotiations/negotiation.protocol.d.ts +0 -1018
- package/dist/negotiations/negotiation.protocol.js +0 -224
- package/dist/negotiations/negotiation.question-safety.d.ts +0 -52
- package/dist/negotiations/negotiation.question-safety.js +0 -119
- package/dist/negotiations/negotiation.reflect.d.ts +0 -194
- package/dist/negotiations/negotiation.reflect.js +0 -145
- package/dist/negotiations/negotiation.scope.d.ts +0 -41
- package/dist/negotiations/negotiation.scope.js +0 -39
- package/dist/negotiations/negotiation.screen.contracts.d.ts +0 -88
- package/dist/negotiations/negotiation.screen.contracts.js +0 -58
- package/dist/negotiations/negotiation.screen.d.ts +0 -78
- package/dist/negotiations/negotiation.screen.js +0 -112
- package/dist/negotiations/negotiation.stall-gap.d.ts +0 -83
- package/dist/negotiations/negotiation.stall-gap.js +0 -152
- package/dist/negotiations/negotiation.stance.contracts.d.ts +0 -123
- package/dist/negotiations/negotiation.stance.contracts.js +0 -317
- package/dist/negotiations/negotiation.state.d.ts +0 -597
- package/dist/negotiations/negotiation.state.js +0 -286
- package/dist/negotiations/negotiation.summarizer.d.ts +0 -25
- package/dist/negotiations/negotiation.summarizer.js +0 -101
- package/dist/negotiations/negotiation.task-lock-policy.d.ts +0 -10
- package/dist/negotiations/negotiation.task-lock-policy.js +0 -22
- package/dist/negotiations/negotiation.tools.d.ts +0 -18
- package/dist/negotiations/negotiation.tools.js +0 -842
- package/dist/negotiations/negotiation.tools.port.d.ts +0 -17
- package/dist/negotiations/negotiation.turn-cap.d.ts +0 -9
- package/dist/negotiations/negotiation.turn-cap.js +0 -12
- package/dist/networks/indexer.state.js +0 -112
- package/dist/networks/network.tools.d.ts +0 -36
- package/dist/networks/network.tools.js +0 -594
- package/dist/opportunities/delivery-card.cache.d.ts +0 -25
- package/dist/opportunities/delivery-card.cache.js +0 -43
- package/dist/opportunities/discovery.env.d.ts +0 -20
- package/dist/opportunities/discovery.env.js +0 -109
- package/dist/opportunities/discriminator/discriminator.adjustments.d.ts +0 -90
- package/dist/opportunities/discriminator/discriminator.adjustments.js +0 -141
- package/dist/opportunities/discriminator/discriminator.assigner.d.ts +0 -78
- package/dist/opportunities/discriminator/discriminator.assigner.js +0 -153
- package/dist/opportunities/discriminator/discriminator.env.d.ts +0 -103
- package/dist/opportunities/discriminator/discriminator.env.js +0 -103
- package/dist/opportunities/discriminator/discriminator.miner.d.ts +0 -114
- package/dist/opportunities/discriminator/discriminator.miner.js +0 -228
- package/dist/opportunities/discriminator/discriminator.push.d.ts +0 -13
- package/dist/opportunities/discriminator/discriminator.push.js +0 -19
- package/dist/opportunities/discriminator/discriminator.question.d.ts +0 -58
- package/dist/opportunities/discriminator/discriminator.question.js +0 -155
- package/dist/opportunities/discriminator/discriminator.scorer.d.ts +0 -32
- package/dist/opportunities/discriminator/discriminator.scorer.js +0 -105
- package/dist/opportunities/discriminator/discriminator.shadow.d.ts +0 -32
- package/dist/opportunities/discriminator/discriminator.shadow.js +0 -90
- package/dist/opportunities/discriminator/discriminator.types.d.ts +0 -93
- package/dist/opportunities/discriminator/discriminator.types.js +0 -18
- package/dist/opportunities/negotiation-context.loader.d.ts +0 -59
- package/dist/opportunities/negotiation-context.loader.js +0 -90
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.env.d.ts +0 -43
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.env.js +0 -44
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.extractor.d.ts +0 -24
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.extractor.js +0 -188
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.miner.d.ts +0 -26
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.miner.js +0 -112
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.shadow.d.ts +0 -19
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.shadow.js +0 -61
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.types.d.ts +0 -191
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.types.js +0 -18
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.verifier.d.ts +0 -34
- package/dist/opportunities/negotiation-evidence/negotiation-evidence.verifier.js +0 -91
- package/dist/opportunities/negotiation-summary.builder.d.ts +0 -37
- package/dist/opportunities/negotiation-summary.builder.js +0 -66
- package/dist/opportunities/opportunity.discovery-negotiation-summary.d.ts +0 -14
- package/dist/opportunities/opportunity.discovery-negotiation-summary.js +0 -46
- package/dist/opportunities/opportunity.enricher.d.ts +0 -71
- package/dist/opportunities/opportunity.enricher.js +0 -280
- package/dist/opportunities/opportunity.evaluator.d.ts +0 -289
- package/dist/opportunities/opportunity.evaluator.js +0 -516
- package/dist/opportunities/opportunity.evidence.d.ts +0 -22
- package/dist/opportunities/opportunity.evidence.js +0 -87
- package/dist/opportunities/opportunity.existing-negotiation.d.ts +0 -79
- package/dist/opportunities/opportunity.existing-negotiation.js +0 -118
- package/dist/opportunities/opportunity.feed-selection.js +0 -96
- package/dist/opportunities/opportunity.graph.d.ts +0 -1611
- package/dist/opportunities/opportunity.graph.discovery-strategies.d.ts +0 -109
- package/dist/opportunities/opportunity.graph.discovery-strategies.js +0 -451
- package/dist/opportunities/opportunity.graph.discovery.d.ts +0 -69
- package/dist/opportunities/opportunity.graph.discovery.js +0 -397
- package/dist/opportunities/opportunity.graph.evaluation.d.ts +0 -82
- package/dist/opportunities/opportunity.graph.evaluation.js +0 -608
- package/dist/opportunities/opportunity.graph.js +0 -193
- package/dist/opportunities/opportunity.graph.modes.d.ts +0 -538
- package/dist/opportunities/opportunity.graph.modes.js +0 -538
- package/dist/opportunities/opportunity.graph.negotiate.d.ts +0 -109
- package/dist/opportunities/opportunity.graph.negotiate.js +0 -392
- package/dist/opportunities/opportunity.graph.persist-node.d.ts +0 -93
- package/dist/opportunities/opportunity.graph.persist-node.js +0 -765
- package/dist/opportunities/opportunity.graph.prep.d.ts +0 -150
- package/dist/opportunities/opportunity.graph.prep.js +0 -381
- package/dist/opportunities/opportunity.graph.shared.d.ts +0 -173
- package/dist/opportunities/opportunity.graph.shared.js +0 -199
- package/dist/opportunities/opportunity.introducer-feature.d.ts +0 -2
- package/dist/opportunities/opportunity.introducer-feature.js +0 -4
- package/dist/opportunities/opportunity.introducer.d.ts +0 -77
- package/dist/opportunities/opportunity.introducer.js +0 -99
- package/dist/opportunities/opportunity.labels.js +0 -10
- package/dist/opportunities/opportunity.lifecycle.d.ts +0 -63
- package/dist/opportunities/opportunity.lifecycle.js +0 -181
- package/dist/opportunities/opportunity.module.d.ts +0 -54
- package/dist/opportunities/opportunity.module.js +0 -39
- package/dist/opportunities/opportunity.newborn-stamping.d.ts +0 -41
- package/dist/opportunities/opportunity.newborn-stamping.js +0 -81
- package/dist/opportunities/opportunity.owner-approval.d.ts +0 -118
- package/dist/opportunities/opportunity.owner-approval.js +0 -34
- package/dist/opportunities/opportunity.owner-provenance.d.ts +0 -6
- package/dist/opportunities/opportunity.owner-provenance.js +0 -28
- package/dist/opportunities/opportunity.persist.d.ts +0 -58
- package/dist/opportunities/opportunity.persist.js +0 -145
- package/dist/opportunities/opportunity.persistence-admission.d.ts +0 -39
- package/dist/opportunities/opportunity.persistence-admission.js +0 -59
- package/dist/opportunities/opportunity.state.d.ts +0 -451
- package/dist/opportunities/opportunity.state.js +0 -256
- package/dist/opportunities/opportunity.tools.cards.d.ts +0 -138
- package/dist/opportunities/opportunity.tools.cards.js +0 -212
- package/dist/opportunities/opportunity.tools.d.ts +0 -12
- package/dist/opportunities/opportunity.tools.js +0 -236
- package/dist/opportunities/opportunity.tools.list.d.ts +0 -10
- package/dist/opportunities/opportunity.tools.list.js +0 -489
- package/dist/opportunities/opportunity.tools.port.d.ts +0 -16
- package/dist/opportunities/opportunity.utils.d.ts +0 -217
- package/dist/opportunities/opportunity.utils.js +0 -395
- package/dist/opportunities/outcome/outcome.env.d.ts +0 -60
- package/dist/opportunities/outcome/outcome.env.js +0 -63
- package/dist/opportunities/outcome/outcome.hypotheses.d.ts +0 -29
- package/dist/opportunities/outcome/outcome.hypotheses.js +0 -117
- package/dist/opportunities/outcome/outcome.shadow.d.ts +0 -56
- package/dist/opportunities/outcome/outcome.shadow.js +0 -87
- package/dist/opportunities/outcome/outcome.types.d.ts +0 -110
- package/dist/opportunities/outcome/outcome.types.js +0 -26
- package/dist/opportunities/radar/radar.health.d.ts +0 -31
- package/dist/opportunities/radar/radar.health.js +0 -75
- package/dist/premises/premise.analyzer.d.ts +0 -35
- package/dist/premises/premise.analyzer.js +0 -115
- package/dist/premises/premise.decomposer.d.ts +0 -69
- package/dist/premises/premise.decomposer.js +0 -213
- package/dist/premises/premise.graph.d.ts +0 -345
- package/dist/premises/premise.graph.js +0 -278
- package/dist/premises/premise.indexer.d.ts +0 -35
- package/dist/premises/premise.indexer.js +0 -86
- package/dist/premises/premise.state.d.ts +0 -67
- package/dist/premises/premise.state.js +0 -94
- package/dist/premises/premise.tools.d.ts +0 -3
- package/dist/premises/premise.tools.js +0 -248
- package/dist/questions/question.env.d.ts +0 -27
- package/dist/questions/question.env.js +0 -27
- package/dist/questions/question.input.d.ts +0 -107
- package/dist/questions/question.module.d.ts +0 -30
- package/dist/questions/question.module.js +0 -28
- package/dist/questions/question.schema.d.ts +0 -1529
- package/dist/questions/question.schema.js +0 -420
- package/dist/shared/agent/activity-projection.d.ts +0 -271
- package/dist/shared/agent/activity-projection.js +0 -254
- package/dist/shared/agent/canonical-guidance.d.ts +0 -30
- package/dist/shared/agent/canonical-guidance.js +0 -246
- package/dist/shared/agent/model.resolver.d.ts +0 -48
- package/dist/shared/agent/tool.factory.d.ts +0 -17
- package/dist/shared/agent/tool.factory.js +0 -221
- package/dist/shared/agent/tool.helpers.d.ts +0 -482
- package/dist/shared/agent/tool.helpers.js +0 -232
- package/dist/shared/agent/tool.registry.d.ts +0 -25
- package/dist/shared/agent/tool.registry.js +0 -76
- package/dist/shared/agent/tool.runtime.d.ts +0 -28
- package/dist/shared/agent/tool.runtime.js +0 -194
- package/dist/shared/agent/tool.scope.d.ts +0 -44
- package/dist/shared/agent/tool.scope.js +0 -50
- package/dist/shared/agent/utility.tools.d.ts +0 -15
- package/dist/shared/agent/utility.tools.js +0 -322
- package/dist/shared/assignment/network-assignment.policy.d.ts +0 -61
- package/dist/shared/assignment/network-assignment.policy.js +0 -105
- package/dist/shared/interfaces/agent-dispatcher.interface.d.ts +0 -100
- package/dist/shared/interfaces/agent-dispatcher.interface.js +0 -12
- package/dist/shared/interfaces/auth.interface.d.ts +0 -37
- package/dist/shared/interfaces/auth.interface.js +0 -1
- package/dist/shared/interfaces/chat-message-writer.interface.d.ts +0 -18
- package/dist/shared/interfaces/chat-message-writer.interface.js +0 -1
- package/dist/shared/interfaces/chat-session.interface.d.ts +0 -23
- package/dist/shared/interfaces/chat-session.interface.js +0 -18
- package/dist/shared/interfaces/chat-summary.interface.d.ts +0 -16
- package/dist/shared/interfaces/chat-summary.interface.js +0 -1
- package/dist/shared/interfaces/database.capabilities.d.ts +0 -100
- package/dist/shared/interfaces/database.interface.d.ts +0 -16
- package/dist/shared/interfaces/database.member-queries.d.ts +0 -219
- package/dist/shared/interfaces/database.member-queries.js +0 -4
- package/dist/shared/interfaces/database.negotiation.d.ts +0 -329
- package/dist/shared/interfaces/database.negotiation.js +0 -26
- package/dist/shared/interfaces/database.network-queries.js +0 -4
- package/dist/shared/interfaces/database.opportunity-queries.js +0 -4
- package/dist/shared/interfaces/delivery-ledger.interface.d.ts +0 -40
- package/dist/shared/interfaces/delivery-ledger.interface.js +0 -5
- package/dist/shared/interfaces/embedder.interface.d.ts +0 -92
- package/dist/shared/interfaces/embedder.interface.js +0 -4
- package/dist/shared/interfaces/enrichment-run.interface.d.ts +0 -62
- package/dist/shared/interfaces/enrichment-run.interface.js +0 -1
- package/dist/shared/interfaces/enrichment.interface.js +0 -1
- package/dist/shared/interfaces/negotiation-events.interface.d.ts +0 -77
- package/dist/shared/interfaces/negotiation-events.interface.js +0 -6
- package/dist/shared/interfaces/negotiation-summary.interface.d.ts +0 -25
- package/dist/shared/interfaces/negotiation-summary.interface.js +0 -1
- package/dist/shared/interfaces/negotiator-memory.interface.d.ts +0 -58
- package/dist/shared/interfaces/negotiator-memory.interface.js +0 -11
- package/dist/shared/interfaces/queue.interface.d.ts +0 -23
- package/dist/shared/interfaces/queue.interface.js +0 -4
- package/dist/shared/interfaces/scraper.interface.js +0 -1
- package/dist/shared/interfaces/tool-request-context.interface.d.ts +0 -11
- package/dist/shared/interfaces/tool-request-context.interface.js +0 -1
- package/dist/shared/observability/request-context.d.ts +0 -27
- package/dist/shared/observability/request-context.js +0 -6
- package/dist/shared/schemas/mcp-auth.schema.d.ts +0 -87
- package/dist/shared/schemas/mcp-auth.schema.js +0 -56
- package/dist/shared/schemas/negotiation-digest.schema.d.ts +0 -58
- package/dist/shared/schemas/negotiation-digest.schema.js +0 -38
- package/dist/shared/schemas/negotiation-state.schema.d.ts +0 -343
- package/dist/shared/schemas/negotiation-state.schema.js +0 -81
- package/dist/shared/schemas/question-block.fixture.d.ts +0 -12
- package/dist/shared/schemas/question-block.fixture.js +0 -39
- package/dist/shared/schemas/question-block.schema.d.ts +0 -111
- package/dist/shared/schemas/question-block.schema.js +0 -124
- package/dist/shared/schemas/structured-question.schema.d.ts +0 -66
- package/dist/shared/schemas/structured-question.schema.js +0 -31
- package/dist/shared/schemas/underspecification.schema.d.ts +0 -13
- package/dist/shared/schemas/underspecification.schema.js +0 -16
- /package/dist/{opportunities → internal/opportunities}/opportunity.update-admission.js +0 -0
- /package/dist/{opportunities → internal/opportunities}/radar/radar.state.js +0 -0
- /package/dist/{shared → internal/shared}/network/metadata.renderer.d.ts +0 -0
- /package/dist/{shared → internal/shared}/network/metadata.renderer.js +0 -0
- /package/dist/{shared → internal/shared}/observability/debug-meta.sanitizer.d.ts +0 -0
- /package/dist/{shared → internal/shared}/observability/debug-meta.sanitizer.js +0 -0
- /package/dist/{shared → internal/shared}/observability/performance.d.ts +0 -0
- /package/dist/{shared → internal/shared}/observability/performance.js +0 -0
- /package/dist/{shared → internal/shared}/observability/trace.d.ts +0 -0
- /package/dist/{shared → internal/shared}/observability/trace.js +0 -0
- /package/dist/{shared → internal/shared}/utils/claim-safety.d.ts +0 -0
- /package/dist/{shared → internal/shared}/utils/claim-safety.js +0 -0
- /package/dist/{shared → internal/shared}/utils/telegram-handle.d.ts +0 -0
- /package/dist/{shared → internal/shared}/utils/telegram-handle.js +0 -0
- /package/dist/{shared/interfaces/database.capabilities.js → platform/database/capabilities.js} +0 -0
- /package/dist/{shared/interfaces/database.entities.js → platform/database/entities.js} +0 -0
- /package/dist/{shared/interfaces/database.identity-queries.js → platform/database/identity-queries.js} +0 -0
- /package/dist/{agents/agent.dispatcher.port.js → platform/database/negotiation.js} +0 -0
- /package/dist/{chat/chat.persona.js → platform/database/opportunity-queries.js} +0 -0
- /package/dist/{contexts/context.tools.port.js → platform/discovery/embedder.js} +0 -0
- /package/dist/{shared/interfaces/scraper.interface.d.ts → platform/discovery/scraper.d.ts} +0 -0
- /package/dist/{negotiations/negotiation.deadlock.contracts.js → platform/discovery/scraper.js} +0 -0
- /package/dist/{shared/interfaces/enrichment.interface.d.ts → platform/enrichment/ports.d.ts} +0 -0
- /package/dist/{negotiations/negotiation.tools.port.js → platform/enrichment/ports.js} +0 -0
- /package/dist/{opportunities/opportunity.tools.port.js → platform/runtime/observability.js} +0 -0
- /package/dist/{questions/question.input.js → protocol/core.js} +0 -0
- /package/dist/{shared → protocol}/schemas/chat-context.schema.d.ts +0 -0
- /package/dist/{shared → protocol}/schemas/chat-context.schema.js +0 -0
|
@@ -1,662 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Negotiation graph, stage 3: one negotiator turn.
|
|
3
|
-
*/
|
|
4
|
-
import { requestContext } from "../shared/observability/request-context.js";
|
|
5
|
-
import { allowedActionsFor, askUserAnswerWindowMs, configuredAskUserEnabled, fallbackActionFor, negotiationAskRoundsCap, rejectActionFor } from "./negotiation.protocol.js";
|
|
6
|
-
import { assessConsultationEligibility, consultationPromptFor, countOpenPreContactConsults, isPreContactConsultResume, MAX_OPEN_PRE_CONTACT_CONSULTS_PER_INTENT, negotiationConsultationPolicyMode, PRE_CONTACT_CONSULT_MARKER } from "./negotiation.consultation-policy.js";
|
|
7
|
-
import { blocksNegotiationBeforeFirstTurn } from "./negotiation.screen.js";
|
|
8
|
-
import { assessDeadlock, configuredDeadlockShiftEnabled, configuredDeadlockThreshold } from "./negotiation.deadlock.js";
|
|
9
|
-
import { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, isSafeAuthoredNegotiationQuestion, negotiationQuestionSettlementId } from './negotiation.question-safety.js';
|
|
10
|
-
import { isNegotiationTurnCapReached } from "./negotiation.turn-cap.js";
|
|
11
|
-
import { buildAttributedDialogue, countNegotiationAskRounds, hasPriorAskUser, memoryQueryText, retrieveClientDm, retrieveMemory, turnLog, turnsFromMessages } from "./negotiation.graph.shared.js";
|
|
12
|
-
/**
|
|
13
|
-
* Whether this signal may open another pre-contact consultation.
|
|
14
|
-
*
|
|
15
|
-
* The count comes from the user's own parked negotiation tasks — the durable
|
|
16
|
-
* parks themselves — rather than a stored counter, so an answered, expired, or
|
|
17
|
-
* resumed park frees its slot with nothing to keep in step. The acting task is
|
|
18
|
-
* excluded: it is `working` at this point, but a retried turn on a task that
|
|
19
|
-
* already parked must not count itself out.
|
|
20
|
-
*
|
|
21
|
-
* Fails OPEN. This bound defends against an agent that would re-ask the same
|
|
22
|
-
* signal-level question candidate by candidate; it is not the safety gate. The
|
|
23
|
-
* per-negotiation ration and the ask-rounds cap already hold that line from
|
|
24
|
-
* the message record, and neither depends on this query — so a database blip
|
|
25
|
-
* must not silently retire the turn-0 verdict.
|
|
26
|
-
*/
|
|
27
|
-
async function preContactConsultsUnderCap(deps, userId, intentId, actingTaskId) {
|
|
28
|
-
try {
|
|
29
|
-
const parked = await deps.database.getTasksForUser(userId, { state: 'input_required' });
|
|
30
|
-
const open = countOpenPreContactConsults(parked, { userId, intentId, excludeTaskId: actingTaskId });
|
|
31
|
-
if (open >= MAX_OPEN_PRE_CONTACT_CONSULTS_PER_INTENT) {
|
|
32
|
-
turnLog.info('negotiation_pre_contact_consult_capped', {
|
|
33
|
-
userId, intentId, open, cap: MAX_OPEN_PRE_CONTACT_CONSULTS_PER_INTENT,
|
|
34
|
-
});
|
|
35
|
-
return false;
|
|
36
|
-
}
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
catch (err) {
|
|
40
|
-
turnLog.warn('Pre-contact consult cap check failed; proceeding without the per-signal bound', {
|
|
41
|
-
userId,
|
|
42
|
-
intentId,
|
|
43
|
-
error: err instanceof Error ? err.message : String(err),
|
|
44
|
-
});
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
export async function turnNode(state, deps) {
|
|
49
|
-
const traceEmitter = requestContext.getStore()?.traceEmitter;
|
|
50
|
-
// Local helper to emit events whose shape is wider than the declared
|
|
51
|
-
// `TraceEmitter` union. The chat agent already casts at its relay sink;
|
|
52
|
-
// here we localize the cast at the callsite so the rest of the body stays typed.
|
|
53
|
-
const emitWide = (event) => traceEmitter?.(event);
|
|
54
|
-
const agentName = "Index negotiator";
|
|
55
|
-
const agentStart = Date.now();
|
|
56
|
-
traceEmitter?.({ type: "agent_start", name: agentName });
|
|
57
|
-
try {
|
|
58
|
-
const history = turnsFromMessages(state.messages);
|
|
59
|
-
const isSource = state.currentSpeaker === "source";
|
|
60
|
-
const ownUser = isSource ? state.sourceUser : state.candidateUser;
|
|
61
|
-
const otherUser = isSource ? state.candidateUser : state.sourceUser;
|
|
62
|
-
const ownIntentId = isSource ? state.sourceIntentId : state.candidateIntentId;
|
|
63
|
-
// Determine if this is the system agent's final allowed turn.
|
|
64
|
-
const isFinalTurn = isNegotiationTurnCapReached(state.turnCount + 1, state.maxTurns);
|
|
65
|
-
// Seat attribution keys on initiatorUserId (rigid v2 stamp), never on
|
|
66
|
-
// parity or source/candidate position — under the conversation-scoped
|
|
67
|
-
// tie-break this run's source may hold the counterparty seat.
|
|
68
|
-
const version = state.protocolVersion ?? 'v1';
|
|
69
|
-
const seat = ownUser.id === (state.initiatorUserId ?? state.sourceUser.id)
|
|
70
|
-
? 'initiator'
|
|
71
|
-
: 'counterparty';
|
|
72
|
-
// Legacy ask_user availability (P3.2): flag on, full pause loop wired
|
|
73
|
-
// (questioner + answer-window timer + an opportunity to resume
|
|
74
|
-
// against), v2 non-final non-opening turn, and this side's one client
|
|
75
|
-
// consultation not yet spent (rationing). Shadow is observational and
|
|
76
|
-
// must preserve this legacy path byte-for-byte except for telemetry.
|
|
77
|
-
//
|
|
78
|
-
// The negotiation-wide ask-rounds cap reads the same message substrate
|
|
79
|
-
// as the per-side ration. It cannot bind on mid-flight consults alone
|
|
80
|
-
// (one per side < default cap); it exists so post-stall parks — which
|
|
81
|
-
// also persist `ask_user` messages — count against the same budget,
|
|
82
|
-
// and a negotiation near its cap cannot spend a further round here.
|
|
83
|
-
const policyMode = negotiationConsultationPolicyMode();
|
|
84
|
-
// The opening turn, before anything is sent. `outreachOpened` is per-run
|
|
85
|
-
// and history is this negotiation's own record, so this is true exactly
|
|
86
|
-
// once per negotiation — and stays true across a pre-contact park, whose
|
|
87
|
-
// resume re-enters holding nothing but its own `ask_user` turn.
|
|
88
|
-
const isFreshOpeningTurn = state.turnCount === 0 && !state.isContinuation;
|
|
89
|
-
const isPreContactResume = state.turnCount === 0 && isPreContactConsultResume(history);
|
|
90
|
-
// Pre-contact consultation (the turn-0 third verdict). The initiator may
|
|
91
|
-
// consult its client BEFORE deciding whether to reach out, so the seat's
|
|
92
|
-
// opening vocabulary stops being binary. Everything downstream is the
|
|
93
|
-
// shipped consult loop unchanged: same park, same binding, same question
|
|
94
|
-
// routing, same expiry. Only admission moves.
|
|
95
|
-
//
|
|
96
|
-
// Bounded twice over. Per negotiation by the same ration and ask-rounds
|
|
97
|
-
// cap the mid-flight consult reads (this consult IS round 1). Per signal
|
|
98
|
-
// by the open-park count below, so one vague intent cannot interrogate
|
|
99
|
-
// its client candidate-by-candidate.
|
|
100
|
-
const preContactConsultShapeAvailable = isFreshOpeningTurn && seat === 'initiator';
|
|
101
|
-
const askUserWiringAvailable = version === 'v2'
|
|
102
|
-
&& !isFinalTurn
|
|
103
|
-
&& configuredAskUserEnabled()
|
|
104
|
-
&& !!deps.questionerEnqueue
|
|
105
|
-
&& !!deps.timeoutQueue?.enqueueAskUserExpiry
|
|
106
|
-
&& !!state.opportunityId
|
|
107
|
-
&& !!ownIntentId
|
|
108
|
-
&& !!state.indexContext.networkId
|
|
109
|
-
&& (!isFreshOpeningTurn || preContactConsultShapeAvailable)
|
|
110
|
-
&& !hasPriorAskUser(state.messages, ownUser.id)
|
|
111
|
-
&& countNegotiationAskRounds(state.messages) < negotiationAskRoundsCap();
|
|
112
|
-
const askUserAvailable = askUserWiringAvailable
|
|
113
|
-
&& (!preContactConsultShapeAvailable
|
|
114
|
-
|| await preContactConsultsUnderCap(deps, ownUser.id, ownIntentId, state.taskId));
|
|
115
|
-
// ─── Deadlock detection → persuasion→bargaining stance (IND-428) ──────
|
|
116
|
-
// Deterministic trailing-run inspection of the persisted history — no
|
|
117
|
-
// LLM in the decision. Gated on the strict default-off flag AND v2,
|
|
118
|
-
// checked alongside the protocol-version plumbing so v1 semantics stay
|
|
119
|
-
// untouched. Fail-open: any detection error means "no deadlock" and
|
|
120
|
-
// the legacy path proceeds byte-identically. The shift changes the
|
|
121
|
-
// system agent's drafting stance only — allowedActions, the dispatch
|
|
122
|
-
// payload, and all termination rules are untouched.
|
|
123
|
-
let deadlock = null;
|
|
124
|
-
if (version === 'v2' && configuredDeadlockShiftEnabled()) {
|
|
125
|
-
try {
|
|
126
|
-
deadlock = assessDeadlock(history, configuredDeadlockThreshold());
|
|
127
|
-
}
|
|
128
|
-
catch (err) {
|
|
129
|
-
turnLog.warn('Deadlock detection failed; proceeding without mode shift', {
|
|
130
|
-
taskId: state.taskId,
|
|
131
|
-
error: err instanceof Error ? err.message : String(err),
|
|
132
|
-
});
|
|
133
|
-
deadlock = null;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
const bargainingMode = deadlock?.deadlocked === true;
|
|
137
|
-
// P5.3: the speaker's own negotiator memory (cached per side across
|
|
138
|
-
// turns). Injected into both the dispatch payload (the user's own
|
|
139
|
-
// agent — scope-correct) and the system-agent prompt.
|
|
140
|
-
const ownSide = isSource ? "source" : "candidate";
|
|
141
|
-
const ownMemory = state.memoryBySide?.[ownSide]
|
|
142
|
-
?? (deps.memoryRetrieve
|
|
143
|
-
? await retrieveMemory(deps, ownUser.id, otherUser.id, memoryQueryText(state, otherUser), "turn")
|
|
144
|
-
: []);
|
|
145
|
-
const payload = {
|
|
146
|
-
negotiationId: state.taskId,
|
|
147
|
-
ownUser,
|
|
148
|
-
otherUser,
|
|
149
|
-
indexContext: state.indexContext,
|
|
150
|
-
seedAssessment: state.seedAssessment,
|
|
151
|
-
history,
|
|
152
|
-
isFinalTurn,
|
|
153
|
-
isDiscoverer: isSource,
|
|
154
|
-
seat,
|
|
155
|
-
protocolVersion: version,
|
|
156
|
-
allowedActions: [...allowedActionsFor(version, seat, isFinalTurn, { askUser: askUserAvailable })],
|
|
157
|
-
...(state.discoveryQuery && isSource && { discoveryQuery: state.discoveryQuery }),
|
|
158
|
-
...(ownMemory.length > 0 && { negotiatorMemory: ownMemory }),
|
|
159
|
-
...(state.privateConsultation?.recipientUserId === ownUser.id
|
|
160
|
-
? { privateConsultation: state.privateConsultation }
|
|
161
|
-
: {}),
|
|
162
|
-
...(state.continuationExecution
|
|
163
|
-
? {
|
|
164
|
-
timeoutContinuation: {
|
|
165
|
-
priorTaskId: state.continuationExecution.taskId,
|
|
166
|
-
settlementId: state.continuationExecution.settlementId,
|
|
167
|
-
successorTaskId: state.continuationExecution.successorTaskId,
|
|
168
|
-
token: state.continuationExecution.token,
|
|
169
|
-
fence: state.continuationExecution.fence,
|
|
170
|
-
},
|
|
171
|
-
}
|
|
172
|
-
: {}),
|
|
173
|
-
};
|
|
174
|
-
const scope = { action: 'manage:negotiations', scopeType: 'network', scopeId: state.indexContext.networkId };
|
|
175
|
-
const dispatchResult = await deps.dispatcher.dispatch(ownUser.id, scope, payload, { timeoutMs: state.timeoutMs });
|
|
176
|
-
let turn;
|
|
177
|
-
if (dispatchResult.handled) {
|
|
178
|
-
// Personal agent responded. Under v2, coerce out-of-seat actions to
|
|
179
|
-
// the conservative fallback — the polling/respond surfaces reject
|
|
180
|
-
// these with a 400, but locally-dispatched turns land here directly.
|
|
181
|
-
turn = dispatchResult.turn;
|
|
182
|
-
if (version === 'v2' && !allowedActionsFor(version, seat, isFinalTurn, { askUser: askUserAvailable }).includes(turn.action)) {
|
|
183
|
-
turnLog.warn('Personal agent returned out-of-seat action, coercing to conservative fallback', {
|
|
184
|
-
action: turn.action, seat, isFinalTurn,
|
|
185
|
-
});
|
|
186
|
-
turn = { ...turn, action: fallbackActionFor(version, seat, isFinalTurn) };
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
else if (dispatchResult.reason === 'waiting') {
|
|
190
|
-
// Long timeout — graph suspends. Persist the full turn context so the
|
|
191
|
-
// polling agent (and MCP consumers via get_negotiation) reconstruct
|
|
192
|
-
// the same view the in-process system agent would see. The view is
|
|
193
|
-
// stored in absolute source/candidate terms; perspective is projected
|
|
194
|
-
// at pickup time using the claiming user's id.
|
|
195
|
-
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: "waiting_for_agent" });
|
|
196
|
-
await deps.database.setTaskTurnContext(state.taskId, {
|
|
197
|
-
sourceUser: state.sourceUser,
|
|
198
|
-
candidateUser: state.candidateUser,
|
|
199
|
-
indexContext: state.indexContext,
|
|
200
|
-
seedAssessment: state.seedAssessment,
|
|
201
|
-
// Keep discoveryQuery speaker-scoped: include it only when the
|
|
202
|
-
// parked turn belongs to the discoverer (source). Persisting it on
|
|
203
|
-
// candidate-side turns would make the pickup prompt frame the
|
|
204
|
-
// search as "your user searched for X" for the wrong user.
|
|
205
|
-
...(isSource && state.discoveryQuery && { discoveryQuery: state.discoveryQuery }),
|
|
206
|
-
...(state.privateConsultation && state.privateConsultation.recipientUserId === ownUser.id
|
|
207
|
-
? { privateConsultation: state.privateConsultation }
|
|
208
|
-
: {}),
|
|
209
|
-
}, state.continuationExecution);
|
|
210
|
-
await deps.database.updateTaskState(state.taskId, "waiting_for_agent", undefined, state.continuationExecution, dispatchResult.resumeToken);
|
|
211
|
-
return { status: 'waiting_for_agent' };
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
// No personal agent or timeout — run system agent
|
|
215
|
-
const agentPriorDialogue = buildAttributedDialogue(state);
|
|
216
|
-
// ─── A2H: the acting user's own negotiator DM for this signal ──────
|
|
217
|
-
// Retrieved HERE, inside the system-agent branch, rather than beside
|
|
218
|
-
// `ownMemory` above. Two reasons, and the first is the constraint:
|
|
219
|
-
//
|
|
220
|
-
// 1. `payload` is built and dispatched before this point, so the
|
|
221
|
-
// excerpt cannot reach an external agent by a later edit — the
|
|
222
|
-
// value does not exist in that scope. Memory is safe to forward
|
|
223
|
-
// (distilled standing rules); a verbatim excerpt of the client's
|
|
224
|
-
// private thread with their own negotiator is not, and an external
|
|
225
|
-
// registered agent can hold the personal-agent seat.
|
|
226
|
-
// 2. A dispatched turn never reads it, so it never pays for the query.
|
|
227
|
-
//
|
|
228
|
-
// Gated on `askUserAvailable`: the grant is settled before the model
|
|
229
|
-
// runs, so the DM is present on exactly the turns where the agent may
|
|
230
|
-
// consult its client — the turns where knowing what they already said
|
|
231
|
-
// changes what it asks. Fetching it on every turn would move the
|
|
232
|
-
// prompt for every negotiation, not just the consulting ones.
|
|
233
|
-
// `askUserAvailable` already requires a non-empty `ownIntentId`.
|
|
234
|
-
const clientDm = askUserAvailable
|
|
235
|
-
? await retrieveClientDm(deps, ownUser.id, ownIntentId)
|
|
236
|
-
: [];
|
|
237
|
-
turn = await deps.systemAgent.invoke({
|
|
238
|
-
ownUser,
|
|
239
|
-
otherUser,
|
|
240
|
-
indexContext: state.indexContext,
|
|
241
|
-
seedAssessment: state.seedAssessment,
|
|
242
|
-
history,
|
|
243
|
-
isFinalTurn,
|
|
244
|
-
isDiscoverer: isSource,
|
|
245
|
-
seat,
|
|
246
|
-
protocolVersion: version,
|
|
247
|
-
...(state.discoveryQuery && isSource && { discoveryQuery: state.discoveryQuery }),
|
|
248
|
-
isContinuation: state.isContinuation,
|
|
249
|
-
...(agentPriorDialogue && { priorDialogue: agentPriorDialogue }),
|
|
250
|
-
...(state.userAnswers.length > 0 && { userAnswers: state.userAnswers }),
|
|
251
|
-
...(askUserAvailable && { canAskUser: true }),
|
|
252
|
-
...(bargainingMode && { bargaining: { consecutiveNonConvergent: deadlock.consecutiveNonConvergent } }),
|
|
253
|
-
...(ownMemory.length > 0 && { memory: ownMemory }),
|
|
254
|
-
...(clientDm.length > 0 && { clientDm }),
|
|
255
|
-
...(state.privateConsultation?.recipientUserId === ownUser.id
|
|
256
|
-
? { privateConsultation: state.privateConsultation }
|
|
257
|
-
: {}),
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: `${turn.action}` });
|
|
261
|
-
// IND-564 / IND-611: the opening-withdraw guard runs BEFORE the turn-0
|
|
262
|
-
// opening force below. Order matters and used to be inverted: the force
|
|
263
|
-
// rewrote a turn-0 `withdraw` into `outreach` first, which (a) made this
|
|
264
|
-
// guard dead code for a v2 initiator on turn 0 and (b) sent an outreach
|
|
265
|
-
// whose surviving `reasoning` argued against the match to the
|
|
266
|
-
// counterparty. An honest turn-0 refusal is now allowed to stand and
|
|
267
|
-
// flows into the existing quiet `screened_out` path — no message is
|
|
268
|
-
// persisted, so the original guard's intent (never retract a message
|
|
269
|
-
// that was never made) is preserved rather than weakened.
|
|
270
|
-
//
|
|
271
|
-
// Exact ask_user resumes are exempt: the successor is the SAME logical
|
|
272
|
-
// negotiation resumed after the client answered, so post-consultation
|
|
273
|
-
// withdraw is legitimate.
|
|
274
|
-
//
|
|
275
|
-
// A PRE-CONTACT resume is exempt from that exemption. The exemption exists
|
|
276
|
-
// because a mid-flight consult has an outreach behind it — there is a
|
|
277
|
-
// message on the table, and walking away from it is a real move. A
|
|
278
|
-
// pre-contact park has nothing behind it: the counterparty was never
|
|
279
|
-
// contacted, so the post-consult refusal is still the opening refusal and
|
|
280
|
-
// must land on the same quiet `screened_out` outcome the unconsulted pass
|
|
281
|
-
// lands on. This is also what makes an UNANSWERED pre-contact consult
|
|
282
|
-
// resolve to today's behavior — the expiry worker resumes through exactly
|
|
283
|
-
// this path.
|
|
284
|
-
if (turn.action === 'withdraw' && !state.outreachOpened && (!state.continuationExecution || isPreContactResume)) {
|
|
285
|
-
turnLog.info('negotiation_opening_withdraw_screened_out', {
|
|
286
|
-
taskId: state.taskId,
|
|
287
|
-
opportunityId: state.opportunityId || undefined,
|
|
288
|
-
seat,
|
|
289
|
-
turnCount: state.turnCount,
|
|
290
|
-
isContinuation: state.isContinuation,
|
|
291
|
-
});
|
|
292
|
-
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: "screened_out: opening withdraw" });
|
|
293
|
-
return { lastTurn: turn, firstTurnScreenedOut: true };
|
|
294
|
-
}
|
|
295
|
-
// First turn must open the negotiation (unless continuing a prior
|
|
296
|
-
// conversation): v1 → "propose"; v2 initiator → "outreach". A v2 turn-0
|
|
297
|
-
// speaker holding the counterparty seat (tie-break inheritance) is left
|
|
298
|
-
// unforced — it is responding, not opening.
|
|
299
|
-
//
|
|
300
|
-
// A legitimate turn-0 refusal never reaches here: the opening-withdraw
|
|
301
|
-
// guard above already returned. What remains are genuinely malformed
|
|
302
|
-
// openings (a turn-0 `counter`/`question`), which are still coerced.
|
|
303
|
-
//
|
|
304
|
-
// A pre-contact resume is coerced by the same rule: nothing was ever sent,
|
|
305
|
-
// so the negotiation still has to OPEN, and a `counter`/`question` there
|
|
306
|
-
// would make the counterparty's first sight of this match a mid-exchange
|
|
307
|
-
// reply. An admissible `ask_user` is the one non-opening action left to
|
|
308
|
-
// stand — it is the turn-0 third verdict, not a malformed opening.
|
|
309
|
-
if (isFreshOpeningTurn || isPreContactResume) {
|
|
310
|
-
const openingAction = version === 'v2' ? 'outreach' : 'propose';
|
|
311
|
-
const consultingInstead = turn.action === 'ask_user' && askUserAvailable;
|
|
312
|
-
if ((version !== 'v2' || seat === 'initiator') && turn.action !== openingAction && !consultingInstead) {
|
|
313
|
-
turnLog.warn(`Agent returned unexpected action on turn 0, forcing to ${openingAction}`, { action: turn.action });
|
|
314
|
-
// Rebind rather than mutate: `turn` may be the very object a dispatched
|
|
315
|
-
// personal agent returned, and every other rewrite in this function
|
|
316
|
-
// already replaces it instead of editing it in place.
|
|
317
|
-
turn = { ...turn, action: openingAction };
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
// IND-508 deterministic admission is evaluated only after the opening
|
|
321
|
-
// guard but before any turn is persisted. It consumes action/role enums
|
|
322
|
-
// only; free-form reasoning, messages, profiles, and evaluator inputs
|
|
323
|
-
// are intentionally unavailable to the policy.
|
|
324
|
-
let consultationPolicyReason;
|
|
325
|
-
const policyEligibility = policyMode === 'off' ? { eligible: false } : assessConsultationEligibility({
|
|
326
|
-
protocolVersion: version,
|
|
327
|
-
seat,
|
|
328
|
-
isOpeningTurn: isFreshOpeningTurn,
|
|
329
|
-
isFinalTurn,
|
|
330
|
-
screenedOut: blocksNegotiationBeforeFirstTurn(state.screenDecision, state.turnCount),
|
|
331
|
-
action: turn.action,
|
|
332
|
-
ownSuggestedRole: turn.assessment?.suggestedRoles?.ownUser,
|
|
333
|
-
priorActions: history.map((prior) => prior.action),
|
|
334
|
-
previouslyConsulted: hasPriorAskUser(state.messages, ownUser.id),
|
|
335
|
-
hasExactResumeCoordinate: Boolean(configuredAskUserEnabled()
|
|
336
|
-
&& deps.questionerEnqueue
|
|
337
|
-
&& deps.timeoutQueue?.enqueueAskUserExpiry
|
|
338
|
-
&& state.taskId
|
|
339
|
-
&& state.opportunityId
|
|
340
|
-
&& ownIntentId
|
|
341
|
-
&& state.indexContext.networkId),
|
|
342
|
-
lifecycleValid: Boolean(state.taskId && state.opportunityId && ownIntentId && state.indexContext.networkId),
|
|
343
|
-
});
|
|
344
|
-
const emitConsultationTelemetry = (stage, reason) => {
|
|
345
|
-
turnLog.info('negotiation_consultation_policy', { stage, mode: policyMode, reason });
|
|
346
|
-
emitWide({ type: 'negotiation_consultation_policy', stage, mode: policyMode, reason });
|
|
347
|
-
};
|
|
348
|
-
if (policyEligibility.eligible && policyEligibility.reason) {
|
|
349
|
-
emitConsultationTelemetry('eligible', policyEligibility.reason);
|
|
350
|
-
if (policyMode === 'on') {
|
|
351
|
-
// Two shapes reach here and the policy owes them different things.
|
|
352
|
-
//
|
|
353
|
-
// A draft that asked for something ELSE is REPLACED: the policy
|
|
354
|
-
// inferred the consultation, so nothing in that draft was written to
|
|
355
|
-
// be read by the client, and its reasoning/message may carry material
|
|
356
|
-
// the client's question must not (the disclosure and authority
|
|
357
|
-
// categories are inferred from exactly such drafts).
|
|
358
|
-
//
|
|
359
|
-
// A draft that already IS `ask_user` is only ADMITTED. Here the policy
|
|
360
|
-
// is the gate, not the author: the agent volunteered the pause and
|
|
361
|
-
// wrote the question its client reads, and it is the only party that
|
|
362
|
-
// has read this negotiation. Overwriting `askUser` would discard that
|
|
363
|
-
// question and park on a server template — which is what the
|
|
364
|
-
// pre-contact verdict has nothing to fall back on, since a turn-0
|
|
365
|
-
// park has no transcript for the client to read instead. The authored
|
|
366
|
-
// payload still faces the identifier-aware safety gate below.
|
|
367
|
-
const draftedOwnConsultation = turn.action === 'ask_user' && !!turn.askUser;
|
|
368
|
-
consultationPolicyReason = draftedOwnConsultation ? turn.askUser.reason : policyEligibility.reason;
|
|
369
|
-
if (!draftedOwnConsultation) {
|
|
370
|
-
turn = {
|
|
371
|
-
...turn,
|
|
372
|
-
action: 'ask_user',
|
|
373
|
-
message: null,
|
|
374
|
-
assessment: {
|
|
375
|
-
reasoning: 'Client consultation required.',
|
|
376
|
-
suggestedRoles: turn.assessment.suggestedRoles,
|
|
377
|
-
},
|
|
378
|
-
askUser: { reason: consultationPolicyReason },
|
|
379
|
-
};
|
|
380
|
-
}
|
|
381
|
-
emitConsultationTelemetry('asked', consultationPolicyReason);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
// Safety net: off/shadow retain legacy behavior. In on, a spontaneous
|
|
385
|
-
// ask_user is admissible only when the deterministic policy just
|
|
386
|
-
// authorized it, so no unbounded pause can enter shared history.
|
|
387
|
-
if (turn.action === 'ask_user' && (!askUserAvailable || (policyMode === 'on' && !consultationPolicyReason))) {
|
|
388
|
-
turnLog.warn('ask_user emitted while unavailable, coercing to conservative fallback', {
|
|
389
|
-
seat, isFinalTurn, taskId: state.taskId,
|
|
390
|
-
});
|
|
391
|
-
turn = { ...turn, action: fallbackActionFor(version, seat, isFinalTurn) };
|
|
392
|
-
}
|
|
393
|
-
// ─── Deadlock shift record (IND-428) ───────────────────────────────
|
|
394
|
-
// Applied-stance analytics: recorded once per session, on the first
|
|
395
|
-
// turn actually drafted in the bargaining stance (the system agent —
|
|
396
|
-
// externally dispatched turns never receive the stance). Internal
|
|
397
|
-
// metadata only: persisted to tasks.metadata.deadlockShift via the
|
|
398
|
-
// optional hook; negotiation API surfaces project specific fields and
|
|
399
|
-
// never return task metadata verbatim. Every step fails open.
|
|
400
|
-
const bargainingApplied = bargainingMode && !dispatchResult.handled;
|
|
401
|
-
let deadlockShiftRecord = null;
|
|
402
|
-
if (bargainingApplied && !state.deadlockShift) {
|
|
403
|
-
deadlockShiftRecord = {
|
|
404
|
-
reason: 'consecutive_non_convergent',
|
|
405
|
-
consecutiveNonConvergent: deadlock.consecutiveNonConvergent,
|
|
406
|
-
threshold: deadlock.threshold,
|
|
407
|
-
shiftedAtTurn: state.turnCount,
|
|
408
|
-
seat,
|
|
409
|
-
detectedAt: new Date().toISOString(),
|
|
410
|
-
};
|
|
411
|
-
await deps.database.setTaskDeadlockShift?.(state.taskId, deadlockShiftRecord, state.continuationExecution).catch((err) => {
|
|
412
|
-
turnLog.error('Failed to persist deadlock shift record', { taskId: state.taskId, error: err });
|
|
413
|
-
});
|
|
414
|
-
turnLog.info('negotiation_deadlock_shift', {
|
|
415
|
-
taskId: state.taskId,
|
|
416
|
-
opportunityId: state.opportunityId || undefined,
|
|
417
|
-
seat,
|
|
418
|
-
consecutiveNonConvergent: deadlockShiftRecord.consecutiveNonConvergent,
|
|
419
|
-
threshold: deadlockShiftRecord.threshold,
|
|
420
|
-
turnIndex: state.turnCount,
|
|
421
|
-
});
|
|
422
|
-
if (state.opportunityId) {
|
|
423
|
-
emitWide({
|
|
424
|
-
type: 'negotiation_deadlock_shift',
|
|
425
|
-
opportunityId: state.opportunityId,
|
|
426
|
-
negotiationConversationId: state.conversationId,
|
|
427
|
-
turnIndex: state.turnCount,
|
|
428
|
-
actor: isSource ? 'source' : 'candidate',
|
|
429
|
-
consecutiveNonConvergent: deadlockShiftRecord.consecutiveNonConvergent,
|
|
430
|
-
threshold: deadlockShiftRecord.threshold,
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
// ─── Authored ask_user question: identifier-aware safety gate ─────────
|
|
435
|
-
// The agent now writes the question its client reads verbatim (the
|
|
436
|
-
// pre-A2H `disclosureSubject` was only an input to server-templated copy),
|
|
437
|
-
// and an external registered agent can hold the personal-agent seat — so
|
|
438
|
-
// this runs on every turn, dispatched or system, not just our own.
|
|
439
|
-
//
|
|
440
|
-
// Placed BEFORE persistence deliberately. The turn is about to become a
|
|
441
|
-
// message in the shared conversation, so a rejected question must not
|
|
442
|
-
// survive there either; and issue 6 reads the field back off the persisted
|
|
443
|
-
// turn, which means dropping it here is what makes that read safe by
|
|
444
|
-
// construction rather than by remembering to re-check.
|
|
445
|
-
//
|
|
446
|
-
// Rejection is a DOWNGRADE, never a failure: the turn, its action, and
|
|
447
|
-
// `askUser.reason` all stand, so the consultation proceeds on today's
|
|
448
|
-
// enum-only path — the same shape a v1 turn or an older agent produces.
|
|
449
|
-
// A guard that could fail a turn would let malformed model output stall a
|
|
450
|
-
// negotiation, which is strictly worse than asking a generic question.
|
|
451
|
-
//
|
|
452
|
-
// The two inputs are exactly what the api-side payload guard can never
|
|
453
|
-
// have: it sees the question at the DB boundary with no idea who the
|
|
454
|
-
// counterparty is or what the evaluator wrote, so it cannot tell that a
|
|
455
|
-
// well-formed question is naming them or paraphrasing it.
|
|
456
|
-
if (turn.askUser?.question) {
|
|
457
|
-
const counterpartyName = otherUser.profile?.name?.trim();
|
|
458
|
-
const seedReasoning = state.seedAssessment?.reasoning?.trim();
|
|
459
|
-
const safeAuthoredQuestion = isSafeAuthoredNegotiationQuestion(turn.askUser.question, {
|
|
460
|
-
...(counterpartyName ? { forbiddenIdentifiers: [counterpartyName] } : {}),
|
|
461
|
-
...(seedReasoning ? { forbiddenSourceText: [seedReasoning] } : {}),
|
|
462
|
-
});
|
|
463
|
-
if (!safeAuthoredQuestion) {
|
|
464
|
-
turnLog.warn('Dropping unsafe authored ask_user question; consultation continues without it', {
|
|
465
|
-
taskId: state.taskId,
|
|
466
|
-
opportunityId: state.opportunityId || undefined,
|
|
467
|
-
seat,
|
|
468
|
-
handledExternally: dispatchResult.handled,
|
|
469
|
-
});
|
|
470
|
-
const { question: _rejected, ...askUserWithoutQuestion } = turn.askUser;
|
|
471
|
-
turn = { ...turn, askUser: askUserWithoutQuestion };
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
const parts = [{ kind: "data", data: turn }];
|
|
475
|
-
const message = await deps.database.createMessage({
|
|
476
|
-
conversationId: state.conversationId,
|
|
477
|
-
senderId: `agent:${ownUser.id}`,
|
|
478
|
-
role: "agent",
|
|
479
|
-
parts,
|
|
480
|
-
taskId: state.taskId,
|
|
481
|
-
...(state.continuationExecution ? { continuationExecution: state.continuationExecution } : {}),
|
|
482
|
-
});
|
|
483
|
-
// ─── ask_user pause (P3.2) ────────────────────────────────────────────
|
|
484
|
-
// The negotiator consults its OWN client: persist the turn (done above),
|
|
485
|
-
// park the full turn context, arm the answer-window timer, enqueue the
|
|
486
|
-
// question through the negotiation_inflight preset, then suspend the
|
|
487
|
-
// task as input_required. The graph exits at this turn boundary exactly
|
|
488
|
-
// like the waiting_for_agent suspend; the answer (or window expiry)
|
|
489
|
-
// resumes via the run-existing continuation path.
|
|
490
|
-
if (turn.action === 'ask_user') {
|
|
491
|
-
const consultationReason = turn.askUser?.reason;
|
|
492
|
-
const safeAskUser = consultationReason
|
|
493
|
-
? consultationPromptFor(consultationReason)
|
|
494
|
-
: null;
|
|
495
|
-
const settlementId = negotiationQuestionSettlementId(state.taskId);
|
|
496
|
-
const askUserBinding = await deps.database.captureNegotiationAskUserBinding({
|
|
497
|
-
taskId: state.taskId,
|
|
498
|
-
settlementId,
|
|
499
|
-
recipientUserId: ownUser.id,
|
|
500
|
-
recipientIntentId: ownIntentId,
|
|
501
|
-
opportunityId: state.opportunityId,
|
|
502
|
-
networkId: state.indexContext.networkId,
|
|
503
|
-
turnContext: {
|
|
504
|
-
sourceUser: state.sourceUser,
|
|
505
|
-
candidateUser: state.candidateUser,
|
|
506
|
-
indexContext: state.indexContext,
|
|
507
|
-
seedAssessment: state.seedAssessment,
|
|
508
|
-
...(isSource && state.discoveryQuery && { discoveryQuery: state.discoveryQuery }),
|
|
509
|
-
...(consultationReason && { consultationPolicyReason: consultationReason }),
|
|
510
|
-
// Marks a park the counterparty has never been contacted about, so
|
|
511
|
-
// the per-signal open-consult cap can count these without counting
|
|
512
|
-
// mid-flight consults. Read back by `countOpenPreContactConsults`;
|
|
513
|
-
// the park row is the only durable record, so the stamp lives on it.
|
|
514
|
-
...(isFreshOpeningTurn ? { [PRE_CONTACT_CONSULT_MARKER]: true } : {}),
|
|
515
|
-
},
|
|
516
|
-
...(state.continuationExecution ? { continuationExecution: state.continuationExecution } : {}),
|
|
517
|
-
});
|
|
518
|
-
// Arm the timer BEFORE flipping state: it is the durable recovery
|
|
519
|
-
// trigger even when generation enqueues no job or persists no row.
|
|
520
|
-
const windowMs = askUserAnswerWindowMs();
|
|
521
|
-
await deps.timeoutQueue.enqueueAskUserExpiry(state.taskId, {
|
|
522
|
-
settlementId,
|
|
523
|
-
opportunityId: state.opportunityId,
|
|
524
|
-
userId: ownUser.id,
|
|
525
|
-
recipientIntentId: ownIntentId,
|
|
526
|
-
networkId: state.indexContext.networkId,
|
|
527
|
-
intentFingerprint: askUserBinding.intentFingerprint,
|
|
528
|
-
opportunityStatus: askUserBinding.opportunityStatus,
|
|
529
|
-
opportunityUpdatedAt: askUserBinding.opportunityUpdatedAt,
|
|
530
|
-
counterpartyUserId: askUserBinding.counterpartyUserId,
|
|
531
|
-
counterpartyIntentId: askUserBinding.counterpartyIntentId,
|
|
532
|
-
}, windowMs);
|
|
533
|
-
// Persistence admission requires the exact task to be input_required.
|
|
534
|
-
// Flip before enqueue; if the structured ask_user fields fail the
|
|
535
|
-
// deterministic privacy gate, the timer alone closes the exact task.
|
|
536
|
-
await deps.database.updateTaskState(state.taskId, 'input_required', undefined, state.continuationExecution);
|
|
537
|
-
if (safeAskUser) {
|
|
538
|
-
const userContext = (await deps.database.getUserContext(ownUser.id, null).catch(() => null))?.text ?? '';
|
|
539
|
-
await deps.questionerEnqueue({
|
|
540
|
-
mode: 'negotiation_inflight',
|
|
541
|
-
purpose: 'inflight_consultation',
|
|
542
|
-
userId: ownUser.id,
|
|
543
|
-
sourceType: 'opportunity',
|
|
544
|
-
sourceId: state.opportunityId,
|
|
545
|
-
negotiation: {
|
|
546
|
-
purpose: 'inflight_consultation',
|
|
547
|
-
recipientUserId: ownUser.id,
|
|
548
|
-
recipientIntentId: ownIntentId,
|
|
549
|
-
opportunityId: state.opportunityId,
|
|
550
|
-
taskId: state.taskId,
|
|
551
|
-
networkId: state.indexContext.networkId,
|
|
552
|
-
},
|
|
553
|
-
context: {
|
|
554
|
-
negotiationId: state.taskId,
|
|
555
|
-
counterpartyHint: NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY,
|
|
556
|
-
indexContext: NEGOTIATION_QUESTION_GENERIC_NETWORK,
|
|
557
|
-
consultationPolicyReason: consultationReason,
|
|
558
|
-
...(userContext && { userContext }),
|
|
559
|
-
},
|
|
560
|
-
}).catch((error) => {
|
|
561
|
-
turnLog.error('Failed to enqueue safe ask_user question; timeout recovery remains armed', {
|
|
562
|
-
taskId: state.taskId,
|
|
563
|
-
opportunityId: state.opportunityId,
|
|
564
|
-
error,
|
|
565
|
-
});
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
else {
|
|
569
|
-
turnLog.warn('Skipping unsafe or incomplete ask_user question generation', {
|
|
570
|
-
taskId: state.taskId,
|
|
571
|
-
opportunityId: state.opportunityId,
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
turnLog.info('negotiation_ask_user_pause', {
|
|
575
|
-
taskId: state.taskId,
|
|
576
|
-
opportunityId: state.opportunityId,
|
|
577
|
-
seat,
|
|
578
|
-
askingUserId: ownUser.id,
|
|
579
|
-
windowMs,
|
|
580
|
-
});
|
|
581
|
-
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: "ask_user" });
|
|
582
|
-
emitWide({
|
|
583
|
-
type: 'negotiation_ask_user',
|
|
584
|
-
opportunityId: state.opportunityId,
|
|
585
|
-
negotiationConversationId: state.conversationId,
|
|
586
|
-
turnIndex: state.turnCount,
|
|
587
|
-
actor: isSource ? 'source' : 'candidate',
|
|
588
|
-
questionGenerationSafe: Boolean(safeAskUser),
|
|
589
|
-
windowMs,
|
|
590
|
-
});
|
|
591
|
-
return {
|
|
592
|
-
messages: [{
|
|
593
|
-
id: message.id,
|
|
594
|
-
senderId: message.senderId,
|
|
595
|
-
role: "agent",
|
|
596
|
-
parts: message.parts,
|
|
597
|
-
createdAt: message.createdAt,
|
|
598
|
-
taskId: state.taskId,
|
|
599
|
-
}],
|
|
600
|
-
turnCount: state.turnCount + 1,
|
|
601
|
-
lastTurn: turn,
|
|
602
|
-
status: 'input_required',
|
|
603
|
-
...(deadlockShiftRecord && { deadlockShift: deadlockShiftRecord }),
|
|
604
|
-
};
|
|
605
|
-
}
|
|
606
|
-
await deps.database.updateTaskState(state.taskId, "working", undefined, state.continuationExecution);
|
|
607
|
-
if (state.opportunityId) {
|
|
608
|
-
emitWide({
|
|
609
|
-
type: "negotiation_turn",
|
|
610
|
-
opportunityId: state.opportunityId,
|
|
611
|
-
negotiationConversationId: state.conversationId,
|
|
612
|
-
turnIndex: state.turnCount,
|
|
613
|
-
actor: isSource ? "source" : "candidate",
|
|
614
|
-
action: turn.action,
|
|
615
|
-
...(turn.assessment?.reasoning && { reasoning: turn.assessment.reasoning }),
|
|
616
|
-
...(turn.message && { message: turn.message }),
|
|
617
|
-
...(turn.assessment?.suggestedRoles && { suggestedRoles: turn.assessment.suggestedRoles }),
|
|
618
|
-
durationMs: Date.now() - agentStart,
|
|
619
|
-
});
|
|
620
|
-
}
|
|
621
|
-
return {
|
|
622
|
-
// `taskId` is what makes this turn part of THIS session's block in the
|
|
623
|
-
// attributed prior dialogue (IND-569). Persisted with the current task
|
|
624
|
-
// id above; carried onto the state message so `buildAttributedDialogue`
|
|
625
|
-
// can match it. Dropping it silently emptied the "[Current opportunity —
|
|
626
|
-
// under negotiation now]" block, which — because the attributed
|
|
627
|
-
// rendering replaces the flat history in the prompt — left every turn
|
|
628
|
-
// after the opening blind to the exchange it was answering.
|
|
629
|
-
messages: [{
|
|
630
|
-
id: message.id,
|
|
631
|
-
senderId: message.senderId,
|
|
632
|
-
role: "agent",
|
|
633
|
-
parts: message.parts,
|
|
634
|
-
createdAt: message.createdAt,
|
|
635
|
-
taskId: state.taskId,
|
|
636
|
-
}],
|
|
637
|
-
turnCount: state.turnCount + 1,
|
|
638
|
-
currentSpeaker: (isSource ? "candidate" : "source"),
|
|
639
|
-
lastTurn: turn,
|
|
640
|
-
memoryBySide: { [ownSide]: ownMemory },
|
|
641
|
-
// Record the in-task outreach so a later `withdraw` is legal (IND-564).
|
|
642
|
-
...(turn.action === 'outreach' && { outreachOpened: true }),
|
|
643
|
-
...(deadlockShiftRecord && { deadlockShift: deadlockShiftRecord }),
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
catch (err) {
|
|
647
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
648
|
-
turnLog.error("Agent invocation failed", { error: errMsg, stack: err instanceof Error ? err.stack : undefined, turnCount: state.turnCount });
|
|
649
|
-
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: `error: ${errMsg}` });
|
|
650
|
-
const errorSeat = (state.currentSpeaker === 'source' ? state.sourceUser.id : state.candidateUser.id) === (state.initiatorUserId ?? state.sourceUser.id)
|
|
651
|
-
? 'initiator'
|
|
652
|
-
: 'counterparty';
|
|
653
|
-
return {
|
|
654
|
-
lastTurn: {
|
|
655
|
-
action: rejectActionFor(state.protocolVersion ?? 'v1', errorSeat),
|
|
656
|
-
assessment: { reasoning: `Agent error: ${errMsg}`, suggestedRoles: { ownUser: "peer", otherUser: "peer" } },
|
|
657
|
-
},
|
|
658
|
-
turnCount: state.turnCount + 1,
|
|
659
|
-
error: `Turn failed: ${errMsg}`,
|
|
660
|
-
};
|
|
661
|
-
}
|
|
662
|
-
}
|