@indexnetwork/protocol 11.0.0-rc.454.1 → 11.0.2-rc.456.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.
Files changed (74) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/dist/capabilities/contacts.facade.d.ts +1 -1
  3. package/dist/capabilities/integrations.facade.d.ts +1 -1
  4. package/dist/capabilities/participant-agents.facade.d.ts +2 -2
  5. package/dist/capabilities/participant-agents.facade.js +1 -1
  6. package/dist/capabilities/questions.facade.d.ts +2 -2
  7. package/dist/capabilities/questions.facade.js +1 -1
  8. package/dist/chat/chat-streaming.types.d.ts +1 -1
  9. package/dist/chat/chat.agent.d.ts +1 -1
  10. package/dist/contacts/domain/contact.types.d.ts +0 -2
  11. package/dist/contacts/domain/contact.types.js +0 -2
  12. package/dist/contacts/domain/index.d.ts +0 -2
  13. package/dist/contacts/index.d.ts +1 -2
  14. package/dist/contacts/index.js +1 -2
  15. package/dist/contacts/ports/contact.tools.port.d.ts +3 -5
  16. package/dist/contacts/ports/contact.tools.port.js +3 -5
  17. package/dist/contacts/ports/index.d.ts +0 -2
  18. package/dist/contacts/ports/index.js +0 -2
  19. package/dist/enrichment/enrichment.graph.d.ts +4 -4
  20. package/dist/enrichment/enrichment.state.d.ts +1 -1
  21. package/dist/index.d.ts +6 -7
  22. package/dist/index.js +2 -2
  23. package/dist/integrations/domain/index.d.ts +0 -2
  24. package/dist/integrations/domain/integration.types.d.ts +0 -2
  25. package/dist/integrations/domain/integration.types.js +0 -2
  26. package/dist/integrations/index.d.ts +1 -2
  27. package/dist/integrations/index.js +1 -2
  28. package/dist/integrations/ports/index.d.ts +0 -2
  29. package/dist/integrations/ports/index.js +0 -2
  30. package/dist/integrations/ports/integration.tools.port.d.ts +3 -5
  31. package/dist/integrations/ports/integration.tools.port.js +3 -5
  32. package/dist/mcp/elicitation.builder.d.ts +1 -1
  33. package/dist/mcp/elicitation.dispatcher.d.ts +1 -1
  34. package/dist/opportunity/application/opportunity.graph.d.ts +5 -5
  35. package/dist/opportunity/discriminator/discriminator.adjustments.d.ts +1 -1
  36. package/dist/opportunity/discriminator/discriminator.push.d.ts +1 -1
  37. package/dist/opportunity/discriminator/discriminator.question.d.ts +1 -1
  38. package/dist/opportunity/domain/opportunity.state.d.ts +1 -1
  39. package/dist/participant-agents/domain/index.d.ts +0 -1
  40. package/dist/participant-agents/index.d.ts +2 -6
  41. package/dist/participant-agents/index.js +2 -6
  42. package/dist/participant-agents/ports/agent.tools.port.d.ts +3 -5
  43. package/dist/participant-agents/ports/agent.tools.port.js +3 -5
  44. package/dist/participant-agents/ports/index.d.ts +1 -2
  45. package/dist/participant-agents/ports/index.js +1 -2
  46. package/dist/questions/domain/index.d.ts +0 -1
  47. package/dist/questions/domain/index.js +0 -1
  48. package/dist/questions/domain/question.schema.d.ts +1 -3
  49. package/dist/questions/domain/question.schema.js +1 -3
  50. package/dist/questions/index.d.ts +1 -6
  51. package/dist/questions/index.js +1 -6
  52. package/dist/questions/ports/question.generator.port.d.ts +1 -2
  53. package/dist/questions/ports/question.persistence.port.d.ts +1 -2
  54. package/dist/questions/public/index.d.ts +1 -1
  55. package/dist/shared/agent/tool.helpers.d.ts +6 -6
  56. package/dist/shared/schemas/pending-question.schema.d.ts +1 -1
  57. package/dist/signals/application/intake.orchestrator.d.ts +63 -13
  58. package/dist/signals/application/intake.orchestrator.js +107 -18
  59. package/dist/signals/application/intent.clarifier.js +1 -1
  60. package/dist/signals/application/intent.graph.d.ts +1 -1
  61. package/dist/signals/application/intent.verifier.d.ts +6 -6
  62. package/package.json +2 -1
  63. package/dist/shared/interfaces/agent.interface.d.ts +0 -17
  64. package/dist/shared/interfaces/agent.interface.js +0 -15
  65. package/dist/shared/interfaces/contact.interface.d.ts +0 -9
  66. package/dist/shared/interfaces/contact.interface.js +0 -8
  67. package/dist/shared/interfaces/integration.interface.d.ts +0 -9
  68. package/dist/shared/interfaces/integration.interface.js +0 -8
  69. package/dist/shared/interfaces/question-generator.interface.d.ts +0 -5
  70. package/dist/shared/interfaces/question-generator.interface.js +0 -1
  71. package/dist/shared/interfaces/questioner.interface.d.ts +0 -5
  72. package/dist/shared/interfaces/questioner.interface.js +0 -1
  73. package/dist/shared/schemas/question.schema.d.ts +0 -5
  74. package/dist/shared/schemas/question.schema.js +0 -5
@@ -5,11 +5,9 @@
5
5
  * optional AgentDatabase so agent registration tools are compiled only
6
6
  * when the database adapter is wired at the composition root.
7
7
  *
8
- * NOTE: This type is intentionally defined inline (not derived via Pick from
9
- * ToolRegistryCompositionDeps in shared/agent/tool.helpers.ts) to avoid a
10
- * module cycle. ToolRegistryCompositionDeps imports AgentDatabase from
11
- * shared/interfaces/agent.interface.ts, which after IND-548 forwards to
12
- * participant-agents/ports — creating a cycle back here.
8
+ * NOTE: This type is intentionally defined inline rather than derived from
9
+ * ToolRegistryCompositionDeps, keeping the capability port independent from
10
+ * the all-capability composition contract.
13
11
  *
14
12
  * Structural equivalence with ToolRegistryCompositionDeps.agentDatabase is
15
13
  * preserved: both have type `AgentDatabase | undefined`.
@@ -19,8 +19,7 @@
19
19
  * - AgentToolDeps — host capabilities for registration/permission tools.
20
20
  *
21
21
  * IND-548: canonical ports surface for the participant-agents capability.
22
- * Legacy paths:
23
- * - shared/interfaces/agent.interface.ts → re-exports AgentDatabase from here
22
+ * Compatibility path:
24
23
  * - shared/interfaces/agent-dispatcher.interface.ts → re-exports from here
25
24
  */
26
25
  export type { AgentDatabase } from "./agent.repository.port.js";
@@ -19,8 +19,7 @@
19
19
  * - AgentToolDeps — host capabilities for registration/permission tools.
20
20
  *
21
21
  * IND-548: canonical ports surface for the participant-agents capability.
22
- * Legacy paths:
23
- * - shared/interfaces/agent.interface.ts → re-exports AgentDatabase from here
22
+ * Compatibility path:
24
23
  * - shared/interfaces/agent-dispatcher.interface.ts → re-exports from here
25
24
  */
26
25
  export {};
@@ -20,6 +20,5 @@
20
20
  * - Persistence/generator ports: questions/ports.
21
21
  *
22
22
  * IND-547: canonical home for question domain types.
23
- * Legacy path (shared/schemas/question.schema.ts) is a thin compatibility shim.
24
23
  */
25
24
  export * from "./question.schema.js";
@@ -20,6 +20,5 @@
20
20
  * - Persistence/generator ports: questions/ports.
21
21
  *
22
22
  * IND-547: canonical home for question domain types.
23
- * Legacy path (shared/schemas/question.schema.ts) is a thin compatibility shim.
24
23
  */
25
24
  export * from "./question.schema.js";
@@ -5,9 +5,7 @@
5
5
  * elicitation dispatch, plus internal generator, persistence, and delivery
6
6
  * envelopes used across the questions capability.
7
7
  *
8
- * IND-547: extracted from shared/schemas/question.schema.ts into the
9
- * questions domain layer. Legacy path (shared/schemas/question.schema.ts)
10
- * is a thin compatibility shim pointing here.
8
+ * IND-547: canonical question schema in the questions domain layer.
11
9
  */
12
10
  import { z } from "zod";
13
11
  export declare const QuestionOptionSchema: z.ZodObject<{
@@ -5,9 +5,7 @@
5
5
  * elicitation dispatch, plus internal generator, persistence, and delivery
6
6
  * envelopes used across the questions capability.
7
7
  *
8
- * IND-547: extracted from shared/schemas/question.schema.ts into the
9
- * questions domain layer. Legacy path (shared/schemas/question.schema.ts)
10
- * is a thin compatibility shim pointing here.
8
+ * IND-547: canonical question schema in the questions domain layer.
11
9
  */
12
10
  import { z } from "zod";
13
11
  export const QuestionOptionSchema = z.object({
@@ -7,14 +7,9 @@
7
7
  * go through the questions public surface.
8
8
  *
9
9
  * IND-547: canonical home for question generation, eligibility, validation,
10
- * provenance, settlement policy, and continuation behaviour previously spread
11
- * across questioner/, shared/schemas/question.schema.ts, and
12
- * shared/interfaces/questioner.interface.ts.
10
+ * provenance, settlement policy, and continuation behaviour.
13
11
  *
14
12
  * Compatibility paths:
15
13
  * - capabilities/questions.facade.ts — re-exports from questions/public/index.js
16
- * - shared/schemas/question.schema.ts — re-exports from questions/domain
17
- * - shared/interfaces/questioner.interface.ts — re-exports from questions/ports
18
- * - shared/interfaces/question-generator.interface.ts — re-exports from questions/ports
19
14
  */
20
15
  export * from "./public/index.js";
@@ -7,14 +7,9 @@
7
7
  * go through the questions public surface.
8
8
  *
9
9
  * IND-547: canonical home for question generation, eligibility, validation,
10
- * provenance, settlement policy, and continuation behaviour previously spread
11
- * across questioner/, shared/schemas/question.schema.ts, and
12
- * shared/interfaces/questioner.interface.ts.
10
+ * provenance, settlement policy, and continuation behaviour.
13
11
  *
14
12
  * Compatibility paths:
15
13
  * - capabilities/questions.facade.ts — re-exports from questions/public/index.js
16
- * - shared/schemas/question.schema.ts — re-exports from questions/domain
17
- * - shared/interfaces/questioner.interface.ts — re-exports from questions/ports
18
- * - shared/interfaces/question-generator.interface.ts — re-exports from questions/ports
19
14
  */
20
15
  export * from "./public/index.js";
@@ -11,8 +11,7 @@
11
11
  * `ProtocolDeps`/`ToolContext`. The protocol module never constructs its own
12
12
  * LLM-bound generator — callers inject one (or `undefined` to opt out).
13
13
  *
14
- * IND-547: canonical home — previously shared/interfaces/question-generator.interface.ts.
15
- * Legacy path is a thin compatibility shim pointing here.
14
+ * IND-547: canonical question generator port.
16
15
  */
17
16
  import type { DiscoveryQuestionInput } from "../../shared/schemas/discovery-question.schema.js";
18
17
  import type { QuestionGenerationResult } from "../domain/question.schema.js";
@@ -5,8 +5,7 @@
5
5
  * QuestionerAgent. Implementations live in the backend and are injected into
6
6
  * ProtocolDeps.
7
7
  *
8
- * IND-547: canonical home — previously shared/interfaces/questioner.interface.ts.
9
- * Legacy path is a thin compatibility shim pointing here.
8
+ * IND-547: canonical question persistence port.
10
9
  */
11
10
  import type { Question, QuestionMode, QuestionPurpose, QuestionStrategy, QuestionDetection, QuestionActor, QuestionAnswer, UnderspecificationType } from "../domain/question.schema.js";
12
11
  /** Shape accepted by `persist()` — everything needed to insert a question row. */
@@ -44,4 +44,4 @@ export { isQuestionerEnabled, isDiscoveryQuestionsEnabled, isUptakeGuardEnabled,
44
44
  export { isValidQuestionerInputContract, } from "../application/index.js";
45
45
  export type { QuestionerInput, QuestionerEnqueuePayload, QuestionerEnqueueFn, PoolDiscoveryContext, RecoveryQuestionerInput, UptakeQuestionerInput, PostStallQuestionerInput, InflightQuestionerInput, } from "../application/index.js";
46
46
  export { createQuestionerTools, createAskUserQuestionTools } from "../application/index.js";
47
- export type { QuestionerToolDeps, AskUserQuestionToolDeps } from "../ports/index.js";
47
+ export type { AskUserQuestionToolDeps, ChatQuestionAnswerOutcome, ChatQuestionsHost, PersistableQuestion, PersistedQuestion, QuestionFilters, QuestionGeneratorReader, QuestionerDatabase, QuestionerToolDeps, } from "../ports/index.js";
@@ -5,25 +5,25 @@ import type { UserIdentity } from "../schemas/identity.schema.js";
5
5
  import type { ChatGraphCompositeDatabase, CreateOpportunityData, NetworkMembership, UserRecord, UserDatabase, SystemDatabase, NegotiationGraphDatabase } from "../interfaces/database.interface.js";
6
6
  import type { Scraper } from "../interfaces/scraper.interface.js";
7
7
  import type { Cache, HydeCache } from "../interfaces/cache.interface.js";
8
- import type { IntegrationAdapter } from "../interfaces/integration.interface.js";
9
- import type { ContactServiceAdapter } from "../interfaces/contact.interface.js";
8
+ import type { IntegrationAdapter } from "../../integrations/ports/index.js";
9
+ import type { ContactServiceAdapter } from "../../contacts/ports/index.js";
10
10
  import type { ProfileEnricher } from "../interfaces/enrichment.interface.js";
11
11
  import type { IntentGraphQueue } from "../interfaces/queue.interface.js";
12
12
  import type { ChatSessionReader } from "../interfaces/chat-session.interface.js";
13
13
  import type { ChatSummaryReader } from "../interfaces/chat-summary.interface.js";
14
14
  import type { ChatMessageWriter } from "../interfaces/chat-message-writer.interface.js";
15
- import type { QuestionGeneratorReader } from "../interfaces/question-generator.interface.js";
15
+ import type { QuestionGeneratorReader } from "../../questions/ports/question.generator.port.js";
16
16
  import type { NegotiationSummaryReader } from "../interfaces/negotiation-summary.interface.js";
17
17
  import type { Embedder } from "../interfaces/embedder.interface.js";
18
- import type { AgentDatabase } from "../interfaces/agent.interface.js";
18
+ import type { AgentDatabase } from "../../participant-agents/ports/index.js";
19
19
  import type { NegotiationTimeoutQueue } from "../interfaces/negotiation-events.interface.js";
20
20
  import type { AgentDispatcher } from "../interfaces/agent-dispatcher.interface.js";
21
21
  import type { DeliveryLedger } from "../interfaces/delivery-ledger.interface.js";
22
- import type { ChatQuestionsHost, QuestionerDatabase } from "../interfaces/questioner.interface.js";
22
+ import type { ChatQuestionsHost, QuestionerDatabase } from "../../questions/ports/index.js";
23
23
  import type { NegotiatorMemoryToolsHost } from "../interfaces/negotiator-memory.interface.js";
24
24
  import type { QuestionerEnqueueFn } from "../../questions/application/question.input.js";
25
25
  import type { PendingQuestionSummary } from "../schemas/pending-question.schema.js";
26
- import type { QuestionMode, QuestionPurpose } from "../schemas/question.schema.js";
26
+ import type { QuestionMode, QuestionPurpose } from "../../questions/domain/question.schema.js";
27
27
  import type { EnrichmentRunQueue, EnrichmentRunStore } from "../interfaces/enrichment-run.interface.js";
28
28
  import type { McpActivityCaller } from "./activity-projection.js";
29
29
  export type IdentityContext = UserIdentity | null;
@@ -3,7 +3,7 @@
3
3
  * in tool results. Omits internal fields (actors, answer, status) that
4
4
  * are not needed by the chat agent or MCP client.
5
5
  */
6
- import type { QuestionMode, QuestionPurpose } from "./question.schema.js";
6
+ import type { QuestionMode, QuestionPurpose } from "../../questions/domain/question.schema.js";
7
7
  export interface PendingQuestionSummary {
8
8
  id: string;
9
9
  title: string;
@@ -56,9 +56,10 @@ export interface SynthesisResult {
56
56
  }
57
57
  declare const followUpPlanSchema: z.ZodObject<{
58
58
  questions: z.ZodArray<z.ZodObject<{
59
+ missingAxis: z.ZodEnum<["purpose", "desired_attributes", "exchange", "constraint"]>;
59
60
  title: z.ZodString;
60
61
  prompt: z.ZodString;
61
- options: z.ZodArray<z.ZodObject<{
62
+ answerGroundedOptions: z.ZodArray<z.ZodObject<{
62
63
  label: z.ZodString;
63
64
  description: z.ZodString;
64
65
  }, "strip", z.ZodTypeAny, {
@@ -71,45 +72,92 @@ declare const followUpPlanSchema: z.ZodObject<{
71
72
  multiSelect: z.ZodBoolean;
72
73
  }, "strip", z.ZodTypeAny, {
73
74
  prompt: string;
74
- options: {
75
+ title: string;
76
+ multiSelect: boolean;
77
+ missingAxis: "purpose" | "desired_attributes" | "exchange" | "constraint";
78
+ answerGroundedOptions: {
75
79
  label: string;
76
80
  description: string;
77
81
  }[];
78
- title: string;
79
- multiSelect: boolean;
80
82
  }, {
81
83
  prompt: string;
82
- options: {
84
+ title: string;
85
+ multiSelect: boolean;
86
+ missingAxis: "purpose" | "desired_attributes" | "exchange" | "constraint";
87
+ answerGroundedOptions: {
83
88
  label: string;
84
89
  description: string;
85
90
  }[];
86
- title: string;
87
- multiSelect: boolean;
88
91
  }>, "many">;
89
92
  plannedFollowUpCount: z.ZodNumber;
90
93
  }, "strip", z.ZodTypeAny, {
91
94
  questions: {
92
95
  prompt: string;
93
- options: {
96
+ title: string;
97
+ multiSelect: boolean;
98
+ missingAxis: "purpose" | "desired_attributes" | "exchange" | "constraint";
99
+ answerGroundedOptions: {
94
100
  label: string;
95
101
  description: string;
96
102
  }[];
97
- title: string;
98
- multiSelect: boolean;
99
103
  }[];
100
104
  plannedFollowUpCount: number;
101
105
  }, {
102
106
  questions: {
103
107
  prompt: string;
104
- options: {
108
+ title: string;
109
+ multiSelect: boolean;
110
+ missingAxis: "purpose" | "desired_attributes" | "exchange" | "constraint";
111
+ answerGroundedOptions: {
105
112
  label: string;
106
113
  description: string;
107
114
  }[];
108
- title: string;
109
- multiSelect: boolean;
110
115
  }[];
111
116
  plannedFollowUpCount: number;
112
117
  }>;
118
+ declare const profileBridgePlanSchema: z.ZodObject<{
119
+ bridges: z.ZodArray<z.ZodObject<{
120
+ questionIndex: z.ZodNumber;
121
+ profileBridgeOption: z.ZodNullable<z.ZodObject<{
122
+ label: z.ZodString;
123
+ description: z.ZodString;
124
+ }, "strip", z.ZodTypeAny, {
125
+ label: string;
126
+ description: string;
127
+ }, {
128
+ label: string;
129
+ description: string;
130
+ }>>;
131
+ }, "strip", z.ZodTypeAny, {
132
+ questionIndex: number;
133
+ profileBridgeOption: {
134
+ label: string;
135
+ description: string;
136
+ } | null;
137
+ }, {
138
+ questionIndex: number;
139
+ profileBridgeOption: {
140
+ label: string;
141
+ description: string;
142
+ } | null;
143
+ }>, "many">;
144
+ }, "strip", z.ZodTypeAny, {
145
+ bridges: {
146
+ questionIndex: number;
147
+ profileBridgeOption: {
148
+ label: string;
149
+ description: string;
150
+ } | null;
151
+ }[];
152
+ }, {
153
+ bridges: {
154
+ questionIndex: number;
155
+ profileBridgeOption: {
156
+ label: string;
157
+ description: string;
158
+ } | null;
159
+ }[];
160
+ }>;
113
161
  /** Static round-1 question used only when pack generation fails outright. */
114
162
  export declare const FALLBACK_WHO_QUESTION: IntakePackQuestion;
115
163
  /** Static round-2 question used when live generation fails. */
@@ -124,12 +172,14 @@ export declare function answerLabel(answer: IntakeAnswer): string;
124
172
  /** Runs the two live stages of the fast intake funnel: follow-up planning and synthesis. */
125
173
  export declare class SignalIntakeOrchestrator {
126
174
  private readonly plannerModel;
175
+ private readonly profileBridgeModel;
127
176
  private readonly synthesisModel;
128
177
  /**
129
178
  * @param models - Optional injected structured models. Tests pass stubs.
130
179
  */
131
180
  constructor(models?: {
132
181
  planner?: Runnable<BaseLanguageModelInput, z.infer<typeof followUpPlanSchema>>;
182
+ profileBridge?: Runnable<BaseLanguageModelInput, z.infer<typeof profileBridgePlanSchema>>;
133
183
  synthesis?: Runnable<BaseLanguageModelInput, SynthesisResult>;
134
184
  });
135
185
  /**
@@ -10,16 +10,35 @@ import { HumanMessage, SystemMessage } from "@langchain/core/messages";
10
10
  import { z } from "zod";
11
11
  import { createStructuredModel } from "../../shared/agent/model.config.js";
12
12
  import { normalizeIntakePack } from "./intake.pack.generator.js";
13
- const questionSchema = z.object({
13
+ const optionSchema = z.object({
14
+ label: z.string().min(1),
15
+ description: z.string(),
16
+ });
17
+ const answerFirstQuestionSchema = z.object({
18
+ missingAxis: z
19
+ .enum(["purpose", "desired_attributes", "exchange", "constraint"])
20
+ .describe("The unanswered decision axis selected only from the answered intake rounds."),
14
21
  title: z.string(),
15
22
  prompt: z.string().min(1),
16
- options: z.array(z.object({ label: z.string().min(1), description: z.string() })),
23
+ answerGroundedOptions: z
24
+ .array(optionSchema)
25
+ .min(2)
26
+ .max(3)
27
+ .describe("Two or three distinct choices derived only from the answered intake rounds."),
17
28
  multiSelect: z.boolean(),
18
29
  });
19
30
  const followUpPlanSchema = z.object({
20
- questions: z.array(questionSchema),
31
+ questions: z.array(answerFirstQuestionSchema),
21
32
  plannedFollowUpCount: z.number().int().min(0),
22
33
  });
34
+ const profileBridgePlanSchema = z.object({
35
+ bridges: z.array(z.object({
36
+ questionIndex: z.number().int().min(0),
37
+ profileBridgeOption: optionSchema
38
+ .nullable()
39
+ .describe("One natural profile intersection, or null when the bridge would be forced."),
40
+ })),
41
+ });
23
42
  const synthesisSchema = z.object({
24
43
  description: z.string().min(1),
25
44
  lookingFor: z.string().min(1),
@@ -49,18 +68,37 @@ export const FALLBACK_BRING_QUESTION = {
49
68
  ],
50
69
  multiSelect: false,
51
70
  };
52
- const PLAN_SYSTEM_PROMPT = `You plan and write follow-up intake questions for a networking product.
71
+ const PLAN_SYSTEM_PROMPT = `You plan and write answer-first follow-up intake questions for a networking product.
72
+
73
+ You receive ONLY the answered intake rounds. Use them to choose the next missing
74
+ axis, write a standalone prompt that names the newly stated person or domain, and
75
+ create 2-3 meaningfully distinct answerGroundedOptions. Choose the most useful
76
+ unanswered axis from: purpose, desired_attributes, exchange, or constraint. Never
77
+ re-ask an axis the rounds already answer. Do not infer a professional background,
78
+ industry, capability, or commercial goal that the rounds do not state.
79
+
80
+ Every answerGroundedOption must be visibly anchored to the stated person or domain
81
+ in its label or description and represent a concrete, distinct path. Generic labels
82
+ such as "Learn", "Share", "Collaborate", or "Networking" are invalid when they do
83
+ not say what the user would learn, share, collaborate on, or network about.
84
+ - Scuba divers: "Learn diving techniques", "Find dive buddies", "Share dive stories".
85
+ - Climate founders: "Compare climate sectors", "Find climate peers", "Discuss adaptation".
53
86
 
54
- Given a brief about the person and the intake rounds they already answered, decide
55
- how many further questions (up to the stated maximum) would make their signal
56
- specific enough to match on, and write them. Each question is one concise prompt
57
- with 3-4 concrete options grounded in the brief and the previous answers; each
58
- option has a short label and a one-line description. Set multiSelect true only
59
- when several options can genuinely apply together. Never re-ask a dimension that
60
- is already answered; skip a dimension the brief already covers. Never expose raw
61
- JSON, IDs, or internal vocabulary. plannedFollowUpCount is the TOTAL number of
62
- follow-up questions the interview should contain, including any returned now;
63
- when the input already fixes it, echo that value unchanged.`;
87
+ Each option needs a short label and a one-line description. Set multiSelect true
88
+ only when several options can genuinely apply together. Never expose raw JSON,
89
+ IDs, or internal vocabulary. plannedFollowUpCount is the TOTAL number of follow-up
90
+ questions the interview should contain, including any returned now; when the input
91
+ already fixes it, echo that value unchanged.`;
92
+ const PROFILE_BRIDGE_SYSTEM_PROMPT = `You may append one optional profile bridge to each already-written signal-intake question.
93
+
94
+ The question, missing axis, and answer-grounded options are immutable. For each
95
+ questionIndex, compare them with the profile brief and return either one genuinely
96
+ useful profileBridgeOption or null. A bridge is useful only when it creates a
97
+ natural additional path that is not already represented. Never rewrite, replace,
98
+ remove, or reclassify a core option. Never return more than one bridge per question.
99
+ When the profile theme is unrelated or the intersection would feel forced, return
100
+ null. Running club + investor may support one sponsorship bridge; scuba divers +
101
+ pianist should return null.`;
64
102
  const SYNTHESIS_SYSTEM_PROMPT = `You write one clear signal for a networking product.
65
103
 
66
104
  Combine the brief and the person's answers into a specific description of who they
@@ -79,6 +117,37 @@ community constraint. Never invent facts beyond the brief and the answers.`;
79
117
  export function answerLabel(answer) {
80
118
  return [...answer.selectedOptions, answer.freeText?.trim() ?? ""].filter(Boolean).join(", ");
81
119
  }
120
+ function normalizeFollowUpQuestion(question, profileBridge, brief) {
121
+ const seen = new Set();
122
+ const normalizeOption = (option) => {
123
+ const label = option.label.trim();
124
+ const key = label.toLocaleLowerCase();
125
+ if (!label || seen.has(key))
126
+ return null;
127
+ seen.add(key);
128
+ return { label, description: option.description.trim() };
129
+ };
130
+ const answerGroundedOptions = question.answerGroundedOptions
131
+ .map(normalizeOption)
132
+ .filter((option) => option !== null)
133
+ .slice(0, 3);
134
+ if (answerGroundedOptions.length < 2) {
135
+ throw new Error("Follow-up question needs at least two answer-grounded options.");
136
+ }
137
+ const profileBridgeOption = profileBridge ? normalizeOption(profileBridge) : null;
138
+ return normalizeIntakePack({
139
+ brief,
140
+ question: {
141
+ title: question.title,
142
+ prompt: question.prompt,
143
+ options: [
144
+ ...answerGroundedOptions,
145
+ ...(profileBridgeOption ? [profileBridgeOption] : []),
146
+ ],
147
+ multiSelect: question.multiSelect,
148
+ },
149
+ }).question;
150
+ }
82
151
  /** Runs the two live stages of the fast intake funnel: follow-up planning and synthesis. */
83
152
  export class SignalIntakeOrchestrator {
84
153
  /**
@@ -87,6 +156,8 @@ export class SignalIntakeOrchestrator {
87
156
  constructor(models) {
88
157
  this.plannerModel = models?.planner
89
158
  ?? createStructuredModel("signalIntakePack", followUpPlanSchema);
159
+ this.profileBridgeModel = models?.profileBridge
160
+ ?? createStructuredModel("signalIntakePack", profileBridgePlanSchema, { name: "signal_intake_profile_bridges" });
90
161
  this.synthesisModel = models?.synthesis
91
162
  ?? createStructuredModel("signalIntakePack", synthesisSchema);
92
163
  }
@@ -107,11 +178,29 @@ export class SignalIntakeOrchestrator {
107
178
  try {
108
179
  const raw = await this.plannerModel.invoke([
109
180
  new SystemMessage(PLAN_SYSTEM_PROMPT),
110
- new HumanMessage(`Brief:\n${input.brief}\n\n${roundsText}\n\nWrite up to ${input.maxFollowUps} follow-up question(s).${lockedLine}`),
181
+ new HumanMessage(`ANSWERED ROUNDS:\n${roundsText}\n\nWrite up to ${input.maxFollowUps} follow-up question(s).${lockedLine}`),
111
182
  ]);
112
- const questions = raw.questions
113
- .slice(0, input.maxFollowUps)
114
- .map((q) => normalizeIntakePack({ brief: input.brief, question: q }).question);
183
+ const coreQuestions = raw.questions.slice(0, input.maxFollowUps);
184
+ const bridgeByQuestion = new Map();
185
+ if (coreQuestions.length > 0 && input.brief.trim()) {
186
+ try {
187
+ const bridgePlan = await this.profileBridgeModel.invoke([
188
+ new SystemMessage(PROFILE_BRIDGE_SYSTEM_PROMPT),
189
+ new HumanMessage(`ANSWERED ROUNDS:\n${roundsText}\n\nPROFILE BRIEF:\n${input.brief}\n\nIMMUTABLE CORE QUESTIONS:\n${JSON.stringify(coreQuestions, null, 2)}\n\nReturn one bridge decision for each questionIndex.`),
190
+ ]);
191
+ for (const bridge of bridgePlan.bridges) {
192
+ if (bridge.questionIndex < coreQuestions.length
193
+ && !bridgeByQuestion.has(bridge.questionIndex)) {
194
+ bridgeByQuestion.set(bridge.questionIndex, bridge.profileBridgeOption);
195
+ }
196
+ }
197
+ }
198
+ catch {
199
+ // Profile personalization is optional. A bridge-model failure must not
200
+ // discard valid answer-grounded questions from the primary model.
201
+ }
202
+ }
203
+ const questions = coreQuestions.map((question, index) => normalizeFollowUpQuestion(question, bridgeByQuestion.get(index) ?? null, input.brief));
115
204
  // Backstop: while budget remains, a successful empty plan must not
116
205
  // silently shrink the interview; serve the static fallback instead.
117
206
  if (questions.length === 0 && input.maxFollowUps > 0) {
@@ -13,7 +13,7 @@ import { createStructuredModel } from "../../shared/agent/model.config.js";
13
13
  import { invokeWithAbortSignal } from "../../shared/agent/model-signal.js";
14
14
  import { protocolLogger } from "../../shared/observability/protocol.logger.js";
15
15
  import { Timed } from "../../shared/observability/performance.js";
16
- import { UnderspecificationTypeSchema } from "../../shared/schemas/question.schema.js";
16
+ import { UnderspecificationTypeSchema } from "../../questions/domain/question.schema.js";
17
17
  const logger = protocolLogger("IntentClarifier");
18
18
  const clarificationSchema = z.discriminatedUnion("needsClarification", [
19
19
  z.object({
@@ -150,7 +150,7 @@ export declare class IntentGraphFactory {
150
150
  message?: string;
151
151
  networkId?: string;
152
152
  } | undefined> | undefined;
153
- }, "query" | "__start__" | "inference" | "verification" | "prep" | "reconciler" | "executor", {
153
+ }, "query" | "__start__" | "prep" | "inference" | "verification" | "reconciler" | "executor", {
154
154
  userId: {
155
155
  (annotation: import("@langchain/langgraph").SingleReducer<string, string>): import("@langchain/langgraph").BaseChannel<string, string | import("@langchain/langgraph").OverwriteValue<string>, unknown>;
156
156
  (): import("@langchain/langgraph").LastValue<string>;
@@ -9,13 +9,13 @@ declare const responseFormat: z.ZodObject<{
9
9
  authority: z.ZodNumber;
10
10
  sincerity: z.ZodNumber;
11
11
  }, "strip", z.ZodTypeAny, {
12
- sincerity: number;
13
12
  clarity: number;
14
13
  authority: number;
15
- }, {
16
14
  sincerity: number;
15
+ }, {
17
16
  clarity: number;
18
17
  authority: number;
18
+ sincerity: number;
19
19
  }>;
20
20
  semantic_entropy: z.ZodNumber;
21
21
  referential_anchor: z.ZodNullable<z.ZodString>;
@@ -27,9 +27,9 @@ declare const responseFormat: z.ZodObject<{
27
27
  reasoning: string;
28
28
  classification: "COMMISSIVE" | "DIRECTIVE" | "ASSERTIVE" | "EXPRESSIVE" | "DECLARATION" | "UNKNOWN";
29
29
  felicity_scores: {
30
- sincerity: number;
31
30
  clarity: number;
32
31
  authority: number;
32
+ sincerity: number;
33
33
  };
34
34
  semantic_entropy: number;
35
35
  referential_anchor: string | null;
@@ -41,9 +41,9 @@ declare const responseFormat: z.ZodObject<{
41
41
  reasoning: string;
42
42
  classification: "COMMISSIVE" | "DIRECTIVE" | "ASSERTIVE" | "EXPRESSIVE" | "DECLARATION" | "UNKNOWN";
43
43
  felicity_scores: {
44
- sincerity: number;
45
44
  clarity: number;
46
45
  authority: number;
46
+ sincerity: number;
47
47
  };
48
48
  semantic_entropy: number;
49
49
  referential_anchor: string | null;
@@ -67,9 +67,9 @@ export declare class SemanticVerifier {
67
67
  reasoning: string;
68
68
  classification: "COMMISSIVE" | "DIRECTIVE" | "ASSERTIVE" | "EXPRESSIVE" | "DECLARATION" | "UNKNOWN";
69
69
  felicity_scores: {
70
- sincerity: number;
71
70
  clarity: number;
72
71
  authority: number;
72
+ sincerity: number;
73
73
  };
74
74
  semantic_entropy: number;
75
75
  referential_anchor: string | null;
@@ -100,9 +100,9 @@ export declare class SemanticVerifier {
100
100
  reasoning: string;
101
101
  classification: "COMMISSIVE" | "DIRECTIVE" | "ASSERTIVE" | "EXPRESSIVE" | "DECLARATION" | "UNKNOWN";
102
102
  felicity_scores: {
103
- sincerity: number;
104
103
  clarity: number;
105
104
  authority: number;
105
+ sincerity: number;
106
106
  };
107
107
  semantic_entropy: number;
108
108
  referential_anchor: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/protocol",
3
- "version": "11.0.0-rc.454.1",
3
+ "version": "11.0.2-rc.456.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -40,6 +40,7 @@
40
40
  "eval:profile": "bun --env-file=../../.env.test ./eval/profile/profile.eval.ts",
41
41
  "eval:opportunity": "bun --env-file=../../.env.test ./eval/opportunity/opportunity.eval.ts",
42
42
  "eval:clarification": "bun --env-file=../../.env.test ./eval/clarification/clarification.eval.ts",
43
+ "eval:intake": "bun --env-file=../../.env.test ./eval/intake/intake.eval.ts",
43
44
  "eval:discovery-retrieval": "bun --env-file=../../.env.test ./eval/discovery-retrieval/discovery-retrieval.eval.ts",
44
45
  "eval:canary": "bun --env-file=../../.env.test ./eval/canary/canary.eval.ts",
45
46
  "eval:stance": "bun --env-file=../../.env.test ./eval/stance/stance.eval.ts",
@@ -1,17 +0,0 @@
1
- /**
2
- * @deprecated — compatibility shim.
3
- *
4
- * Canonical types have moved to the participant-agents domain-first module:
5
- * - Domain entity types → participant-agents/domain
6
- * - AgentDatabase port → participant-agents/ports
7
- *
8
- * This re-export exists solely to avoid breaking imports that pre-date IND-548.
9
- * Import directly from participant-agents/domain or participant-agents/ports
10
- * for new code, or use the capabilities/participant-agents.facade.ts surface
11
- * from outside the package.
12
- *
13
- * IND-548: migrated to src/participant-agents/domain/ and src/participant-agents/ports/.
14
- */
15
- export type { AgentRecord, AgentTransportRecord, AgentPermissionRecord, AgentWithRelations, CreateAgentInput, CreateTransportInput, GrantPermissionInput, } from '../../participant-agents/domain/index.js';
16
- export { SYSTEM_AGENT_IDS } from '../../participant-agents/domain/index.js';
17
- export type { AgentDatabase } from '../../participant-agents/ports/index.js';
@@ -1,15 +0,0 @@
1
- /**
2
- * @deprecated — compatibility shim.
3
- *
4
- * Canonical types have moved to the participant-agents domain-first module:
5
- * - Domain entity types → participant-agents/domain
6
- * - AgentDatabase port → participant-agents/ports
7
- *
8
- * This re-export exists solely to avoid breaking imports that pre-date IND-548.
9
- * Import directly from participant-agents/domain or participant-agents/ports
10
- * for new code, or use the capabilities/participant-agents.facade.ts surface
11
- * from outside the package.
12
- *
13
- * IND-548: migrated to src/participant-agents/domain/ and src/participant-agents/ports/.
14
- */
15
- export { SYSTEM_AGENT_IDS } from '../../participant-agents/domain/index.js';
@@ -1,9 +0,0 @@
1
- /**
2
- * @deprecated Canonical location: contacts/ports
3
- * Retained for backward compatibility during IND-549 migration.
4
- *
5
- * IND-549: types and interfaces migrated to src/contacts/domain and
6
- * src/contacts/ports. This file is a thin compatibility shim.
7
- */
8
- export type { ContactInput, ContactResult, ContactImportResult, ContactEntry, ContactSearchResult, } from "../../contacts/domain/index.js";
9
- export type { ContactServiceAdapter } from "../../contacts/ports/index.js";
@@ -1,8 +0,0 @@
1
- /**
2
- * @deprecated Canonical location: contacts/ports
3
- * Retained for backward compatibility during IND-549 migration.
4
- *
5
- * IND-549: types and interfaces migrated to src/contacts/domain and
6
- * src/contacts/ports. This file is a thin compatibility shim.
7
- */
8
- export {};