@indexnetwork/protocol 6.12.1-rc.404.1 → 6.13.22-rc.405.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 +240 -0
- package/IMPLEMENTATION.md +20 -0
- package/STABILITY.md +4 -0
- package/dist/agent/agent.tools.d.ts +11 -3
- package/dist/agent/agent.tools.js +11 -301
- package/dist/capabilities/communities.facade.d.ts +13 -0
- package/dist/capabilities/communities.facade.js +12 -0
- package/dist/capabilities/communities.tools.port.d.ts +5 -0
- package/dist/capabilities/communities.tools.port.js +1 -0
- package/dist/capabilities/contacts.facade.d.ts +9 -0
- package/dist/capabilities/contacts.facade.js +8 -0
- package/dist/capabilities/contacts.tools.port.d.ts +9 -0
- package/dist/capabilities/contacts.tools.port.js +1 -0
- package/dist/capabilities/integrations.facade.d.ts +8 -0
- package/dist/capabilities/integrations.facade.js +7 -0
- package/dist/capabilities/integrations.tools.port.d.ts +9 -0
- package/dist/capabilities/integrations.tools.port.js +1 -0
- package/dist/capabilities/interaction-composition.facade.d.ts +10 -0
- package/dist/capabilities/interaction-composition.facade.js +9 -0
- package/dist/capabilities/negotiation.discovery.facade.d.ts +9 -0
- package/dist/capabilities/negotiation.discovery.facade.js +7 -0
- package/dist/capabilities/negotiation.facade.d.ts +23 -0
- package/dist/capabilities/negotiation.facade.js +17 -0
- package/dist/capabilities/negotiation.memory.facade.d.ts +6 -0
- package/dist/capabilities/negotiation.memory.facade.js +5 -0
- package/dist/capabilities/negotiation.questions.facade.d.ts +6 -0
- package/dist/capabilities/negotiation.questions.facade.js +5 -0
- package/dist/capabilities/negotiation.state.facade.d.ts +5 -0
- package/dist/capabilities/negotiation.state.facade.js +1 -0
- package/dist/capabilities/negotiation.summary.facade.d.ts +5 -0
- package/dist/capabilities/negotiation.summary.facade.js +5 -0
- package/dist/capabilities/negotiation.tools.port.d.ts +5 -0
- package/dist/capabilities/negotiation.tools.port.js +1 -0
- package/dist/capabilities/opportunities.facade.d.ts +50 -0
- package/dist/capabilities/opportunities.facade.js +50 -0
- package/dist/capabilities/opportunities.safety.facade.d.ts +2 -0
- package/dist/capabilities/opportunities.safety.facade.js +2 -0
- package/dist/capabilities/opportunities.tools.port.d.ts +5 -0
- package/dist/capabilities/opportunities.tools.port.js +1 -0
- package/dist/capabilities/participant-agents.debug.facade.d.ts +2 -0
- package/dist/capabilities/participant-agents.debug.facade.js +1 -0
- package/dist/capabilities/participant-agents.facade.d.ts +35 -0
- package/dist/capabilities/participant-agents.facade.js +35 -0
- package/dist/capabilities/participant-agents.tools.facade.d.ts +8 -0
- package/dist/capabilities/participant-agents.tools.facade.js +8 -0
- package/dist/capabilities/participant-agents.tools.port.d.ts +9 -0
- package/dist/capabilities/participant-agents.tools.port.js +1 -0
- package/dist/capabilities/participant-context.facade.d.ts +13 -0
- package/dist/capabilities/participant-context.facade.js +14 -0
- package/dist/capabilities/participant-context.tools.port.d.ts +9 -0
- package/dist/capabilities/participant-context.tools.port.js +1 -0
- package/dist/capabilities/questions.enqueue.facade.d.ts +5 -0
- package/dist/capabilities/questions.enqueue.facade.js +1 -0
- package/dist/capabilities/questions.facade.d.ts +8 -0
- package/dist/capabilities/questions.facade.js +7 -0
- package/dist/capabilities/questions.runtime.facade.d.ts +5 -0
- package/dist/capabilities/questions.runtime.facade.js +5 -0
- package/dist/capabilities/questions.tools.port.d.ts +5 -0
- package/dist/capabilities/questions.tools.port.js +1 -0
- package/dist/capabilities/signals.facade.d.ts +16 -0
- package/dist/capabilities/signals.facade.js +14 -0
- package/dist/capabilities/signals.indexing.facade.d.ts +12 -0
- package/dist/capabilities/signals.indexing.facade.js +11 -0
- package/dist/capabilities/signals.tools.port.d.ts +5 -0
- package/dist/capabilities/signals.tools.port.js +1 -0
- package/dist/chat/chat-streaming.types.d.ts +0 -1
- package/dist/chat/chat-streaming.types.js +1 -2
- package/dist/chat/chat.agent.d.ts +0 -1
- package/dist/chat/chat.agent.js +0 -1
- package/dist/chat/chat.graph.d.ts +0 -1
- package/dist/chat/chat.graph.js +0 -1
- package/dist/chat/chat.interrupt.classifier.d.ts +0 -1
- package/dist/chat/chat.interrupt.classifier.js +0 -1
- package/dist/chat/chat.persona.d.ts +0 -1
- package/dist/chat/chat.persona.js +0 -1
- package/dist/chat/chat.prompt.d.ts +0 -1
- package/dist/chat/chat.prompt.js +0 -1
- package/dist/chat/chat.prompt.modules.d.ts +0 -1
- package/dist/chat/chat.prompt.modules.js +0 -1
- package/dist/chat/chat.question-dedup.d.ts +0 -1
- package/dist/chat/chat.question-dedup.js +0 -1
- package/dist/chat/chat.state.d.ts +0 -1
- package/dist/chat/chat.state.js +0 -1
- package/dist/chat/chat.streamer.d.ts +0 -1
- package/dist/chat/chat.streamer.js +0 -1
- package/dist/chat/chat.suggester.d.ts +0 -1
- package/dist/chat/chat.suggester.js +0 -1
- package/dist/chat/chat.summarizer.d.ts +0 -1
- package/dist/chat/chat.summarizer.js +0 -1
- package/dist/chat/chat.title.generator.d.ts +0 -1
- package/dist/chat/chat.title.generator.js +0 -1
- package/dist/chat/chat.tools.d.ts +0 -1
- package/dist/chat/chat.tools.js +0 -1
- package/dist/chat/chat.utils.d.ts +0 -1
- package/dist/chat/chat.utils.js +0 -1
- package/dist/chat/negotiator.persona.d.ts +0 -1
- package/dist/chat/negotiator.persona.js +0 -1
- package/dist/chat/negotiator.prompt.d.ts +1 -2
- package/dist/chat/negotiator.prompt.js +1 -2
- package/dist/chat/negotiator.tools.d.ts +0 -1
- package/dist/chat/negotiator.tools.js +0 -1
- package/dist/chat/onboarding.persona.d.ts +0 -1
- package/dist/chat/onboarding.persona.js +0 -1
- package/dist/chat/onboarding.prompt.d.ts +0 -1
- package/dist/chat/onboarding.prompt.js +0 -1
- package/dist/chat/reporter.action.contracts.d.ts +36 -0
- package/dist/chat/reporter.action.contracts.js +1 -0
- package/dist/chat/reporter.action.tools.d.ts +2 -37
- package/dist/chat/reporter.action.tools.js +0 -1
- package/dist/chat/reporter.persona.d.ts +0 -1
- package/dist/chat/reporter.persona.js +0 -1
- package/dist/chat/reporter.prompt.d.ts +0 -1
- package/dist/chat/reporter.prompt.js +0 -1
- package/dist/chat/signal.persona.d.ts +0 -1
- package/dist/chat/signal.persona.js +0 -1
- package/dist/chat/signal.prompt.d.ts +0 -1
- package/dist/chat/signal.prompt.js +0 -1
- package/dist/communities/application/index.d.ts +45 -0
- package/dist/communities/application/index.js +50 -0
- package/dist/communities/application/indexer.graph.d.ts +446 -0
- package/dist/communities/application/indexer.graph.js +420 -0
- package/dist/communities/application/indexer.state.d.ts +172 -0
- package/dist/communities/application/indexer.state.js +116 -0
- package/dist/communities/application/membership.graph.d.ts +270 -0
- package/dist/communities/application/membership.graph.js +229 -0
- package/dist/communities/application/network.graph.d.ts +648 -0
- package/dist/communities/application/network.graph.js +303 -0
- package/dist/communities/application/network.recommender.d.ts +44 -0
- package/dist/communities/application/network.recommender.js +113 -0
- package/dist/communities/application/network.tools.d.ts +35 -0
- package/dist/communities/application/network.tools.js +578 -0
- package/dist/communities/domain/index.d.ts +29 -0
- package/dist/communities/domain/index.js +31 -0
- package/dist/communities/domain/membership.state.d.ts +87 -0
- package/dist/communities/domain/membership.state.js +53 -0
- package/dist/communities/domain/network.state.d.ts +192 -0
- package/dist/communities/domain/network.state.js +66 -0
- package/dist/communities/index.d.ts +14 -0
- package/dist/communities/index.js +14 -0
- package/dist/communities/ports/index.d.ts +25 -0
- package/dist/communities/ports/index.js +27 -0
- package/dist/communities/public/index.d.ts +30 -0
- package/dist/communities/public/index.js +33 -0
- package/dist/contact/contact.inviter.d.ts +7 -44
- package/dist/contact/contact.inviter.js +6 -59
- package/dist/contact/contact.tools.d.ts +7 -5
- package/dist/contact/contact.tools.js +7 -177
- package/dist/contacts/application/contact.inviter.d.ts +49 -0
- package/dist/contacts/application/contact.inviter.js +64 -0
- package/dist/contacts/application/contact.tools.d.ts +20 -0
- package/dist/contacts/application/contact.tools.js +191 -0
- package/dist/contacts/application/index.d.ts +22 -0
- package/dist/contacts/application/index.js +21 -0
- package/dist/contacts/domain/contact.types.d.ts +51 -0
- package/dist/contacts/domain/contact.types.js +10 -0
- package/dist/contacts/domain/index.d.ts +18 -0
- package/dist/contacts/domain/index.js +1 -0
- package/dist/contacts/index.d.ts +24 -0
- package/dist/contacts/index.js +24 -0
- package/dist/contacts/ports/contact.repository.port.d.ts +28 -0
- package/dist/contacts/ports/contact.repository.port.js +14 -0
- package/dist/contacts/ports/contact.tools.port.d.ts +26 -0
- package/dist/contacts/ports/contact.tools.port.js +21 -0
- package/dist/contacts/ports/index.d.ts +22 -0
- package/dist/contacts/ports/index.js +21 -0
- package/dist/contacts/public/index.d.ts +36 -0
- package/dist/contacts/public/index.js +33 -0
- package/dist/context/context.generator.d.ts +0 -1
- package/dist/context/context.generator.js +0 -1
- package/dist/enrichment/enrichment.enricher.d.ts +0 -1
- package/dist/enrichment/enrichment.enricher.js +0 -1
- package/dist/enrichment/enrichment.generator.d.ts +0 -1
- package/dist/enrichment/enrichment.generator.js +0 -1
- package/dist/enrichment/enrichment.graph.d.ts +6 -7
- package/dist/enrichment/enrichment.graph.js +0 -1
- package/dist/enrichment/enrichment.state.d.ts +2 -3
- package/dist/enrichment/enrichment.state.js +0 -1
- package/dist/enrichment/enrichment.tools.d.ts +3 -3
- package/dist/enrichment/enrichment.tools.js +0 -1
- package/dist/index.d.ts +106 -91
- package/dist/index.js +79 -71
- package/dist/integration/integration.tools.d.ts +6 -10
- package/dist/integration/integration.tools.js +6 -82
- package/dist/integrations/application/index.d.ts +14 -0
- package/dist/integrations/application/index.js +14 -0
- package/dist/integrations/application/integration.tools.d.ts +27 -0
- package/dist/integrations/application/integration.tools.js +98 -0
- package/dist/integrations/domain/index.d.ts +18 -0
- package/dist/integrations/domain/index.js +1 -0
- package/dist/integrations/domain/integration.types.d.ts +53 -0
- package/dist/integrations/domain/integration.types.js +11 -0
- package/dist/integrations/index.d.ts +27 -0
- package/dist/integrations/index.js +27 -0
- package/dist/integrations/ports/index.d.ts +28 -0
- package/dist/integrations/ports/index.js +26 -0
- package/dist/integrations/ports/integration.adapter.port.d.ts +62 -0
- package/dist/integrations/ports/integration.adapter.port.js +15 -0
- package/dist/integrations/ports/integration.importer.port.d.ts +31 -0
- package/dist/integrations/ports/integration.importer.port.js +15 -0
- package/dist/integrations/ports/integration.tools.port.d.ts +28 -0
- package/dist/integrations/ports/integration.tools.port.js +21 -0
- package/dist/integrations/public/index.d.ts +37 -0
- package/dist/integrations/public/index.js +34 -0
- package/dist/intent/intent.clarifier.d.ts +3 -52
- package/dist/intent/intent.clarifier.js +2 -202
- package/dist/intent/intent.graph.d.ts +3 -551
- package/dist/intent/intent.graph.js +3 -937
- package/dist/intent/intent.indexer.d.ts +2 -83
- package/dist/intent/intent.indexer.js +2 -171
- package/dist/intent/intent.inferrer.d.ts +2 -95
- package/dist/intent/intent.inferrer.js +2 -234
- package/dist/intent/intent.reconciler.d.ts +2 -106
- package/dist/intent/intent.reconciler.js +2 -187
- package/dist/intent/intent.specificity.d.ts +2 -3
- package/dist/intent/intent.specificity.js +2 -3
- package/dist/intent/intent.state.d.ts +8 -229
- package/dist/intent/intent.state.js +8 -189
- package/dist/intent/intent.tools.d.ts +6 -24
- package/dist/intent/intent.tools.js +4 -788
- package/dist/intent/intent.verifier.d.ts +2 -116
- package/dist/intent/intent.verifier.js +2 -263
- package/dist/maintenance/maintenance.graph.d.ts +0 -1
- package/dist/maintenance/maintenance.graph.js +0 -1
- package/dist/maintenance/maintenance.state.d.ts +0 -1
- package/dist/maintenance/maintenance.state.js +0 -1
- package/dist/mcp/elicitation.builder.d.ts +0 -1
- package/dist/mcp/elicitation.builder.js +0 -1
- package/dist/mcp/elicitation.dispatcher.d.ts +0 -1
- package/dist/mcp/elicitation.dispatcher.js +0 -1
- package/dist/mcp/mcp.server.d.ts +0 -1
- package/dist/mcp/mcp.server.js +1 -2
- package/dist/negotiation/application/index.d.ts +48 -0
- package/dist/negotiation/application/index.js +49 -0
- package/dist/negotiation/application/insight.generator.d.ts +31 -0
- package/dist/negotiation/application/insight.generator.js +105 -0
- package/dist/negotiation/application/negotiation.agent.d.ts +110 -0
- package/dist/negotiation/application/negotiation.agent.js +244 -0
- package/dist/negotiation/application/negotiation.detail-reader.d.ts +94 -0
- package/dist/negotiation/application/negotiation.detail-reader.js +91 -0
- package/dist/negotiation/application/negotiation.graph.d.ts +664 -0
- package/dist/negotiation/application/negotiation.graph.js +1393 -0
- package/dist/negotiation/application/negotiation.reflect.d.ts +194 -0
- package/dist/negotiation/application/negotiation.reflect.js +145 -0
- package/dist/negotiation/application/negotiation.screen.d.ts +78 -0
- package/dist/negotiation/application/negotiation.screen.js +108 -0
- package/dist/negotiation/application/negotiation.summarizer.d.ts +25 -0
- package/dist/negotiation/application/negotiation.summarizer.js +101 -0
- package/dist/negotiation/application/negotiation.tools.d.ts +18 -0
- package/dist/negotiation/application/negotiation.tools.js +782 -0
- package/dist/negotiation/domain/index.d.ts +48 -0
- package/dist/negotiation/domain/index.js +50 -0
- package/dist/negotiation/domain/negotiation.consultation-policy.d.ts +39 -0
- package/dist/negotiation/domain/negotiation.consultation-policy.js +68 -0
- package/dist/negotiation/domain/negotiation.deadlock.contracts.d.ts +10 -0
- package/dist/negotiation/domain/negotiation.deadlock.contracts.js +1 -0
- package/dist/negotiation/domain/negotiation.deadlock.d.ts +81 -0
- package/dist/negotiation/domain/negotiation.deadlock.js +103 -0
- package/dist/negotiation/domain/negotiation.intent-snapshot-provenance.d.ts +21 -0
- package/dist/negotiation/domain/negotiation.intent-snapshot-provenance.js +28 -0
- package/dist/negotiation/domain/negotiation.lifecycle-narration.d.ts +18 -0
- package/dist/negotiation/domain/negotiation.lifecycle-narration.js +87 -0
- package/dist/negotiation/domain/negotiation.memory.d.ts +65 -0
- package/dist/negotiation/domain/negotiation.memory.js +83 -0
- package/dist/negotiation/domain/negotiation.protocol.d.ts +536 -0
- package/dist/negotiation/domain/negotiation.protocol.js +202 -0
- package/dist/negotiation/domain/negotiation.question-safety.d.ts +25 -0
- package/dist/negotiation/domain/negotiation.question-safety.js +55 -0
- package/dist/negotiation/domain/negotiation.screen.contracts.d.ts +88 -0
- package/dist/negotiation/domain/negotiation.screen.contracts.js +58 -0
- package/dist/negotiation/domain/negotiation.state.d.ts +497 -0
- package/dist/negotiation/domain/negotiation.state.js +288 -0
- package/dist/negotiation/domain/negotiation.task-lock-policy.d.ts +10 -0
- package/dist/negotiation/domain/negotiation.task-lock-policy.js +22 -0
- package/dist/negotiation/index.d.ts +49 -0
- package/dist/negotiation/index.js +49 -0
- package/dist/negotiation/insight.generator.d.ts +3 -30
- package/dist/negotiation/insight.generator.js +3 -104
- package/dist/negotiation/negotiation.agent.d.ts +3 -109
- package/dist/negotiation/negotiation.agent.js +3 -248
- package/dist/negotiation/negotiation.attribution.d.ts +0 -1
- package/dist/negotiation/negotiation.attribution.js +0 -1
- package/dist/negotiation/negotiation.consultation-policy.d.ts +3 -38
- package/dist/negotiation/negotiation.consultation-policy.js +3 -67
- package/dist/negotiation/negotiation.deadlock.contracts.d.ts +5 -0
- package/dist/negotiation/negotiation.deadlock.contracts.js +5 -0
- package/dist/negotiation/negotiation.deadlock.d.ts +3 -94
- package/dist/negotiation/negotiation.deadlock.js +3 -101
- package/dist/negotiation/negotiation.detail-reader.d.ts +5 -0
- package/dist/negotiation/negotiation.detail-reader.js +5 -0
- package/dist/negotiation/negotiation.graph.d.ts +3 -663
- package/dist/negotiation/negotiation.graph.js +3 -1459
- package/dist/negotiation/negotiation.intent-snapshot-provenance.d.ts +5 -0
- package/dist/negotiation/negotiation.intent-snapshot-provenance.js +5 -0
- package/dist/negotiation/negotiation.lifecycle-narration.d.ts +5 -0
- package/dist/negotiation/negotiation.lifecycle-narration.js +5 -0
- package/dist/negotiation/negotiation.memory.d.ts +5 -56
- package/dist/negotiation/negotiation.memory.js +5 -69
- package/dist/negotiation/negotiation.protocol.d.ts +3 -535
- package/dist/negotiation/negotiation.protocol.js +3 -201
- package/dist/negotiation/negotiation.question-safety.d.ts +3 -24
- package/dist/negotiation/negotiation.question-safety.js +3 -54
- package/dist/negotiation/negotiation.reflect.d.ts +4 -197
- package/dist/negotiation/negotiation.reflect.js +4 -151
- package/dist/negotiation/negotiation.screen.d.ts +6 -159
- package/dist/negotiation/negotiation.screen.js +6 -152
- package/dist/negotiation/negotiation.state.d.ts +3 -495
- package/dist/negotiation/negotiation.state.js +3 -284
- package/dist/negotiation/negotiation.summarizer.d.ts +3 -24
- package/dist/negotiation/negotiation.summarizer.js +3 -100
- package/dist/negotiation/negotiation.task-lock-policy.d.ts +5 -0
- package/dist/negotiation/negotiation.task-lock-policy.js +5 -0
- package/dist/negotiation/negotiation.tools.d.ts +3 -15
- package/dist/negotiation/negotiation.tools.js +3 -946
- package/dist/negotiation/ports/index.d.ts +18 -0
- package/dist/negotiation/ports/index.js +18 -0
- package/dist/negotiation/ports/negotiation.tools.port.d.ts +18 -0
- package/dist/negotiation/ports/negotiation.tools.port.js +1 -0
- package/dist/negotiation/public/index.d.ts +58 -0
- package/dist/negotiation/public/index.js +60 -0
- package/dist/network/indexer/indexer.graph.d.ts +3 -413
- package/dist/network/indexer/indexer.graph.js +3 -375
- package/dist/network/indexer/indexer.state.d.ts +3 -149
- package/dist/network/indexer/indexer.state.js +3 -98
- package/dist/network/membership/membership.graph.d.ts +3 -248
- package/dist/network/membership/membership.graph.js +3 -202
- package/dist/network/membership/membership.state.d.ts +3 -75
- package/dist/network/membership/membership.state.js +3 -41
- package/dist/network/network.graph.d.ts +3 -629
- package/dist/network/network.graph.js +3 -267
- package/dist/network/network.recommender.d.ts +3 -40
- package/dist/network/network.recommender.js +3 -109
- package/dist/network/network.state.d.ts +3 -180
- package/dist/network/network.state.js +3 -54
- package/dist/network/network.tools.d.ts +5 -3
- package/dist/network/network.tools.js +5 -566
- package/dist/opportunity/application/delivery-card.cache.d.ts +25 -0
- package/dist/opportunity/application/delivery-card.cache.js +43 -0
- package/dist/opportunity/application/index.d.ts +63 -0
- package/dist/opportunity/application/index.js +68 -0
- package/dist/opportunity/application/negotiation-context.loader.d.ts +59 -0
- package/dist/opportunity/application/negotiation-context.loader.js +88 -0
- package/dist/opportunity/application/opportunity.card-presentation.d.ts +44 -0
- package/dist/opportunity/application/opportunity.card-presentation.js +104 -0
- package/dist/opportunity/application/opportunity.discover.d.ts +215 -0
- package/dist/opportunity/application/opportunity.discover.js +793 -0
- package/dist/opportunity/application/opportunity.discovery-continuation-finalization.d.ts +34 -0
- package/dist/opportunity/application/opportunity.discovery-continuation-finalization.js +74 -0
- package/dist/opportunity/application/opportunity.discovery-mcp-lifecycle-finalization.d.ts +44 -0
- package/dist/opportunity/application/opportunity.discovery-mcp-lifecycle-finalization.js +92 -0
- package/dist/opportunity/application/opportunity.discovery-negotiation-summary.d.ts +14 -0
- package/dist/opportunity/application/opportunity.discovery-negotiation-summary.js +46 -0
- package/dist/opportunity/application/opportunity.enricher.d.ts +71 -0
- package/dist/opportunity/application/opportunity.enricher.js +280 -0
- package/dist/opportunity/application/opportunity.evaluator.d.ts +275 -0
- package/dist/opportunity/application/opportunity.evaluator.js +459 -0
- package/dist/opportunity/application/opportunity.existing-negotiation.d.ts +77 -0
- package/dist/opportunity/application/opportunity.existing-negotiation.js +109 -0
- package/dist/opportunity/application/opportunity.feed-selection.d.ts +30 -0
- package/dist/opportunity/application/opportunity.feed-selection.js +96 -0
- package/dist/opportunity/application/opportunity.graph.d.ts +1427 -0
- package/dist/opportunity/application/opportunity.graph.js +3693 -0
- package/dist/opportunity/application/opportunity.introducer.d.ts +77 -0
- package/dist/opportunity/application/opportunity.introducer.js +99 -0
- package/dist/opportunity/application/opportunity.lifecycle.d.ts +63 -0
- package/dist/opportunity/application/opportunity.lifecycle.js +181 -0
- package/dist/opportunity/application/opportunity.newborn-stamping.d.ts +41 -0
- package/dist/opportunity/application/opportunity.newborn-stamping.js +81 -0
- package/dist/opportunity/application/opportunity.pending-questions.d.ts +33 -0
- package/dist/opportunity/application/opportunity.pending-questions.js +42 -0
- package/dist/opportunity/application/opportunity.persist.d.ts +58 -0
- package/dist/opportunity/application/opportunity.persist.js +145 -0
- package/dist/opportunity/application/opportunity.persistence-admission.d.ts +39 -0
- package/dist/opportunity/application/opportunity.persistence-admission.js +59 -0
- package/dist/opportunity/application/opportunity.presenter.d.ts +156 -0
- package/dist/opportunity/application/opportunity.presenter.js +736 -0
- package/dist/opportunity/application/opportunity.tools.d.ts +131 -0
- package/dist/opportunity/application/opportunity.tools.js +1834 -0
- package/dist/opportunity/application/opportunity.update-admission.d.ts +24 -0
- package/dist/opportunity/application/opportunity.update-admission.js +38 -0
- package/dist/opportunity/delivery-card.cache.d.ts +5 -26
- package/dist/opportunity/delivery-card.cache.js +5 -44
- package/dist/opportunity/discovery-question.helper.d.ts +3 -17
- package/dist/opportunity/discovery-question.helper.js +3 -14
- package/dist/opportunity/discriminator/discriminator.adjustments.d.ts +0 -1
- package/dist/opportunity/discriminator/discriminator.adjustments.js +0 -1
- package/dist/opportunity/discriminator/discriminator.assigner.d.ts +4 -5
- package/dist/opportunity/discriminator/discriminator.assigner.js +0 -1
- package/dist/opportunity/discriminator/discriminator.env.d.ts +0 -1
- package/dist/opportunity/discriminator/discriminator.env.js +0 -1
- package/dist/opportunity/discriminator/discriminator.miner.d.ts +0 -1
- package/dist/opportunity/discriminator/discriminator.miner.js +0 -1
- package/dist/opportunity/discriminator/discriminator.push.d.ts +0 -1
- package/dist/opportunity/discriminator/discriminator.push.js +0 -1
- package/dist/opportunity/discriminator/discriminator.question.d.ts +0 -1
- package/dist/opportunity/discriminator/discriminator.question.js +0 -1
- package/dist/opportunity/discriminator/discriminator.scorer.d.ts +0 -1
- package/dist/opportunity/discriminator/discriminator.scorer.js +0 -1
- package/dist/opportunity/discriminator/discriminator.shadow.d.ts +0 -1
- package/dist/opportunity/discriminator/discriminator.shadow.js +0 -1
- package/dist/opportunity/discriminator/discriminator.types.d.ts +0 -1
- package/dist/opportunity/discriminator/discriminator.types.js +0 -1
- package/dist/opportunity/domain/discovery-question.helper.d.ts +18 -0
- package/dist/opportunity/domain/discovery-question.helper.js +15 -0
- package/dist/opportunity/domain/index.d.ts +55 -0
- package/dist/opportunity/domain/index.js +52 -0
- package/dist/opportunity/domain/negotiation-summary.builder.d.ts +37 -0
- package/dist/opportunity/domain/negotiation-summary.builder.js +66 -0
- package/dist/opportunity/domain/opportunity.actor.d.ts +15 -0
- package/dist/opportunity/domain/opportunity.actor.js +39 -0
- package/dist/opportunity/domain/opportunity.claim-safety.d.ts +24 -0
- package/dist/opportunity/domain/opportunity.claim-safety.js +88 -0
- package/dist/opportunity/domain/opportunity.discovery-run-coalescing.d.ts +33 -0
- package/dist/opportunity/domain/opportunity.discovery-run-coalescing.js +33 -0
- package/dist/opportunity/domain/opportunity.discovery.contracts.d.ts +45 -0
- package/dist/opportunity/domain/opportunity.discovery.contracts.js +1 -0
- package/dist/opportunity/domain/opportunity.evidence.d.ts +21 -0
- package/dist/opportunity/domain/opportunity.evidence.js +78 -0
- package/dist/opportunity/domain/opportunity.labels.d.ts +8 -0
- package/dist/opportunity/domain/opportunity.labels.js +10 -0
- package/dist/opportunity/domain/opportunity.presentation-cache.d.ts +6 -0
- package/dist/opportunity/domain/opportunity.presentation-cache.js +14 -0
- package/dist/opportunity/domain/opportunity.presentation.d.ts +76 -0
- package/dist/opportunity/domain/opportunity.presentation.js +516 -0
- package/dist/opportunity/domain/opportunity.safe-presentation.d.ts +104 -0
- package/dist/opportunity/domain/opportunity.safe-presentation.js +102 -0
- package/dist/opportunity/domain/opportunity.state.d.ts +519 -0
- package/dist/opportunity/domain/opportunity.state.js +309 -0
- package/dist/opportunity/domain/opportunity.utils.d.ts +217 -0
- package/dist/opportunity/domain/opportunity.utils.js +395 -0
- package/dist/opportunity/feed/feed.categorizer.d.ts +0 -1
- package/dist/opportunity/feed/feed.categorizer.js +0 -1
- package/dist/opportunity/feed/feed.graph.d.ts +1 -2
- package/dist/opportunity/feed/feed.graph.js +0 -1
- package/dist/opportunity/feed/feed.health.d.ts +0 -1
- package/dist/opportunity/feed/feed.health.js +0 -1
- package/dist/opportunity/feed/feed.state.d.ts +1 -2
- package/dist/opportunity/feed/feed.state.js +0 -1
- package/dist/opportunity/index.d.ts +37 -0
- package/dist/opportunity/index.js +37 -0
- package/dist/opportunity/negotiation-context.loader.d.ts +3 -58
- package/dist/opportunity/negotiation-context.loader.js +3 -87
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.env.d.ts +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.env.js +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.extractor.d.ts +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.extractor.js +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.miner.d.ts +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.miner.js +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.shadow.d.ts +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.shadow.js +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.types.d.ts +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.types.js +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.verifier.d.ts +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.verifier.js +0 -1
- package/dist/opportunity/negotiation-summary.builder.d.ts +3 -36
- package/dist/opportunity/negotiation-summary.builder.js +3 -65
- package/dist/opportunity/opportunity.actor.d.ts +3 -14
- package/dist/opportunity/opportunity.actor.js +3 -38
- package/dist/opportunity/opportunity.card-presentation.d.ts +5 -0
- package/dist/opportunity/opportunity.card-presentation.js +5 -0
- package/dist/opportunity/opportunity.claim-safety.d.ts +3 -23
- package/dist/opportunity/opportunity.claim-safety.js +3 -87
- package/dist/opportunity/opportunity.discover.d.ts +3 -218
- package/dist/opportunity/opportunity.discover.js +3 -917
- package/dist/opportunity/opportunity.discovery-continuation-finalization.d.ts +5 -0
- package/dist/opportunity/opportunity.discovery-continuation-finalization.js +5 -0
- package/dist/opportunity/opportunity.discovery-mcp-lifecycle-finalization.d.ts +5 -0
- package/dist/opportunity/opportunity.discovery-mcp-lifecycle-finalization.js +5 -0
- package/dist/opportunity/opportunity.discovery-negotiation-summary.d.ts +5 -0
- package/dist/opportunity/opportunity.discovery-negotiation-summary.js +5 -0
- package/dist/opportunity/opportunity.discovery-run-coalescing.d.ts +5 -0
- package/dist/opportunity/opportunity.discovery-run-coalescing.js +5 -0
- package/dist/opportunity/opportunity.discovery.contracts.d.ts +5 -0
- package/dist/opportunity/opportunity.discovery.contracts.js +5 -0
- package/dist/opportunity/opportunity.enricher.d.ts +3 -70
- package/dist/opportunity/opportunity.enricher.js +3 -279
- package/dist/opportunity/opportunity.evaluator.d.ts +5 -276
- package/dist/opportunity/opportunity.evaluator.js +5 -460
- package/dist/opportunity/opportunity.evidence.d.ts +5 -22
- package/dist/opportunity/opportunity.evidence.js +5 -79
- package/dist/opportunity/opportunity.existing-negotiation.d.ts +5 -0
- package/dist/opportunity/opportunity.existing-negotiation.js +5 -0
- package/dist/opportunity/opportunity.feed-selection.d.ts +5 -0
- package/dist/opportunity/opportunity.feed-selection.js +5 -0
- package/dist/opportunity/opportunity.graph.d.ts +3 -1489
- package/dist/opportunity/opportunity.graph.js +3 -4071
- package/dist/opportunity/opportunity.introducer.d.ts +3 -76
- package/dist/opportunity/opportunity.introducer.js +3 -98
- package/dist/opportunity/opportunity.labels.d.ts +5 -9
- package/dist/opportunity/opportunity.labels.js +5 -11
- package/dist/opportunity/opportunity.lifecycle.d.ts +5 -0
- package/dist/opportunity/opportunity.lifecycle.js +5 -0
- package/dist/opportunity/opportunity.newborn-stamping.d.ts +5 -0
- package/dist/opportunity/opportunity.newborn-stamping.js +5 -0
- package/dist/opportunity/opportunity.pending-questions.d.ts +3 -32
- package/dist/opportunity/opportunity.pending-questions.js +3 -41
- package/dist/opportunity/opportunity.persist.d.ts +3 -57
- package/dist/opportunity/opportunity.persist.js +3 -144
- package/dist/opportunity/opportunity.persistence-admission.d.ts +5 -0
- package/dist/opportunity/opportunity.persistence-admission.js +5 -0
- package/dist/opportunity/opportunity.presentation-cache.d.ts +5 -7
- package/dist/opportunity/opportunity.presentation-cache.js +5 -15
- package/dist/opportunity/opportunity.presentation.d.ts +3 -75
- package/dist/opportunity/opportunity.presentation.js +3 -515
- package/dist/opportunity/opportunity.presenter.d.ts +10 -155
- package/dist/opportunity/opportunity.presenter.js +10 -735
- package/dist/opportunity/opportunity.safe-presentation.d.ts +3 -103
- package/dist/opportunity/opportunity.safe-presentation.js +3 -101
- package/dist/opportunity/opportunity.state.d.ts +3 -518
- package/dist/opportunity/opportunity.state.js +3 -308
- package/dist/opportunity/opportunity.tools.d.ts +3 -157
- package/dist/opportunity/opportunity.tools.js +3 -2238
- package/dist/opportunity/opportunity.update-admission.d.ts +5 -0
- package/dist/opportunity/opportunity.update-admission.js +5 -0
- package/dist/opportunity/opportunity.utils.d.ts +3 -216
- package/dist/opportunity/opportunity.utils.js +3 -394
- package/dist/opportunity/outcome/outcome.env.d.ts +0 -1
- package/dist/opportunity/outcome/outcome.env.js +0 -1
- package/dist/opportunity/outcome/outcome.hypotheses.d.ts +0 -1
- package/dist/opportunity/outcome/outcome.hypotheses.js +0 -1
- package/dist/opportunity/outcome/outcome.shadow.d.ts +0 -1
- package/dist/opportunity/outcome/outcome.shadow.js +0 -1
- package/dist/opportunity/outcome/outcome.types.d.ts +0 -1
- package/dist/opportunity/outcome/outcome.types.js +0 -1
- package/dist/opportunity/ports/index.d.ts +5 -0
- package/dist/opportunity/ports/index.js +1 -0
- package/dist/opportunity/ports/opportunity.tools.port.d.ts +5 -0
- package/dist/opportunity/ports/opportunity.tools.port.js +1 -0
- package/dist/opportunity/public/index.d.ts +58 -0
- package/dist/opportunity/public/index.js +51 -0
- package/dist/participant-agents/application/agent.tools.d.ts +16 -0
- package/dist/participant-agents/application/agent.tools.js +313 -0
- package/dist/participant-agents/application/index.d.ts +21 -0
- package/dist/participant-agents/application/index.js +22 -0
- package/dist/participant-agents/domain/agent.types.d.ts +76 -0
- package/dist/participant-agents/domain/agent.types.js +22 -0
- package/dist/participant-agents/domain/index.d.ts +20 -0
- package/dist/participant-agents/domain/index.js +1 -0
- package/dist/participant-agents/index.d.ts +24 -0
- package/dist/participant-agents/index.js +24 -0
- package/dist/participant-agents/ports/agent.dispatcher.port.d.ts +25 -0
- package/dist/participant-agents/ports/agent.dispatcher.port.js +1 -0
- package/dist/participant-agents/ports/agent.repository.port.d.ts +118 -0
- package/dist/participant-agents/ports/agent.repository.port.js +10 -0
- package/dist/participant-agents/ports/agent.tools.port.d.ts +24 -0
- package/dist/participant-agents/ports/agent.tools.port.js +20 -0
- package/dist/participant-agents/ports/index.d.ts +29 -0
- package/dist/participant-agents/ports/index.js +27 -0
- package/dist/participant-agents/public/index.d.ts +39 -0
- package/dist/participant-agents/public/index.js +36 -0
- package/dist/participant-context/application/index.d.ts +73 -0
- package/dist/participant-context/application/index.js +83 -0
- package/dist/participant-context/domain/index.d.ts +67 -0
- package/dist/participant-context/domain/index.js +68 -0
- package/dist/participant-context/index.d.ts +16 -0
- package/dist/participant-context/index.js +16 -0
- package/dist/participant-context/ports/index.d.ts +37 -0
- package/dist/participant-context/ports/index.js +34 -0
- package/dist/participant-context/public/index.d.ts +48 -0
- package/dist/participant-context/public/index.js +55 -0
- package/dist/platform/index.d.ts +19 -0
- package/dist/platform/index.js +23 -0
- package/dist/premise/premise.analyzer.d.ts +0 -1
- package/dist/premise/premise.analyzer.js +0 -2
- package/dist/premise/premise.decomposer.d.ts +0 -1
- package/dist/premise/premise.decomposer.js +0 -2
- package/dist/premise/premise.graph.d.ts +1 -2
- package/dist/premise/premise.graph.js +0 -2
- package/dist/premise/premise.indexer.d.ts +0 -1
- package/dist/premise/premise.indexer.js +0 -2
- package/dist/premise/premise.state.d.ts +1 -2
- package/dist/premise/premise.state.js +0 -1
- package/dist/premise/premise.tools.d.ts +3 -3
- package/dist/premise/premise.tools.js +0 -2
- package/dist/public/index.d.ts +17 -0
- package/dist/public/index.js +17 -0
- package/dist/questioner/questioner.agent.d.ts +4 -27
- package/dist/questioner/questioner.agent.js +3 -133
- package/dist/questioner/questioner.ask.tool.d.ts +3 -12
- package/dist/questioner/questioner.ask.tool.js +3 -299
- package/dist/questioner/questioner.discovery.prompt.d.ts +3 -7
- package/dist/questioner/questioner.discovery.prompt.js +3 -180
- package/dist/questioner/questioner.env.d.ts +3 -57
- package/dist/questioner/questioner.env.js +3 -93
- package/dist/questioner/questioner.presets.d.ts +4 -19
- package/dist/questioner/questioner.presets.js +3 -465
- package/dist/questioner/questioner.qud.d.ts +3 -6
- package/dist/questioner/questioner.qud.js +3 -10
- package/dist/questioner/questioner.tools.d.ts +3 -15
- package/dist/questioner/questioner.tools.js +3 -186
- package/dist/questioner/questioner.types.d.ts +4 -218
- package/dist/questioner/questioner.types.js +5 -62
- package/dist/questions/application/index.d.ts +39 -0
- package/dist/questions/application/index.js +41 -0
- package/dist/questions/application/question.agent.d.ts +28 -0
- package/dist/questions/application/question.agent.js +139 -0
- package/dist/questions/application/question.ask.tool.d.ts +12 -0
- package/dist/questions/application/question.ask.tool.js +300 -0
- package/dist/questions/application/question.discovery.prompt.d.ts +8 -0
- package/dist/questions/application/question.discovery.prompt.js +181 -0
- package/dist/questions/application/question.env.d.ts +61 -0
- package/dist/questions/application/question.env.js +97 -0
- package/dist/questions/application/question.input.d.ts +237 -0
- package/dist/questions/application/question.input.js +61 -0
- package/dist/questions/application/question.presets.d.ts +24 -0
- package/dist/questions/application/question.presets.js +445 -0
- package/dist/questions/application/question.qud.d.ts +12 -0
- package/dist/questions/application/question.qud.js +16 -0
- package/dist/questions/application/question.tools.d.ts +15 -0
- package/dist/questions/application/question.tools.js +190 -0
- package/dist/questions/domain/index.d.ts +25 -0
- package/dist/questions/domain/index.js +25 -0
- package/dist/questions/domain/question.schema.d.ts +1537 -0
- package/dist/questions/domain/question.schema.js +422 -0
- package/dist/questions/index.d.ts +22 -0
- package/dist/questions/index.js +22 -0
- package/dist/questions/ports/index.d.ts +29 -0
- package/dist/questions/ports/index.js +27 -0
- package/dist/questions/ports/question.generator.port.d.ts +34 -0
- package/dist/questions/ports/question.generator.port.js +1 -0
- package/dist/questions/ports/question.persistence.port.d.ts +87 -0
- package/dist/questions/ports/question.persistence.port.js +1 -0
- package/dist/questions/ports/question.tools.port.d.ts +15 -0
- package/dist/questions/ports/question.tools.port.js +1 -0
- package/dist/questions/public/index.d.ts +47 -0
- package/dist/questions/public/index.js +49 -0
- package/dist/runtime/background/index.d.ts +14 -0
- package/dist/runtime/background/index.js +14 -0
- package/dist/runtime/foreground/composition/tool.factory.d.ts +16 -0
- package/dist/runtime/foreground/composition/tool.factory.js +224 -0
- package/dist/runtime/foreground/composition/tool.registry.d.ts +11 -0
- package/dist/runtime/foreground/composition/tool.registry.js +106 -0
- package/dist/runtime/foreground/index.d.ts +13 -0
- package/dist/runtime/foreground/index.js +13 -0
- package/dist/runtime/foreground/signals/intent.tools.d.ts +13 -0
- package/dist/runtime/foreground/signals/intent.tools.js +13 -0
- package/dist/shared/agent/model-signal.d.ts +0 -1
- package/dist/shared/agent/model-signal.js +0 -1
- package/dist/shared/agent/model.config.d.ts +0 -1
- package/dist/shared/agent/model.config.js +0 -1
- package/dist/shared/agent/tool.factory.d.ts +4 -15
- package/dist/shared/agent/tool.factory.js +4 -226
- package/dist/shared/agent/tool.helpers.d.ts +51 -12
- package/dist/shared/agent/tool.helpers.js +0 -1
- package/dist/shared/agent/tool.registry.d.ts +9 -9
- package/dist/shared/agent/tool.registry.js +9 -104
- package/dist/shared/agent/tool.runtime.d.ts +0 -1
- package/dist/shared/agent/tool.runtime.js +0 -1
- package/dist/shared/agent/tool.scope.d.ts +0 -1
- package/dist/shared/agent/tool.scope.js +0 -1
- package/dist/shared/agent/utility.tools.d.ts +5 -3
- package/dist/shared/agent/utility.tools.js +0 -1
- package/dist/shared/assignment/network-assignment.policy.d.ts +0 -1
- package/dist/shared/assignment/network-assignment.policy.js +0 -1
- package/dist/shared/hyde/hyde.documents.d.ts +0 -1
- package/dist/shared/hyde/hyde.documents.js +0 -1
- package/dist/shared/hyde/hyde.env.d.ts +0 -1
- package/dist/shared/hyde/hyde.env.js +0 -1
- package/dist/shared/hyde/hyde.frame.d.ts +4 -5
- package/dist/shared/hyde/hyde.frame.js +0 -1
- package/dist/shared/hyde/hyde.generator.d.ts +0 -1
- package/dist/shared/hyde/hyde.generator.js +0 -1
- package/dist/shared/hyde/hyde.graph.d.ts +0 -1
- package/dist/shared/hyde/hyde.graph.js +0 -1
- package/dist/shared/hyde/hyde.state.d.ts +0 -1
- package/dist/shared/hyde/hyde.state.js +0 -1
- package/dist/shared/hyde/hyde.strategies.d.ts +0 -1
- package/dist/shared/hyde/hyde.strategies.js +0 -1
- package/dist/shared/hyde/hyde.validator.d.ts +0 -1
- package/dist/shared/hyde/hyde.validator.js +0 -1
- package/dist/shared/hyde/lens.inferrer.d.ts +6 -7
- package/dist/shared/hyde/lens.inferrer.js +0 -1
- package/dist/shared/interfaces/agent-dispatcher.interface.d.ts +4 -1
- package/dist/shared/interfaces/agent-dispatcher.interface.js +4 -1
- package/dist/shared/interfaces/agent.interface.d.ts +13 -173
- package/dist/shared/interfaces/agent.interface.js +12 -12
- package/dist/shared/interfaces/auth.interface.d.ts +0 -1
- package/dist/shared/interfaces/auth.interface.js +0 -1
- package/dist/shared/interfaces/cache.interface.d.ts +0 -1
- package/dist/shared/interfaces/cache.interface.js +0 -1
- package/dist/shared/interfaces/chat-message-writer.interface.d.ts +0 -1
- package/dist/shared/interfaces/chat-message-writer.interface.js +0 -1
- package/dist/shared/interfaces/chat-session.interface.d.ts +0 -1
- package/dist/shared/interfaces/chat-session.interface.js +0 -1
- package/dist/shared/interfaces/chat-summary.interface.d.ts +0 -1
- package/dist/shared/interfaces/chat-summary.interface.js +0 -1
- package/dist/shared/interfaces/connect-link.interface.d.ts +0 -1
- package/dist/shared/interfaces/connect-link.interface.js +0 -1
- package/dist/shared/interfaces/contact.interface.d.ts +7 -55
- package/dist/shared/interfaces/contact.interface.js +7 -1
- package/dist/shared/interfaces/database.interface.d.ts +0 -1
- package/dist/shared/interfaces/database.interface.js +0 -1
- package/dist/shared/interfaces/delivery-ledger.interface.d.ts +0 -1
- package/dist/shared/interfaces/delivery-ledger.interface.js +0 -1
- package/dist/shared/interfaces/discovery-run.interface.d.ts +2 -3
- package/dist/shared/interfaces/discovery-run.interface.js +0 -1
- package/dist/shared/interfaces/embedder.interface.d.ts +0 -1
- package/dist/shared/interfaces/embedder.interface.js +0 -1
- package/dist/shared/interfaces/enrichment-run.interface.d.ts +2 -3
- package/dist/shared/interfaces/enrichment-run.interface.js +0 -1
- package/dist/shared/interfaces/enrichment.interface.d.ts +0 -1
- package/dist/shared/interfaces/enrichment.interface.js +0 -1
- package/dist/shared/interfaces/integration.interface.d.ts +6 -88
- package/dist/shared/interfaces/integration.interface.js +7 -1
- package/dist/shared/interfaces/negotiation-events.interface.d.ts +0 -1
- package/dist/shared/interfaces/negotiation-events.interface.js +0 -1
- package/dist/shared/interfaces/negotiation-summary.interface.d.ts +0 -1
- package/dist/shared/interfaces/negotiation-summary.interface.js +0 -1
- package/dist/shared/interfaces/negotiator-memory.interface.d.ts +0 -1
- package/dist/shared/interfaces/negotiator-memory.interface.js +0 -1
- package/dist/shared/interfaces/question-generator.interface.d.ts +3 -28
- package/dist/shared/interfaces/question-generator.interface.js +0 -1
- package/dist/shared/interfaces/questioner.interface.d.ts +3 -77
- package/dist/shared/interfaces/questioner.interface.js +0 -1
- package/dist/shared/interfaces/queue.interface.d.ts +0 -1
- package/dist/shared/interfaces/queue.interface.js +0 -1
- package/dist/shared/interfaces/scraper.interface.d.ts +0 -1
- package/dist/shared/interfaces/scraper.interface.js +0 -1
- package/dist/shared/interfaces/tool-request-context.interface.d.ts +12 -0
- package/dist/shared/interfaces/tool-request-context.interface.js +1 -0
- package/dist/shared/network/metadata.renderer.d.ts +0 -1
- package/dist/shared/network/metadata.renderer.js +0 -1
- package/dist/shared/observability/debug-meta.sanitizer.d.ts +0 -1
- package/dist/shared/observability/debug-meta.sanitizer.js +0 -1
- package/dist/shared/observability/log.d.ts +0 -1
- package/dist/shared/observability/log.js +0 -1
- package/dist/shared/observability/performance.d.ts +0 -1
- package/dist/shared/observability/performance.js +0 -1
- package/dist/shared/observability/protocol.logger.d.ts +0 -1
- package/dist/shared/observability/protocol.logger.js +0 -1
- package/dist/shared/observability/request-context.d.ts +0 -1
- package/dist/shared/observability/request-context.js +0 -1
- package/dist/shared/observability/trace.d.ts +0 -1
- package/dist/shared/observability/trace.js +0 -1
- package/dist/shared/schemas/chat-context.schema.d.ts +0 -1
- package/dist/shared/schemas/chat-context.schema.js +0 -1
- package/dist/shared/schemas/discovery-question.schema.d.ts +17 -18
- package/dist/shared/schemas/discovery-question.schema.js +0 -1
- package/dist/shared/schemas/identity.schema.d.ts +0 -1
- package/dist/shared/schemas/identity.schema.js +0 -1
- package/dist/shared/schemas/mcp-auth.schema.d.ts +0 -1
- package/dist/shared/schemas/mcp-auth.schema.js +0 -1
- package/dist/shared/schemas/negotiation-digest.schema.d.ts +5 -6
- package/dist/shared/schemas/negotiation-digest.schema.js +0 -1
- package/dist/shared/schemas/negotiation-state.schema.d.ts +4 -5
- package/dist/shared/schemas/negotiation-state.schema.js +0 -1
- package/dist/shared/schemas/network-assignment.schema.d.ts +0 -1
- package/dist/shared/schemas/network-assignment.schema.js +0 -1
- package/dist/shared/schemas/pending-question.schema.d.ts +0 -1
- package/dist/shared/schemas/pending-question.schema.js +0 -1
- package/dist/shared/schemas/question.schema.d.ts +3 -1535
- package/dist/shared/schemas/question.schema.js +3 -420
- package/dist/shared/ui/lucide.icon-catalog.d.ts +0 -1
- package/dist/shared/ui/lucide.icon-catalog.js +0 -1
- package/dist/shared/utils/social-label.d.ts +0 -1
- package/dist/shared/utils/social-label.js +0 -1
- package/dist/shared/utils/telegram-handle.d.ts +0 -1
- package/dist/shared/utils/telegram-handle.js +0 -1
- package/dist/signals/application/index.d.ts +19 -0
- package/dist/signals/application/index.js +22 -0
- package/dist/signals/application/intent.clarifier.d.ts +51 -0
- package/dist/signals/application/intent.clarifier.js +201 -0
- package/dist/signals/application/intent.graph.d.ts +552 -0
- package/dist/signals/application/intent.graph.js +938 -0
- package/dist/signals/application/intent.indexer.d.ts +82 -0
- package/dist/signals/application/intent.indexer.js +170 -0
- package/dist/signals/application/intent.inferrer.d.ts +94 -0
- package/dist/signals/application/intent.inferrer.js +233 -0
- package/dist/signals/application/intent.reconciler.d.ts +105 -0
- package/dist/signals/application/intent.reconciler.js +186 -0
- package/dist/signals/application/intent.tools.d.ts +24 -0
- package/dist/signals/application/intent.tools.js +789 -0
- package/dist/signals/application/intent.verifier.d.ts +115 -0
- package/dist/signals/application/intent.verifier.js +262 -0
- package/dist/signals/domain/index.d.ts +9 -0
- package/dist/signals/domain/index.js +11 -0
- package/dist/signals/domain/intent.state.d.ts +230 -0
- package/dist/signals/domain/intent.state.js +190 -0
- package/dist/signals/domain/signal.specificity.d.ts +2 -0
- package/dist/signals/domain/signal.specificity.js +2 -0
- package/dist/signals/index.d.ts +13 -0
- package/dist/signals/index.js +13 -0
- package/dist/signals/ports/index.d.ts +15 -0
- package/dist/signals/ports/index.js +13 -0
- package/dist/signals/public/index.d.ts +15 -0
- package/dist/signals/public/index.js +16 -0
- package/package.json +14 -3
- package/dist/agent/agent.tools.d.ts.map +0 -1
- package/dist/agent/agent.tools.js.map +0 -1
- package/dist/agent/tests/fakes.d.ts +0 -25
- package/dist/agent/tests/fakes.d.ts.map +0 -1
- package/dist/agent/tests/fakes.js +0 -178
- package/dist/agent/tests/fakes.js.map +0 -1
- package/dist/chat/chat-streaming.types.d.ts.map +0 -1
- package/dist/chat/chat-streaming.types.js.map +0 -1
- package/dist/chat/chat.agent.d.ts.map +0 -1
- package/dist/chat/chat.agent.js.map +0 -1
- package/dist/chat/chat.graph.d.ts.map +0 -1
- package/dist/chat/chat.graph.js.map +0 -1
- package/dist/chat/chat.interrupt.classifier.d.ts.map +0 -1
- package/dist/chat/chat.interrupt.classifier.js.map +0 -1
- package/dist/chat/chat.persona.d.ts.map +0 -1
- package/dist/chat/chat.persona.js.map +0 -1
- package/dist/chat/chat.prompt.d.ts.map +0 -1
- package/dist/chat/chat.prompt.js.map +0 -1
- package/dist/chat/chat.prompt.modules.d.ts.map +0 -1
- package/dist/chat/chat.prompt.modules.js.map +0 -1
- package/dist/chat/chat.question-dedup.d.ts.map +0 -1
- package/dist/chat/chat.question-dedup.js.map +0 -1
- package/dist/chat/chat.state.d.ts.map +0 -1
- package/dist/chat/chat.state.js.map +0 -1
- package/dist/chat/chat.streamer.d.ts.map +0 -1
- package/dist/chat/chat.streamer.js.map +0 -1
- package/dist/chat/chat.suggester.d.ts.map +0 -1
- package/dist/chat/chat.suggester.js.map +0 -1
- package/dist/chat/chat.summarizer.d.ts.map +0 -1
- package/dist/chat/chat.summarizer.js.map +0 -1
- package/dist/chat/chat.title.generator.d.ts.map +0 -1
- package/dist/chat/chat.title.generator.js.map +0 -1
- package/dist/chat/chat.tools.d.ts.map +0 -1
- package/dist/chat/chat.tools.js.map +0 -1
- package/dist/chat/chat.utils.d.ts.map +0 -1
- package/dist/chat/chat.utils.js.map +0 -1
- package/dist/chat/negotiator.persona.d.ts.map +0 -1
- package/dist/chat/negotiator.persona.js.map +0 -1
- package/dist/chat/negotiator.prompt.d.ts.map +0 -1
- package/dist/chat/negotiator.prompt.js.map +0 -1
- package/dist/chat/negotiator.tools.d.ts.map +0 -1
- package/dist/chat/negotiator.tools.js.map +0 -1
- package/dist/chat/onboarding.persona.d.ts.map +0 -1
- package/dist/chat/onboarding.persona.js.map +0 -1
- package/dist/chat/onboarding.prompt.d.ts.map +0 -1
- package/dist/chat/onboarding.prompt.js.map +0 -1
- package/dist/chat/reporter.action.tools.d.ts.map +0 -1
- package/dist/chat/reporter.action.tools.js.map +0 -1
- package/dist/chat/reporter.persona.d.ts.map +0 -1
- package/dist/chat/reporter.persona.js.map +0 -1
- package/dist/chat/reporter.prompt.d.ts.map +0 -1
- package/dist/chat/reporter.prompt.js.map +0 -1
- package/dist/chat/signal.persona.d.ts.map +0 -1
- package/dist/chat/signal.persona.js.map +0 -1
- package/dist/chat/signal.prompt.d.ts.map +0 -1
- package/dist/chat/signal.prompt.js.map +0 -1
- package/dist/chat/tests/chat.graph.mocks.d.ts +0 -98
- package/dist/chat/tests/chat.graph.mocks.d.ts.map +0 -1
- package/dist/chat/tests/chat.graph.mocks.js +0 -225
- package/dist/chat/tests/chat.graph.mocks.js.map +0 -1
- package/dist/contact/contact.inviter.d.ts.map +0 -1
- package/dist/contact/contact.inviter.js.map +0 -1
- package/dist/contact/contact.tools.d.ts.map +0 -1
- package/dist/contact/contact.tools.js.map +0 -1
- package/dist/context/context.generator.d.ts.map +0 -1
- package/dist/context/context.generator.js.map +0 -1
- package/dist/enrichment/enrichment.enricher.d.ts.map +0 -1
- package/dist/enrichment/enrichment.enricher.js.map +0 -1
- package/dist/enrichment/enrichment.generator.d.ts.map +0 -1
- package/dist/enrichment/enrichment.generator.js.map +0 -1
- package/dist/enrichment/enrichment.graph.d.ts.map +0 -1
- package/dist/enrichment/enrichment.graph.js.map +0 -1
- package/dist/enrichment/enrichment.state.d.ts.map +0 -1
- package/dist/enrichment/enrichment.state.js.map +0 -1
- package/dist/enrichment/enrichment.tools.d.ts.map +0 -1
- package/dist/enrichment/enrichment.tools.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/integration/integration.tools.d.ts.map +0 -1
- package/dist/integration/integration.tools.js.map +0 -1
- package/dist/intent/intent.clarifier.d.ts.map +0 -1
- package/dist/intent/intent.clarifier.js.map +0 -1
- package/dist/intent/intent.graph.d.ts.map +0 -1
- package/dist/intent/intent.graph.js.map +0 -1
- package/dist/intent/intent.indexer.d.ts.map +0 -1
- package/dist/intent/intent.indexer.js.map +0 -1
- package/dist/intent/intent.inferrer.d.ts.map +0 -1
- package/dist/intent/intent.inferrer.js.map +0 -1
- package/dist/intent/intent.reconciler.d.ts.map +0 -1
- package/dist/intent/intent.reconciler.js.map +0 -1
- package/dist/intent/intent.specificity.d.ts.map +0 -1
- package/dist/intent/intent.specificity.js.map +0 -1
- package/dist/intent/intent.state.d.ts.map +0 -1
- package/dist/intent/intent.state.js.map +0 -1
- package/dist/intent/intent.tools.d.ts.map +0 -1
- package/dist/intent/intent.tools.js.map +0 -1
- package/dist/intent/intent.verifier.d.ts.map +0 -1
- package/dist/intent/intent.verifier.js.map +0 -1
- package/dist/maintenance/maintenance.graph.d.ts.map +0 -1
- package/dist/maintenance/maintenance.graph.js.map +0 -1
- package/dist/maintenance/maintenance.state.d.ts.map +0 -1
- package/dist/maintenance/maintenance.state.js.map +0 -1
- package/dist/mcp/elicitation.builder.d.ts.map +0 -1
- package/dist/mcp/elicitation.builder.js.map +0 -1
- package/dist/mcp/elicitation.dispatcher.d.ts.map +0 -1
- package/dist/mcp/elicitation.dispatcher.js.map +0 -1
- package/dist/mcp/mcp.server.d.ts.map +0 -1
- package/dist/mcp/mcp.server.js.map +0 -1
- package/dist/negotiation/insight.generator.d.ts.map +0 -1
- package/dist/negotiation/insight.generator.js.map +0 -1
- package/dist/negotiation/negotiation.agent.d.ts.map +0 -1
- package/dist/negotiation/negotiation.agent.js.map +0 -1
- package/dist/negotiation/negotiation.attribution.d.ts.map +0 -1
- package/dist/negotiation/negotiation.attribution.js.map +0 -1
- package/dist/negotiation/negotiation.consultation-policy.d.ts.map +0 -1
- package/dist/negotiation/negotiation.consultation-policy.js.map +0 -1
- package/dist/negotiation/negotiation.deadlock.d.ts.map +0 -1
- package/dist/negotiation/negotiation.deadlock.js.map +0 -1
- package/dist/negotiation/negotiation.graph.d.ts.map +0 -1
- package/dist/negotiation/negotiation.graph.js.map +0 -1
- package/dist/negotiation/negotiation.memory.d.ts.map +0 -1
- package/dist/negotiation/negotiation.memory.js.map +0 -1
- package/dist/negotiation/negotiation.protocol.d.ts.map +0 -1
- package/dist/negotiation/negotiation.protocol.js.map +0 -1
- package/dist/negotiation/negotiation.question-safety.d.ts.map +0 -1
- package/dist/negotiation/negotiation.question-safety.js.map +0 -1
- package/dist/negotiation/negotiation.reflect.d.ts.map +0 -1
- package/dist/negotiation/negotiation.reflect.js.map +0 -1
- package/dist/negotiation/negotiation.screen.d.ts.map +0 -1
- package/dist/negotiation/negotiation.screen.js.map +0 -1
- package/dist/negotiation/negotiation.state.d.ts.map +0 -1
- package/dist/negotiation/negotiation.state.js.map +0 -1
- package/dist/negotiation/negotiation.summarizer.d.ts.map +0 -1
- package/dist/negotiation/negotiation.summarizer.js.map +0 -1
- package/dist/negotiation/negotiation.tools.d.ts.map +0 -1
- package/dist/negotiation/negotiation.tools.js.map +0 -1
- package/dist/network/indexer/indexer.graph.d.ts.map +0 -1
- package/dist/network/indexer/indexer.graph.js.map +0 -1
- package/dist/network/indexer/indexer.state.d.ts.map +0 -1
- package/dist/network/indexer/indexer.state.js.map +0 -1
- package/dist/network/membership/membership.graph.d.ts.map +0 -1
- package/dist/network/membership/membership.graph.js.map +0 -1
- package/dist/network/membership/membership.state.d.ts.map +0 -1
- package/dist/network/membership/membership.state.js.map +0 -1
- package/dist/network/network.graph.d.ts.map +0 -1
- package/dist/network/network.graph.js.map +0 -1
- package/dist/network/network.recommender.d.ts.map +0 -1
- package/dist/network/network.recommender.js.map +0 -1
- package/dist/network/network.state.d.ts.map +0 -1
- package/dist/network/network.state.js.map +0 -1
- package/dist/network/network.tools.d.ts.map +0 -1
- package/dist/network/network.tools.js.map +0 -1
- package/dist/opportunity/delivery-card.cache.d.ts.map +0 -1
- package/dist/opportunity/delivery-card.cache.js.map +0 -1
- package/dist/opportunity/discovery-question.helper.d.ts.map +0 -1
- package/dist/opportunity/discovery-question.helper.js.map +0 -1
- package/dist/opportunity/discriminator/discriminator.adjustments.d.ts.map +0 -1
- package/dist/opportunity/discriminator/discriminator.adjustments.js.map +0 -1
- package/dist/opportunity/discriminator/discriminator.assigner.d.ts.map +0 -1
- package/dist/opportunity/discriminator/discriminator.assigner.js.map +0 -1
- package/dist/opportunity/discriminator/discriminator.env.d.ts.map +0 -1
- package/dist/opportunity/discriminator/discriminator.env.js.map +0 -1
- package/dist/opportunity/discriminator/discriminator.miner.d.ts.map +0 -1
- package/dist/opportunity/discriminator/discriminator.miner.js.map +0 -1
- package/dist/opportunity/discriminator/discriminator.push.d.ts.map +0 -1
- package/dist/opportunity/discriminator/discriminator.push.js.map +0 -1
- package/dist/opportunity/discriminator/discriminator.question.d.ts.map +0 -1
- package/dist/opportunity/discriminator/discriminator.question.js.map +0 -1
- package/dist/opportunity/discriminator/discriminator.scorer.d.ts.map +0 -1
- package/dist/opportunity/discriminator/discriminator.scorer.js.map +0 -1
- package/dist/opportunity/discriminator/discriminator.shadow.d.ts.map +0 -1
- package/dist/opportunity/discriminator/discriminator.shadow.js.map +0 -1
- package/dist/opportunity/discriminator/discriminator.types.d.ts.map +0 -1
- package/dist/opportunity/discriminator/discriminator.types.js.map +0 -1
- package/dist/opportunity/feed/feed.categorizer.d.ts.map +0 -1
- package/dist/opportunity/feed/feed.categorizer.js.map +0 -1
- package/dist/opportunity/feed/feed.graph.d.ts.map +0 -1
- package/dist/opportunity/feed/feed.graph.js.map +0 -1
- package/dist/opportunity/feed/feed.health.d.ts.map +0 -1
- package/dist/opportunity/feed/feed.health.js.map +0 -1
- package/dist/opportunity/feed/feed.state.d.ts.map +0 -1
- package/dist/opportunity/feed/feed.state.js.map +0 -1
- package/dist/opportunity/negotiation-context.loader.d.ts.map +0 -1
- package/dist/opportunity/negotiation-context.loader.js.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.env.d.ts.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.env.js.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.extractor.d.ts.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.extractor.js.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.miner.d.ts.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.miner.js.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.shadow.d.ts.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.shadow.js.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.types.d.ts.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.types.js.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.verifier.d.ts.map +0 -1
- package/dist/opportunity/negotiation-evidence/negotiation-evidence.verifier.js.map +0 -1
- package/dist/opportunity/negotiation-summary.builder.d.ts.map +0 -1
- package/dist/opportunity/negotiation-summary.builder.js.map +0 -1
- package/dist/opportunity/opportunity.actor.d.ts.map +0 -1
- package/dist/opportunity/opportunity.actor.js.map +0 -1
- package/dist/opportunity/opportunity.claim-safety.d.ts.map +0 -1
- package/dist/opportunity/opportunity.claim-safety.js.map +0 -1
- package/dist/opportunity/opportunity.discover.d.ts.map +0 -1
- package/dist/opportunity/opportunity.discover.js.map +0 -1
- package/dist/opportunity/opportunity.enricher.d.ts.map +0 -1
- package/dist/opportunity/opportunity.enricher.js.map +0 -1
- package/dist/opportunity/opportunity.evaluator.d.ts.map +0 -1
- package/dist/opportunity/opportunity.evaluator.js.map +0 -1
- package/dist/opportunity/opportunity.evidence.d.ts.map +0 -1
- package/dist/opportunity/opportunity.evidence.js.map +0 -1
- package/dist/opportunity/opportunity.graph.d.ts.map +0 -1
- package/dist/opportunity/opportunity.graph.js.map +0 -1
- package/dist/opportunity/opportunity.introducer.d.ts.map +0 -1
- package/dist/opportunity/opportunity.introducer.js.map +0 -1
- package/dist/opportunity/opportunity.labels.d.ts.map +0 -1
- package/dist/opportunity/opportunity.labels.js.map +0 -1
- package/dist/opportunity/opportunity.pending-questions.d.ts.map +0 -1
- package/dist/opportunity/opportunity.pending-questions.js.map +0 -1
- package/dist/opportunity/opportunity.persist.d.ts.map +0 -1
- package/dist/opportunity/opportunity.persist.js.map +0 -1
- package/dist/opportunity/opportunity.presentation-cache.d.ts.map +0 -1
- package/dist/opportunity/opportunity.presentation-cache.js.map +0 -1
- package/dist/opportunity/opportunity.presentation.d.ts.map +0 -1
- package/dist/opportunity/opportunity.presentation.js.map +0 -1
- package/dist/opportunity/opportunity.presenter.d.ts.map +0 -1
- package/dist/opportunity/opportunity.presenter.js.map +0 -1
- package/dist/opportunity/opportunity.safe-presentation.d.ts.map +0 -1
- package/dist/opportunity/opportunity.safe-presentation.js.map +0 -1
- package/dist/opportunity/opportunity.state.d.ts.map +0 -1
- package/dist/opportunity/opportunity.state.js.map +0 -1
- package/dist/opportunity/opportunity.tools.d.ts.map +0 -1
- package/dist/opportunity/opportunity.tools.js.map +0 -1
- package/dist/opportunity/opportunity.utils.d.ts.map +0 -1
- package/dist/opportunity/opportunity.utils.js.map +0 -1
- package/dist/opportunity/outcome/outcome.env.d.ts.map +0 -1
- package/dist/opportunity/outcome/outcome.env.js.map +0 -1
- package/dist/opportunity/outcome/outcome.hypotheses.d.ts.map +0 -1
- package/dist/opportunity/outcome/outcome.hypotheses.js.map +0 -1
- package/dist/opportunity/outcome/outcome.shadow.d.ts.map +0 -1
- package/dist/opportunity/outcome/outcome.shadow.js.map +0 -1
- package/dist/opportunity/outcome/outcome.types.d.ts.map +0 -1
- package/dist/opportunity/outcome/outcome.types.js.map +0 -1
- package/dist/premise/premise.analyzer.d.ts.map +0 -1
- package/dist/premise/premise.analyzer.js.map +0 -1
- package/dist/premise/premise.decomposer.d.ts.map +0 -1
- package/dist/premise/premise.decomposer.js.map +0 -1
- package/dist/premise/premise.graph.d.ts.map +0 -1
- package/dist/premise/premise.graph.js.map +0 -1
- package/dist/premise/premise.indexer.d.ts.map +0 -1
- package/dist/premise/premise.indexer.js.map +0 -1
- package/dist/premise/premise.state.d.ts.map +0 -1
- package/dist/premise/premise.state.js.map +0 -1
- package/dist/premise/premise.tools.d.ts.map +0 -1
- package/dist/premise/premise.tools.js.map +0 -1
- package/dist/questioner/questioner.agent.d.ts.map +0 -1
- package/dist/questioner/questioner.agent.js.map +0 -1
- package/dist/questioner/questioner.ask.tool.d.ts.map +0 -1
- package/dist/questioner/questioner.ask.tool.js.map +0 -1
- package/dist/questioner/questioner.discovery.prompt.d.ts.map +0 -1
- package/dist/questioner/questioner.discovery.prompt.js.map +0 -1
- package/dist/questioner/questioner.env.d.ts.map +0 -1
- package/dist/questioner/questioner.env.js.map +0 -1
- package/dist/questioner/questioner.presets.d.ts.map +0 -1
- package/dist/questioner/questioner.presets.js.map +0 -1
- package/dist/questioner/questioner.qud.d.ts.map +0 -1
- package/dist/questioner/questioner.qud.js.map +0 -1
- package/dist/questioner/questioner.tools.d.ts.map +0 -1
- package/dist/questioner/questioner.tools.js.map +0 -1
- package/dist/questioner/questioner.types.d.ts.map +0 -1
- package/dist/questioner/questioner.types.js.map +0 -1
- package/dist/shared/agent/model-signal.d.ts.map +0 -1
- package/dist/shared/agent/model-signal.js.map +0 -1
- package/dist/shared/agent/model.config.d.ts.map +0 -1
- package/dist/shared/agent/model.config.js.map +0 -1
- package/dist/shared/agent/tests/llm-assert.d.ts +0 -11
- package/dist/shared/agent/tests/llm-assert.d.ts.map +0 -1
- package/dist/shared/agent/tests/llm-assert.js +0 -43
- package/dist/shared/agent/tests/llm-assert.js.map +0 -1
- package/dist/shared/agent/tool.factory.d.ts.map +0 -1
- package/dist/shared/agent/tool.factory.js.map +0 -1
- package/dist/shared/agent/tool.helpers.d.ts.map +0 -1
- package/dist/shared/agent/tool.helpers.js.map +0 -1
- package/dist/shared/agent/tool.registry.d.ts.map +0 -1
- package/dist/shared/agent/tool.registry.js.map +0 -1
- package/dist/shared/agent/tool.runtime.d.ts.map +0 -1
- package/dist/shared/agent/tool.runtime.js.map +0 -1
- package/dist/shared/agent/tool.scope.d.ts.map +0 -1
- package/dist/shared/agent/tool.scope.js.map +0 -1
- package/dist/shared/agent/utility.tools.d.ts.map +0 -1
- package/dist/shared/agent/utility.tools.js.map +0 -1
- package/dist/shared/assignment/network-assignment.policy.d.ts.map +0 -1
- package/dist/shared/assignment/network-assignment.policy.js.map +0 -1
- package/dist/shared/hyde/hyde.documents.d.ts.map +0 -1
- package/dist/shared/hyde/hyde.documents.js.map +0 -1
- package/dist/shared/hyde/hyde.env.d.ts.map +0 -1
- package/dist/shared/hyde/hyde.env.js.map +0 -1
- package/dist/shared/hyde/hyde.frame.d.ts.map +0 -1
- package/dist/shared/hyde/hyde.frame.js.map +0 -1
- package/dist/shared/hyde/hyde.generator.d.ts.map +0 -1
- package/dist/shared/hyde/hyde.generator.js.map +0 -1
- package/dist/shared/hyde/hyde.graph.d.ts.map +0 -1
- package/dist/shared/hyde/hyde.graph.js.map +0 -1
- package/dist/shared/hyde/hyde.state.d.ts.map +0 -1
- package/dist/shared/hyde/hyde.state.js.map +0 -1
- package/dist/shared/hyde/hyde.strategies.d.ts.map +0 -1
- package/dist/shared/hyde/hyde.strategies.js.map +0 -1
- package/dist/shared/hyde/hyde.validator.d.ts.map +0 -1
- package/dist/shared/hyde/hyde.validator.js.map +0 -1
- package/dist/shared/hyde/lens.inferrer.d.ts.map +0 -1
- package/dist/shared/hyde/lens.inferrer.js.map +0 -1
- package/dist/shared/interfaces/agent-dispatcher.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/agent-dispatcher.interface.js.map +0 -1
- package/dist/shared/interfaces/agent.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/agent.interface.js.map +0 -1
- package/dist/shared/interfaces/auth.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/auth.interface.js.map +0 -1
- package/dist/shared/interfaces/cache.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/cache.interface.js.map +0 -1
- package/dist/shared/interfaces/chat-message-writer.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/chat-message-writer.interface.js.map +0 -1
- package/dist/shared/interfaces/chat-session.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/chat-session.interface.js.map +0 -1
- package/dist/shared/interfaces/chat-summary.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/chat-summary.interface.js.map +0 -1
- package/dist/shared/interfaces/connect-link.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/connect-link.interface.js.map +0 -1
- package/dist/shared/interfaces/contact.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/contact.interface.js.map +0 -1
- package/dist/shared/interfaces/database.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/database.interface.js.map +0 -1
- package/dist/shared/interfaces/delivery-ledger.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/delivery-ledger.interface.js.map +0 -1
- package/dist/shared/interfaces/discovery-run.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/discovery-run.interface.js.map +0 -1
- package/dist/shared/interfaces/embedder.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/embedder.interface.js.map +0 -1
- package/dist/shared/interfaces/enrichment-run.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/enrichment-run.interface.js.map +0 -1
- package/dist/shared/interfaces/enrichment.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/enrichment.interface.js.map +0 -1
- package/dist/shared/interfaces/integration.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/integration.interface.js.map +0 -1
- package/dist/shared/interfaces/negotiation-events.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/negotiation-events.interface.js.map +0 -1
- package/dist/shared/interfaces/negotiation-summary.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/negotiation-summary.interface.js.map +0 -1
- package/dist/shared/interfaces/negotiator-memory.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/negotiator-memory.interface.js.map +0 -1
- package/dist/shared/interfaces/question-generator.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/question-generator.interface.js.map +0 -1
- package/dist/shared/interfaces/questioner.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/questioner.interface.js.map +0 -1
- package/dist/shared/interfaces/queue.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/queue.interface.js.map +0 -1
- package/dist/shared/interfaces/scraper.interface.d.ts.map +0 -1
- package/dist/shared/interfaces/scraper.interface.js.map +0 -1
- package/dist/shared/network/metadata.renderer.d.ts.map +0 -1
- package/dist/shared/network/metadata.renderer.js.map +0 -1
- package/dist/shared/observability/debug-meta.sanitizer.d.ts.map +0 -1
- package/dist/shared/observability/debug-meta.sanitizer.js.map +0 -1
- package/dist/shared/observability/log.d.ts.map +0 -1
- package/dist/shared/observability/log.js.map +0 -1
- package/dist/shared/observability/performance.d.ts.map +0 -1
- package/dist/shared/observability/performance.js.map +0 -1
- package/dist/shared/observability/protocol.logger.d.ts.map +0 -1
- package/dist/shared/observability/protocol.logger.js.map +0 -1
- package/dist/shared/observability/request-context.d.ts.map +0 -1
- package/dist/shared/observability/request-context.js.map +0 -1
- package/dist/shared/observability/trace.d.ts.map +0 -1
- package/dist/shared/observability/trace.js.map +0 -1
- package/dist/shared/schemas/chat-context.schema.d.ts.map +0 -1
- package/dist/shared/schemas/chat-context.schema.js.map +0 -1
- package/dist/shared/schemas/discovery-question.schema.d.ts.map +0 -1
- package/dist/shared/schemas/discovery-question.schema.js.map +0 -1
- package/dist/shared/schemas/identity.schema.d.ts.map +0 -1
- package/dist/shared/schemas/identity.schema.js.map +0 -1
- package/dist/shared/schemas/mcp-auth.schema.d.ts.map +0 -1
- package/dist/shared/schemas/mcp-auth.schema.js.map +0 -1
- package/dist/shared/schemas/negotiation-digest.schema.d.ts.map +0 -1
- package/dist/shared/schemas/negotiation-digest.schema.js.map +0 -1
- package/dist/shared/schemas/negotiation-state.schema.d.ts.map +0 -1
- package/dist/shared/schemas/negotiation-state.schema.js.map +0 -1
- package/dist/shared/schemas/network-assignment.schema.d.ts.map +0 -1
- package/dist/shared/schemas/network-assignment.schema.js.map +0 -1
- package/dist/shared/schemas/pending-question.schema.d.ts.map +0 -1
- package/dist/shared/schemas/pending-question.schema.js.map +0 -1
- package/dist/shared/schemas/question.schema.d.ts.map +0 -1
- package/dist/shared/schemas/question.schema.js.map +0 -1
- package/dist/shared/ui/lucide.icon-catalog.d.ts.map +0 -1
- package/dist/shared/ui/lucide.icon-catalog.js.map +0 -1
- package/dist/shared/utils/social-label.d.ts.map +0 -1
- package/dist/shared/utils/social-label.js.map +0 -1
- package/dist/shared/utils/telegram-handle.d.ts.map +0 -1
- package/dist/shared/utils/telegram-handle.js.map +0 -1
|
@@ -0,0 +1,1393 @@
|
|
|
1
|
+
import { StateGraph } from "@langchain/langgraph";
|
|
2
|
+
import { invokeWithAbortSignal } from "../../shared/agent/model-signal.js";
|
|
3
|
+
import { requestContext } from "../../shared/observability/request-context.js";
|
|
4
|
+
import { NegotiationGraphState } from "../domain/negotiation.state.js";
|
|
5
|
+
import { IndexNegotiator } from "./negotiation.agent.js";
|
|
6
|
+
import { allowedActionsFor, askUserAnswerWindowMs, configuredAskUserEnabled, configuredProtocolVersion, fallbackActionFor, isRejectLikeAction, isTerminalAction, readProtocolVersion, rejectActionFor } from "../domain/negotiation.protocol.js";
|
|
7
|
+
import { assessConsultationEligibility, consultationPromptFor, negotiationConsultationPolicyMode } from "../domain/negotiation.consultation-policy.js";
|
|
8
|
+
import { blocksNegotiationBeforeFirstTurn, NegotiationScreener } from "./negotiation.screen.js";
|
|
9
|
+
import { configuredScreenMode } from "../domain/negotiation.screen.contracts.js";
|
|
10
|
+
import { assessDeadlock, configuredDeadlockShiftEnabled, configuredDeadlockThreshold } from "../domain/negotiation.deadlock.js";
|
|
11
|
+
import { protocolLogger } from "../../shared/observability/protocol.logger.js";
|
|
12
|
+
import { NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY, NEGOTIATION_QUESTION_GENERIC_NETWORK, negotiationQuestionSettlementId, validateInflightAskUserFields } from '../domain/negotiation.question-safety.js';
|
|
13
|
+
import { buildIntentSnapshots } from "../domain/negotiation.intent-snapshot-provenance.js";
|
|
14
|
+
import { holdsNegotiationConversationLock } from "../domain/negotiation.task-lock-policy.js";
|
|
15
|
+
import { attributedDialogueIsEmpty, buildSeededAttribution, combineAttributedDialogue } from '../negotiation.attribution.js';
|
|
16
|
+
const logger = protocolLogger("NegotiationGraph");
|
|
17
|
+
const initLog = protocolLogger("NegotiationGraph:Init");
|
|
18
|
+
const screenNodeLog = protocolLogger("NegotiationGraph:Screen");
|
|
19
|
+
const turnLog = protocolLogger("NegotiationGraph:Turn");
|
|
20
|
+
const finalizeLog = protocolLogger("NegotiationGraph:Finalize");
|
|
21
|
+
const negotiateCandidatesLog = protocolLogger("NegotiationGraph:negotiateCandidates");
|
|
22
|
+
/** Extracts the ordered NegotiationTurn list from A2A message data parts. */
|
|
23
|
+
function turnsFromMessages(messages) {
|
|
24
|
+
return messages
|
|
25
|
+
.map((m) => {
|
|
26
|
+
const dataPart = m.parts.find((p) => p.kind === "data");
|
|
27
|
+
return dataPart?.data;
|
|
28
|
+
})
|
|
29
|
+
.filter(Boolean);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Whether `userId`'s side has already spent its one `ask_user` client
|
|
33
|
+
* consultation in this conversation (P3.2 rationing: max one per negotiation
|
|
34
|
+
* per side, checked against the full message history so continuations count
|
|
35
|
+
* prior sessions' consultations too).
|
|
36
|
+
*/
|
|
37
|
+
function hasPriorAskUser(messages, userId) {
|
|
38
|
+
const sender = `agent:${userId}`;
|
|
39
|
+
return messages.some((m) => {
|
|
40
|
+
if (m.senderId !== sender)
|
|
41
|
+
return false;
|
|
42
|
+
const dataPart = m.parts.find((p) => p.kind === "data");
|
|
43
|
+
return dataPart?.data?.action === "ask_user";
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Factory for the bilateral negotiation LangGraph state machine.
|
|
48
|
+
* @remarks Accepts an AgentDispatcher for per-turn agent resolution.
|
|
49
|
+
*/
|
|
50
|
+
export class NegotiationGraphFactory {
|
|
51
|
+
constructor(database, dispatcher, timeoutQueue, questionerEnqueue, reflectEnqueue, memoryRetrieve) {
|
|
52
|
+
this.database = database;
|
|
53
|
+
this.dispatcher = dispatcher;
|
|
54
|
+
this.timeoutQueue = timeoutQueue;
|
|
55
|
+
this.questionerEnqueue = questionerEnqueue;
|
|
56
|
+
this.reflectEnqueue = reflectEnqueue;
|
|
57
|
+
this.memoryRetrieve = memoryRetrieve;
|
|
58
|
+
}
|
|
59
|
+
createGraph() {
|
|
60
|
+
const { database, dispatcher, timeoutQueue, questionerEnqueue, reflectEnqueue, memoryRetrieve } = this;
|
|
61
|
+
const systemAgent = new IndexNegotiator();
|
|
62
|
+
const screener = new NegotiationScreener();
|
|
63
|
+
/**
|
|
64
|
+
* P5.3 memory retrieval — never throws, never blocks a negotiation. The
|
|
65
|
+
* injected fn already resolves [] when NEGOTIATOR_MEMORY_INJECT is off;
|
|
66
|
+
* this wrapper adds the graph-side failure guard.
|
|
67
|
+
*/
|
|
68
|
+
const retrieveMemory = async (userId, counterpartyUserId, queryText, scope) => {
|
|
69
|
+
if (!memoryRetrieve)
|
|
70
|
+
return [];
|
|
71
|
+
try {
|
|
72
|
+
return await memoryRetrieve({ userId, counterpartyUserId, queryText, scope });
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
logger.warn("Negotiator memory retrieval failed; proceeding without memory", {
|
|
76
|
+
userId,
|
|
77
|
+
scope,
|
|
78
|
+
error: err instanceof Error ? err.message : String(err),
|
|
79
|
+
});
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
/** Similarity query text: seed reasoning + counterparty context. */
|
|
84
|
+
const memoryQueryText = (state, counterparty) => [
|
|
85
|
+
state.discoveryQuery ? `Search: ${state.discoveryQuery}` : "",
|
|
86
|
+
state.seedAssessment?.reasoning ?? "",
|
|
87
|
+
counterparty?.profile?.name ?? "",
|
|
88
|
+
counterparty?.profile?.bio ?? "",
|
|
89
|
+
(counterparty?.intents ?? []).slice(0, 5).map((i) => `${i.title}: ${i.description}`).join("\n"),
|
|
90
|
+
].filter(Boolean).join("\n");
|
|
91
|
+
/**
|
|
92
|
+
* IND-569: resolve a prior negotiation task's attribution metadata for the
|
|
93
|
+
* per-opportunity prior-dialogue labels. Never throws — any failure returns
|
|
94
|
+
* null so the turns degrade to the unattributed block instead of leaking
|
|
95
|
+
* into the current opportunity's context.
|
|
96
|
+
*/
|
|
97
|
+
const resolveTaskAttribution = async (taskId) => {
|
|
98
|
+
try {
|
|
99
|
+
const task = await database.getTask(taskId);
|
|
100
|
+
if (!task)
|
|
101
|
+
return null;
|
|
102
|
+
const md = (task.metadata ?? {});
|
|
103
|
+
const opportunityId = typeof md.opportunityId === 'string' && md.opportunityId.length > 0 ? md.opportunityId : null;
|
|
104
|
+
const snapshots = Array.isArray(md.intentSnapshots) ? md.intentSnapshots : [];
|
|
105
|
+
const sourceIntentId = typeof md.sourceIntentId === 'string' ? md.sourceIntentId : null;
|
|
106
|
+
const snap = snapshots.find((s) => s && s.intentId === sourceIntentId) ?? snapshots[0];
|
|
107
|
+
const opportunityTitle = snap && typeof snap.title === 'string' && snap.title.trim().length > 0 ? snap.title : null;
|
|
108
|
+
let outcome = null;
|
|
109
|
+
try {
|
|
110
|
+
const artifacts = await database.getArtifactsForTask(taskId);
|
|
111
|
+
const outArtifact = artifacts.find((a) => a.name === 'negotiation-outcome');
|
|
112
|
+
if (outArtifact) {
|
|
113
|
+
const firstPart = Array.isArray(outArtifact.parts) ? outArtifact.parts[0] : undefined;
|
|
114
|
+
const data = firstPart?.data;
|
|
115
|
+
if (data && typeof data.hasOpportunity === 'boolean') {
|
|
116
|
+
outcome = data.hasOpportunity ? 'accepted' : (data.reason === 'screened_out' ? 'not pursued' : 'declined');
|
|
117
|
+
}
|
|
118
|
+
else if (typeof outArtifact.metadata?.continuationOutcome === 'string') {
|
|
119
|
+
outcome = outArtifact.metadata.continuationOutcome;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch { /* outcome stays null; header degrades to "outcome unknown" */ }
|
|
124
|
+
const concludedAt = task.updatedAt instanceof Date
|
|
125
|
+
? task.updatedAt.toISOString()
|
|
126
|
+
: (task.updatedAt ? new Date(task.updatedAt).toISOString() : null);
|
|
127
|
+
return { opportunityId, opportunityTitle, outcome, concludedAt };
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* IND-569: build the attributed prior dialogue passed to the screener and
|
|
135
|
+
* turn prompts. Combines the immutable seeded attribution (earlier + legacy
|
|
136
|
+
* unattributed blocks, resolved once in init) with this session's own turns
|
|
137
|
+
* (task-id-matched). Null when there is no seeded attribution.
|
|
138
|
+
*/
|
|
139
|
+
const buildAttributedDialogue = (state) => {
|
|
140
|
+
if (!state.isContinuation || !state.priorAttribution)
|
|
141
|
+
return null;
|
|
142
|
+
const currentSessionTurns = turnsFromMessages(state.messages.filter((m) => m.taskId === state.taskId));
|
|
143
|
+
const dialogue = combineAttributedDialogue(state.priorAttribution, currentSessionTurns);
|
|
144
|
+
return attributedDialogueIsEmpty(dialogue) ? null : dialogue;
|
|
145
|
+
};
|
|
146
|
+
const initNode = async (state) => {
|
|
147
|
+
try {
|
|
148
|
+
// Exact continuations reuse the prior conversation and preclaimed
|
|
149
|
+
// successor; they must not create any mutable state before the fence.
|
|
150
|
+
const agentIdA = `agent:${state.sourceUser.id}`;
|
|
151
|
+
const agentIdB = `agent:${state.candidateUser.id}`;
|
|
152
|
+
const execution = state.continuationExecution;
|
|
153
|
+
const conversation = execution
|
|
154
|
+
? { id: execution.conversationId }
|
|
155
|
+
: await database.getOrCreateDM(agentIdA, agentIdB, 'agent');
|
|
156
|
+
// --- Lock gate: check for an active task on this conversation ---
|
|
157
|
+
const priorMessages = await database.getMessagesForConversation(conversation.id);
|
|
158
|
+
if (Boolean(state.resumeFromTaskId) !== Boolean(state.continuationSettlementId)
|
|
159
|
+
|| Boolean(state.resumeFromTaskId) !== Boolean(execution))
|
|
160
|
+
return { error: 'invalid continuation correlation' };
|
|
161
|
+
const exactContinuation = state.resumeFromTaskId && state.continuationSettlementId && execution
|
|
162
|
+
? { taskId: state.resumeFromTaskId, settlementId: state.continuationSettlementId, execution }
|
|
163
|
+
: null;
|
|
164
|
+
const priorTask = exactContinuation
|
|
165
|
+
? await database.getTask(exactContinuation.taskId)
|
|
166
|
+
: state.opportunityId
|
|
167
|
+
? await database.getNegotiationTaskForOpportunity(state.opportunityId)
|
|
168
|
+
: null;
|
|
169
|
+
const claimedSuccessor = exactContinuation
|
|
170
|
+
? await database.getTask(exactContinuation.execution.successorTaskId)
|
|
171
|
+
: null;
|
|
172
|
+
if (exactContinuation) {
|
|
173
|
+
const settlement = priorTask?.metadata?.questionSettlement;
|
|
174
|
+
const storedExecution = claimedSuccessor?.metadata?.continuationExecution;
|
|
175
|
+
if (!priorTask
|
|
176
|
+
|| priorTask.conversationId !== conversation.id
|
|
177
|
+
|| priorTask.state !== 'canceled'
|
|
178
|
+
|| priorTask.metadata?.opportunityId !== state.opportunityId
|
|
179
|
+
|| settlement?.settlementId !== exactContinuation.settlementId
|
|
180
|
+
|| settlement?.taskId !== exactContinuation.taskId
|
|
181
|
+
|| !claimedSuccessor
|
|
182
|
+
|| claimedSuccessor.conversationId !== conversation.id
|
|
183
|
+
|| storedExecution?.token !== exactContinuation.execution.token
|
|
184
|
+
|| storedExecution?.fence !== exactContinuation.execution.fence
|
|
185
|
+
|| storedExecution?.status !== 'claimed')
|
|
186
|
+
return { error: 'invalid exact continuation task' };
|
|
187
|
+
}
|
|
188
|
+
const isLocked = !exactContinuation && !!priorTask && holdsNegotiationConversationLock(priorTask);
|
|
189
|
+
if (isLocked) {
|
|
190
|
+
initLog.info('Conversation locked by active task, returning busy', {
|
|
191
|
+
conversationId: conversation.id,
|
|
192
|
+
opportunityId: state.opportunityId,
|
|
193
|
+
});
|
|
194
|
+
return { error: 'busy' };
|
|
195
|
+
}
|
|
196
|
+
// --- Load prior messages and determine continuation ---
|
|
197
|
+
const priorTurns = turnsFromMessages(priorMessages);
|
|
198
|
+
const isContinuation = priorTurns.length > 0;
|
|
199
|
+
// Determine currentSpeaker from last prior message. An `ask_user` last
|
|
200
|
+
// turn does NOT pass the floor: the sender paused to consult its own
|
|
201
|
+
// client, so on resume the same side speaks again — now armed with the
|
|
202
|
+
// client's answer (or its recorded absence). Flipping here would hand
|
|
203
|
+
// the turn to the counterparty, who has nothing to respond to.
|
|
204
|
+
let currentSpeaker = 'source';
|
|
205
|
+
if (isContinuation && priorMessages.length > 0) {
|
|
206
|
+
const lastMessage = priorMessages[priorMessages.length - 1];
|
|
207
|
+
const lastAction = turnsFromMessages([lastMessage])[0]?.action;
|
|
208
|
+
if (lastAction === 'ask_user') {
|
|
209
|
+
currentSpeaker = lastMessage.senderId === agentIdA ? 'source' : 'candidate';
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
currentSpeaker = lastMessage.senderId === agentIdA ? 'candidate' : 'source';
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Determine scenario-based maxTurns
|
|
216
|
+
const scope = { action: 'manage:negotiations', scopeType: 'network', scopeId: state.indexContext.networkId };
|
|
217
|
+
const [sourceHasAgent, candidateHasAgent] = await Promise.all([
|
|
218
|
+
dispatcher.hasExternalAgent(state.sourceUser.id, scope),
|
|
219
|
+
dispatcher.hasExternalAgent(state.candidateUser.id, scope),
|
|
220
|
+
]);
|
|
221
|
+
const ambientMax = Number(process.env.NEGOTIATION_MAX_TURNS_AMBIENT) || 6;
|
|
222
|
+
let maxTurns = state.maxTurns;
|
|
223
|
+
if (maxTurns == null) {
|
|
224
|
+
maxTurns = (sourceHasAgent && candidateHasAgent) ? 0 : ambientMax;
|
|
225
|
+
}
|
|
226
|
+
// --- Initiator seat resolution (v2: rigid per match, stamped at discovery) ---
|
|
227
|
+
// 1. Continuations inherit from the prior task for the same opportunity —
|
|
228
|
+
// never re-derive, so the seat cannot flip between sessions.
|
|
229
|
+
// 2. Conversation-scoped tie-break: if another negotiation on this DM is
|
|
230
|
+
// active and fresh (symmetric concurrent start under a different
|
|
231
|
+
// opportunityId — the opportunity-scoped lock above cannot see it),
|
|
232
|
+
// the first created task keeps the seat; this run inherits its stamp.
|
|
233
|
+
// 3. Otherwise: explicit stamp from the caller, falling back to the
|
|
234
|
+
// session's sourceUser (pre-stamp heuristic behavior, unchanged).
|
|
235
|
+
const readInitiator = (metadata) => {
|
|
236
|
+
const v = metadata?.initiatorUserId;
|
|
237
|
+
return typeof v === 'string' && v.length > 0 ? v : null;
|
|
238
|
+
};
|
|
239
|
+
let initiatorUserId = readInitiator(priorTask?.metadata) ?? state.initiatorUserId ?? state.sourceUser.id;
|
|
240
|
+
// Conversation-scoped prior task: used only for the initiator tie-break
|
|
241
|
+
// (and only when active+fresh).
|
|
242
|
+
const convTask = !exactContinuation && !readInitiator(priorTask?.metadata)
|
|
243
|
+
? await database.getLatestNegotiationTaskForConversation?.(conversation.id).catch(() => null)
|
|
244
|
+
: null;
|
|
245
|
+
if (!readInitiator(priorTask?.metadata)) {
|
|
246
|
+
if (convTask && convTask.id !== priorTask?.id && holdsNegotiationConversationLock(convTask)) {
|
|
247
|
+
const convInitiator = readInitiator(convTask.metadata);
|
|
248
|
+
if (convInitiator) {
|
|
249
|
+
initLog.info('Conversation-scoped tie-break: inheriting initiator seat from concurrent task', {
|
|
250
|
+
conversationId: conversation.id,
|
|
251
|
+
winningTaskId: convTask.id,
|
|
252
|
+
initiatorUserId: convInitiator,
|
|
253
|
+
});
|
|
254
|
+
initiatorUserId = convInitiator;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// --- Protocol version: pinned per negotiation, re-stamped per match ---
|
|
259
|
+
// A prior task for this same negotiation (exact continuation resume or
|
|
260
|
+
// a re-run of the same opportunity) pins the version, so one
|
|
261
|
+
// negotiation never flips semantics mid-flight (absent field on a
|
|
262
|
+
// genuine prior = pre-v2 task = v1). Everything else — including
|
|
263
|
+
// continuations of older conversations between the same pair — stamps
|
|
264
|
+
// fresh from NEGOTIATION_PROTOCOL_VERSION, so a version cutover
|
|
265
|
+
// reaches existing pairs on their next new match instead of being
|
|
266
|
+
// pinned to v1 forever by conversation history.
|
|
267
|
+
const protocolVersion = priorTask
|
|
268
|
+
? (readProtocolVersion(priorTask.metadata) ?? 'v1')
|
|
269
|
+
: configuredProtocolVersion();
|
|
270
|
+
const taskMetadata = {
|
|
271
|
+
type: 'negotiation',
|
|
272
|
+
sourceUserId: state.sourceUser.id,
|
|
273
|
+
initiatorUserId,
|
|
274
|
+
protocolVersion,
|
|
275
|
+
candidateUserId: state.candidateUser.id,
|
|
276
|
+
networkId: state.indexContext.networkId,
|
|
277
|
+
sourceIntentId: state.sourceIntentId,
|
|
278
|
+
candidateIntentId: state.candidateIntentId,
|
|
279
|
+
participantBindings: [
|
|
280
|
+
...(state.sourceIntentId ? [{ userId: state.sourceUser.id, intentId: state.sourceIntentId, networkId: state.indexContext.networkId }] : []),
|
|
281
|
+
...(state.candidateIntentId ? [{ userId: state.candidateUser.id, intentId: state.candidateIntentId, networkId: state.indexContext.networkId }] : []),
|
|
282
|
+
],
|
|
283
|
+
intentSnapshots: buildIntentSnapshots(state.sourceUser, state.candidateUser),
|
|
284
|
+
...(state.opportunityId && { opportunityId: state.opportunityId }),
|
|
285
|
+
maxTurns,
|
|
286
|
+
isContinuation,
|
|
287
|
+
priorTurnCount: priorTurns.length,
|
|
288
|
+
...(exactContinuation ? {
|
|
289
|
+
resumeFromTaskId: exactContinuation.taskId,
|
|
290
|
+
continuationSettlementId: exactContinuation.settlementId,
|
|
291
|
+
} : {}),
|
|
292
|
+
};
|
|
293
|
+
if (state.opportunityId && Boolean(state.opportunityStatus) !== Boolean(state.opportunityUpdatedAt)) {
|
|
294
|
+
throw new Error('Negotiation attempt requires both opportunity status and updatedAt');
|
|
295
|
+
}
|
|
296
|
+
const task = exactContinuation
|
|
297
|
+
? claimedSuccessor
|
|
298
|
+
: state.opportunityId && state.opportunityStatus && state.opportunityUpdatedAt
|
|
299
|
+
? await database.createNegotiationTaskForAttempt({
|
|
300
|
+
conversationId: conversation.id,
|
|
301
|
+
opportunityId: state.opportunityId,
|
|
302
|
+
expectedStatus: state.opportunityStatus,
|
|
303
|
+
expectedUpdatedAt: state.opportunityUpdatedAt,
|
|
304
|
+
metadata: taskMetadata,
|
|
305
|
+
})
|
|
306
|
+
: await database.createTask(conversation.id, taskMetadata);
|
|
307
|
+
if (!task) {
|
|
308
|
+
throw new Error('Negotiation attempt is stale or already claimed');
|
|
309
|
+
}
|
|
310
|
+
// Attempt-bound discovery atomically promoted the exact persisted state
|
|
311
|
+
// to `negotiating` while inserting the task. Legacy/direct invocations
|
|
312
|
+
// with only an opportunity ID retain the prior best-effort status update.
|
|
313
|
+
if (state.opportunityId && !state.opportunityUpdatedAt) {
|
|
314
|
+
await database.updateOpportunityStatus(state.opportunityId, 'negotiating').catch((err) => {
|
|
315
|
+
initLog.error('Failed to set opportunity status to negotiating', { opportunityId: state.opportunityId, error: err });
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
// Load user answers collected by the questioner between sessions
|
|
319
|
+
const userAnswers = (isContinuation && state.opportunityId)
|
|
320
|
+
? await database.getOpportunityUserAnswers(state.opportunityId).catch((err) => {
|
|
321
|
+
initLog.error('Failed to load user answers', { opportunityId: state.opportunityId, error: err });
|
|
322
|
+
return [];
|
|
323
|
+
})
|
|
324
|
+
: [];
|
|
325
|
+
// Seed messages with prior turns (additive reducer appends new turns on top).
|
|
326
|
+
// taskId is preserved so the turn/screen nodes can separate this
|
|
327
|
+
// session's turns from seeded prior-task turns (IND-569).
|
|
328
|
+
const seedMessages = isContinuation ? priorMessages.map((m) => ({
|
|
329
|
+
id: m.id,
|
|
330
|
+
senderId: m.senderId,
|
|
331
|
+
role: 'agent',
|
|
332
|
+
parts: m.parts,
|
|
333
|
+
createdAt: m.createdAt,
|
|
334
|
+
taskId: m.taskId ?? null,
|
|
335
|
+
})) : [];
|
|
336
|
+
// IND-569: attribute seeded prior turns to their originating opportunity
|
|
337
|
+
// once, up front. Earlier-opportunity and legacy unattributed blocks are
|
|
338
|
+
// immutable for the session; the current block is composed per turn.
|
|
339
|
+
const priorAttribution = isContinuation
|
|
340
|
+
? await buildSeededAttribution(priorMessages
|
|
341
|
+
.map((m) => ({ taskId: m.taskId ?? null, turn: turnsFromMessages([m])[0] }))
|
|
342
|
+
.filter((e) => Boolean(e.turn)), state.opportunityId, resolveTaskAttribution)
|
|
343
|
+
: null;
|
|
344
|
+
return {
|
|
345
|
+
conversationId: conversation.id,
|
|
346
|
+
taskId: task.id,
|
|
347
|
+
currentSpeaker,
|
|
348
|
+
turnCount: 0,
|
|
349
|
+
maxTurns,
|
|
350
|
+
isContinuation,
|
|
351
|
+
initiatorUserId,
|
|
352
|
+
protocolVersion,
|
|
353
|
+
priorTurnCount: priorTurns.length,
|
|
354
|
+
...(priorAttribution && { priorAttribution }),
|
|
355
|
+
...(userAnswers.length > 0 && { userAnswers }),
|
|
356
|
+
...(exactContinuation?.execution.consultation
|
|
357
|
+
? { privateConsultation: exactContinuation.execution.consultation }
|
|
358
|
+
: {}),
|
|
359
|
+
...(exactContinuation && (() => {
|
|
360
|
+
const turnContext = priorTask?.metadata?.turnContext;
|
|
361
|
+
const reason = turnContext?.consultationPolicyReason;
|
|
362
|
+
return typeof reason === 'string' ? { consultationPolicyReason: reason } : {};
|
|
363
|
+
})()),
|
|
364
|
+
...(seedMessages.length > 0 && { messages: seedMessages }),
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
catch (err) {
|
|
368
|
+
return { error: `Init failed: ${err instanceof Error ? err.message : String(err)}` };
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Screen node (P2.1) — the outreach gate. Runs between init and the first
|
|
373
|
+
* turn on FRESH negotiations only (routing skips it on continuations and
|
|
374
|
+
* when NEGOTIATION_SCREEN_MODE=off). The reaching client's negotiator
|
|
375
|
+
* decides whether the match is worth its client's name; in shadow mode the
|
|
376
|
+
* decision is recorded (task metadata + trace event + log line) but never
|
|
377
|
+
* blocks — the negotiation always proceeds to the first turn. In enforce
|
|
378
|
+
* mode (P2.2) a `pass` routes straight to finalize: zero turns, zero
|
|
379
|
+
* counterparty involvement, outcome `reason: "screened_out"`, opportunity
|
|
380
|
+
* quietly `rejected` (init had already flipped it to `negotiating`).
|
|
381
|
+
* A failed screen still fails OPEN in every mode.
|
|
382
|
+
*/
|
|
383
|
+
const screenNode = async (state) => {
|
|
384
|
+
const traceEmitter = requestContext.getStore()?.traceEmitter;
|
|
385
|
+
const emitWide = (event) => traceEmitter?.(event);
|
|
386
|
+
const mode = configuredScreenMode();
|
|
387
|
+
const start = Date.now();
|
|
388
|
+
// The client is the initiator seat's user — the side whose negotiator is
|
|
389
|
+
// reaching out. Fresh runs stamp initiatorUserId in init; fall back to
|
|
390
|
+
// sourceUser (what the stamp defaults to anyway).
|
|
391
|
+
const initiatorId = state.initiatorUserId ?? state.sourceUser.id;
|
|
392
|
+
const clientIsSource = initiatorId !== state.candidateUser.id;
|
|
393
|
+
const clientUser = clientIsSource ? state.sourceUser : state.candidateUser;
|
|
394
|
+
const counterpartyUser = clientIsSource ? state.candidateUser : state.sourceUser;
|
|
395
|
+
// P5.3: the client's own negotiator memory informs the outreach gate.
|
|
396
|
+
// Cached into state so the client's first turn reuses it.
|
|
397
|
+
const clientSide = clientIsSource ? "source" : "candidate";
|
|
398
|
+
const clientMemory = state.memoryBySide?.[clientSide]
|
|
399
|
+
?? (memoryRetrieve
|
|
400
|
+
? await retrieveMemory(clientUser.id, counterpartyUser.id, memoryQueryText(state, counterpartyUser), "screen")
|
|
401
|
+
: []);
|
|
402
|
+
let decision;
|
|
403
|
+
let failedOpen = false;
|
|
404
|
+
let screenError;
|
|
405
|
+
try {
|
|
406
|
+
const counterpartyContext = (await database.getUserContext(counterpartyUser.id, null).catch(() => null))?.text ?? "";
|
|
407
|
+
const priorDialogueAttributed = buildAttributedDialogue(state);
|
|
408
|
+
decision = await screener.invoke({
|
|
409
|
+
clientUser,
|
|
410
|
+
counterpartyUser,
|
|
411
|
+
...(counterpartyContext && { counterpartyContext }),
|
|
412
|
+
...(clientMemory.length > 0 && { memory: clientMemory }),
|
|
413
|
+
// discoveryQuery belongs to the discovery session's source user; only
|
|
414
|
+
// meaningful for the client when the client holds the source side.
|
|
415
|
+
...(clientIsSource && state.discoveryQuery && { discoveryQuery: state.discoveryQuery }),
|
|
416
|
+
seedAssessment: state.seedAssessment,
|
|
417
|
+
indexContext: state.indexContext,
|
|
418
|
+
isContinuation: state.isContinuation,
|
|
419
|
+
...(state.messages.length > 0 && { priorDialogue: turnsFromMessages(state.messages) }),
|
|
420
|
+
...(priorDialogueAttributed && { priorDialogueAttributed }),
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
catch (err) {
|
|
424
|
+
// Fail open: a screen failure must never block a negotiation.
|
|
425
|
+
failedOpen = true;
|
|
426
|
+
screenError = err instanceof Error ? err.message : String(err);
|
|
427
|
+
screenNodeLog.warn("Screen failed; proceeding open (reach_out)", {
|
|
428
|
+
taskId: state.taskId,
|
|
429
|
+
opportunityId: state.opportunityId || undefined,
|
|
430
|
+
error: screenError,
|
|
431
|
+
});
|
|
432
|
+
decision = {
|
|
433
|
+
decision: "reach_out",
|
|
434
|
+
reasoning: `screen_error: ${screenError}`,
|
|
435
|
+
evidence: { counterpartyPremiseFit: "", intentAlignment: "" },
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
const durationMs = Date.now() - start;
|
|
439
|
+
const record = {
|
|
440
|
+
...decision,
|
|
441
|
+
mode,
|
|
442
|
+
...(failedOpen && { failedOpen, error: screenError }),
|
|
443
|
+
screenedAt: new Date().toISOString(),
|
|
444
|
+
durationMs,
|
|
445
|
+
};
|
|
446
|
+
await database.setTaskScreenDecision?.(state.taskId, record, state.continuationExecution).catch((err) => {
|
|
447
|
+
screenNodeLog.error("Failed to persist screen decision", { taskId: state.taskId, error: err });
|
|
448
|
+
});
|
|
449
|
+
screenNodeLog.info("negotiation_screen", {
|
|
450
|
+
taskId: state.taskId,
|
|
451
|
+
opportunityId: state.opportunityId || undefined,
|
|
452
|
+
decision: decision.decision,
|
|
453
|
+
mode,
|
|
454
|
+
failedOpen,
|
|
455
|
+
durationMs,
|
|
456
|
+
});
|
|
457
|
+
if (state.opportunityId) {
|
|
458
|
+
emitWide({
|
|
459
|
+
type: "negotiation_screen",
|
|
460
|
+
opportunityId: state.opportunityId,
|
|
461
|
+
negotiationConversationId: state.conversationId,
|
|
462
|
+
decision: decision.decision,
|
|
463
|
+
reasoning: decision.reasoning,
|
|
464
|
+
mode,
|
|
465
|
+
failedOpen,
|
|
466
|
+
durationMs,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
// Routing happens on the conditional edge: shadow always proceeds to
|
|
470
|
+
// the first turn; enforce routes a (non-failed-open) pass to finalize.
|
|
471
|
+
return { screenDecision: record, memoryBySide: { [clientSide]: clientMemory } };
|
|
472
|
+
};
|
|
473
|
+
const turnNode = async (state) => {
|
|
474
|
+
const traceEmitter = requestContext.getStore()?.traceEmitter;
|
|
475
|
+
// Local helper to emit events whose shape is wider than the declared
|
|
476
|
+
// `TraceEmitter` union. The chat agent already casts at its relay sink;
|
|
477
|
+
// here we localize the cast at the callsite so the rest of the body stays typed.
|
|
478
|
+
const emitWide = (event) => traceEmitter?.(event);
|
|
479
|
+
const agentName = "Index negotiator";
|
|
480
|
+
const agentStart = Date.now();
|
|
481
|
+
traceEmitter?.({ type: "agent_start", name: agentName });
|
|
482
|
+
try {
|
|
483
|
+
const history = turnsFromMessages(state.messages);
|
|
484
|
+
const isSource = state.currentSpeaker === "source";
|
|
485
|
+
const ownUser = isSource ? state.sourceUser : state.candidateUser;
|
|
486
|
+
const otherUser = isSource ? state.candidateUser : state.sourceUser;
|
|
487
|
+
const ownIntentId = isSource ? state.sourceIntentId : state.candidateIntentId;
|
|
488
|
+
// Determine if this is the system agent's final allowed turn
|
|
489
|
+
const maxTurns = state.maxTurns ?? 0;
|
|
490
|
+
const isFinalTurn = maxTurns > 0 && (state.turnCount + 1) >= maxTurns;
|
|
491
|
+
// Seat attribution keys on initiatorUserId (rigid v2 stamp), never on
|
|
492
|
+
// parity or source/candidate position — under the conversation-scoped
|
|
493
|
+
// tie-break this run's source may hold the counterparty seat.
|
|
494
|
+
const version = state.protocolVersion ?? 'v1';
|
|
495
|
+
const seat = ownUser.id === (state.initiatorUserId ?? state.sourceUser.id)
|
|
496
|
+
? 'initiator'
|
|
497
|
+
: 'counterparty';
|
|
498
|
+
// Legacy ask_user availability (P3.2): flag on, full pause loop wired
|
|
499
|
+
// (questioner + answer-window timer + an opportunity to resume
|
|
500
|
+
// against), v2 non-final non-opening turn, and this side's one client
|
|
501
|
+
// consultation not yet spent (rationing). Shadow is observational and
|
|
502
|
+
// must preserve this legacy path byte-for-byte except for telemetry.
|
|
503
|
+
const policyMode = negotiationConsultationPolicyMode();
|
|
504
|
+
const askUserAvailable = version === 'v2'
|
|
505
|
+
&& !isFinalTurn
|
|
506
|
+
&& configuredAskUserEnabled()
|
|
507
|
+
&& !!questionerEnqueue
|
|
508
|
+
&& !!timeoutQueue?.enqueueAskUserExpiry
|
|
509
|
+
&& !!state.opportunityId
|
|
510
|
+
&& !!ownIntentId
|
|
511
|
+
&& !!state.indexContext.networkId
|
|
512
|
+
&& !(state.turnCount === 0 && !state.isContinuation)
|
|
513
|
+
&& !hasPriorAskUser(state.messages, ownUser.id);
|
|
514
|
+
// ─── Deadlock detection → persuasion→bargaining stance (IND-428) ──────
|
|
515
|
+
// Deterministic trailing-run inspection of the persisted history — no
|
|
516
|
+
// LLM in the decision. Gated on the strict default-off flag AND v2,
|
|
517
|
+
// checked alongside the protocol-version plumbing so v1 semantics stay
|
|
518
|
+
// untouched. Fail-open: any detection error means "no deadlock" and
|
|
519
|
+
// the legacy path proceeds byte-identically. The shift changes the
|
|
520
|
+
// system agent's drafting stance only — allowedActions, the dispatch
|
|
521
|
+
// payload, and all termination rules are untouched.
|
|
522
|
+
let deadlock = null;
|
|
523
|
+
if (version === 'v2' && configuredDeadlockShiftEnabled()) {
|
|
524
|
+
try {
|
|
525
|
+
deadlock = assessDeadlock(history, configuredDeadlockThreshold());
|
|
526
|
+
}
|
|
527
|
+
catch (err) {
|
|
528
|
+
turnLog.warn('Deadlock detection failed; proceeding without mode shift', {
|
|
529
|
+
taskId: state.taskId,
|
|
530
|
+
error: err instanceof Error ? err.message : String(err),
|
|
531
|
+
});
|
|
532
|
+
deadlock = null;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
const bargainingMode = deadlock?.deadlocked === true;
|
|
536
|
+
// P5.3: the speaker's own negotiator memory (cached per side across
|
|
537
|
+
// turns). Injected into both the dispatch payload (the user's own
|
|
538
|
+
// agent — scope-correct) and the system-agent prompt.
|
|
539
|
+
const ownSide = isSource ? "source" : "candidate";
|
|
540
|
+
const ownMemory = state.memoryBySide?.[ownSide]
|
|
541
|
+
?? (memoryRetrieve
|
|
542
|
+
? await retrieveMemory(ownUser.id, otherUser.id, memoryQueryText(state, otherUser), "turn")
|
|
543
|
+
: []);
|
|
544
|
+
const payload = {
|
|
545
|
+
negotiationId: state.taskId,
|
|
546
|
+
ownUser,
|
|
547
|
+
otherUser,
|
|
548
|
+
indexContext: state.indexContext,
|
|
549
|
+
seedAssessment: state.seedAssessment,
|
|
550
|
+
history,
|
|
551
|
+
isFinalTurn,
|
|
552
|
+
isDiscoverer: isSource,
|
|
553
|
+
seat,
|
|
554
|
+
protocolVersion: version,
|
|
555
|
+
allowedActions: [...allowedActionsFor(version, seat, isFinalTurn, { askUser: askUserAvailable })],
|
|
556
|
+
...(state.discoveryQuery && isSource && { discoveryQuery: state.discoveryQuery }),
|
|
557
|
+
...(ownMemory.length > 0 && { negotiatorMemory: ownMemory }),
|
|
558
|
+
...(state.privateConsultation?.recipientUserId === ownUser.id
|
|
559
|
+
? { privateConsultation: state.privateConsultation }
|
|
560
|
+
: {}),
|
|
561
|
+
};
|
|
562
|
+
const scope = { action: 'manage:negotiations', scopeType: 'network', scopeId: state.indexContext.networkId };
|
|
563
|
+
const dispatchResult = await dispatcher.dispatch(ownUser.id, scope, payload, { timeoutMs: state.timeoutMs });
|
|
564
|
+
let turn;
|
|
565
|
+
if (dispatchResult.handled) {
|
|
566
|
+
// Personal agent responded. Under v2, coerce out-of-seat actions to
|
|
567
|
+
// the conservative fallback — the polling/respond surfaces reject
|
|
568
|
+
// these with a 400, but locally-dispatched turns land here directly.
|
|
569
|
+
turn = dispatchResult.turn;
|
|
570
|
+
if (version === 'v2' && !allowedActionsFor(version, seat, isFinalTurn, { askUser: askUserAvailable }).includes(turn.action)) {
|
|
571
|
+
turnLog.warn('Personal agent returned out-of-seat action, coercing to conservative fallback', {
|
|
572
|
+
action: turn.action, seat, isFinalTurn,
|
|
573
|
+
});
|
|
574
|
+
turn = { ...turn, action: fallbackActionFor(version, seat, isFinalTurn) };
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
else if (dispatchResult.reason === 'waiting') {
|
|
578
|
+
// Long timeout — graph suspends. Persist the full turn context so the
|
|
579
|
+
// polling agent (and MCP consumers via get_negotiation) reconstruct
|
|
580
|
+
// the same view the in-process system agent would see. The view is
|
|
581
|
+
// stored in absolute source/candidate terms; perspective is projected
|
|
582
|
+
// at pickup time using the claiming user's id.
|
|
583
|
+
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: "waiting_for_agent" });
|
|
584
|
+
await database.setTaskTurnContext(state.taskId, {
|
|
585
|
+
sourceUser: state.sourceUser,
|
|
586
|
+
candidateUser: state.candidateUser,
|
|
587
|
+
indexContext: state.indexContext,
|
|
588
|
+
seedAssessment: state.seedAssessment,
|
|
589
|
+
// Keep discoveryQuery speaker-scoped: include it only when the
|
|
590
|
+
// parked turn belongs to the discoverer (source). Persisting it on
|
|
591
|
+
// candidate-side turns would make the pickup prompt frame the
|
|
592
|
+
// search as "your user searched for X" for the wrong user.
|
|
593
|
+
...(isSource && state.discoveryQuery && { discoveryQuery: state.discoveryQuery }),
|
|
594
|
+
...(state.privateConsultation && state.privateConsultation.recipientUserId === ownUser.id
|
|
595
|
+
? { privateConsultation: state.privateConsultation }
|
|
596
|
+
: {}),
|
|
597
|
+
}, state.continuationExecution);
|
|
598
|
+
await database.updateTaskState(state.taskId, "waiting_for_agent", undefined, state.continuationExecution);
|
|
599
|
+
return { status: 'waiting_for_agent' };
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
// No personal agent or timeout — run system agent
|
|
603
|
+
const agentPriorDialogue = buildAttributedDialogue(state);
|
|
604
|
+
turn = await systemAgent.invoke({
|
|
605
|
+
ownUser,
|
|
606
|
+
otherUser,
|
|
607
|
+
indexContext: state.indexContext,
|
|
608
|
+
seedAssessment: state.seedAssessment,
|
|
609
|
+
history,
|
|
610
|
+
isFinalTurn,
|
|
611
|
+
isDiscoverer: isSource,
|
|
612
|
+
seat,
|
|
613
|
+
protocolVersion: version,
|
|
614
|
+
...(state.discoveryQuery && isSource && { discoveryQuery: state.discoveryQuery }),
|
|
615
|
+
isContinuation: state.isContinuation,
|
|
616
|
+
...(agentPriorDialogue && { priorDialogue: agentPriorDialogue }),
|
|
617
|
+
...(state.userAnswers.length > 0 && { userAnswers: state.userAnswers }),
|
|
618
|
+
...(askUserAvailable && { canAskUser: true }),
|
|
619
|
+
...(bargainingMode && { bargaining: { consecutiveNonConvergent: deadlock.consecutiveNonConvergent } }),
|
|
620
|
+
...(ownMemory.length > 0 && { memory: ownMemory }),
|
|
621
|
+
...(state.privateConsultation?.recipientUserId === ownUser.id
|
|
622
|
+
? { privateConsultation: state.privateConsultation }
|
|
623
|
+
: {}),
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: `${turn.action}` });
|
|
627
|
+
// First turn must open the negotiation (unless continuing a prior
|
|
628
|
+
// conversation): v1 → "propose"; v2 initiator → "outreach". A v2 turn-0
|
|
629
|
+
// speaker holding the counterparty seat (tie-break inheritance) is left
|
|
630
|
+
// unforced — it is responding, not opening.
|
|
631
|
+
if (state.turnCount === 0 && !state.isContinuation) {
|
|
632
|
+
const openingAction = version === 'v2' ? 'outreach' : 'propose';
|
|
633
|
+
if ((version !== 'v2' || seat === 'initiator') && turn.action !== openingAction) {
|
|
634
|
+
turnLog.warn(`Agent returned unexpected action on turn 0, forcing to ${openingAction}`, { action: turn.action });
|
|
635
|
+
turn.action = openingAction;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
// IND-564: block a `withdraw` that comes before the initiator has opened
|
|
639
|
+
// (no in-task `outreach`) — this would retract a message never made and
|
|
640
|
+
// drop a spurious message into the shared thread. Exact ask_user resumes
|
|
641
|
+
// are exempt: the successor is the SAME logical negotiation resumed after
|
|
642
|
+
// the client answered, so post-consultation withdraw is legitimate.
|
|
643
|
+
if (turn.action === 'withdraw' && !state.outreachOpened && !state.continuationExecution) {
|
|
644
|
+
turnLog.info('negotiation_opening_withdraw_screened_out', {
|
|
645
|
+
taskId: state.taskId,
|
|
646
|
+
opportunityId: state.opportunityId || undefined,
|
|
647
|
+
seat,
|
|
648
|
+
turnCount: state.turnCount,
|
|
649
|
+
isContinuation: state.isContinuation,
|
|
650
|
+
});
|
|
651
|
+
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: "screened_out: opening withdraw" });
|
|
652
|
+
return { lastTurn: turn, firstTurnScreenedOut: true };
|
|
653
|
+
}
|
|
654
|
+
// IND-508 deterministic admission is evaluated only after the opening
|
|
655
|
+
// guard but before any turn is persisted. It consumes action/role enums
|
|
656
|
+
// only; free-form reasoning, messages, profiles, and evaluator inputs
|
|
657
|
+
// are intentionally unavailable to the policy.
|
|
658
|
+
let consultationPolicyReason;
|
|
659
|
+
const policyEligibility = policyMode === 'off' ? { eligible: false } : assessConsultationEligibility({
|
|
660
|
+
protocolVersion: version,
|
|
661
|
+
seat,
|
|
662
|
+
isOpeningTurn: state.turnCount === 0 && !state.isContinuation,
|
|
663
|
+
isFinalTurn,
|
|
664
|
+
screenedOut: blocksNegotiationBeforeFirstTurn(state.screenDecision, state.turnCount),
|
|
665
|
+
action: turn.action,
|
|
666
|
+
ownSuggestedRole: turn.assessment?.suggestedRoles?.ownUser,
|
|
667
|
+
priorActions: history.map((prior) => prior.action),
|
|
668
|
+
previouslyConsulted: hasPriorAskUser(state.messages, ownUser.id),
|
|
669
|
+
hasExactResumeCoordinate: Boolean(configuredAskUserEnabled()
|
|
670
|
+
&& questionerEnqueue
|
|
671
|
+
&& timeoutQueue?.enqueueAskUserExpiry
|
|
672
|
+
&& state.taskId
|
|
673
|
+
&& state.opportunityId
|
|
674
|
+
&& ownIntentId
|
|
675
|
+
&& state.indexContext.networkId),
|
|
676
|
+
lifecycleValid: Boolean(state.taskId && state.opportunityId && ownIntentId && state.indexContext.networkId),
|
|
677
|
+
});
|
|
678
|
+
const emitConsultationTelemetry = (stage, reason) => {
|
|
679
|
+
turnLog.info('negotiation_consultation_policy', { stage, mode: policyMode, reason });
|
|
680
|
+
emitWide({ type: 'negotiation_consultation_policy', stage, mode: policyMode, reason });
|
|
681
|
+
};
|
|
682
|
+
if (policyEligibility.eligible && policyEligibility.reason) {
|
|
683
|
+
emitConsultationTelemetry('eligible', policyEligibility.reason);
|
|
684
|
+
if (policyMode === 'on') {
|
|
685
|
+
consultationPolicyReason = policyEligibility.reason;
|
|
686
|
+
turn = {
|
|
687
|
+
...turn,
|
|
688
|
+
action: 'ask_user',
|
|
689
|
+
message: null,
|
|
690
|
+
assessment: {
|
|
691
|
+
reasoning: 'Client consultation required.',
|
|
692
|
+
suggestedRoles: turn.assessment.suggestedRoles,
|
|
693
|
+
},
|
|
694
|
+
askUser: consultationPromptFor(consultationPolicyReason),
|
|
695
|
+
};
|
|
696
|
+
emitConsultationTelemetry('asked', consultationPolicyReason);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// Safety net: off/shadow retain legacy behavior. In on, a spontaneous
|
|
700
|
+
// ask_user is admissible only when the deterministic policy just
|
|
701
|
+
// authorized it, so no unbounded pause can enter shared history.
|
|
702
|
+
if (turn.action === 'ask_user' && (!askUserAvailable || (policyMode === 'on' && !consultationPolicyReason))) {
|
|
703
|
+
turnLog.warn('ask_user emitted while unavailable, coercing to conservative fallback', {
|
|
704
|
+
seat, isFinalTurn, taskId: state.taskId,
|
|
705
|
+
});
|
|
706
|
+
turn = { ...turn, action: fallbackActionFor(version, seat, isFinalTurn) };
|
|
707
|
+
}
|
|
708
|
+
// ─── Deadlock shift record (IND-428) ───────────────────────────────
|
|
709
|
+
// Applied-stance analytics: recorded once per session, on the first
|
|
710
|
+
// turn actually drafted in the bargaining stance (the system agent —
|
|
711
|
+
// externally dispatched turns never receive the stance). Internal
|
|
712
|
+
// metadata only: persisted to tasks.metadata.deadlockShift via the
|
|
713
|
+
// optional hook; negotiation API surfaces project specific fields and
|
|
714
|
+
// never return task metadata verbatim. Every step fails open.
|
|
715
|
+
const bargainingApplied = bargainingMode && !dispatchResult.handled;
|
|
716
|
+
let deadlockShiftRecord = null;
|
|
717
|
+
if (bargainingApplied && !state.deadlockShift) {
|
|
718
|
+
deadlockShiftRecord = {
|
|
719
|
+
reason: 'consecutive_non_convergent',
|
|
720
|
+
consecutiveNonConvergent: deadlock.consecutiveNonConvergent,
|
|
721
|
+
threshold: deadlock.threshold,
|
|
722
|
+
shiftedAtTurn: state.turnCount,
|
|
723
|
+
seat,
|
|
724
|
+
detectedAt: new Date().toISOString(),
|
|
725
|
+
};
|
|
726
|
+
await database.setTaskDeadlockShift?.(state.taskId, deadlockShiftRecord, state.continuationExecution).catch((err) => {
|
|
727
|
+
turnLog.error('Failed to persist deadlock shift record', { taskId: state.taskId, error: err });
|
|
728
|
+
});
|
|
729
|
+
turnLog.info('negotiation_deadlock_shift', {
|
|
730
|
+
taskId: state.taskId,
|
|
731
|
+
opportunityId: state.opportunityId || undefined,
|
|
732
|
+
seat,
|
|
733
|
+
consecutiveNonConvergent: deadlockShiftRecord.consecutiveNonConvergent,
|
|
734
|
+
threshold: deadlockShiftRecord.threshold,
|
|
735
|
+
turnIndex: state.turnCount,
|
|
736
|
+
});
|
|
737
|
+
if (state.opportunityId) {
|
|
738
|
+
emitWide({
|
|
739
|
+
type: 'negotiation_deadlock_shift',
|
|
740
|
+
opportunityId: state.opportunityId,
|
|
741
|
+
negotiationConversationId: state.conversationId,
|
|
742
|
+
turnIndex: state.turnCount,
|
|
743
|
+
actor: isSource ? 'source' : 'candidate',
|
|
744
|
+
consecutiveNonConvergent: deadlockShiftRecord.consecutiveNonConvergent,
|
|
745
|
+
threshold: deadlockShiftRecord.threshold,
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
const parts = [{ kind: "data", data: turn }];
|
|
750
|
+
const message = await database.createMessage({
|
|
751
|
+
conversationId: state.conversationId,
|
|
752
|
+
senderId: `agent:${ownUser.id}`,
|
|
753
|
+
role: "agent",
|
|
754
|
+
parts,
|
|
755
|
+
taskId: state.taskId,
|
|
756
|
+
...(state.continuationExecution ? { continuationExecution: state.continuationExecution } : {}),
|
|
757
|
+
});
|
|
758
|
+
// ─── ask_user pause (P3.2) ────────────────────────────────────────────
|
|
759
|
+
// The negotiator consults its OWN client: persist the turn (done above),
|
|
760
|
+
// park the full turn context, arm the answer-window timer, enqueue the
|
|
761
|
+
// question through the negotiation_inflight preset, then suspend the
|
|
762
|
+
// task as input_required. The graph exits at this turn boundary exactly
|
|
763
|
+
// like the waiting_for_agent suspend; the answer (or window expiry)
|
|
764
|
+
// resumes via the run-existing continuation path.
|
|
765
|
+
if (turn.action === 'ask_user') {
|
|
766
|
+
const counterparty = isSource ? state.candidateUser : state.sourceUser;
|
|
767
|
+
const safeAskUser = validateInflightAskUserFields({
|
|
768
|
+
disclosureSubject: turn.askUser?.disclosureSubject,
|
|
769
|
+
draftQuestion: turn.askUser?.draftQuestion,
|
|
770
|
+
forbiddenIdentifiers: [
|
|
771
|
+
counterparty.id,
|
|
772
|
+
counterparty.profile.name ?? '',
|
|
773
|
+
state.opportunityId,
|
|
774
|
+
state.taskId,
|
|
775
|
+
state.indexContext.networkId,
|
|
776
|
+
isSource ? state.candidateIntentId ?? '' : state.sourceIntentId ?? '',
|
|
777
|
+
],
|
|
778
|
+
forbiddenSourceText: [
|
|
779
|
+
counterparty.profile.bio ?? '',
|
|
780
|
+
counterparty.profile.location ?? '',
|
|
781
|
+
...counterparty.intents.flatMap((intent) => [intent.title, intent.description]),
|
|
782
|
+
state.seedAssessment.reasoning,
|
|
783
|
+
state.indexContext.prompt,
|
|
784
|
+
state.discoveryQuery ?? '',
|
|
785
|
+
],
|
|
786
|
+
});
|
|
787
|
+
const settlementId = negotiationQuestionSettlementId(state.taskId);
|
|
788
|
+
const askUserBinding = await database.captureNegotiationAskUserBinding({
|
|
789
|
+
taskId: state.taskId,
|
|
790
|
+
settlementId,
|
|
791
|
+
recipientUserId: ownUser.id,
|
|
792
|
+
recipientIntentId: ownIntentId,
|
|
793
|
+
opportunityId: state.opportunityId,
|
|
794
|
+
networkId: state.indexContext.networkId,
|
|
795
|
+
turnContext: {
|
|
796
|
+
sourceUser: state.sourceUser,
|
|
797
|
+
candidateUser: state.candidateUser,
|
|
798
|
+
indexContext: state.indexContext,
|
|
799
|
+
seedAssessment: state.seedAssessment,
|
|
800
|
+
...(isSource && state.discoveryQuery && { discoveryQuery: state.discoveryQuery }),
|
|
801
|
+
...(consultationPolicyReason && { consultationPolicyReason }),
|
|
802
|
+
},
|
|
803
|
+
...(state.continuationExecution ? { continuationExecution: state.continuationExecution } : {}),
|
|
804
|
+
});
|
|
805
|
+
// Arm the timer BEFORE flipping state: it is the durable recovery
|
|
806
|
+
// trigger even when generation enqueues no job or persists no row.
|
|
807
|
+
const windowMs = askUserAnswerWindowMs();
|
|
808
|
+
await timeoutQueue.enqueueAskUserExpiry(state.taskId, {
|
|
809
|
+
settlementId,
|
|
810
|
+
opportunityId: state.opportunityId,
|
|
811
|
+
userId: ownUser.id,
|
|
812
|
+
recipientIntentId: ownIntentId,
|
|
813
|
+
networkId: state.indexContext.networkId,
|
|
814
|
+
intentFingerprint: askUserBinding.intentFingerprint,
|
|
815
|
+
opportunityStatus: askUserBinding.opportunityStatus,
|
|
816
|
+
opportunityUpdatedAt: askUserBinding.opportunityUpdatedAt,
|
|
817
|
+
counterpartyUserId: askUserBinding.counterpartyUserId,
|
|
818
|
+
counterpartyIntentId: askUserBinding.counterpartyIntentId,
|
|
819
|
+
}, windowMs);
|
|
820
|
+
// Persistence admission requires the exact task to be input_required.
|
|
821
|
+
// Flip before enqueue; if the structured ask_user fields fail the
|
|
822
|
+
// deterministic privacy gate, the timer alone closes the exact task.
|
|
823
|
+
await database.updateTaskState(state.taskId, 'input_required', undefined, state.continuationExecution);
|
|
824
|
+
if (safeAskUser) {
|
|
825
|
+
const userContext = (await database.getUserContext(ownUser.id, null).catch(() => null))?.text ?? '';
|
|
826
|
+
await questionerEnqueue({
|
|
827
|
+
mode: 'negotiation_inflight',
|
|
828
|
+
purpose: 'inflight_consultation',
|
|
829
|
+
userId: ownUser.id,
|
|
830
|
+
sourceType: 'opportunity',
|
|
831
|
+
sourceId: state.opportunityId,
|
|
832
|
+
negotiation: {
|
|
833
|
+
purpose: 'inflight_consultation',
|
|
834
|
+
recipientUserId: ownUser.id,
|
|
835
|
+
recipientIntentId: ownIntentId,
|
|
836
|
+
opportunityId: state.opportunityId,
|
|
837
|
+
taskId: state.taskId,
|
|
838
|
+
networkId: state.indexContext.networkId,
|
|
839
|
+
},
|
|
840
|
+
context: {
|
|
841
|
+
negotiationId: state.taskId,
|
|
842
|
+
counterpartyHint: NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY,
|
|
843
|
+
disclosureSubject: safeAskUser.disclosureSubject,
|
|
844
|
+
...(safeAskUser.draftQuestion && { draftQuestion: safeAskUser.draftQuestion }),
|
|
845
|
+
indexContext: NEGOTIATION_QUESTION_GENERIC_NETWORK,
|
|
846
|
+
...(consultationPolicyReason && { consultationPolicyReason }),
|
|
847
|
+
...(userContext && { userContext }),
|
|
848
|
+
},
|
|
849
|
+
}).catch((error) => {
|
|
850
|
+
turnLog.error('Failed to enqueue safe ask_user question; timeout recovery remains armed', {
|
|
851
|
+
taskId: state.taskId,
|
|
852
|
+
opportunityId: state.opportunityId,
|
|
853
|
+
error,
|
|
854
|
+
});
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
turnLog.warn('Skipping unsafe or incomplete ask_user question generation', {
|
|
859
|
+
taskId: state.taskId,
|
|
860
|
+
opportunityId: state.opportunityId,
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
turnLog.info('negotiation_ask_user_pause', {
|
|
864
|
+
taskId: state.taskId,
|
|
865
|
+
opportunityId: state.opportunityId,
|
|
866
|
+
seat,
|
|
867
|
+
askingUserId: ownUser.id,
|
|
868
|
+
windowMs,
|
|
869
|
+
});
|
|
870
|
+
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: "ask_user" });
|
|
871
|
+
emitWide({
|
|
872
|
+
type: 'negotiation_ask_user',
|
|
873
|
+
opportunityId: state.opportunityId,
|
|
874
|
+
negotiationConversationId: state.conversationId,
|
|
875
|
+
turnIndex: state.turnCount,
|
|
876
|
+
actor: isSource ? 'source' : 'candidate',
|
|
877
|
+
questionGenerationSafe: Boolean(safeAskUser),
|
|
878
|
+
windowMs,
|
|
879
|
+
});
|
|
880
|
+
return {
|
|
881
|
+
messages: [{
|
|
882
|
+
id: message.id,
|
|
883
|
+
senderId: message.senderId,
|
|
884
|
+
role: "agent",
|
|
885
|
+
parts: message.parts,
|
|
886
|
+
createdAt: message.createdAt,
|
|
887
|
+
}],
|
|
888
|
+
turnCount: state.turnCount + 1,
|
|
889
|
+
lastTurn: turn,
|
|
890
|
+
status: 'input_required',
|
|
891
|
+
...(deadlockShiftRecord && { deadlockShift: deadlockShiftRecord }),
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
await database.updateTaskState(state.taskId, "working", undefined, state.continuationExecution);
|
|
895
|
+
if (state.opportunityId) {
|
|
896
|
+
emitWide({
|
|
897
|
+
type: "negotiation_turn",
|
|
898
|
+
opportunityId: state.opportunityId,
|
|
899
|
+
negotiationConversationId: state.conversationId,
|
|
900
|
+
turnIndex: state.turnCount,
|
|
901
|
+
actor: isSource ? "source" : "candidate",
|
|
902
|
+
action: turn.action,
|
|
903
|
+
...(turn.assessment?.reasoning && { reasoning: turn.assessment.reasoning }),
|
|
904
|
+
...(turn.message && { message: turn.message }),
|
|
905
|
+
...(turn.assessment?.suggestedRoles && { suggestedRoles: turn.assessment.suggestedRoles }),
|
|
906
|
+
durationMs: Date.now() - agentStart,
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
return {
|
|
910
|
+
messages: [{
|
|
911
|
+
id: message.id,
|
|
912
|
+
senderId: message.senderId,
|
|
913
|
+
role: "agent",
|
|
914
|
+
parts: message.parts,
|
|
915
|
+
createdAt: message.createdAt,
|
|
916
|
+
}],
|
|
917
|
+
turnCount: state.turnCount + 1,
|
|
918
|
+
currentSpeaker: (isSource ? "candidate" : "source"),
|
|
919
|
+
lastTurn: turn,
|
|
920
|
+
memoryBySide: { [ownSide]: ownMemory },
|
|
921
|
+
// Record the in-task outreach so a later `withdraw` is legal (IND-564).
|
|
922
|
+
...(turn.action === 'outreach' && { outreachOpened: true }),
|
|
923
|
+
...(deadlockShiftRecord && { deadlockShift: deadlockShiftRecord }),
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
catch (err) {
|
|
927
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
928
|
+
turnLog.error("Agent invocation failed", { error: errMsg, stack: err instanceof Error ? err.stack : undefined, turnCount: state.turnCount });
|
|
929
|
+
traceEmitter?.({ type: "agent_end", name: agentName, durationMs: Date.now() - agentStart, summary: `error: ${errMsg}` });
|
|
930
|
+
const errorSeat = (state.currentSpeaker === 'source' ? state.sourceUser.id : state.candidateUser.id) === (state.initiatorUserId ?? state.sourceUser.id)
|
|
931
|
+
? 'initiator'
|
|
932
|
+
: 'counterparty';
|
|
933
|
+
return {
|
|
934
|
+
lastTurn: {
|
|
935
|
+
action: rejectActionFor(state.protocolVersion ?? 'v1', errorSeat),
|
|
936
|
+
assessment: { reasoning: `Agent error: ${errMsg}`, suggestedRoles: { ownUser: "peer", otherUser: "peer" } },
|
|
937
|
+
},
|
|
938
|
+
turnCount: state.turnCount + 1,
|
|
939
|
+
error: `Turn failed: ${errMsg}`,
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
const evaluateNode = (state) => {
|
|
944
|
+
if (state.status === 'waiting_for_agent')
|
|
945
|
+
return "finalize";
|
|
946
|
+
if (state.status === 'input_required')
|
|
947
|
+
return "finalize";
|
|
948
|
+
if (state.error)
|
|
949
|
+
return "finalize";
|
|
950
|
+
if (!state.lastTurn)
|
|
951
|
+
return "finalize";
|
|
952
|
+
// Terminal actions: accept (v1+v2), reject (v1), withdraw/decline (v2)
|
|
953
|
+
if (isTerminalAction(state.lastTurn.action))
|
|
954
|
+
return "finalize";
|
|
955
|
+
// question routes same as counter — next turn
|
|
956
|
+
if ((state.maxTurns ?? 0) > 0 && state.turnCount >= state.maxTurns)
|
|
957
|
+
return "finalize";
|
|
958
|
+
return "turn";
|
|
959
|
+
};
|
|
960
|
+
const finalizeNode = async (state) => {
|
|
961
|
+
const traceEmitter = requestContext.getStore()?.traceEmitter;
|
|
962
|
+
const emitWide = (event) => traceEmitter?.(event);
|
|
963
|
+
const pauseReceipt = (outcome) => state.continuationExecution
|
|
964
|
+
? {
|
|
965
|
+
continuationReceipt: {
|
|
966
|
+
priorTaskId: state.continuationExecution.taskId,
|
|
967
|
+
settlementId: state.continuationExecution.settlementId,
|
|
968
|
+
successorTaskId: state.continuationExecution.successorTaskId,
|
|
969
|
+
fence: state.continuationExecution.fence,
|
|
970
|
+
outcome,
|
|
971
|
+
},
|
|
972
|
+
}
|
|
973
|
+
: undefined;
|
|
974
|
+
if (state.status === 'waiting_for_agent') {
|
|
975
|
+
if (state.opportunityId) {
|
|
976
|
+
emitWide({
|
|
977
|
+
type: "negotiation_outcome",
|
|
978
|
+
opportunityId: state.opportunityId,
|
|
979
|
+
outcome: "waiting_for_agent",
|
|
980
|
+
turnCount: state.turnCount,
|
|
981
|
+
isContinuation: state.isContinuation,
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
return pauseReceipt('waiting_for_agent') ?? {};
|
|
985
|
+
}
|
|
986
|
+
// ask_user pause: no outcome, no completed state — the task stays
|
|
987
|
+
// input_required until the client answers or the window expires.
|
|
988
|
+
if (state.status === 'input_required') {
|
|
989
|
+
if (state.opportunityId) {
|
|
990
|
+
emitWide({
|
|
991
|
+
type: "negotiation_outcome",
|
|
992
|
+
opportunityId: state.opportunityId,
|
|
993
|
+
outcome: "input_required",
|
|
994
|
+
turnCount: state.turnCount,
|
|
995
|
+
isContinuation: state.isContinuation,
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
return pauseReceipt('input_required') ?? {};
|
|
999
|
+
}
|
|
1000
|
+
// Init can fail closed before an attempt owns a task. Such a rejection is
|
|
1001
|
+
// not a completed negotiation and must not write through an empty task ID,
|
|
1002
|
+
// create an artifact, or advance the opportunity lifecycle.
|
|
1003
|
+
if (!state.taskId) {
|
|
1004
|
+
finalizeLog.info('Skipping outcome persistence because no negotiation task was claimed', {
|
|
1005
|
+
opportunityId: state.opportunityId || undefined,
|
|
1006
|
+
error: state.error || undefined,
|
|
1007
|
+
});
|
|
1008
|
+
return {};
|
|
1009
|
+
}
|
|
1010
|
+
const history = turnsFromMessages(state.messages);
|
|
1011
|
+
const lastTurn = state.lastTurn;
|
|
1012
|
+
const hasOpportunity = lastTurn?.action === "accept";
|
|
1013
|
+
// P2.2: the client's own outreach gate declined before any turn — the
|
|
1014
|
+
// negotiation never happened from the counterparty's perspective.
|
|
1015
|
+
// IND-564: an opening-move `withdraw` blocked before any message was
|
|
1016
|
+
// persisted is the same quiet screen-out outcome (no in-task outreach to
|
|
1017
|
+
// retract), reached from the turn node rather than the screen node.
|
|
1018
|
+
const screenedOut = blocksNegotiationBeforeFirstTurn(state.screenDecision, state.turnCount) || state.firstTurnScreenedOut === true;
|
|
1019
|
+
const atCap = !screenedOut && (state.maxTurns ?? 0) > 0 && state.turnCount >= state.maxTurns && !isTerminalAction(lastTurn?.action);
|
|
1020
|
+
let agreedRoles = [];
|
|
1021
|
+
if (hasOpportunity && history.length >= 2) {
|
|
1022
|
+
const acceptTurn = history[history.length - 1];
|
|
1023
|
+
const precedingTurn = history[history.length - 2];
|
|
1024
|
+
const accepterIsSource = state.currentSpeaker === "candidate";
|
|
1025
|
+
const [sourceRole, candidateRole] = accepterIsSource
|
|
1026
|
+
? [acceptTurn.assessment.suggestedRoles.ownUser, precedingTurn.assessment.suggestedRoles.ownUser]
|
|
1027
|
+
: [precedingTurn.assessment.suggestedRoles.ownUser, acceptTurn.assessment.suggestedRoles.ownUser];
|
|
1028
|
+
agreedRoles = [
|
|
1029
|
+
{ userId: state.sourceUser.id, role: sourceRole },
|
|
1030
|
+
{ userId: state.candidateUser.id, role: candidateRole },
|
|
1031
|
+
];
|
|
1032
|
+
}
|
|
1033
|
+
const outcome = {
|
|
1034
|
+
hasOpportunity,
|
|
1035
|
+
agreedRoles,
|
|
1036
|
+
reasoning: screenedOut
|
|
1037
|
+
? (state.screenDecision?.reasoning ?? lastTurn?.assessment?.reasoning ?? "")
|
|
1038
|
+
: (lastTurn?.assessment.reasoning ?? ""),
|
|
1039
|
+
turnCount: state.turnCount,
|
|
1040
|
+
...(screenedOut
|
|
1041
|
+
? { reason: "screened_out" }
|
|
1042
|
+
: atCap
|
|
1043
|
+
? { reason: "turn_cap" }
|
|
1044
|
+
: {}),
|
|
1045
|
+
};
|
|
1046
|
+
try {
|
|
1047
|
+
await database.updateTaskState(state.taskId, "completed", undefined, state.continuationExecution);
|
|
1048
|
+
await database.createArtifact({
|
|
1049
|
+
taskId: state.taskId,
|
|
1050
|
+
name: "negotiation-outcome",
|
|
1051
|
+
parts: [{ kind: "data", data: outcome }],
|
|
1052
|
+
metadata: {
|
|
1053
|
+
hasOpportunity,
|
|
1054
|
+
turnCount: state.turnCount,
|
|
1055
|
+
...(state.continuationExecution ? {
|
|
1056
|
+
continuationOutcome: hasOpportunity
|
|
1057
|
+
? 'accepted'
|
|
1058
|
+
: (screenedOut || isRejectLikeAction(lastTurn?.action)) ? 'rejected' : 'stalled',
|
|
1059
|
+
} : {}),
|
|
1060
|
+
},
|
|
1061
|
+
...(state.continuationExecution ? { continuationExecution: state.continuationExecution } : {}),
|
|
1062
|
+
});
|
|
1063
|
+
finalizeLog.info('Session complete', {
|
|
1064
|
+
conversationId: state.conversationId,
|
|
1065
|
+
taskId: state.taskId,
|
|
1066
|
+
isContinuation: state.isContinuation,
|
|
1067
|
+
turnsAdded: state.turnCount,
|
|
1068
|
+
priorTurnCount: state.priorTurnCount,
|
|
1069
|
+
outcome: hasOpportunity ? 'accepted' : screenedOut ? 'screened_out' : (atCap ? 'turn_cap' : (lastTurn?.action ?? 'unknown')),
|
|
1070
|
+
opportunityId: state.opportunityId || undefined,
|
|
1071
|
+
});
|
|
1072
|
+
if (state.opportunityId) {
|
|
1073
|
+
// screened_out → 'rejected': quiet terminal status (hidden from
|
|
1074
|
+
// default lists), never 'stalled' — with zero turns the generic
|
|
1075
|
+
// mapping would misfile the client's own gate decision.
|
|
1076
|
+
const nextStatus = lastTurn?.action === 'accept'
|
|
1077
|
+
? 'pending'
|
|
1078
|
+
: (screenedOut || isRejectLikeAction(lastTurn?.action))
|
|
1079
|
+
? 'rejected'
|
|
1080
|
+
: 'stalled';
|
|
1081
|
+
await database.updateOpportunityStatus(state.opportunityId, nextStatus, undefined, state.continuationExecution).catch((err) => {
|
|
1082
|
+
finalizeLog.error("Failed to update opportunity status", { opportunityId: state.opportunityId, nextStatus, error: err });
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
catch (err) {
|
|
1087
|
+
finalizeLog.error("Failed to persist outcome", { error: err });
|
|
1088
|
+
}
|
|
1089
|
+
if (state.opportunityId) {
|
|
1090
|
+
const emittedOutcome = hasOpportunity
|
|
1091
|
+
? "accepted"
|
|
1092
|
+
: screenedOut
|
|
1093
|
+
? "screened_out"
|
|
1094
|
+
: atCap
|
|
1095
|
+
? "turn_cap"
|
|
1096
|
+
: state.error && /timeout/i.test(state.error)
|
|
1097
|
+
? "timed_out"
|
|
1098
|
+
: "rejected_stalled";
|
|
1099
|
+
emitWide({
|
|
1100
|
+
type: "negotiation_outcome",
|
|
1101
|
+
opportunityId: state.opportunityId,
|
|
1102
|
+
outcome: emittedOutcome,
|
|
1103
|
+
turnCount: state.turnCount,
|
|
1104
|
+
isContinuation: state.isContinuation,
|
|
1105
|
+
turnsAdded: state.turnCount,
|
|
1106
|
+
priorTurnCount: state.priorTurnCount,
|
|
1107
|
+
...(outcome.reasoning && { reasoning: outcome.reasoning }),
|
|
1108
|
+
...(hasOpportunity && agreedRoles.length >= 2 && {
|
|
1109
|
+
agreedRoles: {
|
|
1110
|
+
ownUser: agreedRoles[0]?.role,
|
|
1111
|
+
otherUser: agreedRoles[1]?.role,
|
|
1112
|
+
},
|
|
1113
|
+
}),
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
if (state.consultationPolicyReason) {
|
|
1117
|
+
// Stable, content-free terminal funnel telemetry. This executes only
|
|
1118
|
+
// after a fenced continuation has reached its terminal outcome.
|
|
1119
|
+
finalizeLog.info('negotiation_consultation_policy', {
|
|
1120
|
+
stage: 'terminal_outcome',
|
|
1121
|
+
reason: state.consultationPolicyReason,
|
|
1122
|
+
outcome: hasOpportunity ? 'accepted' : (screenedOut || isRejectLikeAction(lastTurn?.action)) ? 'rejected' : 'stalled',
|
|
1123
|
+
});
|
|
1124
|
+
emitWide({
|
|
1125
|
+
type: 'negotiation_consultation_policy',
|
|
1126
|
+
stage: 'terminal_outcome',
|
|
1127
|
+
reason: state.consultationPolicyReason,
|
|
1128
|
+
outcome: hasOpportunity ? 'accepted' : (screenedOut || isRejectLikeAction(lastTurn?.action)) ? 'rejected' : 'stalled',
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
// Enqueue post-negotiation reflection (P5.2 memory write path) — fire
|
|
1132
|
+
// and forget: a reflection failure must never affect the outcome. Only
|
|
1133
|
+
// sessions that actually exchanged turns teach anything; init/turn
|
|
1134
|
+
// errors with turnCount 0 are skipped.
|
|
1135
|
+
if (reflectEnqueue && state.turnCount > 0 && !state.continuationExecution) {
|
|
1136
|
+
reflectEnqueue({
|
|
1137
|
+
negotiationId: state.taskId,
|
|
1138
|
+
conversationId: state.conversationId,
|
|
1139
|
+
...(state.opportunityId && { opportunityId: state.opportunityId }),
|
|
1140
|
+
sourceUser: {
|
|
1141
|
+
id: state.sourceUser.id,
|
|
1142
|
+
...(state.sourceUser.profile.name && { name: state.sourceUser.profile.name }),
|
|
1143
|
+
...(state.sourceUser.profile.bio && { bio: state.sourceUser.profile.bio }),
|
|
1144
|
+
},
|
|
1145
|
+
candidateUser: {
|
|
1146
|
+
id: state.candidateUser.id,
|
|
1147
|
+
...(state.candidateUser.profile.name && { name: state.candidateUser.profile.name }),
|
|
1148
|
+
...(state.candidateUser.profile.bio && { bio: state.candidateUser.profile.bio }),
|
|
1149
|
+
},
|
|
1150
|
+
initiatorUserId: state.initiatorUserId ?? state.sourceUser.id,
|
|
1151
|
+
outcome: { hasOpportunity, reasoning: outcome.reasoning, turnCount: state.turnCount },
|
|
1152
|
+
}).catch((err) => finalizeLog.error('Failed to enqueue negotiation reflection', {
|
|
1153
|
+
taskId: state.taskId,
|
|
1154
|
+
error: err,
|
|
1155
|
+
}));
|
|
1156
|
+
}
|
|
1157
|
+
// Enqueue question generation for stalled/capped negotiations (not accepted or explicitly rejected).
|
|
1158
|
+
// Require turnCount > 0 so early init/turn errors don't enqueue with empty context.
|
|
1159
|
+
if (!hasOpportunity && !isRejectLikeAction(lastTurn?.action) && state.turnCount > 0 && state.opportunityId && state.sourceIntentId && state.indexContext.networkId && questionerEnqueue && !state.continuationExecution) {
|
|
1160
|
+
const stallReason = atCap
|
|
1161
|
+
? 'turn_cap'
|
|
1162
|
+
: (state.error && /timeout/i.test(state.error))
|
|
1163
|
+
? 'timeout'
|
|
1164
|
+
: 'stalled';
|
|
1165
|
+
const userContext = (await database.getUserContext(state.sourceUser.id, null))?.text ?? '';
|
|
1166
|
+
const sourceIntent = state.sourceUser.intents.find((intent) => intent.id === state.sourceIntentId);
|
|
1167
|
+
questionerEnqueue({
|
|
1168
|
+
mode: 'negotiation',
|
|
1169
|
+
purpose: 'stalled_followup',
|
|
1170
|
+
userId: state.sourceUser.id,
|
|
1171
|
+
sourceType: 'opportunity',
|
|
1172
|
+
sourceId: state.opportunityId,
|
|
1173
|
+
negotiation: {
|
|
1174
|
+
purpose: 'stalled_followup',
|
|
1175
|
+
recipientUserId: state.sourceUser.id,
|
|
1176
|
+
recipientIntentId: state.sourceIntentId,
|
|
1177
|
+
opportunityId: state.opportunityId,
|
|
1178
|
+
taskId: state.taskId,
|
|
1179
|
+
networkId: state.indexContext.networkId,
|
|
1180
|
+
},
|
|
1181
|
+
context: {
|
|
1182
|
+
negotiationId: state.taskId,
|
|
1183
|
+
counterpartyHint: NEGOTIATION_QUESTION_GENERIC_COUNTERPARTY,
|
|
1184
|
+
indexContext: NEGOTIATION_QUESTION_GENERIC_NETWORK,
|
|
1185
|
+
outcomeReason: stallReason,
|
|
1186
|
+
recipientIntent: sourceIntent
|
|
1187
|
+
? `${sourceIntent.title}: ${sourceIntent.description}`
|
|
1188
|
+
: 'the signal attached to this match',
|
|
1189
|
+
userContext,
|
|
1190
|
+
},
|
|
1191
|
+
}).catch((err) => finalizeLog.error('Failed to enqueue negotiation question generation', {
|
|
1192
|
+
opportunityId: state.opportunityId,
|
|
1193
|
+
error: err,
|
|
1194
|
+
}));
|
|
1195
|
+
}
|
|
1196
|
+
const terminalReceipt = state.continuationExecution
|
|
1197
|
+
? {
|
|
1198
|
+
continuationReceipt: {
|
|
1199
|
+
priorTaskId: state.continuationExecution.taskId,
|
|
1200
|
+
settlementId: state.continuationExecution.settlementId,
|
|
1201
|
+
successorTaskId: state.continuationExecution.successorTaskId,
|
|
1202
|
+
fence: state.continuationExecution.fence,
|
|
1203
|
+
outcome: hasOpportunity
|
|
1204
|
+
? 'accepted'
|
|
1205
|
+
: (screenedOut || isRejectLikeAction(lastTurn?.action)) ? 'rejected' : 'stalled',
|
|
1206
|
+
},
|
|
1207
|
+
}
|
|
1208
|
+
: undefined;
|
|
1209
|
+
return { outcome, status: 'completed', ...terminalReceipt };
|
|
1210
|
+
};
|
|
1211
|
+
const workflow = new StateGraph(NegotiationGraphState)
|
|
1212
|
+
.addNode("init", initNode)
|
|
1213
|
+
.addNode("screen", screenNode)
|
|
1214
|
+
.addNode("turn", turnNode)
|
|
1215
|
+
.addNode("finalize", finalizeNode)
|
|
1216
|
+
.addConditionalEdges("turn", evaluateNode, {
|
|
1217
|
+
turn: "turn",
|
|
1218
|
+
finalize: "finalize",
|
|
1219
|
+
})
|
|
1220
|
+
.addConditionalEdges("init", (state) => {
|
|
1221
|
+
if (state.error)
|
|
1222
|
+
return "finalize";
|
|
1223
|
+
// Screen gate: fresh negotiations only (continuations already passed
|
|
1224
|
+
// the gate when the dialogue opened); off disables the node entirely.
|
|
1225
|
+
// IND-563: regular continuations (new opportunity, existing dm_pair)
|
|
1226
|
+
// also run through the screen gate so stale matches are caught before
|
|
1227
|
+
// re-engaging the counterparty. Exact ask_user resumes
|
|
1228
|
+
// (continuationExecution) are mid-flight and must never be re-screened.
|
|
1229
|
+
if (configuredScreenMode() !== "off" && !state.continuationExecution)
|
|
1230
|
+
return "screen";
|
|
1231
|
+
return "turn";
|
|
1232
|
+
}, { screen: "screen", turn: "turn", finalize: "finalize" })
|
|
1233
|
+
// P2.2: enforce-mode pass → finalize (screened_out); everything else → turn.
|
|
1234
|
+
.addConditionalEdges("screen", (state) => blocksNegotiationBeforeFirstTurn(state.screenDecision, state.turnCount) ? "finalize" : "turn", { turn: "turn", finalize: "finalize" })
|
|
1235
|
+
.addEdge("__start__", "init")
|
|
1236
|
+
.addEdge("finalize", "__end__");
|
|
1237
|
+
return workflow.compile();
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
/**
|
|
1241
|
+
* Runs bilateral negotiation for each candidate in parallel.
|
|
1242
|
+
* @returns Only candidates that produced an opportunity
|
|
1243
|
+
*/
|
|
1244
|
+
export async function negotiateCandidates(negotiationGraph, sourceUser, candidates, indexContext, opts) {
|
|
1245
|
+
const { maxTurns, traceEmitter, indexContextOverrides, timeoutMs, onCandidateResolved, trigger, initiatorUserId, resumeFromTaskId, continuationSettlementId, continuationExecution, } = opts ?? {};
|
|
1246
|
+
// Local helper to emit events whose shape is wider than the declared
|
|
1247
|
+
// `TraceEmitter` union (mirrors the cast used in chat.agent at the relay sink
|
|
1248
|
+
// and inside turn/finalize nodes above).
|
|
1249
|
+
const emitWide = (event) => traceEmitter?.(event);
|
|
1250
|
+
const results = await Promise.all(candidates.map(async (candidate) => {
|
|
1251
|
+
const start = Date.now();
|
|
1252
|
+
if (candidate.opportunityId) {
|
|
1253
|
+
const candidateName = candidate.candidateUser?.profile?.name;
|
|
1254
|
+
emitWide({
|
|
1255
|
+
type: "negotiation_session_start",
|
|
1256
|
+
opportunityId: candidate.opportunityId,
|
|
1257
|
+
negotiationConversationId: "", // filled in on session_end
|
|
1258
|
+
sourceUserId: sourceUser.id,
|
|
1259
|
+
candidateUserId: candidate.userId,
|
|
1260
|
+
initiatorUserId: initiatorUserId ?? sourceUser.id,
|
|
1261
|
+
...(candidateName && { candidateName }),
|
|
1262
|
+
trigger: trigger ?? "ambient",
|
|
1263
|
+
startedAt: start,
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
traceEmitter?.({ type: "agent_start", name: "Negotiating candidate" });
|
|
1267
|
+
try {
|
|
1268
|
+
const candidateIndexContext = candidate.networkId
|
|
1269
|
+
? { networkId: candidate.networkId, prompt: indexContextOverrides?.get(candidate.networkId) ?? '' }
|
|
1270
|
+
: indexContext;
|
|
1271
|
+
const result = await invokeWithAbortSignal(negotiationGraph, {
|
|
1272
|
+
sourceUser,
|
|
1273
|
+
candidateUser: candidate.candidateUser,
|
|
1274
|
+
...(candidate.sourceIntentId && { sourceIntentId: candidate.sourceIntentId }),
|
|
1275
|
+
...(candidate.candidateIntentId && { candidateIntentId: candidate.candidateIntentId }),
|
|
1276
|
+
indexContext: candidateIndexContext,
|
|
1277
|
+
seedAssessment: {
|
|
1278
|
+
reasoning: candidate.reasoning,
|
|
1279
|
+
valencyRole: candidate.valencyRole,
|
|
1280
|
+
},
|
|
1281
|
+
...(candidate.discoveryQuery && { discoveryQuery: candidate.discoveryQuery }),
|
|
1282
|
+
...(candidate.opportunityId && { opportunityId: candidate.opportunityId }),
|
|
1283
|
+
...(candidate.opportunityStatus && { opportunityStatus: candidate.opportunityStatus }),
|
|
1284
|
+
...(candidate.opportunityUpdatedAt && { opportunityUpdatedAt: candidate.opportunityUpdatedAt }),
|
|
1285
|
+
...(initiatorUserId && { initiatorUserId }),
|
|
1286
|
+
...(resumeFromTaskId && continuationSettlementId && continuationExecution ? {
|
|
1287
|
+
resumeFromTaskId,
|
|
1288
|
+
continuationSettlementId,
|
|
1289
|
+
continuationExecution,
|
|
1290
|
+
} : {}),
|
|
1291
|
+
...(maxTurns !== undefined && { maxTurns }),
|
|
1292
|
+
...(timeoutMs !== undefined && { timeoutMs }),
|
|
1293
|
+
});
|
|
1294
|
+
const durationMs = Date.now() - start;
|
|
1295
|
+
const outcome = result.outcome;
|
|
1296
|
+
const hasOpportunity = outcome?.hasOpportunity === true;
|
|
1297
|
+
const isContinuation = result.isContinuation ?? false;
|
|
1298
|
+
const priorTurnCount = result.priorTurnCount ?? 0;
|
|
1299
|
+
const turnFlow = (result.messages ?? [])
|
|
1300
|
+
.map((m) => {
|
|
1301
|
+
const dataPart = m.parts?.find((p) => p.kind === "data");
|
|
1302
|
+
if (!dataPart?.data)
|
|
1303
|
+
return null;
|
|
1304
|
+
const turn = dataPart.data;
|
|
1305
|
+
return turn.action ?? "unknown";
|
|
1306
|
+
})
|
|
1307
|
+
.filter(Boolean)
|
|
1308
|
+
.join(" → ");
|
|
1309
|
+
const statusTag = hasOpportunity ? "✓ opportunity" : "✗ rejected";
|
|
1310
|
+
traceEmitter?.({ type: "agent_end", name: "Negotiating candidate", durationMs, summary: `${candidate.userId}: ${turnFlow} ${statusTag}` });
|
|
1311
|
+
if (candidate.opportunityId) {
|
|
1312
|
+
emitWide({
|
|
1313
|
+
type: "negotiation_session_end",
|
|
1314
|
+
opportunityId: candidate.opportunityId,
|
|
1315
|
+
negotiationConversationId: result.conversationId ?? "",
|
|
1316
|
+
durationMs: Date.now() - start,
|
|
1317
|
+
isContinuation,
|
|
1318
|
+
turnsAdded: outcome?.turnCount ?? 0,
|
|
1319
|
+
priorTurnCount,
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
const accepted = hasOpportunity && outcome
|
|
1323
|
+
? {
|
|
1324
|
+
userId: candidate.userId,
|
|
1325
|
+
agreedRoles: outcome.agreedRoles,
|
|
1326
|
+
reasoning: outcome.reasoning,
|
|
1327
|
+
turnCount: outcome.turnCount,
|
|
1328
|
+
}
|
|
1329
|
+
: null;
|
|
1330
|
+
if (onCandidateResolved) {
|
|
1331
|
+
const turnHistory = turnsFromMessages(result.messages ?? []);
|
|
1332
|
+
const resolvedOutcome = result.outcome ?? {
|
|
1333
|
+
hasOpportunity: false,
|
|
1334
|
+
agreedRoles: [],
|
|
1335
|
+
reasoning: "no outcome returned by negotiation graph",
|
|
1336
|
+
turnCount: turnHistory.length,
|
|
1337
|
+
};
|
|
1338
|
+
try {
|
|
1339
|
+
await onCandidateResolved({
|
|
1340
|
+
candidate,
|
|
1341
|
+
accepted,
|
|
1342
|
+
turns: turnHistory,
|
|
1343
|
+
outcome: resolvedOutcome,
|
|
1344
|
+
...(result.continuationReceipt ? { continuationReceipt: result.continuationReceipt } : {}),
|
|
1345
|
+
});
|
|
1346
|
+
}
|
|
1347
|
+
catch (hookErr) {
|
|
1348
|
+
// Hook failures must not sink the candidate result — the aggregate
|
|
1349
|
+
// return is still useful, and the orchestrator branch logs its own
|
|
1350
|
+
// failures inline.
|
|
1351
|
+
negotiateCandidatesLog.error("onCandidateResolved hook threw", {
|
|
1352
|
+
candidateUserId: candidate.userId,
|
|
1353
|
+
error: hookErr,
|
|
1354
|
+
});
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
return accepted;
|
|
1358
|
+
}
|
|
1359
|
+
catch (err) {
|
|
1360
|
+
const durationMs = Date.now() - start;
|
|
1361
|
+
traceEmitter?.({ type: "agent_end", name: "Negotiating candidate", durationMs, summary: `${candidate.userId}: error` });
|
|
1362
|
+
if (candidate.opportunityId) {
|
|
1363
|
+
emitWide({
|
|
1364
|
+
type: "negotiation_session_end",
|
|
1365
|
+
opportunityId: candidate.opportunityId,
|
|
1366
|
+
negotiationConversationId: "",
|
|
1367
|
+
durationMs: Date.now() - start,
|
|
1368
|
+
});
|
|
1369
|
+
}
|
|
1370
|
+
negotiateCandidatesLog.error("Negotiation failed", { candidateUserId: candidate.userId, error: err });
|
|
1371
|
+
if (onCandidateResolved) {
|
|
1372
|
+
try {
|
|
1373
|
+
await onCandidateResolved({
|
|
1374
|
+
candidate,
|
|
1375
|
+
accepted: null,
|
|
1376
|
+
turns: [],
|
|
1377
|
+
outcome: {
|
|
1378
|
+
hasOpportunity: false,
|
|
1379
|
+
agreedRoles: [],
|
|
1380
|
+
reasoning: err instanceof Error ? err.message : String(err),
|
|
1381
|
+
turnCount: 0,
|
|
1382
|
+
},
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
catch {
|
|
1386
|
+
// ignore hook failure on error path
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
return null;
|
|
1390
|
+
}
|
|
1391
|
+
}));
|
|
1392
|
+
return results.filter((r) => r !== null);
|
|
1393
|
+
}
|